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:
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
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
......
......@@ -30,7 +30,10 @@ static char rcsid =
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#ifndef _WIN32_WCE
#include <process.h>
#endif
#include "SDL_error.h"
#include "SDL_thread.h"
......@@ -53,9 +56,14 @@ int SDL_SYS_CreateThread(SDL_Thread *thread, void *args)
* 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);
......
......@@ -201,9 +201,9 @@ static SYNCHHANDLE CleanUp (SYNCHHANDLE hSynch, DWORD Flags)
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);
......
......@@ -9,7 +9,7 @@ DIST_SUBDIRS = dummy x11 dga nanox fbcon directfb vgl svga ggi aalib \
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@
......
......@@ -39,6 +39,7 @@ static char rcsid =
#include "SDL_memops.h"
#include "SDL_leaks.h"
/* Public routines */
/*
* Create an empty RGB surface of the appropriate depth
......
......@@ -365,6 +365,9 @@ extern VideoBootStrap SVGALIB_bootstrap;
#ifdef ENABLE_AALIB
extern VideoBootStrap AALIB_bootstrap;
#endif
#ifdef ENABLE_GAPI
extern VideoBootStrap GAPI_bootstrap;
#endif
#ifdef ENABLE_WINDIB
extern VideoBootStrap WINDIB_bootstrap;
#endif
......
......@@ -87,6 +87,9 @@ static VideoBootStrap *bootstrap[] = {
#ifdef ENABLE_AALIB
&AALIB_bootstrap,
#endif
#ifdef ENABLE_GAPI
&GAPI_bootstrap,
#endif
#ifdef ENABLE_WINDIB
&WINDIB_bootstrap,
#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 =
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() \
( \
......
......@@ -47,6 +47,7 @@ static char rcsid =
#endif
#ifdef _WIN32_WCE
#include "SDL_gapivideo.h"
#define NO_GETKEYBOARDSTATE
#define NO_CHANGEDISPLAYSETTINGS
#endif
......@@ -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
static void SDL_RestoreGameMode(void)
......@@ -319,6 +352,10 @@ LONG CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
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 @@ LONG CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
} 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);
......
......@@ -251,6 +251,7 @@ void WIN_UpdateMouse(_THIS)
/* 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 @@ void WIN_CheckMouseMode(_THIS)
} else {
mouse_relative = 0;
}
#else
mouse_relative = 0;
#endif
}
......@@ -59,6 +59,31 @@ static BOOL prev_shiftstates[2];
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 @@ LONG
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 @@ LONG
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 )
......
......@@ -768,14 +768,15 @@ static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects)
ReleaseDC(SDL_Window, hdc);
}
int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
{
RGBQUAD *pal;
int i;
#ifndef _WIN32_WCE
HDC hdc, mdc;
#else
#if (_WIN32_WCE < 400 )
HDC hdc;
#else
HDC hdc, mdc;
#endif
/* Update the display palette */
......@@ -805,7 +806,7 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
}
/* 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 @@ int DIB_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
return(1);
}
static void DIB_CheckGamma(_THIS)
{
#ifndef NO_GAMMA_SUPPORT
......
......@@ -30,6 +30,15 @@ static char rcsid =
#include <windows.h>
/* 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 @@ struct SDL_PrivateVideoData {
#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)
......
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