# HG changeset patch # User Ryan C. Gordon # Date 1137660180 0 # Node ID 86d0d01290eaef05065c43f01579a0f3910dbbb7 # Parent a4d515d0fc3a06326a21fd6ea1d60a297088ff0b Updated Windows CE/PocketPC support...adds GAPI driver, landscape mode, updated project files, VS2005 support, VGA mode, more device support, etc, etc, etc. Fixes Bugzilla #47 and #28. --ryan. diff -r a4d515d0fc3a -r 86d0d01290ea README.WinCE --- a/README.WinCE Thu Jan 19 08:36:41 2006 +0000 +++ b/README.WinCE Thu Jan 19 08:43:00 2006 +0000 @@ -1,5 +1,24 @@ -Project files for embedded Visual C++ 4.0 can be found in VisualCE.zip +Project files for embedded Visual C++ 3.0, 4.0 and +Visual Studio 2005 can be found in VisualCE.zip + +SDL supports GAPI and WinDib output for Windows CE. + +GAPI driver supports: + +- all possible WinCE devices (Pocket PC, Smartphones, HPC) + with different orientations of video memory and resolutions. +- 4, 8 and 16 bpp devices +- special handling of 8bpp on 8bpp devices +- VGA mode, you can even switch between VGA and GAPI in runtime + (between 240x320 and 480x640 for example). On VGA devices you can + use either GAPI or VGA. +- Landscape mode and automatic rotation of buttons and stylus coordinates. + To enable landscape mode make width of video screen bigger than height. + For example: + SDL_SetVideoMode(320,240,16,SDL_FULLSCREEN) +- WM2005 +- SDL_ListModes NOTE: There are several SDL features not available in the WinCE port of SDL. diff -r a4d515d0fc3a -r 86d0d01290ea VisualCE.zip Binary file VisualCE.zip has changed diff -r a4d515d0fc3a -r 86d0d01290ea configure.in --- a/configure.in Thu Jan 19 08:36:41 2006 +0000 +++ b/configure.in Thu Jan 19 08:43:00 2006 +0000 @@ -3140,6 +3140,7 @@ src/video/wincommon/Makefile src/video/windib/Makefile src/video/windx5/Makefile +src/video/gapi/Makefile src/video/x11/Makefile src/video/xbios/Makefile src/video/XFree86/Makefile diff -r a4d515d0fc3a -r 86d0d01290ea src/thread/win32/SDL_systhread.c --- a/src/thread/win32/SDL_systhread.c Thu Jan 19 08:36:41 2006 +0000 +++ b/src/thread/win32/SDL_systhread.c Thu Jan 19 08:43:00 2006 +0000 @@ -30,7 +30,10 @@ #include #include #include + +#ifndef _WIN32_WCE #include +#endif #include "SDL_error.h" #include "SDL_thread.h" @@ -53,9 +56,14 @@ * have to use _beginthreadex if we want the returned handle * to be accessible after the thread exits * threads created with _beginthread auto-close the handle + * Windows CE still use CreateThread. */ +#ifdef _WIN32_WCE + thread->handle = CreateThread(NULL, 0, RunThread, args, 0, &threadid); +#else thread->handle = (SYS_ThreadHandle) _beginthreadex(NULL, 0, RunThread, args, 0, &threadid); +#endif if (thread->handle == NULL) { SDL_SetError("Not enough resources to create thread"); return(-1); diff -r a4d515d0fc3a -r 86d0d01290ea src/thread/win32/win_ce_semaphore.c --- a/src/thread/win32/win_ce_semaphore.c Thu Jan 19 08:36:41 2006 +0000 +++ b/src/thread/win32/win_ce_semaphore.c Thu Jan 19 08:43:00 2006 +0000 @@ -201,9 +201,9 @@ BOOL ok = TRUE; if (hSynch == NULL) return NULL; - if (Flags & 4 == 1 && hSynch->hEvent == NULL) ok = FALSE; - if (Flags & 2 == 1 && hSynch->hMutex == NULL) ok = FALSE; - if (Flags & 1 == 1 && hSynch->hEvent == NULL) ok = FALSE; + if ((Flags & 4) == 1 && (hSynch->hEvent == NULL)) ok = FALSE; + if ((Flags & 2) == 1 && (hSynch->hMutex == NULL)) ok = FALSE; + if ((Flags & 1) == 1 && (hSynch->hEvent == NULL)) ok = FALSE; if (!ok) { CloseSynchHandle (hSynch); diff -r a4d515d0fc3a -r 86d0d01290ea src/video/Makefile.am --- a/src/video/Makefile.am Thu Jan 19 08:36:41 2006 +0000 +++ b/src/video/Makefile.am Thu Jan 19 08:43:00 2006 +0000 @@ -9,7 +9,7 @@ wincommon windib windx5 \ maccommon macdsp macrom riscos quartz \ bwindow ps2gs photon cybergfx epoc picogui \ - ataricommon xbios gem dc qtopia XFree86 wscons \ + ataricommon xbios gem dc qtopia XFree86 wscons gapi \ ipod os2fslib DRIVERS = @VIDEO_DRIVERS@ diff -r a4d515d0fc3a -r 86d0d01290ea src/video/SDL_surface.c --- a/src/video/SDL_surface.c Thu Jan 19 08:36:41 2006 +0000 +++ b/src/video/SDL_surface.c Thu Jan 19 08:43:00 2006 +0000 @@ -39,6 +39,7 @@ #include "SDL_memops.h" #include "SDL_leaks.h" + /* Public routines */ /* * Create an empty RGB surface of the appropriate depth diff -r a4d515d0fc3a -r 86d0d01290ea src/video/SDL_sysvideo.h --- a/src/video/SDL_sysvideo.h Thu Jan 19 08:36:41 2006 +0000 +++ b/src/video/SDL_sysvideo.h Thu Jan 19 08:43:00 2006 +0000 @@ -365,6 +365,9 @@ #ifdef ENABLE_AALIB extern VideoBootStrap AALIB_bootstrap; #endif +#ifdef ENABLE_GAPI +extern VideoBootStrap GAPI_bootstrap; +#endif #ifdef ENABLE_WINDIB extern VideoBootStrap WINDIB_bootstrap; #endif diff -r a4d515d0fc3a -r 86d0d01290ea src/video/SDL_video.c --- a/src/video/SDL_video.c Thu Jan 19 08:36:41 2006 +0000 +++ b/src/video/SDL_video.c Thu Jan 19 08:43:00 2006 +0000 @@ -87,6 +87,9 @@ #ifdef ENABLE_AALIB &AALIB_bootstrap, #endif +#ifdef ENABLE_GAPI + &GAPI_bootstrap, +#endif #ifdef ENABLE_WINDIB &WINDIB_bootstrap, #endif diff -r a4d515d0fc3a -r 86d0d01290ea src/video/gapi/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/gapi/.cvsignore Thu Jan 19 08:43:00 2006 +0000 @@ -0,0 +1,6 @@ +Makefile.in +Makefile +.libs +*.o +*.lo +*.la diff -r a4d515d0fc3a -r 86d0d01290ea src/video/gapi/Makefile.am --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/gapi/Makefile.am Thu Jan 19 08:43:00 2006 +0000 @@ -0,0 +1,10 @@ + +## Makefile.am for SDL using the PocketPC GAPI video driver + +noinst_LTLIBRARIES = libvideo_gapi.la +libvideo_gapi_la_SOURCES = $(GAPI_SRCS) + +# The SDL GAPI driver sources +GAPI_SRCS = \ + SDL_gapivideo.c \ + SDL_gapivideo.h diff -r a4d515d0fc3a -r 86d0d01290ea src/video/gapi/SDL_gapivideo.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/gapi/SDL_gapivideo.c Thu Jan 19 08:43:00 2006 +0000 @@ -0,0 +1,1127 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2004 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* Pocket PC GAPI SDL video driver implementation; +Implemented by Dmitry Yakimov - support@activekitten.com +Inspired by http://arisme.free.fr/ports/SDL.php +*/ + +// TODO: copy surface on window when lost focus +// TODO: test buttons rotation +// TODO: test on be300 and HPC ( check WinDib fullscreen keys catching ) +// TODO: test on smartphones +// TODO: windib on SH3 PPC2000 landscape test +// TODO: optimize 8bpp landscape mode + +#include +#include +#include + +#include "SDL.h" +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "SDL_sysvideo.h" +#include "SDL_pixels_c.h" +#include "SDL_events_c.h" + +#include "SDL_syswm_c.h" +#include "SDL_sysmouse_c.h" +#include "SDL_dibevents_c.h" + +#include "SDL_gapivideo.h" + +#define GAPIVID_DRIVER_NAME "gapi" + +#if defined(DEBUG) || defined (_DEBUG) || defined(NDEBUG) +#define REPORT_VIDEO_INFO 1 +#else +#define REPORT_VIDEO_INFO 0 +#endif + +// for testing with GapiEmu +#define USE_GAPI_EMU 0 + +#if USE_GAPI_EMU && !REPORT_VIDEO_INFO +#pragma message("Warning: Using GapiEmu in release build. I assume you'd like to set USE_GAPI_EMU to zero.") +#endif + +// defined and used in SDL_sysevents.c +extern HINSTANCE aygshell; +extern void SDL_UnregisterApp(); +extern int DIB_AddMode(_THIS, int bpp, int w, int h); + +/* Initialization/Query functions */ +static int GAPI_VideoInit(_THIS, SDL_PixelFormat *vformat); +static SDL_Rect **GAPI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); +static SDL_Surface *GAPI_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); +static int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors); +static void GAPI_VideoQuit(_THIS); + +/* Hardware surface functions */ +static int GAPI_AllocHWSurface(_THIS, SDL_Surface *surface); +static int GAPI_LockHWSurface(_THIS, SDL_Surface *surface); +static void GAPI_UnlockHWSurface(_THIS, SDL_Surface *surface); +static void GAPI_FreeHWSurface(_THIS, SDL_Surface *surface); + +/* Windows message handling functions, will not be processed */ +static void GAPI_RealizePalette(_THIS); +static void GAPI_PaletteChanged(_THIS, HWND window); +static void GAPI_WinPAINT(_THIS, HDC hdc); + +/* etc. */ +static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects); + +static HMODULE g_hGapiLib = 0; +#define LINK(type,name,import) \ + if( g_hGapiLib ) \ + name = (PFN##type)GetProcAddress( g_hGapiLib, _T(import) ); + +static char g_bRawBufferAvailable = 0; + +/* GAPI driver bootstrap functions */ + +/* hi res definitions */ +typedef struct _RawFrameBufferInfo +{ + WORD wFormat; + WORD wBPP; + VOID *pFramePointer; + int cxStride; + int cyStride; + int cxPixels; + int cyPixels; +} RawFrameBufferInfo; + +static struct _RawFrameBufferInfo g_RawFrameBufferInfo = {0}; + +#define GETRAWFRAMEBUFFER 0x00020001 + +#define FORMAT_565 1 +#define FORMAT_555 2 +#define FORMAT_OTHER 3 + +static int GAPI_Available(void) +{ + // try to use VGA display, even on emulator + HDC hdc = GetDC(NULL); + int result = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *)&g_RawFrameBufferInfo); + ReleaseDC(NULL, hdc); + g_bRawBufferAvailable = result > 0; + +#if USE_GAPI_EMU + g_hGapiLib = LoadLibrary(_T("GAPI_Emu.dll")); + if( !g_hGapiLib ) + { + SDL_SetError("Gapi Emu not found!"); + } + return g_hGapiLib != 0; +#endif + + // try to find gx.dll + g_hGapiLib = LoadLibrary(_T("\\Windows\\gx.dll")); + if( !g_hGapiLib ) + { + g_hGapiLib = LoadLibrary(_T("gx.dll")); + if( !g_hGapiLib ) return g_bRawBufferAvailable; + } + + return(1); +} + +static int cmpmodes(const void *va, const void *vb) +{ + SDL_Rect *a = *(SDL_Rect **)va; + SDL_Rect *b = *(SDL_Rect **)vb; + if ( a->w == b->w ) + return b->h - a->h; + else + return b->w - a->w; +} + +static int GAPI_AddMode(_THIS, int bpp, int w, int h) +{ + SDL_Rect *mode; + int i, index; + int next_mode; + + /* Check to see if we already have this mode */ + if ( bpp < 8 ) { /* Not supported */ + return(0); + } + index = ((bpp+7)/8)-1; + for ( i=0; iSDL_nummodes[index]; ++i ) { + mode = gapi->SDL_modelist[index][i]; + if ( (mode->w == w) && (mode->h == h) ) { + return(0); + } + } + + /* Set up the new video mode rectangle */ + mode = (SDL_Rect *)malloc(sizeof *mode); + if ( mode == NULL ) { + SDL_OutOfMemory(); + return(-1); + } + mode->x = 0; + mode->y = 0; + mode->w = w; + mode->h = h; + + /* Allocate the new list of modes, and fill in the new mode */ + next_mode = gapi->SDL_nummodes[index]; + gapi->SDL_modelist[index] = (SDL_Rect **) + realloc(gapi->SDL_modelist[index], (1+next_mode+1)*sizeof(SDL_Rect *)); + if ( gapi->SDL_modelist[index] == NULL ) { + SDL_OutOfMemory(); + gapi->SDL_nummodes[index] = 0; + free(mode); + return(-1); + } + gapi->SDL_modelist[index][next_mode] = mode; + gapi->SDL_modelist[index][next_mode+1] = NULL; + gapi->SDL_nummodes[index]++; + + return(0); +} + +static void GAPI_DeleteDevice(SDL_VideoDevice *device) +{ + if( g_hGapiLib ) + { + FreeLibrary(g_hGapiLib); + g_hGapiLib = 0; + } + free(device->hidden); + free(device); +} + +static SDL_VideoDevice *GAPI_CreateDevice(int devindex) +{ + SDL_VideoDevice *device; + + if( !g_hGapiLib && !g_bRawBufferAvailable) + { + if( !GAPI_Available() ) + { + SDL_SetError("GAPI dll is not found and VGA mode is not available!"); + return 0; + } + } + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice)); + if ( device ) { + memset(device, 0, (sizeof *device)); + device->hidden = (struct SDL_PrivateVideoData *) + malloc((sizeof *device->hidden)); + } + if ( (device == NULL) || (device->hidden == NULL) ) { + SDL_OutOfMemory(); + if ( device ) { + free(device); + } + return(0); + } + memset(device->hidden, 0, (sizeof *device->hidden)); + + /* Set the function pointers */ + device->VideoInit = GAPI_VideoInit; + device->ListModes = GAPI_ListModes; + device->SetVideoMode = GAPI_SetVideoMode; + device->UpdateMouse = WIN_UpdateMouse; + device->CreateYUVOverlay = NULL; + device->SetColors = GAPI_SetColors; + device->UpdateRects = GAPI_UpdateRects; + device->VideoQuit = GAPI_VideoQuit; + device->AllocHWSurface = GAPI_AllocHWSurface; + device->CheckHWBlit = NULL; + device->FillHWRect = NULL; + device->SetHWColorKey = NULL; + device->SetHWAlpha = NULL; + device->LockHWSurface = GAPI_LockHWSurface; + device->UnlockHWSurface = GAPI_UnlockHWSurface; + device->FlipHWSurface = NULL; + device->FreeHWSurface = GAPI_FreeHWSurface; + device->SetCaption = WIN_SetWMCaption; + device->SetIcon = WIN_SetWMIcon; + device->IconifyWindow = WIN_IconifyWindow; + device->GrabInput = WIN_GrabInput; + device->GetWMInfo = WIN_GetWMInfo; + device->FreeWMCursor = WIN_FreeWMCursor; + device->CreateWMCursor = WIN_CreateWMCursor; + device->ShowWMCursor = WIN_ShowWMCursor; + device->WarpWMCursor = WIN_WarpWMCursor; + device->CheckMouseMode = WIN_CheckMouseMode; + device->InitOSKeymap = DIB_InitOSKeymap; + device->PumpEvents = DIB_PumpEvents; + + /* Set up the windows message handling functions */ + WIN_RealizePalette = GAPI_RealizePalette; + WIN_PaletteChanged = GAPI_PaletteChanged; + WIN_WinPAINT = GAPI_WinPAINT; + HandleMessage = DIB_HandleMessage; + + device->free = GAPI_DeleteDevice; + + /* Load gapi library */ +#define gx device->hidden->gxFunc + + LINK( GXOpenDisplay, gx.GXOpenDisplay, "?GXOpenDisplay@@YAHPAUHWND__@@K@Z" ) + LINK( GXCloseDisplay, gx.GXCloseDisplay, "?GXCloseDisplay@@YAHXZ" ) + LINK( GXBeginDraw, gx.GXBeginDraw, "?GXBeginDraw@@YAPAXXZ" ) + LINK( GXEndDraw, gx.GXEndDraw, "?GXEndDraw@@YAHXZ" ) + LINK( GXOpenInput, gx.GXOpenInput, "?GXOpenInput@@YAHXZ" ) + LINK( GXCloseInput, gx.GXCloseInput, "?GXCloseInput@@YAHXZ" ) + LINK( GXGetDisplayProperties, gx.GXGetDisplayProperties,"?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ" ) + LINK( GXGetDefaultKeys, gx.GXGetDefaultKeys, "?GXGetDefaultKeys@@YA?AUGXKeyList@@H@Z" ) + LINK( GXSuspend, gx.GXSuspend, "?GXSuspend@@YAHXZ" ) + LINK( GXResume, gx.GXResume, "?GXResume@@YAHXZ" ) + LINK( GXSetViewport, gx.GXSetViewport, "?GXSetViewport@@YAHKKKK@Z" ) + LINK( GXIsDisplayDRAMBuffer, gx.GXIsDisplayDRAMBuffer, "?GXIsDisplayDRAMBuffer@@YAHXZ" ) + + /* wrong gapi.dll */ + if( !gx.GXOpenDisplay ) + { + if( g_hGapiLib ) + { + FreeLibrary(g_hGapiLib); + g_hGapiLib = 0; + } + } + + if( !gx.GXOpenDisplay && !g_bRawBufferAvailable) + { + SDL_SetError("Error: damaged or unknown gapi.dll!\n"); + GAPI_DeleteDevice(device); + return 0; + } + + return device; +} + +VideoBootStrap GAPI_bootstrap = { + GAPIVID_DRIVER_NAME, "WinCE GAPI video driver", + GAPI_Available, GAPI_CreateDevice +}; + +static void FillStructs(_THIS, BOOL useVga) +{ +#ifdef _ARM_ + WCHAR oemstr[100]; +#endif + /* fill a device properties */ + + if( !useVga ) + { + this->hidden->gxProperties = this->hidden->gxFunc.GXGetDisplayProperties(); + this->hidden->needUpdate = 1; + this->hidden->hiresFix = 0; + this->hidden->useVga = 0; +#ifdef _ARM_ + /* check some devices and extract addition info */ + SystemParametersInfo( SPI_GETOEMINFO, sizeof( oemstr ), oemstr, 0 ); + + // buggy iPaq38xx + if ((oemstr[12] == 'H') && (oemstr[13] == '3') && (oemstr[14] == '8') && (this->hidden->gxProperties.cbxPitch > 0)) + { + this->hidden->videoMem = (PIXEL*)0xac0755a0; + this->hidden->gxProperties.cbxPitch = -640; + this->hidden->gxProperties.cbyPitch = 2; + this->hidden->needUpdate = 0; + } +#endif + } else + { + this->hidden->needUpdate = 0; + this->hidden->hiresFix = 0; + this->hidden->gxProperties.cBPP = g_RawFrameBufferInfo.wBPP; + this->hidden->gxProperties.cbxPitch = g_RawFrameBufferInfo.cxStride; + this->hidden->gxProperties.cbyPitch = g_RawFrameBufferInfo.cyStride; + this->hidden->gxProperties.cxWidth = g_RawFrameBufferInfo.cxPixels; + this->hidden->gxProperties.cyHeight = g_RawFrameBufferInfo.cyPixels; + this->hidden->videoMem = g_RawFrameBufferInfo.pFramePointer; + this->hidden->useVga = 1; + + switch( g_RawFrameBufferInfo.wFormat ) + { + case FORMAT_565: + this->hidden->gxProperties.ffFormat = kfDirect565; + break; + case FORMAT_555: + this->hidden->gxProperties.ffFormat = kfDirect555; + break; + default: + /* unknown pixel format, try define by BPP! */ + switch( g_RawFrameBufferInfo.wBPP ) + { + case 4: + case 8: + this->hidden->gxProperties.ffFormat = kfDirect; + case 16: + this->hidden->gxProperties.ffFormat = kfDirect565; + default: + this->hidden->gxProperties.ffFormat = kfDirect; + break; + } + } + } + + if( this->hidden->gxProperties.cBPP != 16 ) + { + this->hidden->gapiOrientation = SDL_ORIENTATION_UP; + } else + if( (this->hidden->gxProperties.cbxPitch > 0) && (this->hidden->gxProperties.cbyPitch > 0 )) + { + this->hidden->gapiOrientation = SDL_ORIENTATION_UP; + } else + if( (this->hidden->gxProperties.cbxPitch > 0) && (this->hidden->gxProperties.cbyPitch < 0 )) + { + this->hidden->gapiOrientation = SDL_ORIENTATION_RIGHT; // ipaq 3660 + } else + if( (this->hidden->gxProperties.cbxPitch < 0) && (this->hidden->gxProperties.cbyPitch > 0 )) + { + this->hidden->gapiOrientation = SDL_ORIENTATION_LEFT; // ipaq 3800 + } +} + +static void GAPI_CreatePalette(int ncolors, SDL_Color *colors) +{ + // Setup a custom color palette + BYTE buffer[ sizeof(LOGPALETTE) + 255 * sizeof(PALETTEENTRY) ]; + int i; + LOGPALETTE* pLogical = (LOGPALETTE*)buffer; + PALETTEENTRY* entries = pLogical->palPalEntry; + HPALETTE hPalette; + HDC hdc; + + for (i = 0; i < ncolors; ++i) + { + // Find intensity by replicating the bit patterns over a byte + entries[i].peRed = colors[i].r; + entries[i].peGreen = colors[i].g; + entries[i].peBlue = colors[i].b; + entries[i].peFlags = 0; + } + + // Create the GDI palette object + pLogical->palVersion = 0x0300; + pLogical->palNumEntries = ncolors; + + hPalette = CreatePalette( pLogical ); + ASSERT(hPalette); + + + // Realize the palette + hdc = GetDC(0); + + SelectPalette( hdc, hPalette, FALSE ); + RealizePalette( hdc ); + + ReleaseDC( 0, hdc ); + DeleteObject( hPalette ); +} + +int GAPI_VideoInit(_THIS, SDL_PixelFormat *vformat) +{ + int i,bpp; + + /* Create the window */ + if ( DIB_CreateWindow(this) < 0 ) { + return(-1); + } + + if( g_hGapiLib ) + { + FillStructs(this, 0); + + // SDL does not supports 2/4bpp mode, so use 16 bpp + bpp = gapi->gxProperties.cBPP < 8 ? 16 : gapi->gxProperties.cBPP; + + /* set up normal and landscape mode */ + GAPI_AddMode(this, bpp, gapi->gxProperties.cyHeight, gapi->gxProperties.cxWidth); + GAPI_AddMode(this, bpp, gapi->gxProperties.cxWidth, gapi->gxProperties.cyHeight); + } + + /* add hi-res mode */ + if( g_bRawBufferAvailable && + !((gapi->gxProperties.cxWidth == (unsigned)g_RawFrameBufferInfo.cxPixels) && (gapi->gxProperties.cyHeight == (unsigned)g_RawFrameBufferInfo.cyPixels))) + { + FillStructs(this, 1); + + // SDL does not supports 2/4bpp mode, so use 16 bpp + bpp = gapi->gxProperties.cBPP < 8 ? 16 : gapi->gxProperties.cBPP; + + /* set up normal and landscape mode */ + GAPI_AddMode(this, bpp, gapi->gxProperties.cyHeight, gapi->gxProperties.cxWidth); + GAPI_AddMode(this, bpp, gapi->gxProperties.cxWidth, gapi->gxProperties.cyHeight); + } + + /* Sort the mode lists */ + for ( i=0; iSDL_nummodes[i] > 0 ) { + qsort(gapi->SDL_modelist[i], gapi->SDL_nummodes[i], sizeof *gapi->SDL_modelist[i], cmpmodes); + } + } + + vformat->BitsPerPixel = this->hidden->gxProperties.cBPP < 8 ? 16 : (unsigned char)this->hidden->gxProperties.cBPP; + + // Get color mask + if (this->hidden->gxProperties.ffFormat & kfDirect565) { + vformat->BitsPerPixel = 16; + vformat->Rmask = 0x0000f800; + vformat->Gmask = 0x000007e0; + vformat->Bmask = 0x0000001f; + this->hidden->videoMode = GAPI_DIRECT_565; + } + else + if (this->hidden->gxProperties.ffFormat & kfDirect555) { + vformat->BitsPerPixel = 16; + vformat->Rmask = 0x00007c00; + vformat->Gmask = 0x000003e0; + vformat->Bmask = 0x0000001f; + this->hidden->videoMode = GAPI_DIRECT_555; + } + else + if ((this->hidden->gxProperties.ffFormat & kfDirect) && (this->hidden->gxProperties.cBPP < 8)) { + // We'll perform the conversion + vformat->BitsPerPixel = 16; + vformat->Rmask = 0x0000f800; // 16 bit 565 + vformat->Gmask = 0x000007e0; + vformat->Bmask = 0x0000001f; + if (this->hidden->gxProperties.ffFormat & kfDirectInverted) + this->hidden->invert = (1 << this->hidden->gxProperties.cBPP) - 1; + this->hidden->colorscale = this->hidden->gxProperties.cBPP < 8 ? 8 - this->hidden->gxProperties.cBPP : 0; + this->hidden->videoMode = GAPI_MONO; + } + else + if (this->hidden->gxProperties.ffFormat & kfPalette) { + this->hidden->videoMode = GAPI_PALETTE; + } + + /* We're done! */ + return(0); +} + +SDL_Rect **GAPI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) +{ + return(this->hidden->SDL_modelist[((format->BitsPerPixel+7)/8)-1]); +// return (SDL_Rect **) -1; +} + +SDL_Surface *GAPI_SetVideoMode(_THIS, SDL_Surface *current, + int width, int height, int bpp, Uint32 flags) +{ + SDL_Surface *video; + Uint32 Rmask, Gmask, Bmask; + DWORD style; + SDL_Rect allScreen; + + if( bpp < 4 ) + { + SDL_SetError("1 bpp and 2 bpp modes is not implemented yet!"); + return 0; + } + + /* Recalculate bitmasks if necessary */ + if (bpp == current->format->BitsPerPixel) { + video = current; + } + else { + switch(bpp) { + case 8: + Rmask = 0; + Gmask = 0; + Bmask = 0; + break; + case 15: + case 16: + /* Default is 565 unless the display is specifically 555 */ + if (this->hidden->gxProperties.ffFormat & kfDirect555) { + Rmask = 0x00007c00; + Gmask = 0x000003e0; + Bmask = 0x0000001f; + } + else { + Rmask = 0x0000f800; + Gmask = 0x000007e0; + Bmask = 0x0000001f; + } + break; + case 24: + case 32: + Rmask = 0x00ff0000; + Gmask = 0x0000ff00; + Bmask = 0x000000ff; + break; + default: + SDL_SetError("Unsupported Bits Per Pixel format requested"); + return NULL; + } + video = SDL_CreateRGBSurface(SDL_SWSURFACE, + 0, 0, bpp, Rmask, Gmask, Bmask, 0); + if ( video == NULL ) { + SDL_OutOfMemory(); + return(NULL); + } + } + + gapi->userOrientation = SDL_ORIENTATION_UP; + video->flags = SDL_FULLSCREEN; /* Clear flags, GAPI supports fullscreen only */ + + /* GAPI or VGA? */ + if( g_hGapiLib ) + { + FillStructs(this, 0); + if( (((unsigned)width != gapi->gxProperties.cxWidth) || ((unsigned)height != gapi->gxProperties.cyHeight)) + && (((unsigned)width != gapi->gxProperties.cyHeight) || ((unsigned)height != gapi->gxProperties.cxWidth))) + FillStructs(this, 1); // gapi is found but we use VGA resolution + } else + FillStructs(this, 1); + + if ( !this->hidden->needUpdate && !this->hidden->videoMem) { + SDL_SetError("Couldn't get address of video memory, may be unsupported device or bug"); + return(NULL); + } + + /* detect landscape mode */ + if( (width > height) && (GetSystemMetrics(SM_CXSCREEN) < GetSystemMetrics(SM_CYSCREEN))) + gapi->userOrientation = SDL_ORIENTATION_RIGHT; + + /* shall we apply hires fix? for example when we do not use hires resource */ + gapi->hiresFix = 0; + if( gapi->userOrientation == SDL_ORIENTATION_RIGHT ) + { + if( (width > GetSystemMetrics(SM_CYSCREEN)) || (height > GetSystemMetrics(SM_CXSCREEN))) + gapi->hiresFix = 1; + } else + if( (width > GetSystemMetrics(SM_CXSCREEN)) || (height > GetSystemMetrics(SM_CYSCREEN))) + gapi->hiresFix = 1; + + switch( gapi->userOrientation ) + { + case SDL_ORIENTATION_UP: + gapi->startOffset = 0; + gapi->dstLineStep = gapi->gxProperties.cbyPitch; + gapi->dstPixelStep = gapi->gxProperties.cbxPitch; + break; + case SDL_ORIENTATION_RIGHT: + switch( gapi->gapiOrientation ) + { + case SDL_ORIENTATION_UP: + case SDL_ORIENTATION_RIGHT: + case SDL_ORIENTATION_LEFT: + if( (this->hidden->videoMode == GAPI_MONO) ) + gapi->startOffset = -gapi->gxProperties.cbxPitch + 1; // monochrome mode + else + gapi->startOffset = gapi->gxProperties.cbyPitch * (gapi->gxProperties.cyHeight - 1); + + gapi->dstLineStep = gapi->gxProperties.cbxPitch; + gapi->dstPixelStep = -gapi->gxProperties.cbyPitch; + break; + } + } + + video->w = this->hidden->w = width; + video->h = this->hidden->h = height; + video->pitch = SDL_CalculatePitch(video); + + /* Small fix for WinCE/Win32 - when activating window + SDL_VideoSurface is equal to zero, so activating code + is not called properly for fullscreen windows because + macros WINDIB_FULLSCREEN uses SDL_VideoSurface + */ + SDL_VideoSurface = video; + + /* GAPI is always fullscreen, title bar is useless */ + style = 0; + + if (!SDL_windowid) + SetWindowLong(SDL_Window, GWL_STYLE, style); + + /* Allocate bitmap */ + if(gapiBuffer) + { + free(gapiBuffer); + gapiBuffer = NULL; + } + gapiBuffer = malloc(video->h * video->pitch); + video->pixels = gapiBuffer; + + if ( ! this->hidden->buffer ) { + SDL_SetError("Couldn't allocate buffer for requested mode"); + return(NULL); + } + + memset(gapiBuffer, 255, video->h * video->pitch); + MoveWindow(SDL_Window, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), FALSE); + ShowWindow(SDL_Window, SW_SHOW); + SetForegroundWindow(SDL_Window); + +#if REPORT_VIDEO_INFO + printf("Video properties:\n"); + printf("display bpp: %d\n", gapi->gxProperties.cBPP); + printf("display width: %d\n", gapi->gxProperties.cxWidth); + printf("display height: %d\n", gapi->gxProperties.cyHeight); + printf("x pitch: %d\n", gapi->gxProperties.cbxPitch); + printf("y pitch: %d\n", gapi->gxProperties.cbyPitch); + printf("gapi flags: 0x%x\n", gapi->gxProperties.ffFormat); + printf("video memory: 0x%x\n", gapi->videoMem); + printf("need update: %d\n", gapi->needUpdate); + printf("hi-res fix: %d\n", gapi->hiresFix); + printf("VGA is available on the device: %d\n", g_bRawBufferAvailable); + printf("use VGA resolution: %d\n", gapi->useVga); + printf("video surface bpp: %d\n", video->format->BitsPerPixel); + printf("video surface width: %d\n", video->w); + printf("video surface height: %d\n", video->h); +#endif + + /* Open GAPI display */ + if( !gapi->useVga ) + if( !gapi->gxFunc.GXOpenDisplay(SDL_Window, GX_FULLSCREEN) ) + { + SDL_SetError("Couldn't initialize GAPI"); + return(NULL); + } + + /* Blank screen */ + allScreen.x = allScreen.y = 0; + allScreen.w = video->w - 1; + allScreen.h = video->h - 1; + GAPI_UpdateRects(this, 1, &allScreen); + + /* We're done */ + return(video); +} + +/* We don't actually allow hardware surfaces other than the main one */ +static int GAPI_AllocHWSurface(_THIS, SDL_Surface *surface) +{ + return(-1); +} +static void GAPI_FreeHWSurface(_THIS, SDL_Surface *surface) +{ + return; +} + +/* We need to wait for vertical retrace on page flipped displays */ +static int GAPI_LockHWSurface(_THIS, SDL_Surface *surface) +{ + return(0); +} + +static void GAPI_UnlockHWSurface(_THIS, SDL_Surface *surface) +{ + return; +} + +static int updateLine8to8(_THIS, unsigned char *srcPointer, unsigned char *destPointer, int width, int height, int lines) +{ + if( gapi->dstPixelStep == 1) /* optimized blitting on most devices */ + { + memcpy(destPointer, srcPointer, width); + return 1; + } else + { + // TODO: read 4 pixels, write DWORD + int step = gapi->dstPixelStep; + while(width--) + { + *destPointer = *srcPointer++; + destPointer += step; + } + } + return 1; +} + +/* Video memory is very slow so lets optimize as much as possible */ +static int updateLine16to16(_THIS, PIXEL *srcPointer, PIXEL *destPointer, int width, int height, int lines) +{ + PIXEL *line1, *line2; + int step = gapi->dstPixelStep / 2; + + if( step == 1 ) /* optimized blitting on most devices */ + { + memcpy(destPointer, srcPointer, width * sizeof(PIXEL)); + return 1; + } + else + { + if( (gapi->gapiOrientation != SDL_ORIENTATION_UP) && + (gapi->userOrientation == SDL_ORIENTATION_UP )) // iPaq 3660/3800 and user orientation up + { + // to prevent data misalignment copy only one line + if( ((((unsigned)destPointer & 3) != 0) && (gapi->gapiOrientation == SDL_ORIENTATION_LEFT)) + || ((((unsigned)destPointer & 3) == 0) && (gapi->gapiOrientation != SDL_ORIENTATION_LEFT)) + || (lines == 1) ) + { + while(width--) + { + *destPointer = *srcPointer++; + destPointer += step; + } + return 1; + } + + /* read two lines at the same time, write DWORD */ + line1 = srcPointer; + line2 = srcPointer + SDL_VideoSurface->pitch / 2; + + if( gapi->gapiOrientation == SDL_ORIENTATION_LEFT ) + while(width--) // iPaq 3800 + { + *(DWORD*)destPointer =(*line2++ << 16) | *line1++; + destPointer += step; + } + else + { + destPointer += gapi->gxProperties.cbyPitch / 2; + while(width--) // iPaq 3660 + { + *(DWORD*)destPointer =(*line1++ << 16) | *line2++; + destPointer += step; + } + } + return 2; + } else + { + // iPaq 3800 and user orientation landscape + if( gapi->gapiOrientation == SDL_ORIENTATION_LEFT ) + { + int w1; + + // to prevent data misalignment copy only one pixel + if( (((unsigned)destPointer & 3) == 0) && (width > 0)) + { + *destPointer-- = *srcPointer++; + width--; + } + + destPointer--; + + w1 = width / 2; + + while(w1--) + { + DWORD p = *(DWORD*)srcPointer; + *((DWORD*)destPointer) = (p << 16) | (p >> 16); + destPointer -= 2; + srcPointer += 2; + } + + if( width & 1 ) // copy the last pixel + { + destPointer++; + *destPointer = *srcPointer; + } + + return 1; + } + + // modern iPaqs and user orientation landscape + // read two pixels, write DWORD + + line1 = srcPointer; + line2 = srcPointer + SDL_VideoSurface->pitch / 2; + + if( (((unsigned)destPointer & 3) != 0) || (lines == 1) ) + { + while(width--) + { + *destPointer = *srcPointer++; + destPointer += step; + } + return 1; + } + + while(width--) + { + *(DWORD*)destPointer =(*line2++ << 16) | *line1++; + destPointer -= gapi->gxProperties.cbyPitch / 2; + } + return 2; + } + } +} + +// Color component masks for 565 +#define REDMASK (31<<11) +#define GREENMASK (63<<5) +#define BLUEMASK (31) + + +static int updateLine16to4(_THIS, PIXEL *srcPointer, unsigned char *destPointer, int width, int height, int lines, int yNibble, int xNibble) +{ + PIXEL *line1, *line2; + int step = gapi->dstPixelStep; + + if( gapi->userOrientation == SDL_ORIENTATION_UP ) + { + if( yNibble ) // copy bottom half of a line + { + while(width--) + { + PIXEL c1 = *srcPointer++; + c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK); + *destPointer = (*destPointer & 0x0F) | ((~(c1 >> 3) << 4)); + destPointer += step; + } + return 1; + } + + // either 1 pixel picture or tail, anyway this is the last line + if( lines == 1 ) + { + while(width--) + { + PIXEL c1 = *srcPointer++; + c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK); + *destPointer = (*destPointer & 0xF0) | ((~(c1 >> 3) & 0xF)); + destPointer += step; + } + return 1; + } + + line1 = srcPointer; + line2 = srcPointer + SDL_VideoSurface->pitch / 2; + + while(width--) + { + PIXEL c1 = *line1++; + PIXEL c2 = *line2++; + c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK); + c2 = ((c2 & REDMASK) >> 11) + ((c2 & GREENMASK) >> 5) + (c2 & BLUEMASK); + *destPointer = ~((c1 >> 3) + ((c2 >> 3) << 4)); + destPointer += step; + } + return 2; + } else + { + int w1; + w1 = width / 2; + + if( xNibble ) + { + // copy one pixel + PIXEL c1 = *srcPointer++; + c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK); + *destPointer = (*destPointer & 0xF0) | ((~(c1 >> 3) & 0xF)); + destPointer++; + } + + while(w1--) + { + PIXEL c1 = *srcPointer; + PIXEL c2 = *(srcPointer + 1); + c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK); + c2 = ((c2 & REDMASK) >> 11) + ((c2 & GREENMASK) >> 5) + (c2 & BLUEMASK); + *destPointer++ = ~((c2 >> 3) + ((c1 >> 3) << 4)); + srcPointer += 2; + } + + // copy tail + if( (width & 1) && !xNibble ) + { + PIXEL c1 = *srcPointer; + c1 = ((c1 & REDMASK) >> 11) + ((c1 & GREENMASK) >> 5) + (c1 & BLUEMASK); + *destPointer = (*destPointer & 0x0F) | ((~(c1 >> 3) << 4)); + } + + return 1; + } +} + +static void GAPI_UpdateRectsMono(_THIS, int numrects, SDL_Rect *rects) +{ + int i, height; + int linesProcessed; + int xNibble, yNibble; + + for (i=0; iuserOrientation == SDL_ORIENTATION_UP ) + destPointer = (unsigned char*) gapi->videoMem + gapi->startOffset - rects[i].y * gapi->gxProperties.cBPP / 8 + rects[i].x * gapi->dstPixelStep; + else + destPointer = (unsigned char*) gapi->videoMem + gapi->startOffset + rects[i].x * gapi->gxProperties.cBPP / 8 + rects[i].y * gapi->dstLineStep; + + srcPointer = ((unsigned char*) SDL_VideoSurface->pixels) + rects[i].y * SDL_VideoSurface->pitch + rects[i].x * 2; + yNibble = rects[i].y & 1; // TODO: only for 4 bpp + xNibble = rects[i].x & 1; + height = rects[i].h; + while (height > 0) + { + switch(gapi->gxProperties.cBPP) + { + case 2: // TODO + case 4: + linesProcessed = updateLine16to4(this, (PIXEL*) srcPointer, destPointer, rects[i].w, rects[i].h, height, yNibble, xNibble); + yNibble = 0; + } + height -= linesProcessed; + if( gapi->userOrientation == SDL_ORIENTATION_UP ) + destPointer--; // always fill 1 byte + else destPointer += gapi->dstLineStep; + srcPointer += SDL_VideoSurface->pitch * linesProcessed; // pitch in bytes + } + } +} + +static void GAPI_UpdateRectsColor(_THIS, int numrects, SDL_Rect *rects) +{ + int i, height; + int bytesPerPixel = (gapi->gxProperties.cBPP + 1) / 8; + int linesProcessed; + for (i=0; ivideoMem + gapi->startOffset + rects[i].y * gapi->dstLineStep + rects[i].x * gapi->dstPixelStep; + unsigned char *srcPointer = ((unsigned char*) SDL_VideoSurface->pixels) + rects[i].y * SDL_VideoSurface->pitch + rects[i].x * bytesPerPixel; + height = rects[i].h; + +// 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); +// fflush(stderr); + linesProcessed = height; + + while (height > 0) { + switch(bytesPerPixel) + { + case 1: + linesProcessed = updateLine8to8(this, srcPointer, (unsigned char *) destPointer, rects[i].w, rects[i].h, height); + break; + case 2: +#pragma warning(disable: 4133) + linesProcessed = updateLine16to16(this, (PIXEL*) srcPointer, destPointer, rects[i].w, rects[i].h, height); + break; + } + height -= linesProcessed; + destPointer += gapi->dstLineStep * linesProcessed; + srcPointer += SDL_VideoSurface->pitch * linesProcessed; // pitch in bytes + } +// fprintf(stderr, "End of rect\n"); +// fflush(stderr); + } +} + + +static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects) +{ + if( gapi->needUpdate ) + gapi->videoMem = gapi->gxFunc.GXBeginDraw(); + + if( gapi->gxProperties.cBPP < 8 ) + GAPI_UpdateRectsMono(this, numrects, rects); + else + GAPI_UpdateRectsColor(this, numrects, rects); + + if( gapi->needUpdate ) + gapi->gxFunc.GXEndDraw(); +} + +static void FlushMessageQueue() +{ + MSG msg; + while ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) { + if ( msg.message == WM_QUIT ) break; + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } +} + + +/* Note: If we are terminated, this could be called in the middle of + another SDL video routine -- notably UpdateRects. +*/ +void GAPI_VideoQuit(_THIS) +{ + int i, j; + /* Destroy the window and everything associated with it */ + if ( SDL_Window ) + { + if ((g_hGapiLib != 0) && this && this->hidden && this->hidden->gxFunc.GXCloseDisplay && !this->hidden->useVga) + this->hidden->gxFunc.GXCloseDisplay(); + + if (this->screen->pixels != NULL) + { + free(this->screen->pixels); + this->screen->pixels = NULL; + } + if ( screen_icn ) { + DestroyIcon(screen_icn); + screen_icn = NULL; + } + + DIB_DestroyWindow(this); + SDL_UnregisterApp(); + FlushMessageQueue(); + + SDL_Window = NULL; +#if defined(_WIN32_WCE) + +// Unload wince aygshell library to prevent leak + if( aygshell ) + { + FreeLibrary(aygshell); + aygshell = NULL; + } +#endif + + /* Free video mode lists */ + for ( i=0; iSDL_modelist[i] != NULL ) { + for ( j=0; gapi->SDL_modelist[i][j]; ++j ) + free(gapi->SDL_modelist[i][j]); + free(gapi->SDL_modelist[i]); + gapi->SDL_modelist[i] = NULL; + } + } + + } + +} + +static void GAPI_RealizePalette(_THIS) +{ + OutputDebugString(TEXT("GAPI_RealizePalette NOT IMPLEMENTED !\r\n")); +} + +static void GAPI_PaletteChanged(_THIS, HWND window) +{ + OutputDebugString(TEXT("GAPI_PaletteChanged NOT IMPLEMENTED !\r\n")); +} + +/* Exported for the windows message loop only */ +static void GAPI_WinPAINT(_THIS, HDC hdc) +{ + OutputDebugString(TEXT("GAPI_WinPAINT NOT IMPLEMENTED !\r\n")); +} + +int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) +{ + GAPI_CreatePalette(ncolors, colors); + return 1; +} \ No newline at end of file diff -r a4d515d0fc3a -r 86d0d01290ea src/video/gapi/SDL_gapivideo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/video/gapi/SDL_gapivideo.h Thu Jan 19 08:43:00 2006 +0000 @@ -0,0 +1,164 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2004 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +#ifndef _SDL_gapivideo_h +#define _SDL_gapivideo_h + +#include "SDL_mouse.h" +#include "SDL_sysvideo.h" +#include "SDL_mutex.h" + +/* From gx.h, since it's not really C compliant */ + +struct GXDisplayProperties { + DWORD cxWidth; + DWORD cyHeight; // notice lack of 'th' in the word height. + long cbxPitch; // number of bytes to move right one x pixel - can be negative. + long cbyPitch; // number of bytes to move down one y pixel - can be negative. + long cBPP; // # of bits in each pixel + DWORD ffFormat; // format flags. +}; + +struct GXKeyList { + short vkUp; // key for up + POINT ptUp; // x,y position of key/button. Not on screen but in screen coordinates. + short vkDown; + POINT ptDown; + short vkLeft; + POINT ptLeft; + short vkRight; + POINT ptRight; + short vkA; + POINT ptA; + short vkB; + POINT ptB; + short vkC; + POINT ptC; + short vkStart; + POINT ptStart; +}; + +typedef int (*PFNGXOpenDisplay)(HWND hWnd, DWORD dwFlags); +typedef int (*PFNGXCloseDisplay)(); +typedef void* (*PFNGXBeginDraw)(); +typedef int (*PFNGXEndDraw)(); +typedef int (*PFNGXOpenInput)(); +typedef int (*PFNGXCloseInput)(); +typedef struct GXDisplayProperties (*PFNGXGetDisplayProperties)(); +typedef struct GXKeyList (*PFNGXGetDefaultKeys)(int iOptions); +typedef int (*PFNGXSuspend)(); +typedef int (*PFNGXResume)(); +typedef int (*PFNGXSetViewport)( DWORD dwTop, DWORD dwHeight, DWORD dwReserved1, DWORD dwReserved2 ); +typedef BOOL (*PFNGXIsDisplayDRAMBuffer)(); + +struct GapiFunc +{ + PFNGXOpenDisplay GXOpenDisplay; + PFNGXCloseDisplay GXCloseDisplay; + PFNGXBeginDraw GXBeginDraw; + PFNGXEndDraw GXEndDraw; + PFNGXOpenInput GXOpenInput; + PFNGXCloseInput GXCloseInput; + PFNGXGetDisplayProperties GXGetDisplayProperties; + PFNGXGetDefaultKeys GXGetDefaultKeys; + PFNGXSuspend GXSuspend; + PFNGXResume GXResume; + PFNGXSetViewport GXSetViewport; + PFNGXIsDisplayDRAMBuffer GXIsDisplayDRAMBuffer; +}; + +#define kfLandscape 0x8 // Screen is rotated 270 degrees +#define kfPalette 0x10 // Pixel values are indexes into a palette +#define kfDirect 0x20 // Pixel values contain actual level information +#define kfDirect555 0x40 // 5 bits each for red, green and blue values in a pixel. +#define kfDirect565 0x80 // 5 red bits, 6 green bits and 5 blue bits per pixel +#define kfDirect888 0x100 // 8 bits each for red, green and blue values in a pixel. +#define kfDirect444 0x200 // 4 red, 4 green, 4 blue +#define kfDirectInverted 0x400 + +#define GX_FULLSCREEN 0x01 // for OpenDisplay() +#define GX_NORMALKEYS 0x02 +#define GX_LANDSCAPEKEYS 0x03 + +typedef enum +{ + SDL_ORIENTATION_UP, + SDL_ORIENTATION_DOWN, + SDL_ORIENTATION_LEFT, + SDL_ORIENTATION_RIGHT +} SDL_ScreenOrientation; + +/* GAPI video mode */ +typedef enum { + GAPI_NONE = 0, + GAPI_DIRECT_565, + GAPI_DIRECT_555, + GAPI_MONO, + GAPI_PALETTE +} GAPIVideoMode; + +/* Hidden "this" pointer for the video functions */ +#define _THIS SDL_VideoDevice *this + +typedef unsigned short PIXEL; + +/* Private display data + begin with DIB private structure to allow DIB events code sharing +*/ +struct SDL_PrivateVideoData { + HBITMAP screen_bmp; + HPALETTE screen_pal; + +#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */ + int SDL_nummodes[NUM_MODELISTS]; + SDL_Rect **SDL_modelist[NUM_MODELISTS]; + enum SDL_ScreenOrientation userOrientation; + int invert; + char hiresFix; // using hires mode without defining hires resource +// -------------- + int w, h; + enum SDL_ScreenOrientation gapiOrientation; + + void *buffer; // may be 8, 16, 24, 32 bpp + PIXEL *videoMem; + BOOL needUpdate; + struct GXKeyList keyList; + struct GapiFunc gxFunc; + struct GXDisplayProperties gxProperties; + enum GAPIVideoMode videoMode; + int colorscale; + int dstLineStep; // in bytes + int dstPixelStep; // in bytes + int startOffset; // in bytes + int useVga; +}; + + +#define gapiBuffer this->hidden->buffer +#define gapi this->hidden + +#endif /* _SDL_gapivideo_h */ diff -r a4d515d0fc3a -r 86d0d01290ea src/video/wincommon/SDL_lowvideo.h --- a/src/video/wincommon/SDL_lowvideo.h Thu Jan 19 08:36:41 2006 +0000 +++ b/src/video/wincommon/SDL_lowvideo.h Thu Jan 19 08:43:00 2006 +0000 @@ -40,7 +40,8 @@ SDL_VideoSurface && \ ((SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) && \ (((SDL_VideoSurface->flags & SDL_OPENGL ) == SDL_OPENGL ) || \ - (strcmp(this->name, "windib") == 0)) \ + ((strcmp(this->name, "windib") == 0) || \ + (strcmp(this->name, "gapi") == 0))) \ ) #define DDRAW_FULLSCREEN() \ ( \ diff -r a4d515d0fc3a -r 86d0d01290ea src/video/wincommon/SDL_sysevents.c --- a/src/video/wincommon/SDL_sysevents.c Thu Jan 19 08:36:41 2006 +0000 +++ b/src/video/wincommon/SDL_sysevents.c Thu Jan 19 08:43:00 2006 +0000 @@ -47,6 +47,7 @@ #endif #ifdef _WIN32_WCE +#include "SDL_gapivideo.h" #define NO_GETKEYBOARDSTATE #define NO_CHANGEDISPLAYSETTINGS #endif @@ -101,6 +102,38 @@ } } +/* for gapi landscape mode */ +static void GapiTransform(SDL_ScreenOrientation rotate, char hires, Sint16 *x, Sint16 *y) { + Sint16 rotatedX; + Sint16 rotatedY; + + if (hires) { + *x = *x * 2; + *y = *y * 2; + } + + switch(rotate) { + case SDL_ORIENTATION_UP: + break; + case SDL_ORIENTATION_RIGHT: + if (!SDL_VideoSurface) + break; + rotatedX = SDL_VideoSurface->w - *y; + rotatedY = *x; + *x = rotatedX; + *y = rotatedY; + break; + case SDL_ORIENTATION_LEFT: + if (!SDL_VideoSurface) + break; + rotatedX = *y; + rotatedY = SDL_VideoSurface->h - *x; + *x = rotatedX; + *y = rotatedY; + break; + } +} + #endif static void SDL_RestoreGameMode(void) @@ -319,6 +352,10 @@ posted = SDL_PrivateMouseMotion(0, 1, x, y); } } else { +#ifdef _WIN32_WCE + if (SDL_VideoSurface) + GapiTransform(this->hidden->userOrientation, this->hidden->hiresFix, &x, &y); +#endif posted = SDL_PrivateMouseMotion(0, 0, x, y); } } @@ -407,6 +444,10 @@ } else { x = (Sint16)LOWORD(lParam); y = (Sint16)HIWORD(lParam); +#ifdef _WIN32_WCE + if (SDL_VideoSurface) + GapiTransform(this->hidden->userOrientation, this->hidden->hiresFix, &x, &y); +#endif } posted = SDL_PrivateMouseButton( state, button, x, y); diff -r a4d515d0fc3a -r 86d0d01290ea src/video/wincommon/SDL_sysmouse.c --- a/src/video/wincommon/SDL_sysmouse.c Thu Jan 19 08:36:41 2006 +0000 +++ b/src/video/wincommon/SDL_sysmouse.c Thu Jan 19 08:43:00 2006 +0000 @@ -251,6 +251,7 @@ /* Check to see if we need to enter or leave mouse relative mode */ void WIN_CheckMouseMode(_THIS) { +#ifndef _WIN32_WCE /* If the mouse is hidden and input is grabbed, we use relative mode */ if ( !(SDL_cursorstate & CURSOR_VISIBLE) && (this->input_grab != SDL_GRAB_OFF) ) { @@ -258,4 +259,7 @@ } else { mouse_relative = 0; } +#else + mouse_relative = 0; +#endif } diff -r a4d515d0fc3a -r 86d0d01290ea src/video/windib/SDL_dibevents.c --- a/src/video/windib/SDL_dibevents.c Thu Jan 19 08:36:41 2006 +0000 +++ b/src/video/windib/SDL_dibevents.c Thu Jan 19 08:43:00 2006 +0000 @@ -59,6 +59,31 @@ and give him a chance to handle some messages. */ static WNDPROC userWindowProc = NULL; + +#ifdef _WIN32_WCE + +WPARAM rotateKey(WPARAM key,SDL_ScreenOrientation direction) +{ + if (direction != SDL_ORIENTATION_LEFT) + return key; + + switch (key) { + case 0x26: /* up */ + return 0x27; + case 0x27: /* right */ + return 0x28; + case 0x28: /* down */ + return 0x25; + case 0x25: /* left */ + return 0x26; + } + + return key; +} + +#endif + + /* The main Win32 event handler */ LONG DIB_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) @@ -70,6 +95,15 @@ case WM_KEYDOWN: { SDL_keysym keysym; +#ifdef _WIN32_WCE + // Drop GAPI artefacts + if (wParam == 0x84 || wParam == 0x5B) + return 0; + + // Rotate key if necessary + if (this->hidden->orientation != SDL_ORIENTATION_UP) + wParam = rotateKey(wParam, this->hidden->orientation); +#endif /* Ignore repeated keys */ if ( lParam&REPEATED_KEYMASK ) { return(0); @@ -127,6 +161,16 @@ case WM_KEYUP: { SDL_keysym keysym; +#ifdef _WIN32_WCE + // Drop GAPI artefacts + if (wParam == 0x84 || wParam == 0x5B) + return 0; + + // Rotate key if necessary + if (this->hidden->orientation != SDL_ORIENTATION_UP) + wParam = rotateKey(wParam, this->hidden->orientation); +#endif + switch (wParam) { case VK_CONTROL: if ( lParam&EXTENDED_KEYMASK ) diff -r a4d515d0fc3a -r 86d0d01290ea src/video/windib/SDL_dibvideo.c --- a/src/video/windib/SDL_dibvideo.c Thu Jan 19 08:36:41 2006 +0000 +++ b/src/video/windib/SDL_dibvideo.c Thu Jan 19 08:43:00 2006 +0000 @@ -768,14 +768,15 @@ ReleaseDC(SDL_Window, hdc); } + int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) { RGBQUAD *pal; int i; -#ifndef _WIN32_WCE +#if (_WIN32_WCE < 400 ) + HDC hdc; +#else HDC hdc, mdc; -#else - HDC hdc; #endif /* Update the display palette */ @@ -805,7 +806,7 @@ } /* Set the DIB palette and update the display */ -#ifndef _WIN32_WCE +#if ( _WIN32_WCE >= 400 ) mdc = CreateCompatibleDC(hdc); SelectObject(mdc, screen_bmp); SetDIBColorTable(mdc, firstcolor, ncolors, pal); @@ -817,6 +818,7 @@ return(1); } + static void DIB_CheckGamma(_THIS) { #ifndef NO_GAMMA_SUPPORT diff -r a4d515d0fc3a -r 86d0d01290ea src/video/windib/SDL_dibvideo.h --- a/src/video/windib/SDL_dibvideo.h Thu Jan 19 08:36:41 2006 +0000 +++ b/src/video/windib/SDL_dibvideo.h Thu Jan 19 08:43:00 2006 +0000 @@ -30,6 +30,15 @@ #include +/* for PDA */ +typedef enum +{ + SDL_ORIENTATION_UP, + SDL_ORIENTATION_DOWN, + SDL_ORIENTATION_LEFT, + SDL_ORIENTATION_RIGHT +} SDL_ScreenOrientation; + /* Private display data */ struct SDL_PrivateVideoData { HBITMAP screen_bmp; @@ -38,6 +47,10 @@ #define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */ int SDL_nummodes[NUM_MODELISTS]; SDL_Rect **SDL_modelist[NUM_MODELISTS]; + + SDL_ScreenOrientation orientation; + int invert; + char hiresFix; // using hires mode without defining hires resource }; /* Old variable names */ #define screen_bmp (this->hidden->screen_bmp)