Index: src/main/win32/SDL_main.c =================================================================== --- src/main/win32/SDL_main.c (revision 1) +++ src/main/win32/SDL_main.c (working copy) @@ -13,46 +13,37 @@ #include /* For _alloca() */ #ifdef _WIN32_WCE + # define DIR_SEPERATOR TEXT("\\") -# define _getcwd(str,len) wcscpy(str,DIR_SEPERATOR); -# define setbuf(x) -# define setvbuf(x) +# define setbuf(x,y) +# define setvbuf(x,y,z,w) # define fopen _wfopen # define freopen _wfreopen # define remove(x) DeleteFile(x) # define strcat wcscat -#else -# define DIR_SEPERATOR TEXT("/") -# include -#endif +/* The standard output files */ +# define STDOUT_FILE TEXT("SDL_stdout.txt") +# define STDERR_FILE TEXT("SDL_stderr.txt") -/* Include the SDL main definition header */ -#include "SDL.h" -#include "SDL_main.h" +TCHAR fileUnc[MAX_PATH+1]; +static TCHAR *_getcwd(TCHAR *buffer, int maxlen) +{ + TCHAR *plast; -#ifdef main -# ifndef _WIN32_WCE_EMULATION -# undef main -# endif /* _WIN32_WCE_EMULATION */ -#endif /* main */ + GetModuleFileName(NULL, fileUnc, MAX_PATH); + plast = wcsrchr(fileUnc, TEXT('\\')); + if(plast) *plast = 0; + /* Special trick to keep start menu clean... */ + if(_wcsicmp(fileUnc, TEXT("\\windows\\start menu")) == 0) + wcscpy(fileUnc, TEXT("\\Apps")); -/* The standard output files */ -#define STDOUT_FILE TEXT("stdout.txt") -#define STDERR_FILE TEXT("stderr.txt") + if(buffer) wcsncpy(buffer, fileUnc, maxlen); + return fileUnc; +} -#ifndef NO_STDIO_REDIRECT -# ifdef _WIN32_WCE - static wchar_t stdoutPath[MAX_PATH]; - static wchar_t stderrPath[MAX_PATH]; -# else - static char stdoutPath[MAX_PATH]; - static char stderrPath[MAX_PATH]; -# endif -#endif - -#if defined(_WIN32_WCE) && _WIN32_WCE < 300 +# if defined(_WIN32_WCE) && _WIN32_WCE < 300 /* seems to be undefined in Win CE although in online help */ -#define isspace(a) (((CHAR)a == ' ') || ((CHAR)a == '\t')) +# define isspace(a) (((CHAR)a == ' ') || ((CHAR)a == '\t')) /* seems to be undefined in Win CE although in online help */ char *strrchr(char *str, int c) @@ -74,8 +65,39 @@ } return p; } -#endif /* _WIN32_WCE < 300 */ +# endif /* _WIN32_WCE < 300 */ +#else +# define DIR_SEPERATOR TEXT("/") +# include + +/* The standard output files */ +# define STDOUT_FILE TEXT("stdout.txt") +# define STDERR_FILE TEXT("stderr.txt") + +#endif + +/* Include the SDL main definition header */ +#include "SDL.h" +#include "SDL_main.h" + +#ifdef main +# ifndef _WIN32_WCE_EMULATION +# undef main +# endif /* _WIN32_WCE_EMULATION */ +#endif /* main */ + +#ifndef NO_STDIO_REDIRECT +# ifndef _WIN32_WCE + static char stdoutPath[MAX_PATH]; + static char stderrPath[MAX_PATH]; +# else + static wchar_t stdoutPath[MAX_PATH]; + static wchar_t stderrPath[MAX_PATH]; +# endif +#endif + + /* Parse a command line buffer into arguments */ static int ParseCommandLine(char *cmdline, char **argv) { @@ -159,7 +181,7 @@ #ifndef NO_STDIO_REDIRECT /* See if the files have any output in them */ if ( stdoutPath[0] ) { - file = fopen(stdoutPath, TEXT("rb")); + file = (FILE *) fopen(stdoutPath, TEXT("rb")); if ( file ) { empty = (fgetc(file) == EOF) ? 1 : 0; fclose(file); @@ -169,7 +191,7 @@ } } if ( stderrPath[0] ) { - file = fopen(stderrPath, TEXT("rb")); + file = (FILE *) fopen(stderrPath, TEXT("rb")); if ( file ) { empty = (fgetc(file) == EOF) ? 1 : 0; fclose(file); @@ -219,8 +241,11 @@ ShowError("WinMain() error", SDL_GetError()); return(FALSE); } + +#if defined(_WIN32_WCE) && (!defined(GCC_BUILD) && !defined(__GNUC__)) atexit(cleanup_output); atexit(SDL_Quit); +#endif #ifndef DISABLE_VIDEO #if 0 @@ -248,6 +273,10 @@ SDL_main(argc, argv); /* Exit cleanly, calling atexit() functions */ +#if defined(_WIN32_WCE) && defined(__GNUC__) + cleanup_output(); + SDL_Quit(); +#endif exit(0); /* Hush little compiler, don't you cry... */ @@ -289,49 +318,49 @@ strcat( stdoutPath, DIR_SEPERATOR STDOUT_FILE ); /* Redirect standard input and standard output */ - newfp = freopen(stdoutPath, TEXT("w"), stdout); + newfp = (FILE *) freopen(stdoutPath, TEXT("w"), stdout); -#ifndef _WIN32_WCE if ( newfp == NULL ) { /* This happens on NT */ #if !defined(stdout) stdout = fopen(stdoutPath, TEXT("w")); #else - newfp = fopen(stdoutPath, TEXT("w")); + newfp = (FILE *) fopen(stdoutPath, TEXT("w")); if ( newfp ) { *stdout = *newfp; } #endif } -#endif /* _WIN32_WCE */ _getcwd( stderrPath, sizeof( stderrPath ) ); strcat( stderrPath, DIR_SEPERATOR STDERR_FILE ); - newfp = freopen(stderrPath, TEXT("w"), stderr); -#ifndef _WIN32_WCE + newfp = (FILE *) freopen(stderrPath, TEXT("w"), stderr); if ( newfp == NULL ) { /* This happens on NT */ #if !defined(stderr) stderr = fopen(stderrPath, TEXT("w")); #else - newfp = fopen(stderrPath, TEXT("w")); + newfp = (FILE *) fopen(stderrPath, TEXT("w")); if ( newfp ) { *stderr = *newfp; } #endif } -#endif /* _WIN32_WCE */ setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* Line buffered */ setbuf(stderr, NULL); /* No buffering */ #endif /* !NO_STDIO_REDIRECT */ #ifdef _WIN32_WCE - nLen = wcslen(szCmdLine)+128+1; - bufp = (wchar_t *)alloca(nLen*2); - wcscpy (bufp, TEXT("\"")); - GetModuleFileName(NULL, bufp+1, 128-3); - wcscpy (bufp+wcslen(bufp), TEXT("\" ")); - wcsncpy(bufp+wcslen(bufp), szCmdLine,nLen-wcslen(bufp)); + if (wcsncmp(szCmdLine, TEXT("\\"), 1)) { + nLen = wcslen(szCmdLine)+128+1; + bufp = (wchar_t *)alloca(nLen*2); + wcscpy (bufp, TEXT("\"")); + GetModuleFileName(NULL, bufp+1, 128-3); + wcscpy (bufp+wcslen(bufp), TEXT("\" ")); + wcsncpy(bufp+wcslen(bufp), szCmdLine,nLen-wcslen(bufp)); + } else + bufp = szCmdLine; + nLen = wcslen(bufp)+1; cmdline = (char *)alloca(nLen); if ( cmdline == NULL ) { @@ -356,6 +385,16 @@ } ParseCommandLine(cmdline, argv); + /* fix gdb/emulator combo */ + while (argc > 1 && !strstr(argv[0], ".exe")) { + OutputDebugString(TEXT("SDL: gdb argv[0] fixup\n")); + *(argv[1]-1) = ' '; + int i; + for (i=1; iw - *y; + rotatedY = *x; + *x = rotatedX; + *y = rotatedY; + break; + case SDL_ROTATE_RIGHT: + if (!SDL_VideoSurface) + break; + *x -= padHeight; + *y -= padWidth; + rotatedX = *y; + rotatedY = SDL_VideoSurface->h - *x; + *x = rotatedX; + *y = rotatedY; + break; + } +} + /* The main Win32 event handler DJM: This is no longer static as (DX5/DIB)_CreateWindow needs it */ @@ -180,14 +379,13 @@ SDL_VideoDevice *this = current_video; static int mouse_pressed = 0; static int in_window = 0; + #ifdef WMMSG_DEBUG - fprintf(stderr, "Received windows message: "); if ( msg > MAX_WMMSG ) { - fprintf(stderr, "%d", msg); + debugLog("SDL: Received windows message: %d -- 0x%X, 0x%X\n", msg, wParam, lParam); } else { - fprintf(stderr, "%s", wmtab[msg]); + debugLog("SDL: Received windows message: %s -- 0x%X, 0x%X\n", wmtab[msg], wParam, lParam); } - fprintf(stderr, " -- 0x%X, 0x%X\n", wParam, lParam); #endif switch (msg) { @@ -211,6 +409,8 @@ SDL_RestoreGameMode(); } } + if (this->hidden && this->hidden->gapiFuncs.dynamicGXResume) + this->hidden->gapiFuncs.dynamicGXResume(); posted = SDL_PrivateAppActive(1, appstate); WIN_GetKeyboardState(); } else { @@ -230,6 +430,8 @@ SDL_RestoreDesktopMode(); } } + if (this->hidden && this->hidden->gapiFuncs.dynamicGXResume) + this->hidden->gapiFuncs.dynamicGXSuspend(); posted = SDL_PrivateAppActive(0, appstate); } return(0); @@ -272,6 +474,8 @@ posted = SDL_PrivateMouseMotion(0, 1, x, y); } } else { + if (SDL_VideoSurface) + transform(rotation, ozoneHack, &x, &y); posted = SDL_PrivateMouseMotion(0, 0, x, y); } } @@ -360,7 +564,13 @@ } else { x = (Sint16)LOWORD(lParam); y = (Sint16)HIWORD(lParam); + if (SDL_VideoSurface) + transform(rotation, ozoneHack, &x, &y); } +#ifdef _WIN32_WCE + /* Since stylus movements are not continuous */ + posted = SDL_PrivateMouseMotion(0, 0, x, y); +#endif posted = SDL_PrivateMouseButton( state, button, x, y); } @@ -530,6 +740,48 @@ } return(0); +#ifdef _WIN32_WCE + /* mark the device's orientation at startup */ + case WM_CREATE: { + OSVERSIONINFO wv = { 0 }; + wv.dwOSVersionInfoSize = sizeof(LPOSVERSIONINFO); + GetVersionEx(&wv); + debugLog("SDL: Device is %s, OS version %d.%d build %d", (isLandscape) ? "landscape" : "portrait", + wv.dwMajorVersion, wv.dwMinorVersion, wv.dwBuildNumber ); + InitializeDisplayOrientation(); + + } + break; // fall through to the default handler + + case WM_SETTINGCHANGE: { + if (initDspMode == -1) { + int oldtmp = translatelandscape; + if ( (unsigned int) GetSystemMetrics(SM_CXSCREEN) < (unsigned int) GetSystemMetrics(SM_CYSCREEN) ) //portrait + translatelandscape = (isLandscape == 0) ? 0 : 1; + else + translatelandscape = (isLandscape == 1) ? 0 : 1; + debugLog("SDL: Caught WM_SETTINGCHANGE %d -> %d (flag %d)", oldtmp, translatelandscape, isLandscape); + } else { + currDspMode = deRotate(getDisplayMode()); + switch (currDspMode) + { + case ROTATE_NONE: + debugLog("SDL: Selecting no translation"); + break; + case ROTATE_LEFT: + debugLog("SDL: Selecting left translation"); + break; + case ROTATE_RIGHT: + debugLog("SDL: Selecting right translation"); + break; + case ROTATE_FLIP: + debugLog("SDL: Selecting flip translation"); + break; + } + } + } + break; // fall through to the default handler +#endif default: { /* Special handling by the video driver */ if (HandleMessage) { Index: src/video/wincommon/SDL_sysmouse.c =================================================================== --- src/video/wincommon/SDL_sysmouse.c (revision 1) +++ src/video/wincommon/SDL_sysmouse.c (working copy) @@ -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 } Index: src/video/wingapi/SDL_gapivideo.h =================================================================== --- src/video/wingapi/SDL_gapivideo.h (revision 0) +++ src/video/wingapi/SDL_gapivideo.h (revision 35) @@ -0,0 +1,199 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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: SDL_gapivideo.h,v 1.1 2004/02/02 23:25:35 lemure Exp $"; +#endif + +#ifndef _SDL_gapivideo_h +#define _SDL_gapivideo_h + +#include + +/* -------------------------------------------------------------------------------------------- */ + +/* 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; +}; + +#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() + +/* 2003 SE GAPI emulation */ + +#define GETRAWFRAMEBUFFER 0x00020001 +#define FORMAT_565 1 +#define FORMAT_555 2 +#define FORMAT_OTHER 3 + + +/* -------------------------------------------------------------------------------------------- */ + +/* Rotation direction */ +typedef enum { + SDL_ROTATE_NONE, + SDL_ROTATE_LEFT, + SDL_ROTATE_RIGHT +} SDL_RotateAttr; + +/* GAPI video mode */ +typedef enum { + GAPI_NONE = 0, + GAPI_DIRECT_565, + GAPI_DIRECT_555, + GAPI_MONO, + GAPI_PALETTE +} SDL_GAPIVideoMode; + + +/* Hidden "this" pointer for the video functions */ +#define _THIS SDL_VideoDevice *this + +/* GAPI functions definitions */ + +typedef struct GXDisplayProperties (*tGXDisplayProperties)(void); +typedef int (*tGXOpenDisplay)(HWND, unsigned long); +typedef void* (*tGXBeginDraw)(void); +typedef int (*tGXVoidFunction)(void); + +/* Private display data */ + +struct GAPI_funcs { + tGXDisplayProperties dynamicGXGetDisplayProperties; + tGXOpenDisplay dynamicGXOpenDisplay; + tGXVoidFunction dynamicGXCloseDisplay; + tGXBeginDraw dynamicGXBeginDraw; + tGXVoidFunction dynamicGXEndDraw; + tGXVoidFunction dynamicGXSuspend; + tGXVoidFunction dynamicGXResume; +}; + +struct GAPI_properties { + unsigned char invert; + int colorscale; + int dstPixelstep; + int dstLinestep; + int startOffset; + SDL_GAPIVideoMode videoMode; +}; + +#define MAX_CLR 0x100 + +struct palette_properties { + unsigned char *palRed; + unsigned char *palGreen; + unsigned char *palBlue; + unsigned short *pal; +}; + + +struct SDL_PrivateVideoData { + /* --- --- begin with DIB private structure to allow DIB events code sharing */ + HBITMAP screen_bmp; + HPALETTE screen_pal; + void *work_pixels; /* if the display needs to be rotated, memory allocated by the API */ + void *rotation_pixels; /* if the display needs to be rotated, memory allocated by the code */ + SDL_RotateAttr rotation; + char ozoneHack; /* force stylus translation if running without Hi Res flag */ + + #define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */ + int SDL_nummodes[NUM_MODELISTS]; + SDL_Rect **SDL_modelist[NUM_MODELISTS]; + + /* --- --- */ + + int w, h; + void *gapiBuffer; + HPALETTE screenPal; + struct GAPI_funcs gapiFuncs; + struct GAPI_properties gapiProperties; + struct GXDisplayProperties displayProps; + int srcLinestep; + int srcPixelstep; + int padWidth; + int padHeight; + + unsigned short *convertPalette; +}; + +#define gapiBuffer (this->hidden->gapiBuffer) +#define mainSurfaceWidth (this->hidden->w) +#define mainSurfaceHeight (this->hidden->h) +#define rotation (this->hidden->rotation) +#define ozoneHack (this->hidden->ozoneHack) +#define displayProperties (this->hidden->displayProps) +#define screenPal (this->hidden->screenPal) +#define GXGetDisplayProperties (this->hidden->gapiFuncs.dynamicGXGetDisplayProperties) +#define GXOpenDisplay (this->hidden->gapiFuncs.dynamicGXOpenDisplay) +#define GXCloseDisplay (this->hidden->gapiFuncs.dynamicGXCloseDisplay) +#define GXBeginDraw (this->hidden->gapiFuncs.dynamicGXBeginDraw) +#define GXEndDraw (this->hidden->gapiFuncs.dynamicGXEndDraw) +#define GXSuspend (this->hidden->gapiFuncs.dynamicGXSuspend) +#define GXResume (this->hidden->gapiFuncs.dynamicGXResume) +#define invert (this->hidden->gapiProperties.invert) +#define colorscale (this->hidden->gapiProperties.colorscale) +#define videoMode (this->hidden->gapiProperties.videoMode) +#define srcPixelstep (this->hidden->srcPixelstep) +#define srcLinestep (this->hidden->srcLinestep) +#define dstPixelstep (this->hidden->gapiProperties.dstPixelstep) +#define dstLinestep (this->hidden->gapiProperties.dstLinestep) +#define startOffset (this->hidden->gapiProperties.startOffset) +#define padWidth (this->hidden->padWidth) +#define padHeight (this->hidden->padHeight) +#define convertPalette (this->hidden->convertPalette) + +#endif /* _SDL_gapivideo_h */ Index: src/video/wingapi/ARM_rot.s =================================================================== --- src/video/wingapi/ARM_rot.s (revision 0) +++ src/video/wingapi/ARM_rot.s (revision 33) @@ -0,0 +1,157 @@ +@ ARM code version of rotation routines. +@ +@ @author Robin Watts (robin@wss.co.uk) +@ +@ When rotating a block of memory to the screen, the key facts to bear in +@ mind are: +@ * Screen memory is uncached - therefore to get best performance we want +@ to write runs of horizontal pixels so the write buffer can kick in and +@ merge the buffered writes. +@ * Reading large numbers of pixels to be written out horizontally, pulls +@ in lots of cache lines. We need to be careful not to cache bust here. +@ * The 16 or 32 way set associativity for screens can hurt us here too. +@ +@ A good compromise is therefore to write out in bursts of 4 horizontal +@ pixels at once. + + .text + + .global ARM_rotate + + @ Reads block of w*h pixels from srcPtr (addressed by srcPixStep, + @ srcLineStep) and stores them at dst (addressed by dstPixStep, + @ dstLineStep), converting palette by table lookup in convertPalette. +ARM_rotate: + @ r0 = destPtr + @ r1 = srcPtr + @ r2 = w + @ r3 = h + @ r4 = dstLineStep + @ r5 = srcPixStep - e.g. 480 + @ r6 = srcLineStep - e.g. 2 or -2 + MOV r12,r13 + STMFD r13!,{r4-r11,r14} + LDMFD r12,{r4-r6} + + @ For simplicity, we will think about width/height in terms of + @ destination. + + AND r7,r0,#6 + MOV r7,r7,LSR #1 + AND r7,r7,#3 @ r7 = Number over a multiple of 4 we start on + RSB r7,r7,#4 @ r7 = Number to do first time. +rotate_loop: + CMP r7,r2 + MOVGT r7,r2 @ r7 = width to do this time + + SUBS r7,r7,#4 @ r7 = width-4 + BLT thin @ less than 4 pixels wide + SUB r8,r4,#6 @ r8 = dstLineStep-6 +x_loop_4: + @ In this routine we will copy a 4 pixel wide stripe + ADD r9,r5,r5,LSL #1 @ r9 = 3*srcPixStep + SUB r9,r6,r9 @ r9 = srcLineStep-3*srcPixStep + MOV r7,r3 @ r7 = h +y_loop_4: + @ r9 >= 0, so at least 4 to do. + LDRH r10,[r1],r5 @ r10 = *(src) + LDRH r11,[r1],r5 @ r11 = *(src+srcPixStep) + LDRH r12,[r1],r5 @ r12 = *(src+srcPixStep*2) + LDRH r14,[r1],r9 @ r14 = *(src+srcPixStep*3) src+=srcLineStep + STRH r10,[r0],#2 @ *(ptr) = r10 + STRH r11,[r0],#2 @ *(ptr+2) = r11 + STRH r12,[r0],#2 @ *(ptr+4) = r12 + STRH r14,[r0],r8 @ *(ptr+6) = r14 ptr += dstLineStep + SUBS r7,r7,#1 @ h-- + BGT y_loop_4 + + MUL r10,r3,r6 + ADD r1,r1,r5,LSL #2 + SUB r1,r1,r10 + MUL r10,r3,r4 + ADD r0,r0,#8 + SUB r0,r0,r10 + + SUBS r2,r2,#4 @ r2 = w -= 4 + BEQ rotate_end @ if w = 0, none left. + SUBS r7,r2,#4 @ r7 = w - 4 + BGE x_loop_4 @ if 4 or more left, go back. +thin: + MOV r14,r3 @ r14 = h +thin_lp: + ADDS r7,r7,#2 @ Always do 1. GE => do 2. GT => do 3 + BGE just_2 + BGT just_3 + + @ Just do a 1 pixel wide stripe. Either the last pixel stripe, or + @ the first pixel stripe to align us. +y_loop_1: + LDRH r10,[r1],r6 + SUBS r14,r14,#1 + STRH r10,[r0],r4 + BGT y_loop_1 + + MUL r10,r3,r6 @ How much to step r1 back to undo this line? + ADD r1,r1,r5 @ Move r1 on by srcPixStep + SUB r1,r1,r10 @ Move r1 back by amount just added on + MUL r10,r3,r4 @ How much to step r0 back to undo this line? + ADD r0,r0,#2 @ Move r0 on by dstPixStep + SUB r0,r0,r10 @ Move r0 back by amount just added on + + SUBS r2,r2,#1 @ If we havent finished (i.e. we were doing + MOV r7,r2 @ the first pixel rather than the last one) + BGT rotate_loop @ then jump back to do some more +rotate_end: + LDMFD r13!,{r4-r11,PC} + +just_2: + @ Just do a 2 pixel wide stripe. Either the last stripe, or + @ the first stripe to align us. + SUB r9,r6,r5 @ r9 = srcLineStep - srcPixStep + SUB r8,r4,#2 @ r8 = dstLineStep - 2 +y_loop_2: + LDRH r10,[r1],r5 + LDRH r11,[r1],r9 + SUBS r14,r14,#1 + STRH r10,[r0],#2 + STRH r11,[r0],r8 + BGT y_loop_2 + + MUL r10,r3,r6 @ How much to step r1 back to undo this line? + ADD r1,r1,r5,LSL #1 @ Move r1 on by srcPixStep*2 + SUB r1,r1,r10 @ Move r1 back by amount just added on + MUL r10,r3,r4 @ How much to step r0 back to undo this line? + ADD r0,r0,#4 @ Move r0 on by dstPixStep*2 + SUB r0,r0,r10 @ Move r0 back by amount just added on + + SUBS r2,r2,#2 @ If we havent finished (i.e. we were doing + MOV r7,r2 @ the first stripe rather than the last one) + BGT rotate_loop @ then jump back to do some more + + LDMFD r13!,{r4-r11,PC} +just_3: + SUB r9,r6,r5,LSL #1 @ r9 = srcLineStep - srcPixStep + SUB r8,r4,#4 @ r8 = dstLineStep - 2 +y_loop_3: + LDRH r10,[r1],r5 + LDRH r11,[r1],r5 + LDRH r12,[r1],r9 + STRH r10,[r0],#2 + STRH r11,[r0],#2 + STRH r12,[r0],r8 + SUBS r14,r14,#1 + BGT y_loop_3 + + MUL r10,r3,r6 @ How much to step r1 back to undo this line? + ADD r1,r1,r5 @ Move r1 on by srcPixStep*3 + ADD r1,r1,r5,LSL #1 + SUB r1,r1,r10 @ Move r1 back by amount just added on + MUL r10,r3,r4 @ How much to step r0 back to undo this line? + ADD r0,r0,#6 @ Move r0 on by dstPixStep*3 + SUB r0,r0,r10 @ Move r0 back by amount just added on + + SUBS r2,r2,#3 @ If we havent finished (i.e. we were doing + MOV r7,r2 @ the first stripe rather than the last one) + BGT rotate_loop @ then jump back to do some more + + LDMFD r13!,{r4-r11,PC} Index: src/video/wingapi/SDL_gapivideo.c =================================================================== --- src/video/wingapi/SDL_gapivideo.c (revision 0) +++ src/video/wingapi/SDL_gapivideo.c (revision 41) @@ -0,0 +1,1109 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 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: SDL_gapivideo.c,v 1.5 2004/02/29 21:54:11 lemure Exp $"; +#endif + +#include +#include +#include +#include + +/* Not yet in the mingw32 cross-compile headers */ +#ifndef CDS_FULLSCREEN +#define CDS_FULLSCREEN 4 +#endif + +#ifndef WS_THICKFRAME +#define WS_THICKFRAME 0 +#endif + +#include "SDL.h" +#include "SDL_mutex.h" +#include "SDL_syswm.h" +#include "SDL_sysvideo.h" +#include "SDL_sysevents.h" +#include "SDL_events_c.h" +#include "SDL_pixels_c.h" +#include "SDL_syswm_c.h" +#include "SDL_sysmouse_c.h" +#include "SDL_dibevents_c.h" +#include "SDL_gapivideo.h" + +extern void InitializeDisplayOrientation(void); + +/* 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); + +static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects); + +static int GAPI_Available(void); +static SDL_VideoDevice *GAPI_CreateDevice(int devindex); + +void GAPI_GrabHardwareKeys(BOOL grab); + +VideoBootStrap WINGAPI_bootstrap = { + "wingapi", "WinCE GAPI", + GAPI_Available, GAPI_CreateDevice +}; + +static void* _OzoneFrameBuffer = NULL; +static struct GXDisplayProperties _OzoneDisplayProperties; +static char _OzoneAvailable = 0; + +typedef struct _RawFrameBufferInfo +{ + WORD wFormat; + WORD wBPP; + VOID *pFramePointer; + int cxStride; + int cyStride; + int cxPixels; + int cyPixels; +} RawFrameBufferInfo; + +/* our logger. log to stdout as well as to the debugger */ +void debugLog(const char *txt, ...) { + char str[256]; + TCHAR txtw[256]; + va_list va; + + va_start(va, txt); + vsnprintf(str, 256, txt, va); + va_end(va); + + MultiByteToWideChar(CP_ACP, 0, str, strlen(str) + 1, txtw, 255); + + fprintf(stderr, "%s\n", str); + OutputDebugString(txtw); +} + + +struct GXDisplayProperties Ozone_GetDisplayProperties(void) { + return _OzoneDisplayProperties; +} + +int Ozone_OpenDisplay(HWND window, unsigned long flag) { + return 1; +} + +int Ozone_CloseDisplay(void) { + return 1; +} + +void* Ozone_BeginDraw(void) { + return _OzoneFrameBuffer; +} + +int Ozone_EndDraw(void) { + return 1; +} + +int Ozone_Suspend(void) { + return 1; +} + +int Ozone_Resume(void) { + return 1; +} + +static HINSTANCE checkOzone(tGXDisplayProperties *gxGetDisplayProperties, tGXOpenDisplay *gxOpenDisplay, + tGXVoidFunction *gxCloseDisplay, tGXBeginDraw *gxBeginDraw, + tGXVoidFunction *gxEndDraw, tGXVoidFunction *gxSuspend, tGXVoidFunction *gxResume) { +#ifdef ARM + + int result; + RawFrameBufferInfo frameBufferInfo; + HDC hdc = GetDC(NULL); + result = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char *)&frameBufferInfo); + ReleaseDC(NULL, hdc); + if (result < 0) + return NULL; + debugLog("SDL: Running on Ozone"); + + _OzoneAvailable = 1; + + // Initializing global parameters + _OzoneFrameBuffer = frameBufferInfo.pFramePointer; + _OzoneDisplayProperties.cBPP = frameBufferInfo.wBPP; + _OzoneDisplayProperties.cbxPitch = frameBufferInfo.cxStride; + _OzoneDisplayProperties.cbyPitch = frameBufferInfo.cyStride; + _OzoneDisplayProperties.cxWidth = frameBufferInfo.cxPixels; + _OzoneDisplayProperties.cyHeight = frameBufferInfo.cyPixels; + + if (frameBufferInfo.wFormat == FORMAT_565) + _OzoneDisplayProperties.ffFormat = kfDirect565; + else if (frameBufferInfo.wFormat == FORMAT_555) + _OzoneDisplayProperties.ffFormat = kfDirect555; + else { + debugLog("SDL: Ozone unknown screen format"); + return NULL; + } + + if (gxGetDisplayProperties) + *gxGetDisplayProperties = Ozone_GetDisplayProperties; + if (gxOpenDisplay) + *gxOpenDisplay = Ozone_OpenDisplay; + if (gxCloseDisplay) + *gxCloseDisplay = Ozone_CloseDisplay; + if (gxBeginDraw) + *gxBeginDraw = Ozone_BeginDraw; + if (gxEndDraw) + *gxEndDraw = Ozone_EndDraw; + if (gxSuspend) + *gxSuspend = Ozone_Suspend; + if (gxResume) + *gxResume = Ozone_Resume; + + return (HINSTANCE)1; + +#else + + return NULL; + +#endif +} + +int getScreenWidth(_THIS) { + return displayProperties.cxWidth; +} + +int getScreenHeight(_THIS) { + return displayProperties.cyHeight; +} + + +/* Check GAPI library */ + +#define IMPORT(Handle,Variable,Type,Function, Store) \ + Variable = GetProcAddress(Handle, TEXT(Function)); \ + if (!Variable) { \ + FreeLibrary(Handle); \ + return NULL; \ + } \ + if (Store) \ + *Store = (Type)Variable; + +static HINSTANCE checkGAPI(tGXDisplayProperties *gxGetDisplayProperties, tGXOpenDisplay *gxOpenDisplay, + tGXVoidFunction *gxCloseDisplay, tGXBeginDraw *gxBeginDraw, + tGXVoidFunction *gxEndDraw, tGXVoidFunction *gxSuspend, tGXVoidFunction *gxResume, + BOOL bypassOzone) { + HMODULE gapiLibrary; + FARPROC proc; + HINSTANCE result; + // FIXME paletted ! + tGXDisplayProperties temp_gxGetDisplayProperties; + + // Workaround for Windows Mobile 2003 SE + _OzoneFrameBuffer = NULL; // FIXME !! + if (!bypassOzone) { + result = checkOzone(gxGetDisplayProperties, gxOpenDisplay, gxCloseDisplay, gxBeginDraw, gxEndDraw, gxSuspend, gxResume); + if (result) + return result; + } + + gapiLibrary = LoadLibrary(TEXT("gx.dll")); + if (!gapiLibrary) + return NULL; + + IMPORT(gapiLibrary, proc, tGXDisplayProperties, "?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ", gxGetDisplayProperties) + IMPORT(gapiLibrary, proc, tGXOpenDisplay, "?GXOpenDisplay@@YAHPAUHWND__@@K@Z", gxOpenDisplay) + IMPORT(gapiLibrary, proc, tGXVoidFunction, "?GXCloseDisplay@@YAHXZ", gxCloseDisplay) + IMPORT(gapiLibrary, proc, tGXBeginDraw, "?GXBeginDraw@@YAPAXXZ", gxBeginDraw) + IMPORT(gapiLibrary, proc, tGXVoidFunction, "?GXEndDraw@@YAHXZ", gxEndDraw) + IMPORT(gapiLibrary, proc, tGXVoidFunction, "?GXSuspend@@YAHXZ", gxSuspend) + IMPORT(gapiLibrary, proc, tGXVoidFunction, "?GXResume@@YAHXZ", gxResume) + + // FIXME paletted ! for the moment we just bail out + if (!gxGetDisplayProperties) { + IMPORT(gapiLibrary, proc, tGXDisplayProperties, "?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ", &temp_gxGetDisplayProperties) + if (temp_gxGetDisplayProperties().ffFormat & kfPalette) { + FreeLibrary(gapiLibrary); + return NULL; + } + FreeLibrary(gapiLibrary); + gapiLibrary = (HINSTANCE)1; + } + + return gapiLibrary; +} + + +/* GAPI driver bootstrap functions */ + +static int GAPI_Available(void) +{ + /* Check if the GAPI library is available */ +#ifndef GCC_BUILD + if (!checkGAPI(NULL, NULL, NULL, NULL, NULL, NULL, NULL, TRUE)) { + debugLog("SDL: GAPI driver not available"); + return 0; + } + else { + debugLog("SDL: GAPI driver available"); + return 1; + } +#else + return 1; +#endif +} + +static void GAPI_DeleteDevice(SDL_VideoDevice *device) +{ + if (device && device->hidden && device->hidden->gapiFuncs.dynamicGXCloseDisplay) + device->hidden->gapiFuncs.dynamicGXCloseDisplay(); + + if (device && device->hidden) + free(device->hidden); + if (device) + free(device); + +} + +static SDL_VideoDevice *GAPI_CreateDevice(int devindex) +{ + SDL_VideoDevice *device; + debugLog("SDL: Version $Rev$ bootstrapping GAPI device"); + + /* 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); + } + /* Reset GAPI pointers */ + memset(device->hidden, 0, sizeof(struct SDL_PrivateVideoData)); + + /* Set the function pointers */ + device->VideoInit = GAPI_VideoInit; + device->ListModes = GAPI_ListModes; + device->SetVideoMode = GAPI_SetVideoMode; + device->UpdateMouse = WIN_UpdateMouse; + device->SetColors = GAPI_SetColors; + device->UpdateRects = NULL; + 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; + device->SetColors = GAPI_SetColors; + + /* 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; + + /* set this flag to allow loose checking of modes inside sdl */ + device->handles_any_size = 1; + + return device; +} + + +int GAPI_VideoInit(_THIS, SDL_PixelFormat *vformat) +{ + HINSTANCE ret; + int gapifound = 0; + unsigned int mx, my, newmx, newmy; + + /* Create the window */ + if ( DIB_CreateWindow(this) < 0 ) { + return(-1); + } + + /* pump some events to get the window drawn ok */ + DIB_PumpEvents(this); + + debugLog("SDL: Starting video access detection --->"); + debugLog("SDL: System %dx%d", GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); + + /* grab the screen dimensions before opening gapi */ + mx = GetSystemMetrics(SM_CXSCREEN); + my = GetSystemMetrics(SM_CYSCREEN); + + /* first try to get basic gapi support */ + debugLog("SDL: Checking for GAPI"); + ret = checkGAPI(&this->hidden->gapiFuncs.dynamicGXGetDisplayProperties, + &this->hidden->gapiFuncs.dynamicGXOpenDisplay, + &this->hidden->gapiFuncs.dynamicGXCloseDisplay, + &this->hidden->gapiFuncs.dynamicGXBeginDraw, + &this->hidden->gapiFuncs.dynamicGXEndDraw, + &this->hidden->gapiFuncs.dynamicGXSuspend, + &this->hidden->gapiFuncs.dynamicGXResume, + TRUE); + if (ret) { /* found gapi */ + gapifound = 1; + this->hidden->gapiFuncs.dynamicGXOpenDisplay(SDL_Window, GX_FULLSCREEN); + this->hidden->displayProps = this->hidden->gapiFuncs.dynamicGXGetDisplayProperties(); + debugLog("SDL: GAPI OK, %dx%d, H=%d V=%d, %dbpp, landscape %s", displayProperties.cxWidth, displayProperties.cyHeight, + displayProperties.cbxPitch, displayProperties.cbyPitch, displayProperties.cBPP, + (displayProperties.ffFormat & kfLandscape) ? "true" : "false"); + } + + /* grab the screen dimensions after opening gapi */ + newmx = GetSystemMetrics(SM_CXSCREEN); + newmy = GetSystemMetrics(SM_CYSCREEN); + + /* if the reported extents are not directly equal to the system metrics, try ozone */ + +// if ( !( ( ((unsigned int) GetSystemMetrics(SM_CXSCREEN) == displayProperties.cxWidth) && ((unsigned int) GetSystemMetrics(SM_CYSCREEN) == displayProperties.cyHeight) ) || +// ( ((unsigned int) GetSystemMetrics(SM_CYSCREEN) == displayProperties.cxWidth) && ((unsigned int) GetSystemMetrics(SM_CXSCREEN) == displayProperties.cyHeight) ) ) +// || !ret ) { + + if ( newmx != displayProperties.cxWidth || newmy != displayProperties.cyHeight || ! ret) { + debugLog("SDL: Trying Ozone"); + // gapi reports incorrect extents (or unavailable) so force ozone + if (!gapifound) + ret = checkGAPI(&this->hidden->gapiFuncs.dynamicGXGetDisplayProperties, + &this->hidden->gapiFuncs.dynamicGXOpenDisplay, + &this->hidden->gapiFuncs.dynamicGXCloseDisplay, + &this->hidden->gapiFuncs.dynamicGXBeginDraw, + &this->hidden->gapiFuncs.dynamicGXEndDraw, + &this->hidden->gapiFuncs.dynamicGXSuspend, + &this->hidden->gapiFuncs.dynamicGXResume, + FALSE); + else // keep around some useful stuff from gapi + ret = checkGAPI(&this->hidden->gapiFuncs.dynamicGXGetDisplayProperties, + &this->hidden->gapiFuncs.dynamicGXOpenDisplay, + &this->hidden->gapiFuncs.dynamicGXCloseDisplay, + &this->hidden->gapiFuncs.dynamicGXBeginDraw, + &this->hidden->gapiFuncs.dynamicGXEndDraw, + NULL, + NULL, + FALSE); + this->hidden->displayProps = this->hidden->gapiFuncs.dynamicGXGetDisplayProperties(); + debugLog("SDL: Ozone %dx%d", displayProperties.cxWidth, displayProperties.cyHeight); + } + + /* Ozone is not working ok, fall back to gapi */ + if ( _OzoneAvailable && !( (mx == displayProperties.cxWidth && my == displayProperties.cyHeight) || + (mx == displayProperties.cyHeight && my == displayProperties.cxWidth) ) ) { + _OzoneAvailable = 0; + debugLog("SDL: Ozone no good, switching back to GAPI"); + ret = checkGAPI(&this->hidden->gapiFuncs.dynamicGXGetDisplayProperties, + &this->hidden->gapiFuncs.dynamicGXOpenDisplay, + &this->hidden->gapiFuncs.dynamicGXCloseDisplay, + &this->hidden->gapiFuncs.dynamicGXBeginDraw, + &this->hidden->gapiFuncs.dynamicGXEndDraw, + &this->hidden->gapiFuncs.dynamicGXSuspend, + &this->hidden->gapiFuncs.dynamicGXResume, + TRUE); + this->hidden->displayProps = this->hidden->gapiFuncs.dynamicGXGetDisplayProperties(); + } + + /* Which will need a tiny input hack if the original code does not have the "Hi Res" aware resource property set */ + ozoneHack = 0; + if (_OzoneFrameBuffer && (GetSystemMetrics(SM_CXSCREEN) != _OzoneDisplayProperties.cxWidth || GetSystemMetrics(SM_CYSCREEN) != _OzoneDisplayProperties.cyHeight)) { + debugLog("SDL: Running true Ozone with stylus hack"); + ozoneHack = 1; + } + + vformat->BitsPerPixel = (unsigned char)displayProperties.cBPP; + + /* if we got to here, the orientation has changed && the framebuffer reports extents using the new orientation, reinit the orientation */ + if (mx != newmx && my != newmy && displayProperties.cxWidth == newmx && displayProperties.cyHeight == newmy) + { + debugLog("SDL: Orientation reinit"); + InitializeDisplayOrientation(); + } + + /* print a nice debug info string */ + debugLog("SDL: <----- Detection finished. Running on %s driver at %dx%d (real %d, %d), using %s blitter", + _OzoneAvailable ? "Ozone" : "GAPI", + displayProperties.cxWidth, displayProperties.cyHeight, + GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), +#ifdef ARM + "ARM accelerated" +#else + "fallback fast C" +#endif + ); + + // Get color mask + if (displayProperties.ffFormat & kfDirect565) { + vformat->BitsPerPixel = 16; + vformat->Rmask = 0x0000f800; + vformat->Gmask = 0x000007e0; + vformat->Bmask = 0x0000001f; + videoMode = GAPI_DIRECT_565; + } + else + if (displayProperties.ffFormat & kfDirect555) { + vformat->BitsPerPixel = 16; + vformat->Rmask = 0x00007c00; + vformat->Gmask = 0x000003e0; + vformat->Bmask = 0x0000001f; + videoMode = GAPI_DIRECT_555; + } + else + if ((displayProperties.ffFormat & kfDirect) && (displayProperties.cBPP <= 8)) { + // We'll perform the conversion + vformat->BitsPerPixel = 24; + vformat->Rmask = 0x00ff0000; + vformat->Gmask = 0x0000ff00; + vformat->Bmask = 0x000000ff; + if (displayProperties.ffFormat & kfDirectInverted) + invert = (1 << displayProperties.cBPP) - 1; + colorscale = displayProperties.cBPP < 8 ? 8 - displayProperties.cBPP : 0; + videoMode = GAPI_MONO; + } + else + if (displayProperties.ffFormat & kfPalette) { + videoMode = GAPI_PALETTE; + } + + this->UpdateRects = GAPI_UpdateRects; + + /* We're done! */ + return(0); +} + +SDL_Rect **GAPI_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) +{ + static SDL_Rect res = { -1, -1, -1, -1 }, *resa[] = {&res, (SDL_Rect *)NULL}; + + res.w = getScreenWidth(this); + res.h = getScreenHeight(this); + + return resa; +} + +SDL_Surface *GAPI_SetVideoMode(_THIS, SDL_Surface *current, + int width, int height, int bpp, Uint32 flags) +{ + SDL_Surface *video; + Uint32 Rmask, Gmask, Bmask; + Uint32 prev_flags; + DWORD style; + const DWORD directstyle = (WS_VISIBLE|WS_POPUP); + const DWORD windowstyle = (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX); + const DWORD resizestyle = (WS_THICKFRAME|WS_MAXIMIZEBOX); + int screenWidth, screenHeight, x, y; + Uint8 *scr, *scrold; +#ifdef WINCE_EXTRADEBUG + debugLog("SDL: Opening mode %dx%d", width, height); +#endif + /* 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 (displayProperties.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); + } + } + + /* Fill in part of the video surface */ + prev_flags = video->flags; + video->flags = SDL_HWPALETTE; /* Clear flags */ + video->w = width; + video->h = height; + video->pitch = SDL_CalculatePitch(video); + mainSurfaceWidth = width; + mainSurfaceHeight = height; + + /* Reset the palette and create a new one if necessary */ + if (screenPal != NULL) { + DeleteObject(screenPal); + screenPal = NULL; + } + + /* See if we need to create a translation palette */ + if (convertPalette != NULL) { + free(convertPalette); + } + if (bpp == 8) { + debugLog("SDL: creating palette"); + convertPalette = (unsigned short*)malloc(256 * sizeof(unsigned short)); + } + + if (displayProperties.ffFormat & kfPalette) { + /* Will only be able to support 256 colors in this mode */ + // FIXME + //screenPal = GAPI_CreatePalette(); + } + + /* Set Window style */ + style = GetWindowLong(SDL_Window, GWL_STYLE); + if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) { + // do nothing, window has been created for fullscreen + } else { + if ( flags & SDL_NOFRAME ) { + // do nothing, window has been created for fullscreen + video->flags |= SDL_NOFRAME; + } else { + style &= ~directstyle; + style |= windowstyle; + if ( flags & SDL_RESIZABLE ) { + style |= resizestyle; + video->flags |= SDL_RESIZABLE; + } + } + } + + if (!SDL_windowid && !( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN )) + { + debugLog("SDL: GAPI: Setting new window style"); + SetWindowLong(SDL_Window, GWL_STYLE, style); + } + + /* Allocate bitmap */ + if (gapiBuffer) { + free(gapiBuffer); + gapiBuffer = NULL; + } + gapiBuffer = malloc(video->h * video->pitch); + video->pixels = gapiBuffer; + + /* See if we will rotate */ + if (flags & SDL_LANDSCVIDEO) { + rotation = SDL_ROTATE_LEFT; +#ifdef WINCE_EXTRADEBUG + debugLog("SDL: Requested landscape mode"); +#endif + } else if (flags & SDL_INVLNDVIDEO) { + rotation = SDL_ROTATE_RIGHT; +#ifdef WINCE_EXTRADEBUG + debugLog("SDL: Requested inverse landscape mode"); +#endif + } else { + rotation = SDL_ROTATE_NONE; +#ifdef WINCE_EXTRADEBUG + debugLog("SDL: Requested portrait mode"); +#endif + } + screenWidth = getScreenWidth(this); + screenHeight = getScreenHeight(this); + if (flags & SDL_FULLSCREEN) + if (width > screenWidth && width <= screenHeight && rotation == SDL_ROTATE_NONE) { + rotation = SDL_ROTATE_LEFT; + if (flags & SDL_INVLNDVIDEO) + rotation = SDL_ROTATE_RIGHT; + } else if (width > screenHeight && width <= screenWidth && rotation != SDL_ROTATE_NONE) + rotation = SDL_ROTATE_NONE; + /* save into flags */ + switch (rotation) { + case SDL_ROTATE_NONE: + video->flags |= SDL_PORTRTVIDEO; +#ifdef WINCE_EXTRADEBUG + debugLog("SDL: Setting portrait mode"); +#endif + break; + case SDL_ROTATE_LEFT: + video->flags |= SDL_LANDSCVIDEO; +#ifdef WINCE_EXTRADEBUG + debugLog("SDL: Setting landscape mode"); +#endif + break; + case SDL_ROTATE_RIGHT: + video->flags |= SDL_INVLNDVIDEO; +#ifdef WINCE_EXTRADEBUG + debugLog("SDL: Setting inverse landscape mode"); +#endif + break; + } + + /* Compute padding */ + padWidth = 0; + padHeight = 0; + + if (rotation == SDL_ROTATE_NONE) { + if (getScreenWidth(this) > width) + padWidth = (getScreenWidth(this) - width) / 2; + if (getScreenHeight(this) > height) + padHeight = (getScreenHeight(this) - height) / 2; + } + else { + if (getScreenWidth(this) > height) + padWidth = (getScreenHeight(this) - width) / 2; + if (getScreenHeight(this) > width) + padHeight = (getScreenWidth(this) - height) / 2; + } + + /* Compute the different drawing properties */ + switch(rotation) { + case SDL_ROTATE_NONE: + dstPixelstep = displayProperties.cbxPitch; + dstLinestep = displayProperties.cbyPitch; + startOffset = 0; + break; + case SDL_ROTATE_LEFT: + dstPixelstep = -displayProperties.cbyPitch; + dstLinestep = displayProperties.cbxPitch; + startOffset = displayProperties.cbyPitch * (displayProperties.cyHeight - 1); + break; + case SDL_ROTATE_RIGHT: + dstPixelstep = displayProperties.cbyPitch; + dstLinestep = -displayProperties.cbxPitch; + startOffset = displayProperties.cbxPitch * displayProperties.cxWidth; // predecrement scheme on inverse landscape. thx ggn :-) + break; + } + startOffset += padWidth * dstPixelstep + padHeight * dstLinestep; + + srcLinestep = video->pitch; + srcPixelstep = (bpp == 15 ? 2 : bpp / 8); + + SetWindowPos(SDL_Window, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + // especially, do not unhide the window. it is not hidden upon creation + + /* Grab hardware keys if necessary */ + if (flags & SDL_FULLSCREEN) + GAPI_GrabHardwareKeys(TRUE); + + /* Blank screen */ + scr = GXBeginDraw(); + for (y=0; yw; + height = rects->h; + destPointer = screenBuffer + startOffset + (rects->x * dstPixelstep) + (rects->y * dstLinestep); + srcPointer = (unsigned char*)gapiBuffer + (rects->x * srcPixelstep) + (rects->y * srcLinestep); + + while (height--) { + destPointerTmp = destPointer; + srcPointerTmp = srcPointer; + wloop = width; + while (wloop--) { + *(unsigned short *)destPointerTmp = *(unsigned short *)srcPointerTmp; + destPointerTmp += dstPixelstep; + srcPointerTmp += srcPixelstep; + } + + destPointer += dstLinestep; + srcPointer += srcLinestep; + } + rects++; + } + + GXEndDraw(); +} + + + +#ifdef ARM +/* special assembly blitter contributed by Robin Watts */ +extern void ARM_rotate(unsigned char *dstptr, unsigned char *srcPtr, int w, int h, int dstLineStep, int srcPixStep, int srcLineStep); +#endif + +static void GAPI_UpdateRects(_THIS, int numrects, SDL_Rect *rects) +{ + static int height=0, width=0, w4=0, w4loop=0, w2=0, w1=0, x1=0, h4=0, h4loop=0, h2=0, h1=0, dstPixelstep2=0, dstLinestep2=0, aligned=0, srcPixelstep2=0, dstLinestep2c=0; + static unsigned char *screenBuffer = NULL; + static unsigned char *destPointer = NULL, *destPointerTmp = NULL; + static unsigned char *srcPointer = NULL, *srcPointerTmp = NULL; + static unsigned int pixels = 0, pixels2 = 0; + + /* paletted blitting not supported */ + if (convertPalette) + return; + + /* non standard displays get the compatibility (read slow) blitter. sorry :-D */ + if ( (rotation == SDL_ROTATE_NONE && dstPixelstep != 2) || + (rotation == SDL_ROTATE_LEFT && dstLinestep != 2) || + (rotation == SDL_ROTATE_RIGHT && dstLinestep != -2) ) + { + static logflag = 0; + if (logflag == 0) { + logflag = 1; + debugLog("SDL: Falling back to compatibility blitter"); + } + GAPI_CompatibilityBlit(this, numrects, rects); + return; + } + + screenBuffer = GXBeginDraw(); + dstPixelstep2 = dstPixelstep << 1; + srcPixelstep2 = srcPixelstep << 1; + dstLinestep2 = dstLinestep << 1; + dstLinestep2c = dstLinestep2 - dstPixelstep; + + while (numrects--) { +#ifndef ARM + destPointer = screenBuffer + startOffset + (rects->x * dstPixelstep) + (rects->y * dstLinestep); + srcPointer = (unsigned char*)gapiBuffer + (rects->x * srcPixelstep) + (rects->y * srcLinestep); + width = rects->w; + height = rects->h; + x1 = (((unsigned int)destPointer) & 2) >> 1; + aligned = !((((unsigned int)srcPointer) & 2) ^ (((unsigned int)destPointer) & 2)); // xnor +#endif + switch (rotation) + { + case SDL_ROTATE_NONE: +#ifdef ARM + destPointer = screenBuffer + startOffset + (rects->x * dstPixelstep) + (rects->y * dstLinestep); + srcPointer = (unsigned char*)gapiBuffer + (rects->x * srcPixelstep) + (rects->y * srcLinestep); + width = rects->w; + height = rects->h; +#endif + while (height) { + memcpy(destPointer, srcPointer, width << 1); + destPointer += dstLinestep; + srcPointer += srcLinestep; + height--; + } + break; + + case SDL_ROTATE_LEFT: +#ifdef ARM + ARM_rotate(screenBuffer + startOffset + ((rects->x+rects->w-1) * dstPixelstep) + (rects->y * dstLinestep), + (unsigned char*)gapiBuffer + ((rects->x+rects->w-1) * srcPixelstep) + (rects->y * srcLinestep), + rects->h, rects->w, + -dstPixelstep, /* 480 */ + srcLinestep, /* 640 */ + -srcPixelstep); /* -2 */ +#else + h4 = (height - x1) >> 2; + h2 = (height - x1) & 2; + h1 = (height - x1) & 1; + while (width > 0) { + srcPointerTmp = srcPointer; + destPointerTmp = destPointer; + if (!aligned || width == 1 || (((unsigned int) srcPointer) & 2)) { + if (x1) { + *(unsigned short*)destPointer = *(unsigned short *)srcPointer; destPointer += dstLinestep; srcPointer += srcLinestep; } + for (h4loop = h4; h4loop > 0; h4loop--) { + pixels = *(unsigned short*)srcPointer; srcPointer += srcLinestep; + pixels |= ((unsigned int)*(unsigned short*)srcPointer)<<16; srcPointer += srcLinestep; + *(unsigned int*)destPointer = pixels; destPointer += dstLinestep2; + pixels = *(unsigned short*)srcPointer; srcPointer += srcLinestep; + pixels |= ((unsigned int)*(unsigned short*)srcPointer)<<16; srcPointer += srcLinestep; + *(unsigned int*)destPointer = pixels; destPointer += dstLinestep2; + } + if (h2) { + pixels = *(unsigned short*)srcPointer; srcPointer += srcLinestep; + pixels |= ((unsigned int)*(unsigned short*)srcPointer)<<16; srcPointer += srcLinestep; + *(unsigned int*)destPointer = pixels; destPointer += dstLinestep2; + } + if (h1) + *(unsigned short*)destPointer = *(unsigned short *)srcPointer; + srcPointer = srcPointerTmp + srcPixelstep; + destPointer = destPointerTmp + dstPixelstep; + width--; + } else { + if (x1) { + pixels = *(unsigned int*)srcPointer; srcPointer += srcLinestep; + *(unsigned short*)destPointer = (unsigned short) pixels; destPointer += dstPixelstep; + *(unsigned short*)destPointer = (unsigned short) (pixels >> 16); destPointer += dstLinestep - dstPixelstep; + } + for (h4loop = h4; h4loop > 0; h4loop--) { + pixels = *(unsigned int*)srcPointer; srcPointer += srcLinestep; + pixels2 = *(unsigned int*)srcPointer; srcPointer += srcLinestep; + *(unsigned int*)destPointer = (pixels2 << 16) | ((short unsigned int) pixels); destPointer += dstPixelstep; + *(unsigned int*)destPointer = (pixels2 & 0xFFFF0000) | (pixels >> 16); destPointer += dstLinestep2c; + pixels = *(unsigned int*)srcPointer; srcPointer += srcLinestep; + pixels2 = *(unsigned int*)srcPointer; srcPointer += srcLinestep; + *(unsigned int*)destPointer = (pixels2 << 16) | ((short unsigned int) pixels); destPointer += dstPixelstep; + *(unsigned int*)destPointer = (pixels2 & 0xFFFF0000) | (pixels >> 16); destPointer += dstLinestep2c; + } + if (h2) { + pixels = *(unsigned int*)srcPointer; srcPointer += srcLinestep; + pixels2 = *(unsigned int*)srcPointer; srcPointer += srcLinestep; + *(unsigned int*)destPointer = (pixels2 << 16) | ((short unsigned int) pixels); destPointer += dstPixelstep; + *(unsigned int*)destPointer = (pixels2 & 0xFFFF0000) | (pixels >> 16); destPointer += dstLinestep2c; + } + if (h1) { + pixels = *(unsigned int*)srcPointer; + *(unsigned short*)destPointer = (unsigned short) pixels; destPointer += dstPixelstep; + *(unsigned short*)destPointer = (unsigned short) (pixels >> 16); + } + srcPointer = srcPointerTmp + srcPixelstep2; + destPointer = destPointerTmp + dstPixelstep2; + width -= 2; + } + } +#endif + break; + + case SDL_ROTATE_RIGHT: +#ifdef ARM + ARM_rotate(screenBuffer + startOffset - 2 + (rects->x * dstPixelstep) + ((rects->y+rects->h-1) * dstLinestep), + (unsigned char*)gapiBuffer + (rects->x * srcPixelstep) + ((rects->y+rects->h-1) * srcLinestep), + rects->h, rects->w, + dstPixelstep, /* 480 */ + -srcLinestep, /* -480 */ + srcPixelstep); /* 2 */ +#else + h4 = (height - x1) >> 2; + h2 = (height - x1) & 2; + h1 = (height - x1) & 1; + while (width > 0) { + srcPointerTmp = srcPointer; + destPointerTmp = destPointer; + if (!aligned || width == 1 || (((unsigned int) srcPointer) & 2)) { + if (x1) { + destPointer += dstLinestep; *(unsigned short*)destPointer = *(unsigned short *)srcPointer; srcPointer += srcLinestep; } + for (h4loop = h4; h4loop > 0; h4loop--) { + pixels = ((unsigned int)*(unsigned short*)srcPointer)<<16; srcPointer += srcLinestep; + pixels |= *(unsigned short*)srcPointer; srcPointer += srcLinestep; + destPointer += dstLinestep2; *(unsigned int*)destPointer = pixels; + pixels = ((unsigned int)*(unsigned short*)srcPointer)<<16; srcPointer += srcLinestep; + pixels |= *(unsigned short*)srcPointer; srcPointer += srcLinestep; + destPointer += dstLinestep2; *(unsigned int*)destPointer = pixels; + } + if (h2) { + pixels = ((unsigned int)*(unsigned short*)srcPointer)<<16; srcPointer += srcLinestep; + pixels |= *(unsigned short*)srcPointer; srcPointer += srcLinestep; + destPointer += dstLinestep2; *(unsigned int*)destPointer = pixels; + } + if (h1) { + destPointer += dstLinestep; *(unsigned short*)destPointer = *(unsigned short *)srcPointer; } + srcPointer = srcPointerTmp + srcPixelstep; + destPointer = destPointerTmp + dstPixelstep; + width--; + } else { + if (x1) { + pixels = *(unsigned int*)srcPointer; srcPointer += srcLinestep; + destPointer += dstLinestep; *(unsigned short*)destPointer = (unsigned short) pixels; + destPointer += dstPixelstep; *(unsigned short*)destPointer = (unsigned short) (pixels >> 16); + } else if (h4 || h2) + destPointer += dstPixelstep; + for (h4loop = h4; h4loop > 0; h4loop--) { + pixels = *(unsigned int*)srcPointer; srcPointer += srcLinestep; + pixels2 = *(unsigned int*)srcPointer; srcPointer += srcLinestep; + destPointer += dstLinestep2c;*(unsigned int*)destPointer = (pixels << 16) | ((short unsigned int) pixels2); + destPointer += dstPixelstep; *(unsigned int*)destPointer = (pixels & 0xFFFF0000) | (pixels2 >> 16); + pixels = *(unsigned int*)srcPointer; srcPointer += srcLinestep; + pixels2 = *(unsigned int*)srcPointer; srcPointer += srcLinestep; + destPointer += dstLinestep2c;*(unsigned int*)destPointer = (pixels << 16) | ((short unsigned int) pixels2); + destPointer += dstPixelstep; *(unsigned int*)destPointer = (pixels & 0xFFFF0000) | (pixels2 >> 16); + } + if (h2) { + pixels = *(unsigned int*)srcPointer; srcPointer += srcLinestep; + pixels2 = *(unsigned int*)srcPointer; srcPointer += srcLinestep; + destPointer += dstLinestep2c;*(unsigned int*)destPointer = (pixels << 16) | ((short unsigned int) pixels2); + destPointer += dstPixelstep; *(unsigned int*)destPointer = (pixels & 0xFFFF0000) | (pixels2 >> 16); + } + if (h4 || h2) destPointer -= dstPixelstep; + if (h1) { + pixels = *(unsigned int*)srcPointer; + destPointer += dstLinestep; *(unsigned short*)destPointer = (unsigned short) pixels; + destPointer += dstPixelstep; *(unsigned short*)destPointer = (unsigned short) (pixels >> 16); + } + srcPointer = srcPointerTmp + srcPixelstep2; + destPointer = destPointerTmp + dstPixelstep2; + width -= 2; + } + } +#endif + } + rects++; + } + + GXEndDraw(); +} + +/* -------------------------------------------------------------------------------- */ +// Global fixme for paletted mode ! + +#define COLORCONV565(r,g,b) (((r&0xf8)<<(11-3))|((g&0xfc)<<(5-2))|((b&0xf8)>>3)) + +#define COLORCONV555(r,g,b) (((r&0xf8)<<(10-3))|((g&0xf8)<<(5-2))|((b&0xf8)>>3)) + +int GAPI_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) +{ + int i; + /* Convert colors to appropriate 565 or 555 mapping */ + for (i=0; ipixels) */ + if ( this->screen ) { + if ( this->screen->flags & SDL_FULLSCREEN ) + GAPI_GrabHardwareKeys(FALSE); + + if (this->screen->pixels != NULL) + { + free(this->screen->pixels); + this->screen->pixels = NULL; + } + + if (GXCloseDisplay) + GXCloseDisplay(); + } + } +} + +void GAPI_GrabHardwareKeys(BOOL grab) { + HINSTANCE GAPI_handle; + tGXVoidFunction GAPIActionInput; + + GAPI_handle = LoadLibrary(TEXT("gx.dll")); + if (!GAPI_handle) + return; + GAPIActionInput = (tGXVoidFunction)GetProcAddress(GAPI_handle, (grab ? TEXT("?GXOpenInput@@YAHXZ") : TEXT("?GXCloseInput@@YAHXZ"))); + if (GAPIActionInput) { + GAPIActionInput(); + } + FreeLibrary(GAPI_handle); +} Property changes on: src/video/wingapi/SDL_gapivideo.c ___________________________________________________________________ Name: svn:keywords + Rev Index: src/video/ARM_blit1to2.s =================================================================== --- src/video/ARM_blit1to2.s (revision 0) +++ src/video/ARM_blit1to2.s (revision 23) @@ -0,0 +1,80 @@ +@ ARM code version of Blit1to2. +@ +@ @author Robin Watts (robin@wss.co.uk) + + .text + + .global Blit1to2ARM + + @ Reads a width x height block of 8 bpp pixels from srcPtr, looks + @ them up in the palette at map, and stores them as 16bpp pixels + @ at dstPtr. srcPitch and dstPitch give information about how to + @ find the next lines. +Blit1to2ARM: + @ r0 = srcPtr + @ r1 = srcPitch + @ r2 = dstPtr + @ r3 = dstPitch + MOV r12,r13 + STMFD r13!,{r4-r11,r14} + LDMIA r12,{r4-r6} + @ r4 = width + @ r5 = height + @ r6 = map + + SUBS r5,r5,#1 @ while (--height) + BLT end +height_loop: + SUBS r7,r4,#5 @ r7= width_minus_5 + BLE thin +width_loop: + @ Have to do at least 6 here + LDRB r8, [r0],#1 @ r8 = *src++ + LDRB r9, [r0],#1 @ r9 = *src++ + LDRB r10,[r0],#1 @ r10= *src++ + LDRB r11,[r0],#1 @ r11= *src++ + LDRB r12,[r0],#1 @ r12= *src++ + LDRB r14,[r0],#1 @ r14= *src++ + ADD r8, r8, r8 @ r8 = 2*r8 + ADD r9, r9, r9 @ r9 = 2*r9 + ADD r10,r10,r10 @ r10= 2*r10 + ADD r11,r11,r11 @ r11= 2*r11 + ADD r12,r12,r12 @ r12= 2*r12 + ADD r14,r14,r14 @ r14= 2*r14 + LDRH r8, [r6,r8] @ r8 = map[r8] + LDRH r9, [r6,r9] @ r9 = map[r9] + LDRH r10,[r6,r10] @ r10= map[r10] + LDRH r11,[r6,r11] @ r11= map[r11] + LDRH r12,[r6,r12] @ r12= map[r12] + LDRH r14,[r6,r14] @ r14= map[r14] + SUBS r7,r7,#6 @ r7 = width_minus_5 -= 6 + STRH r8, [r2],#2 @ *dstPtr++ = r8 + STRH r9, [r2],#2 @ *dstPtr++ = r9 + STRH r10,[r2],#2 @ *dstPtr++ = r10 + STRH r11,[r2],#2 @ *dstPtr++ = r11 + STRH r12,[r2],#2 @ *dstPtr++ = r12 + STRH r14,[r2],#2 @ *dstPtr++ = r14 + BGT width_loop @ width_minus_5>0 => 6+ left to do +thin: + ADDS r7,r7,#5 @ r7 = width (width <= 5) + BEQ end_thin +thin_lp: + LDRB r8,[r0],#1 @ r8 = *src++ + SUBS r7,r7,#1 @ r7 = width-- + @ Stall + ADD r8,r8,r8 @ r8 = 2*r8 + LDRH r8,[r6,r8] @ r8 = map[r8] + @ Stall + @ Stall + STRH r8,[r2],#2 @ *dstPtr++ = r8 + BGT thin_lp +end_thin: + + ADD r2,r2,r3 @ dstPtr += dstPitch + ADD r0,r0,r1 @ srcPtr += srcPitch + + SUBS r5,r5,#1 + BGE height_loop + +end: + LDMFD r13!,{r4-r11,PC} Index: src/video/windib/SDL_dibevents.c =================================================================== --- src/video/windib/SDL_dibevents.c (revision 1) +++ src/video/windib/SDL_dibevents.c (working copy) @@ -59,17 +59,79 @@ and give him a chance to handle some messages. */ static WNDPROC userWindowProc = NULL; +#ifdef _WIN32_WCE + +WPARAM rotateKey(WPARAM key, SDL_RotateAttr direction) { + switch (direction) { + case SDL_ROTATE_NONE: + return key; + + case SDL_ROTATE_LEFT: + switch (key) { + case VK_UP: + return VK_RIGHT; + case VK_RIGHT: + return VK_DOWN; + case VK_DOWN: + return VK_LEFT; + case VK_LEFT: + return VK_UP; + } + + case SDL_ROTATE_RIGHT: + switch (key) { + case VK_UP: + return VK_LEFT; + case VK_RIGHT: + return VK_UP; + case VK_DOWN: + return VK_RIGHT; + case VK_LEFT: + return VK_DOWN; + } + } + + return key; +} + +#endif + + /* The main Win32 event handler */ LONG DIB_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { extern int posted; + MSG tmpmsg; + static int dropnextvklwinup = 0; switch (msg) { - case WM_SYSKEYDOWN: + //case WM_SYSKEYDOWN: case WM_KEYDOWN: { SDL_keysym keysym; +#ifdef _WIN32_WCE + // Drop spurious keystrokes + if ( wParam == VK_F20 || // VK_ROCKER with arrow keys + wParam == VK_F21 || // VK_DPAD with arrow keys + wParam == VK_F23 // VK_ACTION with dpad enter + ) + return 0; + + if (wParam == VK_LWIN && PeekMessage(&tmpmsg, NULL, 0, 0, PM_NOREMOVE)) // drop VK_LWIN messages if they're part of a chord + if (tmpmsg.message == WM_KEYDOWN && tmpmsg.wParam != VK_LWIN) { +#ifdef WMMSG_DEBUG + debugLog("SDL: DROPPING chorded VK_LWIN DOWN"); +#endif + dropnextvklwinup = 1; + return 0; + } + + // Rotate key if necessary + if (rotation != SDL_ROTATE_NONE) + wParam = rotateKey(wParam, rotation); +#endif + /* Ignore repeated keys */ if ( lParam&REPEATED_KEYMASK ) { return(0); @@ -100,35 +162,45 @@ wParam = VK_LMENU; break; } -#ifdef NO_GETKEYBOARDSTATE - /* this is the workaround for the missing ToAscii() and ToUnicode() in CE (not necessary at KEYUP!) */ - if ( SDL_TranslateUNICODE ) { - MSG m; - - m.hwnd = hwnd; - m.message = msg; - m.wParam = wParam; - m.lParam = lParam; - m.time = 0; - if ( TranslateMessage(&m) && PeekMessage(&m, hwnd, 0, WM_USER, PM_NOREMOVE) && (m.message == WM_CHAR) ) { - GetMessage(&m, hwnd, 0, WM_USER); - wParam = m.wParam; - } else { - wParam = 0; - } - } else { - wParam = 0; - } -#endif /* NO_GETKEYBOARDSTATE */ - posted = SDL_PrivateKeyboard(SDL_PRESSED, - TranslateKey(wParam,HIWORD(lParam),&keysym,1)); +#ifdef _WIN32_WCE + TranslateKey(wParam,HIWORD(lParam),&keysym,1); + if (keysym.sym != SDLK_UNKNOWN) // drop keys w/ 0 keycode + posted = SDL_PrivateKeyboard(SDL_PRESSED, &keysym); +#ifdef WMMSG_DEBUG + else + debugLog("SDL: DROPPING SDLK_UNKNOWN DOWN"); +#endif +#else + posted = SDL_PrivateKeyboard(SDL_PRESSED,TranslateKey(wParam,HIWORD(lParam),&keysym,1)); +#endif } return(0); - case WM_SYSKEYUP: + //case WM_SYSKEYUP: case WM_KEYUP: { SDL_keysym keysym; +#ifdef _WIN32_WCE + // Drop spurious keystrokes + if ( wParam == VK_F20 || // VK_ROCKER with arrow keys + wParam == VK_F21 || // VK_DPAD with arrow keys + wParam == VK_F23 // VK_ACTION with dpad enter + ) + return 0; + + if (dropnextvklwinup && wParam == VK_LWIN) { // drop VK_LWIN messages if they're part of a chord +#ifdef WMMSG_DEBUG + debugLog("SDL: DROPPING chorded VK_LWIN UP"); +#endif + dropnextvklwinup = 0; + return 0; + } + + // Rotate key if necessary + if (rotation != SDL_ROTATE_NONE) + wParam = rotateKey(wParam, rotation); +#endif + switch (wParam) { case VK_CONTROL: if ( lParam&EXTENDED_KEYMASK ) @@ -155,8 +227,17 @@ wParam = VK_LMENU; break; } - posted = SDL_PrivateKeyboard(SDL_RELEASED, - TranslateKey(wParam,HIWORD(lParam),&keysym,0)); +#ifdef _WIN32_WCE + TranslateKey(wParam,HIWORD(lParam),&keysym,0); + if (keysym.sym != SDLK_UNKNOWN) // drop keys w/ 0 keycode + posted = SDL_PrivateKeyboard(SDL_RELEASED, &keysym); +#ifdef WMMSG_DEBUG + else + debugLog("SDL: DROPPING SDLK_UNKNOWN UP"); +#endif +#else + posted = SDL_PrivateKeyboard(SDL_RELEASED,TranslateKey(wParam,HIWORD(lParam),&keysym,0)); +#endif } return(0); @@ -233,6 +314,7 @@ VK_keymap[VK_RBRACKET] = SDLK_RIGHTBRACKET; VK_keymap[VK_GRAVE] = SDLK_BACKQUOTE; VK_keymap[VK_BACKTICK] = SDLK_BACKQUOTE; +#ifndef _WIN32_WCE VK_keymap[VK_A] = SDLK_a; VK_keymap[VK_B] = SDLK_b; VK_keymap[VK_C] = SDLK_c; @@ -259,6 +341,34 @@ VK_keymap[VK_X] = SDLK_x; VK_keymap[VK_Y] = SDLK_y; VK_keymap[VK_Z] = SDLK_z; +#else + VK_keymap['A'] = SDLK_a; + VK_keymap['B'] = SDLK_b; + VK_keymap['C'] = SDLK_c; + VK_keymap['D'] = SDLK_d; + VK_keymap['E'] = SDLK_e; + VK_keymap['F'] = SDLK_f; + VK_keymap['G'] = SDLK_g; + VK_keymap['H'] = SDLK_h; + VK_keymap['I'] = SDLK_i; + VK_keymap['J'] = SDLK_j; + VK_keymap['K'] = SDLK_k; + VK_keymap['L'] = SDLK_l; + VK_keymap['M'] = SDLK_m; + VK_keymap['N'] = SDLK_n; + VK_keymap['O'] = SDLK_o; + VK_keymap['P'] = SDLK_p; + VK_keymap['Q'] = SDLK_q; + VK_keymap['R'] = SDLK_r; + VK_keymap['S'] = SDLK_s; + VK_keymap['T'] = SDLK_t; + VK_keymap['U'] = SDLK_u; + VK_keymap['V'] = SDLK_v; + VK_keymap['W'] = SDLK_w; + VK_keymap['X'] = SDLK_x; + VK_keymap['Y'] = SDLK_y; + VK_keymap['Z'] = SDLK_z; +#endif VK_keymap[VK_DELETE] = SDLK_DELETE; VK_keymap[VK_NUMPAD0] = SDLK_KP0; @@ -302,6 +412,15 @@ VK_keymap[VK_F13] = SDLK_F13; VK_keymap[VK_F14] = SDLK_F14; VK_keymap[VK_F15] = SDLK_F15; + VK_keymap[VK_F16] = SDLK_F16; + VK_keymap[VK_F17] = SDLK_F17; + VK_keymap[VK_F18] = SDLK_F18; + VK_keymap[VK_F19] = SDLK_F19; + VK_keymap[VK_F20] = SDLK_F20; + VK_keymap[VK_F21] = SDLK_F21; + VK_keymap[VK_F22] = SDLK_F22; + VK_keymap[VK_F23] = SDLK_F23; + VK_keymap[VK_F24] = SDLK_F24; VK_keymap[VK_NUMLOCK] = SDLK_NUMLOCK; VK_keymap[VK_CAPITAL] = SDLK_CAPSLOCK; @@ -325,6 +444,15 @@ prev_shiftstates[0] = FALSE; prev_shiftstates[1] = FALSE; + +#ifdef _WIN32_WCE + VK_keymap[0xC1] = SDLK_APP1; + VK_keymap[0xC2] = SDLK_APP2; + VK_keymap[0xC3] = SDLK_APP3; + VK_keymap[0xC4] = SDLK_APP4; + VK_keymap[0xC5] = SDLK_APP5; + VK_keymap[0xC6] = SDLK_APP6; +#endif } static SDL_keysym *TranslateKey(UINT vkey, UINT scancode, SDL_keysym *keysym, int pressed) @@ -356,8 +484,15 @@ #ifndef CS_BYTEALIGNCLIENT #define CS_BYTEALIGNCLIENT 0 #endif +#ifndef _WIN32_WCE SDL_RegisterApp("SDL_app", CS_BYTEALIGNCLIENT, 0); +#else + //SDL_RegisterApp("SDL_app", CS_BYTEALIGNCLIENT | CS_HREDRAW | CS_VREDRAW, 0); + SDL_RegisterApp("SDL_app", CS_HREDRAW | CS_VREDRAW, 0); +#endif if ( SDL_windowid ) { +// FIXME +#ifndef _WIN32_WCE SDL_Window = (HWND)strtol(SDL_windowid, NULL, 0); /* DJM: we want all event's for the user specified @@ -367,16 +502,29 @@ userWindowProc = (WNDPROC)GetWindowLong(SDL_Window, GWL_WNDPROC); SetWindowLong(SDL_Window, GWL_WNDPROC, (LONG)WinMessage); } +#endif } else { + +#ifndef _WIN32_WCE SDL_Window = CreateWindow(SDL_Appname, SDL_Appname, (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX), 0, 0, 0, 0, NULL, NULL, SDL_Instance, NULL); +#else + SDL_Window = CreateWindow(SDL_Appname, SDL_Appname, WS_VISIBLE | WS_POPUP, + 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), + NULL, NULL, SDL_Instance, NULL); + SetWindowPos(SDL_Window, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + +#endif if ( SDL_Window == NULL ) { SDL_SetError("Couldn't create window"); return(-1); } - ShowWindow(SDL_Window, SW_HIDE); +#ifndef _WIN32_WCE + ShowWindow(SDL_Window, SW_HIDE); +#endif } + return(0); } Index: src/video/windib/SDL_dibvideo.c =================================================================== --- src/video/windib/SDL_dibvideo.c (revision 1) +++ src/video/windib/SDL_dibvideo.c (working copy) @@ -29,16 +29,25 @@ #include #include #include -#if defined(WIN32_PLATFORM_PSPC) -#include // Add Pocket PC includes +#if defined(UNDER_CE) && (_WIN32_WCE >= 300) +/*#include // Add Pocket PC includes #pragma comment( lib, "aygshell" ) // Link Pocket PC library +*/ +#include #endif +#ifdef _MSC_VER +#define inline __inline +#endif /* Not yet in the mingw32 cross-compile headers */ #ifndef CDS_FULLSCREEN #define CDS_FULLSCREEN 4 #endif +#ifndef WS_THICKFRAME +#define WS_THICKFRAME 0 +#endif + #include "SDL.h" #include "SDL_mutex.h" #include "SDL_syswm.h" @@ -56,6 +65,17 @@ #define NO_GETDIBITS #define NO_CHANGEDISPLAYSETTINGS #define NO_GAMMA_SUPPORT + +/* uncomment this line if you target WinCE 3.x platform: */ +//#define NO_SETDIBCOLORTABLE + +/* these 2 variables are used to suport paletted DIBs on WinCE 3.x that + does not implement SetDIBColorTable, and when SetDIBColorTable is not working. + Slow. DIB is recreated every time. +*/ +static BITMAPINFO *last_bitmapinfo; +static void** last_bits; + #endif #ifndef WS_MAXIMIZE #define WS_MAXIMIZE 0 @@ -94,6 +114,13 @@ /* helper fn */ static int DIB_SussScreenDepth(); +#ifdef _WIN32_WCE +void DIB_ShowTaskBar(BOOL taskBarShown); +#ifdef ENABLE_WINGAPI +extern void GAPI_GrabHardwareKeys(BOOL grab); +#endif +#endif + /* DIB driver bootstrap functions */ static int DIB_Available(void) @@ -350,6 +377,9 @@ /* Fill in some window manager capabilities */ this->info.wm_available = 1; + /* Rotation information */ + rotation = SDL_ROTATE_NONE; + /* We're done! */ return(0); } @@ -368,7 +398,43 @@ #endif } +#ifdef _WIN32_WCE +void DIB_ShowTaskBar(BOOL taskBarShown) { +#if !defined(WIN32_PLATFORM_PSPC) || (_WIN32_WCE < 300) + // Hide taskbar, WinCE 2.x style - from EasyCE + HKEY hKey=0; + DWORD dwValue = 0; + unsigned long lSize = sizeof( DWORD ); + DWORD dwType = REG_DWORD; + HWND hWnd; + + RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("\\software\\microsoft\\shell"), 0, KEY_ALL_ACCESS, &hKey ); + RegQueryValueEx( hKey, TEXT("TBOpt"), 0, &dwType, (BYTE*)&dwValue, &lSize ); + if (taskBarShown) + dwValue &= 0xFFFFFFFF - 8; // reset bit to show taskbar + else + dwValue |= 8; // set bit to hide taskbar + RegSetValueEx( hKey, TEXT("TBOpt"), 0, REG_DWORD, (BYTE*)&dwValue, lSize ); + hWnd = FindWindow( TEXT("HHTaskBar"), NULL ); + SendMessage(hWnd, WM_COMMAND, 0x03EA, 0 ); + SetForegroundWindow(SDL_Window); +#else + if (taskBarShown) + SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON | SHFS_SHOWSTARTICON); + else + SHFullScreen(SDL_Window, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON); +#endif + if (FindWindow(TEXT("HHTaskBar"), NULL)) { // is it valid for HPC ? + if (taskBarShown) + ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL); + else + ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE); + } +} + +#endif + /* Helper fn to work out which screen depth windows is currently using. 15 bit mode is considered 555 format, 16 bit is 565. @@ -442,6 +508,7 @@ /* Various screen update functions available */ static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects); +static void DIB_RotatedUpdate(_THIS, int numrects, SDL_Rect *rects); SDL_Surface *DIB_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) @@ -462,14 +529,17 @@ int x, y; BOOL was_visible; Uint32 Rmask, Gmask, Bmask; + int screenWidth, screenHeight, i; /* See whether or not we should center the window */ was_visible = IsWindowVisible(SDL_Window); +#ifdef HAVE_OPENGL /* Clean up any GL context that may be hanging around */ if ( current->flags & SDL_OPENGL ) { WIN_GL_ShutDown(this); } +#endif /* Recalculate the bitmasks if necessary */ if ( bpp == current->format->BitsPerPixel ) { @@ -518,23 +588,30 @@ video->h = height; video->pitch = SDL_CalculatePitch(video); -#ifdef WIN32_PLATFORM_PSPC +//#ifdef WIN32_PLATFORM_PSPC /* Stuff to hide that $#!^%#$ WinCE taskbar in fullscreen... */ if ( flags & SDL_FULLSCREEN ) { if ( !(prev_flags & SDL_FULLSCREEN) ) { - SHFullScreen(SDL_Window, SHFS_HIDETASKBAR); - SHFullScreen(SDL_Window, SHFS_HIDESIPBUTTON); - ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE); + + //ShowWindow(SDL_Window, SW_SHOW); + //SetWindowPos(SDL_Window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + //SetForegroundWindow(SDL_Window); + + //SHFullScreen(SDL_Window, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON); + //ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE); + + DIB_ShowTaskBar(FALSE); + } video->flags |= SDL_FULLSCREEN; } else { if ( prev_flags & SDL_FULLSCREEN ) { - SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR); - SHFullScreen(SDL_Window, SHFS_SHOWSIPBUTTON); - ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL); + //SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON | SHFS_SHOWSTARTICON); + //ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL); + DIB_ShowTaskBar(TRUE); } } -#endif +//#endif #ifndef NO_CHANGEDISPLAYSETTINGS /* Set fullscreen mode if appropriate */ if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) { @@ -560,6 +637,7 @@ DeleteObject(screen_pal); screen_pal = NULL; } + if ( bpp <= 8 ) { /* RJR: March 28, 2000 @@ -591,7 +669,7 @@ } } #if WS_MAXIMIZE - if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE; +// if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE; #endif } @@ -615,6 +693,7 @@ binfo_size += video->format->palette->ncolors * sizeof(RGBQUAD); } + binfo = (BITMAPINFO *)malloc(binfo_size); if ( ! binfo ) { if ( video != current ) { @@ -642,19 +721,65 @@ ((Uint32*)binfo->bmiColors)[1] = video->format->Gmask; ((Uint32*)binfo->bmiColors)[2] = video->format->Bmask; } else { +#ifdef UNDER_CE + binfo->bmiHeader.biCompression = BI_RGB; /* 332 */ + if ( video->format->palette ) { + binfo->bmiHeader.biClrUsed = video->format->palette->ncolors; + for(i=0; iformat->palette->ncolors; i++) + { + binfo->bmiColors[i].rgbRed=i&(7<<5); + binfo->bmiColors[i].rgbGreen=(i&(7<<2))<<3; + binfo->bmiColors[i].rgbBlue=(i&3)<<5; + binfo->bmiColors[i].rgbReserved=0; + } + } +#else binfo->bmiHeader.biCompression = BI_RGB; /* BI_BITFIELDS for 565 vs 555 */ if ( video->format->palette ) { memset(binfo->bmiColors, 0, video->format->palette->ncolors*sizeof(RGBQUAD)); } +#endif } /* Create the offscreen bitmap buffer */ hdc = GetDC(SDL_Window); + /* See if we need to rotate the buffer (WinCE specific) */ + screenWidth = GetDeviceCaps(hdc, HORZRES); + screenHeight = GetDeviceCaps(hdc, VERTRES); + rotation = SDL_ROTATE_NONE; + work_pixels = NULL; + if (rotation_pixels) { + free(rotation_pixels); + rotation_pixels = NULL; + } + + if ((flags & SDL_FULLSCREEN) && (width>height) && (width > screenWidth) ) { + /* OK, we rotate the screen */ + video->pixels = malloc(video->h * video->pitch); + rotation_pixels = video->pixels; + if (video->pixels) + rotation = SDL_ROTATE_LEFT; + OutputDebugString(TEXT("will rotate\r\n")); + } + screen_bmp = CreateDIBSection(hdc, binfo, DIB_RGB_COLORS, - (void **)(&video->pixels), NULL, 0); + (rotation == SDL_ROTATE_NONE ? (void **)(&video->pixels) : (void**)&work_pixels), NULL, 0); ReleaseDC(SDL_Window, hdc); +#if defined(UNDER_CE) +/* keep bitmapinfo for palette in 8-bit modes for devices that don't have SetDIBColorTable */ + last_bits = (rotation == SDL_ROTATE_NONE ? (void **)(&video->pixels) : (void**)&work_pixels); + if(last_bitmapinfo) + free(last_bitmapinfo); + if(is16bitmode) + { + last_bitmapinfo = 0; + free(binfo); + } else + last_bitmapinfo = binfo; +#else free(binfo); +#endif if ( screen_bmp == NULL ) { if ( video != current ) { SDL_FreeSurface(video); @@ -662,7 +787,7 @@ SDL_SetError("Couldn't create DIB section"); return(NULL); } - this->UpdateRects = DIB_NormalUpdate; + this->UpdateRects = (work_pixels ? DIB_RotatedUpdate : DIB_NormalUpdate); /* Set video surface flags */ if ( bpp <= 8 ) { @@ -681,6 +806,14 @@ bounds.top = 0; bounds.right = video->w; bounds.bottom = video->h; +#ifdef UNDER_CE + if(rotation != SDL_ROTATE_NONE) + { + int t=bounds.right; + bounds.right = bounds.bottom; + bounds.bottom=t; + } +#endif AdjustWindowRectEx(&bounds, GetWindowLong(SDL_Window, GWL_STYLE), FALSE, 0); width = bounds.right-bounds.left; height = bounds.bottom-bounds.top; @@ -690,27 +823,56 @@ y -= GetSystemMetrics(SM_CYCAPTION)/2; } swp_flags = (SWP_NOCOPYBITS | SWP_FRAMECHANGED | SWP_SHOWWINDOW); - if ( was_visible && !(flags & SDL_FULLSCREEN) ) { +#ifndef UNDER_CE + if ( was_visible && !(flags & SDL_FULLSCREEN)) { swp_flags |= SWP_NOMOVE; } +#endif if ( flags & SDL_FULLSCREEN ) { top = HWND_TOPMOST; } else { top = HWND_NOTOPMOST; } +#ifndef _WIN32_WCE SetWindowPos(SDL_Window, top, x, y, width, height, swp_flags); +#else + if (flags & SDL_FULLSCREEN) { +/* When WinCE program switches resolution from larger to smaller we should move its window so it would be visible in fullscreen */ +// SetWindowPos(SDL_Window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + DIB_ShowTaskBar(FALSE); + if(x>0) x=0; // remove space from the left side of a screen in 320x200 mode + if(y>0) y=0; + SetWindowPos(SDL_Window, HWND_TOPMOST, x, y, width, height, SWP_NOCOPYBITS); + ShowWindow(SDL_Window, SW_SHOW); + } + else + SetWindowPos(SDL_Window, top, x, y, width, height, swp_flags); +#endif + SDL_resizing = 0; SetForegroundWindow(SDL_Window); } /* Set up for OpenGL */ if ( flags & SDL_OPENGL ) { +#ifdef HAVE_OPENGL if ( WIN_GL_SetupWindow(this) < 0 ) { return(NULL); } video->flags |= SDL_OPENGL; +#else + return (NULL); +#endif + } +#ifdef ENABLE_WINGAPI + /* Grab hardware keys if necessary */ + if ( flags & SDL_FULLSCREEN ) { + GAPI_GrabHardwareKeys(TRUE); + } +#endif + /* We're live! */ return(video); } @@ -726,28 +888,163 @@ } static int DIB_LockHWSurface(_THIS, SDL_Surface *surface) { - return(0); + return(0); } static void DIB_UnlockHWSurface(_THIS, SDL_Surface *surface) { return; } +static inline void rotateBlit(unsigned short *src, unsigned short *dest, SDL_Rect *rect, int pitch) { + int i=rect->w, j=rect->h; + src+=i; + + for (;i--;) { + register unsigned short *S=src--; +// I use loop unrolling to spedup things a little + int cnt = j; + if(cnt&1) + { + *(dest++) = *S; + S+=pitch; + } + cnt>>=1; + if(cnt&1) + { + *(dest++) = *S; + S+=pitch; + *(dest++) = *S; + S+=pitch; + } + cnt>>=1; + for (; cnt--; ) { + *(dest++) = *S; + S+=pitch; + *(dest++) = *S; + S+=pitch; + *(dest++) = *S; + S+=pitch; + *(dest++) = *S; + S+=pitch; + } + } +/* tiny optimization + int i, j; + src+=rect->w; + + for (i=0; iw; i++) { + register unsigned short *S=src--; + for (j=0; jh; j++) { + *(dest++) = *S; + S+=pitch; + } + } +*/ +/* original unoptimized version + int i, j; + + for (i=0; iw; i++) { + for (j=0; jh; j++) { + dest[i * rect->h + j] = src[pitch * j + (rect->w - i)]; + } + } +*/ +} + +static inline void rotateBlit8(unsigned char *src, unsigned char *dest, SDL_Rect *rect, int pitch) { + int i=rect->w, j=rect->h; + src+=i; + + for (;i--;) { + register unsigned char *S=src--; +// I use loop unrolling to spedup things a little + int cnt = j; + if(cnt&1) + { + *(dest++) = *S; + S+=pitch; + } + cnt>>=1; + if(cnt&1) + { + *(dest++) = *S; + S+=pitch; + *(dest++) = *S; + S+=pitch; + } + cnt>>=1; + for (; cnt--; ) { + *(dest++) = *S; + S+=pitch; + *(dest++) = *S; + S+=pitch; + *(dest++) = *S; + S+=pitch; + *(dest++) = *S; + S+=pitch; + } + } +} + +static void DIB_RotatedUpdate(_THIS, int numrects, SDL_Rect *rects) +{ + HDC hdc, mdc; + HBITMAP hb, old; + int i; + + hdc = GetDC(SDL_Window); + if ( screen_pal ) { + SelectPalette(hdc, screen_pal, FALSE); + } + mdc = CreateCompatibleDC(hdc); + /*SelectObject(mdc, screen_bmp);*/ + if(this->screen->format->BytesPerPixel == 2) { + for ( i=0; iscreen->pixels; + rotateBlit(src + (this->screen->w * rects[i].y) + rects[i].x, work_pixels, &rects[i], this->screen->w); + hb = CreateBitmap(rects[i].h, rects[i].w, 1, 16, work_pixels); + old = (HBITMAP)SelectObject(mdc, hb); + BitBlt(hdc, rects[i].y, this->screen->w - (rects[i].x + rects[i].w), rects[i].h, rects[i].w, + mdc, 0, 0, SRCCOPY); + SelectObject(mdc, old); + DeleteObject(hb); + } + } else { + if ( screen_pal ) { + SelectPalette(mdc, screen_pal, FALSE); + } + for ( i=0; iscreen->pixels; + rotateBlit8(src + (this->screen->w * rects[i].y) + rects[i].x, work_pixels, &rects[i], this->screen->w); + hb = CreateBitmap(rects[i].h, rects[i].w, 1, 8, work_pixels); + old = (HBITMAP)SelectObject(mdc, hb); + BitBlt(hdc, rects[i].y, this->screen->w - (rects[i].x + rects[i].w), rects[i].h, rects[i].w, + mdc, 0, 0, SRCCOPY); + SelectObject(mdc, old); + DeleteObject(hb); + } + } + DeleteDC(mdc); + ReleaseDC(SDL_Window, hdc); +} + static void DIB_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) { HDC hdc, mdc; int i; + HBITMAP old; hdc = GetDC(SDL_Window); if ( screen_pal ) { SelectPalette(hdc, screen_pal, FALSE); } mdc = CreateCompatibleDC(hdc); - SelectObject(mdc, screen_bmp); + old = (HBITMAP)SelectObject(mdc, screen_bmp); for ( i=0; ibmiHeader.biClrUsed=256; + for ( i=firstcolor; ibmiColors[i]=pal[i]; + screen_bmp = CreateDIBSection(hdc, last_bitmapinfo, DIB_RGB_COLORS, + last_bits, NULL, 0); + } +#else SelectObject(mdc, screen_bmp); SetDIBColorTable(mdc, firstcolor, ncolors, pal); +#endif +#ifndef UNDER_CE BitBlt(hdc, 0, 0, this->screen->w, this->screen->h, mdc, 0, 0, SRCCOPY); +#else + { + SDL_Rect rect; + rect.x=0; rect.y=0; + rect.w=this->screen->w; rect.h=this->screen->h; +// Fixme: screen flickers: (this->UpdateRects)(this, 1, &rect) ; + } +#endif DeleteDC(mdc); -#endif ReleaseDC(SDL_Window, hdc); return(1); } @@ -916,26 +1239,34 @@ void DIB_VideoQuit(_THIS) { /* Destroy the window and everything associated with it */ + DIB_ShowTaskBar(TRUE); +#ifdef ENABLE_WINGAPI + GAPI_GrabHardwareKeys(FALSE); +#endif + if ( SDL_Window ) { /* Delete the screen bitmap (also frees screen->pixels) */ if ( this->screen ) { -#ifdef WIN32_PLATFORM_PSPC +//#ifdef WIN32_PLATFORM_PSPC if ( this->screen->flags & SDL_FULLSCREEN ) { /* Unhide taskbar, etc. */ - SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR); - SHFullScreen(SDL_Window, SHFS_SHOWSIPBUTTON); - ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL); + //SHFullScreen(SDL_Window, SHFS_SHOWTASKBAR | SHFS_SHOWSIPBUTTON | SHFS_SHOWSTARTICON); + //ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOWNORMAL); } -#endif +//#endif #ifndef NO_CHANGEDISPLAYSETTINGS if ( this->screen->flags & SDL_FULLSCREEN ) { ChangeDisplaySettings(NULL, 0); ShowWindow(SDL_Window, SW_HIDE); } #endif + +#ifdef HAVE_OPENGL if ( this->screen->flags & SDL_OPENGL ) { WIN_GL_ShutDown(this); } +#endif + this->screen->pixels = NULL; } if ( screen_bmp ) { Index: src/video/windib/SDL_dibvideo.h =================================================================== --- src/video/windib/SDL_dibvideo.h (revision 1) +++ src/video/windib/SDL_dibvideo.h (working copy) @@ -30,19 +30,34 @@ #include +/* Rotation direction */ +typedef enum { + SDL_ROTATE_NONE, + SDL_ROTATE_LEFT, + SDL_ROTATE_RIGHT +} SDL_RotateAttr; + /* Private display data */ struct SDL_PrivateVideoData { HBITMAP screen_bmp; HPALETTE screen_pal; + void *work_pixels; /* if the display needs to be rotated, memory allocated by the API */ + void *rotation_pixels; /* if the display needs to be rotated, memory allocated by the code */ + SDL_RotateAttr rotation; + char ozoneHack; /* force stylus translation if running without Hi Res flag */ #define NUM_MODELISTS 4 /* 8, 16, 24, and 32 bits-per-pixel */ int SDL_nummodes[NUM_MODELISTS]; SDL_Rect **SDL_modelist[NUM_MODELISTS]; }; /* Old variable names */ -#define screen_bmp (this->hidden->screen_bmp) -#define screen_pal (this->hidden->screen_pal) +#define screen_bmp (this->hidden->screen_bmp) +#define screen_pal (this->hidden->screen_pal) #define SDL_nummodes (this->hidden->SDL_nummodes) #define SDL_modelist (this->hidden->SDL_modelist) +#define work_pixels (this->hidden->work_pixels) +#define rotation (this->hidden->rotation) +#define rotation_pixels (this->hidden->rotation_pixels) +#define ozoneHack (this->hidden->ozoneHack) #endif /* _SDL_dibvideo_h */ Index: src/video/SDL_video.c =================================================================== --- src/video/SDL_video.c (revision 1) +++ src/video/SDL_video.c (working copy) @@ -81,6 +81,9 @@ #ifdef ENABLE_DIRECTX &DIRECTX_bootstrap, #endif +#ifdef ENABLE_WINGAPI + &WINGAPI_bootstrap, +#endif #ifdef ENABLE_WINDIB &WINDIB_bootstrap, #endif @@ -856,6 +859,7 @@ (SDL_VideoSurface->flags&SDL_HWSURFACE) && !(SDL_VideoSurface->flags&SDL_DOUBLEBUF)) ) ) { + SDL_CreateShadowSurface(bpp); if ( SDL_ShadowSurface == NULL ) { SDL_SetError("Couldn't create shadow surface"); Index: src/video/SDL_sysvideo.h =================================================================== --- src/video/SDL_sysvideo.h (revision 1) +++ src/video/SDL_sysvideo.h (working copy) @@ -362,6 +362,9 @@ #ifdef ENABLE_WINDIB extern VideoBootStrap WINDIB_bootstrap; #endif +#ifdef ENABLE_WINGAPI +extern VideoBootStrap WINGAPI_bootstrap; +#endif #ifdef ENABLE_DIRECTX extern VideoBootStrap DIRECTX_bootstrap; #endif Index: src/video/SDL_RLEaccel.c =================================================================== --- src/video/SDL_RLEaccel.c (revision 1) +++ src/video/SDL_RLEaccel.c (working copy) @@ -102,6 +102,28 @@ #include "SDL_memops.h" #include "SDL_RLEaccel_c.h" +#if defined(_WIN32_WCE) && (_WIN32_WCE < 300) && defined(ARM) + +/* Crashes the compiler otherwise !!! */ + +int SDL_RLESurface(SDL_Surface *surface) { + return -1; +} + +int SDL_RLEBlit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect) { + return -1; +} + +int SDL_RLEAlphaBlit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect) { + return -1; +} + +void SDL_UnRLESurface(SDL_Surface *surface, int recode) { +} + +#else + + #if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) #include "mmx.h" /* Function to check the CPU flags */ @@ -1938,4 +1960,4 @@ } } - +#endif // HPC workaround Index: src/video/SDL_blit_1.c =================================================================== --- src/video/SDL_blit_1.c (revision 1) +++ src/video/SDL_blit_1.c (working copy) @@ -81,8 +81,25 @@ #define HI 0 #define LO 1 #endif + +#if defined(ARM) +void Blit1to2ARM(Uint8 *src, int srcskip, + Uint8 *dst, int dstskip, + int width, int height, + Uint16 *map); +#endif + static void Blit1to2(SDL_BlitInfo *info) { +#if defined(ARM) + Blit1to2ARM(info->s_pixels, + info->s_skip, + info->d_pixels, + info->d_skip, + info->d_width, + info->d_height, + (Uint16 *)info->table); +#else #ifndef USE_DUFFS_LOOP int c; #endif @@ -189,6 +206,7 @@ } } #endif /* USE_DUFFS_LOOP */ +#endif /* ARM */ } static void Blit1to3(SDL_BlitInfo *info) { Index: src/joystick/win32/SDL_mmjoystick.c =================================================================== --- src/joystick/win32/SDL_mmjoystick.c (revision 1) +++ src/joystick/win32/SDL_mmjoystick.c (working copy) @@ -36,6 +36,39 @@ #include "SDL_joystick_c.h" #include + +#ifdef _WIN32_WCE + +int SDL_SYS_JoystickInit(void) +{ + return 0; +} + +void SDL_SYS_JoystickClose(SDL_Joystick *joystick) +{ +} + +const char *SDL_SYS_JoystickName(int index) +{ + return NULL; +} + +int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) +{ + return 0; +} + +void SDL_SYS_JoystickQuit(void) +{ + return; +} + +void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) +{ +} + +#else + #include #define MAX_JOYSTICKS 16 @@ -336,3 +369,5 @@ } SDL_SetError("%s", errbuf); } + +#endif \ No newline at end of file Index: src/audio/SDL_audio.c =================================================================== --- src/audio/SDL_audio.c (revision 1) +++ src/audio/SDL_audio.c (working copy) @@ -453,7 +453,7 @@ } /* Allocate a fake audio memory buffer */ - audio->fake_stream = SDL_AllocAudioMem(audio->spec.size); + audio->fake_stream = (Uint8 *) SDL_AllocAudioMem(audio->spec.size); if ( audio->fake_stream == NULL ) { SDL_CloseAudio(); SDL_OutOfMemory(); Index: src/audio/windib/SDL_dibaudio.c =================================================================== --- src/audio/windib/SDL_dibaudio.c (revision 1) +++ src/audio/windib/SDL_dibaudio.c (working copy) @@ -40,6 +40,7 @@ #if defined(_WIN32_WCE) && (_WIN32_WCE < 300) #include "win_ce_semaphore.h" #endif +#undef waveOutGetErrorText /* Audio driver functions */ @@ -147,7 +148,7 @@ /* Set high priority for the audio thread */ static void DIB_ThreadInit(_THIS) { - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); + SetThreadPriority(GetCurrentThread(), this->hidden->thread_priority); } void DIB_WaitAudio(_THIS) @@ -229,6 +230,10 @@ int i; WAVEFORMATEX waveformat; + this->hidden->thread_priority = spec->thread_priority; + if (this->hidden->thread_priority <= 0) + this->hidden->thread_priority = THREAD_PRIORITY_NORMAL; + /* Initialize the wavebuf structures for closing */ sound = NULL; audio_sem = NULL; Index: src/audio/windib/SDL_dibaudio.h =================================================================== --- src/audio/windib/SDL_dibaudio.h (revision 1) +++ src/audio/windib/SDL_dibaudio.h (working copy) @@ -41,6 +41,7 @@ Uint8 *mixbuf; /* The raw allocated mixing buffer */ WAVEHDR wavebuf[NUM_BUFFERS]; /* Wave audio fragments */ int next_buffer; + Uint8 thread_priority; /* Thread priority */ }; /* Old variable names */ Index: src/cdrom/win32/SDL_syscdrom.c =================================================================== --- src/cdrom/win32/SDL_syscdrom.c (revision 1) +++ src/cdrom/win32/SDL_syscdrom.c (working copy) @@ -30,12 +30,30 @@ #include #include #include +#ifndef _WIN32_WCE #include +#endif #include "SDL_error.h" #include "SDL_cdrom.h" + +#ifdef _WIN32_WCE + +int SDL_SYS_CDInit() { + return 0; +} + +static void SDL_SYS_CDClose(SDL_CD *cdrom) { +} + +void SDL_SYS_CDQuit(void) { +} + +#else + #include "SDL_syscdrom.h" + /* This really broken?? */ #define BROKEN_MCI_PAUSE /* Pausing actually stops play -- Doh! */ @@ -384,3 +402,5 @@ SDL_numcds = 0; } } + +#endif \ No newline at end of file Index: src/thread/win32/win_ce_semaphore.c =================================================================== --- src/thread/win32/win_ce_semaphore.c (revision 1) +++ src/thread/win32/win_ce_semaphore.c (working copy) @@ -59,17 +59,19 @@ { SYNCHHANDLE hSynch = NULL, result = NULL; - __try +// __try { if (lInitialCount > lMaximumCount || lMaximumCount < 0 || lInitialCount < 0) { /* Bad parameters */ SetLastError (SYNCH_ERROR); - __leave; +// __leave; + return CleanUp(hSynch, 6); } hSynch = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, SYNCH_HANDLE_SIZE); - if (hSynch == NULL) __leave; +// if (hSynch == NULL) __leave; + if (hSynch == NULL) return CleanUp(hSynch, 6); hSynch->MaxCount = lMaximumCount; hSynch->CurCount = lInitialCount; @@ -85,12 +87,12 @@ ReleaseMutex (hSynch->hMutex); hSynch->hSemph = NULL; } - __finally - { - /* Return with the handle, or, if there was any error, return - a null after closing any open handles and freeing any allocated memory. */ +// __finally +// { +// /* Return with the handle, or, if there was any error, return +// a null after closing any open handles and freeing any allocated memory. */ result=CleanUp(hSynch, 6 /* An event and a mutex, but no semaphore. */); - } +// } return result; } @@ -103,7 +105,7 @@ /* Gain access to the object to assure that the release count would not cause the total count to exceed the maximum. */ - __try +// __try { WaitForSingleObject (hSemCE->hMutex, INFINITE); /* reply only if asked to */ @@ -113,7 +115,9 @@ { SetLastError (SYNCH_ERROR); Result = FALSE; - __leave; +// __leave; + ReleaseMutex (hSemCE->hMutex); + return Result; } hSemCE->CurCount += cReleaseCount; @@ -122,10 +126,10 @@ SetEvent (hSemCE->hEvent); } - __finally - { +// __finally +// { ReleaseMutex (hSemCE->hMutex); - } +// } return Result; } Index: Makefile =================================================================== --- Makefile (revision 0) +++ Makefile (revision 29) @@ -0,0 +1,31 @@ +CC = arm-wince-pe-gcc +AS = arm-wince-pe-as +CFLAGS = -Iinclude -Isrc/audio -Isrc/cdrom -Isrc/timer -Isrc/joystick -Isrc/events -Isrc/video -Isrc/thread -Isrc/thread/win32 -Isrc -Isrc/video/wincommon -Isrc/video/windib -I/cygdrive/e/wince-gcc-root/include -D__cdecl= -UWM_GETMINMAXINFO -UWS_MAXIMIZE +CFLAGS += -D_WIN32_WCE=300 -DARM -D_ARM_ -D__ARM__ -DUNICODE -D_UNICODE -DNO_SIGNAL_H -DENABLE_WINDIB -DENABLE_WINGAPI -D_FORCE_CE_SEMAPHORE -DWIN32 -DGCC_BUILD -D__stdcall__= -DNO_STDIO_REDIRECT +#CFLAGS += -DWMMSG_DEBUG +#CFLAGS += -DDEBUG -g +CFLAGS += -O3 -march=armv4 -mtune=xscale + +OBJS = src/audio/SDL_audio.o src/audio/SDL_audiocvt.o src/audio/SDL_audiodev.o src/audio/SDL_audiomem.o src/audio/SDL_mixer.o src/audio/SDL_wave.o +OBJS += src/audio/windib/SDL_dibaudio.o +OBJS += src/cdrom/SDL_cdrom.o src/cdrom/win32/SDL_syscdrom.o src/endian/SDL_endian.o src/events/SDL_active.o src/events/SDL_events.o src/events/SDL_expose.o +OBJS += src/events/SDL_keyboard.o src/events/SDL_mouse.o src/events/SDL_quit.o src/events/SDL_resize.o src/file/SDL_rwops.o src/joystick/SDL_joystick.o +OBJS += src/joystick/win32/SDL_mmjoystick.o src/thread/win32/SDL_sysmutex.o src/thread/win32/SDL_syssem.o src/thread/win32/SDL_systhread.o +OBJS += src/thread/SDL_thread.o src/thread/win32/win_ce_semaphore.o src/timer/win32/SDL_systimer.o src/timer/SDL_timer.o src/video/windib/SDL_dibevents.o +OBJS += src/video/windib/SDL_dibvideo.o src/video/wincommon/SDL_sysevents.o src/video/wincommon/SDL_sysmouse.o src/video/wincommon/SDL_syswm.o +OBJS += src/video/wingapi/SDL_gapivideo.o src/video/wingapi/ARM_rot.o src/video/SDL_blit.o src/video/SDL_blit_0.o src/video/SDL_blit_1.o src/video/SDL_blit_A.o +OBJS += src/video/ARM_blit1to2.o src/video/SDL_blit_N.o src/video/SDL_bmp.o src/video/SDL_cursor.o src/video/SDL_gamma.o src/video/SDL_pixels.o src/video/SDL_RLEaccel.o +OBJS += src/video/SDL_stretch.o src/video/SDL_surface.o src/video/SDL_video.o src/video/SDL_yuv.o src/video/SDL_yuv_mmx.o src/video/SDL_yuv_sw.o +OBJS += src/main/win32/SDL_main.o src/SDL.o src/SDL_error.o src/SDL_fatal.o src/SDL_getenv.o src/SDL_loadso.o + +all : libSDL.lib + +#ARM_blit1to2.o : +# arm-wince-pe-as $*.s -o $@ + +libSDL.lib : $(OBJS) + arm-wince-pe-ar cru $@ $^ + arm-wince-pe-ranlib $@ + +clean : + rm `find . -name *.o` Index: include/SDL_keysym.h =================================================================== --- include/SDL_keysym.h (revision 1) +++ include/SDL_keysym.h (working copy) @@ -258,8 +258,53 @@ SDLK_F13 = 294, SDLK_F14 = 295, SDLK_F15 = 296, +#ifdef _WIN32_WCE + SDLK_F16 = 297, + SDLK_F17 = 298, + SDLK_F18 = 299, + SDLK_F19 = 300, + SDLK_F20 = 301, + SDLK_F21 = 302, + SDLK_F22 = 303, + SDLK_F23 = 304, + SDLK_F24 = 305, /* Key state modifier keys */ + SDLK_NUMLOCK = 310, + SDLK_CAPSLOCK = 311, + SDLK_SCROLLOCK = 312, + SDLK_RSHIFT = 313, + SDLK_LSHIFT = 314, + SDLK_RCTRL = 315, + SDLK_LCTRL = 316, + SDLK_RALT = 317, + SDLK_LALT = 318, + SDLK_RMETA = 319, + SDLK_LMETA = 320, + SDLK_LSUPER = 321, /* Left "Windows" key */ + SDLK_RSUPER = 322, /* Right "Windows" key */ + SDLK_MODE = 323, /* "Alt Gr" key */ + SDLK_COMPOSE = 324, /* Multi-key compose key */ + + /* Miscellaneous function keys */ + SDLK_HELP = 325, + SDLK_PRINT = 326, + SDLK_SYSREQ = 327, + SDLK_BREAK = 328, + SDLK_MENU = 329, + SDLK_POWER = 330, /* Power Macintosh power key */ + SDLK_EURO = 331, /* Some european keyboards */ + SDLK_UNDO = 332, /* Atari keyboard has Undo */ + + /* Add any other keys here */ + SDLK_APP1 = 340, + SDLK_APP2 = 341, + SDLK_APP3 = 342, + SDLK_APP4 = 343, + SDLK_APP5 = 344, + SDLK_APP6 = 345, +#else + /* Key state modifier keys */ SDLK_NUMLOCK = 300, SDLK_CAPSLOCK = 301, SDLK_SCROLLOCK = 302, @@ -276,7 +321,7 @@ SDLK_MODE = 313, /* "Alt Gr" key */ SDLK_COMPOSE = 314, /* Multi-key compose key */ - /* Miscellaneous function keys */ + /* Miscellaneous function keys */ SDLK_HELP = 315, SDLK_PRINT = 316, SDLK_SYSREQ = 317, @@ -285,9 +330,8 @@ SDLK_POWER = 320, /* Power Macintosh power key */ SDLK_EURO = 321, /* Some european keyboards */ SDLK_UNDO = 322, /* Atari keyboard has Undo */ +#endif - /* Add any other keys here */ - SDLK_LAST } SDLKey; Index: include/SDL_audio.h =================================================================== --- include/SDL_audio.h (revision 1) +++ include/SDL_audio.h (working copy) @@ -53,6 +53,7 @@ Uint16 samples; /* Audio buffer size in samples (power of 2) */ Uint16 padding; /* Necessary for some compile environments */ Uint32 size; /* Audio buffer size in bytes (calculated) */ + Uint8 thread_priority; /* Thread priority */ /* This function is called when the audio device needs more data. 'stream' is a pointer to the audio data buffer 'len' is the length of that buffer in bytes. Index: include/SDL_video.h =================================================================== --- include/SDL_video.h (revision 1) +++ include/SDL_video.h (working copy) @@ -146,6 +146,9 @@ #define SDL_RLEACCEL 0x00004000 /* Surface is RLE encoded */ #define SDL_SRCALPHA 0x00010000 /* Blit uses source alpha blending */ #define SDL_PREALLOC 0x01000000 /* Surface uses preallocated memory */ +#define SDL_PORTRTVIDEO 0x00100000 /* wince */ +#define SDL_LANDSCVIDEO 0x00200000 /* wince */ +#define SDL_INVLNDVIDEO 0x00400000 /* wince */ /* Evaluates to true if the surface needs to be locked before access */ #define SDL_MUSTLOCK(surface) \ Property changes on: . ___________________________________________________________________ Name: svn:ignore + libSDL.lib