mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-15 07:00:58 +00:00
Merge pull request #209 from Wintermute0110/master
SDL joystick input handling implementation
This commit is contained in:
commit
c6f4ffc7e6
8 changed files with 633 additions and 24 deletions
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -27,3 +27,11 @@ base/sound/
|
|||
base/strings/
|
||||
base/video/
|
||||
base/wads/
|
||||
|
||||
GPATH
|
||||
GRTAGS
|
||||
GSYMS
|
||||
GTAGS
|
||||
HTML/
|
||||
neo/.kdev4
|
||||
neo/neo.kdev4
|
||||
|
|
234
README.SDL_Joystick
Normal file
234
README.SDL_Joystick
Normal file
|
@ -0,0 +1,234 @@
|
|||
This file documents the use of a joystick/gamepad under Linux with RBDoom3-BFG.
|
||||
Joystick support has been tested with an XBox 360 wireless and a
|
||||
Logitech F710 wireless gamepads, but in theory should work with any XBox 360
|
||||
compatible gamepad, either wireless or wired/USB.
|
||||
|
||||
To use the gamepad follow this instructions,
|
||||
|
||||
a) Make sure your joystick is detected by Linux.
|
||||
|
||||
One way to check this is to look for jsN files under /dev/input/, where
|
||||
N is a number. For example, /dev/input/js0 is the first joystick,
|
||||
/dev/input/js1 the second one, and so on. Executing the following command you
|
||||
should see something like this:
|
||||
|
||||
$ ls -l /dev/input/js*
|
||||
crw-rw-r--+ 1 root input 13, 0 Nov 20 04:39 /dev/input/js0
|
||||
|
||||
Another way to check is to use the udevadm monitor command. This is what happens
|
||||
when you connect a USB joystick (launch udevadm and then connect the gamepad or
|
||||
the wireless receiver):
|
||||
|
||||
$ udevadm monitor -u
|
||||
monitor will print the received events for:
|
||||
UDEV - the event which udev sends out after rule processing
|
||||
|
||||
UDEV [14503.227311] add /devices/pci0000:00/0000:00:1d.0/usb5/5-2 (usb)
|
||||
UDEV [14504.551280] add /devices/pci0000:00/0000:00:1d.0/usb5/5-2/5-2:1.0 (usb)
|
||||
UDEV [14504.553328] add /devices/pci0000:00/0000:00:1d.0/usb5/5-2/5-2:1.0/input/input22 (input)
|
||||
UDEV [14504.555805] add /devices/pci0000:00/0000:00:1d.0/usb5/5-2/5-2:1.0/input/input22/event19 (input)
|
||||
UDEV [14504.565611] add /devices/pci0000:00/0000:00:1d.0/usb5/5-2/5-2:1.0/input/input22/js0 (input)
|
||||
|
||||
The program jstest allows you to check if your joystick works OK:
|
||||
|
||||
$ jstest /dev/input/js0
|
||||
Driver version is 2.1.0.
|
||||
Joystick (Xbox 360 Wireless Receiver) has 6 axes (X, Y, Z, Rx, Ry, Rz)
|
||||
and 15 buttons (BtnX, BtnY, BtnTL, BtnTR, BtnTR2, BtnSelect, BtnThumbL, BtnThumbR, ....
|
||||
Testing ... (interrupt to exit)
|
||||
|
||||
Every time you press a button or move an axis you should see the changes printed on
|
||||
the screen. Press CTRL+C to end jstest.
|
||||
|
||||
No matter how many joysticks you have, RBDoom3-BFG only uses the first
|
||||
joystick named /dev/input/js0.
|
||||
|
||||
b) Make sure RBDoom3-BFG detects and is able to use your joystick.
|
||||
|
||||
Execute RBDoom3-BFG in a console/terminal to see the messages printed there. If
|
||||
your joystick is correctly detected you should see something like this:
|
||||
|
||||
$ ./RBDoom3BFG
|
||||
|
||||
... lots of text ...
|
||||
|
||||
----- R_InitOpenGL -----
|
||||
Initializing OpenGL subsystem
|
||||
Using 8 color bits, 24 depth, 8 stencil display
|
||||
Using GLEW 1.10.0
|
||||
Sys_InitInput: Joystick subsystem init
|
||||
Sys_InitInput: Joystic - Found 4 joysticks
|
||||
Opened Joystick 0
|
||||
Name: Xbox 360 Wireless Receiver
|
||||
Number of Axes: 6
|
||||
Number of Buttons: 15
|
||||
Number of Hats: 0
|
||||
Number of Balls: 0
|
||||
|
||||
... more text ...
|
||||
|
||||
If the number of detected joysticks is 0 and none is opened check again
|
||||
a) and make sure the file /dev/input/js0 is there (for example, if you
|
||||
are using a wireless joystick make sure the gamepad is ON and not
|
||||
in sleeping mode when you run RBDoom3-BFG) and that you have permissions
|
||||
to read that file (for example, in Debian users that want to use the
|
||||
joystick must be added to the group input).
|
||||
|
||||
c) Set the bindings of your joystick.
|
||||
|
||||
You can use the Doom3 console to set the bindings. To bind a joystick
|
||||
button/axis to a game action, press the tilde key (just below ESC) to
|
||||
show the Doom3 console. Then type:
|
||||
|
||||
] bind <key_name> <action>
|
||||
|
||||
For example, this binds gamepad button 0 with the action "jump":
|
||||
|
||||
] bind JOY1 _moveup
|
||||
|
||||
Apendix A gives you a list of the gamepad axis/button names and the
|
||||
possible actions you can bind to them.
|
||||
|
||||
Alternatively, you can use configuration files to set the bindings
|
||||
automatically. Copy the files joy_righty.cfg, joy_lefty.cfg and joy_360_0.cfg
|
||||
to your Doom3 base directory. You can find these files in Appendix B at the
|
||||
bottom of this file.
|
||||
|
||||
d) Enjoy!
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
TODO/BUGS
|
||||
|
||||
* Only XBox 360 gamepad clones are supported at the moment.
|
||||
|
||||
* SDL axis/keycode numbers are hard-coded to Doom3 axis/keycode names.
|
||||
Depending of your gamepad model maybe this will produce unwanted results.
|
||||
It is not clear at the moment how to remap this (configuration file, GUI, ...).
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
Apendix A) Doom3 joystick key names and key bindings
|
||||
|
||||
This is a list of the supported key/axis names. Note that the names of the
|
||||
buttons are only valid for the XBox 360 wireless gamepad. Other gamepads
|
||||
may have different names depending on the gamepad layout and/or more buttons
|
||||
available so you can map more actions. Also note that RBDoom3-BFG treats
|
||||
the back triggers like buttons rather that axes.
|
||||
|
||||
JOY1 (A button)
|
||||
JOY2 (B/Circle button)
|
||||
JOY3 (X/Square button)
|
||||
JOY4 (Y/Triangle button)
|
||||
JOY5 (L Shoulder)
|
||||
JOY6 (R Shoulder)
|
||||
JOY7 (BACK)
|
||||
JOY8 (START)
|
||||
JOY9 (XBOX button)
|
||||
JOY10 (LEFT ANALOG JOY BUTTON)
|
||||
JOY11 (RIGHT ANALOG JOY BUTTON)
|
||||
|
||||
JOY_TRIGGER1 (LEFT TRIGGER)
|
||||
JOY_TRIGGER2 (RIGHT TRIGGER)
|
||||
|
||||
JOY_DPAD_RIGHT (D-PAD ANALOG JOYSTIC UP)
|
||||
JOY_DPAD_LEFT (D-PAD ANALOG JOYSTIC DOWN)
|
||||
JOY_DPAD_UP (D-PAD ANALOG JOYSTIC LEFT)
|
||||
JOY_DPAD_DOWN (D-PAD ANALOG JOYSTIC RIGHT)
|
||||
|
||||
JOY_STICK1_UP (RIGHT ANALOG JOYSTIC UP)
|
||||
JOY_STICK1_DOWN (RIGHT ANALOG JOYSTIC DOWN)
|
||||
JOY_STICK1_LEFT (RIGHT ANALOG JOYSTIC LEFT)
|
||||
JOY_STICK1_RIGHT (RIGHT ANALOG JOYSTIC RIGHT)
|
||||
JOY_STICK2_UP (LEFT ANALOG JOYSTIC UP)
|
||||
JOY_STICK2_DOWN (LEFT ANALOG JOYSTIC DOWN)
|
||||
JOY_STICK2_LEFT (LEFT ANALOG JOYSTIC LEFT)
|
||||
JOY_STICK2_RIGHT (LEFT ANALOG JOYSTIC RIGHT)
|
||||
|
||||
This is a list of commands that can be binded in Doom3. This commands are
|
||||
only valid in-game, the GUI uses its own set of hard-coded key bindings. Note
|
||||
that commands having spaces in between (more than one word) must be quoted "":
|
||||
|
||||
_impulse0 Fists / Grabber
|
||||
_impulse2 Pistol
|
||||
_impulse3 Shotgun / Double shotgun (Doomclassic)
|
||||
_impulse5 Machinegun
|
||||
_impulse6 Chaingun
|
||||
_impulse7 Grenades
|
||||
_impulse8 Plasma Gun
|
||||
_impulse9 Rockets
|
||||
_impulse10 BFG 9000
|
||||
_impulse12 Soulcube / Artifact
|
||||
_impulse13 Reload weapon
|
||||
_impulse14 Previous weapon
|
||||
_impulse15 Next weapon
|
||||
_impulse16 Flashlight
|
||||
_impulse19 PDA / Scoreboard
|
||||
|
||||
_attack Fire / Melee
|
||||
_use Use / Action
|
||||
_speed Run
|
||||
|
||||
_forward Move forward
|
||||
_back Move backwards
|
||||
_moveleft Move left
|
||||
_moveright Move right
|
||||
_moveup Jump
|
||||
_movedown Crouch
|
||||
_left Look left
|
||||
_right Look right
|
||||
_lookup Look up
|
||||
_lookdown Look down
|
||||
|
||||
"savegame quick" Quick Save
|
||||
"loadgame quick" Quick Load
|
||||
"screenshot" Take screenshot
|
||||
|
||||
Apendix B) Joystick bindings
|
||||
|
||||
-- joy_righty.cfg --------------------------------------------------------
|
||||
bind "JOY_STICK1_UP" "_forward"
|
||||
bind "JOY_STICK1_DOWN" "_back"
|
||||
bind "JOY_STICK1_LEFT" "_moveleft"
|
||||
bind "JOY_STICK1_RIGHT" "_moveright"
|
||||
|
||||
bind "JOY_STICK2_UP" "_lookup"
|
||||
bind "JOY_STICK2_DOWN" "_lookdown"
|
||||
bind "JOY_STICK2_LEFT" "_left"
|
||||
bind "JOY_STICK2_RIGHT" "_right"
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
-- joy_lefty.cfg ---------------------------------------------------------
|
||||
bind "JOY_STICK2_UP" "_forward"
|
||||
bind "JOY_STICK2_DOWN" "_back"
|
||||
bind "JOY_STICK2_LEFT" "_moveleft"
|
||||
bind "JOY_STICK2_RIGHT" "_moveright"
|
||||
|
||||
bind "JOY_STICK1_UP" "_lookup"
|
||||
bind "JOY_STICK1_DOWN" "_lookdown"
|
||||
bind "JOY_STICK1_LEFT" "_left"
|
||||
bind "JOY_STICK1_RIGHT" "_right"
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
-- joy_360_0.cfg ---------------------------------------------------------
|
||||
bind "JOY_DPAD_RIGHT" "_impulse5" // Put your favourite weapons here
|
||||
bind "JOY_DPAD_LEFT" "_impulse12" // for quick access.
|
||||
bind "JOY_DPAD_UP" "_impulse6"
|
||||
bind "JOY_DPAD_DOWN" "_impulse8"
|
||||
|
||||
bind "JOY_TRIGGER1" "_impulse16"
|
||||
bind "JOY_TRIGGER2" "_attack"
|
||||
|
||||
bind "JOY1" "_moveup" // (A/X button)
|
||||
bind "JOY2" "" // (B/Circle button)
|
||||
bind "JOY3" "_impulse13" // (X/Square button)
|
||||
bind "JOY4" "_use" // (Y/Triangle button)
|
||||
|
||||
bind "JOY5" "_impulse15" // (L Shoulder)
|
||||
bind "JOY6" "_impulse14" // (R Shoulder)
|
||||
|
||||
bind "JOY7" "_impulse19" // (BACK)
|
||||
bind "JOY8" "" // (START) (Used to show the game GUI)
|
||||
bind "JOY9" "" // (XBOX)
|
||||
|
||||
bind "JOY10" "_speed" // (LEFT ANALOG JOY BUTTON)
|
||||
bind "JOY11" "_movedown" // (RIGHT ANALOG JOY BUTTON)
|
||||
--------------------------------------------------------------------------
|
5
neo/cmake-linux-debug.sh
Executable file
5
neo/cmake-linux-debug.sh
Executable file
|
@ -0,0 +1,5 @@
|
|||
cd ..
|
||||
rm -rf build
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug ../neo
|
|
@ -2,4 +2,4 @@ cd ..
|
|||
rm -rf build
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DSDL2=OFF ../neo
|
||||
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DONATIVE=ON ../neo
|
||||
|
|
|
@ -551,6 +551,19 @@ void idCmdSystemLocal::ExecuteTokenizedString( const idCmdArgs& args )
|
|||
return; // no tokens
|
||||
}
|
||||
|
||||
// DEBUG: print commands executed by the console
|
||||
/*
|
||||
if(args.Argc() == 1) {
|
||||
common->Printf("idCmdSystemLocal::ExecuteTokenizedString: '%s'\n", args.Argv( 0 ));
|
||||
}
|
||||
else if(args.Argc() == 2) {
|
||||
common->Printf("idCmdSystemLocal::ExecuteTokenizedString: '%s' '%s'\n", args.Argv( 0 ), args.Argv( 1 ));
|
||||
}
|
||||
else if(args.Argc() == 3) {
|
||||
common->Printf("idCmdSystemLocal::ExecuteTokenizedString: '%s' '%s' '%s'\n", args.Argv( 0 ), args.Argv( 1 ), args.Argv( 2 ));
|
||||
}
|
||||
*/
|
||||
|
||||
// check registered command functions
|
||||
for( prev = &commands; *prev; prev = &cmd->next )
|
||||
{
|
||||
|
|
|
@ -436,11 +436,13 @@ void idPlayerProfile::ExecConfig( bool save, bool forceDefault )
|
|||
|
||||
if( leftyFlip )
|
||||
{
|
||||
cmdSystem->AppendCommandText( "exec joy_lefty.cfg" );
|
||||
cmdSystem->AppendCommandText( "exec joy_lefty.cfg\n" );
|
||||
cmdSystem->AppendCommandText( "exec joy_360_0.cfg\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
cmdSystem->AppendCommandText( "exec joy_righty.cfg" );
|
||||
cmdSystem->AppendCommandText( "exec joy_righty.cfg\n" );
|
||||
cmdSystem->AppendCommandText( "exec joy_360_0.cfg\n" );
|
||||
}
|
||||
|
||||
cmdSystem->ExecuteCommandBuffer();
|
||||
|
|
|
@ -1423,7 +1423,11 @@ idUsercmdGenLocal::Joystick
|
|||
void idUsercmdGenLocal::Joystick( int deviceNum )
|
||||
{
|
||||
int numEvents = Sys_PollJoystickInputEvents( deviceNum );
|
||||
|
||||
|
||||
// if(numEvents) {
|
||||
// common->Printf("idUsercmdGenLocal::Joystick: numEvents = %i\n", numEvents);
|
||||
// }
|
||||
|
||||
// Study each of the buffer elements and process them.
|
||||
for( int i = 0; i < numEvents; i++ )
|
||||
{
|
||||
|
@ -1431,6 +1435,8 @@ void idUsercmdGenLocal::Joystick( int deviceNum )
|
|||
int value;
|
||||
if( Sys_ReturnJoystickInputEvent( i, action, value ) )
|
||||
{
|
||||
// common->Printf("idUsercmdGenLocal::Joystick: i = %i / action = %i / value = %i\n", i, action, value);
|
||||
|
||||
if( action >= J_ACTION1 && action <= J_ACTION_MAX )
|
||||
{
|
||||
int joyButton = K_JOY1 + ( action - J_ACTION1 );
|
||||
|
|
|
@ -116,6 +116,25 @@ struct mouse_poll_t
|
|||
static idList<kbd_poll_t> kbd_polls;
|
||||
static idList<mouse_poll_t> mouse_polls;
|
||||
|
||||
struct joystick_poll_t
|
||||
{
|
||||
int action;
|
||||
int value;
|
||||
|
||||
joystick_poll_t()
|
||||
{
|
||||
}
|
||||
|
||||
joystick_poll_t( int a, int v )
|
||||
{
|
||||
action = a;
|
||||
value = v;
|
||||
}
|
||||
};
|
||||
static idList<joystick_poll_t> joystick_polls;
|
||||
SDL_Joystick *joy = NULL;
|
||||
int SDL_joystick_has_hat = 0;
|
||||
|
||||
// RB begin
|
||||
static int SDL_KeyToDoom3Key( SDL_Keycode key, bool& isChar )
|
||||
{
|
||||
|
@ -551,6 +570,8 @@ Sys_InitInput
|
|||
*/
|
||||
void Sys_InitInput()
|
||||
{
|
||||
int numJoysticks, i;
|
||||
|
||||
kbd_polls.SetGranularity( 64 );
|
||||
mouse_polls.SetGranularity( 64 );
|
||||
|
||||
|
@ -558,8 +579,54 @@ void Sys_InitInput()
|
|||
SDL_EnableUNICODE( 1 );
|
||||
SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL );
|
||||
#endif
|
||||
|
||||
in_keyboard.SetModified();
|
||||
|
||||
// WM0110: Initialise SDL Joystick
|
||||
common->Printf( "Sys_InitInput: Joystick subsystem init\n" );
|
||||
if( SDL_Init(SDL_INIT_JOYSTICK) ) {
|
||||
common->Printf( "Sys_InitInput: Joystic Init ERROR!\n");
|
||||
}
|
||||
|
||||
numJoysticks = SDL_NumJoysticks();
|
||||
common->Printf( "Sys_InitInput: Joystic - Found %i joysticks\n", numJoysticks);
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
for(i=0; i<numJoysticks; i++)
|
||||
common->Printf(" Joystick %i name '%s'\n", i, SDL_JoystickName(i));
|
||||
#endif
|
||||
|
||||
// Open first available joystick and use it
|
||||
if(SDL_NumJoysticks() > 0) {
|
||||
joy = SDL_JoystickOpen(0);
|
||||
|
||||
if(joy) {
|
||||
int num_hats;
|
||||
|
||||
num_hats = SDL_JoystickNumHats(joy);
|
||||
common->Printf("Opened Joystick number 0\n");
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
common->Printf("Name: %s\n", SDL_JoystickName(joy));
|
||||
#else
|
||||
common->Printf("Name: %s\n", SDL_JoystickName(0));
|
||||
#endif
|
||||
common->Printf("Number of Axes: %d\n", SDL_JoystickNumAxes(joy));
|
||||
common->Printf("Number of Buttons: %d\n", SDL_JoystickNumButtons(joy));
|
||||
common->Printf("Number of Hats: %d\n", num_hats);
|
||||
common->Printf("Number of Balls: %d\n", SDL_JoystickNumBalls(joy));
|
||||
|
||||
SDL_joystick_has_hat = 0;
|
||||
if(num_hats) {
|
||||
SDL_joystick_has_hat = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
joy = NULL;
|
||||
common->Printf("Couldn't open Joystick 0\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
joy = NULL;
|
||||
}
|
||||
// WM0110
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -571,6 +638,15 @@ void Sys_ShutdownInput()
|
|||
{
|
||||
kbd_polls.Clear();
|
||||
mouse_polls.Clear();
|
||||
joystick_polls.Clear();
|
||||
|
||||
// Close any opened SDL Joystic
|
||||
if(joy) {
|
||||
common->Printf("Sys_ShutdownInput: closing SDL joystick.\n");
|
||||
SDL_JoystickClose(joy);
|
||||
} else {
|
||||
common->Printf("Sys_ShutdownInput: SDL joystick not initialized. Nothing to close.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -681,9 +757,11 @@ sysEvent_t Sys_GetEvent()
|
|||
SDL_Event ev;
|
||||
sysEvent_t res = { };
|
||||
int key;
|
||||
|
||||
static const sysEvent_t res_none = { SE_NONE, 0, 0, 0, NULL };
|
||||
|
||||
|
||||
// WM0110: previous state of joystick hat
|
||||
static int previous_hat_state = SDL_HAT_CENTERED;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
static char* s = NULL;
|
||||
static size_t s_pos = 0;
|
||||
|
@ -870,7 +948,7 @@ sysEvent_t Sys_GetEvent()
|
|||
// DG end
|
||||
#endif
|
||||
|
||||
// fall through
|
||||
// fall through
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
bool isChar;
|
||||
|
@ -990,7 +1068,7 @@ sysEvent_t Sys_GetEvent()
|
|||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
res.evType = SE_KEY;
|
||||
|
||||
|
||||
switch( ev.button.button )
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
|
@ -1019,15 +1097,264 @@ sysEvent_t Sys_GetEvent()
|
|||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
res.evValue2 = ev.button.state == SDL_PRESSED ? 1 : 0;
|
||||
|
||||
return res;
|
||||
|
||||
|
||||
// WM0110
|
||||
// NOTE: it seems that the key bindings for the GUI and for the game are
|
||||
// totally independant. I think the event returned by this function seems to work
|
||||
// on the GUI and the event returned by Sys_ReturnJoystickInputEvent() works on
|
||||
// the game.
|
||||
// Also, remember that joystick keys must be binded to actions in order to work!
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
case SDL_JOYBUTTONUP:
|
||||
// sys_public.h: evValue is an axis number and evValue2 is the current state (-127 to 127)
|
||||
// WM0110: joystick ranges must be between (-32769, 32768)!
|
||||
res.evType = SE_KEY;
|
||||
switch( ev.jbutton.button )
|
||||
{
|
||||
case 0:
|
||||
res.evValue = K_JOY1;
|
||||
joystick_polls.Append( joystick_poll_t( J_ACTION1, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
res.evValue = K_JOY2;
|
||||
joystick_polls.Append( joystick_poll_t( J_ACTION2, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
res.evValue = K_JOY3;
|
||||
joystick_polls.Append( joystick_poll_t( J_ACTION3, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
break;
|
||||
|
||||
case 3:
|
||||
res.evValue = K_JOY4;
|
||||
joystick_polls.Append( joystick_poll_t( J_ACTION4, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
break;
|
||||
|
||||
case 4:
|
||||
res.evValue = K_JOY5;
|
||||
joystick_polls.Append( joystick_poll_t( J_ACTION5, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
break;
|
||||
|
||||
case 5:
|
||||
res.evValue = K_JOY6;
|
||||
joystick_polls.Append( joystick_poll_t( J_ACTION6, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
break;
|
||||
|
||||
case 6:
|
||||
res.evValue = K_JOY7;
|
||||
joystick_polls.Append( joystick_poll_t( J_ACTION7, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
break;
|
||||
|
||||
case 7:
|
||||
res.evValue = K_JOY8;
|
||||
joystick_polls.Append( joystick_poll_t( J_ACTION8, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
break;
|
||||
|
||||
case 8:
|
||||
res.evValue = K_JOY9;
|
||||
joystick_polls.Append( joystick_poll_t( J_ACTION9, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
break;
|
||||
|
||||
case 9:
|
||||
res.evValue = K_JOY10;
|
||||
joystick_polls.Append( joystick_poll_t( J_ACTION10, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
break;
|
||||
|
||||
case 10:
|
||||
res.evValue = K_JOY11;
|
||||
joystick_polls.Append( joystick_poll_t( J_ACTION11, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
break;
|
||||
|
||||
// D-PAD left (XBox 360 wireless)
|
||||
case 11:
|
||||
// If joystick has a hat, then use the hat as D-PAD. If not, D-PAD is mapped
|
||||
// to buttons.
|
||||
if(SDL_joystick_has_hat) {
|
||||
res.evValue = K_JOY12;
|
||||
joystick_polls.Append( joystick_poll_t( J_ACTION12, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
} else {
|
||||
res.evValue = K_JOY_DPAD_LEFT;
|
||||
joystick_polls.Append( joystick_poll_t( J_DPAD_LEFT, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
}
|
||||
break;
|
||||
|
||||
// D-PAD right
|
||||
case 12:
|
||||
if(SDL_joystick_has_hat) {
|
||||
res.evValue = K_JOY13;
|
||||
joystick_polls.Append( joystick_poll_t( J_ACTION13, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
} else {
|
||||
res.evValue = K_JOY_DPAD_RIGHT;
|
||||
joystick_polls.Append( joystick_poll_t( J_DPAD_RIGHT, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
}
|
||||
break;
|
||||
|
||||
// D-PAD up
|
||||
case 13:
|
||||
if(SDL_joystick_has_hat) {
|
||||
res.evValue = K_JOY14;
|
||||
joystick_polls.Append( joystick_poll_t( J_ACTION14, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
} else {
|
||||
res.evValue = K_JOY_DPAD_UP;
|
||||
joystick_polls.Append( joystick_poll_t( J_DPAD_UP, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
}
|
||||
break;
|
||||
|
||||
// D-PAD down
|
||||
case 14:
|
||||
if(SDL_joystick_has_hat) {
|
||||
res.evValue = K_JOY15;
|
||||
joystick_polls.Append( joystick_poll_t( J_ACTION15, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
} else {
|
||||
res.evValue = K_JOY_DPAD_DOWN;
|
||||
joystick_polls.Append( joystick_poll_t( J_DPAD_DOWN, ev.jbutton.state == SDL_PRESSED ? 1 : 0 ) );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
common->Warning( "Sys_GetEvent(): Unknown joystick button number %i\n", ev.jbutton.button );
|
||||
return res_none;
|
||||
}
|
||||
res.evValue2 = ev.jbutton.state == SDL_PRESSED ? 1 : 0;
|
||||
|
||||
return res;
|
||||
|
||||
case SDL_JOYHATMOTION:
|
||||
// If this is not the first hat, ignore this event.
|
||||
if(ev.jhat.which != 0)
|
||||
return res_none;
|
||||
|
||||
res.evType = SE_KEY;
|
||||
if(ev.jhat.value & SDL_HAT_UP) {
|
||||
res.evValue = K_JOY_DPAD_UP;
|
||||
joystick_polls.Append( joystick_poll_t( J_DPAD_UP, 1 ) );
|
||||
res.evValue2 = 1;
|
||||
previous_hat_state = J_DPAD_UP;
|
||||
}
|
||||
else if (ev.jhat.value & SDL_HAT_DOWN) {
|
||||
res.evValue = K_JOY_DPAD_DOWN;
|
||||
joystick_polls.Append( joystick_poll_t( J_DPAD_DOWN, 1 ) );
|
||||
res.evValue2 = 1;
|
||||
previous_hat_state = J_DPAD_DOWN;
|
||||
}
|
||||
else if (ev.jhat.value & SDL_HAT_RIGHT) {
|
||||
res.evValue = K_JOY_DPAD_RIGHT;
|
||||
joystick_polls.Append( joystick_poll_t( J_DPAD_RIGHT, 1 ) );
|
||||
res.evValue2 = 1;
|
||||
previous_hat_state = J_DPAD_RIGHT;
|
||||
}
|
||||
else if (ev.jhat.value & SDL_HAT_LEFT) {
|
||||
res.evValue = K_JOY_DPAD_LEFT;
|
||||
joystick_polls.Append( joystick_poll_t( J_DPAD_LEFT, 1 ) );
|
||||
res.evValue2 = 1;
|
||||
previous_hat_state = J_DPAD_LEFT;
|
||||
}
|
||||
// SDL_HAT_CENTERED is defined as 0
|
||||
else if (ev.jhat.value == SDL_HAT_CENTERED) {
|
||||
// We need to know the previous state to know which event to send.
|
||||
if(previous_hat_state == J_DPAD_UP) {
|
||||
res.evValue = K_JOY_DPAD_UP;
|
||||
joystick_polls.Append( joystick_poll_t( J_DPAD_UP, 0 ) );
|
||||
res.evValue2 = 0;
|
||||
}
|
||||
else if(previous_hat_state == J_DPAD_DOWN) {
|
||||
res.evValue = K_JOY_DPAD_DOWN;
|
||||
joystick_polls.Append( joystick_poll_t( J_DPAD_DOWN, 0 ) );
|
||||
res.evValue2 = 0;
|
||||
}
|
||||
else if(previous_hat_state == J_DPAD_RIGHT) {
|
||||
res.evValue = K_JOY_DPAD_RIGHT;
|
||||
joystick_polls.Append( joystick_poll_t( J_DPAD_RIGHT, 0 ) );
|
||||
res.evValue2 = 0;
|
||||
}
|
||||
else if(previous_hat_state == J_DPAD_LEFT) {
|
||||
res.evValue = K_JOY_DPAD_LEFT;
|
||||
joystick_polls.Append( joystick_poll_t( J_DPAD_LEFT, 0 ) );
|
||||
res.evValue2 = 0;
|
||||
}
|
||||
else if(previous_hat_state == SDL_HAT_CENTERED) {
|
||||
common->Warning( "Sys_GetEvent(): SDL_JOYHATMOTION: previous state SDL_HAT_CENTERED repeated!\n" );
|
||||
return res_none;
|
||||
}
|
||||
else {
|
||||
common->Warning( "Sys_GetEvent(): SDL_JOYHATMOTION: unknown previous hat state %i\n", previous_hat_state );
|
||||
return res_none;
|
||||
}
|
||||
|
||||
previous_hat_state = SDL_HAT_CENTERED;
|
||||
}
|
||||
else {
|
||||
common->Warning( "Sys_GetEvent(): Unknown SDL_JOYHATMOTION value %i\n", ev.jhat.value );
|
||||
return res_none;
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
case SDL_JOYAXISMOTION:
|
||||
res.evType = SE_JOYSTICK;
|
||||
// SDL joystick range is: -32768 to 32767, which is what is expected
|
||||
// in void idUsercmdGenLocal::Joystick( int deviceNum ).
|
||||
switch( ev.jaxis.axis )
|
||||
{
|
||||
int trigger_value;
|
||||
|
||||
// LEFT trigger
|
||||
case 2:
|
||||
// Convert TRIGGER value from space (-32768, 32767) to (0, 32767)
|
||||
trigger_value = (ev.jaxis.value + 32768) / 2;
|
||||
// common->Printf("Sys_GetEvent: LEFT trigger value = %i / converted value = %i\n", ev.jaxis.value, trigger_value);
|
||||
res.evValue = J_AXIS_LEFT_TRIG;
|
||||
joystick_polls.Append( joystick_poll_t( J_AXIS_LEFT_TRIG, trigger_value ) );
|
||||
break;
|
||||
|
||||
// Right trigger
|
||||
case 5:
|
||||
trigger_value = (ev.jaxis.value + 32768) / 2;
|
||||
// common->Printf("Sys_GetEvent: RIGHT trigger value = %i / converted value = %i\n", ev.jaxis.value, trigger_value);
|
||||
res.evValue = J_AXIS_RIGHT_TRIG;
|
||||
joystick_polls.Append( joystick_poll_t( J_AXIS_RIGHT_TRIG, trigger_value ) );
|
||||
break;
|
||||
|
||||
// LEFT X
|
||||
case 0:
|
||||
res.evValue = J_AXIS_LEFT_X;
|
||||
joystick_polls.Append( joystick_poll_t( J_AXIS_LEFT_X, ev.jaxis.value ) );
|
||||
break;
|
||||
|
||||
// LEFT Y
|
||||
case 1:
|
||||
res.evValue = J_AXIS_LEFT_Y;
|
||||
joystick_polls.Append( joystick_poll_t( J_AXIS_LEFT_Y, ev.jaxis.value ) );
|
||||
break;
|
||||
|
||||
// RIGHT X
|
||||
case 3:
|
||||
res.evValue = J_AXIS_RIGHT_X;
|
||||
joystick_polls.Append( joystick_poll_t( J_AXIS_RIGHT_X, ev.jaxis.value ) );
|
||||
break;
|
||||
|
||||
// RIGHT Y
|
||||
case 4:
|
||||
res.evValue = J_AXIS_RIGHT_Y;
|
||||
joystick_polls.Append( joystick_poll_t( J_AXIS_RIGHT_Y, ev.jaxis.value ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
common->Warning( "Sys_GetEvent(): Unknown joystick axis number %i\n", ev.jaxis.axis );
|
||||
return res_none;
|
||||
}
|
||||
|
||||
return res;
|
||||
// WM0110
|
||||
|
||||
case SDL_QUIT:
|
||||
PushConsoleEvent( "quit" );
|
||||
return res_none;
|
||||
|
||||
|
||||
case SDL_USEREVENT:
|
||||
switch( ev.user.code )
|
||||
{
|
||||
|
@ -1036,16 +1363,18 @@ sysEvent_t Sys_GetEvent()
|
|||
res.evPtrLength = ( intptr_t )ev.user.data1;
|
||||
res.evPtr = ev.user.data2;
|
||||
return res;
|
||||
|
||||
default:
|
||||
common->Warning( "unknown user event %u", ev.user.code );
|
||||
common->Warning( "Sys_GetEvent: unknown SDL_USEREVENT %u", ev.user.code );
|
||||
return res_none;
|
||||
}
|
||||
|
||||
default:
|
||||
common->Warning( "unknown event %u", ev.type );
|
||||
common->Warning( "Sys_GetEvent: unknown SDL event %u", ev.type );
|
||||
return res_none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return res_none;
|
||||
}
|
||||
|
||||
|
@ -1150,25 +1479,37 @@ int Sys_PollMouseInputEvents( int mouseEvents[MAX_MOUSE_EVENTS][2] )
|
|||
void Sys_SetRumble( int device, int low, int hi )
|
||||
{
|
||||
// TODO;
|
||||
// SDL 2.0 required (SDL Haptic subsystem)
|
||||
}
|
||||
|
||||
int Sys_PollJoystickInputEvents( int deviceNum )
|
||||
{
|
||||
// TODO;
|
||||
return 0;
|
||||
int numEvents = joystick_polls.Num();
|
||||
|
||||
return numEvents;
|
||||
}
|
||||
|
||||
|
||||
// This funcion called by void idUsercmdGenLocal::Joystick( int deviceNum ) in
|
||||
// file UsercmdGen.cpp
|
||||
// action - must have values belonging to enum sys_jEvents (sys_public.h)
|
||||
// value - must be 1/0 for button or DPAD pressed/released
|
||||
// for joystick axes must be in the range (-32769, 32768)
|
||||
// for joystick trigger must be in the range (0, 32768)
|
||||
int Sys_ReturnJoystickInputEvent( const int n, int& action, int& value )
|
||||
{
|
||||
// TODO;
|
||||
return 0;
|
||||
// Get last element of the list and copy into argument references
|
||||
const joystick_poll_t& mp = joystick_polls[n];
|
||||
action = mp.action;
|
||||
value = mp.value;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// This funcion called by void idUsercmdGenLocal::Joystick( int deviceNum ) in
|
||||
// file UsercmdGen.cpp
|
||||
void Sys_EndJoystickInputEvents()
|
||||
{
|
||||
// Empty the joystick event container. This is called after
|
||||
// all joystick events have been read using Sys_ReturnJoystickInputEvent()
|
||||
joystick_polls.SetNum( 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue