Windows CE orientation support: latest fixes

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 direction
90
!! 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!

P.S. the machine-readable version of teh patch is:
http://folk.poesie.ru/powder/SDL_final.patch

2009/1/28, Ilya Kasnacheev <@Ilya_Kasnacheev>:> 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 direction
90
!! 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!

Hi,

I just checked your patch and reread it.
I’ve got some points we should probably discuss before committing this
to SVN.

I think that the dibvideo backend is also supported under WinCE but you
are silently dropping support by changing the include directives in
SDL_dibevents.c
The first few lines of the SDL_PrivateVideoData where shared between
dibvideo and gapivideo. This allowed DIB_HandleMessage to work on this
common part no matter if _THIS->hidden came from GAPI or DIB. The common
part included the orientation enum which should therefore not be
replaced by coordinateTransform.
Things started to break in revision 3122 when the *screen_logpal member
was introduced in SDL_dibevents.h, breaking the shared members.
So to keep the stable version stable we have to fix this.

One thing I don’t understand is the need for 3 orientation members in
gapi SDL_PrivateVideoData. We have userOrientation (which used to map to
orientation when including the windib header), gapiOrientation and
coordinateTransform. coordinateTransform has type SDL_ScreenOrientation
but encodes a rotation in quarters of a circle, which has to be applied
to the cursor coordinates/keys.
My problem is, that the old orientation member was mean’t to solve the
problem coordinateTransform tries to solve again.
Shouldn’t we put a little more work in fixing the old system than
introducing new variables?

I think dibvideo does all the orientation thing better in using
DM_DISPLAYORIENTATION and not guessing RIGHT or UP based on width and
height of the requested size.

I don’t know what’s the best way to proceed.

Right now I see the following options:

  • Drop the dib support for WinCE and stay with current code. I don’t
    like this option, as dib seems to work rather well.
  • Reunite the SDL_PrivateVideoData struct between gapi and dib, clearly
    marking the shared members.
  • Create a duplication of SDL_dibevents for gapi, dropping the
    connection between dib and gapi
  • Leave the whole 1.2 branch in a somehow unstable state and concentrate
    on a solid implementation for 1.3

Propably Sam Lantinga has a oppinion here? Sam?
I for my part mostly prefer 2 and 4 :wink:

Kind regards
Stefan> 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 direction
90
!! 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!

Hi! Thanks for reading my code and actually caring.

I just checked your patch and reread it.
I’ve got some points we should probably discuss before committing this
to SVN.

I think that the dibvideo backend is also supported under WinCE but you
are silently dropping support by changing the include directives in
SDL_dibevents.c
I didn’t know that dibvideo backend is supported under WinCE.
Is it a compile time define? If yes, then we should just replace the
#ifdef to the apropriate define.

The first few lines of the SDL_PrivateVideoData where shared between
dibvideo and gapivideo. This allowed DIB_HandleMessage to work on this
common part no matter if _THIS->hidden came from GAPI or DIB. The common
part included the orientation enum which should therefore not be
replaced by coordinateTransform.
It isn’t really replaced by coordinateTransform. The systemOrientation
thing is what I’ve added in previous patch which was committed by Sam.
It turned out that I don’t really need it outside one function; so
I’ve replaced it with coordinateTransform. It was obviously never used
outside my code.

Things started to break in revision 3122 when the *screen_logpal member
was introduced in SDL_dibevents.h, breaking the shared members.
So to keep the stable version stable we have to fix this.
Sorry, I don’t really understand. Can you cite the code that breaks?

One thing I don’t understand is the need for 3 orientation members in
gapi SDL_PrivateVideoData. We have userOrientation (which used to map to
orientation when including the windib header), gapiOrientation and
coordinateTransform. coordinateTransform has type SDL_ScreenOrientation
but encodes a rotation in quarters of a circle, which has to be applied
to the cursor coordinates/keys.
Well, those all are basically the same thing mathematically.

SDL_ScreenOrientation’s measure units are pi/2 in all cases. It
encodes the rotation of a given orientation compared to the basic one.

The only difference is - both userOrientation and gapiOrientation
assume that basic one is UP.
And coordinateTransform assumes that the basic orientation is whatever
system sends messages according to.

My problem is, that the old orientation member was mean’t to solve the
problem coordinateTransform tries to solve again.
Shouldn’t we put a little more work in fixing the old system than
introducing new variables?
Well, we might drop either userOrientation or gapiOrientation if they
aren’t used outside some specific part of code; I’ll check that.
However I’m sure that we shouldn’t drop coordinateTransform: It’s fundamental.
It’s the thing which binds orientation that user expects to see to
orientation that system thinks user is supposed to see.

On other hand, gapiOrientation is useless in vga mode, and user
orientation don’t give us enough information to transfer coordinates.

I think dibvideo does all the orientation thing better in using
DM_DISPLAYORIENTATION and not guessing RIGHT or UP based on width and
height of the requested size.
I didn’t actually check dib; I don’t really understand how does it
work; However, I think you might be right. I’ll check it out when I’ll
be back from Minsk.

Right now I see the following options:

  • Drop the dib support for WinCE and stay with current code. I don’t
    like this option, as dib seems to work rather well.
    I don’t like this option either. Why drop the working stuff?
    How do I turn the dib video on, again?
  • Reunite the SDL_PrivateVideoData struct between gapi and dib, clearly
    marking the shared members.
    Well, this seems to be the way to go.
    But I’ll repeat that I did noting to part them, so I think they are
    still in sync if they were previously.
    Do you have any examples where this sync is broken currently?
  • Create a duplication of SDL_dibevents for gapi, dropping the
    connection between dib and gapi
    I don’t think it’s viable, because SDL_dibevents isn’t really about
    either dib or gapi. It’s all about windows event handling which is
    independent.
  • Leave the whole 1.2 branch in a somehow unstable state and concentrate
    on a solid implementation for 1.3
    I don’t like this option because I’m porting POWDER to Windows CE.
    POWDER runs in SDL 1.2
    With my patchset, gapi/vga video is epically stable, so we just should
    find a way to bring them into SVN without breaking others’ code.> Propably Sam Lantinga has a oppinion here? Sam?
    I for my part mostly prefer 2 and 4 :wink:

I like option 2 or 3. We really should keep dib support (especially for
compatibility), and I think SDL 1.2 should be a stable implementation. 1.3
will be a little more work, especially without documentation and with new
features still to be added.

Jonny DOn Thu, Jan 29, 2009 at 3:07 PM, Stefan Klug <klug.stefan at gmx.de> wrote:

Hi,

I just checked your patch and reread it.
I’ve got some points we should probably discuss before committing this to
SVN.

I think that the dibvideo backend is also supported under WinCE but you are
silently dropping support by changing the include directives in
SDL_dibevents.c
The first few lines of the SDL_PrivateVideoData where shared between
dibvideo and gapivideo. This allowed DIB_HandleMessage to work on this
common part no matter if _THIS->hidden came from GAPI or DIB. The common
part included the orientation enum which should therefore not be replaced by
coordinateTransform.
Things started to break in revision 3122 when the *screen_logpal member was
introduced in SDL_dibevents.h, breaking the shared members.
So to keep the stable version stable we have to fix this.

One thing I don’t understand is the need for 3 orientation members in
gapi SDL_PrivateVideoData. We have userOrientation (which used to map to
orientation when including the windib header), gapiOrientation and
coordinateTransform. coordinateTransform has type SDL_ScreenOrientation but
encodes a rotation in quarters of a circle, which has to be applied to the
cursor coordinates/keys.
My problem is, that the old orientation member was mean’t to solve the
problem coordinateTransform tries to solve again.
Shouldn’t we put a little more work in fixing the old system than
introducing new variables?

I think dibvideo does all the orientation thing better in using
DM_DISPLAYORIENTATION and not guessing RIGHT or UP based on width and height
of the requested size.

I don’t know what’s the best way to proceed.

Right now I see the following options:

  • Drop the dib support for WinCE and stay with current code. I don’t like
    this option, as dib seems to work rather well.
  • Reunite the SDL_PrivateVideoData struct between gapi and dib, clearly
    marking the shared members.
  • Create a duplication of SDL_dibevents for gapi, dropping the connection
    between dib and gapi
  • Leave the whole 1.2 branch in a somehow unstable state and concentrate on
    a solid implementation for 1.3

Propably Sam Lantinga has a oppinion here? Sam?
I for my part mostly prefer 2 and 4 :wink:

Kind regards
Stefan

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 direction
90
!! 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!


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Hi,

I answered this last friday, but my mail got rejected because of its
size. So here again my answers without the patch.
I hope nobody kills me if I resend the formerly attached patch in an
empty eMail.
One week after writing this eMail I still don’t know if there is a
reliable way to fix SDL 1.2 windib and gapi for CE without as much
change as I did in the patch. I think the easiest way is to concentrate
on the upcoming 1.3…

Hi! Thanks for reading my code and actually caring.

I just checked your patch and reread it.
I’ve got some points we should probably discuss before committing this
to SVN.

I think that the dibvideo backend is also supported under WinCE but you
are silently dropping support by changing the include directives in
SDL_dibevents.c
I didn’t know that dibvideo backend is supported under WinCE.
Is it a compile time define? If yes, then we should just replace the
#ifdef to the apropriate define.

yes it is. and defines SDL_VIDEO_DRIVER_WINDIB the problem comes up, if
both drivers are compiled into SDL at the same time. (I write about that
later on)

The first few lines of the SDL_PrivateVideoData where shared between
dibvideo and gapivideo. This allowed DIB_HandleMessage to work on this
common part no matter if _THIS->hidden came from GAPI or DIB. The common
part included the orientation enum which should therefore not be
replaced by coordinateTransform.
It isn’t really replaced by coordinateTransform. The systemOrientation
thing is what I’ve added in previous patch which was committed by Sam.
It turned out that I don’t really need it outside one function; so
I’ve replaced it with coordinateTransform. It was obviously never used
outside my code.

Things started to break in revision 3122 when the *screen_logpal member
was introduced in SDL_dibevents.h, breaking the shared members.
So to keep the stable version stable we have to fix this.
Sorry, I don’t really understand. Can you cite the code that breaks?

See below

One thing I don’t understand is the need for 3 orientation members in
gapi SDL_PrivateVideoData. We have userOrientation (which used to map to
orientation when including the windib header), gapiOrientation and
coordinateTransform. coordinateTransform has type SDL_ScreenOrientation
but encodes a rotation in quarters of a circle, which has to be applied
to the cursor coordinates/keys.
Well, those all are basically the same thing mathematically.

SDL_ScreenOrientation’s measure units are pi/2 in all cases. It
encodes the rotation of a given orientation compared to the basic one.

The only difference is - both userOrientation and gapiOrientation
assume that basic one is UP.
And coordinateTransform assumes that the basic orientation is whatever
system sends messages according to.

Ok that makes sense. As the video driver is the only one who knows the
displayed orientation and the orientation the events come in, he can
calculate the rotation.

My problem is, that the old orientation member was mean’t to solve the
problem coordinateTransform tries to solve again.
Shouldn’t we put a little more work in fixing the old system than
introducing new variables?
Well, we might drop either userOrientation or gapiOrientation if they
aren’t used outside some specific part of code; I’ll check that.
However I’m sure that we shouldn’t drop coordinateTransform: It’s fundamental.
It’s the thing which binds orientation that user expects to see to
orientation that system thinks user is supposed to see.

I think these would be still sufficient, if they are set correctly. But
you are right, a single coordinateTransform value is easier to maintain,
as all the small device specific details are kept in the video code.

On other hand, gapiOrientation is useless in vga mode, and user
orientation don’t give us enough information to transfer coordinates.

I think dibvideo does all the orientation thing better in using
DM_DISPLAYORIENTATION and not guessing RIGHT or UP based on width and
height of the requested size.
I didn’t actually check dib; I don’t really understand how does it
work; However, I think you might be right. I’ll check it out when I’ll
be back from Minsk.

The main problem is that the GAPI code assumes that if(height < width)
its ORIENTATION_RIGHT and otherwise its ORIENTATION_UP. But the truth is
only known by the device. Some devices default to ORIENTATION_DOWN and
for example the Axim 51 lets the user choose UP,RIGHT and LEFT. These
assumptions lead to weird behaviour on some devices.

Right now I see the following options:

  • Drop the dib support for WinCE and stay with current code. I don’t
    like this option, as dib seems to work rather well.
    I don’t like this option either. Why drop the working stuff?
    How do I turn the dib video on, again?

