1 /* 2 SDL - Simple DirectMedia Layer 3 Copyright (C) 1997-2006 Sam Lantinga 4 5 This library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 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 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 19 Sam Lantinga 20 slouken (at) libsdl.org 21 */ 22 #include "SDL_config.h" 23 24 /* 25 * Xbios SDL video driver 26 * 27 * Patrice Mandin 28 */ 29 30 #include <sys/stat.h> 31 #include <unistd.h> 32 33 /* Mint includes */ 34 #include <mint/cookie.h> 35 #include <mint/osbind.h> 36 #include <mint/falcon.h> 37 38 #include "SDL_video.h" 39 #include "SDL_mouse.h" 40 #include "../SDL_sysvideo.h" 41 #include "../SDL_pixels_c.h" 42 #include "../../events/SDL_events_c.h" 43 44 #include "../ataricommon/SDL_ataric2p_s.h" 45 #include "../ataricommon/SDL_atarievents_c.h" 46 #include "../ataricommon/SDL_atarimxalloc_c.h" 47 #include "../ataricommon/SDL_atarigl_c.h" 48 #include "SDL_xbios.h" 49 #include "SDL_xbios_blowup.h" 50 #include "SDL_xbios_centscreen.h" 51 #include "SDL_xbios_sb3.h" 52 #include "SDL_xbios_tveille.h" 53 54 #define XBIOS_VID_DRIVER_NAME "xbios" 55 56 /* Debug print info */ 57 #if 0 58 #define DEBUG_PRINT(what) \ 59 { \ 60 printf what; \ 61 } 62 #define DEBUG_VIDEO_XBIOS 1 63 #else 64 #define DEBUG_PRINT(what) 65 #undef DEBUG_VIDEO_XBIOS 66 #endif 67 68 /* Initialization/Query functions */ 69 static int XBIOS_VideoInit(_THIS, SDL_PixelFormat *vformat); 70 static SDL_Rect **XBIOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); 71 static SDL_Surface *XBIOS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); 72 static int XBIOS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); 73 static void XBIOS_VideoQuit(_THIS); 74 75 /* Hardware surface functions */ 76 static int XBIOS_AllocHWSurface(_THIS, SDL_Surface *surface); 77 static int XBIOS_LockHWSurface(_THIS, SDL_Surface *surface); 78 static int XBIOS_FlipHWSurface(_THIS, SDL_Surface *surface); 79 static void XBIOS_UnlockHWSurface(_THIS, SDL_Surface *surface); 80 static void XBIOS_FreeHWSurface(_THIS, SDL_Surface *surface); 81 static void XBIOS_UpdateRects(_THIS, int numrects, SDL_Rect *rects); 82 83 #if SDL_VIDEO_OPENGL 84 /* OpenGL functions */ 85 static void XBIOS_GL_SwapBuffers(_THIS); 86 #endif 87 88 /* To setup palette */ 89 90 static unsigned short TT_palette[256]; 91 static unsigned long F30_palette[256]; 92 93 /* Xbios driver bootstrap functions */ 94 95 static int XBIOS_Available(void) 96 { 97 unsigned long cookie_vdo, cookie_mil, cookie_hade, cookie_scpn; 98 99 /* Milan/Hades Atari clones do not have an Atari video chip */ 100 if ( (Getcookie(C__MIL, &cookie_mil) == C_FOUND) || 101 (Getcookie(C_hade, &cookie_hade) == C_FOUND) ) { 102 return 0; 103 } 104 105 /* Cookie _VDO present ? if not, assume ST machine */ 106 if (Getcookie(C__VDO, &cookie_vdo) != C_FOUND) { 107 cookie_vdo = VDO_ST << 16; 108 } 109 110 /* Test if we have a monochrome monitor plugged in */ 111 switch( cookie_vdo >>16) { 112 case VDO_ST: 113 case VDO_STE: 114 if ( Getrez() == (ST_HIGH>>8) ) 115 return 0; 116 break; 117 case VDO_TT: 118 if ( (EgetShift() & ES_MODE) == TT_HIGH) 119 return 0; 120 break; 121 case VDO_F30: 122 if ( VgetMonitor() == MONITOR_MONO) 123 return 0; 124 if (Getcookie(C_SCPN, &cookie_scpn) == C_FOUND) { 125 if (!SDL_XBIOS_SB3Usable((scpn_cookie_t *)cookie_scpn)) { 126 return 0; 127 } 128 } 129 break; 130 default: 131 return 0; 132 } 133 134 return 1; 135 } 136 137 static void XBIOS_DeleteDevice(SDL_VideoDevice *device) 138 { 139 SDL_free(device->hidden); 140 SDL_free(device); 141 } 142 143 static SDL_VideoDevice *XBIOS_CreateDevice(int devindex) 144 { 145 SDL_VideoDevice *device; 146 147 /* Initialize all variables that we clean on shutdown */ 148 device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); 149 if ( device ) { 150 SDL_memset(device, 0, (sizeof *device)); 151 device->hidden = (struct SDL_PrivateVideoData *) 152 SDL_malloc((sizeof *device->hidden)); 153 device->gl_data = (struct SDL_PrivateGLData *) 154 SDL_malloc((sizeof *device->gl_data)); 155 } 156 if ( (device == NULL) || (device->hidden == NULL) ) { 157 SDL_OutOfMemory(); 158 if ( device ) { 159 SDL_free(device); 160 } 161 return(0); 162 } 163 SDL_memset(device->hidden, 0, (sizeof *device->hidden)); 164 SDL_memset(device->gl_data, 0, sizeof(*device->gl_data)); 165 166 /* Video functions */ 167 device->VideoInit = XBIOS_VideoInit; 168 device->ListModes = XBIOS_ListModes; 169 device->SetVideoMode = XBIOS_SetVideoMode; 170 device->SetColors = XBIOS_SetColors; 171 device->UpdateRects = NULL; 172 device->VideoQuit = XBIOS_VideoQuit; 173 device->AllocHWSurface = XBIOS_AllocHWSurface; 174 device->LockHWSurface = XBIOS_LockHWSurface; 175 device->UnlockHWSurface = XBIOS_UnlockHWSurface; 176 device->FlipHWSurface = XBIOS_FlipHWSurface; 177 device->FreeHWSurface = XBIOS_FreeHWSurface; 178 179 #if SDL_VIDEO_OPENGL 180 /* OpenGL functions */ 181 device->GL_LoadLibrary = SDL_AtariGL_LoadLibrary; 182 device->GL_GetProcAddress = SDL_AtariGL_GetProcAddress; 183 device->GL_GetAttribute = SDL_AtariGL_GetAttribute; 184 device->GL_MakeCurrent = SDL_AtariGL_MakeCurrent; 185 device->GL_SwapBuffers = XBIOS_GL_SwapBuffers; 186 #endif 187 188 /* Events */ 189 device->InitOSKeymap = Atari_InitOSKeymap; 190 device->PumpEvents = Atari_PumpEvents; 191 192 device->free = XBIOS_DeleteDevice; 193 194 return device; 195 } 196 197 VideoBootStrap XBIOS_bootstrap = { 198 XBIOS_VID_DRIVER_NAME, "Atari Xbios driver", 199 XBIOS_Available, XBIOS_CreateDevice 200 }; 201 202 void SDL_XBIOS_AddMode(_THIS, Uint16 modecode, Uint16 width, Uint16 height, 203 Uint16 depth, SDL_bool flags) 204 { 205 int i, curpos; 206 xbiosmode_t *current_mode; 207 208 /* Check if mode already exists */ 209 if (XBIOS_modelist) { 210 current_mode = XBIOS_modelist; 211 for (i=0;i<XBIOS_nummodes; i++, current_mode++) { 212 if (current_mode->width != width) 213 continue; 214 if (current_mode->height != height) 215 continue; 216 if (current_mode->depth != depth) 217 continue; 218 return; 219 } 220 } 221 222 ++XBIOS_nummodes; 223 XBIOS_modelist = (xbiosmode_t *) SDL_realloc(XBIOS_modelist, XBIOS_nummodes * sizeof(xbiosmode_t)); 224 225 /* Keep the list sorted: bpp, width, height */ 226 curpos=0; 227 228 for(i=0; i<XBIOS_nummodes-1; i++) { 229 if (XBIOS_modelist[i].depth <= depth) { 230 if (XBIOS_modelist[i].width < width) { 231 break; 232 } else if (XBIOS_modelist[i].width == width) { 233 if (XBIOS_modelist[i].height <= height) { 234 break; 235 } 236 } 237 } 238 curpos++; 239 } 240 241 /* Push remaining modes further */ 242 for(i=XBIOS_nummodes-1; i>curpos; i--) { 243 SDL_memcpy(&XBIOS_modelist[i], &XBIOS_modelist[i-1], sizeof(xbiosmode_t)); 244 } 245 246 XBIOS_modelist[curpos].number = modecode; 247 XBIOS_modelist[curpos].width = width; 248 XBIOS_modelist[curpos].height = height; 249 XBIOS_modelist[curpos].depth = depth; 250 XBIOS_modelist[curpos].doubleline = flags; 251 } 252 253 static int XBIOS_VideoInit(_THIS, SDL_PixelFormat *vformat) 254 { 255 int i,j8,j16; 256 xbiosmode_t *current_mode; 257 unsigned long cookie_blow, cookie_scpn, cookie_cnts; 258 259 /* Initialize all variables that we clean on shutdown */ 260 memset (SDL_modelist, 0, sizeof(SDL_modelist)); 261 262 /* Cookie _VDO present ? if not, assume ST machine */ 263 if (Getcookie(C__VDO, &XBIOS_cvdo) != C_FOUND) { 264 XBIOS_cvdo = VDO_ST << 16; 265 } 266 267 /* Allocate memory for old palette */ 268 XBIOS_oldpalette = (void *)SDL_malloc(256*sizeof(long)); 269 if ( !XBIOS_oldpalette ) { 270 SDL_SetError("Unable to allocate memory for old palette\n"); 271 return(-1); 272 } 273 274 /* Initialize video mode list */ 275 /* and save current screen status (palette, screen address, video mode) */ 276 XBIOS_nummodes = 0; 277 XBIOS_modelist = NULL; 278 XBIOS_centscreen = SDL_FALSE; 279 280 switch (XBIOS_cvdo >>16) { 281 case VDO_ST: 282 case VDO_STE: 283 { 284 short *oldpalette; 285 286 SDL_XBIOS_AddMode(this, ST_LOW>>8,320,200,4,SDL_FALSE); 287 288 XBIOS_oldvbase=Physbase(); 289 XBIOS_oldvmode=Getrez(); 290 switch(XBIOS_oldvmode << 8) { 291 case ST_LOW: 292 XBIOS_oldnumcol=16; 293 break; 294 case ST_MED: 295 XBIOS_oldnumcol=4; 296 break; 297 case ST_HIGH: 298 XBIOS_oldnumcol=2; 299 break; 300 default: 301 XBIOS_oldnumcol=0; 302 break; 303 } 304 305 oldpalette= (short *) XBIOS_oldpalette; 306 for (i=0;i<XBIOS_oldnumcol;i++) { 307 *oldpalette++=Setcolor(i,-1); 308 } 309 310 vformat->BitsPerPixel = 8; 311 } 312 break; 313 case VDO_TT: 314 315 SDL_XBIOS_AddMode(this, TT_LOW,320,480,8,SDL_FALSE); 316 /* Software double-lined mode */ 317 SDL_XBIOS_AddMode(this, TT_LOW,320,240,8,SDL_TRUE); 318 319 XBIOS_oldvbase=Logbase(); 320 XBIOS_oldvmode=EgetShift(); 321 322 switch(XBIOS_oldvmode & ES_MODE) { 323 case TT_LOW: 324 XBIOS_oldnumcol=256; 325 break; 326 case ST_LOW: 327 case TT_MED: 328 XBIOS_oldnumcol=16; 329 break; 330 case ST_MED: 331 XBIOS_oldnumcol=4; 332 break; 333 case ST_HIGH: 334 case TT_HIGH: 335 XBIOS_oldnumcol=2; 336 break; 337 default: 338 XBIOS_oldnumcol=0; 339 break; 340 } 341 if (XBIOS_oldnumcol) { 342 EgetPalette(0, XBIOS_oldnumcol, XBIOS_oldpalette); 343 } 344 345 vformat->BitsPerPixel = 8; 346 break; 347 case VDO_F30: 348 switch (VgetMonitor()) 349 { 350 case MONITOR_MONO: 351 /* Not usable */ 352 break; 353 case MONITOR_RGB: 354 case MONITOR_TV: 355 SDL_XBIOS_AddMode(this, BPS16|COL80|OVERSCAN|VERTFLAG,768,480,16,SDL_FALSE); 356 SDL_XBIOS_AddMode(this, BPS16|COL80|OVERSCAN,768,240,16,SDL_FALSE); 357 SDL_XBIOS_AddMode(this, BPS16|COL80|VERTFLAG,640,400,16,SDL_FALSE); 358 SDL_XBIOS_AddMode(this, BPS16|COL80,640,200,16,SDL_FALSE); 359 SDL_XBIOS_AddMode(this, BPS16|OVERSCAN|VERTFLAG,384,480,16,SDL_FALSE); 360 SDL_XBIOS_AddMode(this, BPS16|OVERSCAN,384,240,16,SDL_FALSE); 361 SDL_XBIOS_AddMode(this, BPS16|VERTFLAG,320,400,16,SDL_FALSE); 362 SDL_XBIOS_AddMode(this, BPS16,320,200,16,SDL_FALSE); 363 SDL_XBIOS_AddMode(this, BPS8|COL80|OVERSCAN|VERTFLAG,768,480,8,SDL_FALSE); 364 SDL_XBIOS_AddMode(this, BPS8|COL80|OVERSCAN,768,240,8,SDL_FALSE); 365 SDL_XBIOS_AddMode(this, BPS8|COL80|VERTFLAG,640,400,8,SDL_FALSE); 366 SDL_XBIOS_AddMode(this, BPS8|COL80,640,200,8,SDL_FALSE); 367 SDL_XBIOS_AddMode(this, BPS8|OVERSCAN|VERTFLAG,384,480,8,SDL_FALSE); 368 SDL_XBIOS_AddMode(this, BPS8|OVERSCAN,384,240,8,SDL_FALSE); 369 SDL_XBIOS_AddMode(this, BPS8|VERTFLAG,320,400,8,SDL_FALSE); 370 SDL_XBIOS_AddMode(this, BPS8,320,200,8,SDL_FALSE); 371 break; 372 case MONITOR_VGA: 373 SDL_XBIOS_AddMode(this, BPS16,320,480,16,SDL_FALSE); 374 SDL_XBIOS_AddMode(this, BPS16|VERTFLAG,320,240,16,SDL_FALSE); 375 SDL_XBIOS_AddMode(this, BPS8|COL80,640,480,8,SDL_FALSE); 376 SDL_XBIOS_AddMode(this, BPS8|COL80|VERTFLAG,640,240,8,SDL_FALSE); 377 SDL_XBIOS_AddMode(this, BPS8,320,480,8,SDL_FALSE); 378 SDL_XBIOS_AddMode(this, BPS8|VERTFLAG,320,240,8,SDL_FALSE); 379 break; 380 } 381 XBIOS_oldvbase=Logbase(); 382 XBIOS_oldvmode=VsetMode(-1); 383 384 XBIOS_oldnumcol= 1<< (1 << (XBIOS_oldvmode & NUMCOLS)); 385 if (XBIOS_oldnumcol > 256) { 386 XBIOS_oldnumcol = 0; 387 } 388 if (XBIOS_oldnumcol) { 389 VgetRGB(0, XBIOS_oldnumcol, XBIOS_oldpalette); 390 } 391 392 vformat->BitsPerPixel = 16; 393 394 /* Keep vga/rvb, and pal/ntsc bits */ 395 current_mode = XBIOS_modelist; 396 for (i=0;i<XBIOS_nummodes;i++) { 397 Uint16 newvmode; 398 399 newvmode = current_mode->number; 400 newvmode &= ~(VGA|PAL); 401 newvmode |= XBIOS_oldvmode & (VGA|PAL); 402 current_mode->number = newvmode; 403 404 current_mode++; 405 } 406 407 /* Initialize BlowUp/SB3/Centscreen stuff if present */ 408 if (Getcookie(C_BLOW, &cookie_blow) == C_FOUND) { 409 SDL_XBIOS_BlowupInit(this, (blow_cookie_t *)cookie_blow); 410 } else if (Getcookie(C_SCPN, &cookie_scpn) == C_FOUND) { 411 SDL_XBIOS_SB3Init(this, (scpn_cookie_t *)cookie_scpn); 412 } else if (Getcookie(C_CNTS, &cookie_cnts) == C_FOUND) { 413 XBIOS_oldvmode = SDL_XBIOS_CentscreenInit(this); 414 XBIOS_centscreen = SDL_TRUE; 415 } 416 417 break; 418 } 419 420 /* Determine the current screen size */ 421 if ( XBIOS_nummodes > 0 ) { 422 /* FIXME: parse video mode list to search for current mode */ 423 this->info.current_w = XBIOS_modelist[0].width; 424 this->info.current_h = XBIOS_modelist[0].height; 425 } 426 427 current_mode = XBIOS_modelist; 428 j8 = j16 = 0; 429 for (i=0; i<XBIOS_nummodes; i++, current_mode++) { 430 switch (current_mode->depth) { 431 case 4: 432 case 8: 433 SDL_modelist[0][j8] = SDL_malloc(sizeof(SDL_Rect)); 434 SDL_modelist[0][j8]->x = SDL_modelist[0][j8]->y = 0; 435 SDL_modelist[0][j8]->w = current_mode->width; 436 SDL_modelist[0][j8]->h = current_mode->height; 437 XBIOS_videomodes[0][j8]=current_mode; 438 j8++; 439 break; 440 case 16: 441 SDL_modelist[1][j16] = SDL_malloc(sizeof(SDL_Rect)); 442 SDL_modelist[1][j16]->x = SDL_modelist[1][j16]->y = 0; 443 SDL_modelist[1][j16]->w = current_mode->width; 444 SDL_modelist[1][j16]->h = current_mode->height; 445 XBIOS_videomodes[1][j16]=current_mode; 446 j16++; 447 break; 448 } 449 } 450 SDL_modelist[0][j8] = NULL; 451 SDL_modelist[1][j16] = NULL; 452 453 XBIOS_screens[0]=NULL; 454 XBIOS_screens[1]=NULL; 455 XBIOS_shadowscreen=NULL; 456 457 /* Update hardware info */ 458 this->info.hw_available = 1; 459 this->info.video_mem = (Uint32) Atari_SysMalloc(-1L, MX_STRAM); 460 461 /* Init chunky to planar routine */ 462 SDL_Atari_C2pConvert = SDL_Atari_C2pConvert8; 463 464 #if SDL_VIDEO_OPENGL 465 SDL_AtariGL_InitPointers(this); 466 #endif 467 468 /* Disable screensavers */ 469 if (SDL_XBIOS_TveillePresent(this)) { 470 SDL_XBIOS_TveilleDisable(this); 471 } 472 473 /* We're done! */ 474 return(0); 475 } 476 477 static SDL_Rect **XBIOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) 478 { 479 /* 8 bits -> list 0 */ 480 /* 16 bits -> list 1 */ 481 if ((format->BitsPerPixel != 8) && (format->BitsPerPixel !=16)) { 482 return NULL; 483 } 484 485 return(SDL_modelist[(format->BitsPerPixel)>>4]); 486 } 487 488 static void XBIOS_FreeBuffers(_THIS) 489 { 490 int i; 491 492 for (i=0;i<2;i++) { 493 if (XBIOS_screensmem[i]!=NULL) { 494 Mfree(XBIOS_screensmem[i]); 495 XBIOS_screensmem[i]=NULL; 496 } 497 } 498 499 if (XBIOS_shadowscreen!=NULL) { 500 Mfree(XBIOS_shadowscreen); 501 XBIOS_shadowscreen=NULL; 502 } 503 } 504 505 static SDL_Surface *XBIOS_SetVideoMode(_THIS, SDL_Surface *current, 506 int width, int height, int bpp, Uint32 flags) 507 { 508 int mode, new_depth; 509 int i; 510 xbiosmode_t *new_video_mode; 511 Uint32 new_screen_size; 512 Uint32 modeflags; 513 514 /* Free current buffers */ 515 XBIOS_FreeBuffers(this); 516 517 /* Limit bpp */ 518 if (bpp>16) { 519 bpp = 16; 520 } 521 bpp >>= 4; 522 523 /* Search if the mode exists (width, height, bpp) */ 524 for ( mode=0; SDL_modelist[bpp][mode]; ++mode ) { 525 if ( (SDL_modelist[bpp][mode]->w == width) && 526 (SDL_modelist[bpp][mode]->h == height) ) { 527 528 break; 529 } 530 } 531 if ( SDL_modelist[bpp][mode] == NULL ) { 532 SDL_SetError("Couldn't find requested mode in list"); 533 return(NULL); 534 } 535 536 modeflags = SDL_FULLSCREEN | SDL_PREALLOC; 537 538 /* Allocate needed buffers: simple/double buffer and shadow surface */ 539 new_video_mode = XBIOS_videomodes[bpp][mode]; 540 new_depth = new_video_mode->depth; 541 if (new_depth == 4) { 542 SDL_Atari_C2pConvert = SDL_Atari_C2pConvert4; 543 new_depth=8; 544 modeflags |= SDL_SWSURFACE|SDL_HWPALETTE; 545 } else if (new_depth == 8) { 546 SDL_Atari_C2pConvert = SDL_Atari_C2pConvert8; 547 modeflags |= SDL_SWSURFACE|SDL_HWPALETTE; 548 } else { 549 modeflags |= SDL_HWSURFACE; 550 } 551 552 new_screen_size = width * height * ((new_depth)>>3); 553 new_screen_size += 256; /* To align on a 256 byte adress */ 554 555 if (new_depth == 8) { 556 XBIOS_shadowscreen = Atari_SysMalloc(new_screen_size, MX_PREFTTRAM); 557 558 if (XBIOS_shadowscreen == NULL) { 559 SDL_SetError("Can not allocate %d KB for shadow buffer", new_screen_size>>10); 560 return (NULL); 561 } 562 SDL_memset(XBIOS_shadowscreen, 0, new_screen_size); 563 } 564 565 /* Output buffer needs to be twice in size for the software double-line mode */ 566 XBIOS_doubleline = SDL_FALSE; 567 if (new_video_mode->doubleline) { 568 new_screen_size <<= 1; 569 XBIOS_doubleline = SDL_TRUE; 570 } 571 572 XBIOS_screensmem[0] = Atari_SysMalloc(new_screen_size, MX_STRAM); 573 574 if (XBIOS_screensmem[0]==NULL) { 575 XBIOS_FreeBuffers(this); 576 SDL_SetError("Can not allocate %d KB for frame buffer", new_screen_size>>10); 577 return (NULL); 578 } 579 SDL_memset(XBIOS_screensmem[0], 0, new_screen_size); 580 581 XBIOS_screens[0]=(void *) (( (long) XBIOS_screensmem[0]+256) & 0xFFFFFF00UL); 582 583 #if SDL_VIDEO_OPENGL 584 if (flags & SDL_OPENGL) { 585 if (this->gl_config.double_buffer) { 586 flags |= SDL_DOUBLEBUF; 587 } 588 } 589 #endif 590 591 /* Double buffer ? */ 592 if (flags & SDL_DOUBLEBUF) { 593 XBIOS_screensmem[1] = Atari_SysMalloc(new_screen_size, MX_STRAM); 594 595 if (XBIOS_screensmem[1]==NULL) { 596 XBIOS_FreeBuffers(this); 597 SDL_SetError("Can not allocate %d KB for double buffer", new_screen_size>>10); 598 return (NULL); 599 } 600 SDL_memset(XBIOS_screensmem[1], 0, new_screen_size); 601 602 XBIOS_screens[1]=(void *) (( (long) XBIOS_screensmem[1]+256) & 0xFFFFFF00UL); 603 modeflags |= SDL_DOUBLEBUF; 604 } 605 606 /* Allocate the new pixel format for the screen */ 607 if ( ! SDL_ReallocFormat(current, new_depth, 0, 0, 0, 0) ) { 608 XBIOS_FreeBuffers(this); 609 SDL_SetError("Couldn't allocate new pixel format for requested mode"); 610 return(NULL); 611 } 612 613 current->w = XBIOS_width = width; 614 current->h = XBIOS_height = height; 615 current->pitch = (width * new_depth)>>3; 616 617 /* this is for C2P conversion */ 618 XBIOS_pitch = (new_video_mode->width * new_video_mode->depth)>>3; 619 620 if (new_depth == 8) 621 current->pixels = XBIOS_shadowscreen; 622 else 623 current->pixels = XBIOS_screens[0]; 624 625 XBIOS_fbnum = 0; 626 627 #if SDL_VIDEO_OPENGL 628 if (flags & SDL_OPENGL) { 629 if (!SDL_AtariGL_Init(this, current)) { 630 XBIOS_FreeBuffers(this); 631 SDL_SetError("Can not create OpenGL context"); 632 return NULL; 633 } 634 635 modeflags |= SDL_OPENGL; 636 } 637 #endif 638 639 current->flags = modeflags; 640 641 /* Now set the video mode */ 642 #ifndef DEBUG_VIDEO_XBIOS 643 Setscreen(-1,XBIOS_screens[0],-1); 644 #endif 645 646 switch(XBIOS_cvdo >> 16) { 647 case VDO_ST: 648 #ifndef DEBUG_VIDEO_XBIOS 649 Setscreen(-1,-1,new_video_mode->number); 650 #endif 651 /* Reset palette */ 652 for (i=0;i<16;i++) { 653 TT_palette[i]= ((i>>1)<<8) | (((i*8)/17)<<4) | (i>>1); 654 } 655 #ifndef DEBUG_VIDEO_XBIOS 656 Setpalette(TT_palette); 657 #endif 658 break; 659 case VDO_STE: 660 #ifndef DEBUG_VIDEO_XBIOS 661 Setscreen(-1,-1,new_video_mode->number); 662 #endif 663 /* Reset palette */ 664 for (i=0;i<16;i++) 665 { 666 int c; 667 668 c=((i&1)<<3)|((i>>1)&7); 669 TT_palette[i]=(c<<8)|(c<<4)|c; 670 } 671 #ifndef DEBUG_VIDEO_XBIOS 672 Setpalette(TT_palette); 673 #endif 674 break; 675 case VDO_TT: 676 #ifndef DEBUG_VIDEO_XBIOS 677 EsetShift(new_video_mode->number); 678 #endif 679 break; 680 case VDO_F30: 681 #ifndef DEBUG_VIDEO_XBIOS 682 if (XBIOS_centscreen) { 683 SDL_XBIOS_CentscreenSetmode(this, width, height, new_depth); 684 } else { 685 VsetMode(new_video_mode->number); 686 } 687 #endif 688 /* Set hardware palette to black in True Colour */ 689 if (new_depth == 16) { 690 SDL_memset(F30_palette, 0, sizeof(F30_palette)); 691 VsetRGB(0,256,F30_palette); 692 } 693 break; 694 } 695 696 Vsync(); 697 698 this->UpdateRects = XBIOS_UpdateRects; 699 700 return (current); 701 } 702 703 /* We don't actually allow hardware surfaces other than the main one */ 704 static int XBIOS_AllocHWSurface(_THIS, SDL_Surface *surface) 705 { 706 return(-1); 707 } 708 709 static void XBIOS_FreeHWSurface(_THIS, SDL_Surface *surface) 710 { 711 return; 712 } 713 714 static int XBIOS_LockHWSurface(_THIS, SDL_Surface *surface) 715 { 716 return(0); 717 } 718 719 static void XBIOS_UnlockHWSurface(_THIS, SDL_Surface *surface) 720 { 721 return; 722 } 723 724 static void XBIOS_UpdateRects(_THIS, int numrects, SDL_Rect *rects) 725 { 726 SDL_Surface *surface; 727 728 surface = this->screen; 729 730 if ((surface->format->BitsPerPixel) == 8) { 731 int i; 732 733 for (i=0;i<numrects;i++) { 734 void *source,*destination; 735 int x1,x2; 736 737 x1 = rects[i].x & ~15; 738 x2 = rects[i].x+rects[i].w; 739 if (x2 & 15) { 740 x2 = (x2 | 15) +1; 741 } 742 743 source = surface->pixels; 744 source += surface->pitch * rects[i].y; 745 source += x1; 746 747 destination = XBIOS_screens[XBIOS_fbnum]; 748 destination += XBIOS_pitch * rects[i].y; 749 destination += x1; 750 751 /* Convert chunky to planar screen */ 752 SDL_Atari_C2pConvert( 753 source, 754 destination, 755 x2-x1, 756 rects[i].h, 757 XBIOS_doubleline, 758 surface->pitch, 759 XBIOS_pitch 760 ); 761 } 762 } 763 764 #ifndef DEBUG_VIDEO_XBIOS 765 Setscreen(-1,XBIOS_screens[XBIOS_fbnum],-1); 766 #endif 767 Vsync(); 768 769 if ((surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) { 770 XBIOS_fbnum ^= 1; 771 if ((surface->format->BitsPerPixel) > 8) { 772 surface->pixels=XBIOS_screens[XBIOS_fbnum]; 773 } 774 } 775 } 776 777 static int XBIOS_FlipHWSurface(_THIS, SDL_Surface *surface) 778 { 779 if ((surface->format->BitsPerPixel) == 8) { 780 void *destscr; 781 int destx; 782 783 /* Center on destination screen */ 784 destscr = XBIOS_screens[XBIOS_fbnum]; 785 destscr += XBIOS_pitch * ((XBIOS_height - surface->h) >> 1); 786 destx = (XBIOS_width - surface->w) >> 1; 787 destx &= ~15; 788 destscr += destx; 789 790 /* Convert chunky to planar screen */ 791 SDL_Atari_C2pConvert( 792 surface->pixels, 793 destscr, 794 surface->w, 795 surface->h, 796 XBIOS_doubleline, 797 surface->pitch, 798 XBIOS_pitch 799 ); 800 } 801 802 #ifndef DEBUG_VIDEO_XBIOS 803 Setscreen(-1,XBIOS_screens[XBIOS_fbnum],-1); 804 #endif 805 Vsync(); 806 807 if ((surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) { 808 XBIOS_fbnum ^= 1; 809 if ((surface->format->BitsPerPixel) > 8) { 810 surface->pixels=XBIOS_screens[XBIOS_fbnum]; 811 } 812 } 813 814 return(0); 815 } 816 817 static int XBIOS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) 818 { 819 int i; 820 int r,v,b; 821 822 switch( XBIOS_cvdo >> 16) { 823 case VDO_ST: 824 case VDO_STE: 825 for (i=0;i<ncolors;i++) 826 { 827 r = colors[i].r; 828 v = colors[i].g; 829 b = colors[i].b; 830 831 TT_palette[firstcolor+i]=((r*30)+(v*59)+(b*11))/100; 832 } 833 SDL_Atari_C2pConvert4_pal(TT_palette); /* convert the lighting */ 834 break; 835 case VDO_TT: 836 for(i = 0; i < ncolors; i++) 837 { 838 r = colors[i].r; 839 v = colors[i].g; 840 b = colors[i].b; 841 842 TT_palette[i]=((r>>4)<<8)|((v>>4)<<4)|(b>>4); 843 } 844 #ifndef DEBUG_VIDEO_XBIOS 845 EsetPalette(firstcolor,ncolors,TT_palette); 846 #endif 847 break; 848 case VDO_F30: 849 for(i = 0; i < ncolors; i++) 850 { 851 r = colors[i].r; 852 v = colors[i].g; 853 b = colors[i].b; 854 855 F30_palette[i]=(r<<16)|(v<<8)|b; 856 } 857 #ifndef DEBUG_VIDEO_XBIOS 858 VsetRGB(firstcolor,ncolors,F30_palette); 859 #endif 860 break; 861 } 862 863 return(1); 864 } 865 866 /* Note: If we are terminated, this could be called in the middle of 867 another SDL video routine -- notably UpdateRects. 868 */ 869 static void XBIOS_VideoQuit(_THIS) 870 { 871 int i,j; 872 873 Atari_ShutdownEvents(); 874 875 /* Restore video mode and palette */ 876 #ifndef DEBUG_VIDEO_XBIOS 877 switch(XBIOS_cvdo >> 16) { 878 case VDO_ST: 879 case VDO_STE: 880 Setscreen(-1,XBIOS_oldvbase,XBIOS_oldvmode); 881 if (XBIOS_oldnumcol) { 882 Setpalette(XBIOS_oldpalette); 883 } 884 break; 885 case VDO_TT: 886 Setscreen(-1,XBIOS_oldvbase,-1); 887 EsetShift(XBIOS_oldvmode); 888 if (XBIOS_oldnumcol) { 889 EsetPalette(0, XBIOS_oldnumcol, XBIOS_oldpalette); 890 } 891 break; 892 case VDO_F30: 893 Setscreen(-1, XBIOS_oldvbase, -1); 894 if (XBIOS_centscreen) { 895 SDL_XBIOS_CentscreenRestore(this, XBIOS_oldvmode); 896 } else { 897 VsetMode(XBIOS_oldvmode); 898 } 899 if (XBIOS_oldnumcol) { 900 VsetRGB(0, XBIOS_oldnumcol, XBIOS_oldpalette); 901 } 902 break; 903 } 904 Vsync(); 905 #endif 906 907 908 #if SDL_VIDEO_OPENGL 909 if (gl_active) { 910 SDL_AtariGL_Quit(this, SDL_TRUE); 911 } 912 #endif 913 914 if (XBIOS_oldpalette) { 915 SDL_free(XBIOS_oldpalette); 916 XBIOS_oldpalette=NULL; 917 } 918 XBIOS_FreeBuffers(this); 919 920 /* Free mode list */ 921 for (j=0;j<NUM_MODELISTS;j++) { 922 for (i=0;i<SDL_NUMMODES;i++) { 923 if (SDL_modelist[j][i]!=NULL) { 924 SDL_free(SDL_modelist[j][i]); 925 SDL_modelist[j][i]=NULL; 926 } 927 } 928 } 929 930 if (XBIOS_modelist) { 931 SDL_free(XBIOS_modelist); 932 XBIOS_nummodes=0; 933 XBIOS_modelist=NULL; 934 } 935 936 this->screen->pixels = NULL; 937 938 /* Restore screensavers */ 939 if (SDL_XBIOS_TveillePresent(this)) { 940 SDL_XBIOS_TveilleRestore(this); 941 } 942 } 943 944 #if SDL_VIDEO_OPENGL 945 946 static void XBIOS_GL_SwapBuffers(_THIS) 947 { 948 SDL_AtariGL_SwapBuffers(this); 949 XBIOS_FlipHWSurface(this, this->screen); 950 SDL_AtariGL_MakeCurrent(this); 951 } 952 953 #endif 954