1 /* 2 SDL - Simple DirectMedia Layer 3 Copyright (C) 1997-2012 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 /* Pocket PC GAPI SDL video driver implementation; 25 Implemented by Dmitry Yakimov - support (at) activekitten.com 26 Inspired by http://arisme.free.fr/ports/SDL.php 27 */ 28 29 // TODO: copy surface on window when lost focus 30 // TODO: test buttons rotation 31 // TODO: test on be300 and HPC ( check WinDib fullscreen keys catching ) 32 // TODO: test on smartphones 33 // TODO: windib on SH3 PPC2000 landscape test 34 // TODO: optimize 8bpp landscape mode 35 36 // there is some problems in runnings apps from a device landscape mode 37 // due to WinCE bugs. Some works and some - does not. 38 // TODO: finish Axim Dell X30 and user landscape mode, device landscape mode 39 // TODO: finish Axim Dell X30 user portrait, device landscape stylus conversion 40 // TODO: fix running GAPI apps from landscape mode - 41 // wince goes to portrait mode, but does not update video memory 42 43 44 #include "SDL.h" 45 #include "SDL_error.h" 46 #include "SDL_video.h" 47 #include "SDL_mouse.h" 48 #include "../SDL_sysvideo.h" 49 #include "../SDL_pixels_c.h" 50 #include "../../events/SDL_events_c.h" 51 #include "../wincommon/SDL_syswm_c.h" 52 #include "../wincommon/SDL_sysmouse_c.h" 53 #include "../windib/SDL_dibevents_c.h" 54 55 #include "../windib/SDL_gapidibvideo.h" 56 #include "SDL_gapivideo.h" 57 58 #define gapi this->hidden->gapiInfo 59 60 #define GAPIVID_DRIVER_NAME "gapi" 61 62 #if defined(DEBUG) || defined (_DEBUG) || defined(NDEBUG) 63 #define REPORT_VIDEO_INFO 1 64 #else 65 #define REPORT_VIDEO_INFO 0 66 #endif 67 68 // for testing with GapiEmu 69 #define USE_GAPI_EMU 0 70 #define EMULATE_AXIM_X30 0 71 #define WITHOUT_GAPI 0 72 73 #if USE_GAPI_EMU && !REPORT_VIDEO_INFO 74 #pragma message("Warning: Using GapiEmu in release build. I assume you'd like to set USE_GAPI_EMU to zero.") 75 #endif 76 77 #ifndef _T 78 #define _T(x) L##x 79 #endif 80 81 #ifndef ASSERT 82 #define ASSERT(x) 83 #endif 84 85 // defined and used in SDL_sysevents.c 86 extern HINSTANCE aygshell; 87 extern void SDL_UnregisterApp(); 88 extern int DIB_AddMode(_THIS, int bpp, int w, int h); 89 90 /* Initialization/Query functions */ 91 static int GAPI_VideoInit(_THIS, SDL_PixelFormat *vformat); 92 static SDL_Rect **GAPI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); 93 static SDL_Surface *GAPI_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); 94 static int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); 95 static void GAPI_VideoQuit(_THIS); 96 97 /* Hardware surface functions */ 98 static int GAPI_AllocHWSurface(_THIS, SDL_Surface *surface); 99 static int GAPI_LockHWSurface(_THIS, SDL_Surface *surface); 100 static void GAPI_UnlockHWSurface(_THIS, SDL_Surface *surface); 101 static void GAPI_FreeHWSurface(_THIS, SDL_Surface *surface); 102 103 /* Windows message handling functions, will not be processed */ 104 static void GAPI_Activate(_THIS, BOOL active, BOOL minimized); 105 static void GAPI_RealizePalette(_THIS); 106 static void GAPI_PaletteChanged(_THIS, HWND window); 107 static void GAPI_WinPAINT(_THIS, HDC hdc); 108 109 /* etc. */ 110 static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects); 111 112 static HMODULE g_hGapiLib = 0; 113 #define LINK(type,name,import) \ 114 if( g_hGapiLib ) \ 115 name = (PFN##type)GetProcAddress( g_hGapiLib, _T(import) ); 116 117 static char g_bRawBufferAvailable = 0; 118 119 /* GAPI driver bootstrap functions */ 120 121 /* hi res definitions */ 122 typedef struct _RawFrameBufferInfo 123 { 124 WORD wFormat; 125 WORD wBPP; 126 VOID *pFramePointer; 127 int cxStride; 128 int cyStride; 129 int cxPixels; 130 int cyPixels; 131 } RawFrameBufferInfo; 132 133 static struct _RawFrameBufferInfo g_RawFrameBufferInfo = {0}; 134 135 #define GETRAWFRAMEBUFFER 0x00020001 136 137 #define FORMAT_565 1 138 #define FORMAT_555 2 139 #define FORMAT_OTHER 3 140 141 /* Dell Axim x30 hangs when we use GAPI from landscape, 142 so lets avoid using GxOpenDisplay there via GETGXINFO trick 143 It seems that GAPI subsystem use the same ExtEscape code. 144 */ 145 #define GETGXINFO 0x00020000 146 147 typedef struct GXDeviceInfo 148 { 149 long Version; //00 (should filled with 100 before calling ExtEscape) 150 void * pvFrameBuffer; //04 151 unsigned long cbStride; //08 152 unsigned long cxWidth; //0c 153 unsigned long cyHeight; //10 154 unsigned long cBPP; //14 155 unsigned long ffFormat; //18 156 char Unused[0x84-7*4]; 157 } GXDeviceInfo; 158 159 static int GAPI_Available(void) 160 { 161 // try to use VGA display, even on emulator 162 HDC hdc = GetDC(NULL); 163 int result = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *)&g_RawFrameBufferInfo); 164 ReleaseDC(NULL, hdc); 165 g_bRawBufferAvailable = result > 0; 166 167 //My Asus MyPAL 696 reports the RAWFRAMEBUFFER as available, but with a size of 0 x 0 168 if(g_RawFrameBufferInfo.cxPixels <= 0 || g_RawFrameBufferInfo.cyPixels <= 0){ 169 g_bRawBufferAvailable = 0; 170 } 171 172 #if WITHOUT_GAPI 173 return g_bRawBufferAvailable; 174 #endif 175 176 #if USE_GAPI_EMU 177 g_hGapiLib = LoadLibrary(_T("GAPI_Emu.dll")); 178 if( !g_hGapiLib ) 179 { 180 SDL_SetError("Gapi Emu not found!"); 181 } 182 return g_hGapiLib != 0; 183 #endif 184 185 // try to find gx.dll 186 g_hGapiLib = LoadLibrary(_T("\\Windows\\gx.dll")); 187 if( !g_hGapiLib ) 188 { 189 g_hGapiLib = LoadLibrary(_T("gx.dll")); 190 if( !g_hGapiLib ) return g_bRawBufferAvailable; 191 } 192 193 return(1); 194 } 195 196 static int cmpmodes(const void *va, const void *vb) 197 { 198 SDL_Rect *a = *(SDL_Rect **)va; 199 SDL_Rect *b = *(SDL_Rect **)vb; 200 if ( a->w == b->w ) 201 return b->h - a->h; 202 else 203 return b->w - a->w; 204 } 205 206 static int GAPI_AddMode(_THIS, int bpp, int w, int h) 207 { 208 SDL_Rect *mode; 209 int i, index; 210 int next_mode; 211 212 /* Check to see if we already have this mode */ 213 if ( bpp < 8 ) { /* Not supported */ 214 return(0); 215 } 216 index = ((bpp+7)/8)-1; 217 for ( i=0; i<gapi->SDL_nummodes[index]; ++i ) { 218 mode = gapi->SDL_modelist[index][i]; 219 if ( (mode->w == w) && (mode->h == h) ) { 220 return(0); 221 } 222 } 223 224 /* Set up the new video mode rectangle */ 225 mode = (SDL_Rect *)SDL_malloc(sizeof *mode); 226 if ( mode == NULL ) { 227 SDL_OutOfMemory(); 228 return(-1); 229 } 230 mode->x = 0; 231 mode->y = 0; 232 mode->w = w; 233 mode->h = h; 234 235 /* Allocate the new list of modes, and fill in the new mode */ 236 next_mode = gapi->SDL_nummodes[index]; 237 gapi->SDL_modelist[index] = (SDL_Rect **) 238 SDL_realloc(gapi->SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *)); 239 if ( gapi->SDL_modelist[index] == NULL ) { 240 SDL_OutOfMemory(); 241 gapi->SDL_nummodes[index] = 0; 242 SDL_free(mode); 243 return(-1); 244 } 245 gapi->SDL_modelist[index][next_mode] = mode; 246 gapi->SDL_modelist[index][next_mode+1] = NULL; 247 gapi->SDL_nummodes[index]++; 248 249 return(0); 250 } 251 252 static void GAPI_DeleteDevice(SDL_VideoDevice *device) 253 { 254 if( g_hGapiLib ) 255 { 256 FreeLibrary(g_hGapiLib); 257 g_hGapiLib = 0; 258 } 259 SDL_free(device->hidden->gapiInfo); 260 SDL_free(device->hidden); 261 SDL_free(device); 262 } 263 264 static SDL_VideoDevice *GAPI_CreateDevice(int devindex) 265 { 266 SDL_VideoDevice *device; 267 268 if( !g_hGapiLib && !g_bRawBufferAvailable) 269 { 270 if( !GAPI_Available() ) 271 { 272 SDL_SetError("GAPI dll is not found and VGA mode is not available!"); 273 return 0; 274 } 275 } 276 277 /* Initialize all variables that we clean on shutdown */ 278 device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice)); 279 if ( device ) { 280 SDL_memset(device, 0, (sizeof *device)); 281 device->hidden = (struct SDL_PrivateVideoData *) 282 SDL_malloc((sizeof *device->hidden)); 283 if(device->hidden){ 284 SDL_memset(device->hidden, 0, (sizeof *device->hidden)); 285 device->hidden->gapiInfo = (GapiInfo *)SDL_malloc((sizeof(GapiInfo))); 286 if(device->hidden->gapiInfo == NULL) 287 { 288 SDL_free(device->hidden); 289 device->hidden = NULL; 290 } 291 } 292 } 293 if ( (device == NULL) || (device->hidden == NULL) ) { 294 SDL_OutOfMemory(); 295 if ( device ) { 296 SDL_free(device); 297 } 298 return(0); 299 } 300 SDL_memset(device->hidden->gapiInfo, 0, (sizeof *device->hidden->gapiInfo)); 301 302 /* Set the function pointers */ 303 device->VideoInit = GAPI_VideoInit; 304 device->ListModes = GAPI_ListModes; 305 device->SetVideoMode = GAPI_SetVideoMode; 306 device->UpdateMouse = WIN_UpdateMouse; 307 device->CreateYUVOverlay = NULL; 308 device->SetColors = GAPI_SetColors; 309 device->UpdateRects = GAPI_UpdateRects; 310 device->VideoQuit = GAPI_VideoQuit; 311 device->AllocHWSurface = GAPI_AllocHWSurface; 312 device->CheckHWBlit = NULL; 313 device->FillHWRect = NULL; 314 device->SetHWColorKey = NULL; 315 device->SetHWAlpha = NULL; 316 device->LockHWSurface = GAPI_LockHWSurface; 317 device->UnlockHWSurface = GAPI_UnlockHWSurface; 318 device->FlipHWSurface = NULL; 319 device->FreeHWSurface = GAPI_FreeHWSurface; 320 device->SetCaption = WIN_SetWMCaption; 321 device->SetIcon = WIN_SetWMIcon; 322 device->IconifyWindow = WIN_IconifyWindow; 323 device->GrabInput = WIN_GrabInput; 324 device->GetWMInfo = WIN_GetWMInfo; 325 device->FreeWMCursor = WIN_FreeWMCursor; 326 device->CreateWMCursor = WIN_CreateWMCursor; 327 device->ShowWMCursor = WIN_ShowWMCursor; 328 device->WarpWMCursor = WIN_WarpWMCursor; 329 device->CheckMouseMode = WIN_CheckMouseMode; 330 device->InitOSKeymap = DIB_InitOSKeymap; 331 device->PumpEvents = DIB_PumpEvents; 332 333 /* Set up the windows message handling functions */ 334 WIN_Activate = GAPI_Activate; 335 WIN_RealizePalette = GAPI_RealizePalette; 336 WIN_PaletteChanged = GAPI_PaletteChanged; 337 WIN_WinPAINT = GAPI_WinPAINT; 338 HandleMessage = DIB_HandleMessage; 339 340 device->free = GAPI_DeleteDevice; 341 342 /* Load gapi library */ 343 #define gx device->hidden->gapiInfo->gxFunc 344 345 LINK( GXOpenDisplay, gx.GXOpenDisplay, "?GXOpenDisplay@@YAHPAUHWND__@@K@Z" ) 346 LINK( GXCloseDisplay, gx.GXCloseDisplay, "?GXCloseDisplay@@YAHXZ" ) 347 LINK( GXBeginDraw, gx.GXBeginDraw, "?GXBeginDraw@@YAPAXXZ" ) 348 LINK( GXEndDraw, gx.GXEndDraw, "?GXEndDraw@@YAHXZ" ) 349 LINK( GXOpenInput, gx.GXOpenInput, "?GXOpenInput@@YAHXZ" ) 350 LINK( GXCloseInput, gx.GXCloseInput, "?GXCloseInput@@YAHXZ" ) 351 LINK( GXGetDisplayProperties, gx.GXGetDisplayProperties,"?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ" ) 352 LINK( GXGetDefaultKeys, gx.GXGetDefaultKeys, "?GXGetDefaultKeys@@YA?AUGXKeyList@@H@Z" ) 353 LINK( GXSuspend, gx.GXSuspend, "?GXSuspend@@YAHXZ" ) 354 LINK( GXResume, gx.GXResume, "?GXResume@@YAHXZ" ) 355 LINK( GXSetViewport, gx.GXSetViewport, "?GXSetViewport@@YAHKKKK@Z" ) 356 LINK( GXIsDisplayDRAMBuffer, gx.GXIsDisplayDRAMBuffer, "?GXIsDisplayDRAMBuffer@@YAHXZ" ) 357 358 /* wrong gapi.dll */ 359 if( !gx.GXOpenDisplay ) 360 { 361 if( g_hGapiLib ) 362 { 363 FreeLibrary(g_hGapiLib); 364 g_hGapiLib = 0; 365 } 366 } 367 368 if( !gx.GXOpenDisplay && !g_bRawBufferAvailable) 369 { 370 SDL_SetError("Error: damaged or unknown gapi.dll!\n"); 371 GAPI_DeleteDevice(device); 372 return 0; 373 } 374 375 return device; 376 } 377 378 VideoBootStrap GAPI_bootstrap = { 379 GAPIVID_DRIVER_NAME, "WinCE GAPI video driver", 380 GAPI_Available, GAPI_CreateDevice 381 }; 382 383 static void FillStructs(_THIS, BOOL useVga) 384 { 385 #ifdef _ARM_ 386 WCHAR oemstr[100]; 387 #endif 388 /* fill a device properties */ 389 390 if( !useVga ) 391 { 392 gapi->gxProperties = gapi->gxFunc.GXGetDisplayProperties(); 393 gapi->needUpdate = 1; 394 gapi->hiresFix = 0; 395 gapi->useVga = 0; 396 gapi->useGXOpenDisplay = 1; 397 398 #ifdef _ARM_ 399 /* check some devices and extract addition info */ 400 SystemParametersInfo( SPI_GETOEMINFO, sizeof( oemstr ), oemstr, 0 ); 401 402 // buggy iPaq38xx 403 if ((oemstr[12] == 'H') && (oemstr[13] == '3') && (oemstr[14] == '8') && (gapi->gxProperties.cbxPitch > 0)) 404 { 405 gapi->videoMem = (PIXEL*)0xac0755a0; 406 gapi->gxProperties.cbxPitch = -640; 407 gapi->gxProperties.cbyPitch = 2; 408 gapi->needUpdate = 0; 409 } 410 #if (EMULATE_AXIM_X30 == 0) 411 // buggy Dell Axim X30 412 if( _tcsncmp(oemstr, L"Dell Axim X30", 13) == 0 ) 413 #endif 414 { 415 GXDeviceInfo gxInfo = {0}; 416 HDC hdc = GetDC(NULL); 417 int result; 418 419 gxInfo.Version = 100; 420 result = ExtEscape(hdc, GETGXINFO, 0, NULL, sizeof(gxInfo), (char *)&gxInfo); 421 if( result > 0 ) 422 { 423 gapi->useGXOpenDisplay = 0; 424 gapi->videoMem = gxInfo.pvFrameBuffer; 425 gapi->needUpdate = 0; 426 gapi->gxProperties.cbxPitch = 2; 427 gapi->gxProperties.cbyPitch = 480; 428 gapi->gxProperties.cxWidth = gxInfo.cxWidth; 429 gapi->gxProperties.cyHeight = gxInfo.cyHeight; 430 gapi->gxProperties.ffFormat = gxInfo.ffFormat; 431 } 432 } 433 #endif 434 } else 435 { 436 gapi->needUpdate = 0; 437 gapi->hiresFix = 0; 438 gapi->gxProperties.cBPP = g_RawFrameBufferInfo.wBPP; 439 gapi->gxProperties.cbxPitch = g_RawFrameBufferInfo.cxStride; 440 gapi->gxProperties.cbyPitch = g_RawFrameBufferInfo.cyStride; 441 gapi->gxProperties.cxWidth = g_RawFrameBufferInfo.cxPixels; 442 gapi->gxProperties.cyHeight = g_RawFrameBufferInfo.cyPixels; 443 gapi->videoMem = g_RawFrameBufferInfo.pFramePointer; 444 gapi->useVga = 1; 445 446 switch( g_RawFrameBufferInfo.wFormat ) 447 { 448 case FORMAT_565: 449 gapi->gxProperties.ffFormat = kfDirect565; 450 break; 451 case FORMAT_555: 452 gapi->gxProperties.ffFormat = kfDirect555; 453 break; 454 default: 455 /* unknown pixel format, try define by BPP! */ 456 switch( g_RawFrameBufferInfo.wBPP ) 457 { 458 case 4: 459 case 8: 460 gapi->gxProperties.ffFormat = kfDirect; 461 case 16: 462 gapi->gxProperties.ffFormat = kfDirect565; 463 default: 464 gapi->gxProperties.ffFormat = kfDirect; 465 break; 466 } 467 } 468 } 469 470 if( gapi->gxProperties.cBPP != 16 ) 471 { 472 gapi->gapiOrientation = SDL_ORIENTATION_UP; 473 } else 474 if( (gapi->gxProperties.cbxPitch > 0) && (gapi->gxProperties.cbyPitch > 0 )) 475 { 476 gapi->gapiOrientation = SDL_ORIENTATION_UP; 477 } else 478 if( (gapi->gxProperties.cbxPitch > 0) && (gapi->gxProperties.cbyPitch < 0 )) 479 { 480 gapi->gapiOrientation = SDL_ORIENTATION_RIGHT; // ipaq 3660 481 } else 482 if( (gapi->gxProperties.cbxPitch < 0) && (gapi->gxProperties.cbyPitch > 0 )) 483 { 484 gapi->gapiOrientation = SDL_ORIENTATION_LEFT; // ipaq 3800 485 } 486 } 487 488 static void GAPI_CreatePalette(int ncolors, SDL_Color *colors) 489 { 490 // Setup a custom color palette 491 BYTE buffer[ sizeof(LOGPALETTE) + 255 * sizeof(PALETTEENTRY) ]; 492 int i; 493 LOGPALETTE* pLogical = (LOGPALETTE*)buffer; 494 PALETTEENTRY* entries = pLogical->palPalEntry; 495 HPALETTE hPalette; 496 HDC hdc; 497 498 for (i = 0; i < ncolors; ++i) 499 { 500 // Find intensity by replicating the bit patterns over a byte 501 entries[i].peRed = colors[i].r; 502 entries[i].peGreen = colors[i].g; 503 entries[i].peBlue = colors[i].b; 504 entries[i].peFlags = 0; 505 } 506 507 // Create the GDI palette object 508 pLogical->palVersion = 0x0300; 509 pLogical->palNumEntries = ncolors; 510 511 hPalette = CreatePalette( pLogical ); 512 ASSERT(hPalette); 513 514 515 // Realize the palette 516 hdc = GetDC(0); 517 518 SelectPalette( hdc, hPalette, FALSE ); 519 RealizePalette( hdc ); 520 521 ReleaseDC( 0, hdc ); 522 DeleteObject( hPalette ); 523 } 524 525 int GAPI_VideoInit(_THIS, SDL_PixelFormat *vformat) 526 { 527 int i,bpp; 528 529 /* Create the window */ 530 if ( DIB_CreateWindow(this) < 0 ) { 531 return(-1); 532 } 533 534 if( g_hGapiLib ) 535 { 536 FillStructs(this, 0); 537 538 // SDL does not supports 2/4bpp mode, so use 16 bpp 539 bpp = gapi->gxProperties.cBPP < 8 ? 16 : gapi->gxProperties.cBPP; 540 541 /* set up normal and landscape mode */ 542 GAPI_AddMode(this, bpp, gapi->gxProperties.cyHeight, gapi->gxProperties.cxWidth); 543 GAPI_AddMode(this, bpp, gapi->gxProperties.cxWidth, gapi->gxProperties.cyHeight); 544 } 545 546 /* add hi-res mode */ 547 if( g_bRawBufferAvailable && 548 !((gapi->gxProperties.cxWidth == (unsigned)g_RawFrameBufferInfo.cxPixels) && (gapi->gxProperties.cyHeight == (unsigned)g_RawFrameBufferInfo.cyPixels))) 549 { 550 FillStructs(this, 1); 551 552 // SDL does not supports 2/4bpp mode, so use 16 bpp 553 bpp = gapi->gxProperties.cBPP < 8 ? 16 : gapi->gxProperties.cBPP; 554 555 /* set up normal and landscape mode */ 556 GAPI_AddMode(this, bpp, gapi->gxProperties.cyHeight, gapi->gxProperties.cxWidth); 557 GAPI_AddMode(this, bpp, gapi->gxProperties.cxWidth, gapi->gxProperties.cyHeight); 558 } 559 560 /* Determine the current screen size. 561 * This is NOT necessarily the size of the Framebuffer or GAPI, as they return 562 * the displaysize in ORIENTATION_UP */ 563 this->info.current_w = GetSystemMetrics(SM_CXSCREEN); 564 this->info.current_h = GetSystemMetrics(SM_CYSCREEN); 565 566 /* Sort the mode lists */ 567 for ( i=0; i<NUM_MODELISTS; ++i ) { 568 if ( gapi->SDL_nummodes[i] > 0 ) { 569 SDL_qsort(gapi->SDL_modelist[i], gapi->SDL_nummodes[i], sizeof *gapi->SDL_modelist[i], cmpmodes); 570 } 571 } 572 573 vformat->BitsPerPixel = gapi->gxProperties.cBPP < 8 ? 16 : (unsigned char)gapi->gxProperties.cBPP; 574 575 // Get color mask 576 if (gapi->gxProperties.ffFormat & kfDirect565) { 577 vformat->BitsPerPixel = 16; 578 vformat->Rmask = 0x0000f800; 579 vformat->Gmask = 0x000007e0; 580 vformat->Bmask = 0x0000001f; 581 gapi->videoMode = GAPI_DIRECT_565; 582 } 583 else 584 if (gapi->gxProperties.ffFormat & kfDirect555) { 585 vformat->BitsPerPixel = 16; 586 vformat->Rmask = 0x00007c00; 587 vformat->Gmask = 0x000003e0; 588 vformat->Bmask = 0x0000001f; 589 gapi->videoMode = GAPI_DIRECT_555; 590 } 591 else 592 if ((gapi->gxProperties.ffFormat & kfDirect) && (gapi->gxProperties.cBPP < 8)) { 593 // We'll perform the conversion 594 vformat->BitsPerPixel = 16; 595 vformat->Rmask = 0x0000f800; // 16 bit 565 596 vformat->Gmask = 0x000007e0; 597 vformat->Bmask = 0x0000001f; 598 if (gapi->gxProperties.ffFormat & kfDirectInverted) 599 gapi->invert = (1 << gapi->gxProperties.cBPP) - 1; 600 gapi->colorscale = gapi->gxProperties.cBPP < 8 ? 8 - gapi->gxProperties.cBPP : 0; 601 gapi->videoMode = GAPI_MONO; 602 } 603 else 604 if (gapi->gxProperties.ffFormat & kfPalette) { 605 gapi->videoMode = GAPI_PALETTE; 606 } 607 608 /* We're done! */ 609 return(0); 610 } 611 612 SDL_Rect **GAPI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) 613 { 614 return(gapi->SDL_modelist[((format->BitsPerPixel+7)/8)-1]); 615 // return (SDL_Rect **) -1; 616 } 617 618 SDL_Surface *GAPI_SetVideoMode(_THIS, SDL_Surface *current, 619 int width, int height, int bpp, Uint32 flags) 620 { 621 SDL_Surface *video; 622 Uint32 Rmask, Gmask, Bmask; 623 DWORD style; 624 SDL_Rect allScreen; 625 626 if( bpp < 4 ) 627 { 628 SDL_SetError("1 bpp and 2 bpp modes is not implemented yet!"); 629 return 0; 630 } 631 632 /* Recalculate bitmasks if necessary */ 633 if (bpp == current->format->BitsPerPixel) { 634 video = current; 635 } 636 else { 637 switch(bpp) { 638 case 8: 639 Rmask = 0; 640 Gmask = 0; 641 Bmask = 0; 642 break; 643 case 15: 644 case 16: 645 /* Default is 565 unless the display is specifically 555 */ 646 if (gapi->gxProperties.ffFormat & kfDirect555) { 647 Rmask = 0x00007c00; 648 Gmask = 0x000003e0; 649 Bmask = 0x0000001f; 650 } 651 else { 652 Rmask = 0x0000f800; 653 Gmask = 0x000007e0; 654 Bmask = 0x0000001f; 655 } 656 break; 657 case 24: 658 case 32: 659 Rmask = 0x00ff0000; 660 Gmask = 0x0000ff00; 661 Bmask = 0x000000ff; 662 break; 663 default: 664 SDL_SetError("Unsupported Bits Per Pixel format requested"); 665 return NULL; 666 } 667 video = SDL_CreateRGBSurface(SDL_SWSURFACE, 668 0, 0, bpp, Rmask, Gmask, Bmask, 0); 669 if ( video == NULL ) { 670 SDL_OutOfMemory(); 671 return(NULL); 672 } 673 } 674 675 gapi->userOrientation = SDL_ORIENTATION_UP; 676 gapi->systemOrientation = SDL_ORIENTATION_UP; 677 video->flags = SDL_FULLSCREEN; /* Clear flags, GAPI supports fullscreen only */ 678 679 /* GAPI or VGA? */ 680 if( g_hGapiLib ) 681 { 682 FillStructs(this, 0); 683 if( (((unsigned)width != gapi->gxProperties.cxWidth) || ((unsigned)height != gapi->gxProperties.cyHeight)) 684 && (((unsigned)width != gapi->gxProperties.cyHeight) || ((unsigned)height != gapi->gxProperties.cxWidth))) 685 FillStructs(this, 1); // gapi is found but we use VGA resolution 686 } else 687 FillStructs(this, 1); 688 689 if ( !gapi->needUpdate && !gapi->videoMem) { 690 SDL_SetError("Couldn't get address of video memory, may be unsupported device or bug"); 691 return(NULL); 692 } 693 694 /* detect user landscape mode */ 695 if( (width > height) && (gapi->gxProperties.cxWidth < gapi->gxProperties.cyHeight)) 696 gapi->userOrientation = SDL_ORIENTATION_RIGHT; 697 698 if(GetSystemMetrics(SM_CYSCREEN) < GetSystemMetrics(SM_CXSCREEN)) 699 gapi->systemOrientation = SDL_ORIENTATION_RIGHT; 700 701 gapi->hiresFix = 0; 702 703 /* check hires */ 704 if(GetSystemMetrics(SM_CXSCREEN) < width && GetSystemMetrics(SM_CYSCREEN) < height) 705 { 706 gapi->hiresFix = 1; 707 } 708 709 switch( gapi->userOrientation ) 710 { 711 case SDL_ORIENTATION_UP: 712 gapi->startOffset = 0; 713 gapi->dstLineStep = gapi->gxProperties.cbyPitch; 714 gapi->dstPixelStep = gapi->gxProperties.cbxPitch; 715 break; 716 case SDL_ORIENTATION_RIGHT: 717 switch( gapi->gapiOrientation ) 718 { 719 case SDL_ORIENTATION_UP: 720 case SDL_ORIENTATION_RIGHT: 721 case SDL_ORIENTATION_LEFT: 722 if( (gapi->videoMode == GAPI_MONO) ) 723 gapi->startOffset = -gapi->gxProperties.cbxPitch + 1; // monochrome mode 724 else 725 gapi->startOffset = gapi->gxProperties.cbyPitch * (gapi->gxProperties.cyHeight - 1); 726 727 gapi->dstLineStep = gapi->gxProperties.cbxPitch; 728 gapi->dstPixelStep = -gapi->gxProperties.cbyPitch; 729 break; 730 } 731 } 732 733 video->w = gapi->w = width; 734 video->h = gapi->h = height; 735 video->pitch = SDL_CalculatePitch(video); 736 737 /* Small fix for WinCE/Win32 - when activating window 738 SDL_VideoSurface is equal to zero, so activating code 739 is not called properly for fullscreen windows because 740 macros WINDIB_FULLSCREEN uses SDL_VideoSurface 741 */ 742 SDL_VideoSurface = video; 743 744 /* GAPI is always fullscreen, title bar is useless */ 745 style = 0; 746 747 if (!SDL_windowid) 748 SetWindowLong(SDL_Window, GWL_STYLE, style); 749 750 /* Allocate bitmap */ 751 if( gapi->buffer ) 752 { 753 SDL_free( gapi->buffer ); 754 gapi->buffer = NULL; 755 } 756 gapi->buffer = SDL_malloc(video->h * video->pitch); 757 video->pixels = gapi->buffer; 758 759 if ( ! gapi->buffer ) { 760 SDL_SetError("Couldn't allocate buffer for requested mode"); 761 return(NULL); 762 } 763 764 SDL_memset(gapi->buffer, 255, video->h * video->pitch); 765 MoveWindow(SDL_Window, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), FALSE); 766 ShowWindow(SDL_Window, SW_SHOW); 767 SetForegroundWindow(SDL_Window); 768 769 /* JC 14 Mar 2006 770 Flush the message loop or this can cause big problems later 771 Especially if the user decides to use dialog boxes or assert()! 772 */ 773 WIN_FlushMessageQueue(); 774 775 /* Open GAPI display */ 776 if( !gapi->useVga && gapi->useGXOpenDisplay && !gapi->alreadyGXOpened ) 777 { 778 #if REPORT_VIDEO_INFO 779 printf("system display width (orig): %d\n", GetSystemMetrics(SM_CXSCREEN)); 780 printf("system display height (orig): %d\n", GetSystemMetrics(SM_CYSCREEN)); 781 #endif 782 gapi->alreadyGXOpened = 1; 783 if( !gapi->gxFunc.GXOpenDisplay(SDL_Window, GX_FULLSCREEN) ) 784 { 785 SDL_SetError("Couldn't initialize GAPI"); 786 return(NULL); 787 } 788 } 789 790 if(gapi->useVga) 791 gapi->coordinateTransform = (4 - gapi->systemOrientation + gapi->userOrientation) % 4; 792 else 793 gapi->coordinateTransform = gapi->userOrientation; 794 795 #if REPORT_VIDEO_INFO 796 printf("Video properties:\n"); 797 printf("display bpp: %d\n", gapi->gxProperties.cBPP); 798 printf("display width: %d\n", gapi->gxProperties.cxWidth); 799 printf("display height: %d\n", gapi->gxProperties.cyHeight); 800 printf("system display width: %d\n", GetSystemMetrics(SM_CXSCREEN)); 801 printf("system display height: %d\n", GetSystemMetrics(SM_CYSCREEN)); 802 printf("x pitch: %d\n", gapi->gxProperties.cbxPitch); 803 printf("y pitch: %d\n", gapi->gxProperties.cbyPitch); 804 printf("gapi flags: 0x%x\n", gapi->gxProperties.ffFormat); 805 printf("user orientation: %d\n", gapi->userOrientation); 806 printf("system orientation: %d\n", gapi->systemOrientation); 807 printf("gapi orientation: %d\n", gapi->gapiOrientation); 808 809 810 if( !gapi->useVga && gapi->useGXOpenDisplay && gapi->needUpdate) 811 { 812 gapi->videoMem = gapi->gxFunc.GXBeginDraw(); 813 gapi->gxFunc.GXEndDraw(); 814 } 815 816 printf("video memory: 0x%x\n", gapi->videoMem); 817 printf("need update: %d\n", gapi->needUpdate); 818 printf("hi-res fix: %d\n", gapi->hiresFix); 819 printf("VGA is available on the device: %d\n", g_bRawBufferAvailable); 820 printf("use raw framebuffer: %d\n", gapi->useVga); 821 printf("video surface bpp: %d\n", video->format->BitsPerPixel); 822 printf("video surface width: %d\n", video->w); 823 printf("video surface height: %d\n", video->h); 824 printf("mouse/arrows transformation angle: %d\n", gapi->coordinateTransform); 825 #endif 826 827 828 /* Blank screen */ 829 allScreen.x = allScreen.y = 0; 830 allScreen.w = video->w - 1; 831 allScreen.h = video->h - 1; 832 GAPI_UpdateRects(this, 1, &allScreen); 833 834 /* We're done */ 835 return(video); 836 } 837 838 /* We don't actually allow hardware surfaces other than the main one */ 839 static int GAPI_AllocHWSurface(_THIS, SDL_Surface *surface) 840 { 841 return(-1); 842 } 843 static void GAPI_FreeHWSurface(_THIS, SDL_Surface *surface) 844 { 845 return; 846 } 847 848 /* We need to wait for vertical retrace on page flipped displays */ 849 static int GAPI_LockHWSurface(_THIS, SDL_Surface *surface) 850 { 851 return(0); 852 } 853 854 static void GAPI_UnlockHWSurface(_THIS, SDL_Surface *surface) 855 { 856 return; 857 } 858 859 static int updateLine8to8(_THIS, unsigned char *srcPointer, unsigned char *destPointer, int width, int height, int lines) 860 { 861 if( gapi->dstPixelStep == 1) /* optimized blitting on most devices */ 862 { 863 SDL_memcpy(destPointer, srcPointer, width); 864 return 1; 865 } else 866 { 867 // TODO: read 4 pixels, write DWORD 868 int step = gapi->dstPixelStep; 869 while(width--) 870 { 871 *destPointer = *srcPointer++; 872 destPointer += step; 873 } 874 } 875 return 1; 876 } 877 878 /* Video memory is very slow so lets optimize as much as possible */ 879 static int updateLine16to16(_THIS, PIXEL *srcPointer, PIXEL *destPointer, int width, int height, int lines) 880 { 881 PIXEL *line1, *line2; 882 int step = gapi->dstPixelStep / 2; 883 884 if( step == 1 ) /* optimized blitting on most devices */ 885 { 886 SDL_memcpy(destPointer, srcPointer, width * sizeof(PIXEL)); 887 return 1; 888 } 889 else 890 { 891 if( (gapi->gapiOrientation != SDL_ORIENTATION_UP) && 892 (gapi->userOrientation == SDL_ORIENTATION_UP )) // iPaq 3660/3800 and user orientation up 893 { 894 // to prevent data misalignment copy only one line 895 if( ((((unsigned)destPointer & 3) != 0) && (gapi->gapiOrientation == SDL_ORIENTATION_LEFT)) 896 || ((((unsigned)destPointer & 3) == 0) && (gapi->gapiOrientation != SDL_ORIENTATION_LEFT)) 897 || (lines == 1) ) 898 { 899 while(width--) 900 { 901 *destPointer = *srcPointer++; 902 destPointer += step; 903 } 904 return 1; 905 } 906 907 /* read two lines at the same time, write DWORD */ 908 line1 = srcPointer; 909 line2 = srcPointer + SDL_VideoSurface->pitch / 2; 910 911 if( gapi->gapiOrientation == SDL_ORIENTATION_LEFT ) 912 while(width--) // iPaq 3800 913 { 914 *(DWORD*)destPointer =(*line2++ << 16) | *line1++; 915 destPointer += step; 916 } 917 else 918 { 919 destPointer += gapi->gxProperties.cbyPitch / 2; 920 921 while(width--) // iPaq 3660 922 { 923 *(DWORD*)destPointer =(*line1++ << 16) | *line2++; 924 destPointer += step; 925 } 926 } 927 return 2; 928 } else 929 { 930 // iPaq 3800 and user orientation landscape 931 if( gapi->gapiOrientation == SDL_ORIENTATION_LEFT ) 932 { 933 int w1; 934 935 // to prevent data misalignment copy only one pixel 936 if( (((unsigned)destPointer & 3) == 0) && (width > 0)) 937 { 938 *destPointer-- = *srcPointer++; 939 width--; 940 } 941 942 destPointer--; 943 944 w1 = width / 2; 945 946 while(w1--) 947 { 948 DWORD p = *(DWORD*)srcPointer; 949 *((DWORD*)destPointer) = (p << 16) | (p >> 16); 950 destPointer -= 2; 951 srcPointer += 2; 952 } 953 954 if( width & 1 ) // copy the last pixel 955 { 956 destPointer++; 957 *destPointer = *srcPointer; 958 } 959 960 return 1; 961 } 962 963 // modern iPaqs and user orientation landscape 964 // read two pixels, write DWORD 965 966 line1 = srcPointer; 967 line2 = srcPointer + SDL_VideoSurface->pitch / 2; 968 969 if( (((unsigned)destPointer & 3) != 0) || (lines == 1) ) 970 { 971 while(width--) 972 { 973 *destPointer = *srcPointer++; 974 destPointer += step; 975 } 976 return 1; 977 } 978 979 while(width--) 980 { 981 *(DWORD*)destPointer =(*line2++ << 16) | *line1++; 982 destPointer -= gapi->gxProperties.cbyPitch / 2; 983 } 984 return 2; 985 } 986 } 987 } 988 989 // Color component masks for 565 990 #define REDMASK (31<<11) 991 #define GREENMASK (63<<5) 992 #define BLUEMASK (31) 993 994 995 static int updateLine16to4(_THIS, PIXEL *srcPointer, unsigned char *destPointer, int width, int height, int lines, int yNibble, int xNibble) 996 { 997 PIXEL *line1, *line2; 998 int step = gapi->dstPixelStep; 999 1000 if( gapi->userOrientation == SDL_ORIENTATION_UP ) 1001 { 1002 if( yNibble ) // copy bottom half of a line 1003 { 1004 while(width--) 1005 { 1006 PIXEL c1 = *srcPointer++; 1007 c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK); 1008 *destPointer = (*destPointer & 0x0F) | ((~(c1 >> 3) << 4)); 1009 destPointer += step; 1010 } 1011 return 1; 1012 } 1013 1014 // either 1 pixel picture or tail, anyway this is the last line 1015 if( lines == 1 ) 1016 { 1017 while(width--) 1018 { 1019 PIXEL c1 = *srcPointer++; 1020 c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK); 1021 *destPointer = (*destPointer & 0xF0) | ((~(c1 >> 3) & 0xF)); 1022 destPointer += step; 1023 } 1024 return 1; 1025 } 1026 1027 line1 = srcPointer; 1028 line2 = srcPointer + SDL_VideoSurface->pitch / 2; 1029 1030 while(width--) 1031 { 1032 PIXEL c1 = *line1++; 1033 PIXEL c2 = *line2++; 1034 c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK); 1035 c2 = ((c2 & REDMASK) >> 11) + ((c2 & GREENMASK) >> 5) + (c2 & BLUEMASK); 1036 *destPointer = ~((c1 >> 3) + ((c2 >> 3) << 4)); 1037 destPointer += step; 1038 } 1039 return 2; 1040 } else 1041 { 1042 int w1; 1043 w1 = width / 2; 1044 1045 if( xNibble ) 1046 { 1047 // copy one pixel 1048 PIXEL c1 = *srcPointer++; 1049 c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK); 1050 *destPointer = (*destPointer & 0xF0) | ((~(c1 >> 3) & 0xF)); 1051 destPointer++; 1052 } 1053 1054 while(w1--) 1055 { 1056 PIXEL c1 = *srcPointer; 1057 PIXEL c2 = *(srcPointer + 1); 1058 c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK); 1059 c2 = ((c2 & REDMASK) >> 11) + ((c2 & GREENMASK) >> 5) + (c2 & BLUEMASK); 1060 *destPointer++ = ~((c2 >> 3) + ((c1 >> 3) << 4)); 1061 srcPointer += 2; 1062 } 1063 1064 // copy tail 1065 if( (width & 1) && !xNibble ) 1066 { 1067 PIXEL c1 = *srcPointer; 1068 c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK); 1069 *destPointer = (*destPointer & 0x0F) | ((~(c1 >> 3) << 4)); 1070 } 1071 1072 return 1; 1073 } 1074 } 1075 1076 static void GAPI_UpdateRectsMono(_THIS, int numrects, SDL_Rect *rects) 1077 { 1078 int i, height; 1079 int linesProcessed; 1080 int xNibble, yNibble; 1081 1082 for (i=0; i<numrects; i++) 1083 { 1084 unsigned char *destPointer; 1085 unsigned char *srcPointer; 1086 1087 if( gapi->userOrientation == SDL_ORIENTATION_UP ) 1088 destPointer = (unsigned char*) gapi->videoMem + gapi->startOffset - rects[i].y * gapi->gxProperties.cBPP / 8 + rects[i].x * gapi->dstPixelStep; 1089 else 1090 destPointer = (unsigned char*) gapi->videoMem + gapi->startOffset + rects[i].x * gapi->gxProperties.cBPP / 8 + rects[i].y * gapi->dstLineStep; 1091 1092 srcPointer = ((unsigned char*) SDL_VideoSurface->pixels) + rects[i].y * SDL_VideoSurface->pitch + rects[i].x * 2; 1093 yNibble = rects[i].y & 1; // TODO: only for 4 bpp 1094 xNibble = rects[i].x & 1; 1095 height = rects[i].h; 1096 while (height > 0) 1097 { 1098 switch(gapi->gxProperties.cBPP) 1099 { 1100 case 2: // TODO 1101 case 4: 1102 linesProcessed = updateLine16to4(this, (PIXEL*) srcPointer, destPointer, rects[i].w, rects[i].h, height, yNibble, xNibble); 1103 yNibble = 0; 1104 } 1105 height -= linesProcessed; 1106 if( gapi->userOrientation == SDL_ORIENTATION_UP ) 1107 destPointer--; // always fill 1 byte 1108 else destPointer += gapi->dstLineStep; 1109 srcPointer += SDL_VideoSurface->pitch * linesProcessed; // pitch in bytes 1110 } 1111 } 1112 } 1113 1114 static void GAPI_UpdateRectsColor(_THIS, int numrects, SDL_Rect *rects) 1115 { 1116 int i, height; 1117 int bytesPerPixel = (gapi->gxProperties.cBPP + 1) / 8; 1118 int linesProcessed; 1119 for (i=0; i<numrects; i++) { 1120 unsigned char *destPointer = (unsigned char*) gapi->videoMem + gapi->startOffset + rects[i].y * gapi->dstLineStep + rects[i].x * gapi->dstPixelStep; 1121 unsigned char *srcPointer = ((unsigned char*) SDL_VideoSurface->pixels) + rects[i].y * SDL_VideoSurface->pitch + rects[i].x * bytesPerPixel; 1122 height = rects[i].h; 1123 1124 // fprintf(stderr, "Starting rect %dx%d, dst=0x%x, w = %d, h = %d\n", rects[i].w, rects[i].h,destPointer,rects[i].w,rects[i].h); 1125 // fflush(stderr); 1126 linesProcessed = height; 1127 1128 while (height > 0) { 1129 switch(bytesPerPixel) 1130 { 1131 case 1: 1132 linesProcessed = updateLine8to8(this, srcPointer, (unsigned char *) destPointer, rects[i].w, rects[i].h, height); 1133 break; 1134 case 2: 1135 #pragma warning(disable: 4133) 1136 linesProcessed = updateLine16to16(this, (PIXEL*) srcPointer, destPointer, rects[i].w, rects[i].h, height); 1137 break; 1138 } 1139 height -= linesProcessed; 1140 destPointer += gapi->dstLineStep * linesProcessed; 1141 srcPointer += SDL_VideoSurface->pitch * linesProcessed; // pitch in bytes 1142 } 1143 // fprintf(stderr, "End of rect\n"); 1144 // fflush(stderr); 1145 } 1146 } 1147 1148 1149 static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects) 1150 { 1151 // we do not want to corrupt video memory 1152 if( gapi->suspended ) return; 1153 1154 if( gapi->needUpdate ) 1155 gapi->videoMem = gapi->gxFunc.GXBeginDraw(); 1156 1157 if( gapi->gxProperties.cBPP < 8 ) 1158 GAPI_UpdateRectsMono(this, numrects, rects); 1159 else 1160 GAPI_UpdateRectsColor(this, numrects, rects); 1161 1162 if( gapi->needUpdate ) 1163 gapi->gxFunc.GXEndDraw(); 1164 } 1165 1166 /* Note: If we are terminated, this could be called in the middle of 1167 another SDL video routine -- notably UpdateRects. 1168 */ 1169 void GAPI_VideoQuit(_THIS) 1170 { 1171 int i, j; 1172 /* Destroy the window and everything associated with it */ 1173 if ( SDL_Window ) 1174 { 1175 if ((g_hGapiLib != 0) && this && gapi && gapi->gxFunc.GXCloseDisplay && !gapi->useVga) 1176 gapi->gxFunc.GXCloseDisplay(); 1177 1178 if (this->screen->pixels != NULL) 1179 { 1180 SDL_free(this->screen->pixels); 1181 this->screen->pixels = NULL; 1182 } 1183 if ( screen_icn ) { 1184 DestroyIcon(screen_icn); 1185 screen_icn = NULL; 1186 } 1187 1188 DIB_DestroyWindow(this); 1189 SDL_UnregisterApp(); 1190 1191 SDL_Window = NULL; 1192 #if defined(_WIN32_WCE) 1193 1194 // Unload wince aygshell library to prevent leak 1195 if( aygshell ) 1196 { 1197 FreeLibrary(aygshell); 1198 aygshell = NULL; 1199 } 1200 #endif 1201 1202 /* Free video mode lists */ 1203 for ( i=0; i<NUM_MODELISTS; ++i ) { 1204 if ( gapi->SDL_modelist[i] != NULL ) { 1205 for ( j=0; gapi->SDL_modelist[i][j]; ++j ) 1206 SDL_free(gapi->SDL_modelist[i][j]); 1207 SDL_free(gapi->SDL_modelist[i]); 1208 gapi->SDL_modelist[i] = NULL; 1209 } 1210 } 1211 1212 } 1213 1214 } 1215 1216 static void GAPI_Activate(_THIS, BOOL active, BOOL minimized) 1217 { 1218 //Nothing to do here (as far as I know) 1219 } 1220 1221 static void GAPI_RealizePalette(_THIS) 1222 { 1223 OutputDebugString(TEXT("GAPI_RealizePalette NOT IMPLEMENTED !\r\n")); 1224 } 1225 1226 static void GAPI_PaletteChanged(_THIS, HWND window) 1227 { 1228 OutputDebugString(TEXT("GAPI_PaletteChanged NOT IMPLEMENTED !\r\n")); 1229 } 1230 1231 static void GAPI_WinPAINT(_THIS, HDC hdc) 1232 { 1233 // draw current offscreen buffer on hdc 1234 1235 int bpp = 16; // we always use either 8 or 16 bpp internally 1236 HGDIOBJ prevObject; 1237 unsigned short *bitmapData; 1238 HBITMAP hb; 1239 HDC srcDC; 1240 1241 // Create a DIB 1242 BYTE buffer[sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD)] = {0}; 1243 BITMAPINFO* pBMI = (BITMAPINFO*)buffer; 1244 BITMAPINFOHEADER* pHeader = &pBMI->bmiHeader; 1245 DWORD* pColors = (DWORD*)&pBMI->bmiColors; 1246 1247 // CreateDIBSection does not support 332 pixel format on wce 1248 if( gapi->gxProperties.cBPP == 8 ) return; 1249 1250 // DIB Header 1251 pHeader->biSize = sizeof(BITMAPINFOHEADER); 1252 pHeader->biWidth = gapi->w; 1253 pHeader->biHeight = -gapi->h; 1254 pHeader->biPlanes = 1; 1255 pHeader->biBitCount = bpp; 1256 pHeader->biCompression = BI_RGB; 1257 pHeader->biSizeImage = (gapi->w * gapi->h * bpp) / 8; 1258 1259 // Color masks 1260 if( bpp == 16 ) 1261 { 1262 pColors[0] = REDMASK; 1263 pColors[1] = GREENMASK; 1264 pColors[2] = BLUEMASK; 1265 pHeader->biCompression = BI_BITFIELDS; 1266 } 1267 // Create the DIB 1268 hb = CreateDIBSection( 0, pBMI, DIB_RGB_COLORS, (void**)&bitmapData, 0, 0 ); 1269 1270 // copy data 1271 // FIXME: prevent misalignment, but I've never seen non aligned width of screen 1272 memcpy(bitmapData, gapi->buffer, pHeader->biSizeImage); 1273 srcDC = CreateCompatibleDC(hdc); 1274 prevObject = SelectObject(srcDC, hb); 1275 1276 BitBlt(hdc, 0, 0, gapi->w, gapi->h, srcDC, 0, 0, SRCCOPY); 1277 1278 SelectObject(srcDC, prevObject); 1279 DeleteObject(hb); 1280 DeleteDC(srcDC); 1281 } 1282 1283 int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) 1284 { 1285 GAPI_CreatePalette(ncolors, colors); 1286 return 1; 1287 } 1288