./configure :wink:
I expect you’ll have to enable SDL_VIDEO_DRIVER_WINDIB and add
SDL_dibvideo.c to the project.

  • Reunite the SDL_PrivateVideoData struct between gapi and dib, clearly
    marking the shared members.
    Well, this seems to be the way to go.
    But I’ll repeat that I did noting to part them, so I think they are
    still in sync if they were previously.
    Do you have any examples where this sync is broken currently?

See below.>

  • Create a duplication of SDL_dibevents for gapi, dropping the
    connection between dib and gapi
    I don’t think it’s viable, because SDL_dibevents isn’t really about
    either dib or gapi. It’s all about windows event handling which is
    independent.
  • Leave the whole 1.2 branch in a somehow unstable state and concentrate
    on a solid implementation for 1.3
    I don’t like this option because I’m porting POWDER to Windows CE.
    POWDER runs in SDL 1.2
    With my patchset, gapi/vga video is epically stable, so we just should
    find a way to bring them into SVN without breaking others’ code.

Some Notes on sharing between windib and gapi:
Both backends define a struct SDL_PrivateVideoData which has a member
named “orientation”

In gapivideo the orientation member is set, referring to the struct
layout defined in gapivideo.h
In dibevents the same member is used, but this time referring to the
struct layout defined in dibvideo.h
This all worked well, as long as these members were at the same position
in both structs. (before revision 3122)
You solved it by including gapivideo.h, and effectively disabling windib.

But as soon as you want to have both backends in your dll (and forcing
one by using SDL_VideoInit() ) this will lead to undefined
behaviour.


I started to fix this, and a preliminary patch is attached to this email.
I know it’s huge change and I don’t know if there is any way to get this
into SVN… Sam any comment is welcome :wink:

I’ve included your patch, so your code should continue to work.

The main changes are:
The SDL_PrivateVideoData is now defined in SDL_gapidibvideo.h and
contains pointers to a gapiInfo struct and a dibInfo struct where these
two backends store their private data. That way the compiler can check
if you’re referring to the correct members.
I tried to keep the changes to windib as small as possible but I think
it makes sense to fix this. (the maccommon code uses a similar technique).
I kept coordinateTransform but changed the type to int, as it doesn’t
represent an actual orientation.

The following issues got also fixed:

  • SDL_SetVideoMode(0,0,0,flags) no longer crashes, but creates a
    fullscreen screen of the current resolution and orientation (orientation
    is only correct under windib). This is expected behaviour as stated in
    the docs. For me this is important, as I sometimes have to open a native
    window on top of the SDL screen.

The following issues are persistent (for me):

  • SDL_SetVideoMode(0,0,0,flags) uses the correct resolution but UP or
    RIGHT under gapi.
  • if I specify the size (SDL_SetVideoMode(320,240,0,flags)) it always
    uses ORIENTATION_RIGHT. There is currently no way to specify the wanted
    orientation. (We could use a environment variable like
    "SDL_PREFERRED_ORIENTATION=SYSTEM,UP,LEFT" which would mean “Use the
    current orientation, if we are in landscape/portrait and
    landscape/portrait is requested, otherwise use UP if portrait is
    requested but the device is in landscape and vice versa for LEFT”).

Pheew lots of text. Would be great if someone could still comment that.

Stefan K

Stefan
-------------- next part --------------
A non-text attachment was scrubbed…
Name: windib_gapi_fixes.patch
Type: text/x-patch
Size: 34625 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20090205/639f756e/attachment.bin

Interesting!

You’ve incorporated my patches, right?

I’ll surely try this patch for my next POWDER build.

2009/2/5, Stefan Klug <klug.stefan at gmx.de>:> Stefan

One week after writing this eMail I still don’t know if there is a
reliable way to fix SDL 1.2 windib and gapi for CE without as much
change as I did in the patch. I think the easiest way is to concentrate
on the upcoming 1.3…

I think your main problem is that you’re trying to fix all the windows
ce backend in one kick.
This is unnecessarily painful.

As for me, first I’ve got SDL and POWDER working; then, I’ve got both
orientations going fine in 320x240 mode (and this is already
committed); now, I’ve got both orientations going fine in 640x480
mode, and also now we rewrite arrows correctly!

We’re not breaking any public apis, we just make it work better and
better and better!

Let’s make it into SVN (your patch shows a lot of promise), and then,
when we’d have a stable working thing in SVN, we can make the next
step: figuring out orientations besides UP and RIGHT, figuring out
weird orientations on weird devices.

