comparison src/video/ps2gs/SDL_gsvideo.c @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents 8d9bb0cf2c2a
children e1da92da346c
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
40 #include "SDL_gsevents_c.h" 40 #include "SDL_gsevents_c.h"
41 #include "SDL_gsyuv_c.h" 41 #include "SDL_gsyuv_c.h"
42 42
43 43
44 /* Initialization/Query functions */ 44 /* Initialization/Query functions */
45 static int GS_VideoInit(_THIS, SDL_PixelFormat *vformat); 45 static int GS_VideoInit(_THIS, SDL_PixelFormat * vformat);
46 static SDL_Rect **GS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); 46 static SDL_Rect **GS_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags);
47 static SDL_Surface *GS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); 47 static SDL_Surface *GS_SetVideoMode(_THIS, SDL_Surface * current, int width,
48 static int GS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); 48 int height, int bpp, Uint32 flags);
49 static int GS_SetColors(_THIS, int firstcolor, int ncolors,
50 SDL_Color * colors);
49 static void GS_VideoQuit(_THIS); 51 static void GS_VideoQuit(_THIS);
50 52
51 /* Hardware surface functions */ 53 /* Hardware surface functions */
52 static int GS_AllocHWSurface(_THIS, SDL_Surface *surface); 54 static int GS_AllocHWSurface(_THIS, SDL_Surface * surface);
53 static int GS_LockHWSurface(_THIS, SDL_Surface *surface); 55 static int GS_LockHWSurface(_THIS, SDL_Surface * surface);
54 static void GS_UnlockHWSurface(_THIS, SDL_Surface *surface); 56 static void GS_UnlockHWSurface(_THIS, SDL_Surface * surface);
55 static void GS_FreeHWSurface(_THIS, SDL_Surface *surface); 57 static void GS_FreeHWSurface(_THIS, SDL_Surface * surface);
56 58
57 /* GS driver bootstrap functions */ 59 /* GS driver bootstrap functions */
58 60
59 static int GS_Available(void) 61 static int
60 { 62 GS_Available(void)
61 int console, memory; 63 {
62 64 int console, memory;
63 console = open(PS2_DEV_GS, O_RDWR, 0); 65
64 if ( console >= 0 ) { 66 console = open(PS2_DEV_GS, O_RDWR, 0);
65 close(console); 67 if (console >= 0) {
66 } 68 close(console);
67 memory = open(PS2_DEV_MEM, O_RDWR, 0); 69 }
68 if ( memory >= 0 ) { 70 memory = open(PS2_DEV_MEM, O_RDWR, 0);
69 close(memory); 71 if (memory >= 0) {
70 } 72 close(memory);
71 return((console >= 0) && (memory >= 0)); 73 }
72 } 74 return ((console >= 0) && (memory >= 0));
73 75 }
74 static void GS_DeleteDevice(SDL_VideoDevice *device) 76
75 { 77 static void
76 SDL_free(device->hidden); 78 GS_DeleteDevice(SDL_VideoDevice * device)
77 SDL_free(device); 79 {
78 } 80 SDL_free(device->hidden);
79 81 SDL_free(device);
80 static SDL_VideoDevice *GS_CreateDevice(int devindex) 82 }
81 { 83
82 SDL_VideoDevice *this; 84 static SDL_VideoDevice *
83 85 GS_CreateDevice(int devindex)
84 /* Initialize all variables that we clean on shutdown */ 86 {
85 this = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); 87 SDL_VideoDevice *this;
86 if ( this ) { 88
87 SDL_memset(this, 0, (sizeof *this)); 89 /* Initialize all variables that we clean on shutdown */
88 this->hidden = (struct SDL_PrivateVideoData *) 90 this = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice));
89 SDL_malloc((sizeof *this->hidden)); 91 if (this) {
90 } 92 SDL_memset(this, 0, (sizeof *this));
91 if ( (this == NULL) || (this->hidden == NULL) ) { 93 this->hidden = (struct SDL_PrivateVideoData *)
92 SDL_OutOfMemory(); 94 SDL_malloc((sizeof *this->hidden));
93 if ( this ) { 95 }
94 SDL_free(this); 96 if ((this == NULL) || (this->hidden == NULL)) {
95 } 97 SDL_OutOfMemory();
96 return(0); 98 if (this) {
97 } 99 SDL_free(this);
98 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); 100 }
99 mouse_fd = -1; 101 return (0);
100 keyboard_fd = -1; 102 }
101 103 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
102 /* Set the function pointers */ 104 mouse_fd = -1;
103 this->VideoInit = GS_VideoInit; 105 keyboard_fd = -1;
104 this->ListModes = GS_ListModes; 106
105 this->SetVideoMode = GS_SetVideoMode; 107 /* Set the function pointers */
106 this->CreateYUVOverlay = GS_CreateYUVOverlay; 108 this->VideoInit = GS_VideoInit;
107 this->SetColors = GS_SetColors; 109 this->ListModes = GS_ListModes;
108 this->UpdateRects = NULL; 110 this->SetVideoMode = GS_SetVideoMode;
109 this->VideoQuit = GS_VideoQuit; 111 this->CreateYUVOverlay = GS_CreateYUVOverlay;
110 this->AllocHWSurface = GS_AllocHWSurface; 112 this->SetColors = GS_SetColors;
111 this->CheckHWBlit = NULL; 113 this->UpdateRects = NULL;
112 this->FillHWRect = NULL; 114 this->VideoQuit = GS_VideoQuit;
113 this->SetHWColorKey = NULL; 115 this->AllocHWSurface = GS_AllocHWSurface;
114 this->SetHWAlpha = NULL; 116 this->CheckHWBlit = NULL;
115 this->LockHWSurface = GS_LockHWSurface; 117 this->FillHWRect = NULL;
116 this->UnlockHWSurface = GS_UnlockHWSurface; 118 this->SetHWColorKey = NULL;
117 this->FlipHWSurface = NULL; 119 this->SetHWAlpha = NULL;
118 this->FreeHWSurface = GS_FreeHWSurface; 120 this->LockHWSurface = GS_LockHWSurface;
119 this->SetIcon = NULL; 121 this->UnlockHWSurface = GS_UnlockHWSurface;
120 this->SetCaption = NULL; 122 this->FlipHWSurface = NULL;
121 this->GetWMInfo = NULL; 123 this->FreeHWSurface = GS_FreeHWSurface;
122 this->FreeWMCursor = GS_FreeWMCursor; 124 this->SetIcon = NULL;
123 this->CreateWMCursor = GS_CreateWMCursor; 125 this->SetCaption = NULL;
124 this->ShowWMCursor = GS_ShowWMCursor; 126 this->GetWMInfo = NULL;
125 this->MoveWMCursor = GS_MoveWMCursor; 127 this->FreeWMCursor = GS_FreeWMCursor;
126 this->InitOSKeymap = GS_InitOSKeymap; 128 this->CreateWMCursor = GS_CreateWMCursor;
127 this->PumpEvents = GS_PumpEvents; 129 this->ShowWMCursor = GS_ShowWMCursor;
128 130 this->MoveWMCursor = GS_MoveWMCursor;
129 this->free = GS_DeleteDevice; 131 this->InitOSKeymap = GS_InitOSKeymap;
130 132 this->PumpEvents = GS_PumpEvents;
131 return this; 133
134 this->free = GS_DeleteDevice;
135
136 return this;
132 } 137 }
133 138
134 VideoBootStrap PS2GS_bootstrap = { 139 VideoBootStrap PS2GS_bootstrap = {
135 "ps2gs", "PlayStation 2 Graphics Synthesizer", 140 "ps2gs", "PlayStation 2 Graphics Synthesizer",
136 GS_Available, GS_CreateDevice 141 GS_Available, GS_CreateDevice
137 }; 142 };
138 143
139 /* These are the pixel formats for the 32, 24, and 16 bit video modes */ 144 /* These are the pixel formats for the 32, 24, and 16 bit video modes */
140 static struct { 145 static struct
141 int bpp; 146 {
142 Uint32 r; 147 int bpp;
143 Uint32 g; 148 Uint32 r;
144 Uint32 b; 149 Uint32 g;
150 Uint32 b;
145 } GS_pixelmasks[] = { 151 } GS_pixelmasks[] = {
146 { 32, 0x000000FF, /* RGB little-endian */ 152 {
147 0x0000FF00, 153 32, 0x000000FF, /* RGB little-endian */
148 0x00FF0000 }, 154 0x0000FF00, 0x00FF0000}, {
149 { 24, 0x000000FF, /* RGB little-endian */ 155 24, 0x000000FF, /* RGB little-endian */
150 0x0000FF00, 156 0x0000FF00, 0x00FF0000}, {
151 0x00FF0000 }, 157 16, 0x0000001f, /* RGB little-endian */
152 { 16, 0x0000001f, /* RGB little-endian */ 158 0x000003e0, 0x00007c00},};
153 0x000003e0, 159
154 0x00007c00 },
155 };
156 /* This is a mapping from SDL bytes-per-pixel to GS pixel format */ 160 /* This is a mapping from SDL bytes-per-pixel to GS pixel format */
157 static int GS_formatmap[] = { 161 static int GS_formatmap[] = {
158 -1, /* 0 bpp, not a legal value */ 162 -1, /* 0 bpp, not a legal value */
159 -1, /* 8 bpp, not supported (yet?) */ 163 -1, /* 8 bpp, not supported (yet?) */
160 PS2_GS_PSMCT16, /* 16 bpp */ 164 PS2_GS_PSMCT16, /* 16 bpp */
161 PS2_GS_PSMCT24, /* 24 bpp */ 165 PS2_GS_PSMCT24, /* 24 bpp */
162 PS2_GS_PSMCT32 /* 32 bpp */ 166 PS2_GS_PSMCT32 /* 32 bpp */
163 }; 167 };
164 168
165 static unsigned long long head_tags[] __attribute__((aligned(16))) = { 169 static unsigned long long head_tags[] __attribute__ ((aligned(16))) = {
166 4 | (1LL << 60), /* GIFtag */ 170 4 | (1LL << 60), /* GIFtag */
167 0x0e, /* A+D */ 171 0x0e, /* A+D */
168 0, /* 2 */ 172 0, /* 2 */
169 PS2_GS_BITBLTBUF, 173 PS2_GS_BITBLTBUF, 0, /* 4 */
170 0, /* 4 */ 174 PS2_GS_TRXPOS, 0, /* 6 */
171 PS2_GS_TRXPOS, 175 PS2_GS_TRXREG, 0, /* 8 */
172 0, /* 6 */ 176 PS2_GS_TRXDIR};
173 PS2_GS_TRXREG,
174 0, /* 8 */
175 PS2_GS_TRXDIR
176 };
177 177
178 #define MAXIMG (32767 * 16) 178 #define MAXIMG (32767 * 16)
179 #define MAXTAGS 8 179 #define MAXTAGS 8
180 180
181 static inline int loadimage_nonblock(int fd, struct ps2_image *image, int size, 181 static inline int
182 unsigned long long *hm, 182 loadimage_nonblock(int fd, struct ps2_image *image, int size,
183 unsigned long long *im) 183 unsigned long long *hm, unsigned long long *im)
184 { 184 {
185 struct ps2_plist plist; 185 struct ps2_plist plist;
186 struct ps2_packet packet[1 + MAXTAGS * 2]; 186 struct ps2_packet packet[1 + MAXTAGS * 2];
187 int isize; 187 int isize;
188 int pnum, it, eop; 188 int pnum, it, eop;
189 char *data; 189 char *data;
190 190
191 /* initialize the variables */ 191 /* initialize the variables */
192 data = (char *)image->ptr; 192 data = (char *) image->ptr;
193 pnum = it = eop = 0; 193 pnum = it = eop = 0;
194 plist.packet = packet; 194 plist.packet = packet;
195 195
196 /* make BITBLT packet */ 196 /* make BITBLT packet */
197 packet[pnum].ptr = hm; 197 packet[pnum].ptr = hm;
198 packet[pnum].len = sizeof(head_tags); 198 packet[pnum].len = sizeof(head_tags);
199 pnum++; 199 pnum++;
200 hm[2] = ((unsigned long long)image->fbp << 32) | 200 hm[2] = ((unsigned long long) image->fbp << 32) |
201 ((unsigned long long)image->fbw << 48) | 201 ((unsigned long long) image->fbw << 48) |
202 ((unsigned long long)image->psm << 56); 202 ((unsigned long long) image->psm << 56);
203 hm[4] = ((unsigned long long)image->x << 32) | 203 hm[4] = ((unsigned long long) image->x << 32) |
204 ((unsigned long long)image->y << 48); 204 ((unsigned long long) image->y << 48);
205 hm[6] = (unsigned long long)image->w | 205 hm[6] = (unsigned long long) image->w |
206 ((unsigned long long)image->h << 32); 206 ((unsigned long long) image->h << 32);
207 207
208 /* make image mode tags */ 208 /* make image mode tags */
209 while (!eop) { 209 while (!eop) {
210 isize = size > MAXIMG ? MAXIMG : size; 210 isize = size > MAXIMG ? MAXIMG : size;
211 size -= isize; 211 size -= isize;
212 eop = (size == 0); 212 eop = (size == 0);
213 213
214 packet[pnum].ptr = &im[it]; 214 packet[pnum].ptr = &im[it];
215 packet[pnum].len = sizeof(unsigned long long) * 2; 215 packet[pnum].len = sizeof(unsigned long long) * 2;
216 pnum++; 216 pnum++;
217 im[it++] = (isize >> 4) | (eop ? (1 << 15) : 0) | (2LL << 58); 217 im[it++] = (isize >> 4) | (eop ? (1 << 15) : 0) | (2LL << 58);
218 im[it++] = 0; 218 im[it++] = 0;
219 219
220 packet[pnum].ptr = (void *)data; 220 packet[pnum].ptr = (void *) data;
221 packet[pnum].len = isize; 221 packet[pnum].len = isize;
222 pnum++; 222 pnum++;
223 data += isize; 223 data += isize;
224 } 224 }
225 plist.num = pnum; 225 plist.num = pnum;
226 226
227 return ioctl(fd, PS2IOC_SENDL, &plist); 227 return ioctl(fd, PS2IOC_SENDL, &plist);
228 } 228 }
229 229
230 static unsigned long long tex_tags[] __attribute__((aligned(16))) = { 230 static unsigned long long tex_tags[] __attribute__ ((aligned(16))) = {
231 3 | (1LL << 60), /* GIFtag */ 231 3 | (1LL << 60), /* GIFtag */
232 0x0e, /* A+D */ 232 0x0e, /* A+D */
233 0, /* 2 */ 233 0, /* 2 */
234 PS2_GS_TEX0_1, 234 PS2_GS_TEX0_1, (1 << 5) + (1 << 6), PS2_GS_TEX1_1, 0, PS2_GS_TEXFLUSH};
235 (1 << 5) + (1 << 6), 235 static unsigned long long scale_tags[] __attribute__ ((aligned(16))) = {
236 PS2_GS_TEX1_1, 236 5 | (1LL << 60), /* GIFtag */
237 0, 237 0x0e, /* A+D */
238 PS2_GS_TEXFLUSH 238 6 + (1 << 4) + (1 << 8), PS2_GS_PRIM, ((unsigned long long) 0 * 16) + (((unsigned long long) 0 * 16) << 16), PS2_GS_UV, ((unsigned long long) 0 * 16) + (((unsigned long long) 0 * 16) << 16), PS2_GS_XYZ2, 0, /* 8 */
239 }; 239 PS2_GS_UV, 0, /* 10 */
240 static unsigned long long scale_tags[] __attribute__((aligned(16))) = { 240 PS2_GS_XYZ2};
241 5 | (1LL << 60), /* GIFtag */ 241
242 0x0e, /* A+D */ 242
243 6 + (1 << 4) + (1 << 8), 243 int
244 PS2_GS_PRIM, 244 scaleimage_nonblock(int fd, unsigned long long *tm, unsigned long long *sm)
245 ((unsigned long long)0 * 16) + (((unsigned long long)0 * 16) << 16), 245 {
246 PS2_GS_UV, 246 struct ps2_plist plist;
247 ((unsigned long long)0 * 16) + (((unsigned long long)0 * 16) << 16), 247 struct ps2_packet packet[2];
248 PS2_GS_XYZ2, 248
249 0, /* 8 */ 249 /* initialize the variables */
250 PS2_GS_UV, 250 plist.num = 2;
251 0, /* 10 */ 251 plist.packet = packet;
252 PS2_GS_XYZ2 252
253 }; 253 packet[0].ptr = tm;
254 254 packet[0].len = sizeof(tex_tags);
255 255 packet[1].ptr = sm;
256 int scaleimage_nonblock(int fd, unsigned long long *tm, unsigned long long *sm) 256 packet[1].len = sizeof(scale_tags);
257 { 257
258 struct ps2_plist plist; 258 return ioctl(fd, PS2IOC_SENDL, &plist);
259 struct ps2_packet packet[2]; 259 }
260 260
261 /* initialize the variables */ 261 static int
262 plist.num = 2; 262 power_of_2(int value)
263 plist.packet = packet; 263 {
264 264 int shift;
265 packet[0].ptr = tm; 265
266 packet[0].len = sizeof(tex_tags); 266 for (shift = 0; (1 << shift) < value; ++shift) {
267 packet[1].ptr = sm; 267 /* Keep looking */ ;
268 packet[1].len = sizeof(scale_tags); 268 }
269 269 return (shift);
270 return ioctl(fd, PS2IOC_SENDL, &plist); 270 }
271 } 271
272 272 static int
273 static int power_of_2(int value) 273 GS_VideoInit(_THIS, SDL_PixelFormat * vformat)
274 { 274 {
275 int shift; 275 struct ps2_screeninfo vinfo;
276 276
277 for ( shift = 0; (1<<shift) < value; ++shift ) { 277 /* Initialize the library */
278 /* Keep looking */ ; 278 console_fd = open(PS2_DEV_GS, O_RDWR, 0);
279 } 279 if (console_fd < 0) {
280 return(shift); 280 SDL_SetError("Unable to open %s", PS2_DEV_GS);
281 } 281 return (-1);
282 282 }
283 static int GS_VideoInit(_THIS, SDL_PixelFormat *vformat) 283 memory_fd = open(PS2_DEV_MEM, O_RDWR, 0);
284 { 284 if (memory_fd < 0) {
285 struct ps2_screeninfo vinfo; 285 close(console_fd);
286 286 console_fd = -1;
287 /* Initialize the library */ 287 SDL_SetError("Unable to open %s", PS2_DEV_MEM);
288 console_fd = open(PS2_DEV_GS, O_RDWR, 0); 288 return (-1);
289 if ( console_fd < 0 ) { 289 }
290 SDL_SetError("Unable to open %s", PS2_DEV_GS); 290
291 return(-1); 291 if (ioctl(console_fd, PS2IOC_GSCREENINFO, &vinfo) < 0) {
292 } 292 close(memory_fd);
293 memory_fd = open(PS2_DEV_MEM, O_RDWR, 0); 293 close(console_fd);
294 if ( memory_fd < 0 ) { 294 console_fd = -1;
295 close(console_fd); 295 SDL_SetError("Couldn't get console pixel format");
296 console_fd = -1; 296 return (-1);
297 SDL_SetError("Unable to open %s", PS2_DEV_MEM); 297 }
298 return(-1); 298
299 } 299 /* Determine the current screen size */
300 300 this->info.current_w = vinfo.w;
301 if ( ioctl(console_fd, PS2IOC_GSCREENINFO, &vinfo) < 0 ) { 301 this->info.current_h = vinfo.h;
302 close(memory_fd); 302
303 close(console_fd); 303 /* Determine the current screen depth */
304 console_fd = -1; 304 switch (vinfo.psm) {
305 SDL_SetError("Couldn't get console pixel format"); 305 /* Supported pixel formats */
306 return(-1); 306 case PS2_GS_PSMCT32:
307 } 307 case PS2_GS_PSMCT24:
308 308 case PS2_GS_PSMCT16:
309 /* Determine the current screen size */ 309 break;
310 this->info.current_w = vinfo.w; 310 default:
311 this->info.current_h = vinfo.h; 311 GS_VideoQuit(this);
312 312 SDL_SetError("Unknown console pixel format: %d", vinfo.psm);
313 /* Determine the current screen depth */ 313 return (-1);
314 switch (vinfo.psm) { 314 }
315 /* Supported pixel formats */ 315 vformat->BitsPerPixel = GS_pixelmasks[vinfo.psm].bpp;
316 case PS2_GS_PSMCT32: 316 vformat->Rmask = GS_pixelmasks[vinfo.psm].r;
317 case PS2_GS_PSMCT24: 317 vformat->Gmask = GS_pixelmasks[vinfo.psm].g;
318 case PS2_GS_PSMCT16: 318 vformat->Bmask = GS_pixelmasks[vinfo.psm].b;
319 break; 319 saved_vinfo = vinfo;
320 default: 320
321 GS_VideoQuit(this); 321 /* Enable mouse and keyboard support */
322 SDL_SetError("Unknown console pixel format: %d", vinfo.psm); 322 if (GS_OpenKeyboard(this) < 0) {
323 return(-1); 323 GS_VideoQuit(this);
324 } 324 SDL_SetError("Unable to open keyboard");
325 vformat->BitsPerPixel = GS_pixelmasks[vinfo.psm].bpp; 325 return (-1);
326 vformat->Rmask = GS_pixelmasks[vinfo.psm].r; 326 }
327 vformat->Gmask = GS_pixelmasks[vinfo.psm].g; 327 if (GS_OpenMouse(this) < 0) {
328 vformat->Bmask = GS_pixelmasks[vinfo.psm].b; 328 const char *sdl_nomouse;
329 saved_vinfo = vinfo; 329
330 330 sdl_nomouse = SDL_getenv("SDL_NOMOUSE");
331 /* Enable mouse and keyboard support */ 331 if (!sdl_nomouse) {
332 if ( GS_OpenKeyboard(this) < 0 ) { 332 GS_VideoQuit(this);
333 GS_VideoQuit(this); 333 SDL_SetError("Unable to open mouse");
334 SDL_SetError("Unable to open keyboard"); 334 return (-1);
335 return(-1); 335 }
336 } 336 }
337 if ( GS_OpenMouse(this) < 0 ) { 337
338 const char *sdl_nomouse; 338 /* We're done! */
339 339 return (0);
340 sdl_nomouse = SDL_getenv("SDL_NOMOUSE"); 340 }
341 if ( ! sdl_nomouse ) { 341
342 GS_VideoQuit(this); 342 static SDL_Rect **
343 SDL_SetError("Unable to open mouse"); 343 GS_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags)
344 return(-1); 344 {
345 } 345 static SDL_Rect GS_vesa_mode_list[] = {
346 } 346 {0, 0, 1280, 1024},
347 347 {0, 0, 1024, 768},
348 /* We're done! */ 348 {0, 0, 800, 600},
349 return(0); 349 {0, 0, 640, 480}
350 } 350 };
351 351 static SDL_Rect *GS_vesa_modes[] = {
352 static SDL_Rect **GS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) 352 &GS_vesa_mode_list[0],
353 { 353 &GS_vesa_mode_list[1],
354 static SDL_Rect GS_vesa_mode_list[] = { 354 &GS_vesa_mode_list[2],
355 { 0, 0, 1280, 1024 }, 355 &GS_vesa_mode_list[3],
356 { 0, 0, 1024, 768 }, 356 NULL
357 { 0, 0, 800, 600 }, 357 };
358 { 0, 0, 640, 480 } 358 static SDL_Rect GS_tvout_stretch;
359 }; 359 static SDL_Rect GS_tvout_mode;
360 static SDL_Rect *GS_vesa_modes[] = { 360 static SDL_Rect *GS_tvout_modes[3];
361 &GS_vesa_mode_list[0], 361 SDL_Rect **modes = NULL;
362 &GS_vesa_mode_list[1], 362
363 &GS_vesa_mode_list[2], 363 switch (format->BitsPerPixel) {
364 &GS_vesa_mode_list[3], 364 case 16:
365 NULL 365 case 24:
366 }; 366 case 32:
367 static SDL_Rect GS_tvout_stretch; 367 if (saved_vinfo.mode == PS2_GS_VESA) {
368 static SDL_Rect GS_tvout_mode; 368 modes = GS_vesa_modes;
369 static SDL_Rect *GS_tvout_modes[3]; 369 } else {
370 SDL_Rect **modes = NULL; 370 int i, j = 0;
371
372 switch (format->BitsPerPixel) {
373 case 16:
374 case 24:
375 case 32:
376 if ( saved_vinfo.mode == PS2_GS_VESA ) {
377 modes = GS_vesa_modes;
378 } else {
379 int i, j = 0;
380 371
381 // FIXME - what's wrong with the stretch code at 16 bpp? 372 // FIXME - what's wrong with the stretch code at 16 bpp?
382 if ( format->BitsPerPixel != 32 ) break; 373 if (format->BitsPerPixel != 32)
383 /* Add a mode that we could possibly stretch to */ 374 break;
384 for ( i=0; GS_vesa_modes[i]; ++i ) { 375 /* Add a mode that we could possibly stretch to */
385 if ( (GS_vesa_modes[i]->w == saved_vinfo.w) && 376 for (i = 0; GS_vesa_modes[i]; ++i) {
386 (GS_vesa_modes[i]->h != saved_vinfo.h) ) { 377 if ((GS_vesa_modes[i]->w == saved_vinfo.w) &&
387 GS_tvout_stretch.w=GS_vesa_modes[i]->w; 378 (GS_vesa_modes[i]->h != saved_vinfo.h)) {
388 GS_tvout_stretch.h=GS_vesa_modes[i]->h; 379 GS_tvout_stretch.w = GS_vesa_modes[i]->w;
389 GS_tvout_modes[j++] = &GS_tvout_stretch; 380 GS_tvout_stretch.h = GS_vesa_modes[i]->h;
390 break; 381 GS_tvout_modes[j++] = &GS_tvout_stretch;
391 } 382 break;
392 } 383 }
393 /* Add the current TV video mode */ 384 }
394 GS_tvout_mode.w = saved_vinfo.w; 385 /* Add the current TV video mode */
395 GS_tvout_mode.h = saved_vinfo.h; 386 GS_tvout_mode.w = saved_vinfo.w;
396 GS_tvout_modes[j++] = &GS_tvout_mode; 387 GS_tvout_mode.h = saved_vinfo.h;
397 GS_tvout_modes[j++] = NULL; 388 GS_tvout_modes[j++] = &GS_tvout_mode;
398 389 GS_tvout_modes[j++] = NULL;
399 /* Return the created list of modes */ 390
400 modes = GS_tvout_modes; 391 /* Return the created list of modes */
401 } 392 modes = GS_tvout_modes;
402 break; 393 }
403 default: 394 break;
404 break; 395 default:
405 } 396 break;
406 return(modes); 397 }
398 return (modes);
407 } 399 }
408 400
409 /* Various screen update functions available */ 401 /* Various screen update functions available */
410 static void GS_DMAFullUpdate(_THIS, int numrects, SDL_Rect *rects); 402 static void GS_DMAFullUpdate(_THIS, int numrects, SDL_Rect * rects);
411 403
412 static SDL_Surface *GS_SetVideoMode(_THIS, SDL_Surface *current, 404 static SDL_Surface *
413 int width, int height, int bpp, Uint32 flags) 405 GS_SetVideoMode(_THIS, SDL_Surface * current,
414 { 406 int width, int height, int bpp, Uint32 flags)
415 struct ps2_screeninfo vinfo; 407 {
416 408 struct ps2_screeninfo vinfo;
417 /* Set the terminal into graphics mode */ 409
418 if ( GS_EnterGraphicsMode(this) < 0 ) { 410 /* Set the terminal into graphics mode */
419 return(NULL); 411 if (GS_EnterGraphicsMode(this) < 0) {
420 } 412 return (NULL);
421 413 }
422 /* Set the video mode and get the final screen format */ 414
423 if ( ioctl(console_fd, PS2IOC_GSCREENINFO, &vinfo) < 0 ) { 415 /* Set the video mode and get the final screen format */
424 SDL_SetError("Couldn't get console screen info"); 416 if (ioctl(console_fd, PS2IOC_GSCREENINFO, &vinfo) < 0) {
425 return(NULL); 417 SDL_SetError("Couldn't get console screen info");
426 } 418 return (NULL);
427 if ( (vinfo.w != width) || (vinfo.h != height) || 419 }
428 (GS_pixelmasks[vinfo.psm].bpp != bpp) ) { 420 if ((vinfo.w != width) || (vinfo.h != height) ||
429 /* If we're not in VESA mode, we have to scale resolution */ 421 (GS_pixelmasks[vinfo.psm].bpp != bpp)) {
430 if ( saved_vinfo.mode == PS2_GS_VESA ) { 422 /* If we're not in VESA mode, we have to scale resolution */
431 switch (width) { 423 if (saved_vinfo.mode == PS2_GS_VESA) {
432 case 640: 424 switch (width) {
433 vinfo.res = PS2_GS_640x480; 425 case 640:
434 break; 426 vinfo.res = PS2_GS_640x480;
435 case 800: 427 break;
436 vinfo.res = PS2_GS_800x600; 428 case 800:
437 break; 429 vinfo.res = PS2_GS_800x600;
438 case 1024: 430 break;
439 vinfo.res = PS2_GS_1024x768; 431 case 1024:
440 break; 432 vinfo.res = PS2_GS_1024x768;
441 case 1280: 433 break;
442 vinfo.res = PS2_GS_1280x1024; 434 case 1280:
443 break; 435 vinfo.res = PS2_GS_1280x1024;
444 default: 436 break;
445 SDL_SetError("Unsupported resolution: %dx%d\n", 437 default:
446 width, height); 438 SDL_SetError("Unsupported resolution: %dx%d\n",
447 return(NULL); 439 width, height);
448 } 440 return (NULL);
449 vinfo.res |= (PS2_GS_75Hz << 8); 441 }
450 vinfo.w = width; 442 vinfo.res |= (PS2_GS_75Hz << 8);
451 vinfo.h = height; 443 vinfo.w = width;
452 } 444 vinfo.h = height;
453 vinfo.fbp = 0; 445 }
454 vinfo.psm = GS_formatmap[bpp/8]; 446 vinfo.fbp = 0;
455 if ( vinfo.psm < 0 ) { 447 vinfo.psm = GS_formatmap[bpp / 8];
456 SDL_SetError("Unsupported depth: %d bpp\n", bpp); 448 if (vinfo.psm < 0) {
457 return(NULL); 449 SDL_SetError("Unsupported depth: %d bpp\n", bpp);
458 } 450 return (NULL);
459 if ( ioctl(console_fd, PS2IOC_SSCREENINFO, &vinfo) < 0 ) { 451 }
460 SDL_SetError("Couldn't set console screen info"); 452 if (ioctl(console_fd, PS2IOC_SSCREENINFO, &vinfo) < 0) {
461 return(NULL); 453 SDL_SetError("Couldn't set console screen info");
462 } 454 return (NULL);
463 455 }
464 /* Unmap the previous DMA buffer */ 456
465 if ( mapped_mem ) { 457 /* Unmap the previous DMA buffer */
466 munmap(mapped_mem, mapped_len); 458 if (mapped_mem) {
467 mapped_mem = NULL; 459 munmap(mapped_mem, mapped_len);
468 } 460 mapped_mem = NULL;
469 } 461 }
470 if ( ! SDL_ReallocFormat(current, GS_pixelmasks[vinfo.psm].bpp, 462 }
471 GS_pixelmasks[vinfo.psm].r, 463 if (!SDL_ReallocFormat(current, GS_pixelmasks[vinfo.psm].bpp,
472 GS_pixelmasks[vinfo.psm].g, 464 GS_pixelmasks[vinfo.psm].r,
473 GS_pixelmasks[vinfo.psm].b, 0) ) { 465 GS_pixelmasks[vinfo.psm].g,
474 return(NULL); 466 GS_pixelmasks[vinfo.psm].b, 0)) {
475 } 467 return (NULL);
476 468 }
477 /* Set up the new mode framebuffer */ 469
478 current->flags = SDL_FULLSCREEN; 470 /* Set up the new mode framebuffer */
479 current->w = width; 471 current->flags = SDL_FULLSCREEN;
480 current->h = height; 472 current->w = width;
481 current->pitch = SDL_CalculatePitch(current); 473 current->h = height;
482 474 current->pitch = SDL_CalculatePitch(current);
483 /* Memory map the DMA area for block memory transfer */ 475
484 if ( ! mapped_mem ) { 476 /* Memory map the DMA area for block memory transfer */
485 pixels_len = height * current->pitch; 477 if (!mapped_mem) {
486 mapped_len = pixels_len + 478 pixels_len = height * current->pitch;
487 /* Screen update DMA command area */ 479 mapped_len = pixels_len +
488 sizeof(head_tags) + ((2 * MAXTAGS) * 16); 480 /* Screen update DMA command area */
489 if ( saved_vinfo.mode != PS2_GS_VESA ) { 481 sizeof(head_tags) + ((2 * MAXTAGS) * 16);
490 mapped_len += sizeof(tex_tags) + sizeof(scale_tags); 482 if (saved_vinfo.mode != PS2_GS_VESA) {
491 } 483 mapped_len += sizeof(tex_tags) + sizeof(scale_tags);
492 mapped_mem = mmap(0, mapped_len, PROT_READ|PROT_WRITE, 484 }
493 MAP_SHARED, memory_fd, 0); 485 mapped_mem = mmap(0, mapped_len, PROT_READ | PROT_WRITE,
494 if ( mapped_mem == MAP_FAILED ) { 486 MAP_SHARED, memory_fd, 0);
495 SDL_SetError("Unable to map %d bytes for DMA", 487 if (mapped_mem == MAP_FAILED) {
496 mapped_len); 488 SDL_SetError("Unable to map %d bytes for DMA", mapped_len);
497 mapped_mem = NULL; 489 mapped_mem = NULL;
498 return(NULL); 490 return (NULL);
499 } 491 }
500 492
501 /* Set up the entire screen for DMA transfer */ 493 /* Set up the entire screen for DMA transfer */
502 screen_image.ptr = mapped_mem; 494 screen_image.ptr = mapped_mem;
503 screen_image.fbp = 0; 495 screen_image.fbp = 0;
504 screen_image.fbw = (vinfo.w + 63) / 64; 496 screen_image.fbw = (vinfo.w + 63) / 64;
505 screen_image.psm = vinfo.psm; 497 screen_image.psm = vinfo.psm;
506 screen_image.x = 0; 498 screen_image.x = 0;
507 if ( vinfo.h == height ) { 499 if (vinfo.h == height) {
508 screen_image.y = 0; 500 screen_image.y = 0;
509 } else { 501 } else {
510 /* Put image offscreen and scale to screen height */ 502 /* Put image offscreen and scale to screen height */
511 screen_image.y = vinfo.h; 503 screen_image.y = vinfo.h;
512 } 504 }
513 screen_image.w = current->w; 505 screen_image.w = current->w;
514 screen_image.h = current->h; 506 screen_image.h = current->h;
515 507
516 /* get screen image data size (qword aligned) */ 508 /* get screen image data size (qword aligned) */
517 screen_image_size = (screen_image.w * screen_image.h); 509 screen_image_size = (screen_image.w * screen_image.h);
518 switch (screen_image.psm) { 510 switch (screen_image.psm) {
519 case PS2_GS_PSMCT32: 511 case PS2_GS_PSMCT32:
520 screen_image_size *= 4; 512 screen_image_size *= 4;
521 break; 513 break;
522 case PS2_GS_PSMCT24: 514 case PS2_GS_PSMCT24:
523 screen_image_size *= 3; 515 screen_image_size *= 3;
524 break; 516 break;
525 case PS2_GS_PSMCT16: 517 case PS2_GS_PSMCT16:
526 screen_image_size *= 2; 518 screen_image_size *= 2;
527 break; 519 break;
528 } 520 }
529 screen_image_size = (screen_image_size + 15) & ~15; 521 screen_image_size = (screen_image_size + 15) & ~15;
530 522
531 /* Set up the memory for screen update DMA commands */ 523 /* Set up the memory for screen update DMA commands */
532 head_tags_mem = (unsigned long long *) 524 head_tags_mem = (unsigned long long *) (mapped_mem + pixels_len);
533 (mapped_mem + pixels_len); 525 image_tags_mem = (unsigned long long *)
534 image_tags_mem = (unsigned long long *) 526 ((caddr_t) head_tags_mem + sizeof(head_tags));
535 ((caddr_t)head_tags_mem + sizeof(head_tags)); 527 SDL_memcpy(head_tags_mem, head_tags, sizeof(head_tags));
536 SDL_memcpy(head_tags_mem, head_tags, sizeof(head_tags)); 528 if (saved_vinfo.mode != PS2_GS_VESA) {
537 if ( saved_vinfo.mode != PS2_GS_VESA ) { 529 tex_tags_mem = (unsigned long long *)
538 tex_tags_mem = (unsigned long long *) 530 ((caddr_t) image_tags_mem + ((2 * MAXTAGS) * 16));
539 ((caddr_t)image_tags_mem + ((2*MAXTAGS)*16)); 531 scale_tags_mem = (unsigned long long *)
540 scale_tags_mem = (unsigned long long *) 532 ((caddr_t) tex_tags_mem + sizeof(tex_tags));
541 ((caddr_t)tex_tags_mem + sizeof(tex_tags)); 533 SDL_memcpy(tex_tags_mem, tex_tags, sizeof(tex_tags));
542 SDL_memcpy(tex_tags_mem, tex_tags, sizeof(tex_tags)); 534 tex_tags_mem[2] =
543 tex_tags_mem[2] = 535 (vinfo.h * vinfo.w) / 64 +
544 (vinfo.h * vinfo.w) / 64 + 536 ((unsigned long long) screen_image.fbw << 14) +
545 ((unsigned long long)screen_image.fbw << 14) + 537 ((unsigned long long) screen_image.psm << 20) +
546 ((unsigned long long)screen_image.psm << 20) + 538 ((unsigned long long) power_of_2(screen_image.w) << 26) +
547 ((unsigned long long)power_of_2(screen_image.w) << 26) + 539 ((unsigned long long) power_of_2(screen_image.h) << 30) +
548 ((unsigned long long)power_of_2(screen_image.h) << 30) + 540 ((unsigned long long) 1 << 34) +
549 ((unsigned long long)1 << 34) + 541 ((unsigned long long) 1 << 35);
550 ((unsigned long long)1 << 35); 542 SDL_memcpy(scale_tags_mem, scale_tags, sizeof(scale_tags));
551 SDL_memcpy(scale_tags_mem, scale_tags, sizeof(scale_tags)); 543 scale_tags_mem[8] =
552 scale_tags_mem[8] = 544 ((unsigned long long) screen_image.w * 16) +
553 ((unsigned long long)screen_image.w * 16) + 545 (((unsigned long long) screen_image.h * 16) << 16);
554 (((unsigned long long)screen_image.h * 16) << 16); 546 scale_tags_mem[10] =
555 scale_tags_mem[10] = 547 ((unsigned long long) vinfo.w * 16) +
556 ((unsigned long long)vinfo.w * 16) + 548 (((unsigned long long) vinfo.h * 16) << 16);
557 (((unsigned long long)vinfo.h * 16) << 16); 549 }
558 } 550 }
559 } 551 current->pixels = NULL;
560 current->pixels = NULL; 552 if (SDL_getenv("SDL_FULLSCREEN_UPDATE")) {
561 if ( SDL_getenv("SDL_FULLSCREEN_UPDATE") ) { 553 /* Correct semantics */
562 /* Correct semantics */ 554 current->flags |= SDL_ASYNCBLIT;
563 current->flags |= SDL_ASYNCBLIT; 555 } else {
564 } else { 556 /* We lie here - the screen memory isn't really the visible
565 /* We lie here - the screen memory isn't really the visible 557 display memory and still requires an update, but this
566 display memory and still requires an update, but this 558 has the desired effect for most applications.
567 has the desired effect for most applications. 559 */
568 */ 560 current->flags |= SDL_HWSURFACE;
569 current->flags |= SDL_HWSURFACE; 561 }
570 } 562
571 563 /* Set the update rectangle function */
572 /* Set the update rectangle function */ 564 this->UpdateRects = GS_DMAFullUpdate;
573 this->UpdateRects = GS_DMAFullUpdate; 565
574 566 /* We're done */
575 /* We're done */ 567 return (current);
576 return(current);
577 } 568 }
578 569
579 /* We don't support hardware surfaces yet */ 570 /* We don't support hardware surfaces yet */
580 static int GS_AllocHWSurface(_THIS, SDL_Surface *surface) 571 static int
581 { 572 GS_AllocHWSurface(_THIS, SDL_Surface * surface)
582 return(-1); 573 {
583 } 574 return (-1);
584 static void GS_FreeHWSurface(_THIS, SDL_Surface *surface) 575 }
585 { 576 static void
586 return; 577 GS_FreeHWSurface(_THIS, SDL_Surface * surface)
587 } 578 {
588 static int GS_LockHWSurface(_THIS, SDL_Surface *surface) 579 return;
589 { 580 }
590 if ( surface == this->screen ) { 581 static int
591 /* Since mouse motion affects 'pixels', lock it */ 582 GS_LockHWSurface(_THIS, SDL_Surface * surface)
592 SDL_LockCursor(); 583 {
593 584 if (surface == this->screen) {
594 /* Make sure any pending DMA has completed */ 585 /* Since mouse motion affects 'pixels', lock it */
595 if ( dma_pending ) { 586 SDL_LockCursor();
596 ioctl(console_fd, PS2IOC_SENDQCT, 1); 587
597 dma_pending = 0; 588 /* Make sure any pending DMA has completed */
598 } 589 if (dma_pending) {
599 590 ioctl(console_fd, PS2IOC_SENDQCT, 1);
600 /* If the cursor is drawn on the DMA area, remove it */ 591 dma_pending = 0;
601 if ( cursor_drawn ) { 592 }
602 surface->pixels = mapped_mem + surface->offset; 593
603 SDL_EraseCursorNoLock(this->screen); 594 /* If the cursor is drawn on the DMA area, remove it */
604 cursor_drawn = 0; 595 if (cursor_drawn) {
605 } 596 surface->pixels = mapped_mem + surface->offset;
606 597 SDL_EraseCursorNoLock(this->screen);
607 /* Set the surface pixels to the base of the DMA area */ 598 cursor_drawn = 0;
608 surface->pixels = mapped_mem; 599 }
609 600
610 /* We're finished! */ 601 /* Set the surface pixels to the base of the DMA area */
611 SDL_UnlockCursor(); 602 surface->pixels = mapped_mem;
612 } 603
613 return(0); 604 /* We're finished! */
614 } 605 SDL_UnlockCursor();
615 static void GS_UnlockHWSurface(_THIS, SDL_Surface *surface) 606 }
616 { 607 return (0);
617 if ( surface == this->screen ) { 608 }
618 /* Since mouse motion affects 'pixels', lock it */ 609 static void
619 SDL_LockCursor(); 610 GS_UnlockHWSurface(_THIS, SDL_Surface * surface)
620 surface->pixels = NULL; 611 {
621 SDL_UnlockCursor(); 612 if (surface == this->screen) {
622 } 613 /* Since mouse motion affects 'pixels', lock it */
623 } 614 SDL_LockCursor();
624 615 surface->pixels = NULL;
625 static void GS_DMAFullUpdate(_THIS, int numrects, SDL_Rect *rects) 616 SDL_UnlockCursor();
626 { 617 }
627 /* Lock so we aren't interrupted by a mouse update */ 618 }
628 SDL_LockCursor(); 619
629 620 static void
630 /* Make sure any pending DMA has completed */ 621 GS_DMAFullUpdate(_THIS, int numrects, SDL_Rect * rects)
631 if ( dma_pending ) { 622 {
632 ioctl(console_fd, PS2IOC_SENDQCT, 1); 623 /* Lock so we aren't interrupted by a mouse update */
633 dma_pending = 0; 624 SDL_LockCursor();
634 } 625
635 626 /* Make sure any pending DMA has completed */
636 /* If the mouse is visible, draw it on the DMA area */ 627 if (dma_pending) {
637 if ( (SDL_cursorstate & CURSOR_VISIBLE) && !cursor_drawn ) { 628 ioctl(console_fd, PS2IOC_SENDQCT, 1);
638 this->screen->pixels = mapped_mem + this->screen->offset; 629 dma_pending = 0;
639 SDL_DrawCursorNoLock(this->screen); 630 }
640 this->screen->pixels = NULL; 631
641 cursor_drawn = 1; 632 /* If the mouse is visible, draw it on the DMA area */
642 } 633 if ((SDL_cursorstate & CURSOR_VISIBLE) && !cursor_drawn) {
643 634 this->screen->pixels = mapped_mem + this->screen->offset;
644 /* Put the image onto the screen */ 635 SDL_DrawCursorNoLock(this->screen);
645 loadimage_nonblock(console_fd, 636 this->screen->pixels = NULL;
646 &screen_image, screen_image_size, 637 cursor_drawn = 1;
647 head_tags_mem, image_tags_mem); 638 }
648 if ( screen_image.y > 0 ) { 639
649 /* Need to scale offscreen image to TV output */ 640 /* Put the image onto the screen */
650 ioctl(console_fd, PS2IOC_SENDQCT, 1); 641 loadimage_nonblock(console_fd,
651 dma_pending = 0; 642 &screen_image, screen_image_size,
652 scaleimage_nonblock(console_fd, tex_tags_mem, scale_tags_mem); 643 head_tags_mem, image_tags_mem);
653 } else { 644 if (screen_image.y > 0) {
654 dma_pending = 1; 645 /* Need to scale offscreen image to TV output */
655 } 646 ioctl(console_fd, PS2IOC_SENDQCT, 1);
656 647 dma_pending = 0;
657 /* We're finished! */ 648 scaleimage_nonblock(console_fd, tex_tags_mem, scale_tags_mem);
658 SDL_UnlockCursor(); 649 } else {
659 } 650 dma_pending = 1;
660 651 }
661 static int GS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) 652
662 { 653 /* We're finished! */
663 return(0); 654 SDL_UnlockCursor();
664 } 655 }
665 656
666 static void GS_VideoQuit(_THIS) 657 static int
667 { 658 GS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors)
668 /* Close console and input file descriptors */ 659 {
669 if ( console_fd > 0 ) { 660 return (0);
670 /* Unmap the video framebuffer */ 661 }
671 if ( mapped_mem ) { 662
672 /* Unmap the video framebuffer */ 663 static void
673 munmap(mapped_mem, mapped_len); 664 GS_VideoQuit(_THIS)
674 mapped_mem = NULL; 665 {
675 } 666 /* Close console and input file descriptors */
676 close(memory_fd); 667 if (console_fd > 0) {
677 668 /* Unmap the video framebuffer */
678 /* Restore the original video mode */ 669 if (mapped_mem) {
679 if ( GS_InGraphicsMode(this) ) { 670 /* Unmap the video framebuffer */
680 ioctl(console_fd, PS2IOC_SSCREENINFO, &saved_vinfo); 671 munmap(mapped_mem, mapped_len);
681 } 672 mapped_mem = NULL;
682 673 }
683 /* We're all done with the graphics device */ 674 close(memory_fd);
684 close(console_fd); 675
685 console_fd = -1; 676 /* Restore the original video mode */
686 } 677 if (GS_InGraphicsMode(this)) {
687 GS_CloseMouse(this); 678 ioctl(console_fd, PS2IOC_SSCREENINFO, &saved_vinfo);
688 GS_CloseKeyboard(this); 679 }
689 } 680
681 /* We're all done with the graphics device */
682 close(console_fd);
683 console_fd = -1;
684 }
685 GS_CloseMouse(this);
686 GS_CloseKeyboard(this);
687 }
688
689 /* vi: set ts=4 sw=4 expandtab: */