Commit f2d9ddec authored by Ryan C. Gordon's avatar Ryan C. Gordon

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.

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%401254
parent e691b061
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: NOTE:
There are several SDL features not available in the WinCE port of SDL. There are several SDL features not available in the WinCE port of SDL.
......
No preview for this file type
...@@ -3140,6 +3140,7 @@ src/video/vgl/Makefile ...@@ -3140,6 +3140,7 @@ src/video/vgl/Makefile
src/video/wincommon/Makefile src/video/wincommon/Makefile
src/video/windib/Makefile src/video/windib/Makefile
src/video/windx5/Makefile src/video/windx5/Makefile
src/video/gapi/Makefile
src/video/x11/Makefile src/video/x11/Makefile
src/video/xbios/Makefile src/video/xbios/Makefile
src/video/XFree86/Makefile src/video/XFree86/Makefile
......
...@@ -30,7 +30,10 @@ static char rcsid = ...@@ -30,7 +30,10 @@ static char rcsid =
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <windows.h> #include <windows.h>
#ifndef _WIN32_WCE
#include <process.h> #include <process.h>
#endif
#include "SDL_error.h" #include "SDL_error.h"
#include "SDL_thread.h" #include "SDL_thread.h"
...@@ -53,9 +56,14 @@ int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) ...@@ -53,9 +56,14 @@ int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
* have to use _beginthreadex if we want the returned handle * have to use _beginthreadex if we want the returned handle
* to be accessible after the thread exits * to be accessible after the thread exits
* threads created with _beginthread auto-close the handle * 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, thread->handle = (SYS_ThreadHandle) _beginthreadex(NULL, 0, RunThread,
args, 0, &threadid); args, 0, &threadid);
#endif
if (thread->handle == NULL) { if (thread->handle == NULL) {
SDL_SetError("Not enough resources to create thread"); SDL_SetError("Not enough resources to create thread");
return(-1); return(-1);
......
...@@ -201,9 +201,9 @@ static SYNCHHANDLE CleanUp (SYNCHHANDLE hSynch, DWORD Flags) ...@@ -201,9 +201,9 @@ static SYNCHHANDLE CleanUp (SYNCHHANDLE hSynch, DWORD Flags)
BOOL ok = TRUE; BOOL ok = TRUE;
if (hSynch == NULL) return NULL; if (hSynch == NULL) return NULL;
if (Flags & 4 == 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 & 2) == 1 && (hSynch->hMutex == NULL)) ok = FALSE;
if (Flags & 1 == 1 && hSynch->hEvent == NULL) ok = FALSE; if ((Flags & 1) == 1 && (hSynch->hEvent == NULL)) ok = FALSE;
if (!ok) if (!ok)
{ {
CloseSynchHandle (hSynch); CloseSynchHandle (hSynch);
......
...@@ -9,7 +9,7 @@ DIST_SUBDIRS = dummy x11 dga nanox fbcon directfb vgl svga ggi aalib \ ...@@ -9,7 +9,7 @@ DIST_SUBDIRS = dummy x11 dga nanox fbcon directfb vgl svga ggi aalib \
wincommon windib windx5 \ wincommon windib windx5 \
maccommon macdsp macrom riscos quartz \ maccommon macdsp macrom riscos quartz \
bwindow ps2gs photon cybergfx epoc picogui \ bwindow ps2gs photon cybergfx epoc picogui \
ataricommon xbios gem dc qtopia XFree86 wscons \ ataricommon xbios gem dc qtopia XFree86 wscons gapi \
ipod os2fslib ipod os2fslib
DRIVERS = @VIDEO_DRIVERS@ DRIVERS = @VIDEO_DRIVERS@
......
...@@ -39,6 +39,7 @@ static char rcsid = ...@@ -39,6 +39,7 @@ static char rcsid =
#include "SDL_memops.h" #include "SDL_memops.h"
#include "SDL_leaks.h" #include "SDL_leaks.h"
/* Public routines */ /* Public routines */
/* /*
* Create an empty RGB surface of the appropriate depth * Create an empty RGB surface of the appropriate depth
......
...@@ -365,6 +365,9 @@ extern VideoBootStrap SVGALIB_bootstrap; ...@@ -365,6 +365,9 @@ extern VideoBootStrap SVGALIB_bootstrap;
#ifdef ENABLE_AALIB #ifdef ENABLE_AALIB
extern VideoBootStrap AALIB_bootstrap; extern VideoBootStrap AALIB_bootstrap;
#endif #endif
#ifdef ENABLE_GAPI
extern VideoBootStrap GAPI_bootstrap;
#endif
#ifdef ENABLE_WINDIB #ifdef ENABLE_WINDIB
extern VideoBootStrap WINDIB_bootstrap; extern VideoBootStrap WINDIB_bootstrap;
#endif #endif
......
...@@ -87,6 +87,9 @@ static VideoBootStrap *bootstrap[] = { ...@@ -87,6 +87,9 @@ static VideoBootStrap *bootstrap[] = {
#ifdef ENABLE_AALIB #ifdef ENABLE_AALIB
&AALIB_bootstrap, &AALIB_bootstrap,
#endif #endif
#ifdef ENABLE_GAPI
&GAPI_bootstrap,
#endif
#ifdef ENABLE_WINDIB #ifdef ENABLE_WINDIB
&WINDIB_bootstrap, &WINDIB_bootstrap,
#endif #endif
......
Makefile.in
Makefile
.libs
*.o
*.lo
*.la
## 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
/*
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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; i<gapi->SDL_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; i<NUM_MODELISTS; ++i ) {
if ( gapi->SDL_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; i<numrects; i++)
{
unsigned char *destPointer;
unsigned char *srcPointer;
if( gapi->userOrientation == 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; i<numrects; i++) {
unsigned char *destPointer = (unsigned char*) gapi->videoMem + 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; i<NUM_MODELISTS; ++i ) {
if ( gapi->SDL_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
/*
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 */
...@@ -40,7 +40,8 @@ static char rcsid = ...@@ -40,7 +40,8 @@ static char rcsid =
SDL_VideoSurface && \ SDL_VideoSurface && \
((SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) && \ ((SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) && \
(((SDL_VideoSurface->flags & SDL_OPENGL ) == SDL_OPENGL ) || \ (((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() \ #define DDRAW_FULLSCREEN() \
( \ ( \
......
...@@ -47,6 +47,7 @@ static char rcsid = ...@@ -47,6 +47,7 @@ static char rcsid =
#endif #endif
#ifdef _WIN32_WCE #ifdef _WIN32_WCE
#include "SDL_gapivideo.h"
#define NO_GETKEYBOARDSTATE #define NO_GETKEYBOARDSTATE
#define NO_CHANGEDISPLAYSETTINGS #define NO_CHANGEDISPLAYSETTINGS
#endif #endif
...@@ -101,6 +102,38 @@ static void LoadAygshell(void) ...@@ -101,6 +102,38 @@ static void LoadAygshell(void)
} }
} }
/* 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 #endif
static void SDL_RestoreGameMode(void) static void SDL_RestoreGameMode(void)
...@@ -319,6 +352,10 @@ LONG CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ...@@ -319,6 +352,10 @@ LONG CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
posted = SDL_PrivateMouseMotion(0, 1, x, y); posted = SDL_PrivateMouseMotion(0, 1, x, y);
} }
} else { } else {
#ifdef _WIN32_WCE
if (SDL_VideoSurface)
GapiTransform(this->hidden->userOrientation, this->hidden->hiresFix, &x, &y);
#endif
posted = SDL_PrivateMouseMotion(0, 0, x, y); posted = SDL_PrivateMouseMotion(0, 0, x, y);
} }
} }
...@@ -407,6 +444,10 @@ LONG CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) ...@@ -407,6 +444,10 @@ LONG CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
} else { } else {
x = (Sint16)LOWORD(lParam); x = (Sint16)LOWORD(lParam);
y = (Sint16)HIWORD(lParam); y = (Sint16)HIWORD(lParam);
#ifdef _WIN32_WCE
if (SDL_VideoSurface)
GapiTransform(this->hidden->userOrientation, this->hidden->hiresFix, &x, &y);
#endif
} }
posted = SDL_PrivateMouseButton( posted = SDL_PrivateMouseButton(
state, button, x, y); state, button, x, y);
......
...@@ -251,6 +251,7 @@ void WIN_UpdateMouse(_THIS) ...@@ -251,6 +251,7 @@ void WIN_UpdateMouse(_THIS)
/* Check to see if we need to enter or leave mouse relative mode */ /* Check to see if we need to enter or leave mouse relative mode */
void WIN_CheckMouseMode(_THIS) void WIN_CheckMouseMode(_THIS)
{ {
#ifndef _WIN32_WCE
/* If the mouse is hidden and input is grabbed, we use relative mode */ /* If the mouse is hidden and input is grabbed, we use relative mode */
if ( !(SDL_cursorstate & CURSOR_VISIBLE) && if ( !(SDL_cursorstate & CURSOR_VISIBLE) &&
(this->input_grab != SDL_GRAB_OFF) ) { (this->input_grab != SDL_GRAB_OFF) ) {
...@@ -258,4 +259,7 @@ void WIN_CheckMouseMode(_THIS) ...@@ -258,4 +259,7 @@ void WIN_CheckMouseMode(_THIS)
} else { } else {
mouse_relative = 0; mouse_relative = 0;
} }
#else
mouse_relative = 0;
#endif
} }
...@@ -59,6 +59,31 @@ static BOOL prev_shiftstates[2]; ...@@ -59,6 +59,31 @@ static BOOL prev_shiftstates[2];
and give him a chance to handle some messages. */ and give him a chance to handle some messages. */
static WNDPROC userWindowProc = NULL; 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 */ /* The main Win32 event handler */
LONG LONG
DIB_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) DIB_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
...@@ -70,6 +95,15 @@ LONG ...@@ -70,6 +95,15 @@ LONG
case WM_KEYDOWN: { case WM_KEYDOWN: {
SDL_keysym keysym; 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 */ /* Ignore repeated keys */
if ( lParam&REPEATED_KEYMASK ) { if ( lParam&REPEATED_KEYMASK ) {
return(0); return(0);
...@@ -127,6 +161,16 @@ LONG ...@@ -127,6 +161,16 @@ LONG
case WM_KEYUP: { case WM_KEYUP: {
SDL_keysym keysym; 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) { switch (wParam) {
case VK_CONTROL: case VK_CONTROL:
if ( lParam&EXTENDED_KEYMASK ) if ( lParam&EXTENDED_KEYMASK )
......
...@@ -768,14 +768,15 @@ static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) ...@@ -768,14 +768,15 @@ static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
ReleaseDC(SDL_Window, hdc); ReleaseDC(SDL_Window, hdc);
} }
int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
{ {
RGBQUAD *pal; RGBQUAD *pal;
int i; int i;
#ifndef _WIN32_WCE #if (_WIN32_WCE < 400 )
HDC hdc, mdc;
#else
HDC hdc; HDC hdc;
#else
HDC hdc, mdc;
#endif #endif
/* Update the display palette */ /* Update the display palette */
...@@ -805,7 +806,7 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) ...@@ -805,7 +806,7 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
} }
/* Set the DIB palette and update the display */ /* Set the DIB palette and update the display */
#ifndef _WIN32_WCE #if ( _WIN32_WCE >= 400 )
mdc = CreateCompatibleDC(hdc); mdc = CreateCompatibleDC(hdc);
SelectObject(mdc, screen_bmp); SelectObject(mdc, screen_bmp);
SetDIBColorTable(mdc, firstcolor, ncolors, pal); SetDIBColorTable(mdc, firstcolor, ncolors, pal);
...@@ -817,6 +818,7 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) ...@@ -817,6 +818,7 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
return(1); return(1);
} }
static void DIB_CheckGamma(_THIS) static void DIB_CheckGamma(_THIS)
{ {
#ifndef NO_GAMMA_SUPPORT #ifndef NO_GAMMA_SUPPORT
......
...@@ -30,6 +30,15 @@ static char rcsid = ...@@ -30,6 +30,15 @@ static char rcsid =
#include <windows.h> #include <windows.h>
/* for PDA */
typedef enum
{
SDL_ORIENTATION_UP,
SDL_ORIENTATION_DOWN,
SDL_ORIENTATION_LEFT,
SDL_ORIENTATION_RIGHT
} SDL_ScreenOrientation;
/* Private display data */ /* Private display data */
struct SDL_PrivateVideoData { struct SDL_PrivateVideoData {
HBITMAP screen_bmp; HBITMAP screen_bmp;
...@@ -38,6 +47,10 @@ struct SDL_PrivateVideoData { ...@@ -38,6 +47,10 @@ struct SDL_PrivateVideoData {
#define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */ #define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */
int SDL_nummodes[NUM_MODELISTS]; int SDL_nummodes[NUM_MODELISTS];
SDL_Rect **SDL_modelist[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 */ /* Old variable names */
#define screen_bmp (this->hidden->screen_bmp) #define screen_bmp (this->hidden->screen_bmp)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment