ps2sdk  1.1
A collection of Open Source libraries used for developing applications on Sony's PlayStation 2® (PS2).
screenshot.c
Go to the documentation of this file.
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright 2001-2004, ps2dev - http://www.ps2dev.org
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
9 */
10 
16 #include "screenshot.h"
17 #include <tamtypes.h>
18 #include <kernel.h>
19 #include <fcntl.h>
20 #include <unistd.h>
21 
22 // These macros are kept local so the screenshot funcion can work without
23 // interfering with other macros
24 
25 #define PS2SS_GIF_AD 0x0e
26 
27 #define PS2SS_GIFTAG(NLOOP,EOP,PRE,PRIM,FLG,NREG) \
28  ((u64)(NLOOP) << 0) | \
29  ((u64)(EOP) << 15) | \
30  ((u64)(PRE) << 46) | \
31  ((u64)(PRIM) << 47) | \
32  ((u64)(FLG) << 58) | \
33  ((u64)(NREG) << 60)
34 
35 #define PS2SS_GSBITBLTBUF_SET(sbp, sbw, spsm, dbp, dbw, dpsm) \
36  ((u64)(sbp) | ((u64)(sbw) << 16) | \
37  ((u64)(spsm) << 24) | ((u64)(dbp) << 32) | \
38  ((u64)(dbw) << 48) | ((u64)(dpsm) << 56))
39 
40 #define PS2SS_GSTRXREG_SET(rrw, rrh) \
41  ((u64)(rrw) | ((u64)(rrh) << 32))
42 
43 #define PS2SS_GSTRXPOS_SET(ssax, ssay, dsax, dsay, dir) \
44  ((u64)(ssax) | ((u64)(ssay) << 16) | \
45  ((u64)(dsax) << 32) | ((u64)(dsay) << 48) | \
46  ((u64)(dir) << 59))
47 
48 #define PS2SS_GSTRXDIR_SET(xdr) ((u64)(xdr))
49 
50 #define PS2SS_GSBITBLTBUF 0x50
51 #define PS2SS_GSFINISH 0x61
52 #define PS2SS_GSTRXPOS 0x51
53 #define PS2SS_GSTRXREG 0x52
54 #define PS2SS_GSTRXDIR 0x53
55 
56 #define PS2SS_GSPSMCT32 0
57 #define PS2SS_GSPSMCT24 1
58 #define PS2SS_GSPSMCT16 2
59 
60 #define PS2SS_D1_CHCR ((volatile unsigned int *)(0x10009000))
61 #define PS2SS_D1_MADR ((volatile unsigned int *)(0x10009010))
62 #define PS2SS_D1_QWC ((volatile unsigned int *)(0x10009020))
63 #define PS2SS_D1_TADR ((volatile unsigned int *)(0x10009030))
64 #define PS2SS_D1_ASR0 ((volatile unsigned int *)(0x10009040))
65 #define PS2SS_D1_ASR1 ((volatile unsigned int *)(0x10009050))
66 
67 #define PS2SS_CSR_FINISH (1 << 1)
68 #define PS2SS_GS_CSR ((volatile u64 *)(0x12001000))
69 #define PS2SS_GS_BUSDIR ((volatile u64 *)(0x12001040))
70 
71 #define PS2SS_VIF1_STAT ((volatile u32 *)(0x10003c00))
72 #define PS2SS_VIF1_STAT_FDR (1<< 23)
73 #define PS2SS_VIF1_MSKPATH3(mask) ((u32)(mask) | ((u32)0x06 << 24))
74 #define PS2SS_VIF1_NOP 0
75 #define PS2SS_VIF1_FLUSHA (((u32)0x13 << 24))
76 #define PS2SS_VIF1_DIRECT(count) ((u32)(count) | ((u32)(0x50) << 24))
77 #define PS2SS_VIF1_FIFO ((volatile u128 *)(0x10005000))
78 
79 // Internal convfunctions
80 
81 void ps2_screenshot_16to32_buffer(void *pTemp, u32 w, u32 h);
82 void ps2_screenshot_16to32_line(void *pTemp, u32 w);
83 
84 int ps2_screenshot_file( const char* pFilename,unsigned int VramAdress,
85  unsigned int Width, unsigned int Height, unsigned int Psm )
86 {
87  s32 file_handle;
88  u32 y;
89  static u32 in_buffer[1024 * 4]; // max 1024*32bit for a line, should be ok
90  static u32 out_buffer[1024 * 4]; // max 1024*32bit for a line, should be ok
91 
92  unsigned char header[18] =
93  {
94  0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
95  0, 0, // Width
96  0, 0, // Heigth
97  32, 8
98  };
99 
100  s16 *p_header = (s16 *)&header;
101 
102  file_handle = open( pFilename, O_CREAT|O_WRONLY );
103 
104  // make sure we could open the file for output
105 
106  if (file_handle < 0)
107  return 0;
108 
109  // setup tga header
110 
111  p_header[6] = (s16) Width;
112  p_header[7] = (s16) Height;
113 
114  write (file_handle, (void *)&header, 18);
115 
116  // Check if we have a tempbuffer, if we do we use it
117 
118  for (y = 0; y < Height; y++)
119  {
120  u32 *p_out = (u32 *)&out_buffer;
121  ps2_screenshot(in_buffer, VramAdress, 0, (Height - 1) - y, Width, 1, Psm);
122 
123  if (Psm == PS2SS_GSPSMCT16)
124  {
125  u32 x;
126  u16* p_in = (u16*)&in_buffer;
127 
128  for (x = 0; x < Width; x++)
129  {
130  u32 r = (p_in[x] & 31) << 3;
131  u32 g = ((p_in[x] >> 5) & 31) << 3;
132  u32 b = ((p_in[x] >> 10) & 31) << 3;
133  p_out[x] = (0xff<<24)|(r<<16)|(g<<8)|b;
134  }
135  }
136  else
137  if (Psm == PS2SS_GSPSMCT24)
138  {
139  u32 x;
140  u8* p_in = (u8*)&in_buffer;
141 
142  for( x = 0; x < Width; x++ )
143  {
144  u8 r = *p_in++;
145  u8 g = *p_in++;
146  u8 b = *p_in++;
147  p_out[x] = (0xff<<24)|(r<<16)|(g<<8)|b;
148  }
149  }
150  else
151  {
152  u8 *p_in = (u8 *) &in_buffer;
153  u32 x;
154 
155  for(x = 0; x < Width; x++)
156  {
157  u8 r = *p_in++;
158  u8 g = *p_in++;
159  u8 b = *p_in++;
160  u8 a = *p_in++;
161  p_out[x] = (a << 24) | (r << 16) | (g << 8) | b;
162  }
163  }
164 
165  write(file_handle, p_out, Width * 4);
166  }
167 
168  close(file_handle);
169 
170  return 0;
171 }
172 
181 int ps2_screenshot( void *pDest, unsigned int VramAdress, unsigned int x,
182  unsigned int y, unsigned int Width, unsigned int Height,
183  unsigned int Psm )
184 {
185  static union {
186  u32 value_u32[4];
187  u128 value;
188  } enable_path3 ALIGNED(16) = {
190  };
191 
192  u32 dma_chain[20*2] ALIGNED(16);
193  u32* p_dma32 = (u32*)&dma_chain;
194  u64 *p_dma64 = (u64*)(p_dma32 + 4);
195  u32 uQSize;
196  u32 prev_imr;
197  u32 prev_chcr;
198 
199  // Calc size depending on Psm
200 
201  if( Psm == PS2SS_GSPSMCT16 )
202  uQSize = ((Width*Height*2)/16);
203  else if( Psm == PS2SS_GSPSMCT24 )
204  uQSize = ((Width*Height*3)/16);
205  else
206  uQSize = (Width*Height*4)/16;
207 
208  // Setup transfer texture back to memory
209 
210  p_dma32[0] = PS2SS_VIF1_NOP;
211  p_dma32[1] = PS2SS_VIF1_MSKPATH3(0x8000);
212  p_dma32[2] = PS2SS_VIF1_FLUSHA;
213  p_dma32[3] = PS2SS_VIF1_DIRECT(6);
214 
215  // Setup the blit
216 
217  p_dma64[0] = PS2SS_GIFTAG(5, 1, 0, 0, 0, 1); // GIFTAG(NLOOP, EOP, PRE, PRIM, FLG, NREG)
218  p_dma64[1] = PS2SS_GIF_AD;
219 
220  p_dma64[2] = PS2SS_GSBITBLTBUF_SET(VramAdress, Width/64, Psm, 0, 0, Psm);
221  p_dma64[3] = PS2SS_GSBITBLTBUF;
222 
223  p_dma64[4] = PS2SS_GSTRXPOS_SET(x, y, 0, 0, 0); // SSAX, SSAY, DSAX, DSAY, DIR
224  p_dma64[5] = PS2SS_GSTRXPOS;
225 
226  p_dma64[6] = PS2SS_GSTRXREG_SET(Width, Height); // RRW, RRh
227  p_dma64[7] = PS2SS_GSTRXREG;
228 
229  p_dma64[8] = 0;
230  p_dma64[9] = PS2SS_GSFINISH;
231 
232  p_dma64[10] = PS2SS_GSTRXDIR_SET(1); // XDIR
233  p_dma64[11] = PS2SS_GSTRXDIR;
234 
235  prev_imr = GsPutIMR(GsGetIMR() | 0x0200);
236  prev_chcr = *PS2SS_D1_CHCR;
237 
238  if( (*PS2SS_D1_CHCR & 0x0100) != 0 )
239  return 0;
240 
241  // set the FINISH event
242 
244 
245  // DMA from memory and start DMA transfer
246 
247  FlushCache(0);
248 
249  *PS2SS_D1_QWC = 0x7;
250  *PS2SS_D1_MADR = (u32)p_dma32;
251  *PS2SS_D1_CHCR = 0x101;
252 
253  asm __volatile__("sync.l\n");
254 
255  // check if DMA is complete (STR=0)
256 
257  while( *PS2SS_D1_CHCR & 0x0100 );
258  while( ( *PS2SS_GS_CSR & PS2SS_CSR_FINISH ) == 0 );
259 
260  // Wait for viffifo to become empty
261 
262  while( (*PS2SS_VIF1_STAT & (0x1f000000) ) );
263 
264  // Reverse busdir and transfer image to host
265 
267  *PS2SS_GS_BUSDIR = (u64)0x00000001;
268 
269  FlushCache(0);
270 
271  *PS2SS_D1_QWC = uQSize;
272  *PS2SS_D1_MADR = (u32)pDest;
273  *PS2SS_D1_CHCR = 0x100;
274 
275  asm __volatile__(" sync.l\n");
276 
277  // check if DMA is complete (STR=0)
278 
279  while ( *PS2SS_D1_CHCR & 0x0100 );
280  *PS2SS_D1_CHCR = prev_chcr;
281  asm __volatile__(" sync.l\n");
282  *PS2SS_VIF1_STAT = 0;
283  *PS2SS_GS_BUSDIR = (u64)0;
284 
285  // Put back prew imr and set finish event
286 
287  GsPutIMR( prev_imr );
289 
290  // Enable path3 again
291 
292 
293  *PS2SS_VIF1_FIFO = enable_path3.value;
294 
295  return 1;
296 }
297 
300 void ps2_screenshot_16to32_line(void *pTemp, u32 w)
301 {
302 }
303 
306 void ps2_screenshot_16to32_buffer(void *pTemp, u32 w, u32 h)
307 {
308 }
309 
u64 GsGetIMR(void)
#define ALIGNED(x)
Definition: kernel.h:50
void FlushCache(s32 operation)
u64 GsPutIMR(u64 imr)
s32 x
Definition: libmouse.c:34
s32 y
Definition: libmouse.c:34
#define PS2SS_GSBITBLTBUF
Definition: screenshot.c:50
int ps2_screenshot(void *pDest, unsigned int VramAdress, unsigned int x, unsigned int y, unsigned int Width, unsigned int Height, unsigned int Psm)
Definition: screenshot.c:181
#define PS2SS_VIF1_STAT_FDR
Definition: screenshot.c:72
#define PS2SS_GSTRXREG_SET(rrw, rrh)
Definition: screenshot.c:40
#define PS2SS_GSTRXDIR_SET(xdr)
Definition: screenshot.c:48
#define PS2SS_GSTRXREG
Definition: screenshot.c:53
#define PS2SS_GS_CSR
Definition: screenshot.c:68
#define PS2SS_GIF_AD
Definition: screenshot.c:25
#define PS2SS_GSFINISH
Definition: screenshot.c:51
#define PS2SS_GS_BUSDIR
Definition: screenshot.c:69
#define PS2SS_D1_QWC
Definition: screenshot.c:62
#define PS2SS_D1_CHCR
Definition: screenshot.c:60
#define PS2SS_VIF1_FIFO
Definition: screenshot.c:77
#define PS2SS_GSTRXDIR
Definition: screenshot.c:54
#define PS2SS_GSPSMCT24
Definition: screenshot.c:57
#define PS2SS_VIF1_DIRECT(count)
Definition: screenshot.c:76
#define PS2SS_VIF1_STAT
Definition: screenshot.c:71
#define PS2SS_GSTRXPOS_SET(ssax, ssay, dsax, dsay, dir)
Definition: screenshot.c:43
int ps2_screenshot_file(const char *pFilename, unsigned int VramAdress, unsigned int Width, unsigned int Height, unsigned int Psm)
Definition: screenshot.c:84
#define PS2SS_GSPSMCT16
Definition: screenshot.c:58
#define PS2SS_GSBITBLTBUF_SET(sbp, sbw, spsm, dbp, dbw, dpsm)
Definition: screenshot.c:35
#define PS2SS_VIF1_NOP
Definition: screenshot.c:74
#define PS2SS_D1_MADR
Definition: screenshot.c:61
#define PS2SS_GIFTAG(NLOOP, EOP, PRE, PRIM, FLG, NREG)
Definition: screenshot.c:27
#define PS2SS_GSTRXPOS
Definition: screenshot.c:52
#define PS2SS_VIF1_MSKPATH3(mask)
Definition: screenshot.c:73
#define PS2SS_CSR_FINISH
Definition: screenshot.c:67
#define PS2SS_VIF1_FLUSHA
Definition: screenshot.c:75
void ps2_screenshot_16to32_buffer(void *pTemp, u32 w, u32 h)
Definition: screenshot.c:306
void ps2_screenshot_16to32_line(void *pTemp, u32 w)
Definition: screenshot.c:300
signed int s32
Definition: tamtypes.h:58
unsigned int u32
Definition: tamtypes.h:30
unsigned int u128
Definition: tamtypes.h:36
signed short s16
Definition: tamtypes.h:52
unsigned short u16
Definition: tamtypes.h:24
unsigned char u8
Definition: tamtypes.h:23
unsigned long u64
Definition: tamtypes.h:34