But trying to make a next step without finishing the previous one is
somewhat painful.

Ilya Kasnacheev schrieb:

One week after writing this eMail I still don’t know if there is a
reliable way to fix SDL 1.2 windib and gapi for CE without as much
change as I did in the patch. I think the easiest way is to concentrate
on the upcoming 1.3…

I think your main problem is that you’re trying to fix all the windows
ce backend in one kick.
This is unnecessarily painful.

As for me, first I’ve got SDL and POWDER working; then, I’ve got both
orientations going fine in 320x240 mode (and this is already
committed); now, I’ve got both orientations going fine in 640x480
mode, and also now we rewrite arrows correctly!

We’re not breaking any public apis, we just make it work better and
better and better!

Let’s make it into SVN (your patch shows a lot of promise), and then,
when we’d have a stable working thing in SVN, we can make the next
step: figuring out orientations besides UP and RIGHT, figuring out
weird orientations on weird devices.

But trying to make a next step without finishing the previous one is
somewhat painful.

No I’m not trying to fix all the problems. There are plenty of them left.
My patch does fix one or two minor problems and incorporates your
changes, but it mainly does some reorganization to have gapi and dib
running side by side.
My main concern is, that I see no clean way of fixing the gapi/dib
connections without massively touching the dib code.
But if I were a SDL maintainer I don’t know if I would accept such a
patch, which modifies the mature and well tested win32 backend in favour
of the unsupported WinCE backend :wink:

Regards
Stefan

I’ve tried this patch with my experimental POWDER build and it worked just fine

I vote to commit it and move on.

Sam, would you be so kind? The patch is on the list.

2009/2/5, Stefan Klug <klug.stefan at gmx.de>:> Stefan

And yes, there was a small glitch:

— SDL-1.2/src/video/gapi/SDL_gapivideo.c Mon Feb 16 21:48:36 2009
+++ SDL-1.2-final/src/video/gapi/SDL_gapivideo.c Fri Feb 13 19:16:56 2009
@@ -400,7 +400,7 @@
SystemParametersInfo( SPI_GETOEMINFO, sizeof( oemstr
), oemstr, 0 );

            // buggy iPaq38xx
  •           if ((oemstr[12] == 'H') && (oemstr[13] == '3') &&
    

(oemstr[14] == ‘8’) && (this->hidden->gxProperties.cbxPitch > 0))

  •           if ((oemstr[12] == 'H') && (oemstr[13] == '3') &&
    

(oemstr[14] == ‘8’) && (gapi->gxProperties.cbxPitch > 0))
{
gapi->videoMem = (PIXEL*)0xac0755a0;
gapi->gxProperties.cbxPitch = -640;

Apply it post-yours.

2009/2/16, Ilya Kasnacheev <@Ilya_Kasnacheev>:> I’ve tried this patch with my experimental POWDER build and it worked just

fine

I vote to commit it and move on.

Sam, would you be so kind? The patch is on the list.

2009/2/5, Stefan Klug <klug.stefan at gmx.de>:

Stefan

This patch has been added to subversion, thanks!

-Sam Lantinga, Founder and President, Galaxy Gameworks LLC

This patch has been added to subversion, thanks!

-Sam Lantinga, Founder and President, Galaxy Gameworks LLC

Whohoo,

I didn’t expect this patch to get into SVN that easily. Great…

But I must confess, that in the meantime I switched over to SDL 1.3

I rewrote the GAPI/RawFramebuffer backend, which does a pretty descent
Job to encapsulate machine dependent differences now. The main problem
left is input transformation… While working on this I’ve noticed that
vendors are really dropping GAPI support. (On a ASUS MyPal 696
RawFramebuffer isn’t available and a gapi blit takes 51 ms!!!)

So GAPI is a bit of a dead-end.

I’ve then started a DirectDraw Renderer which works amazingly well.
Blending and AlphaBlitting still has to be implemented, but it works
like a charm.
I hope to have some patches available soon.

Cheers Stefan

I’ve then started a DirectDraw Renderer which works amazingly well.
Blending and AlphaBlitting still has to be implemented, but it works
like a charm.
I hope to have some patches available soon.

Great, I’m looking forward to it!

See ya,
-Sam Lantinga, Founder and President, Galaxy Gameworks LLC