X-55 Twist Rudder Axis Doesn't Work
#21
Whoops, that should have been i==2 and not i = 2

JOYCAPS_HASZ wasn't quite right either, I had to OR it with the joystick's wCaps

The updated code builds and runs fine, and the axis is now detected in DXX-Rebirth (and DOSBOX)


Essentially what this change does:
-If reached axis 2 but Z axis is reported unused, shift all later axes down a slot so they are contiguous
-This fixes case where joystick that has no throttle axis does not detect any later axes either

SDL mistakenly worked from the assumption that all joystick axes must be contiguous, however DirectInput specifies that there can be a hole in the Z axis if the joystick does not use one, so that is why it only checks at axis 2
Reply
#22
I'm not sure that Direct Input only allows Z to be skipped, perhaps others as well. I've wrote a generic solution here which should cover any skipped axes:

file: SDL_mmjoystick.c
function: int SDL_SYS_JoystickOpen(SDL_Joystick *joystick)

change this line:
Code:
joystick->naxes = SYS_Joystick[index].wNumAxes;
to
Code:
int topslot=1;
for (i=2 ; i < MAX_AXES ; i++)    //all joysticks have at least slot 0 and 1
{
    if (SYS_Joystick[index].wCaps & (1<<(i-2))) {topslot=i;}
}
joystick->naxes = topslot + 1;
/* quick reference
#define JOYCAPS_HASZ    1
#define JOYCAPS_HASR    2
#define JOYCAPS_HASU    4
#define JOYCAPS_HASV    8
*/

file: SDL_mmjoystick.c
function: void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)

add this line
Code:
index = joystick->index;

add a condition within the first for loop
Code:
if ((i>1) && ((SYS_Joystick[index].wCaps & (1<<(i-2))) == 0)  {continue;}    //doesn't exist, continue to the next axis

That might be it. I believe SYS_Joystick[index].wCaps is in scope to both functions.
Reply
#23
According to http://msdn.microsoft.com/en-us/library/...85%29.aspx at "No Holes." rule, only Z can be unmapped. Any further axes must be continuous.

I think my implementation is fine. It does not increase naxes, so the reported number of axes is still correct. Also, you can use JOYCAPS_HASZ instead of (1<<(1-2)), it's defined in mmsystem.h, which is included.
Reply
#24
Hmm, I wonder why they didn't just say only Z can be skipped, rather then draw it out and say only 1, and that one can only be Z. The quick reference was in a comment section just as a reference, aye those definitions are in mmsystem.h

If you leave naxes at 3 it might cause problems with file SDL_joystick.c It's going to allocate memory for 3 axis. Those axes are referenced by array index. How is it going to reference axes[3] when it only allocated axes[0],axes[1],axes[2]?

For example, function Sint16 SDL_JoystickGetAxis(SDL_Joystick *joystick, int axis)
axis 3 is not less than naxes, so state for that axis will not be updated.

int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value)
will be affected as well. Perhaps those functions are not important, so maybe it doesn't really matter.

UPDATE:

I didn't look at your code block carefully, so Rz will feeding data into Z's axes[2] slot and there will be no axes[3] to worry about. SDL2-2.0.3's DX3 SDL_mmjoystick.c does the same thing, perhaps this should be reported to SDL's bug forums.

Which version of SDL was DOSBOX using? Seems like SDL2 can use either DX3 or DX5. I'm curious how the SDL DX5 code reacts to that controller.
Reply
#25
DOSBOX also uses SDL1.

I've tried some SDL2 games and it doesn't have the issue. Though it's probably because they use the more modern joystick handling instead. I think SDL2 has to be built with a special flag to use the old mmjoystick method.

I'll go report it anyways just for good measure.
Reply
#26
I hope DOSBOX upgrades to SDL2. Ya, it seems that either one or the other is compiled looking over these 3 files:

file: CMakeLists.txt

Code:
  if(SDL_JOYSTICK)
    if(HAVE_DINPUT_H)
      set(SDL_JOYSTICK_DINPUT 1)
      set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/joystick/windows/SDL_dxjoystick.c)
      list(APPEND EXTRA_LIBS dinput8 dxguid dxerr)
    else()
      set(SDL_JOYSTICK_WINMM 1)
      set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/joystick/windows/SDL_mmjoystick.c)
    endif()
    set(HAVE_SDL_JOYSTICK TRUE)
  endif()
 
file: configure

Code:
$as_echo "#define SDL_JOYSTICK_DINPUT 1" >>confdefs.h

                SOURCES="$SOURCES $srcdir/src/joystick/windows/SDL_dxjoystick.c"
                EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldinput8 -ldxguid -ldxerr8"
            else

$as_echo "#define SDL_JOYSTICK_WINMM 1" >>confdefs.h

                SOURCES="$SOURCES $srcdir/src/joystick/windows/SDL_mmjoystick.c"
            fi
            have_joystick=yes
        fi
        if test x$enable_haptic = xyes; then
            if test x$have_dinput = xyes; then

file: configure.in

Code:
        # Set up files for the joystick library
        if test x$enable_joystick = xyes; then
            if test x$have_dinput = xyes; then
                AC_DEFINE(SDL_JOYSTICK_DINPUT, 1, [ ])
                SOURCES="$SOURCES $srcdir/src/joystick/windows/SDL_dxjoystick.c"
                EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldinput8 -ldxguid -ldxerr8"
            else
                AC_DEFINE(SDL_JOYSTICK_WINMM, 1, [ ])
                SOURCES="$SOURCES $srcdir/src/joystick/windows/SDL_mmjoystick.c"
            fi
            have_joystick=yes
        fi

The way joysticks are coded in SDL you have to choose at compile time. For example: both SDL_dxjoystick.c and SDL_mmjoystick.c have their own definition of SDL_SYS_JoystickInit(void) . If SDL was coded differently I believe it would be possible to swap input source at run time.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)