0
|
1 /*
|
|
2 SDL - Simple DirectMedia Layer
|
|
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
|
|
4
|
|
5 This library is free software; you can redistribute it and/or
|
|
6 modify it under the terms of the GNU Library General Public
|
|
7 License as published by the Free Software Foundation; either
|
|
8 version 2 of the License, or (at your option) any later version.
|
|
9
|
|
10 This library is distributed in the hope that it will be useful,
|
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
13 Library General Public License for more details.
|
|
14
|
|
15 You should have received a copy of the GNU Library General Public
|
|
16 License along with this library; if not, write to the Free
|
|
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
18
|
|
19 Sam Lantinga
|
|
20 slouken@devolution.com
|
|
21 */
|
|
22
|
|
23 #ifdef SAVE_RCSID
|
|
24 static char rcsid =
|
|
25 "@(#) $Id$";
|
|
26 #endif
|
|
27
|
|
28 /* CGX based SDL video driver implementation.
|
|
29 */
|
|
30
|
|
31 /*
|
|
32 #include <stdlib.h>
|
|
33 #include <stdio.h>
|
|
34 #include <unistd.h>
|
|
35 #include <string.h>
|
|
36 #include <sys/ioctl.h>
|
|
37 #ifdef MTRR_SUPPORT
|
|
38 #include <asm/mtrr.h>
|
|
39 #include <sys/fcntl.h>
|
|
40 #endif
|
|
41 */
|
|
42
|
|
43 #include "SDL.h"
|
|
44 #include "SDL_error.h"
|
|
45 #include "SDL_timer.h"
|
|
46 #include "SDL_thread.h"
|
|
47 #include "SDL_video.h"
|
|
48 #include "SDL_mouse.h"
|
|
49 #include "SDL_endian.h"
|
|
50 #include "SDL_sysvideo.h"
|
|
51 #include "SDL_pixels_c.h"
|
|
52 #include "SDL_events_c.h"
|
|
53 #include "SDL_cgxvideo.h"
|
|
54 #include "SDL_cgxwm_c.h"
|
|
55 #include "SDL_amigamouse_c.h"
|
|
56 #include "SDL_amigaevents_c.h"
|
|
57 #include "SDL_cgxmodes_c.h"
|
|
58 #include "SDL_cgximage_c.h"
|
|
59 #include "SDL_cgxyuv_c.h"
|
|
60 #include "SDL_cgxgl_c.h"
|
|
61
|
|
62 /* Initialization/Query functions */
|
|
63 static int CGX_VideoInit(_THIS, SDL_PixelFormat *vformat);
|
|
64 static SDL_Surface *CGX_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
|
|
65 static int CGX_ToggleFullScreen(_THIS, int on);
|
|
66 static void CGX_UpdateMouse(_THIS);
|
|
67 static int CGX_SetColors(_THIS, int firstcolor, int ncolors,
|
|
68 SDL_Color *colors);
|
|
69 static void CGX_VideoQuit(_THIS);
|
|
70
|
|
71 /* CGX driver bootstrap functions */
|
|
72
|
|
73 struct Library *CyberGfxBase=NULL;
|
|
74 struct IntuitionBase *IntuitionBase=NULL;
|
|
75 struct GfxBase *GfxBase=NULL;
|
|
76
|
|
77 static void DestroyScreen(_THIS)
|
|
78 {
|
|
79 if(currently_fullscreen)
|
|
80 {
|
|
81 if(this->hidden->dbuffer)
|
|
82 {
|
|
83 extern struct MsgPort *safeport,*dispport;
|
|
84
|
|
85 this->hidden->dbuffer=0;
|
|
86
|
|
87 if(safeport)
|
|
88 {
|
|
89 while(GetMsg(safeport)!=NULL);
|
|
90 DeleteMsgPort(safeport);
|
|
91 }
|
|
92 if(dispport)
|
|
93 {
|
|
94 while(GetMsg(dispport)!=NULL);
|
|
95 DeleteMsgPort(dispport);
|
|
96 }
|
|
97
|
|
98 this->hidden->SB[0]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=this->hidden->SB[0]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort=NULL;
|
|
99 this->hidden->SB[1]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=this->hidden->SB[1]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort=NULL;
|
|
100
|
|
101 if(this->hidden->SB[1])
|
|
102 FreeScreenBuffer(SDL_Display,this->hidden->SB[0]);
|
|
103 if(this->hidden->SB[0])
|
|
104 FreeScreenBuffer(SDL_Display,this->hidden->SB[1]);
|
|
105
|
|
106
|
|
107 this->hidden->SB[0]=this->hidden->SB[1]=NULL;
|
|
108 free(SDL_RastPort);
|
|
109 SDL_RastPort=NULL;
|
|
110 this->hidden->dbuffer=0;
|
|
111 }
|
|
112 CloseScreen(GFX_Display);
|
|
113 }
|
|
114 else
|
|
115 UnlockPubScreen(NULL,GFX_Display);
|
|
116
|
|
117 GFX_Display = NULL;
|
|
118 }
|
|
119
|
|
120 static int CGX_Available(void)
|
|
121 {
|
|
122 struct Library *l;
|
|
123
|
|
124 l = OpenLibrary("cybergraphics.library",NULL);
|
|
125
|
|
126 if ( l != NULL ) {
|
|
127 CloseLibrary(l);
|
|
128 }
|
|
129 return(l != NULL);
|
|
130 }
|
|
131
|
|
132 static void CGX_DeleteDevice(SDL_VideoDevice *device)
|
|
133 {
|
|
134 if ( device ) {
|
|
135 if ( device->hidden ) {
|
|
136 free(device->hidden);
|
|
137 }
|
|
138 if ( device->gl_data ) {
|
|
139 free(device->gl_data);
|
|
140 }
|
|
141 free(device);
|
|
142 }
|
|
143 }
|
|
144
|
|
145 static SDL_VideoDevice *CGX_CreateDevice(int devindex)
|
|
146 {
|
|
147 SDL_VideoDevice *device;
|
|
148
|
|
149 /* Initialize all variables that we clean on shutdown */
|
|
150 device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice));
|
|
151 if ( device ) {
|
|
152 memset(device, 0, (sizeof *device));
|
|
153 device->hidden = (struct SDL_PrivateVideoData *)
|
|
154 malloc((sizeof *device->hidden));
|
|
155 device->gl_data = (struct SDL_PrivateGLData *)
|
|
156 malloc((sizeof *device->gl_data));
|
|
157 }
|
|
158 if ( (device == NULL) || (device->hidden == NULL) ||
|
|
159 (device->gl_data == NULL) ) {
|
|
160 SDL_OutOfMemory();
|
|
161 CGX_DeleteDevice(device);
|
|
162 return(0);
|
|
163 }
|
|
164 memset(device->hidden, 0, (sizeof *device->hidden));
|
|
165 memset(device->gl_data, 0, (sizeof *device->gl_data));
|
|
166
|
|
167 /* Set the driver flags */
|
|
168 device->handles_any_size = 1;
|
|
169
|
|
170 /* Set the function pointers */
|
|
171 device->VideoInit = CGX_VideoInit;
|
|
172 device->ListModes = CGX_ListModes;
|
|
173 device->SetVideoMode = CGX_SetVideoMode;
|
|
174 device->ToggleFullScreen = CGX_ToggleFullScreen;
|
|
175 device->UpdateMouse = CGX_UpdateMouse;
|
|
176 device->SetColors = CGX_SetColors;
|
|
177 device->UpdateRects = NULL;
|
|
178 device->VideoQuit = CGX_VideoQuit;
|
|
179 device->AllocHWSurface = CGX_AllocHWSurface;
|
|
180 device->CheckHWBlit = CGX_CheckHWBlit;
|
|
181 device->FillHWRect = CGX_FillHWRect;
|
|
182 device->SetHWColorKey = CGX_SetHWColorKey;
|
|
183 device->SetHWAlpha = NULL;
|
|
184 device->LockHWSurface = CGX_LockHWSurface;
|
|
185 device->UnlockHWSurface = CGX_UnlockHWSurface;
|
|
186 device->FlipHWSurface = CGX_FlipHWSurface;
|
|
187 device->FreeHWSurface = CGX_FreeHWSurface;
|
|
188 #ifdef HAVE_OPENGL
|
|
189 device->GL_LoadLibrary = X11_GL_LoadLibrary;
|
|
190 device->GL_GetProcAddress = X11_GL_GetProcAddress;
|
|
191 device->GL_GetAttribute = X11_GL_GetAttribute;
|
|
192 device->GL_MakeCurrent = X11_GL_MakeCurrent;
|
|
193 device->GL_SwapBuffers = X11_GL_SwapBuffers;
|
|
194 #endif
|
|
195 device->SetCaption = CGX_SetCaption;
|
|
196 device->SetIcon = CGX_SetIcon;
|
|
197 device->IconifyWindow = NULL; /* CGX_IconifyWindow; */
|
|
198 device->GrabInput = NULL /* CGX_GrabInput*/;
|
|
199 device->GetWMInfo = CGX_GetWMInfo;
|
|
200 device->FreeWMCursor = amiga_FreeWMCursor;
|
|
201 device->CreateWMCursor = amiga_CreateWMCursor;
|
|
202 device->ShowWMCursor = amiga_ShowWMCursor;
|
|
203 device->WarpWMCursor = amiga_WarpWMCursor;
|
|
204 device->CheckMouseMode = amiga_CheckMouseMode;
|
|
205 device->InitOSKeymap = amiga_InitOSKeymap;
|
|
206 device->PumpEvents = amiga_PumpEvents;
|
|
207
|
|
208 device->free = CGX_DeleteDevice;
|
|
209
|
|
210 return device;
|
|
211 }
|
|
212
|
|
213 VideoBootStrap CGX_bootstrap = {
|
|
214 "CGX", "Amiga CyberGFX video",
|
|
215 CGX_Available, CGX_CreateDevice
|
|
216 };
|
|
217
|
|
218
|
|
219 Uint32 MakeBitMask(_THIS,int type,int format,int *bpp)
|
|
220 {
|
|
221 D(if(type==0)bug("REAL pixel format: "));
|
|
222
|
|
223 if(this->hidden->depth==*bpp)
|
|
224 {
|
|
225
|
|
226 switch(format)
|
|
227 {
|
|
228 case PIXFMT_LUT8:
|
|
229 D(if(type==0)bug("LUT8\n"));
|
|
230 return 0;
|
|
231 case PIXFMT_BGR15:
|
|
232 case PIXFMT_RGB15PC:
|
|
233 switch(type)
|
|
234 {
|
|
235 case 0:
|
|
236 D(bug("RGB15PC/BGR15\n"));
|
|
237 return 31;
|
|
238 case 1:
|
|
239 return 992;
|
|
240 case 2:
|
|
241 return 31744;
|
|
242 }
|
|
243 case PIXFMT_RGB15:
|
|
244 case PIXFMT_BGR15PC:
|
|
245 switch(type)
|
|
246 {
|
|
247 case 0:
|
|
248 D(bug("RGB15/BGR15PC\n"));
|
|
249 return 31744;
|
|
250 case 1:
|
|
251 return 992;
|
|
252 case 2:
|
|
253 return 31;
|
|
254 }
|
|
255 case PIXFMT_BGR16PC:
|
|
256 case PIXFMT_RGB16:
|
|
257 switch(type)
|
|
258 {
|
|
259 case 0:
|
|
260 D(bug("RGB16PC\n"));
|
|
261 return 63488;
|
|
262 case 1:
|
|
263 return 2016;
|
|
264 case 2:
|
|
265 return 31;
|
|
266 }
|
|
267 case PIXFMT_BGR16:
|
|
268 case PIXFMT_RGB16PC:
|
|
269 switch(type)
|
|
270 {
|
|
271 case 0:
|
|
272 D(bug("RGB16PC/BGR16\n"));
|
|
273 return 31;
|
|
274 case 1:
|
|
275 return 2016;
|
|
276 case 2:
|
|
277 return 63488;
|
|
278 }
|
|
279
|
|
280 case PIXFMT_RGB24:
|
|
281 switch(type)
|
|
282 {
|
|
283 case 0:
|
|
284 D(bug("RGB24/BGR24\n"));
|
|
285 return 0xff0000;
|
|
286 case 1:
|
|
287 return 0xff00;
|
|
288 case 2:
|
|
289 return 0xff;
|
|
290 }
|
|
291 case PIXFMT_BGR24:
|
|
292 switch(type)
|
|
293 {
|
|
294 case 0:
|
|
295 D(bug("BGR24\n"));
|
|
296 return 0xff;
|
|
297 case 1:
|
|
298 return 0xff00;
|
|
299 case 2:
|
|
300 return 0xff0000;
|
|
301 }
|
|
302 case PIXFMT_ARGB32:
|
|
303 switch(type)
|
|
304 {
|
|
305 case 0:
|
|
306 D(bug("ARGB32\n"));
|
|
307 return 0xff0000;
|
|
308 case 1:
|
|
309 return 0xff00;
|
|
310 case 2:
|
|
311 return 0xff;
|
|
312 }
|
|
313 case PIXFMT_BGRA32:
|
|
314 switch(type)
|
|
315 {
|
|
316 case 0:
|
|
317 D(bug("BGRA32\n"));
|
|
318 return 0xff00;
|
|
319 case 1:
|
|
320 return 0xff0000;
|
|
321 case 2:
|
|
322 return 0xff000000;
|
|
323 }
|
|
324 case PIXFMT_RGBA32:
|
|
325 switch(type)
|
|
326 {
|
|
327 case 0:
|
|
328 D(bug("RGBA32\n"));
|
|
329 return 0xff000000;
|
|
330 case 1:
|
|
331 return 0xff0000;
|
|
332 case 2:
|
|
333 return 0xff00;
|
|
334 }
|
|
335 default:
|
|
336 D(bug("Unknown pixel format! Default to 24bit\n"));
|
|
337 return (Uint32) (255<<(type*8));
|
|
338 }
|
|
339 }
|
|
340 else
|
|
341 {
|
|
342 D(if(type==0)bug("DIFFERENT from screen.\nAllocated screen format: "));
|
|
343
|
|
344 switch(*bpp)
|
|
345 {
|
|
346 case 32:
|
|
347 D(if(type==0) bug("RGBA32\n"));
|
|
348 switch(type)
|
|
349 {
|
|
350 case 0:
|
|
351 return 0xff000000;
|
|
352 case 1:
|
|
353 return 0xff0000;
|
|
354 case 2:
|
|
355 return 0xff00;
|
|
356 }
|
|
357 break;
|
|
358 case 24:
|
|
359 use_truecolor:
|
|
360 switch(type)
|
|
361 {
|
|
362 case 0:
|
|
363 D(bug("RGB24\n"));
|
|
364 return 0xff0000;
|
|
365 case 1:
|
|
366 return 0xff00;
|
|
367 case 2:
|
|
368 return 0xff;
|
|
369 }
|
|
370 case 16:
|
|
371 case 15:
|
|
372 D(if(type==0) bug("Not supported, switching to 24bit!\n"));
|
|
373 *bpp=24;
|
|
374 goto use_truecolor;
|
|
375 break;
|
|
376 default:
|
|
377 D(if(type==0)bug("This is a chunky display\n"));
|
|
378 // For chunky display mask is always 0;
|
|
379 return 0;
|
|
380 }
|
|
381 }
|
|
382 return 0;
|
|
383 }
|
|
384
|
|
385 static int CGX_VideoInit(_THIS, SDL_PixelFormat *vformat)
|
|
386 {
|
|
387 int i;
|
|
388
|
|
389 if(!(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",39L)))
|
|
390 {
|
|
391 SDL_SetError("Couldn't open intuition V39+");
|
|
392 return -1;
|
|
393 }
|
|
394 if(!(GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",39L)))
|
|
395 {
|
|
396 SDL_SetError("Couldn't open graphics V39+");
|
|
397 return -1;
|
|
398 }
|
|
399 if(!(CyberGfxBase=OpenLibrary("cybergraphics.library",40L)))
|
|
400 {
|
|
401 SDL_SetError("Couldn't open cybergraphics.");
|
|
402 return(-1);
|
|
403 }
|
|
404
|
|
405 SDL_Display = LockPubScreen(NULL);
|
|
406
|
|
407 if ( SDL_Display == NULL ) {
|
|
408 SDL_SetError("Couldn't lock the display");
|
|
409 return(-1);
|
|
410 }
|
|
411
|
|
412 if(!IsCyberModeID(GetVPModeID(&SDL_Display->ViewPort)))
|
|
413 {
|
|
414 Uint32 okid=BestCModeIDTags(CYBRBIDTG_NominalWidth,SDL_Display->Width,
|
|
415 CYBRBIDTG_NominalHeight,SDL_Display->Height,
|
|
416 CYBRBIDTG_Depth,8,
|
|
417 TAG_DONE);
|
|
418
|
|
419 UnlockPubScreen(NULL,SDL_Display);
|
|
420
|
|
421 GFX_Display=NULL;
|
|
422
|
|
423 if(okid!=INVALID_ID)
|
|
424 {
|
|
425 GFX_Display=OpenScreenTags(NULL,
|
|
426 SA_Width,SDL_Display->Width,
|
|
427 SA_Height,SDL_Display->Height,
|
|
428 SA_Depth,8,SA_Quiet,TRUE,
|
|
429 SA_ShowTitle,FALSE,
|
|
430 SA_DisplayID,okid,
|
|
431 TAG_DONE);
|
|
432 }
|
|
433
|
|
434 if(!GFX_Display)
|
|
435 {
|
|
436 SDL_SetError("Unable to open a suited CGX display");
|
|
437 return -1;
|
|
438 }
|
|
439 else SDL_Display=GFX_Display;
|
|
440
|
|
441 }
|
|
442 else GFX_Display = SDL_Display;
|
|
443
|
|
444
|
|
445 /* See whether or not we need to swap pixels */
|
|
446
|
|
447 swap_pixels = 0;
|
|
448
|
|
449 // Non e' detto che sia cosi' pero', alcune schede potrebbero gestire i modi in modo differente
|
|
450
|
|
451 if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) {
|
|
452 swap_pixels = 1;
|
|
453 }
|
|
454
|
|
455 /* Get the available video modes */
|
|
456 if(CGX_GetVideoModes(this) < 0)
|
|
457 return -1;
|
|
458
|
|
459 /* Determine the default screen depth:
|
|
460 Use the default visual (or at least one with the same depth) */
|
|
461
|
|
462 for(i = 0; i < this->hidden->nvisuals; i++)
|
|
463 if(this->hidden->visuals[i].depth == GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH))
|
|
464 break;
|
|
465 if(i == this->hidden->nvisuals) {
|
|
466 /* default visual was useless, take the deepest one instead */
|
|
467 i = 0;
|
|
468 }
|
|
469 SDL_Visual = this->hidden->visuals[i].visual;
|
|
470
|
|
471 this->hidden->depth = this->hidden->visuals[i].depth;
|
|
472 D(bug("Setto la profiondita' dello schermo a: %ld\n",this->hidden->depth));
|
|
473 vformat->BitsPerPixel = this->hidden->visuals[i].depth; /* this->hidden->visuals[i].bpp; */
|
|
474
|
|
475 {
|
|
476 int form;
|
|
477 APTR handle;
|
|
478 struct DisplayInfo info;
|
|
479
|
|
480 if(!(handle=FindDisplayInfo(this->hidden->visuals[i].visual)))
|
|
481 return -1;
|
|
482
|
|
483 if(!GetDisplayInfoData(handle,(char *)&info,sizeof(struct DisplayInfo),DTAG_DISP,NULL))
|
|
484 return -1;
|
|
485
|
|
486 form=GetCyberIDAttr(CYBRIDATTR_PIXFMT,SDL_Visual);
|
|
487
|
|
488 // In this case I use makebitmask in a way that I'm sure I'll get PIXFMT pixel mask
|
|
489
|
|
490 if ( vformat->BitsPerPixel > 8 )
|
|
491 {
|
|
492 vformat->Rmask = MakeBitMask(this,0,form,&this->hidden->depth);
|
|
493 vformat->Gmask = MakeBitMask(this,1,form,&this->hidden->depth);
|
|
494 vformat->Bmask = MakeBitMask(this,2,form,&this->hidden->depth);
|
|
495 }
|
|
496 }
|
|
497
|
|
498 /* Create the fullscreen and managed windows */
|
|
499 // create_aux_windows(this);
|
|
500
|
|
501 /* Create the blank cursor */
|
|
502 SDL_BlankCursor = AllocMem(16,MEMF_CHIP|MEMF_CLEAR);
|
|
503
|
|
504 /* Fill in some window manager capabilities */
|
|
505 this->info.wm_available = 1;
|
|
506 this->info.blit_hw = 1;
|
|
507 this->info.blit_hw_CC = 1;
|
|
508 this->info.blit_sw = 1;
|
|
509 this->info.blit_fill = 1;
|
|
510 this->info.video_mem=2000000; // Not always true but almost any Amiga card has this memory!
|
|
511
|
|
512 this->hidden->same_format=0;
|
|
513 SDL_RastPort=&SDL_Display->RastPort;
|
|
514 /* We're done! */
|
|
515 return(0);
|
|
516 }
|
|
517
|
|
518 void CGX_DestroyWindow(_THIS, SDL_Surface *screen)
|
|
519 {
|
|
520 /* Hide the managed window */
|
|
521 int was_fullscreen=0;
|
|
522
|
|
523 if ( screen && (screen->flags & SDL_FULLSCREEN) ) {
|
|
524 was_fullscreen=1;
|
|
525 screen->flags &= ~SDL_FULLSCREEN;
|
|
526 CGX_LeaveFullScreen(this);
|
|
527 }
|
|
528
|
|
529 /* Destroy the output window */
|
|
530 if ( SDL_Window ) {
|
|
531 CloseWindow(SDL_Window);
|
|
532 SDL_Window=NULL;
|
|
533 }
|
|
534
|
|
535 /* Free the colormap entries */
|
|
536 if ( SDL_XPixels ) {
|
|
537 int numcolors;
|
|
538 unsigned long pixel;
|
|
539
|
|
540 if(this->screen->format&&this->hidden->depth==8&&!was_fullscreen)
|
|
541 {
|
|
542 numcolors = 1<<this->screen->format->BitsPerPixel;
|
|
543
|
|
544 if(numcolors>256)
|
|
545 numcolors=256;
|
|
546
|
|
547 if(!was_fullscreen&&this->hidden->depth==8)
|
|
548 {
|
|
549 for ( pixel=0; pixel<numcolors; pixel++ )
|
|
550 {
|
|
551 if(SDL_XPixels[pixel]>=0)
|
|
552 ReleasePen(GFX_Display->ViewPort.ColorMap,SDL_XPixels[pixel]);
|
|
553 }
|
|
554 }
|
|
555 }
|
|
556 free(SDL_XPixels);
|
|
557 SDL_XPixels = NULL;
|
|
558 }
|
|
559 }
|
|
560
|
|
561 static void CGX_SetSizeHints(_THIS, int w, int h, Uint32 flags)
|
|
562 {
|
|
563 if ( flags & SDL_RESIZABLE ) {
|
|
564 WindowLimits(SDL_Window, 32, 32,4096,4096);
|
|
565 } else {
|
|
566 WindowLimits(SDL_Window, w,h,w,h);
|
|
567 }
|
|
568 if ( flags & SDL_FULLSCREEN ) {
|
|
569 flags&=~SDL_RESIZABLE;
|
|
570 } else if ( getenv("SDL_VIDEO_CENTERED") ) {
|
|
571 int display_w, display_h;
|
|
572
|
|
573 display_w = SDL_Display->Width;
|
|
574 display_h = SDL_Display->Height;
|
|
575 ChangeWindowBox(SDL_Window,(display_w - w - SDL_Window->BorderLeft-SDL_Window->BorderRight)/2,
|
|
576 (display_h - h - SDL_Window->BorderTop-SDL_Window->BorderBottom)/2,
|
|
577 w+SDL_Window->BorderLeft+SDL_Window->BorderRight,
|
|
578 h+SDL_Window->BorderTop+SDL_Window->BorderBottom);
|
|
579 }
|
|
580 }
|
|
581
|
|
582 int CGX_CreateWindow(_THIS, SDL_Surface *screen,
|
|
583 int w, int h, int bpp, Uint32 flags)
|
|
584 {
|
|
585 #if 0
|
|
586 int i, depth;
|
|
587 Uint32 vis;
|
|
588 #endif
|
|
589 /* If a window is already present, destroy it and start fresh */
|
|
590 if ( SDL_Window ) {
|
|
591 CGX_DestroyWindow(this, screen);
|
|
592 }
|
|
593 SDL_Window = 0;
|
|
594
|
|
595 /* find out which visual we are going to use */
|
|
596 #if 0
|
|
597 /* questo l'ho spostato nell'apertura dello schermo, in quanto su Amiga le finestre
|
|
598 hanno il pixel mode degli schermi.
|
|
599 */
|
|
600 if ( flags & SDL_OPENGL ) {
|
|
601 SDL_SetError("OpenGL not supported by the Amiga SDL!");
|
|
602 return -1;
|
|
603 }
|
|
604 else {
|
|
605 for ( i = 0; i < this->hidden->nvisuals; i++ ) {
|
|
606 if ( this->hidden->visuals[i].depth == bpp ) /* era .depth */
|
|
607 break;
|
|
608 }
|
|
609 if ( i == this->hidden->nvisuals ) {
|
|
610 SDL_SetError("No matching visual for requested depth");
|
|
611 return -1; /* should never happen */
|
|
612 }
|
|
613 vis = this->hidden->visuals[i].visual;
|
|
614 depth = this->hidden->visuals[i].depth;
|
|
615 }
|
|
616 SDL_Visual = vis;
|
|
617 this->hidden->depth = depth;
|
|
618 D(bug("Setto la profiondita' dello schermo a: %ld\n",this->hidden->depth));
|
|
619 #endif
|
|
620
|
|
621 /* Allocate the new pixel format for this video mode */
|
|
622 {
|
|
623 Uint32 form;
|
|
624 APTR handle;
|
|
625 struct DisplayInfo info;
|
|
626
|
|
627 if(!(handle=FindDisplayInfo(SDL_Visual)))
|
|
628 return -1;
|
|
629
|
|
630 if(!GetDisplayInfoData(handle,(char *)&info,sizeof(struct DisplayInfo),DTAG_DISP,NULL))
|
|
631 return -1;
|
|
632
|
|
633 form=GetCyberIDAttr(CYBRIDATTR_PIXFMT,SDL_Visual);
|
|
634
|
|
635 if(flags&SDL_HWSURFACE)
|
|
636 {
|
|
637 if(bpp!=this->hidden->depth)
|
|
638 {
|
|
639 bpp=this->hidden->depth;
|
|
640 D(bug("Accel forces bpp to be equal (%ld)\n",bpp));
|
|
641 }
|
|
642 }
|
|
643
|
|
644 D(bug("BEFORE screen allocation: bpp:%ld (real:%ld)\n",bpp,this->hidden->depth));
|
|
645
|
|
646 /* With this call if needed I'll revert the wanted bpp to a bpp best suited for the display, actually occurs
|
|
647 only with requested format 15/16bit and display format != 15/16bit
|
|
648 */
|
|
649
|
|
650 if ( ! SDL_ReallocFormat(screen, bpp,
|
|
651 MakeBitMask(this,0,form,&bpp), MakeBitMask(this,1,form,&bpp), MakeBitMask(this,2,form,&bpp), 0) )
|
|
652 return -1;
|
|
653
|
|
654 D(bug("AFTER screen allocation: bpp:%ld (real:%ld)\n",bpp,this->hidden->depth));
|
|
655
|
|
656 }
|
|
657
|
|
658 /* Create the appropriate colormap */
|
|
659 if ( GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_PIXFMT)==PIXFMT_LUT8 || bpp==8 ) {
|
|
660 int ncolors;
|
|
661 D(bug("Alloco XPixels x la palette...\n"));
|
|
662
|
|
663 /* Allocate the pixel flags */
|
|
664
|
|
665 if(bpp==8)
|
|
666 ncolors=256;
|
|
667 else
|
|
668 ncolors = 1 << screen->format->BitsPerPixel;
|
|
669
|
|
670 SDL_XPixels = (Sint32 *)malloc(ncolors * sizeof(Sint32));
|
|
671
|
|
672 if(SDL_XPixels == NULL) {
|
|
673 SDL_OutOfMemory();
|
|
674 return -1;
|
|
675 }
|
|
676
|
|
677 memset(SDL_XPixels, -1, ncolors * sizeof(Sint32));
|
|
678
|
|
679 /* always allocate a private colormap on non-default visuals */
|
|
680 if(bpp==8)
|
|
681 flags |= SDL_HWPALETTE;
|
|
682
|
|
683 if ( flags & SDL_HWPALETTE ) {
|
|
684 screen->flags |= SDL_HWPALETTE;
|
|
685 }
|
|
686 }
|
|
687
|
|
688 /* resize the (possibly new) window manager window */
|
|
689
|
|
690 /* Create (or use) the X11 display window */
|
|
691 if ( flags & SDL_OPENGL ) {
|
|
692 return(-1);
|
|
693 } else {
|
|
694 if(flags & SDL_FULLSCREEN)
|
|
695 SDL_Window = OpenWindowTags(NULL,WA_Width,w,WA_Height,h,
|
|
696 WA_Flags,WFLG_ACTIVATE|WFLG_RMBTRAP|WFLG_BORDERLESS|WFLG_BACKDROP|WFLG_REPORTMOUSE,
|
|
697 WA_IDCMP,IDCMP_RAWKEY|IDCMP_MOUSEBUTTONS|IDCMP_MOUSEMOVE,
|
|
698 WA_CustomScreen,(ULONG)SDL_Display,
|
|
699 TAG_DONE);
|
|
700 else
|
|
701 SDL_Window = OpenWindowTags(NULL,WA_InnerWidth,w,WA_InnerHeight,h,
|
|
702 WA_Flags,WFLG_REPORTMOUSE|WFLG_ACTIVATE|WFLG_RMBTRAP|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_DRAGBAR| ((screen->flags&SDL_RESIZABLE) ? WFLG_SIZEGADGET|WFLG_SIZEBBOTTOM : 0),
|
|
703 WA_IDCMP,IDCMP_RAWKEY|IDCMP_CLOSEWINDOW|IDCMP_MOUSEBUTTONS|IDCMP_NEWSIZE|IDCMP_MOUSEMOVE,
|
|
704 WA_PubScreen,(ULONG)SDL_Display,
|
|
705 TAG_DONE);
|
|
706 }
|
|
707 /* Only manage our input if we own the window */
|
|
708 if(!SDL_Window)
|
|
709 return -1;
|
|
710
|
|
711 this->hidden->BytesPerPixel=GetCyberMapAttr(SDL_Window->RPort->BitMap,CYBRMATTR_BPPIX);
|
|
712
|
|
713 if(screen->flags & SDL_DOUBLEBUF)
|
|
714 {
|
|
715 if(SDL_RastPort=malloc(sizeof(struct RastPort)))
|
|
716 {
|
|
717 InitRastPort(SDL_RastPort);
|
|
718 SDL_RastPort->BitMap=this->hidden->SB[1]->sb_BitMap;
|
|
719 }
|
|
720 else
|
|
721 return -1;
|
|
722 }
|
|
723 else SDL_RastPort=SDL_Window->RPort;
|
|
724 #if 0
|
|
725
|
|
726 if(screen->flags & SDL_HWPALETTE) {
|
|
727 /* Since the full-screen window might have got a nonzero background
|
|
728 colour (0 is white on some displays), we should reset the
|
|
729 background to 0 here since that is what the user expects
|
|
730 with a private colormap */
|
|
731 SetAPen(SDL_Window->RPort,0);
|
|
732 RectFill(SDL_Window->RPort,SDL_Window->BorderLeft,SDL_Window->BorderTop,w+SDL_Window->BorderLeft,h+SDL_Window->BorderTop);
|
|
733 }
|
|
734 #endif
|
|
735
|
|
736 if(flags&SDL_HWSURFACE)
|
|
737 screen->flags|=SDL_HWSURFACE;
|
|
738
|
|
739 CGX_SetSizeHints(this, w, h, flags);
|
|
740 current_w = w;
|
|
741 current_h = h;
|
|
742
|
|
743 /* Map them both and go fullscreen, if requested */
|
|
744 if ( flags & SDL_FULLSCREEN ) {
|
|
745 screen->flags |= SDL_FULLSCREEN;
|
|
746 currently_fullscreen=1;
|
|
747 // CGX_EnterFullScreen(this); Ci siamo gia'!
|
|
748 } else {
|
|
749 screen->flags &= ~SDL_FULLSCREEN;
|
|
750 }
|
|
751 return(0);
|
|
752 }
|
|
753
|
|
754 int CGX_ResizeWindow(_THIS,
|
|
755 SDL_Surface *screen, int w, int h, Uint32 flags)
|
|
756 {
|
|
757 /* Resize the window manager window */
|
|
758 CGX_SetSizeHints(this, w, h, flags);
|
|
759 current_w = w;
|
|
760 current_h = h;
|
|
761
|
|
762 ChangeWindowBox(SDL_Window,SDL_Window->LeftEdge,SDL_Window->TopEdge, w+SDL_Window->BorderLeft+SDL_Window->BorderRight,
|
|
763 h+SDL_Window->BorderTop+SDL_Window->BorderBottom);
|
|
764
|
|
765 /* Resize the fullscreen and display windows */
|
|
766 if ( flags & SDL_FULLSCREEN ) {
|
|
767 if ( screen->flags & SDL_FULLSCREEN ) {
|
|
768 CGX_ResizeFullScreen(this);
|
|
769 } else {
|
|
770 screen->flags |= SDL_FULLSCREEN;
|
|
771 CGX_EnterFullScreen(this);
|
|
772 }
|
|
773 } else {
|
|
774 if ( screen->flags & SDL_FULLSCREEN ) {
|
|
775 screen->flags &= ~SDL_FULLSCREEN;
|
|
776 CGX_LeaveFullScreen(this);
|
|
777 }
|
|
778 }
|
|
779 return(0);
|
|
780 }
|
|
781
|
|
782 static SDL_Surface *CGX_SetVideoMode(_THIS, SDL_Surface *current,
|
|
783 int width, int height, int bpp, Uint32 flags)
|
|
784 {
|
|
785 Uint32 saved_flags;
|
|
786
|
|
787 /* Lock the event thread, in multi-threading environments */
|
|
788 SDL_Lock_EventThread();
|
|
789
|
|
790 // Check if we need to close an already existing videomode...
|
|
791
|
|
792 if(current->flags&SDL_FULLSCREEN && !(flags&SDL_FULLSCREEN))
|
|
793 {
|
|
794 CGX_DestroyImage(this,current);
|
|
795 CGX_DestroyWindow(this,current);
|
|
796 DestroyScreen(this);
|
|
797 }
|
|
798 /* Check the combination of flags we were passed */
|
|
799 if ( flags & SDL_FULLSCREEN ) {
|
|
800 int i;
|
|
801
|
|
802 /* Clear fullscreen flag if not supported */
|
|
803 if(current->flags&SDL_FULLSCREEN )
|
|
804 {
|
|
805 if(current->w!=width ||
|
|
806 current->h!=height ||
|
|
807 this->hidden->depth!=bpp)
|
|
808 {
|
|
809 CGX_DestroyImage(this,current);
|
|
810 CGX_DestroyWindow(this,current);
|
|
811 DestroyScreen(this);
|
|
812 goto buildnewscreen;
|
|
813 }
|
|
814 }
|
|
815 else
|
|
816 buildnewscreen:
|
|
817 {
|
|
818 Uint32 okid=BestCModeIDTags(CYBRBIDTG_NominalWidth,width,
|
|
819 CYBRBIDTG_NominalHeight,height,
|
|
820 CYBRBIDTG_Depth,bpp,
|
|
821 TAG_DONE);
|
|
822
|
|
823 GFX_Display=NULL;
|
|
824
|
|
825 if(okid!=INVALID_ID)
|
|
826 {
|
|
827 GFX_Display=OpenScreenTags(NULL,
|
|
828 SA_Width,width,
|
|
829 SA_Height,height,
|
|
830 SA_Quiet,TRUE,SA_ShowTitle,FALSE,
|
|
831 SA_Depth,bpp,
|
|
832 SA_DisplayID,okid,
|
|
833 TAG_DONE);
|
|
834 }
|
|
835
|
|
836
|
|
837 if(!GFX_Display)
|
|
838 {
|
|
839 GFX_Display=SDL_Display;
|
|
840 flags &= ~SDL_FULLSCREEN;
|
|
841 flags &= ~SDL_DOUBLEBUF;
|
|
842 }
|
|
843 else
|
|
844 {
|
|
845 UnlockPubScreen(NULL,SDL_Display);
|
|
846 SDL_Display=GFX_Display;
|
|
847
|
|
848 if(flags&SDL_DOUBLEBUF)
|
|
849 {
|
|
850 int ok=0;
|
|
851
|
|
852 if(this->hidden->SB[0]=AllocScreenBuffer(SDL_Display,NULL,SB_SCREEN_BITMAP))
|
|
853 {
|
|
854 if(this->hidden->SB[1]=AllocScreenBuffer(SDL_Display,NULL,0L))
|
|
855 {
|
|
856 extern struct MsgPort *safeport,*dispport;
|
|
857
|
|
858 safeport=CreateMsgPort();
|
|
859 dispport=CreateMsgPort();
|
|
860
|
|
861 if(!safeport || !dispport)
|
|
862 {
|
|
863 if(safeport)
|
|
864 {
|
|
865 DeleteMsgPort(safeport);
|
|
866 safeport=NULL;
|
|
867 }
|
|
868 if(dispport)
|
|
869 {
|
|
870 DeleteMsgPort(dispport);
|
|
871 dispport=NULL;
|
|
872 }
|
|
873 FreeScreenBuffer(SDL_Display,this->hidden->SB[0]);
|
|
874 FreeScreenBuffer(SDL_Display,this->hidden->SB[1]);
|
|
875 }
|
|
876 else
|
|
877 {
|
|
878 extern ULONG safe_sigbit,disp_sigbit;
|
|
879 int i;
|
|
880
|
|
881 safe_sigbit=1L<< safeport->mp_SigBit;
|
|
882 disp_sigbit=1L<< dispport->mp_SigBit;
|
|
883
|
|
884 for(i=0;i<2;i++)
|
|
885 {
|
|
886 this->hidden->SB[i]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort=safeport;
|
|
887 this->hidden->SB[i]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort=dispport;
|
|
888 }
|
|
889
|
|
890 ok=1;
|
|
891 D(bug("Dbuffering enabled!\n"));
|
|
892 this->hidden->dbuffer=1;
|
|
893 current->flags|=SDL_DOUBLEBUF;
|
|
894 }
|
|
895 }
|
|
896 else
|
|
897 {
|
|
898 FreeScreenBuffer(SDL_Display,this->hidden->SB[1]);
|
|
899 this->hidden->SB[0]=NULL;
|
|
900 }
|
|
901 }
|
|
902
|
|
903 if(!ok)
|
|
904 {
|
|
905 flags&=~SDL_DOUBLEBUF;
|
|
906 }
|
|
907 }
|
|
908 }
|
|
909
|
|
910 if(GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH)==bpp)
|
|
911 this->hidden->same_format=1;
|
|
912 }
|
|
913
|
|
914 bpp=this->hidden->depth=GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_DEPTH);
|
|
915 D(bug("Setto la profiondita' dello schermo a: %ld\n",this->hidden->depth));
|
|
916
|
|
917 for ( i = 0; i < this->hidden->nvisuals; i++ ) {
|
|
918 if ( this->hidden->visuals[i].depth == bpp ) /* era .depth */
|
|
919 break;
|
|
920 }
|
|
921 if ( i == this->hidden->nvisuals ) {
|
|
922 SDL_SetError("No matching visual for requested depth");
|
|
923 return NULL; /* should never happen */
|
|
924 }
|
|
925 SDL_Visual = this->hidden->visuals[i].visual;
|
|
926
|
|
927 }
|
|
928
|
|
929 /* Set up the X11 window */
|
|
930 saved_flags = current->flags;
|
|
931
|
|
932 if (SDL_Window && (saved_flags&SDL_OPENGL) == (flags&SDL_OPENGL)
|
|
933 && bpp == current->format->BitsPerPixel) {
|
|
934 if (CGX_ResizeWindow(this, current, width, height, flags) < 0) {
|
|
935 current = NULL;
|
|
936 goto done;
|
|
937 }
|
|
938 } else {
|
|
939 if (CGX_CreateWindow(this,current,width,height,bpp,flags) < 0) {
|
|
940 current = NULL;
|
|
941 goto done;
|
|
942 }
|
|
943 }
|
|
944
|
|
945 /* Set up the new mode framebuffer */
|
|
946 if ( ((current->w != width) || (current->h != height)) ||
|
|
947 ((saved_flags&SDL_OPENGL) != (flags&SDL_OPENGL)) ) {
|
|
948 current->w = width;
|
|
949 current->h = height;
|
|
950 current->pitch = SDL_CalculatePitch(current);
|
|
951 CGX_ResizeImage(this, current, flags);
|
|
952 }
|
|
953 current->flags |= (flags&SDL_RESIZABLE); // Resizable only if the user asked it
|
|
954
|
|
955 done:
|
|
956 /* Release the event thread */
|
|
957 SDL_Unlock_EventThread();
|
|
958
|
|
959 /* We're done! */
|
|
960 return(current);
|
|
961 }
|
|
962
|
|
963 static int CGX_ToggleFullScreen(_THIS, int on)
|
|
964 {
|
|
965 Uint32 event_thread;
|
|
966
|
|
967 /* Don't lock if we are the event thread */
|
|
968 event_thread = SDL_EventThreadID();
|
|
969 if ( event_thread && (SDL_ThreadID() == event_thread) ) {
|
|
970 event_thread = 0;
|
|
971 }
|
|
972 if ( event_thread ) {
|
|
973 SDL_Lock_EventThread();
|
|
974 }
|
|
975 if ( on ) {
|
|
976 this->screen->flags |= SDL_FULLSCREEN;
|
|
977 CGX_EnterFullScreen(this);
|
|
978 } else {
|
|
979 this->screen->flags &= ~SDL_FULLSCREEN;
|
|
980 CGX_LeaveFullScreen(this);
|
|
981 }
|
|
982 CGX_RefreshDisplay(this);
|
|
983 if ( event_thread ) {
|
|
984 SDL_Unlock_EventThread();
|
|
985 }
|
|
986 SDL_ResetKeyboard();
|
|
987 return(1);
|
|
988 }
|
|
989
|
|
990 static void SetSingleColor(Uint32 fmt, unsigned char r, unsigned char g, unsigned char b, unsigned char *c)
|
|
991 {
|
|
992 switch(fmt)
|
|
993 {
|
|
994 case PIXFMT_BGR15:
|
|
995 case PIXFMT_RGB15PC:
|
|
996 {
|
|
997 Uint16 *t=(Uint16 *)c;
|
|
998 *t=(r>>3) | ((g>>3)<<5) | ((b>>3)<<10) ;
|
|
999 }
|
|
1000 break;
|
|
1001 case PIXFMT_RGB15:
|
|
1002 case PIXFMT_BGR15PC:
|
|
1003 {
|
|
1004 Uint16 *t=(Uint16 *)c;
|
|
1005 *t=(b>>3) | ((g>>3)<<5) | ((r>>3)<<10) ;
|
|
1006 }
|
|
1007 break;
|
|
1008 case PIXFMT_BGR16PC:
|
|
1009 case PIXFMT_RGB16:
|
|
1010 {
|
|
1011 Uint16 *t=(Uint16 *)c;
|
|
1012 *t=(b>>3) | ((g>>2)<<5) | ((r>>3)<<11) ;
|
|
1013 }
|
|
1014 break;
|
|
1015 case PIXFMT_BGR16:
|
|
1016 case PIXFMT_RGB16PC:
|
|
1017 {
|
|
1018 Uint16 *t=(Uint16 *)c;
|
|
1019 *t=(r>>3) | ((g>>2)<<5) | ((b>>3)<<11) ;
|
|
1020 }
|
|
1021 break;
|
|
1022 case PIXFMT_RGB24:
|
|
1023 c[0]=r;
|
|
1024 c[1]=g;
|
|
1025 c[2]=b;
|
|
1026 c[3]=0;
|
|
1027 break;
|
|
1028 case PIXFMT_BGR24:
|
|
1029 c[0]=b;
|
|
1030 c[1]=g;
|
|
1031 c[2]=r;
|
|
1032 c[3]=0;
|
|
1033 break;
|
|
1034 case PIXFMT_ARGB32:
|
|
1035 c[0]=0;
|
|
1036 c[1]=r;
|
|
1037 c[2]=g;
|
|
1038 c[3]=b;
|
|
1039 break;
|
|
1040 case PIXFMT_BGRA32:
|
|
1041 c[0]=b;
|
|
1042 c[1]=g;
|
|
1043 c[2]=r;
|
|
1044 c[3]=0;
|
|
1045 break;
|
|
1046 case PIXFMT_RGBA32:
|
|
1047 c[0]=r;
|
|
1048 c[1]=g;
|
|
1049 c[2]=b;
|
|
1050 c[3]=0;
|
|
1051 break;
|
|
1052
|
|
1053 default:
|
|
1054 D(bug("Errore, SetSingleColor con PIXFMT %ld!\n",fmt));
|
|
1055 }
|
|
1056 }
|
|
1057
|
|
1058 /* Update the current mouse state and position */
|
|
1059 static void CGX_UpdateMouse(_THIS)
|
|
1060 {
|
|
1061 /* Lock the event thread, in multi-threading environments */
|
|
1062 SDL_Lock_EventThread();
|
|
1063
|
|
1064 if(currently_fullscreen)
|
|
1065 {
|
|
1066 SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
|
|
1067 SDL_PrivateMouseMotion(0, 0, SDL_Display->MouseX, SDL_Display->MouseY);
|
|
1068 }
|
|
1069 else
|
|
1070 {
|
|
1071 if( SDL_Display->MouseX>=(SDL_Window->LeftEdge+SDL_Window->BorderLeft) && SDL_Display->MouseX<(SDL_Window->LeftEdge+SDL_Window->Width-SDL_Window->BorderRight) &&
|
|
1072 SDL_Display->MouseY>=(SDL_Window->TopEdge+SDL_Window->BorderLeft) && SDL_Display->MouseY<(SDL_Window->TopEdge+SDL_Window->Height-SDL_Window->BorderBottom)
|
|
1073 )
|
|
1074 {
|
|
1075 SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
|
|
1076 SDL_PrivateMouseMotion(0, 0, SDL_Display->MouseX-SDL_Window->LeftEdge-SDL_Window->BorderLeft,
|
|
1077 SDL_Display->MouseY-SDL_Window->TopEdge-SDL_Window->BorderTop);
|
|
1078 }
|
|
1079 else
|
|
1080 {
|
|
1081 SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
|
|
1082 }
|
|
1083 }
|
|
1084 SDL_Unlock_EventThread();
|
|
1085 }
|
|
1086
|
|
1087 static int CGX_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
|
|
1088 {
|
|
1089 int i;
|
|
1090
|
|
1091 /* Check to make sure we have a colormap allocated */
|
|
1092
|
|
1093 // It's not needed to reload the whole palette each time on Amiga!
|
|
1094 // ncolors = this->screen->format->palette->ncolors;
|
|
1095
|
|
1096 /* It's easy if we have a hidden colormap */
|
|
1097 if ( (this->screen->flags & SDL_HWPALETTE) && currently_fullscreen )
|
|
1098 {
|
|
1099 ULONG xcmap[256*3+2];
|
|
1100
|
|
1101 xcmap[0]=(ncolors<<16);
|
|
1102 xcmap[0]+=firstcolor;
|
|
1103
|
|
1104 // D(bug("Setting %ld colors on an HWPALETTE screen\n",ncolors));
|
|
1105
|
|
1106 for ( i=0; i<ncolors; i++ ) {
|
|
1107 xcmap[i*3+1] = colors[i].r<<24;
|
|
1108 xcmap[i*3+2] = colors[i].g<<24;
|
|
1109 xcmap[i*3+3] = colors[i].b<<24;
|
|
1110 }
|
|
1111 xcmap[ncolors*3+1]=0;
|
|
1112 LoadRGB32(&GFX_Display->ViewPort,xcmap);
|
|
1113 } else {
|
|
1114 // XPixels are not needed on 8bit screen with hwpalette
|
|
1115 unsigned long pixel;
|
|
1116
|
|
1117 if ( SDL_XPixels == NULL ) {
|
|
1118 D(bug("SetColors without colormap!"));
|
|
1119 return(0);
|
|
1120 }
|
|
1121
|
|
1122 colors = this->screen->format->palette->colors;
|
|
1123 if(this->hidden->depth==8)
|
|
1124 {
|
|
1125 // In this case I have to unalloc and realloc the full palette
|
|
1126 D(bug("Obtaining %ld colors on the screen\n",ncolors));
|
|
1127
|
|
1128 /* Free existing allocated colors */
|
|
1129 for ( pixel=0; pixel<this->screen->format->palette->ncolors; ++pixel ) {
|
|
1130 if(SDL_XPixels[pixel]>=0)
|
|
1131 ReleasePen(GFX_Display->ViewPort.ColorMap,SDL_XPixels[pixel]);
|
|
1132 }
|
|
1133
|
|
1134 /* Try to allocate all the colors */
|
|
1135 for ( i=0; i<this->screen->format->palette->ncolors; ++i ) {
|
|
1136 SDL_XPixels[i]=ObtainBestPenA(GFX_Display->ViewPort.ColorMap,colors[i].r<<24,colors[i].g<<24,colors[i].b<<24,NULL);
|
|
1137 }
|
|
1138 }
|
|
1139 else
|
|
1140 {
|
|
1141 #ifndef USE_CGX_WRITELUTPIXEL
|
|
1142 Uint32 fmt;
|
|
1143 D(bug("Preparing a conversion pixel table...\n"));
|
|
1144
|
|
1145 fmt=GetCyberMapAttr(SDL_Display->RastPort.BitMap,CYBRMATTR_PIXFMT);
|
|
1146
|
|
1147 for(i=0;i<ncolors;i++)
|
|
1148 {
|
|
1149 SetSingleColor(fmt,colors[firstcolor+i].r,colors[firstcolor+i].g,colors[firstcolor+i].b,(unsigned char *)&SDL_XPixels[firstcolor+i]);
|
|
1150 }
|
|
1151 #else
|
|
1152 // D(bug("Eseguo remap degli XPixel(%lx): (da %ld, %ld colori) primo: r%ld g%ld b%ld\n",SDL_XPixels,firstcolor,ncolors,colors[firstcolor].r,colors[firstcolor].g,colors[firstcolor].b));
|
|
1153 for(i=0;i<ncolors;i++)
|
|
1154 SDL_XPixels[i+firstcolor]=(colors[firstcolor+i].r<<16)+(colors[firstcolor+i].g<<8)+colors[firstcolor+i].b;
|
|
1155 #endif
|
|
1156 }
|
|
1157 }
|
|
1158
|
|
1159 // Actually it cannot fail!
|
|
1160
|
|
1161 return 1;
|
|
1162 }
|
|
1163
|
|
1164 /* Note: If we are terminated, this could be called in the middle of
|
|
1165 another SDL video routine -- notably UpdateRects.
|
|
1166 */
|
|
1167 static void CGX_VideoQuit(_THIS)
|
|
1168 {
|
|
1169 /* Shutdown everything that's still up */
|
|
1170 /* The event thread should be done, so we can touch SDL_Display */
|
|
1171 if ( SDL_Display != NULL ) {
|
|
1172 /* Clean up OpenGL */
|
|
1173
|
|
1174 /* Start shutting down the windows */
|
|
1175 CGX_DestroyImage(this, this->screen);
|
|
1176 CGX_DestroyWindow(this, this->screen);
|
|
1177 // Otherwise SDL_VideoQuit will try to free it!
|
|
1178 SDL_VideoSurface=NULL;
|
|
1179 CGX_FreeVideoModes(this);
|
|
1180
|
|
1181 /* Free that blank cursor */
|
|
1182 if ( SDL_BlankCursor != NULL ) {
|
|
1183 FreeMem(SDL_BlankCursor,16);
|
|
1184 SDL_BlankCursor = NULL;
|
|
1185 }
|
|
1186
|
|
1187 /* Close the X11 graphics connection */
|
|
1188 this->hidden->same_format=0;
|
|
1189
|
|
1190 if ( GFX_Display != NULL )
|
|
1191 DestroyScreen(this);
|
|
1192
|
|
1193 /* Close the X11 display connection */
|
|
1194 SDL_Display = NULL;
|
|
1195
|
|
1196 /* Unload GL library after X11 shuts down */
|
|
1197 }
|
|
1198
|
|
1199 if( CyberGfxBase)
|
|
1200 {
|
|
1201 CloseLibrary(CyberGfxBase);
|
|
1202 CyberGfxBase=NULL;
|
|
1203 }
|
|
1204
|
|
1205 if (IntuitionBase)
|
|
1206 {
|
|
1207 CloseLibrary((struct Library *)IntuitionBase);
|
|
1208 IntuitionBase=NULL;
|
|
1209 }
|
|
1210 if (GfxBase)
|
|
1211 {
|
|
1212 CloseLibrary((struct Library *)GfxBase);
|
|
1213 GfxBase=NULL;
|
|
1214 }
|
|
1215
|
|
1216 if ( this->screen && (this->screen->flags & SDL_HWSURFACE) ) {
|
|
1217 /* Direct screen access, no memory buffer */
|
|
1218 this->screen->pixels = NULL;
|
|
1219 }
|
|
1220 }
|
|
1221
|