• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@libsdl.org
21 */
22 #include "SDL_config.h"
23 
24 /* Pocket PC GAPI SDL video driver implementation;
25 Implemented by Dmitry Yakimov - support@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 
GAPI_Available(void)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 
cmpmodes(const void * va,const void * vb)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 
GAPI_AddMode(_THIS,int bpp,int w,int h)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 
GAPI_DeleteDevice(SDL_VideoDevice * device)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 
GAPI_CreateDevice(int devindex)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 
FillStructs(_THIS,BOOL useVga)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 
GAPI_CreatePalette(int ncolors,SDL_Color * colors)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 
GAPI_VideoInit(_THIS,SDL_PixelFormat * vformat)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 
GAPI_ListModes(_THIS,SDL_PixelFormat * format,Uint32 flags)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 
GAPI_SetVideoMode(_THIS,SDL_Surface * current,int width,int height,int bpp,Uint32 flags)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 */
GAPI_AllocHWSurface(_THIS,SDL_Surface * surface)839 static int GAPI_AllocHWSurface(_THIS, SDL_Surface *surface)
840 {
841 	return(-1);
842 }
GAPI_FreeHWSurface(_THIS,SDL_Surface * surface)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 */
GAPI_LockHWSurface(_THIS,SDL_Surface * surface)849 static int GAPI_LockHWSurface(_THIS, SDL_Surface *surface)
850 {
851 	return(0);
852 }
853 
GAPI_UnlockHWSurface(_THIS,SDL_Surface * surface)854 static void GAPI_UnlockHWSurface(_THIS, SDL_Surface *surface)
855 {
856 	return;
857 }
858 
updateLine8to8(_THIS,unsigned char * srcPointer,unsigned char * destPointer,int width,int height,int lines)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 */
updateLine16to16(_THIS,PIXEL * srcPointer,PIXEL * destPointer,int width,int height,int lines)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 
updateLine16to4(_THIS,PIXEL * srcPointer,unsigned char * destPointer,int width,int height,int lines,int yNibble,int xNibble)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 
GAPI_UpdateRectsMono(_THIS,int numrects,SDL_Rect * rects)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 
GAPI_UpdateRectsColor(_THIS,int numrects,SDL_Rect * rects)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 
GAPI_UpdateRects(_THIS,int numrects,SDL_Rect * rects)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 */
GAPI_VideoQuit(_THIS)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 
GAPI_Activate(_THIS,BOOL active,BOOL minimized)1216 static void GAPI_Activate(_THIS, BOOL active, BOOL minimized)
1217 {
1218 	//Nothing to do here (as far as I know)
1219 }
1220 
GAPI_RealizePalette(_THIS)1221 static void GAPI_RealizePalette(_THIS)
1222 {
1223 	OutputDebugString(TEXT("GAPI_RealizePalette NOT IMPLEMENTED !\r\n"));
1224 }
1225 
GAPI_PaletteChanged(_THIS,HWND window)1226 static void GAPI_PaletteChanged(_THIS, HWND window)
1227 {
1228 	OutputDebugString(TEXT("GAPI_PaletteChanged NOT IMPLEMENTED !\r\n"));
1229 }
1230 
GAPI_WinPAINT(_THIS,HDC hdc)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 
GAPI_SetColors(_THIS,int firstcolor,int ncolors,SDL_Color * colors)1283 int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
1284 {
1285 	GAPI_CreatePalette(ncolors, colors);
1286 	return 1;
1287 }
1288