Hi *! Howdy!
You might remember me as I’ve sent the patches to libSDL which fixed
some of troubles the library had on Windows CE:
http://lists.libsdl.org/pipermail/sdl-libsdl.org/2008-October/066879.html
Today I’m happy to anounce another patchset with fixes the remaining issues.
I’ll annotate it carefully, please commit it because without it, my
previous patchset is incomplete, and it’s already committed.
Things that are fixed:
Mouse works correctly in both ‘up’ and ‘right’ VGA orientations.
Direction keys are rotated correctly.
Lines starting with !! denote annotations, remove them before applying.
!! I’ve decided to make systemOrientation a local variable, because
it’s not used
!! outside of this function.
diff -ru SDL-1.2-old/src/video/gapi/SDL_gapivideo.c
SDL-1.2/src/video/gapi/SDL_gapivideo.c
— SDL-1.2-old/src/video/gapi/SDL_gapivideo.c 2009-01-27
23:02:09.000000000 +0300
+++ SDL-1.2/src/video/gapi/SDL_gapivideo.c 2009-01-27
23:10:55.000000000 +0300
@@ -600,6 +600,7 @@
Uint32 Rmask, Gmask, Bmask;
DWORD style;
SDL_Rect allScreen;
-
enum SDL_ScreenOrientation systemOrientation; if( bpp < 4 ) {
@@ -651,7 +652,7 @@
}
gapi->userOrientation = SDL_ORIENTATION_UP;
-
gapi->systemOrientation = SDL_ORIENTATION_UP;
-
systemOrientation = SDL_ORIENTATION_UP; video->flags = SDL_FULLSCREEN; /* Clear flags, GAPI supports
fullscreen only */
/* GAPI or VGA? */
@@ -674,11 +675,11 @@
gapi->userOrientation = SDL_ORIENTATION_RIGHT;
if(GetSystemMetrics(SM_CYSCREEN) < GetSystemMetrics(SM_CXSCREEN))
-
gapi->systemOrientation = SDL_ORIENTATION_RIGHT;
-
systemOrientation = SDL_ORIENTATION_RIGHT; /* shall we apply hires fix? for example when we do not use
hires resource */
gapi->hiresFix = 0;
-
if( gapi->systemOrientation == gapi->userOrientation )
-
if( systemOrientation == gapi->userOrientation ) { if( (width > GetSystemMetrics(SM_CXSCREEN)) || (height
GetSystemMetrics(SM_CYSCREEN)))
gapi->hiresFix = 1;
!! Here we calculate a coordinate transform.
!! Its meaning is commented in the following header file.
@@ -764,6 +765,11 @@
}
}
-
if(gapi->useVga)
-
gapi->coordinateTransform = (4 - systemOrientation +
gapi->userOrientation) % 4;
-
else
-
gapi->coordinateTransform = gapi->userOrientation;+
#if REPORT_VIDEO_INFO
printf(“Video properties:\n”);
printf(“display bpp: %d\n”, gapi->gxProperties.cBPP);
@@ -775,7 +781,7 @@
printf(“y pitch: %d\n”, gapi->gxProperties.cbyPitch);
printf(“gapi flags: 0x%x\n”, gapi->gxProperties.ffFormat);
printf(“user orientation: %d\n”, gapi->userOrientation);
-
printf("system orientation: %d\n", gapi->userOrientation);
-
printf("system orientation: %d\n", systemOrientation); printf("gapi orientation: %d\n", gapi->gapiOrientation);
@@ -793,6 +799,7 @@
printf(“video surface bpp: %d\n”, video->format->BitsPerPixel);
printf(“video surface width: %d\n”, video->w);
printf(“video surface height: %d\n”, video->h);
-
printf("mouse/arrows transformation angle: %d\n",
gapi->coordinateTransform);
#endif
diff -ru SDL-1.2-old/src/video/gapi/SDL_gapivideo.h
SDL-1.2/src/video/gapi/SDL_gapivideo.h
— SDL-1.2-old/src/video/gapi/SDL_gapivideo.h 2009-01-27
23:02:09.000000000 +0300
+++ SDL-1.2/src/video/gapi/SDL_gapivideo.h 2009-01-27
23:10:55.000000000 +0300
@@ -158,10 +158,10 @@
int startOffset; // in bytes
int useVga;
int suspended; // do not pu anything into video memory
-
// The orientation of the system, as defined by SM_CXSCREEN
and SM_CYSCREEN
-
// User can change it by using 'screen layout' in system options
-
// Restricted to UP or RIGHT
-
enum SDL_ScreenOrientation systemOrientation;
-
// The difference between mouse coordinates that system will report
-
// and mouse coordinates application expects. Measured in pi/2.
-
// This is also used to rotate arrow keys.
-
enum SDL_ScreenOrientation coordinateTransform;
};
!! And now we use coordinateTransform to transform mouse coordinates, not
!! userOrientation which can’t be safely used for that.
diff -ru SDL-1.2-old/src/video/wincommon/SDL_sysevents.c
SDL-1.2/src/video/wincommon/SDL_sysevents.c
— SDL-1.2-old/src/video/wincommon/SDL_sysevents.c 2009-01-27
23:02:09.000000000 +0300
+++ SDL-1.2/src/video/wincommon/SDL_sysevents.c 2009-01-27
23:18:05.000000000 +0300
@@ -461,7 +461,7 @@
} else {
#ifdef _WIN32_WCE
if (SDL_VideoSurface)
GapiTransform(this->hidden->userOrientation, this->hidden->hiresFix,
&x, &y);
+
GapiTransform(this->hidden->coordinateTransform,
this->hidden->hiresFix, &x, &y);
#endif
posted =
SDL_PrivateMouseMotion(0, 0, x, y);
}
@@ -566,7 +566,7 @@
y = (Sint16)HIWORD(lParam);
#ifdef _WIN32_WCE
if (SDL_VideoSurface)
GapiTransform(this->hidden->userOrientation, this->hidden->hiresFix,
&x, &y);
+
GapiTransform(this->hidden->coordinateTransform,
this->hidden->hiresFix, &x, &y);
#endif
}
posted = SDL_PrivateMouseButton(
!! dibevents is used on Windows CE and it used to always include dibvideo.h
!! However dibvideo.h is completely irrelevant in context of Windows CE,
!! so now we include gapivideo.h and use coordinateTransform from it.
diff -ru SDL-1.2-old/src/video/windib/SDL_dibevents.c
SDL-1.2/src/video/windib/SDL_dibevents.c
— SDL-1.2-old/src/video/windib/SDL_dibevents.c 2009-01-27
23:02:11.000000000 +0300
+++ SDL-1.2/src/video/windib/SDL_dibevents.c 2009-01-27
23:10:55.000000000 +0300
@@ -30,7 +30,11 @@
#include “…/…/events/SDL_sysevents.h”
#include “…/…/events/SDL_events_c.h”
#include “…/wincommon/SDL_lowvideo.h”
-#include “SDL_dibvideo.h”
+#ifdef _WIN32_WCE
-
#include “SDL_gapivideo.h”
+#else -
#include “SDL_dibvideo.h”
+#endif
#include “SDL_vkeys.h”
#ifndef WM_APP
!! Arrows_keymap is a circular buffer (field) with key directions. It
is used to transform direction
!! pad presses to the correct orientation.
@@ -44,6 +48,7 @@
/* The translation table from a Microsoft VK keysym to a SDL keysym */
static SDLKey VK_keymap[SDLK_LAST];
static SDL_keysym *TranslateKey(WPARAM vkey, UINT scancode,
SDL_keysym *keysym, int pressed);
+static SDLKey Arrows_keymap[4];
/* Masks for processing the windows KEYDOWN and KEYUP messages /
#define REPEATED_KEYMASK (1<<30)
!! There’s some advanced field math here: we need to shift the press
by direction90
!! degrees, counterclockwise. Yes, it does actually work.
@@ -63,18 +68,15 @@
WPARAM rotateKey(WPARAM key,SDL_ScreenOrientation direction)
{
-
if (direction != SDL_ORIENTATION_LEFT)
-
return key;
-
switch (key) { case 0x26: /* up */
-
return 0x27;
-
return Arrows_keymap[(2 + direction) % 4]; case 0x27: /* right */
-
return 0x28;
-
return Arrows_keymap[(1 + direction) % 4]; case 0x28: /* down */
-
return 0x25;
-
return Arrows_keymap[direction % 4]; case 0x25: /* left */
-
return 0x26;
-
return Arrows_keymap[(3 + direction) % 4]; } return key;
@@ -99,8 +101,8 @@
return 0;
// Rotate key if necessary
-
if (this->hidden->orientation != SDL_ORIENTATION_UP)
-
wParam = rotateKey(wParam,
this->hidden->orientation);
-
if (this->hidden->coordinateTransform !=
SDL_ORIENTATION_UP)
-
wParam = rotateKey(wParam,
this->hidden->coordinateTransform);
#endif
/* Ignore repeated keys */
if ( lParam&REPEATED_KEYMASK ) {
@@ -173,8 +175,8 @@
return 0;
// Rotate key if necessary
-
if (this->hidden->orientation != SDL_ORIENTATION_UP)
-
wParam = rotateKey(wParam,
this->hidden->orientation);
-
if (this->hidden->coordinateTransform !=
SDL_ORIENTATION_UP)
-
wParam = rotateKey(wParam,
this->hidden->coordinateTransform);
#endif
switch (wParam) {
!!Here we fill Arrows_keymap with arrow scan codes.
@@ -430,6 +432,11 @@
VK_keymap[VK_SNAPSHOT] = SDLK_PRINT;
VK_keymap[VK_CANCEL] = SDLK_BREAK;
VK_keymap[VK_APPS] = SDLK_MENU;
+
-
Arrows_keymap[3] = 0x25;
-
Arrows_keymap[2] = 0x26;
-
Arrows_keymap[1] = 0x27;
-
Arrows_keymap[0] = 0x28;
}
#define EXTKEYPAD(keypad) ((scancode & 0x100)?(mvke):(keypad))
!! Here goes the tough shit.
!! Old code used to report scan codes as unicode positions; this was incorrect,
!! because, for example, arrows are 0x25~0x28 and this is a pretty
legitimate punctuation.
!! So application thought you enter a lot of punctuation when you
tapped the direction keys.
!! Now it tries to only report sane unicode keys, for which their scan
code == their ascii code.
@@ -485,9 +492,19 @@
keysym->scancode = (unsigned char) scancode;
keysym->mod = KMOD_NONE;
keysym->unicode = 0;
+
-
if ((vkey == VK_RETURN) && (scancode & 0x100)) {
-
/* No VK_ code for the keypad enter key */
-
keysym->sym = SDLK_KP_ENTER;
-
}
-
else {
-
keysym->sym = VK_keymap[SDL_MapVirtualKey(scancode, vkey)];
-
}
-
if ( pressed && SDL_TranslateUNICODE ) {
#ifdef NO_GETKEYBOARDSTATE
/* Uh oh, better hope the vkey is close enough… */
-
if((keysym->sym == vkey) || (vkey > 0x7f)) keysym->unicode = vkey;
#else
BYTE keystate[256];
@@ -501,14 +518,6 @@
#endif /* NO_GETKEYBOARDSTATE */
}
-
if ((vkey == VK_RETURN) && (scancode & 0x100)) {
-
/* No VK_ code for the keypad enter key */
-
keysym->sym = SDLK_KP_ENTER;
-
}
-
else {
-
keysym->sym = VK_keymap[SDL_MapVirtualKey(scancode, vkey)];
-
}
#if 0
{
HKL hLayoutCurrent = GetKeyboardLayout(0);
If you have any questions, feel free to ask!
If you happen to question whether that code can really work, I invite you to try
http://groups.google.com/group/rec.games.roguelike.misc/browse_thread/thread/1cce4aff6cbeb561#
Brand new POWDER 110!