comparison src/video/ps2gs/SDL_gsvideo.c @ 1662:782fd950bd46 SDL-1.3

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