From 5045f19259acfb87995d45d97eb21e334ecf82a8 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 13 Jun 2005 14:48:02 +0000 Subject: [PATCH] Add patch 1094730 from Jon Niehof. Added a time out event for the joystick.(fixes detection in certain games). Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2217 --- include/joystick.h | 14 +++ src/dosbox.cpp | 11 +- src/gui/sdl_mapper.cpp | 241 ++++++++++++++++++++++++++++++++++++-- src/hardware/joystick.cpp | 31 ++++- 4 files changed, 281 insertions(+), 16 deletions(-) diff --git a/include/joystick.h b/include/joystick.h index 88407ad7..b79666e3 100644 --- a/include/joystick.h +++ b/include/joystick.h @@ -16,6 +16,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: joystick.h,v 1.7 2005-06-13 14:48:01 qbix79 Exp $ */ +#ifndef DOSBOX_JOYSTICK_H +#define DOSBOX_JOYSTICK_H void JOYSTICK_Enable(Bitu which,bool enabled); void JOYSTICK_Button(Bitu which,Bitu num,bool pressed); @@ -31,3 +34,14 @@ bool JOYSTICK_GetButton(Bitu which, Bitu num); float JOYSTICK_GetMove_X(Bitu which); float JOYSTICK_GetMove_Y(Bitu which); + +enum JoystickType { + JOY_NONE, + JOY_2AXIS, + JOY_4AXIS, + JOY_FCS, + JOY_CH +}; + +extern JoystickType joytype; +#endif diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 6722a5c5..8d865c43 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.84 2005-04-21 21:17:45 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.85 2005-06-13 14:48:00 qbix79 Exp $ */ #include #include @@ -260,7 +260,6 @@ void DOSBOX_Init(void) { secprop->AddInitFunction(&DMA_Init);//done secprop->AddInitFunction(&VGA_Init); secprop->AddInitFunction(&KEYBOARD_Init); - secprop->AddInitFunction(&JOYSTICK_Init);//done secprop=control->AddSection_prop("mixer",&MIXER_Init); secprop->Add_bool("nosound",false); @@ -354,6 +353,14 @@ void DOSBOX_Init(void) { secprop=control->AddSection_prop("bios",&BIOS_Init,false);//done secprop->AddInitFunction(&INT10_Init); secprop->AddInitFunction(&MOUSE_Init); //Must be after int10 as it uses CurMode + secprop->AddInitFunction(&JOYSTICK_Init); + secprop->Add_string("joysticktype","2axis"); + MSG_Add("BIOS_CONFIGFILE_HELP", + "joysticktype -- Type of joystick to emulate: none, 2axis, 4axis,\n" + " fcs (Thrustmaster) ,ch (CH Flightstick).\n" + " none disables joystick emulation.\n" + " 2axis is the default and supports two joysticks.\n" + ); /* All the DOS Related stuff, which will eventually start up in the shell */ //TODO Maybe combine most of the dos stuff in one section like ems,xms diff --git a/src/gui/sdl_mapper.cpp b/src/gui/sdl_mapper.cpp index 3d100faa..ba3d94d7 100644 --- a/src/gui/sdl_mapper.cpp +++ b/src/gui/sdl_mapper.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: sdl_mapper.cpp,v 1.11 2005-02-10 10:21:07 qbix79 Exp $ */ +/* $Id: sdl_mapper.cpp,v 1.12 2005-06-13 14:48:02 qbix79 Exp $ */ #define OLD_JOYSTICK 1 @@ -346,7 +346,9 @@ public: hat_lists=new CBindList[hats]; #if OLD_JOYSTICK LOG_MSG("Using joystick %s with %d axes and %d buttons",SDL_JoystickName(stick),axes,buttons); - JOYSTICK_Enable(stick,true); + //if the first stick is set, we must be the second + emustick=JOYSTICK_IsEnabled(0); + JOYSTICK_Enable(emustick,true); #endif } ~CStickBindGroup() { @@ -380,7 +382,7 @@ public: return CreateButtonBind(event->jbutton.button); } else return 0; } - bool CheckEvent(SDL_Event * event) { + virtual bool CheckEvent(SDL_Event * event) { #if OLD_JOYSTICK SDL_JoyAxisEvent * jaxis = NULL; SDL_JoyButtonEvent * jbutton = NULL; @@ -388,18 +390,19 @@ public: switch(event->type) { case SDL_JOYAXISMOTION: jaxis = &event->jaxis; - if(jaxis->axis == 0) - JOYSTICK_Move_X(stick,(float)(jaxis->value/32768.0)); - else if(jaxis->axis == 1) - JOYSTICK_Move_Y(stick,(float)(jaxis->value/32768.0)); + if(jaxis->which == stick) + if(jaxis->axis == 0) + JOYSTICK_Move_X(emustick,(float)(jaxis->value/32768.0)); + else if(jaxis->axis == 1) + JOYSTICK_Move_Y(emustick,(float)(jaxis->value/32768.0)); break; case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: jbutton = &event->jbutton; bool state; state=jbutton->type==SDL_JOYBUTTONDOWN; - if (jbutton->button<2) { - JOYSTICK_Button(stick,jbutton->button,state); + if ((jbutton->which == stick) && (jbutton->button<2)) { + JOYSTICK_Button(emustick,jbutton->button,state); } break; } @@ -427,11 +430,201 @@ protected: CBindList * neg_axis_lists; CBindList * button_lists; CBindList * hat_lists; - Bitu stick,axes,buttons,hats; + Bitu stick,emustick,axes,buttons,hats; SDL_Joystick * sdl_joystick; char configname[10]; }; +class C4AxisBindGroup : public CStickBindGroup { +public: + C4AxisBindGroup(Bitu _stick) : CStickBindGroup (_stick){ +#if OLD_JOYSTICK + JOYSTICK_Enable(1,true); +#endif + } + bool CheckEvent(SDL_Event * event) { +#if OLD_JOYSTICK + SDL_JoyAxisEvent * jaxis = NULL; + SDL_JoyButtonEvent * jbutton = NULL; + + switch(event->type) { + case SDL_JOYAXISMOTION: + jaxis = &event->jaxis; + if(jaxis->which == stick && jaxis->axis < 4) + if(jaxis->axis & 1) + JOYSTICK_Move_Y(jaxis->axis>>1 & 1,(float)(jaxis->value/32768.0)); + else + JOYSTICK_Move_X(jaxis->axis>>1 & 1,(float)(jaxis->value/32768.0)); + break; + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + jbutton = &event->jbutton; + bool state; + state=jbutton->type==SDL_JOYBUTTONDOWN; + if ((jbutton->which == stick) && (jbutton->button<4)) { + JOYSTICK_Button((jbutton->button >> 1), + (jbutton->button & 1),state); + } + break; + } +#endif + return false; + } +}; + +class CFCSBindGroup : public CStickBindGroup { +public: + CFCSBindGroup(Bitu _stick) : CStickBindGroup (_stick){ +#if OLD_JOYSTICK + JOYSTICK_Enable(1,true); + JOYSTICK_Move_Y(1,1.0); +#endif + } + bool CheckEvent(SDL_Event * event) { +#if OLD_JOYSTICK + SDL_JoyAxisEvent * jaxis = NULL; + SDL_JoyButtonEvent * jbutton = NULL; + SDL_JoyHatEvent * jhat = NULL; + + switch(event->type) { + case SDL_JOYAXISMOTION: + jaxis = &event->jaxis; + if(jaxis->which == stick) + if(jaxis->axis == 0) + JOYSTICK_Move_X(0,(float)(jaxis->value/32768.0)); + else if(jaxis->axis == 1) + JOYSTICK_Move_Y(0,(float)(jaxis->value/32768.0)); + else if(jaxis->axis == 2) + JOYSTICK_Move_X(1,(float)(jaxis->value/32768.0)); + break; + case SDL_JOYHATMOTION: + jhat = &event->jhat; + if(jhat->which == stick) { + switch(jhat->value) { + case SDL_HAT_CENTERED: + JOYSTICK_Move_Y(1,1.0); + break; + case SDL_HAT_UP: + JOYSTICK_Move_Y(1,-1.0); + break; + case SDL_HAT_RIGHT: + JOYSTICK_Move_Y(1,-0.5); + break; + case SDL_HAT_DOWN: + JOYSTICK_Move_Y(1,0.0); + break; + case SDL_HAT_LEFT: + JOYSTICK_Move_Y(1,0.5); + break; + case SDL_HAT_LEFTUP: + if(JOYSTICK_GetMove_Y(1) < 0) + JOYSTICK_Move_Y(1,0.5); + else + JOYSTICK_Move_Y(1,-1.0); + break; + case SDL_HAT_RIGHTUP: + if(JOYSTICK_GetMove_Y(1) < -0.7) + JOYSTICK_Move_Y(1,-0.5); + else + JOYSTICK_Move_Y(1,-1.0); + break; + case SDL_HAT_RIGHTDOWN: + if(JOYSTICK_GetMove_Y(1) < -0.2) + JOYSTICK_Move_Y(1,0.0); + else + JOYSTICK_Move_Y(1,-0.5); + break; + case SDL_HAT_LEFTDOWN: + if(JOYSTICK_GetMove_Y(1) > 0.2) + JOYSTICK_Move_Y(1,0.0); + else + JOYSTICK_Move_Y(1,0.5); + break; + } + } + + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + jbutton = &event->jbutton; + bool state; + state=jbutton->type==SDL_JOYBUTTONDOWN; + if ((jbutton->which == stick) && (jbutton->button<4)) { + JOYSTICK_Button((jbutton->button >> 1), + (jbutton->button & 1),state); + } + break; + } +#endif + return false; + } +}; + +class CCHBindGroup : public CStickBindGroup { +public: + CCHBindGroup(Bitu _stick) : CStickBindGroup (_stick){ +#if OLD_JOYSTICK + JOYSTICK_Enable(1,true); + button_state=0; +#endif + } + bool CheckEvent(SDL_Event * event) { +#if OLD_JOYSTICK + SDL_JoyAxisEvent * jaxis = NULL; + SDL_JoyButtonEvent * jbutton = NULL; + SDL_JoyHatEvent * jhat = NULL; + static unsigned const button_magic[6]={0x02,0x04,0x10,0x100,0x20,0x200}; + static unsigned const hat_magic[2][5]={{0x8888,0x8000,0x800,0x80,0x08}, + {0x5440,0x4000,0x400,0x40,0x1000}}; + switch(event->type) { + case SDL_JOYAXISMOTION: + jaxis = &event->jaxis; + if(jaxis->which == stick && jaxis->axis < 4) + if(jaxis->axis & 1) + JOYSTICK_Move_Y(jaxis->axis>>1 & 1,(float)(jaxis->value/32768.0)); + else + JOYSTICK_Move_X(jaxis->axis>>1 & 1,(float)(jaxis->value/32768.0)); + break; + case SDL_JOYHATMOTION: + jhat = &event->jhat; + if(jhat->which == stick && jhat->hat < 2) { + if(jhat->value == SDL_HAT_CENTERED) + button_state&=~hat_magic[jhat->hat][0]; + if(jhat->value & SDL_HAT_UP) + button_state|=hat_magic[jhat->hat][1]; + if(jhat->value & SDL_HAT_RIGHT) + button_state|=hat_magic[jhat->hat][2]; + if(jhat->value & SDL_HAT_DOWN) + button_state|=hat_magic[jhat->hat][3]; + if(jhat->value & SDL_HAT_LEFT) + button_state|=hat_magic[jhat->hat][4]; + } + break; + case SDL_JOYBUTTONDOWN: + jbutton = &event->jbutton; + if ((jbutton->which == stick) && (jbutton->button<6)) + button_state|=button_magic[jbutton->button]; + break; + case SDL_JOYBUTTONUP: + jbutton = &event->jbutton; + if ((jbutton->which == stick) && (jbutton->button<6)) + button_state&=~button_magic[jbutton->button]; + break; + } + unsigned i; + Bit16u j; + j=button_state; + for(i=0;i<16;i++) if (j & 1) break; else j>>=1; + JOYSTICK_Button(0,0,i&0x01); + JOYSTICK_Button(0,1,i>>1&0x01); + JOYSTICK_Button(1,0,i>>2&0x01); + JOYSTICK_Button(1,1,i>>3&0x01); +#endif + + return false; + } +protected: + Bit16u button_state; +}; static struct { SDL_Surface * surface; @@ -1209,9 +1402,31 @@ void BIND_MappingEvents(void) { static void CreateBindGroups(void) { bindgroups.clear(); new CKeyBindGroup(SDLK_LAST); - Bitu numsticks=SDL_NumJoysticks(); - if (numsticks) SDL_JoystickEventState(SDL_ENABLE); - for (Bitu i=0;i #include "dosbox.h" #include "inout.h" #include "setup.h" +#include "joystick.h" +#include "pic.h" #define RANGE 64 +#define TIMEOUT 10 struct JoyStick { bool enabled; @@ -29,11 +35,23 @@ struct JoyStick { bool button[2]; }; - +JoystickType joytype; static JoyStick stick[2]; +static Bit32u last_write = 0; +static bool write_active = false; static Bitu read_p201(Bitu port,Bitu iolen) { + /* Reset Joystick to 0 after TIMEOUT ms */ + if(write_active && ((PIC_Ticks - last_write) > TIMEOUT)) { + write_active = false; + stick[0].xcount = 0; + stick[1].xcount = 0; + stick[0].ycount = 0; + stick[1].ycount = 0; +// LOG_MSG("reset by time %d %d",PIC_Ticks,last_write); + } + /** Format of the byte to be returned: ** | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ** +-------------------------------+ @@ -60,6 +78,9 @@ static Bitu read_p201(Bitu port,Bitu iolen) { } static void write_p201(Bitu port,Bitu val,Bitu iolen) { + /* Store writetime index */ + write_active = true; + last_write = PIC_Ticks; if (stick[0].enabled) { stick[0].xcount=(Bitu)((stick[0].xpos*RANGE)+RANGE); stick[0].ycount=(Bitu)((stick[0].ypos*RANGE)+RANGE); @@ -121,6 +142,14 @@ private: IO_WriteHandleObject WriteHandler; public: JOYSTICK(Section* configuration):Module_base(configuration){ + Section_prop * section=static_cast(configuration); + const char * type=section->Get_string("joysticktype"); + if (!strcasecmp(type,"none")) joytype=JOY_NONE; + else if (!strcasecmp(type,"2axis")) joytype=JOY_2AXIS; + else if (!strcasecmp(type,"4axis")) joytype=JOY_4AXIS; + else if (!strcasecmp(type,"fcs")) joytype=JOY_FCS; + else if (!strcasecmp(type,"ch")) joytype=JOY_CH; + else joytype=JOY_2AXIS; ReadHandler.Install(0x201,read_p201,IO_MB); WriteHandler.Install(0x201,write_p201,IO_MB); stick[0].enabled=false;