Mercurial > sdl-ios-xcode
comparison src/video/gem/SDL_gemvideo.c @ 2189:f54670a477bb
Update GEM driver to new API, will have to fill the void later :)
author | Patrice Mandin <patmandin@gmail.com> |
---|---|
date | Fri, 13 Jul 2007 22:55:15 +0000 |
parents | 2c835d58faad |
children | 7e1caa8452f3 |
comparison
equal
deleted
inserted
replaced
2188:0e751c1f83f5 | 2189:f54670a477bb |
---|---|
33 #include <gem.h> | 33 #include <gem.h> |
34 #include <gemx.h> | 34 #include <gemx.h> |
35 #include <mint/osbind.h> | 35 #include <mint/osbind.h> |
36 #include <mint/cookie.h> | 36 #include <mint/cookie.h> |
37 | 37 |
38 #include "SDL_endian.h" | |
39 #include "SDL_video.h" | 38 #include "SDL_video.h" |
40 #include "SDL_mouse.h" | 39 #include "SDL_mouse.h" |
41 #include "../SDL_sysvideo.h" | 40 #include "../SDL_sysvideo.h" |
42 #include "../SDL_pixels_c.h" | 41 #include "../SDL_pixels_c.h" |
43 #include "../../events/SDL_events_c.h" | |
44 #include "../SDL_cursor_c.h" | |
45 | |
46 #include "../ataricommon/SDL_ataric2p_s.h" | |
47 #include "../ataricommon/SDL_atarieddi_s.h" | |
48 #include "../ataricommon/SDL_atarimxalloc_c.h" | |
49 #include "../ataricommon/SDL_atarigl_c.h" | |
50 | 42 |
51 #include "SDL_gemvideo.h" | 43 #include "SDL_gemvideo.h" |
52 #include "SDL_gemevents_c.h" | |
53 #include "SDL_gemmouse_c.h" | |
54 #include "SDL_gemwm_c.h" | |
55 #include "../ataricommon/SDL_xbiosevents_c.h" | |
56 #include "../ataricommon/SDL_ataridevmouse_c.h" | |
57 | |
58 /* Defines */ | |
59 | |
60 /*#define DEBUG_VIDEO_GEM 1*/ | |
61 | |
62 #define GEM_VID_DRIVER_NAME "gem" | |
63 | |
64 #undef MIN | |
65 #define MIN(a,b) (((a)<(b)) ? (a) : (b)) | |
66 #undef MAX | |
67 #define MAX(a,b) (((a)>(b)) ? (a) : (b)) | |
68 | |
69 /* Variables */ | |
70 | |
71 static unsigned char vdi_index[256] = { | |
72 0, 2, 3, 6, 4, 7, 5, 8, | |
73 9, 10, 11, 14, 12, 15, 13, 255 | |
74 }; | |
75 | |
76 static const unsigned char empty_name[] = ""; | |
77 | 44 |
78 /* Initialization/Query functions */ | 45 /* Initialization/Query functions */ |
79 static int GEM_VideoInit(_THIS, SDL_PixelFormat * vformat); | 46 static int GEM_VideoInit(_THIS); |
80 static SDL_Rect **GEM_ListModes(_THIS, SDL_PixelFormat * format, | |
81 Uint32 flags); | |
82 static SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface * current, int width, | |
83 int height, int bpp, Uint32 flags); | |
84 static int GEM_SetColors(_THIS, int firstcolor, int ncolors, | |
85 SDL_Color * colors); | |
86 static void GEM_VideoQuit(_THIS); | 47 static void GEM_VideoQuit(_THIS); |
87 | 48 |
88 /* Hardware surface functions */ | |
89 static int GEM_AllocHWSurface(_THIS, SDL_Surface * surface); | |
90 static int GEM_LockHWSurface(_THIS, SDL_Surface * surface); | |
91 static int GEM_FlipHWSurface(_THIS, SDL_Surface * surface); | |
92 static void GEM_UnlockHWSurface(_THIS, SDL_Surface * surface); | |
93 static void GEM_FreeHWSurface(_THIS, SDL_Surface * surface); | |
94 static void GEM_UpdateRects(_THIS, int numrects, SDL_Rect * rects); | |
95 #if 0 | |
96 static int GEM_ToggleFullScreen(_THIS, int on); | |
97 #endif | |
98 | |
99 /* Internal functions */ | |
100 static void GEM_FreeBuffers(_THIS); | |
101 static void GEM_ClearScreen(_THIS); | |
102 static void GEM_ClearRect(_THIS, short *rect); | |
103 static void GEM_SetNewPalette(_THIS, Uint16 newpal[256][3]); | |
104 static void GEM_LockScreen(_THIS); | |
105 static void GEM_UnlockScreen(_THIS); | |
106 static void refresh_window(_THIS, int winhandle, short *rect); | |
107 | |
108 #if SDL_VIDEO_OPENGL | |
109 /* OpenGL functions */ | |
110 static void GEM_GL_SwapBuffers(_THIS); | 49 static void GEM_GL_SwapBuffers(_THIS); |
111 #endif | 50 |
112 | |
113 /* GEM driver bootstrap functions */ | |
114 | 51 |
115 static int | 52 static int |
116 GEM_Available(void) | 53 GEM_Available(void) |
117 { | 54 { |
118 /* Test if AES available */ | 55 /* Test if AES available */ |
124 } | 61 } |
125 | 62 |
126 static void | 63 static void |
127 GEM_DeleteDevice(SDL_VideoDevice * device) | 64 GEM_DeleteDevice(SDL_VideoDevice * device) |
128 { | 65 { |
129 SDL_free(device->hidden); | 66 SDL_VideoData *data = (SDL_VideoData *) device->driverdata; |
67 | |
68 SDL_free(device->driverdata); | |
130 SDL_free(device); | 69 SDL_free(device); |
131 } | 70 } |
132 | 71 |
133 static SDL_VideoDevice * | 72 static SDL_VideoDevice * |
134 GEM_CreateDevice(int devindex) | 73 GEM_CreateDevice(int devindex) |
135 { | 74 { |
136 SDL_VideoDevice *device; | 75 SDL_VideoDevice *device; |
137 int vectors_mask; | 76 SDL_VideoData *data; |
138 unsigned long dummy; | |
139 | 77 |
140 /* Initialize all variables that we clean on shutdown */ | 78 /* Initialize all variables that we clean on shutdown */ |
141 device = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice)); | 79 device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); |
142 if (device) { | 80 if (device) { |
143 SDL_memset(device, 0, (sizeof *device)); | 81 data = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); |
144 device->hidden = (struct SDL_PrivateVideoData *) | 82 } |
145 SDL_malloc((sizeof *device->hidden)); | 83 if (!device || !data) { |
146 device->gl_data = (struct SDL_PrivateGLData *) | |
147 SDL_malloc((sizeof *device->gl_data)); | |
148 } | |
149 if ((device == NULL) || (device->hidden == NULL)) { | |
150 SDL_OutOfMemory(); | 84 SDL_OutOfMemory(); |
151 if (device) { | 85 if (device) { |
152 SDL_free(device); | 86 SDL_free(device); |
153 } | 87 } |
154 return (0); | 88 return NULL; |
155 } | 89 } |
156 SDL_memset(device->hidden, 0, (sizeof *device->hidden)); | 90 device->driverdata = data; |
157 SDL_memset(device->gl_data, 0, sizeof(*device->gl_data)); | |
158 | 91 |
159 /* Set the function pointers */ | 92 /* Set the function pointers */ |
160 device->VideoInit = GEM_VideoInit; | 93 device->VideoInit = GEM_VideoInit; |
161 device->ListModes = GEM_ListModes; | |
162 device->SetVideoMode = GEM_SetVideoMode; | |
163 device->SetColors = GEM_SetColors; | |
164 device->UpdateRects = NULL /*GEM_UpdateRects */ ; | |
165 device->VideoQuit = GEM_VideoQuit; | 94 device->VideoQuit = GEM_VideoQuit; |
166 device->AllocHWSurface = GEM_AllocHWSurface; | 95 device->GetDisplayModes = GEM_GetDisplayModes; |
167 device->LockHWSurface = GEM_LockHWSurface; | 96 device->SetDisplayMode = GEM_SetDisplayMode; |
168 device->UnlockHWSurface = GEM_UnlockHWSurface; | |
169 device->FlipHWSurface = GEM_FlipHWSurface; | |
170 device->FreeHWSurface = GEM_FreeHWSurface; | |
171 device->ToggleFullScreen = NULL /*GEM_ToggleFullScreen */ ; | |
172 | |
173 /* Window manager */ | |
174 device->SetCaption = GEM_SetCaption; | |
175 device->SetIcon = GEM_SetIcon; | |
176 device->IconifyWindow = GEM_IconifyWindow; | |
177 device->GrabInput = GEM_GrabInput; | |
178 | |
179 /* Events */ | |
180 device->InitOSKeymap = GEM_InitOSKeymap; | |
181 device->PumpEvents = GEM_PumpEvents; | 97 device->PumpEvents = GEM_PumpEvents; |
182 | 98 |
183 /* Mouse */ | 99 device->CreateWindow = GEM_CreateWindow; |
184 device->FreeWMCursor = GEM_FreeWMCursor; | 100 device->CreateWindowFrom = GEM_CreateWindowFrom; |
185 device->CreateWMCursor = GEM_CreateWMCursor; | 101 device->SetWindowTitle = GEM_SetWindowTitle; |
186 device->ShowWMCursor = GEM_ShowWMCursor; | 102 device->SetWindowPosition = GEM_SetWindowPosition; |
187 device->WarpWMCursor = NULL /*GEM_WarpWMCursor */ ; | 103 device->SetWindowSize = GEM_SetWindowSize; |
188 device->CheckMouseMode = GEM_CheckMouseMode; | 104 device->ShowWindow = GEM_ShowWindow; |
105 device->HideWindow = GEM_HideWindow; | |
106 device->RaiseWindow = GEM_RaiseWindow; | |
107 device->MaximizeWindow = GEM_MaximizeWindow; | |
108 device->MinimizeWindow = GEM_MinimizeWindow; | |
109 device->RestoreWindow = GEM_RestoreWindow; | |
110 device->SetWindowGrab = GEM_SetWindowGrab; | |
111 device->DestroyWindow = GEM_DestroyWindow; | |
112 device->GetWindowWMInfo = GEM_GetWindowWMInfo; | |
189 | 113 |
190 #if SDL_VIDEO_OPENGL | 114 #if SDL_VIDEO_OPENGL |
191 /* OpenGL functions */ | |
192 device->GL_LoadLibrary = SDL_AtariGL_LoadLibrary; | 115 device->GL_LoadLibrary = SDL_AtariGL_LoadLibrary; |
193 device->GL_GetProcAddress = SDL_AtariGL_GetProcAddress; | 116 device->GL_GetProcAddress = SDL_AtariGL_GetProcAddress; |
194 device->GL_GetAttribute = SDL_AtariGL_GetAttribute; | 117 device->GL_CreateContext = SDL_AtariGL_CreateContext; |
195 device->GL_MakeCurrent = SDL_AtariGL_MakeCurrent; | 118 device->GL_MakeCurrent = SDL_AtariGL_MakeCurrent; |
196 device->GL_SwapBuffers = GEM_GL_SwapBuffers; | 119 device->GL_SetSwapInterval = SDL_AtariGL_SetSwapInterval; |
120 device->GL_GetSwapInterval = SDL_AtariGL_GetSwapInterval; | |
121 device->GL_SwapWindow = GEM_GL_SwapWindow; | |
122 device->GL_DeleteContext = SDL_AtariGL_DeleteContext; | |
197 #endif | 123 #endif |
198 | 124 |
199 device->hidden->use_dev_mouse = | |
200 (SDL_AtariDevMouse_Open() != 0) ? SDL_TRUE : SDL_FALSE; | |
201 | |
202 vectors_mask = ATARI_XBIOS_JOYSTICKEVENTS; /* XBIOS joystick events */ | |
203 if (!(device->hidden->use_dev_mouse)) { | |
204 vectors_mask |= ATARI_XBIOS_MOUSEEVENTS; /* XBIOS mouse events */ | |
205 } | |
206 /*if (Getcookie(C_MiNT, &dummy) == C_FOUND) { | |
207 vectors_mask = 0; | |
208 } */ | |
209 | |
210 SDL_AtariXbios_InstallVectors(vectors_mask); | |
211 | |
212 device->free = GEM_DeleteDevice; | 125 device->free = GEM_DeleteDevice; |
213 | 126 |
214 return device; | 127 return device; |
215 } | 128 } |
216 | 129 |
217 VideoBootStrap GEM_bootstrap = { | 130 VideoBootStrap GEM_bootstrap = { |
218 GEM_VID_DRIVER_NAME, "Atari GEM video driver", | 131 "gem", "Atari GEM video driver", |
219 GEM_Available, GEM_CreateDevice | 132 GEM_Available, GEM_CreateDevice |
220 }; | 133 }; |
221 | 134 |
222 static void | |
223 VDI_ReadExtInfo(_THIS, short *work_out) | |
224 { | |
225 unsigned long EdDI_version; | |
226 unsigned long cookie_EdDI; | |
227 Uint32 num_colours; | |
228 Uint16 clut_type, num_bits; | |
229 | |
230 /* Read EdDI informations */ | |
231 if (Getcookie(C_EdDI, &cookie_EdDI) == C_NOTFOUND) { | |
232 return; | |
233 } | |
234 | |
235 EdDI_version = Atari_get_EdDI_version((void *) cookie_EdDI); | |
236 | |
237 vq_scrninfo(VDI_handle, work_out); | |
238 | |
239 VDI_format = work_out[0]; | |
240 clut_type = work_out[1]; | |
241 num_bits = work_out[2]; | |
242 num_colours = *((Uint32 *) & work_out[3]); | |
243 | |
244 /* With EdDI>=1.1, we can have screen pitch, address and format | |
245 * so we can directly write to screen without using vro_cpyfm | |
246 */ | |
247 if (EdDI_version >= EDDI_11) { | |
248 VDI_pitch = work_out[5]; | |
249 VDI_screen = (void *) *((unsigned long *) &work_out[6]); | |
250 } | |
251 | |
252 switch (clut_type) { | |
253 case VDI_CLUT_HARDWARE: | |
254 { | |
255 int i; | |
256 Uint16 *tmp_p; | |
257 | |
258 tmp_p = (Uint16 *) & work_out[16]; | |
259 | |
260 for (i = 0; i < 256; i++) { | |
261 vdi_index[*tmp_p++] = i; | |
262 } | |
263 } | |
264 break; | |
265 case VDI_CLUT_SOFTWARE: | |
266 { | |
267 int component; /* red, green, blue, alpha, overlay */ | |
268 int num_bit; | |
269 unsigned short *tmp_p; | |
270 | |
271 /* We can build masks with info here */ | |
272 tmp_p = (unsigned short *) &work_out[16]; | |
273 for (component = 0; component < 5; component++) { | |
274 for (num_bit = 0; num_bit < 16; num_bit++) { | |
275 unsigned short valeur; | |
276 | |
277 valeur = *tmp_p++; | |
278 | |
279 if (valeur == 0xffff) { | |
280 continue; | |
281 } | |
282 | |
283 switch (component) { | |
284 case 0: | |
285 VDI_redmask |= 1 << valeur; | |
286 break; | |
287 case 1: | |
288 VDI_greenmask |= 1 << valeur; | |
289 break; | |
290 case 2: | |
291 VDI_bluemask |= 1 << valeur; | |
292 break; | |
293 case 3: | |
294 VDI_alphamask |= 1 << valeur; | |
295 break; | |
296 } | |
297 } | |
298 } | |
299 } | |
300 | |
301 /* Remove lower green bits for Intel endian screen */ | |
302 if ((VDI_greenmask == ((7 << 13) | 3)) | |
303 || (VDI_greenmask == ((7 << 13) | 7))) { | |
304 VDI_greenmask &= ~(7 << 13); | |
305 } | |
306 break; | |
307 case VDI_CLUT_NONE: | |
308 break; | |
309 } | |
310 } | |
311 | |
312 int | 135 int |
313 GEM_VideoInit(_THIS, SDL_PixelFormat * vformat) | 136 GEM_VideoInit(_THIS) |
314 { | 137 { |
315 int i, menubar_size; | 138 int i; |
316 short work_in[12], work_out[272], dummy; | 139 short work_in[12], work_out[272], dummy; |
140 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; | |
317 | 141 |
318 /* Open AES (Application Environment Services) */ | 142 /* Open AES (Application Environment Services) */ |
319 if (appl_init() == -1) { | 143 if (appl_init() == -1) { |
320 fprintf(stderr, "Can not open AES\n"); | 144 fprintf(stderr, "Can not open AES\n"); |
321 return 1; | 145 return 1; |
322 } | 146 } |
323 | 147 |
324 /* Read version and features */ | 148 /* Read version and features */ |
325 GEM_version = aes_global[0]; | 149 if (aes_global[0] >= 0x0410) { |
326 if (GEM_version >= 0x0410) { | 150 short ap_gout[4]; |
327 short ap_gout[4], errorcode; | 151 |
328 | 152 data->wfeatures = 0; |
329 GEM_wfeatures = 0; | 153 if (appl_getinfo(AES_WINDOW, &ap_gout[0], &ap_gout[1], &ap_gout[2], |
330 errorcode = | 154 &ap_gout[3]) == 0) { |
331 appl_getinfo(AES_WINDOW, &ap_gout[0], &ap_gout[1], &ap_gout[2], | 155 data->wfeatures = ap_gout[0]; |
332 &ap_gout[3]); | |
333 | |
334 if (errorcode == 0) { | |
335 GEM_wfeatures = ap_gout[0]; | |
336 } | 156 } |
337 } | 157 } |
338 | 158 |
339 /* Ask VDI physical workstation handle opened by AES */ | 159 /* Ask VDI physical workstation handle opened by AES */ |
340 VDI_handle = graf_handle(&dummy, &dummy, &dummy, &dummy); | 160 data->vdi_handle = graf_handle(&dummy, &dummy, &dummy, &dummy); |
341 if (VDI_handle < 1) { | |
342 fprintf(stderr, "Wrong VDI handle %d returned by AES\n", VDI_handle); | |
343 return 1; | |
344 } | |
345 | 161 |
346 /* Open virtual VDI workstation */ | 162 /* Open virtual VDI workstation */ |
347 work_in[0] = Getrez() + 2; | 163 work_in[0] = Getrez() + 2; |
348 for (i = 1; i < 10; i++) | 164 for (i = 1; i < 10; i++) |
349 work_in[i] = 1; | 165 work_in[i] = 1; |
350 work_in[10] = 2; | 166 work_in[10] = 2; |
351 | 167 |
352 v_opnvwk(work_in, &VDI_handle, work_out); | 168 v_opnvwk(work_in, &(data->vdi_handle), work_out); |
353 if (VDI_handle == 0) { | 169 if (data->vdi_handle == 0) { |
354 fprintf(stderr, "Can not open VDI virtual workstation\n"); | 170 fprintf(stderr, "Can not open VDI virtual workstation\n"); |
355 return 1; | 171 return 1; |
356 } | 172 } |
357 | 173 |
358 /* Read fullscreen size */ | |
359 VDI_w = work_out[0] + 1; | |
360 VDI_h = work_out[1] + 1; | |
361 | |
362 /* Read desktop size and position */ | |
363 if (!wind_get | |
364 (DESKTOP_HANDLE, WF_WORKXYWH, &GEM_desk_x, &GEM_desk_y, &GEM_desk_w, | |
365 &GEM_desk_h)) { | |
366 fprintf(stderr, "Can not read desktop properties\n"); | |
367 return 1; | |
368 } | |
369 | |
370 /* Read bit depth */ | |
371 vq_extnd(VDI_handle, 1, work_out); | |
372 VDI_bpp = work_out[4]; | |
373 VDI_oldnumcolors = 0; | |
374 | |
375 switch (VDI_bpp) { | |
376 case 8: | |
377 VDI_pixelsize = 1; | |
378 break; | |
379 case 15: | |
380 case 16: | |
381 VDI_pixelsize = 2; | |
382 break; | |
383 case 24: | |
384 VDI_pixelsize = 3; | |
385 break; | |
386 case 32: | |
387 VDI_pixelsize = 4; | |
388 break; | |
389 default: | |
390 fprintf(stderr, "%d bits colour depth not supported\n", VDI_bpp); | |
391 return 1; | |
392 } | |
393 | |
394 /* Setup hardware -> VDI palette mapping */ | |
395 for (i = 16; i < 255; i++) { | |
396 vdi_index[i] = i; | |
397 } | |
398 vdi_index[255] = 1; | |
399 | |
400 /* Save current palette */ | |
401 if (VDI_bpp > 8) { | |
402 VDI_oldnumcolors = 1 << 8; | |
403 } else { | |
404 VDI_oldnumcolors = 1 << VDI_bpp; | |
405 } | |
406 | |
407 for (i = 0; i < VDI_oldnumcolors; i++) { | |
408 short rgb[3]; | |
409 | |
410 vq_color(VDI_handle, i, 0, rgb); | |
411 | |
412 VDI_oldpalette[i][0] = rgb[0]; | |
413 VDI_oldpalette[i][1] = rgb[1]; | |
414 VDI_oldpalette[i][2] = rgb[2]; | |
415 } | |
416 VDI_setpalette = GEM_SetNewPalette; | |
417 SDL_memcpy(VDI_curpalette, VDI_oldpalette, sizeof(VDI_curpalette)); | |
418 | |
419 /* Setup screen info */ | |
420 GEM_title_name = empty_name; | |
421 GEM_icon_name = empty_name; | |
422 | |
423 GEM_handle = -1; | |
424 GEM_locked = SDL_FALSE; | |
425 GEM_win_fulled = SDL_FALSE; | |
426 GEM_fullscreen = SDL_FALSE; | |
427 GEM_lock_redraw = SDL_TRUE; /* Prevent redraw till buffers are setup */ | |
428 | |
429 VDI_screen = NULL; | |
430 VDI_pitch = VDI_w * VDI_pixelsize; | |
431 VDI_format = ((VDI_bpp <= 8) ? VDI_FORMAT_INTER : VDI_FORMAT_PACK); | |
432 VDI_redmask = VDI_greenmask = VDI_bluemask = VDI_alphamask = 0; | |
433 VDI_ReadExtInfo(this, work_out); | |
434 | |
435 #ifdef DEBUG_VIDEO_GEM | |
436 printf("sdl:video:gem: screen: address=0x%08x, pitch=%d\n", VDI_screen, | |
437 VDI_pitch); | |
438 printf("sdl:video:gem: format=%d\n", VDI_format); | |
439 printf("sdl:video:gem: masks: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", | |
440 VDI_alphamask, VDI_redmask, VDI_greenmask, VDI_bluemask); | |
441 #endif | |
442 | |
443 /* Setup destination mfdb */ | |
444 VDI_dst_mfdb.fd_addr = NULL; | |
445 | |
446 /* Determine the current screen size */ | |
447 this->info.current_w = VDI_w; | |
448 this->info.current_h = VDI_h; | |
449 | |
450 /* Determine the screen depth */ | |
451 /* we change this during the SDL_SetVideoMode implementation... */ | |
452 vformat->BitsPerPixel = VDI_bpp; | |
453 | |
454 /* Set mouse cursor to arrow */ | 174 /* Set mouse cursor to arrow */ |
455 graf_mouse(ARROW, NULL); | 175 graf_mouse(ARROW, NULL); |
456 | 176 |
457 /* Init chunky to planar routine */ | |
458 SDL_Atari_C2pConvert = SDL_Atari_C2pConvert8; | |
459 | |
460 /* Setup VDI fill functions */ | 177 /* Setup VDI fill functions */ |
461 vsf_color(VDI_handle, 0); | 178 vsf_color(data->vdi_handle, 0); |
462 vsf_interior(VDI_handle, 1); | 179 vsf_interior(data->vdi_handle, 1); |
463 vsf_perimeter(VDI_handle, 0); | 180 vsf_perimeter(data->vdi_handle, 0); |
464 | 181 |
465 /* Menu bar save buffer */ | 182 GEM_InitModes(_this); |
466 menubar_size = GEM_desk_w * GEM_desk_y * VDI_pixelsize; | 183 |
467 GEM_menubar = Atari_SysMalloc(menubar_size, MX_PREFTTRAM); | 184 GEM_InitKeyboard(_this); |
468 | 185 GEM_InitMouse(_this); |
469 /* Fill video modes list */ | 186 |
470 SDL_modelist[0] = SDL_malloc(sizeof(SDL_Rect)); | |
471 SDL_modelist[0]->x = 0; | |
472 SDL_modelist[0]->y = 0; | |
473 SDL_modelist[0]->w = VDI_w; | |
474 SDL_modelist[0]->h = VDI_h; | |
475 | |
476 SDL_modelist[1] = NULL; | |
477 | |
478 #if SDL_VIDEO_OPENGL | |
479 SDL_AtariGL_InitPointers(this); | |
480 #endif | |
481 | |
482 this->info.wm_available = 1; | |
483 | |
484 /* We're done! */ | |
485 return (0); | 187 return (0); |
486 } | 188 } |
487 | 189 |
488 SDL_Rect ** | |
489 GEM_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags) | |
490 { | |
491 if (format->BitsPerPixel != VDI_bpp) { | |
492 return ((SDL_Rect **) NULL); | |
493 } | |
494 | |
495 if (flags & SDL_FULLSCREEN) { | |
496 return (SDL_modelist); | |
497 } | |
498 | |
499 return ((SDL_Rect **) - 1); | |
500 } | |
501 | |
502 static void | |
503 GEM_FreeBuffers(_THIS) | |
504 { | |
505 /* Release buffer */ | |
506 if (GEM_buffer2) { | |
507 Mfree(GEM_buffer2); | |
508 GEM_buffer2 = NULL; | |
509 } | |
510 | |
511 if (GEM_buffer1) { | |
512 Mfree(GEM_buffer1); | |
513 GEM_buffer1 = NULL; | |
514 } | |
515 } | |
516 | |
517 static void | |
518 GEM_ClearRect(_THIS, short *rect) | |
519 { | |
520 short oldrgb[3], rgb[3] = { 0, 0, 0 }; | |
521 | |
522 vq_color(VDI_handle, vdi_index[0], 0, oldrgb); | |
523 vs_color(VDI_handle, vdi_index[0], rgb); | |
524 | |
525 vsf_color(VDI_handle, 0); | |
526 vsf_interior(VDI_handle, 1); | |
527 vsf_perimeter(VDI_handle, 0); | |
528 v_bar(VDI_handle, rect); | |
529 | |
530 vs_color(VDI_handle, vdi_index[0], oldrgb); | |
531 } | |
532 | |
533 static void | |
534 GEM_ClearScreen(_THIS) | |
535 { | |
536 short pxy[4]; | |
537 | |
538 v_hide_c(VDI_handle); | |
539 | |
540 pxy[0] = pxy[1] = 0; | |
541 pxy[2] = VDI_w - 1; | |
542 pxy[3] = VDI_h - 1; | |
543 GEM_ClearRect(this, pxy); | |
544 | |
545 v_show_c(VDI_handle, 1); | |
546 } | |
547 | |
548 static void | |
549 GEM_SetNewPalette(_THIS, Uint16 newpal[256][3]) | |
550 { | |
551 int i; | |
552 short rgb[3]; | |
553 | |
554 if (VDI_oldnumcolors == 0) | |
555 return; | |
556 | |
557 for (i = 0; i < VDI_oldnumcolors; i++) { | |
558 rgb[0] = newpal[i][0]; | |
559 rgb[1] = newpal[i][1]; | |
560 rgb[2] = newpal[i][2]; | |
561 | |
562 vs_color(VDI_handle, i, rgb); | |
563 } | |
564 } | |
565 | |
566 static void | |
567 GEM_LockScreen(_THIS) | |
568 { | |
569 if (!GEM_locked) { | |
570 /* Lock AES */ | |
571 wind_update(BEG_UPDATE); | |
572 wind_update(BEG_MCTRL); | |
573 /* Reserve memory space, used to be sure of compatibility */ | |
574 form_dial(FMD_START, 0, 0, 0, 0, 0, 0, VDI_w, VDI_h); | |
575 | |
576 /* Save menu bar */ | |
577 if (GEM_menubar) { | |
578 MFDB mfdb_src; | |
579 short blitcoords[8]; | |
580 | |
581 mfdb_src.fd_addr = GEM_menubar; | |
582 mfdb_src.fd_w = GEM_desk_w; | |
583 mfdb_src.fd_h = GEM_desk_y; | |
584 mfdb_src.fd_wdwidth = GEM_desk_w >> 4; | |
585 mfdb_src.fd_nplanes = VDI_bpp; | |
586 mfdb_src.fd_stand = | |
587 mfdb_src.fd_r1 = mfdb_src.fd_r2 = mfdb_src.fd_r3 = 0; | |
588 | |
589 blitcoords[0] = blitcoords[4] = 0; | |
590 blitcoords[1] = blitcoords[5] = 0; | |
591 blitcoords[2] = blitcoords[6] = GEM_desk_w - 1; | |
592 blitcoords[3] = blitcoords[7] = GEM_desk_y - 1; | |
593 | |
594 vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &VDI_dst_mfdb, | |
595 &mfdb_src); | |
596 } | |
597 | |
598 GEM_locked = SDL_TRUE; | |
599 } | |
600 } | |
601 | |
602 static void | |
603 GEM_UnlockScreen(_THIS) | |
604 { | |
605 if (GEM_locked) { | |
606 /* Restore menu bar */ | |
607 if (GEM_menubar) { | |
608 MFDB mfdb_src; | |
609 short blitcoords[8]; | |
610 | |
611 mfdb_src.fd_addr = GEM_menubar; | |
612 mfdb_src.fd_w = GEM_desk_w; | |
613 mfdb_src.fd_h = GEM_desk_y; | |
614 mfdb_src.fd_wdwidth = GEM_desk_w >> 4; | |
615 mfdb_src.fd_nplanes = VDI_bpp; | |
616 mfdb_src.fd_stand = | |
617 mfdb_src.fd_r1 = mfdb_src.fd_r2 = mfdb_src.fd_r3 = 0; | |
618 | |
619 blitcoords[0] = blitcoords[4] = 0; | |
620 blitcoords[1] = blitcoords[5] = 0; | |
621 blitcoords[2] = blitcoords[6] = GEM_desk_w - 1; | |
622 blitcoords[3] = blitcoords[7] = GEM_desk_y - 1; | |
623 | |
624 vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, | |
625 &VDI_dst_mfdb); | |
626 } | |
627 | |
628 /* Restore screen memory, and send REDRAW to all apps */ | |
629 form_dial(FMD_FINISH, 0, 0, 0, 0, 0, 0, VDI_w, VDI_h); | |
630 /* Unlock AES */ | |
631 wind_update(END_MCTRL); | |
632 wind_update(END_UPDATE); | |
633 | |
634 GEM_locked = SDL_FALSE; | |
635 } | |
636 } | |
637 | |
638 SDL_Surface * | |
639 GEM_SetVideoMode(_THIS, SDL_Surface * current, | |
640 int width, int height, int bpp, Uint32 flags) | |
641 { | |
642 Uint32 modeflags, screensize; | |
643 SDL_bool use_shadow1, use_shadow2; | |
644 | |
645 /* width must be multiple of 16, for vro_cpyfm() and c2p_convert() */ | |
646 if ((width & 15) != 0) { | |
647 width = (width | 15) + 1; | |
648 } | |
649 | |
650 /*--- Verify if asked mode can be used ---*/ | |
651 if (VDI_bpp != bpp) { | |
652 SDL_SetError("%d bpp mode not supported", bpp); | |
653 return (NULL); | |
654 } | |
655 | |
656 if (flags & SDL_FULLSCREEN) { | |
657 if ((VDI_w < width) || (VDI_h < height)) { | |
658 SDL_SetError("%dx%d mode is too large", width, height); | |
659 return (NULL); | |
660 } | |
661 } | |
662 | |
663 /*--- Allocate the new pixel format for the screen ---*/ | |
664 if (!SDL_ReallocFormat | |
665 (current, VDI_bpp, VDI_redmask, VDI_greenmask, VDI_bluemask, | |
666 VDI_alphamask)) { | |
667 SDL_SetError("Couldn't allocate new pixel format for requested mode"); | |
668 return (NULL); | |
669 } | |
670 | |
671 screensize = width * height * VDI_pixelsize; | |
672 | |
673 #ifdef DEBUG_VIDEO_GEM | |
674 printf("sdl:video:gem: setvideomode(): %dx%dx%d = %d\n", width, height, | |
675 bpp, screensize); | |
676 #endif | |
677 | |
678 /*--- Allocate shadow buffers if needed, and conversion operations ---*/ | |
679 GEM_FreeBuffers(this); | |
680 | |
681 GEM_bufops = 0; | |
682 use_shadow1 = use_shadow2 = SDL_FALSE; | |
683 if (VDI_screen && (flags & SDL_FULLSCREEN)) { | |
684 if (VDI_format == VDI_FORMAT_INTER) { | |
685 use_shadow1 = SDL_TRUE; | |
686 GEM_bufops = B2S_C2P_1TOS; | |
687 } | |
688 } else { | |
689 use_shadow1 = SDL_TRUE; | |
690 if (VDI_format == VDI_FORMAT_PACK) { | |
691 GEM_bufops = B2S_VROCPYFM_1TOS; | |
692 } else { | |
693 use_shadow2 = SDL_TRUE; | |
694 GEM_bufops = B2S_C2P_1TO2 | B2S_VROCPYFM_2TOS; | |
695 } | |
696 } | |
697 | |
698 if (use_shadow1) { | |
699 GEM_buffer1 = Atari_SysMalloc(screensize, MX_PREFTTRAM); | |
700 if (GEM_buffer1 == NULL) { | |
701 SDL_SetError("Can not allocate %d KB for frame buffer", | |
702 screensize >> 10); | |
703 return NULL; | |
704 } | |
705 SDL_memset(GEM_buffer1, 0, screensize); | |
706 #ifdef DEBUG_VIDEO_GEM | |
707 printf("sdl:video:gem: setvideomode(): allocated buffer 1\n"); | |
708 #endif | |
709 } | |
710 | |
711 if (use_shadow2) { | |
712 GEM_buffer2 = Atari_SysMalloc(screensize, MX_PREFTTRAM); | |
713 if (GEM_buffer2 == NULL) { | |
714 SDL_SetError("Can not allocate %d KB for shadow buffer", | |
715 screensize >> 10); | |
716 return NULL; | |
717 } | |
718 SDL_memset(GEM_buffer2, 0, screensize); | |
719 #ifdef DEBUG_VIDEO_GEM | |
720 printf("sdl:video:gem: setvideomode(): allocated buffer 2\n"); | |
721 #endif | |
722 } | |
723 | |
724 /*--- Initialize screen ---*/ | |
725 modeflags = SDL_PREALLOC; | |
726 if (VDI_bpp == 8) { | |
727 modeflags |= SDL_HWPALETTE; | |
728 } | |
729 | |
730 if (flags & SDL_FULLSCREEN) { | |
731 GEM_LockScreen(this); | |
732 | |
733 GEM_ClearScreen(this); | |
734 | |
735 modeflags |= SDL_FULLSCREEN; | |
736 if (VDI_screen && (VDI_format == VDI_FORMAT_PACK) && !use_shadow1) { | |
737 modeflags |= SDL_HWSURFACE; | |
738 } else { | |
739 modeflags |= SDL_SWSURFACE; | |
740 } | |
741 | |
742 GEM_fullscreen = SDL_TRUE; | |
743 } else { | |
744 int old_win_type; | |
745 short x2, y2, w2, h2; | |
746 | |
747 GEM_UnlockScreen(this); | |
748 | |
749 /* Set window gadgets */ | |
750 old_win_type = GEM_win_type; | |
751 if (!(flags & SDL_NOFRAME)) { | |
752 GEM_win_type = NAME | MOVER | CLOSER | SMALLER; | |
753 if (flags & SDL_RESIZABLE) { | |
754 GEM_win_type |= FULLER | SIZER; | |
755 modeflags |= SDL_RESIZABLE; | |
756 } | |
757 } else { | |
758 GEM_win_type = 0; | |
759 modeflags |= SDL_NOFRAME; | |
760 } | |
761 modeflags |= SDL_SWSURFACE; | |
762 | |
763 /* Recreate window ? only for different widget or non-created window */ | |
764 if ((old_win_type != GEM_win_type) || (GEM_handle < 0)) { | |
765 /* Calculate window size */ | |
766 if (!wind_calc | |
767 (WC_BORDER, GEM_win_type, 0, 0, width, height, &x2, &y2, | |
768 &w2, &h2)) { | |
769 GEM_FreeBuffers(this); | |
770 SDL_SetError("Can not calculate window attributes"); | |
771 return NULL; | |
772 } | |
773 | |
774 /* Center window */ | |
775 x2 = (GEM_desk_w - w2) >> 1; | |
776 y2 = (GEM_desk_h - h2) >> 1; | |
777 if (x2 < 0) { | |
778 x2 = 0; | |
779 } | |
780 if (y2 < 0) { | |
781 y2 = 0; | |
782 } | |
783 x2 += GEM_desk_x; | |
784 y2 += GEM_desk_y; | |
785 | |
786 /* Destroy existing window */ | |
787 if (GEM_handle >= 0) { | |
788 wind_close(GEM_handle); | |
789 wind_delete(GEM_handle); | |
790 } | |
791 | |
792 /* Create window */ | |
793 GEM_handle = wind_create(GEM_win_type, x2, y2, w2, h2); | |
794 if (GEM_handle < 0) { | |
795 GEM_FreeBuffers(this); | |
796 SDL_SetError("Can not create window"); | |
797 return NULL; | |
798 } | |
799 #ifdef DEBUG_VIDEO_GEM | |
800 printf("sdl:video:gem: handle=%d\n", GEM_handle); | |
801 #endif | |
802 | |
803 /* Setup window name */ | |
804 wind_set(GEM_handle, WF_NAME, | |
805 (short) (((unsigned long) GEM_title_name) >> 16), | |
806 (short) (((unsigned long) GEM_title_name) & 0xffff), | |
807 0, 0); | |
808 GEM_refresh_name = SDL_FALSE; | |
809 | |
810 /* Open the window */ | |
811 wind_open(GEM_handle, x2, y2, w2, h2); | |
812 } else { | |
813 /* Resize window to fit asked video mode */ | |
814 wind_get(GEM_handle, WF_WORKXYWH, &x2, &y2, &w2, &h2); | |
815 if (wind_calc | |
816 (WC_BORDER, GEM_win_type, x2, y2, width, height, &x2, &y2, | |
817 &w2, &h2)) { | |
818 wind_set(GEM_handle, WF_CURRXYWH, x2, y2, w2, h2); | |
819 } | |
820 } | |
821 | |
822 GEM_fullscreen = SDL_FALSE; | |
823 } | |
824 | |
825 /* Set up the new mode framebuffer */ | |
826 current->w = width; | |
827 current->h = height; | |
828 if (use_shadow1) { | |
829 current->pixels = GEM_buffer1; | |
830 current->pitch = width * VDI_pixelsize; | |
831 } else { | |
832 current->pixels = VDI_screen; | |
833 current->pitch = VDI_pitch; | |
834 } | |
835 | |
836 #if SDL_VIDEO_OPENGL | |
837 if (flags & SDL_INTERNALOPENGL) { | |
838 if (!SDL_AtariGL_Init(this, current)) { | |
839 GEM_FreeBuffers(this); | |
840 SDL_SetError("Can not create OpenGL context"); | |
841 return NULL; | |
842 } | |
843 | |
844 modeflags |= SDL_INTERNALOPENGL; | |
845 } | |
846 #endif | |
847 | |
848 current->flags = modeflags; | |
849 | |
850 #ifdef DEBUG_VIDEO_GEM | |
851 printf("sdl:video:gem: surface: %dx%d\n", current->w, current->h); | |
852 #endif | |
853 | |
854 this->UpdateRects = GEM_UpdateRects; | |
855 GEM_lock_redraw = SDL_FALSE; /* Enable redraw */ | |
856 | |
857 /* We're done */ | |
858 return (current); | |
859 } | |
860 | |
861 static int | |
862 GEM_AllocHWSurface(_THIS, SDL_Surface * surface) | |
863 { | |
864 return -1; | |
865 } | |
866 | |
867 static void | |
868 GEM_FreeHWSurface(_THIS, SDL_Surface * surface) | |
869 { | |
870 return; | |
871 } | |
872 | |
873 static int | |
874 GEM_LockHWSurface(_THIS, SDL_Surface * surface) | |
875 { | |
876 return (0); | |
877 } | |
878 | |
879 static void | |
880 GEM_UnlockHWSurface(_THIS, SDL_Surface * surface) | |
881 { | |
882 return; | |
883 } | |
884 | |
885 static void | |
886 GEM_UpdateRectsFullscreen(_THIS, int numrects, SDL_Rect * rects) | |
887 { | |
888 SDL_Surface *surface; | |
889 int i, surf_width; | |
890 | |
891 surface = this->screen; | |
892 /* Need to be a multiple of 16 pixels */ | |
893 surf_width = surface->w; | |
894 if ((surf_width & 15) != 0) { | |
895 surf_width = (surf_width | 15) + 1; | |
896 } | |
897 | |
898 if (GEM_bufops & (B2S_C2P_1TO2 | B2S_C2P_1TOS)) { | |
899 void *destscr; | |
900 int destpitch; | |
901 | |
902 if (GEM_bufops & B2S_C2P_1TOS) { | |
903 destscr = VDI_screen; | |
904 destpitch = VDI_pitch; | |
905 } else { | |
906 destscr = GEM_buffer2; | |
907 destpitch = surface->pitch; | |
908 } | |
909 | |
910 for (i = 0; i < numrects; i++) { | |
911 void *source, *destination; | |
912 int x1, x2; | |
913 | |
914 x1 = rects[i].x & ~15; | |
915 x2 = rects[i].x + rects[i].w; | |
916 if (x2 & 15) { | |
917 x2 = (x2 | 15) + 1; | |
918 } | |
919 | |
920 source = surface->pixels; | |
921 source += surface->pitch * rects[i].y; | |
922 source += x1; | |
923 | |
924 destination = destscr; | |
925 destination += destpitch * rects[i].y; | |
926 destination += x1; | |
927 | |
928 SDL_Atari_C2pConvert(source, destination, | |
929 x2 - x1, rects[i].h, | |
930 SDL_FALSE, surface->pitch, destpitch); | |
931 } | |
932 } | |
933 | |
934 if (GEM_bufops & (B2S_VROCPYFM_1TOS | B2S_VROCPYFM_2TOS)) { | |
935 MFDB mfdb_src; | |
936 short blitcoords[8]; | |
937 | |
938 mfdb_src.fd_addr = surface->pixels; | |
939 mfdb_src.fd_w = surf_width; | |
940 mfdb_src.fd_h = surface->h; | |
941 mfdb_src.fd_wdwidth = (surface->pitch / VDI_pixelsize) >> 4; | |
942 mfdb_src.fd_nplanes = surface->format->BitsPerPixel; | |
943 mfdb_src.fd_stand = | |
944 mfdb_src.fd_r1 = mfdb_src.fd_r2 = mfdb_src.fd_r3 = 0; | |
945 if (GEM_bufops & B2S_VROCPYFM_2TOS) { | |
946 mfdb_src.fd_addr = GEM_buffer2; | |
947 } | |
948 | |
949 for (i = 0; i < numrects; ++i) { | |
950 blitcoords[0] = blitcoords[4] = rects[i].x; | |
951 blitcoords[1] = blitcoords[5] = rects[i].y; | |
952 blitcoords[2] = blitcoords[6] = rects[i].x + rects[i].w - 1; | |
953 blitcoords[3] = blitcoords[7] = rects[i].y + rects[i].h - 1; | |
954 | |
955 vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, | |
956 &VDI_dst_mfdb); | |
957 } | |
958 } | |
959 } | |
960 | |
961 static void | |
962 GEM_UpdateRectsWindowed(_THIS, int numrects, SDL_Rect * rects) | |
963 { | |
964 short pxy[4], wind_pxy[4]; | |
965 int i; | |
966 | |
967 if (wind_get | |
968 (GEM_handle, WF_WORKXYWH, &wind_pxy[0], &wind_pxy[1], &wind_pxy[2], | |
969 &wind_pxy[3]) == 0) { | |
970 return; | |
971 } | |
972 | |
973 for (i = 0; i < numrects; ++i) { | |
974 pxy[0] = wind_pxy[0] + rects[i].x; | |
975 pxy[1] = wind_pxy[1] + rects[i].y; | |
976 pxy[2] = rects[i].w; | |
977 pxy[3] = rects[i].h; | |
978 | |
979 GEM_wind_redraw(this, GEM_handle, pxy); | |
980 } | |
981 } | |
982 | |
983 static void | |
984 GEM_UpdateRects(_THIS, int numrects, SDL_Rect * rects) | |
985 { | |
986 SDL_Surface *surface; | |
987 | |
988 if (GEM_lock_redraw) { | |
989 return; | |
990 } | |
991 | |
992 surface = this->screen; | |
993 | |
994 if (surface->flags & SDL_FULLSCREEN) { | |
995 GEM_UpdateRectsFullscreen(this, numrects, rects); | |
996 } else { | |
997 GEM_UpdateRectsWindowed(this, numrects, rects); | |
998 } | |
999 } | |
1000 | |
1001 static int | |
1002 GEM_FlipHWSurfaceFullscreen(_THIS, SDL_Surface * surface) | |
1003 { | |
1004 int surf_width; | |
1005 | |
1006 /* Need to be a multiple of 16 pixels */ | |
1007 surf_width = surface->w; | |
1008 if ((surf_width & 15) != 0) { | |
1009 surf_width = (surf_width | 15) + 1; | |
1010 } | |
1011 | |
1012 if (GEM_bufops & (B2S_C2P_1TO2 | B2S_C2P_1TOS)) { | |
1013 void *destscr; | |
1014 int destpitch; | |
1015 | |
1016 if (GEM_bufops & B2S_C2P_1TOS) { | |
1017 destscr = VDI_screen; | |
1018 destpitch = VDI_pitch; | |
1019 } else { | |
1020 destscr = GEM_buffer2; | |
1021 destpitch = surface->pitch; | |
1022 } | |
1023 | |
1024 SDL_Atari_C2pConvert(surface->pixels, destscr, | |
1025 surf_width, surface->h, | |
1026 SDL_FALSE, surface->pitch, destpitch); | |
1027 } | |
1028 | |
1029 if (GEM_bufops & (B2S_VROCPYFM_1TOS | B2S_VROCPYFM_2TOS)) { | |
1030 MFDB mfdb_src; | |
1031 short blitcoords[8]; | |
1032 | |
1033 mfdb_src.fd_w = surf_width; | |
1034 mfdb_src.fd_h = surface->h; | |
1035 mfdb_src.fd_wdwidth = mfdb_src.fd_w >> 4; | |
1036 mfdb_src.fd_nplanes = surface->format->BitsPerPixel; | |
1037 mfdb_src.fd_stand = | |
1038 mfdb_src.fd_r1 = mfdb_src.fd_r2 = mfdb_src.fd_r3 = 0; | |
1039 if (GEM_bufops & B2S_VROCPYFM_1TOS) { | |
1040 mfdb_src.fd_addr = surface->pixels; | |
1041 } else { | |
1042 mfdb_src.fd_addr = GEM_buffer2; | |
1043 } | |
1044 | |
1045 blitcoords[0] = blitcoords[4] = 0; | |
1046 blitcoords[1] = blitcoords[5] = 0; | |
1047 blitcoords[2] = blitcoords[6] = surface->w - 1; | |
1048 blitcoords[3] = blitcoords[7] = surface->h - 1; | |
1049 | |
1050 vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb); | |
1051 } | |
1052 | |
1053 return (0); | |
1054 } | |
1055 | |
1056 static int | |
1057 GEM_FlipHWSurfaceWindowed(_THIS, SDL_Surface * surface) | |
1058 { | |
1059 short pxy[8]; | |
1060 | |
1061 /* Update the whole window */ | |
1062 wind_get(GEM_handle, WF_WORKXYWH, &pxy[0], &pxy[1], &pxy[2], &pxy[3]); | |
1063 | |
1064 GEM_wind_redraw(this, GEM_handle, pxy); | |
1065 | |
1066 return (0); | |
1067 } | |
1068 | |
1069 static int | |
1070 GEM_FlipHWSurface(_THIS, SDL_Surface * surface) | |
1071 { | |
1072 if (GEM_lock_redraw) { | |
1073 return (0); | |
1074 } | |
1075 | |
1076 if (surface->flags & SDL_FULLSCREEN) { | |
1077 return GEM_FlipHWSurfaceFullscreen(this, surface); | |
1078 } else { | |
1079 return GEM_FlipHWSurfaceWindowed(this, surface); | |
1080 } | |
1081 } | |
1082 | |
1083 static int | |
1084 GEM_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors) | |
1085 { | |
1086 int i; | |
1087 SDL_Surface *surface; | |
1088 | |
1089 #ifdef DEBUG_VIDEO_GEM | |
1090 printf("sdl:video:gem: setcolors()\n"); | |
1091 #endif | |
1092 | |
1093 /* Do not change palette in True Colour */ | |
1094 surface = this->screen; | |
1095 if (surface->format->BitsPerPixel > 8) { | |
1096 return 1; | |
1097 } | |
1098 | |
1099 for (i = 0; i < ncolors; i++) { | |
1100 int r, g, b; | |
1101 short rgb[3]; | |
1102 | |
1103 r = colors[i].r; | |
1104 g = colors[i].g; | |
1105 b = colors[i].b; | |
1106 | |
1107 rgb[0] = VDI_curpalette[i][0] = (1000 * r) / 255; | |
1108 rgb[1] = VDI_curpalette[i][1] = (1000 * g) / 255; | |
1109 rgb[2] = VDI_curpalette[i][2] = (1000 * b) / 255; | |
1110 | |
1111 vs_color(VDI_handle, vdi_index[firstcolor + i], rgb); | |
1112 } | |
1113 | |
1114 return (1); | |
1115 } | |
1116 | |
1117 #if 0 | |
1118 static int | |
1119 GEM_ToggleFullScreen(_THIS, int on) | |
1120 { | |
1121 if (on) { | |
1122 GEM_LockScreen(this); | |
1123 } else { | |
1124 GEM_UnlockScreen(this); | |
1125 } | |
1126 | |
1127 return (1); | |
1128 } | |
1129 #endif | |
1130 | |
1131 /* Note: If we are terminated, this could be called in the middle of | |
1132 another SDL video routine -- notably UpdateRects. | |
1133 */ | |
1134 void | 190 void |
1135 GEM_VideoQuit(_THIS) | 191 GEM_VideoQuit(_THIS) |
1136 { | 192 { |
1137 SDL_AtariXbios_RestoreVectors(); | 193 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; |
1138 if (GEM_usedevmouse) { | 194 |
1139 SDL_AtariDevMouse_Close(); | 195 GEM_QuitMouse(_this); |
1140 } | 196 GEM_QuitKeyboard(_this); |
1141 | 197 |
1142 GEM_FreeBuffers(this); | 198 GEM_QuitModes(_this); |
1143 | 199 |
1144 #if SDL_VIDEO_OPENGL | 200 /* Close VDI workstation */ |
1145 if (gl_active) { | 201 if (data->vdi_handle) { |
1146 SDL_AtariGL_Quit(this, SDL_TRUE); | 202 v_clsvwk(data->vdi_handle); |
1147 } | |
1148 #endif | |
1149 | |
1150 /* Destroy window */ | |
1151 if (GEM_handle >= 0) { | |
1152 wind_close(GEM_handle); | |
1153 wind_delete(GEM_handle); | |
1154 GEM_handle = -1; | |
1155 } | |
1156 | |
1157 GEM_UnlockScreen(this); | |
1158 if (GEM_menubar) { | |
1159 Mfree(GEM_menubar); | |
1160 GEM_menubar = NULL; | |
1161 } | 203 } |
1162 | 204 |
1163 appl_exit(); | 205 appl_exit(); |
1164 | 206 } |
1165 GEM_SetNewPalette(this, VDI_oldpalette); | 207 |
1166 | |
1167 /* Close VDI workstation */ | |
1168 if (VDI_handle) { | |
1169 v_clsvwk(VDI_handle); | |
1170 } | |
1171 | |
1172 /* Free mode list */ | |
1173 if (SDL_modelist[0]) { | |
1174 SDL_free(SDL_modelist[0]); | |
1175 SDL_modelist[0] = NULL; | |
1176 } | |
1177 | |
1178 this->screen->pixels = NULL; | |
1179 } | |
1180 | |
1181 void | |
1182 GEM_wind_redraw(_THIS, int winhandle, short *inside) | |
1183 { | |
1184 short todo[4]; | |
1185 | |
1186 /* Tell AES we are going to update */ | |
1187 wind_update(BEG_UPDATE); | |
1188 | |
1189 v_hide_c(VDI_handle); | |
1190 | |
1191 /* Browse the rectangle list to redraw */ | |
1192 if (wind_get | |
1193 (winhandle, WF_FIRSTXYWH, &todo[0], &todo[1], &todo[2], | |
1194 &todo[3]) != 0) { | |
1195 | |
1196 while (todo[2] && todo[3]) { | |
1197 | |
1198 if (rc_intersect((GRECT *) inside, (GRECT *) todo)) { | |
1199 todo[2] += todo[0] - 1; | |
1200 todo[3] += todo[1] - 1; | |
1201 refresh_window(this, winhandle, todo); | |
1202 } | |
1203 | |
1204 if (wind_get | |
1205 (winhandle, WF_NEXTXYWH, &todo[0], &todo[1], &todo[2], | |
1206 &todo[3]) == 0) { | |
1207 break; | |
1208 } | |
1209 } | |
1210 | |
1211 } | |
1212 | |
1213 /* Update finished */ | |
1214 wind_update(END_UPDATE); | |
1215 | |
1216 v_show_c(VDI_handle, 1); | |
1217 } | |
1218 | |
1219 static void | |
1220 refresh_window(_THIS, int winhandle, short *rect) | |
1221 { | |
1222 MFDB mfdb_src; | |
1223 short pxy[8], wind_pxy[8]; | |
1224 SDL_Surface *surface; | |
1225 int iconified; | |
1226 | |
1227 /* Is window iconified ? */ | |
1228 iconified = 0; | |
1229 /* if (GEM_wfeatures & (1<<WF_ICONIFY))*/ | |
1230 { | |
1231 if (wind_get | |
1232 (winhandle, WF_ICONIFY, &wind_pxy[0], &wind_pxy[1], &wind_pxy[2], | |
1233 &wind_pxy[3]) != 0) { | |
1234 iconified = wind_pxy[0]; | |
1235 } | |
1236 } | |
1237 | |
1238 if (wind_get | |
1239 (winhandle, WF_WORKXYWH, &wind_pxy[0], &wind_pxy[1], &wind_pxy[2], | |
1240 &wind_pxy[3]) == 0) { | |
1241 return; | |
1242 } | |
1243 | |
1244 if (iconified && GEM_icon) { | |
1245 short icon_rect[4], dst_rect[4]; | |
1246 short iconx, icony; | |
1247 | |
1248 surface = GEM_icon; | |
1249 | |
1250 GEM_ClearRect(this, rect); | |
1251 | |
1252 /* Calculate centered icon(x,y,w,h) relative to window */ | |
1253 iconx = (wind_pxy[2] - surface->w) >> 1; | |
1254 icony = (wind_pxy[3] - surface->h) >> 1; | |
1255 | |
1256 icon_rect[0] = iconx; | |
1257 icon_rect[1] = icony; | |
1258 icon_rect[2] = surface->w; | |
1259 icon_rect[3] = surface->h; | |
1260 | |
1261 /* Calculate redraw rectangle(x,y,w,h) relative to window */ | |
1262 dst_rect[0] = rect[0] - wind_pxy[0]; | |
1263 dst_rect[1] = rect[1] - wind_pxy[1]; | |
1264 dst_rect[2] = rect[2] - rect[0] + 1; | |
1265 dst_rect[3] = rect[3] - rect[1] + 1; | |
1266 | |
1267 /* Does the icon rectangle must be redrawn ? */ | |
1268 if (!rc_intersect((GRECT *) icon_rect, (GRECT *) dst_rect)) { | |
1269 return; | |
1270 } | |
1271 #if DEBUG_VIDEO_GEM | |
1272 printf("sdl:video:gem: clip(0,0,%d,%d) to (%d,%d,%d,%d)\n", | |
1273 surface->w - 1, surface->h - 1, dst_rect[0], dst_rect[1], | |
1274 dst_rect[2], dst_rect[3]); | |
1275 printf("sdl:video:gem: icon(%d,%d,%d,%d)\n", icon_rect[0], | |
1276 icon_rect[1], icon_rect[2], icon_rect[3]); | |
1277 printf("sdl:video:gem: refresh_window(): draw icon\n"); | |
1278 #endif | |
1279 | |
1280 /* Calculate icon(x1,y1,x2,y2) relative to screen */ | |
1281 icon_rect[0] += wind_pxy[0]; | |
1282 icon_rect[1] += wind_pxy[1]; | |
1283 icon_rect[2] += icon_rect[0] - 1; | |
1284 icon_rect[3] += icon_rect[1] - 1; | |
1285 | |
1286 /* Calculate intersection rectangle to redraw */ | |
1287 pxy[4] = pxy[0] = MAX(icon_rect[0], rect[0]); | |
1288 pxy[5] = pxy[1] = MAX(icon_rect[1], rect[1]); | |
1289 pxy[6] = pxy[2] = MIN(icon_rect[2], rect[2]); | |
1290 pxy[7] = pxy[3] = MIN(icon_rect[3], rect[3]); | |
1291 | |
1292 /* Calculate icon source image pos relative to window */ | |
1293 pxy[0] -= wind_pxy[0] + iconx; | |
1294 pxy[1] -= wind_pxy[1] + icony; | |
1295 pxy[2] -= wind_pxy[0] + iconx; | |
1296 pxy[3] -= wind_pxy[1] + icony; | |
1297 | |
1298 } else { | |
1299 surface = this->screen; | |
1300 | |
1301 #if DEBUG_VIDEO_GEM | |
1302 printf("sdl:video:gem: refresh_window(): draw frame buffer\n"); | |
1303 #endif | |
1304 | |
1305 /* Redraw all window content */ | |
1306 pxy[0] = rect[0] - wind_pxy[0]; | |
1307 pxy[1] = rect[1] - wind_pxy[1]; | |
1308 pxy[2] = rect[2] - wind_pxy[0]; | |
1309 pxy[3] = rect[3] - wind_pxy[1]; | |
1310 | |
1311 pxy[4] = rect[0]; | |
1312 pxy[5] = rect[1]; | |
1313 pxy[6] = rect[2]; | |
1314 pxy[7] = rect[3]; | |
1315 } | |
1316 | |
1317 if (GEM_bufops & B2S_C2P_1TO2) { | |
1318 void *src, *dest; | |
1319 int x1, x2; | |
1320 | |
1321 x1 = (rect[0] - wind_pxy[0]) & ~15; | |
1322 x2 = rect[2] - wind_pxy[0]; | |
1323 if (x2 & 15) { | |
1324 x2 = (x2 | 15) + 1; | |
1325 } | |
1326 | |
1327 src = surface->pixels; | |
1328 src += surface->pitch * (rect[1] - wind_pxy[1]); | |
1329 src += x1; | |
1330 | |
1331 dest = GEM_buffer2; | |
1332 dest += surface->pitch * (rect[1] - wind_pxy[1]); | |
1333 dest += x1; | |
1334 | |
1335 SDL_Atari_C2pConvert(src, dest, | |
1336 x2 - x1, rect[3] - rect[1] + 1, | |
1337 SDL_FALSE, surface->pitch, surface->pitch); | |
1338 } | |
1339 | |
1340 mfdb_src.fd_addr = surface->pixels; | |
1341 { | |
1342 int width; | |
1343 | |
1344 /* Need to be a multiple of 16 pixels */ | |
1345 width = surface->w; | |
1346 if ((width & 15) != 0) { | |
1347 width = (width | 15) + 1; | |
1348 } | |
1349 mfdb_src.fd_w = width; | |
1350 } | |
1351 mfdb_src.fd_h = surface->h; | |
1352 mfdb_src.fd_nplanes = surface->format->BitsPerPixel; | |
1353 mfdb_src.fd_wdwidth = mfdb_src.fd_w >> 4; | |
1354 mfdb_src.fd_stand = mfdb_src.fd_r1 = mfdb_src.fd_r2 = mfdb_src.fd_r3 = 0; | |
1355 | |
1356 if (GEM_bufops & B2S_VROCPYFM_2TOS) { | |
1357 mfdb_src.fd_addr = GEM_buffer2; | |
1358 } | |
1359 #if DEBUG_VIDEO_GEM | |
1360 printf("sdl:video:gem: redraw %dx%d: (%d,%d,%d,%d) to (%d,%d,%d,%d)\n", | |
1361 surface->w, surface->h, | |
1362 pxy[0], pxy[1], pxy[2], pxy[3], pxy[4], pxy[5], pxy[6], pxy[7]); | |
1363 #endif | |
1364 | |
1365 vro_cpyfm(VDI_handle, S_ONLY, pxy, &mfdb_src, &VDI_dst_mfdb); | |
1366 } | |
1367 | |
1368 #if SDL_VIDEO_OPENGL | |
1369 | |
1370 static void | |
1371 GEM_GL_SwapBuffers(_THIS) | |
1372 { | |
1373 SDL_AtariGL_SwapBuffers(this); | |
1374 GEM_FlipHWSurface(this, this->screen); | |
1375 } | |
1376 | |
1377 #endif | |
1378 /* vi: set ts=4 sw=4 expandtab: */ | 208 /* vi: set ts=4 sw=4 expandtab: */ |