mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 01:01:33 +00:00
Revert "Merge branch 'gamepad-refactor' into next"
This reverts commit696e2ab909
, reversing changes made tod98d59494f
.
This commit is contained in:
parent
366ee4ad92
commit
e5dea805fa
34 changed files with 2663 additions and 3556 deletions
|
@ -51,7 +51,6 @@ p_spec.c
|
|||
p_telept.c
|
||||
p_tick.c
|
||||
p_user.c
|
||||
p_haptic.c
|
||||
p_slopes.c
|
||||
tables.c
|
||||
r_bsp.c
|
||||
|
|
|
@ -77,6 +77,7 @@ CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}};
|
|||
|
||||
// Filter consvars by EXECVERSION
|
||||
// First implementation is 26 (2.1.21), so earlier configs default at 25 (2.1.20)
|
||||
// Also set CV_HIDEN during runtime, after config is loaded
|
||||
static boolean execversion_enabled = false;
|
||||
consvar_t cv_execversion = CVAR_INIT ("execversion","25",CV_CALL,CV_Unsigned, CV_EnforceExecVersion);
|
||||
|
||||
|
@ -2233,12 +2234,12 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
|
|||
// reset all axis settings to defaults
|
||||
if (joyaxis_count == 6)
|
||||
{
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_turnaxis[0].name, cv_turnaxis[0].defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_moveaxis[0].name, cv_moveaxis[0].defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_sideaxis[0].name, cv_sideaxis[0].defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_lookaxis[0].name, cv_lookaxis[0].defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_fireaxis[0].name, cv_fireaxis[0].defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_firenaxis[0].name, cv_firenaxis[0].defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_turnaxis.name, cv_turnaxis.defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_moveaxis.name, cv_moveaxis.defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_sideaxis.name, cv_sideaxis.defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_lookaxis.name, cv_lookaxis.defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_fireaxis.name, cv_fireaxis.defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_firenaxis.name, cv_firenaxis.defaultvalue));
|
||||
joyaxis_count++;
|
||||
return false;
|
||||
}
|
||||
|
@ -2292,12 +2293,12 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
|
|||
// reset all axis settings to defaults
|
||||
if (joyaxis2_count == 6)
|
||||
{
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_turnaxis[1].name, cv_turnaxis[1].defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_moveaxis[1].name, cv_moveaxis[1].defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_sideaxis[1].name, cv_sideaxis[1].defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_lookaxis[1].name, cv_lookaxis[1].defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_fireaxis[1].name, cv_fireaxis[1].defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_firenaxis[1].name, cv_firenaxis[1].defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_turnaxis2.name, cv_turnaxis2.defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_moveaxis2.name, cv_moveaxis2.defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_sideaxis2.name, cv_sideaxis2.defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_lookaxis2.name, cv_lookaxis2.defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_fireaxis2.name, cv_fireaxis2.defaultvalue));
|
||||
COM_BufInsertText(va("%s \"%s\"\n", cv_firenaxis2.name, cv_firenaxis2.defaultvalue));
|
||||
joyaxis2_count++;
|
||||
return false;
|
||||
}
|
||||
|
@ -2307,49 +2308,6 @@ static boolean CV_FilterJoyAxisVars(consvar_t *v, const char *valstr)
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifndef OLD_GAMEPAD_AXES
|
||||
static boolean CV_ConvertOldJoyAxisVars(consvar_t *v, const char *valstr)
|
||||
{
|
||||
static struct {
|
||||
const char *old;
|
||||
const char *new;
|
||||
} axis_names[] = {
|
||||
{"X-Axis", "Left Stick X"},
|
||||
{"Y-Axis", "Left Stick Y"},
|
||||
{"X-Axis-", "Left Stick X-"},
|
||||
{"Y-Axis-", "Left Stick Y-"},
|
||||
{"X-Rudder", "Right Stick X"},
|
||||
{"Y-Rudder", "Right Stick Y"},
|
||||
{"X-Rudder-", "Right Stick X-"},
|
||||
{"Y-Rudder-", "Right Stick Y-"},
|
||||
{"Z-Axis", "Left Trigger"},
|
||||
{"Z-Rudder", "Right Trigger"},
|
||||
{"Z-Axis-", "Left Trigger"},
|
||||
{"Z-Rudder-", "Right Trigger"},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
if (v->PossibleValue != joyaxis_cons_t)
|
||||
return true;
|
||||
|
||||
for (unsigned i = 0;; i++)
|
||||
{
|
||||
if (axis_names[i].old == NULL)
|
||||
{
|
||||
CV_SetCVar(v, "None", false);
|
||||
return false;
|
||||
}
|
||||
else if (!stricmp(valstr, axis_names[i].old))
|
||||
{
|
||||
CV_SetCVar(v, axis_names[i].new, false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr)
|
||||
{
|
||||
// True means allow the CV change, False means block it
|
||||
|
@ -2378,8 +2336,8 @@ static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr)
|
|||
&& atoi(valstr) == 35)
|
||||
return false;
|
||||
|
||||
// GAMEPAD DEFAULTS
|
||||
// use_gamepad was changed from 0 to 1 to automatically use a gamepad if available
|
||||
// JOYSTICK DEFAULTS
|
||||
// use_joystick was changed from 0 to 1 to automatically use a joystick if available
|
||||
#if defined(HAVE_SDL) || defined(_WINDOWS)
|
||||
if ((!stricmp(v->name, "use_joystick")
|
||||
|| !stricmp(v->name, "use_joystick2"))
|
||||
|
@ -2392,15 +2350,6 @@ static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr)
|
|||
if (!CV_FilterJoyAxisVars(v, valstr))
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef OLD_GAMEPAD_AXES
|
||||
if (GETMAJOREXECVERSION(cv_execversion.value) <= 51 && GETMINOREXECVERSION(cv_execversion.value) < 1)
|
||||
{
|
||||
if (!CV_ConvertOldJoyAxisVars(v, valstr))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -918,8 +918,7 @@ boolean CON_Responder(event_t *ev)
|
|||
static INT32 alias_skips;
|
||||
|
||||
const char *cmd = NULL;
|
||||
INT32 key = ev->key;
|
||||
boolean key_is_console = (key == gamecontrol[GC_CONSOLE][0] || key == gamecontrol[GC_CONSOLE][1]);
|
||||
INT32 key;
|
||||
|
||||
if (chat_on)
|
||||
return false;
|
||||
|
@ -927,18 +926,20 @@ boolean CON_Responder(event_t *ev)
|
|||
// let go keyup events, don't eat them
|
||||
if (ev->type != ev_keydown && ev->type != ev_console)
|
||||
{
|
||||
if (key_is_console)
|
||||
if (ev->key == gamecontrol[GC_CONSOLE][0] || ev->key == gamecontrol[GC_CONSOLE][1])
|
||||
consdown = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
key = ev->key;
|
||||
|
||||
// check for console toggle key
|
||||
if (ev->type != ev_console)
|
||||
{
|
||||
if (modeattacking || metalrecording || marathonmode)
|
||||
return false;
|
||||
|
||||
if (key_is_console)
|
||||
if (key == gamecontrol[GC_CONSOLE][0] || key == gamecontrol[GC_CONSOLE][1])
|
||||
{
|
||||
if (consdown) // ignore repeat
|
||||
return true;
|
||||
|
|
|
@ -25,8 +25,7 @@
|
|||
#include "st_stuff.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "keys.h"
|
||||
#include "g_input.h"
|
||||
#include "i_gamepad.h"
|
||||
#include "g_input.h" // JOY1
|
||||
#include "m_menu.h"
|
||||
#include "console.h"
|
||||
#include "d_netfil.h"
|
||||
|
@ -34,7 +33,6 @@
|
|||
#include "p_saveg.h"
|
||||
#include "z_zone.h"
|
||||
#include "p_local.h"
|
||||
#include "p_haptic.h"
|
||||
#include "m_misc.h"
|
||||
#include "am_map.h"
|
||||
#include "m_random.h"
|
||||
|
@ -51,7 +49,7 @@
|
|||
#include "m_perfstats.h"
|
||||
|
||||
// aaaaaa
|
||||
#include "i_gamepad.h"
|
||||
#include "i_joy.h"
|
||||
|
||||
#ifndef NONET
|
||||
// cl loading screen
|
||||
|
@ -655,6 +653,22 @@ static UINT8 Snake_GetOppositeDir(UINT8 dir)
|
|||
return 12 + 5 - dir;
|
||||
}
|
||||
|
||||
event_t *snakejoyevents[MAXEVENTS];
|
||||
UINT16 joyeventcount = 0;
|
||||
|
||||
// I'm screaming the hack is clean - ashi
|
||||
static boolean Snake_Joy_Grabber(event_t *ev)
|
||||
{
|
||||
if (ev->type == ev_joystick && ev->key == 0)
|
||||
{
|
||||
snakejoyevents[joyeventcount] = ev;
|
||||
joyeventcount++;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static void Snake_FindFreeSlot(UINT8 *freex, UINT8 *freey, UINT8 headx, UINT8 heady)
|
||||
{
|
||||
UINT8 x, y;
|
||||
|
@ -681,17 +695,19 @@ static void Snake_Handle(void)
|
|||
UINT8 x, y;
|
||||
UINT8 oldx, oldy;
|
||||
UINT16 i;
|
||||
UINT16 j;
|
||||
UINT16 joystate = 0;
|
||||
static INT32 pjoyx = 0, pjoyy = 0;
|
||||
|
||||
// Handle retry
|
||||
if (snake->gameover && (G_PlayerInputDown(0, GC_JUMP) || gamekeydown[KEY_ENTER]))
|
||||
if (snake->gameover && (PLAYER1INPUTDOWN(GC_JUMP) || gamekeydown[KEY_ENTER]))
|
||||
{
|
||||
Snake_Initialise();
|
||||
snake->pausepressed = true; // Avoid accidental pause on respawn
|
||||
}
|
||||
|
||||
// Handle pause
|
||||
if (G_PlayerInputDown(0, GC_PAUSE) || gamekeydown[KEY_ENTER])
|
||||
if (PLAYER1INPUTDOWN(GC_PAUSE) || gamekeydown[KEY_ENTER])
|
||||
{
|
||||
if (!snake->pausepressed)
|
||||
snake->paused = !snake->paused;
|
||||
|
@ -710,23 +726,58 @@ static void Snake_Handle(void)
|
|||
oldx = snake->snakex[1];
|
||||
oldy = snake->snakey[1];
|
||||
|
||||
// process the input events in here dear lord
|
||||
for (j = 0; j < joyeventcount; j++)
|
||||
{
|
||||
event_t *ev = snakejoyevents[j];
|
||||
const INT32 jdeadzone = (JOYAXISRANGE * cv_digitaldeadzone.value) / FRACUNIT;
|
||||
if (ev->y != INT32_MAX)
|
||||
{
|
||||
if (Joystick.bGamepadStyle || abs(ev->y) > jdeadzone)
|
||||
{
|
||||
if (ev->y < 0 && pjoyy >= 0)
|
||||
joystate = 1;
|
||||
else if (ev->y > 0 && pjoyy <= 0)
|
||||
joystate = 2;
|
||||
pjoyy = ev->y;
|
||||
}
|
||||
else
|
||||
pjoyy = 0;
|
||||
}
|
||||
|
||||
if (ev->x != INT32_MAX)
|
||||
{
|
||||
if (Joystick.bGamepadStyle || abs(ev->x) > jdeadzone)
|
||||
{
|
||||
if (ev->x < 0 && pjoyx >= 0)
|
||||
joystate = 3;
|
||||
else if (ev->x > 0 && pjoyx <= 0)
|
||||
joystate = 4;
|
||||
pjoyx = ev->x;
|
||||
}
|
||||
else
|
||||
pjoyx = 0;
|
||||
}
|
||||
}
|
||||
joyeventcount = 0;
|
||||
|
||||
// Update direction
|
||||
if (G_PlayerInputDown(0, GC_STRAFELEFT) || gamekeydown[KEY_LEFTARROW] || joystate == 3)
|
||||
if (PLAYER1INPUTDOWN(GC_STRAFELEFT) || gamekeydown[KEY_LEFTARROW] || joystate == 3)
|
||||
{
|
||||
if (snake->snakelength < 2 || x <= oldx)
|
||||
snake->snakedir[0] = 1;
|
||||
}
|
||||
else if (G_PlayerInputDown(0, GC_STRAFERIGHT) || gamekeydown[KEY_RIGHTARROW] || joystate == 4)
|
||||
else if (PLAYER1INPUTDOWN(GC_STRAFERIGHT) || gamekeydown[KEY_RIGHTARROW] || joystate == 4)
|
||||
{
|
||||
if (snake->snakelength < 2 || x >= oldx)
|
||||
snake->snakedir[0] = 2;
|
||||
}
|
||||
else if (G_PlayerInputDown(0, GC_FORWARD) || gamekeydown[KEY_UPARROW] || joystate == 1)
|
||||
else if (PLAYER1INPUTDOWN(GC_FORWARD) || gamekeydown[KEY_UPARROW] || joystate == 1)
|
||||
{
|
||||
if (snake->snakelength < 2 || y <= oldy)
|
||||
snake->snakedir[0] = 3;
|
||||
}
|
||||
else if (G_PlayerInputDown(0, GC_BACKWARD) || gamekeydown[KEY_DOWNARROW] || joystate == 2)
|
||||
else if (PLAYER1INPUTDOWN(GC_BACKWARD) || gamekeydown[KEY_DOWNARROW] || joystate == 2)
|
||||
{
|
||||
if (snake->snakelength < 2 || y >= oldy)
|
||||
snake->snakedir[0] = 4;
|
||||
|
@ -1652,8 +1703,6 @@ static void CL_LoadReceivedSavegame(boolean reloading)
|
|||
titledemo = false;
|
||||
automapactive = false;
|
||||
|
||||
P_StopRumble(NULL);
|
||||
|
||||
// load a base level
|
||||
if (P_LoadNetGame(reloading))
|
||||
{
|
||||
|
@ -1940,10 +1989,9 @@ void CL_UpdateServerList(boolean internetsearch, INT32 room)
|
|||
static void M_ConfirmConnect(event_t *ev)
|
||||
{
|
||||
#ifndef NONET
|
||||
|
||||
if (ev->type == ev_keydown || ev->type == ev_gamepad_down)
|
||||
if (ev->type == ev_keydown)
|
||||
{
|
||||
if ((ev->type == ev_keydown && (ev->key == ' ' || ev->key == 'y' || ev->key == KEY_ENTER)) || (ev->type == ev_gamepad_down && ev->which == 0 && ev->key == GAMEPAD_BUTTON_A))
|
||||
if (ev->key == ' ' || ev->key == 'y' || ev->key == KEY_ENTER || ev->key == KEY_JOY1)
|
||||
{
|
||||
if (totalfilesrequestednum > 0)
|
||||
{
|
||||
|
@ -1958,7 +2006,7 @@ static void M_ConfirmConnect(event_t *ev)
|
|||
|
||||
M_ClearMenus(true);
|
||||
}
|
||||
else if ((ev->type == ev_keydown && (ev->key == 'n' || ev->key == KEY_ESCAPE)) || (ev->type == ev_gamepad_down && ev->which == 0 && ev->key == GAMEPAD_BUTTON_B))
|
||||
else if (ev->key == 'n' || ev->key == KEY_ESCAPE || ev->key == KEY_JOY1 + 3)
|
||||
{
|
||||
cl_mode = CL_ABORTED;
|
||||
M_ClearMenus(true);
|
||||
|
@ -2392,11 +2440,14 @@ static boolean CL_ServerConnectionTicker(const char *tmpsave, tic_t *oldtic, tic
|
|||
// my hand has been forced and I am dearly sorry for this awful hack :vomit:
|
||||
for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1))
|
||||
{
|
||||
G_MapEventsToControls(&events[eventtail]);
|
||||
#ifndef NONET
|
||||
if (!Snake_Joy_Grabber(&events[eventtail]))
|
||||
#endif
|
||||
G_MapEventsToControls(&events[eventtail]);
|
||||
}
|
||||
}
|
||||
|
||||
if (gamekeydown[KEY_ESCAPE] || gamepads[0].buttons[GAMEPAD_BUTTON_B] || cl_mode == CL_ABORTED)
|
||||
if (gamekeydown[KEY_ESCAPE] || gamekeydown[KEY_JOY1+1] || cl_mode == CL_ABORTED)
|
||||
{
|
||||
CONS_Printf(M_GetText("Network game synchronization aborted.\n"));
|
||||
M_StartMessage(M_GetText("Network game synchronization aborted.\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||
|
@ -5179,7 +5230,7 @@ static void Local_Maketic(INT32 realtics)
|
|||
// game responder calls HU_Responder, AM_Responder,
|
||||
// and G_MapEventsToControls
|
||||
if (!dedicated) rendergametic = gametic;
|
||||
// translate inputs (keyboard/mouse/gamepad) into game controls
|
||||
// translate inputs (keyboard/mouse/joystick) into game controls
|
||||
G_BuildTiccmd(&localcmds, realtics, 1);
|
||||
if (splitscreen || botingame)
|
||||
G_BuildTiccmd(&localcmds2, realtics, 2);
|
||||
|
|
|
@ -24,21 +24,19 @@ typedef enum
|
|||
ev_keyup,
|
||||
ev_console,
|
||||
ev_mouse,
|
||||
ev_joystick,
|
||||
ev_mouse2,
|
||||
ev_gamepad_up,
|
||||
ev_gamepad_down,
|
||||
ev_gamepad_axis
|
||||
ev_joystick2,
|
||||
} evtype_t;
|
||||
|
||||
// Event structure.
|
||||
typedef struct
|
||||
{
|
||||
evtype_t type;
|
||||
INT32 key; // key, mouse button, or gamepad button/axis type
|
||||
INT32 x; // mouse x move, or gamepad axis value
|
||||
INT32 y; // mouse y move
|
||||
UINT8 which; // which gamepad or mouse ID
|
||||
boolean repeated; // is the event repeated?
|
||||
INT32 key; // keys/mouse/joystick buttons
|
||||
INT32 x; // mouse/joystick x move
|
||||
INT32 y; // mouse/joystick y move
|
||||
boolean repeated; // key repeat
|
||||
} event_t;
|
||||
|
||||
//
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include "i_time.h"
|
||||
#include "i_threads.h"
|
||||
#include "i_video.h"
|
||||
#include "i_gamepad.h"
|
||||
#include "m_argv.h"
|
||||
#include "m_menu.h"
|
||||
#include "m_misc.h"
|
||||
|
@ -987,7 +986,6 @@ void D_StartTitle(void)
|
|||
G_SetGametype(GT_COOP);
|
||||
paused = false;
|
||||
advancedemo = false;
|
||||
P_StopRumble(NULL);
|
||||
F_InitMenuPresValues();
|
||||
F_StartTitleScreen();
|
||||
|
||||
|
@ -1398,9 +1396,6 @@ void D_SRB2Main(void)
|
|||
CONS_Printf("I_InitializeTime()...\n");
|
||||
I_InitializeTime();
|
||||
|
||||
// Initializes the game logic side of gamepads
|
||||
G_InitGamepads();
|
||||
|
||||
// Make backups of some SOCcable tables.
|
||||
P_BackupTables();
|
||||
|
||||
|
@ -1456,9 +1451,6 @@ void D_SRB2Main(void)
|
|||
|
||||
D_RegisterServerCommands();
|
||||
D_RegisterClientCommands(); // be sure that this is called before D_CheckNetGame
|
||||
|
||||
I_InitGamepads();
|
||||
|
||||
R_RegisterEngineStuff();
|
||||
S_RegisterSoundStuff();
|
||||
|
||||
|
|
140
src/d_netcmd.c
140
src/d_netcmd.c
|
@ -21,7 +21,6 @@
|
|||
#include "g_game.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "g_input.h"
|
||||
#include "i_gamepad.h"
|
||||
#include "m_menu.h"
|
||||
#include "r_local.h"
|
||||
#include "r_skins.h"
|
||||
|
@ -183,6 +182,14 @@ static CV_PossibleValue_t mouse2port_cons_t[] = {{1, "COM1"}, {2, "COM2"}, {3, "
|
|||
{0, NULL}};
|
||||
#endif
|
||||
|
||||
#ifdef LJOYSTICK
|
||||
static CV_PossibleValue_t joyport_cons_t[] = {{1, "/dev/js0"}, {2, "/dev/js1"}, {3, "/dev/js2"},
|
||||
{4, "/dev/js3"}, {0, NULL}};
|
||||
#else
|
||||
// accept whatever value - it is in fact the joystick device number
|
||||
#define usejoystick_cons_t NULL
|
||||
#endif
|
||||
|
||||
static CV_PossibleValue_t teamscramble_cons_t[] = {{0, "Off"}, {1, "Random"}, {2, "Points"}, {0, NULL}};
|
||||
|
||||
static CV_PossibleValue_t startingliveslimit_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}};
|
||||
|
@ -241,61 +248,19 @@ INT32 cv_debug;
|
|||
consvar_t cv_usemouse = CVAR_INIT ("use_mouse", "On", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse);
|
||||
consvar_t cv_usemouse2 = CVAR_INIT ("use_mouse2", "Off", CV_SAVE|CV_CALL,usemouse_cons_t, I_StartupMouse2);
|
||||
|
||||
// We use cv_usegamepad.string as the USER-SET var
|
||||
// and cv_usegamepad.value as the INTERNAL var
|
||||
//
|
||||
// In practice, if cv_usegamepad.string == 0, this overrides
|
||||
// cv_usegamepad.value and always disables
|
||||
|
||||
static void UseGamepad_OnChange(void)
|
||||
{
|
||||
I_ChangeGamepad(0);
|
||||
}
|
||||
|
||||
static void UseGamepad2_OnChange(void)
|
||||
{
|
||||
I_ChangeGamepad(1);
|
||||
}
|
||||
|
||||
consvar_t cv_usegamepad[2] = {
|
||||
CVAR_INIT ("use_gamepad", "1", CV_SAVE|CV_CALL, NULL, UseGamepad_OnChange),
|
||||
CVAR_INIT ("use_gamepad2", "2", CV_SAVE|CV_CALL, NULL, UseGamepad2_OnChange)
|
||||
};
|
||||
|
||||
static void PadScale_OnChange(void)
|
||||
{
|
||||
I_SetGamepadDigital(0, cv_gamepad_scale[0].value == 0);
|
||||
}
|
||||
|
||||
static void PadScale2_OnChange(void)
|
||||
{
|
||||
I_SetGamepadDigital(1, cv_gamepad_scale[1].value == 0);
|
||||
}
|
||||
|
||||
consvar_t cv_gamepad_scale[2] = {
|
||||
CVAR_INIT ("padscale", "1", CV_SAVE|CV_CALL, NULL, PadScale_OnChange),
|
||||
CVAR_INIT ("padscale2", "1", CV_SAVE|CV_CALL, NULL, PadScale2_OnChange)
|
||||
};
|
||||
|
||||
static void PadRumble_OnChange(void)
|
||||
{
|
||||
if (!cv_gamepad_rumble[0].value)
|
||||
I_StopGamepadRumble(0);
|
||||
}
|
||||
|
||||
static void PadRumble2_OnChange(void)
|
||||
{
|
||||
if (!cv_gamepad_rumble[1].value)
|
||||
I_StopGamepadRumble(1);
|
||||
}
|
||||
|
||||
consvar_t cv_gamepad_rumble[2] = {
|
||||
CVAR_INIT ("padrumble", "Off", CV_SAVE|CV_CALL, CV_OnOff, PadRumble_OnChange),
|
||||
CVAR_INIT ("padrumble2", "Off", CV_SAVE|CV_CALL, CV_OnOff, PadRumble2_OnChange)
|
||||
};
|
||||
|
||||
consvar_t cv_gamepad_autopause = CVAR_INIT ("pauseongamepaddisconnect", "On", CV_SAVE, CV_OnOff, NULL);
|
||||
|
||||
consvar_t cv_usejoystick = CVAR_INIT ("use_gamepad", "1", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick);
|
||||
consvar_t cv_usejoystick2 = CVAR_INIT ("use_gamepad2", "2", CV_SAVE|CV_CALL, usejoystick_cons_t, I_InitJoystick2);
|
||||
#if (defined (LJOYSTICK) || defined (HAVE_SDL))
|
||||
#ifdef LJOYSTICK
|
||||
consvar_t cv_joyport = CVAR_INIT ("padport", "/dev/js0", CV_SAVE, joyport_cons_t, NULL);
|
||||
consvar_t cv_joyport2 = CVAR_INIT ("padport2", "/dev/js0", CV_SAVE, joyport_cons_t, NULL); //Alam: for later
|
||||
#endif
|
||||
consvar_t cv_joyscale = CVAR_INIT ("padscale", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale);
|
||||
consvar_t cv_joyscale2 = CVAR_INIT ("padscale2", "1", CV_SAVE|CV_CALL, NULL, I_JoyScale2);
|
||||
#else
|
||||
consvar_t cv_joyscale = CVAR_INIT ("padscale", "1", CV_SAVE|CV_HIDEN, NULL, NULL); //Alam: Dummy for save
|
||||
consvar_t cv_joyscale2 = CVAR_INIT ("padscale2", "1", CV_SAVE|CV_HIDEN, NULL, NULL); //Alam: Dummy for save
|
||||
#endif
|
||||
#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)
|
||||
consvar_t cv_mouse2port = CVAR_INIT ("mouse2port", "/dev/gpmdata", CV_SAVE, mouse2port_cons_t, NULL);
|
||||
consvar_t cv_mouse2opt = CVAR_INIT ("mouse2opt", "0", CV_SAVE, NULL, NULL);
|
||||
|
@ -807,26 +772,26 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_pauseifunfocused);
|
||||
|
||||
// g_input.c
|
||||
CV_RegisterVar(&cv_sideaxis[0]);
|
||||
CV_RegisterVar(&cv_sideaxis[1]);
|
||||
CV_RegisterVar(&cv_turnaxis[0]);
|
||||
CV_RegisterVar(&cv_turnaxis[1]);
|
||||
CV_RegisterVar(&cv_moveaxis[0]);
|
||||
CV_RegisterVar(&cv_moveaxis[1]);
|
||||
CV_RegisterVar(&cv_lookaxis[0]);
|
||||
CV_RegisterVar(&cv_lookaxis[1]);
|
||||
CV_RegisterVar(&cv_jumpaxis[0]);
|
||||
CV_RegisterVar(&cv_jumpaxis[1]);
|
||||
CV_RegisterVar(&cv_spinaxis[0]);
|
||||
CV_RegisterVar(&cv_spinaxis[1]);
|
||||
CV_RegisterVar(&cv_fireaxis[0]);
|
||||
CV_RegisterVar(&cv_fireaxis[1]);
|
||||
CV_RegisterVar(&cv_firenaxis[0]);
|
||||
CV_RegisterVar(&cv_firenaxis[1]);
|
||||
CV_RegisterVar(&cv_deadzone[0]);
|
||||
CV_RegisterVar(&cv_deadzone[1]);
|
||||
CV_RegisterVar(&cv_digitaldeadzone[0]);
|
||||
CV_RegisterVar(&cv_digitaldeadzone[1]);
|
||||
CV_RegisterVar(&cv_sideaxis);
|
||||
CV_RegisterVar(&cv_sideaxis2);
|
||||
CV_RegisterVar(&cv_turnaxis);
|
||||
CV_RegisterVar(&cv_turnaxis2);
|
||||
CV_RegisterVar(&cv_moveaxis);
|
||||
CV_RegisterVar(&cv_moveaxis2);
|
||||
CV_RegisterVar(&cv_lookaxis);
|
||||
CV_RegisterVar(&cv_lookaxis2);
|
||||
CV_RegisterVar(&cv_jumpaxis);
|
||||
CV_RegisterVar(&cv_jumpaxis2);
|
||||
CV_RegisterVar(&cv_spinaxis);
|
||||
CV_RegisterVar(&cv_spinaxis2);
|
||||
CV_RegisterVar(&cv_fireaxis);
|
||||
CV_RegisterVar(&cv_fireaxis2);
|
||||
CV_RegisterVar(&cv_firenaxis);
|
||||
CV_RegisterVar(&cv_firenaxis2);
|
||||
CV_RegisterVar(&cv_deadzone);
|
||||
CV_RegisterVar(&cv_deadzone2);
|
||||
CV_RegisterVar(&cv_digitaldeadzone);
|
||||
CV_RegisterVar(&cv_digitaldeadzone2);
|
||||
|
||||
// filesrch.c
|
||||
CV_RegisterVar(&cv_addons_option);
|
||||
|
@ -855,14 +820,14 @@ void D_RegisterClientCommands(void)
|
|||
CV_RegisterVar(&cv_mousemove);
|
||||
CV_RegisterVar(&cv_mousemove2);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
CV_RegisterVar(&cv_usegamepad[i]);
|
||||
CV_RegisterVar(&cv_gamepad_scale[i]);
|
||||
CV_RegisterVar(&cv_gamepad_rumble[i]);
|
||||
}
|
||||
|
||||
CV_RegisterVar(&cv_gamepad_autopause);
|
||||
CV_RegisterVar(&cv_usejoystick);
|
||||
CV_RegisterVar(&cv_usejoystick2);
|
||||
#ifdef LJOYSTICK
|
||||
CV_RegisterVar(&cv_joyport);
|
||||
CV_RegisterVar(&cv_joyport2);
|
||||
#endif
|
||||
CV_RegisterVar(&cv_joyscale);
|
||||
CV_RegisterVar(&cv_joyscale2);
|
||||
|
||||
// Analog Control
|
||||
CV_RegisterVar(&cv_analog[0]);
|
||||
|
@ -2251,14 +2216,9 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
|
|||
{
|
||||
if (!menuactive || netgame)
|
||||
S_PauseAudio();
|
||||
|
||||
P_PauseRumble(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
S_ResumeAudio();
|
||||
P_UnpauseRumble(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
I_UpdateMouseGrab();
|
||||
|
@ -4653,8 +4613,6 @@ void Command_ExitGame_f(void)
|
|||
emeralds = 0;
|
||||
memset(&luabanks, 0, sizeof(luabanks));
|
||||
|
||||
P_StopRumble(NULL);
|
||||
|
||||
if (dirmenu)
|
||||
closefilemenu(true);
|
||||
|
||||
|
|
|
@ -33,10 +33,14 @@ extern consvar_t cv_defaultskin2;
|
|||
|
||||
extern consvar_t cv_seenames, cv_allowseenames;
|
||||
extern consvar_t cv_usemouse;
|
||||
extern consvar_t cv_usegamepad[2];
|
||||
extern consvar_t cv_gamepad_scale[2];
|
||||
extern consvar_t cv_gamepad_rumble[2];
|
||||
extern consvar_t cv_gamepad_autopause;
|
||||
extern consvar_t cv_usejoystick;
|
||||
extern consvar_t cv_usejoystick2;
|
||||
#ifdef LJOYSTICK
|
||||
extern consvar_t cv_joyport;
|
||||
extern consvar_t cv_joyport2;
|
||||
#endif
|
||||
extern consvar_t cv_joyscale;
|
||||
extern consvar_t cv_joyscale2;
|
||||
|
||||
// splitscreen with second mouse
|
||||
extern consvar_t cv_mouse2port;
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
#include "v_video.h" // video flags (for lua)
|
||||
#include "i_sound.h" // musictype_t (for lua)
|
||||
#include "g_state.h" // gamestate_t (for lua)
|
||||
#include "g_game.h" // Gamepad axes (for lua)
|
||||
#include "g_game.h" // Joystick axes (for lua)
|
||||
#include "i_joy.h"
|
||||
#include "g_input.h" // Game controls (for lua)
|
||||
#include "i_gamepad.h"
|
||||
|
||||
#include "deh_tables.h"
|
||||
|
||||
|
@ -4841,7 +4841,7 @@ const char *const MENUTYPES_LIST[] = {
|
|||
"OP_CHANGECONTROLS", // OP_ChangeControlsDef shared with P2
|
||||
"OP_P1MOUSE",
|
||||
"OP_P1JOYSTICK",
|
||||
"OP_JOYSTICKSET", // OP_GamepadSetDef shared with P2
|
||||
"OP_JOYSTICKSET", // OP_JoystickSetDef shared with P2
|
||||
"OP_P1CAMERA",
|
||||
|
||||
"OP_P2CONTROLS",
|
||||
|
@ -5642,7 +5642,7 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"GS_DEDICATEDSERVER",GS_DEDICATEDSERVER},
|
||||
{"GS_WAITINGPLAYERS",GS_WAITINGPLAYERS},
|
||||
|
||||
// Gamepad axes
|
||||
// Joystick axes
|
||||
{"JA_NONE",JA_NONE},
|
||||
{"JA_TURN",JA_TURN},
|
||||
{"JA_MOVE",JA_MOVE},
|
||||
|
@ -5653,7 +5653,7 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"JA_SPIN",JA_SPIN},
|
||||
{"JA_FIRE",JA_FIRE},
|
||||
{"JA_FIRENORMAL",JA_FIRENORMAL},
|
||||
{"JOYAXISRANGE",OLDJOYAXISRANGE},
|
||||
{"JOYAXISRANGE",JOYAXISRANGE},
|
||||
|
||||
// Game controls
|
||||
{"GC_NULL",GC_NULL},
|
||||
|
|
|
@ -209,7 +209,7 @@ extern char logfilename[1024];
|
|||
// to an increment in MODVERSION. This might never happen in practice.
|
||||
// If MODVERSION increases, set MINOREXECVERSION to 0.
|
||||
#define MAJOREXECVERSION MODVERSION
|
||||
#define MINOREXECVERSION 1
|
||||
#define MINOREXECVERSION 0
|
||||
// (It would have been nice to use VERSION and SUBVERSION but those are zero'd out for DEVELOP builds)
|
||||
|
||||
// Macros
|
||||
|
@ -556,6 +556,9 @@ UINT32 quickncasehash (const char *p, size_t n)
|
|||
#define max(x, y) (((x) > (y)) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
// Max gamepad/joysticks that can be detected/used.
|
||||
#define MAX_JOYSTICKS 4
|
||||
|
||||
#ifndef M_PIl
|
||||
#define M_PIl 3.1415926535897932384626433832795029L
|
||||
#endif
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include "m_cond.h"
|
||||
#include "p_local.h"
|
||||
#include "p_setup.h"
|
||||
#include "p_haptic.h"
|
||||
#include "st_stuff.h" // hud hiding
|
||||
#include "fastcmp.h"
|
||||
#include "console.h"
|
||||
|
@ -511,7 +510,6 @@ void F_StartIntro(void)
|
|||
gameaction = ga_nothing;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
P_StopRumble(NULL);
|
||||
F_NewCutscene(introtext[0]);
|
||||
|
||||
intro_scenenum = 0;
|
||||
|
@ -993,10 +991,9 @@ void F_IntroTicker(void)
|
|||
//
|
||||
boolean F_IntroResponder(event_t *event)
|
||||
{
|
||||
INT32 type = event->type;
|
||||
INT32 key = G_RemapGamepadEvent(event, &type);
|
||||
INT32 key = event->key;
|
||||
|
||||
// remap virtual keys (mouse & gamepad buttons)
|
||||
// remap virtual keys (mouse & joystick buttons)
|
||||
switch (key)
|
||||
{
|
||||
case KEY_MOUSE1:
|
||||
|
@ -1005,30 +1002,34 @@ boolean F_IntroResponder(event_t *event)
|
|||
case KEY_MOUSE1 + 1:
|
||||
key = KEY_BACKSPACE;
|
||||
break;
|
||||
case GAMEPAD_KEY(START):
|
||||
case GAMEPAD_KEY(A):
|
||||
case GAMEPAD_KEY(X):
|
||||
case GAMEPAD_KEY(B):
|
||||
case KEY_JOY1:
|
||||
case KEY_JOY1 + 2:
|
||||
key = KEY_ENTER;
|
||||
break;
|
||||
case GAMEPAD_KEY(DPAD_UP):
|
||||
case KEY_JOY1 + 3:
|
||||
key = 'n';
|
||||
break;
|
||||
case KEY_JOY1 + 1:
|
||||
key = KEY_BACKSPACE;
|
||||
break;
|
||||
case KEY_HAT1:
|
||||
key = KEY_UPARROW;
|
||||
break;
|
||||
case GAMEPAD_KEY(DPAD_DOWN):
|
||||
case KEY_HAT1 + 1:
|
||||
key = KEY_DOWNARROW;
|
||||
break;
|
||||
case GAMEPAD_KEY(DPAD_LEFT):
|
||||
case KEY_HAT1 + 2:
|
||||
key = KEY_LEFTARROW;
|
||||
break;
|
||||
case GAMEPAD_KEY(DPAD_RIGHT):
|
||||
case KEY_HAT1 + 3:
|
||||
key = KEY_RIGHTARROW;
|
||||
break;
|
||||
}
|
||||
|
||||
if (type != ev_keydown)
|
||||
if (event->type != ev_keydown && key != 301)
|
||||
return false;
|
||||
|
||||
if (key != KEY_ESCAPE && key != KEY_ENTER && key != KEY_SPACE && key != KEY_BACKSPACE)
|
||||
if (key != 27 && key != KEY_ENTER && key != KEY_SPACE && key != KEY_BACKSPACE)
|
||||
return false;
|
||||
|
||||
if (keypressed)
|
||||
|
@ -1263,7 +1264,6 @@ void F_StartCredits(void)
|
|||
gameaction = ga_nothing;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
P_StopRumble(NULL);
|
||||
S_StopMusic();
|
||||
S_StopSounds();
|
||||
|
||||
|
@ -1376,10 +1376,9 @@ void F_CreditTicker(void)
|
|||
|
||||
boolean F_CreditResponder(event_t *event)
|
||||
{
|
||||
INT32 type = event->type;
|
||||
INT32 key = G_RemapGamepadEvent(event, &type);
|
||||
INT32 key = event->key;
|
||||
|
||||
// remap virtual keys (mouse & gamepad buttons)
|
||||
// remap virtual keys (mouse & joystick buttons)
|
||||
switch (key)
|
||||
{
|
||||
case KEY_MOUSE1:
|
||||
|
@ -1388,22 +1387,26 @@ boolean F_CreditResponder(event_t *event)
|
|||
case KEY_MOUSE1 + 1:
|
||||
key = KEY_BACKSPACE;
|
||||
break;
|
||||
case GAMEPAD_KEY(START):
|
||||
case GAMEPAD_KEY(A):
|
||||
case GAMEPAD_KEY(X):
|
||||
case GAMEPAD_KEY(B):
|
||||
case KEY_JOY1:
|
||||
case KEY_JOY1 + 2:
|
||||
key = KEY_ENTER;
|
||||
break;
|
||||
case GAMEPAD_KEY(DPAD_UP):
|
||||
case KEY_JOY1 + 3:
|
||||
key = 'n';
|
||||
break;
|
||||
case KEY_JOY1 + 1:
|
||||
key = KEY_BACKSPACE;
|
||||
break;
|
||||
case KEY_HAT1:
|
||||
key = KEY_UPARROW;
|
||||
break;
|
||||
case GAMEPAD_KEY(DPAD_DOWN):
|
||||
case KEY_HAT1 + 1:
|
||||
key = KEY_DOWNARROW;
|
||||
break;
|
||||
case GAMEPAD_KEY(DPAD_LEFT):
|
||||
case KEY_HAT1 + 2:
|
||||
key = KEY_LEFTARROW;
|
||||
break;
|
||||
case GAMEPAD_KEY(DPAD_RIGHT):
|
||||
case KEY_HAT1 + 3:
|
||||
key = KEY_RIGHTARROW;
|
||||
break;
|
||||
}
|
||||
|
@ -1411,7 +1414,7 @@ boolean F_CreditResponder(event_t *event)
|
|||
if (!(timesBeaten) && !(netgame || multiplayer) && !cv_debug)
|
||||
return false;
|
||||
|
||||
if (type != ev_keydown)
|
||||
if (event->type != ev_keydown)
|
||||
return false;
|
||||
|
||||
if (key != KEY_ESCAPE && key != KEY_ENTER && key != KEY_SPACE && key != KEY_BACKSPACE)
|
||||
|
@ -1452,7 +1455,6 @@ void F_StartGameEvaluation(void)
|
|||
gameaction = ga_nothing;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
P_StopRumble(NULL);
|
||||
|
||||
finalecount = -1;
|
||||
sparklloop = 0;
|
||||
|
@ -1778,7 +1780,6 @@ void F_StartEnding(void)
|
|||
gameaction = ga_nothing;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
P_StopRumble(NULL);
|
||||
S_StopMusic(); // todo: placeholder
|
||||
S_StopSounds();
|
||||
|
||||
|
@ -2224,7 +2225,6 @@ void F_StartGameEnd(void)
|
|||
paused = false;
|
||||
CON_ToggleOff();
|
||||
S_StopSounds();
|
||||
P_StopRumble(NULL);
|
||||
|
||||
// In case menus are still up?!!
|
||||
M_ClearMenus(true);
|
||||
|
@ -3567,7 +3567,6 @@ void F_StartContinue(void)
|
|||
keypressed = false;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
P_StopRumble(NULL);
|
||||
|
||||
// In case menus are still up?!!
|
||||
M_ClearMenus(true);
|
||||
|
@ -3820,26 +3819,24 @@ void F_ContinueTicker(void)
|
|||
|
||||
boolean F_ContinueResponder(event_t *event)
|
||||
{
|
||||
INT32 key = event->key;
|
||||
|
||||
if (keypressed)
|
||||
return true;
|
||||
|
||||
INT32 type = event->type;
|
||||
INT32 key = G_RemapGamepadEvent(event, &type);
|
||||
|
||||
if (timetonext >= 21*TICRATE/2)
|
||||
return false;
|
||||
if (event->type != ev_keydown)
|
||||
return false;
|
||||
|
||||
// remap virtual keys (mouse & gamepad buttons)
|
||||
// remap virtual keys (mouse & joystick buttons)
|
||||
switch (key)
|
||||
{
|
||||
case KEY_ENTER:
|
||||
case KEY_SPACE:
|
||||
case KEY_MOUSE1:
|
||||
case GAMEPAD_KEY(START):
|
||||
case GAMEPAD_KEY(A):
|
||||
case GAMEPAD_KEY(X):
|
||||
case KEY_JOY1:
|
||||
case KEY_JOY1 + 2:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
|
@ -3957,7 +3954,6 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
|
|||
gameaction = ga_nothing;
|
||||
paused = false;
|
||||
CON_ToggleOff();
|
||||
P_StopRumble(NULL);
|
||||
|
||||
F_NewCutscene(cutscenes[cutscenenum]->scene[0].text);
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "z_zone.h"
|
||||
#include "i_video.h"
|
||||
#include "byteptr.h"
|
||||
#include "i_gamepad.h"
|
||||
#include "i_joy.h"
|
||||
#include "r_local.h"
|
||||
#include "r_skins.h"
|
||||
#include "y_inter.h"
|
||||
|
@ -1527,9 +1527,9 @@ void G_BeginRecording(void)
|
|||
buf |= 0x08;
|
||||
pflags |= PF_AUTOBRAKE;
|
||||
}
|
||||
if (cv_usegamepad[0].value)
|
||||
if (cv_usejoystick.value)
|
||||
buf |= 0x10;
|
||||
CV_SetValue(&cv_showinputjoy, !!(cv_usegamepad[0].value));
|
||||
CV_SetValue(&cv_showinputjoy, !!(cv_usejoystick.value));
|
||||
|
||||
WRITEUINT8(demo_p,buf);
|
||||
player->pflags = pflags;
|
||||
|
|
705
src/g_game.c
705
src/g_game.c
File diff suppressed because it is too large
Load diff
24
src/g_game.h
24
src/g_game.h
|
@ -68,14 +68,10 @@ typedef enum {
|
|||
#define P_ControlStyle(player) ((((player)->pflags & PF_ANALOGMODE) ? CS_LMAOGALOG : 0) | (((player)->pflags & PF_DIRECTIONCHAR) ? CS_STANDARD : 0))
|
||||
|
||||
extern consvar_t cv_autobrake, cv_autobrake2;
|
||||
extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis,cv_deadzone,cv_digitaldeadzone;
|
||||
extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2,cv_digitaldeadzone2;
|
||||
extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest;
|
||||
|
||||
extern consvar_t cv_sideaxis[2], cv_turnaxis[2], cv_moveaxis[2], cv_lookaxis[2],
|
||||
cv_jumpaxis[2], cv_spinaxis[2], cv_fireaxis[2], cv_firenaxis[2],
|
||||
cv_deadzone[2], cv_digitaldeadzone[2];
|
||||
|
||||
extern CV_PossibleValue_t joyaxis_cons_t[];
|
||||
|
||||
// hi here's some new controls
|
||||
extern consvar_t cv_cam_shiftfacing[2], cv_cam_turnfacing[2],
|
||||
cv_cam_turnfacingability[2], cv_cam_turnfacingspindash[2], cv_cam_turnfacinginput[2],
|
||||
|
@ -88,12 +84,10 @@ typedef enum
|
|||
LOCK_INTERESTS = 1<<2,
|
||||
} lockassist_e;
|
||||
|
||||
// Legacy axis stuff
|
||||
#define JOYAXISSET 4 // 4 Sets of 2 axes
|
||||
|
||||
typedef enum
|
||||
{
|
||||
JA_NONE,
|
||||
JA_NONE = 0,
|
||||
JA_TURN,
|
||||
JA_MOVE,
|
||||
JA_LOOK,
|
||||
|
@ -107,7 +101,8 @@ typedef enum
|
|||
JA_FIRENORMAL,
|
||||
} joyaxis_e;
|
||||
|
||||
INT16 G_JoyAxis(UINT8 which, joyaxis_e axissel);
|
||||
INT32 JoyAxis(joyaxis_e axissel);
|
||||
INT32 Joy2Axis(joyaxis_e axissel);
|
||||
|
||||
// mouseaiming (looking up/down with the mouse or keyboard)
|
||||
#define KB_LOOKSPEED (1<<25)
|
||||
|
@ -127,15 +122,6 @@ ticcmd_t *G_CopyTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n);
|
|||
// copy ticcmd_t to and fro network packets
|
||||
ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n);
|
||||
|
||||
// gets the user-set gamepad device for a specific player
|
||||
INT32 G_GetGamepadDeviceIndex(INT32 player);
|
||||
|
||||
// returns a player's gamepad index
|
||||
INT16 G_GetGamepadForPlayer(player_t *player);
|
||||
|
||||
// called when a player's gamepad is disconnected
|
||||
void G_OnGamepadDisconnect(UINT8 which);
|
||||
|
||||
// clip the console player aiming to the view
|
||||
INT16 G_ClipAimingPitch(INT32 *aiming);
|
||||
INT16 G_SoftwareClipAimingPitch(INT32 *aiming);
|
||||
|
|
1331
src/g_input.c
1331
src/g_input.c
File diff suppressed because it is too large
Load diff
216
src/g_input.h
216
src/g_input.h
|
@ -8,7 +8,7 @@
|
|||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file g_input.h
|
||||
/// \brief handle mouse/keyboard/gamepad inputs,
|
||||
/// \brief handle mouse/keyboard/joystick inputs,
|
||||
/// maps inputs to game controls (forward, spin, jump...)
|
||||
|
||||
#ifndef __G_INPUT__
|
||||
|
@ -17,178 +17,45 @@
|
|||
#include "d_event.h"
|
||||
#include "keys.h"
|
||||
#include "command.h"
|
||||
#include "m_fixed.h"
|
||||
|
||||
// number of total 'button' inputs, include keyboard keys, plus virtual
|
||||
// keys (mousebuttons and joybuttons becomes keys)
|
||||
#define NUMKEYS 256
|
||||
|
||||
// Max gamepads that can be used by every player
|
||||
#define NUM_GAMEPADS 2
|
||||
|
||||
// Max gamepads that can be detected
|
||||
#define MAX_CONNECTED_GAMEPADS 4
|
||||
|
||||
// Max mouse buttons
|
||||
#define MOUSEBUTTONS 8
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GAMEPAD_TYPE_UNKNOWN,
|
||||
|
||||
GAMEPAD_TYPE_XBOX360,
|
||||
GAMEPAD_TYPE_XBOXONE,
|
||||
GAMEPAD_TYPE_XBOX_SERIES_XS,
|
||||
GAMEPAD_TYPE_XBOX_ELITE,
|
||||
|
||||
GAMEPAD_TYPE_PS3,
|
||||
GAMEPAD_TYPE_PS4,
|
||||
GAMEPAD_TYPE_PS5,
|
||||
|
||||
GAMEPAD_TYPE_NINTENDO_SWITCH_PRO,
|
||||
GAMEPAD_TYPE_NINTENDO_SWITCH_JOY_CON_GRIP,
|
||||
GAMEPAD_TYPE_NINTENDO_SWITCH_JOY_CON_LEFT,
|
||||
GAMEPAD_TYPE_NINTENDO_SWITCH_JOY_CON_RIGHT,
|
||||
|
||||
GAMEPAD_TYPE_GOOGLE_STADIA,
|
||||
GAMEPAD_TYPE_AMAZON_LUNA,
|
||||
GAMEPAD_TYPE_STEAM_CONTROLLER,
|
||||
|
||||
GAMEPAD_TYPE_VIRTUAL
|
||||
} gamepadtype_e;
|
||||
|
||||
boolean G_GamepadTypeIsXbox(gamepadtype_e type);
|
||||
boolean G_GamepadTypeIsPlayStation(gamepadtype_e type);
|
||||
boolean G_GamepadTypeIsNintendoSwitch(gamepadtype_e type);
|
||||
boolean G_GamepadTypeIsJoyCon(gamepadtype_e type);
|
||||
|
||||
const char *G_GamepadTypeToString(gamepadtype_e type);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GAMEPAD_BUTTON_A,
|
||||
GAMEPAD_BUTTON_B,
|
||||
GAMEPAD_BUTTON_X,
|
||||
GAMEPAD_BUTTON_Y,
|
||||
GAMEPAD_BUTTON_BACK,
|
||||
GAMEPAD_BUTTON_GUIDE,
|
||||
GAMEPAD_BUTTON_START,
|
||||
GAMEPAD_BUTTON_LEFTSTICK,
|
||||
GAMEPAD_BUTTON_RIGHTSTICK,
|
||||
GAMEPAD_BUTTON_LEFTSHOULDER,
|
||||
GAMEPAD_BUTTON_RIGHTSHOULDER,
|
||||
GAMEPAD_BUTTON_DPAD_UP,
|
||||
GAMEPAD_BUTTON_DPAD_DOWN,
|
||||
GAMEPAD_BUTTON_DPAD_LEFT,
|
||||
GAMEPAD_BUTTON_DPAD_RIGHT,
|
||||
|
||||
// According to SDL, this button can be:
|
||||
// the Xbox Series X|S share button
|
||||
// the PS5 microphone button
|
||||
// the Nintendo Switch (Pro or Joy-Con) capture button
|
||||
// the Amazon Luna microphone button
|
||||
GAMEPAD_BUTTON_MISC1,
|
||||
|
||||
// Xbox Elite paddles
|
||||
GAMEPAD_BUTTON_PADDLE1,
|
||||
GAMEPAD_BUTTON_PADDLE2,
|
||||
GAMEPAD_BUTTON_PADDLE3,
|
||||
GAMEPAD_BUTTON_PADDLE4,
|
||||
|
||||
// PS4/PS5 touchpad button
|
||||
GAMEPAD_BUTTON_TOUCHPAD,
|
||||
|
||||
NUM_GAMEPAD_BUTTONS
|
||||
} gamepad_button_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GAMEPAD_AXIS_LEFTX,
|
||||
GAMEPAD_AXIS_LEFTY,
|
||||
GAMEPAD_AXIS_RIGHTX,
|
||||
GAMEPAD_AXIS_RIGHTY,
|
||||
GAMEPAD_AXIS_TRIGGERLEFT,
|
||||
GAMEPAD_AXIS_TRIGGERRIGHT,
|
||||
|
||||
NUM_GAMEPAD_AXES
|
||||
} gamepad_axis_e;
|
||||
|
||||
extern const char *const gamepad_button_names[NUM_GAMEPAD_BUTTONS + 1];
|
||||
extern const char *const gamepad_axis_names[NUM_GAMEPAD_AXES + 1];
|
||||
|
||||
// Haptic effects
|
||||
typedef struct
|
||||
{
|
||||
fixed_t large_magnitude; // Magnitude of the large motor
|
||||
fixed_t small_magnitude; // Magnitude of the small motor
|
||||
tic_t duration; // The total duration of the effect, in tics
|
||||
} haptic_t;
|
||||
|
||||
// Gamepad info for each player on the system
|
||||
typedef struct
|
||||
{
|
||||
// Gamepad index
|
||||
UINT8 num;
|
||||
|
||||
// Gamepad is connected and being used by a player
|
||||
boolean connected;
|
||||
|
||||
// What kind of controller this is (Xbox 360, DualShock, Joy-Con, etc.)
|
||||
gamepadtype_e type;
|
||||
|
||||
// Treat this gamepad's axes as if it they were buttons
|
||||
boolean digital;
|
||||
|
||||
struct {
|
||||
boolean supported; // Gamepad can rumble
|
||||
boolean active; // Rumble is active
|
||||
boolean paused; // Rumble is paused
|
||||
haptic_t data; // Current haptic effect status
|
||||
} rumble;
|
||||
|
||||
UINT8 buttons[NUM_GAMEPAD_BUTTONS]; // Current state of all buttons
|
||||
INT16 axes[NUM_GAMEPAD_AXES]; // Current state of all axes
|
||||
} gamepad_t;
|
||||
|
||||
void G_InitGamepads(void);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GAMEPAD_STRING_DEFAULT, // A
|
||||
GAMEPAD_STRING_MENU1, // A Button
|
||||
GAMEPAD_STRING_MENU2 // the A Button
|
||||
} gamepad_string_e;
|
||||
|
||||
const char *G_GetGamepadButtonString(gamepadtype_e type, gamepad_button_e button, gamepad_string_e strtype);
|
||||
const char *G_GetGamepadAxisString(gamepadtype_e type, gamepad_axis_e button, gamepad_string_e strtype, boolean inv);
|
||||
|
||||
extern gamepad_t gamepads[NUM_GAMEPADS];
|
||||
#define JOYBUTTONS 32 // 32 buttons
|
||||
#define JOYHATS 4 // 4 hats
|
||||
#define JOYAXISSET 4 // 4 Sets of 2 axises
|
||||
|
||||
//
|
||||
// mouse and gamepad buttons are handled as 'virtual' keys
|
||||
// mouse and joystick buttons are handled as 'virtual' keys
|
||||
//
|
||||
typedef enum
|
||||
{
|
||||
KEY_MOUSE1 = NUMKEYS,
|
||||
KEY_GAMEPAD = KEY_MOUSE1 + MOUSEBUTTONS,
|
||||
KEY_AXES = KEY_GAMEPAD + NUM_GAMEPAD_BUTTONS, // Sure, why not.
|
||||
KEY_INV_AXES = KEY_AXES + NUM_GAMEPAD_AXES,
|
||||
KEY_JOY1 = KEY_MOUSE1 + MOUSEBUTTONS,
|
||||
KEY_HAT1 = KEY_JOY1 + JOYBUTTONS,
|
||||
|
||||
KEY_DBLMOUSE1 = KEY_INV_AXES + NUM_GAMEPAD_AXES, // double clicks
|
||||
KEY_DBLMOUSE1 =KEY_HAT1 + JOYHATS*4, // double clicks
|
||||
KEY_DBLJOY1 = KEY_DBLMOUSE1 + MOUSEBUTTONS,
|
||||
KEY_DBLHAT1 = KEY_DBLJOY1 + JOYBUTTONS,
|
||||
|
||||
KEY_2MOUSE1 = KEY_DBLMOUSE1 + MOUSEBUTTONS,
|
||||
KEY_DBL2MOUSE1 = KEY_2MOUSE1 + MOUSEBUTTONS,
|
||||
KEY_2MOUSE1 = KEY_DBLHAT1 + JOYHATS*4,
|
||||
KEY_2JOY1 = KEY_2MOUSE1 + MOUSEBUTTONS,
|
||||
KEY_2HAT1 = KEY_2JOY1 + JOYBUTTONS,
|
||||
|
||||
KEY_MOUSEWHEELUP = KEY_DBL2MOUSE1 + MOUSEBUTTONS,
|
||||
KEY_MOUSEWHEELDOWN,
|
||||
KEY_2MOUSEWHEELUP,
|
||||
KEY_2MOUSEWHEELDOWN,
|
||||
KEY_DBL2MOUSE1 = KEY_2HAT1 + JOYHATS*4,
|
||||
KEY_DBL2JOY1 = KEY_DBL2MOUSE1 + MOUSEBUTTONS,
|
||||
KEY_DBL2HAT1 = KEY_DBL2JOY1 + JOYBUTTONS,
|
||||
|
||||
NUMINPUTS
|
||||
KEY_MOUSEWHEELUP = KEY_DBL2HAT1 + JOYHATS*4,
|
||||
KEY_MOUSEWHEELDOWN = KEY_MOUSEWHEELUP + 1,
|
||||
KEY_2MOUSEWHEELUP = KEY_MOUSEWHEELDOWN + 1,
|
||||
KEY_2MOUSEWHEELDOWN = KEY_2MOUSEWHEELUP + 1,
|
||||
|
||||
NUMINPUTS = KEY_2MOUSEWHEELDOWN + 1,
|
||||
} key_input_e;
|
||||
|
||||
#define GAMEPAD_KEY(key) (KEY_GAMEPAD + GAMEPAD_BUTTON_##key)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GC_NULL = 0, // a key/button mapped to GC_NULL has no effect
|
||||
|
@ -274,22 +141,19 @@ typedef struct
|
|||
extern mouse_t mouse;
|
||||
extern mouse_t mouse2;
|
||||
|
||||
extern INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymove[JOYAXISSET];
|
||||
|
||||
// current state of the keys: true if pushed
|
||||
extern UINT8 gamekeydown[NUMINPUTS];
|
||||
|
||||
// two key codes (or virtual key) per game control
|
||||
extern INT32 gamecontrol[NUM_GAMECONTROLS][2];
|
||||
extern INT32 gamecontrolbis[NUM_GAMECONTROLS][2]; // secondary splitscreen player
|
||||
|
||||
// default control storage, use 0 (gcs_custom) for memory retention
|
||||
extern INT32 gamecontroldefault[num_gamecontrolschemes][NUM_GAMECONTROLS][2];
|
||||
extern INT32 gamecontroldefault[num_gamecontrolschemes][NUM_GAMECONTROLS][2]; // default control storage, use 0 (gcs_custom) for memory retention
|
||||
extern INT32 gamecontrolbisdefault[num_gamecontrolschemes][NUM_GAMECONTROLS][2];
|
||||
|
||||
boolean G_PlayerInputDown(UINT8 which, gamecontrols_e gc);
|
||||
boolean G_CheckDigitalPlayerInput(UINT8 which, gamecontrols_e gc);
|
||||
|
||||
SINT8 G_PlayerInputIsAnalog(UINT8 which, gamecontrols_e gc, UINT8 settings);
|
||||
INT16 G_GetAnalogPlayerInput(UINT8 which, gamecontrols_e gc, UINT8 settings);
|
||||
#define PLAYER1INPUTDOWN(gc) (gamekeydown[gamecontrol[gc][0]] || gamekeydown[gamecontrol[gc][1]])
|
||||
#define PLAYER2INPUTDOWN(gc) (gamekeydown[gamecontrolbis[gc][0]] || gamekeydown[gamecontrolbis[gc][1]])
|
||||
#define PLAYERINPUTDOWN(p, gc) ((p) == 2 ? PLAYER2INPUTDOWN(gc) : PLAYER1INPUTDOWN(gc))
|
||||
|
||||
#define num_gcl_tutorial_check 6
|
||||
#define num_gcl_tutorial_used 8
|
||||
|
@ -317,37 +181,13 @@ extern const INT32 gcl_jump_spin[num_gcl_jump_spin];
|
|||
// remaps the input event to a game control.
|
||||
void G_MapEventsToControls(event_t *ev);
|
||||
|
||||
boolean G_RumbleSupported(UINT8 which);
|
||||
boolean G_RumbleGamepad(UINT8 which, fixed_t large_magnitude, fixed_t small_magnitude, tic_t duration);
|
||||
void G_StopGamepadRumble(UINT8 which);
|
||||
|
||||
fixed_t G_GetLargeMotorFreq(UINT8 which);
|
||||
fixed_t G_GetSmallMotorFreq(UINT8 which);
|
||||
boolean G_GetGamepadRumblePaused(UINT8 which);
|
||||
boolean G_SetLargeMotorFreq(UINT8 which, fixed_t freq);
|
||||
boolean G_SetSmallMotorFreq(UINT8 which, fixed_t freq);
|
||||
void G_SetGamepadRumblePaused(UINT8 which, boolean pause);
|
||||
|
||||
INT16 G_GamepadAxisEventValue(UINT8 which, INT16 value);
|
||||
INT16 G_GetGamepadAxisValue(UINT8 which, gamepad_axis_e axis);
|
||||
fixed_t G_GetAdjustedGamepadAxis(UINT8 which, gamepad_axis_e axis, boolean applyDeadzone);
|
||||
|
||||
UINT16 G_GetGamepadDeadZone(UINT8 which);
|
||||
UINT16 G_GetGamepadDigitalDeadZone(UINT8 which);
|
||||
INT32 G_BasicDeadZoneCalculation(INT32 magnitude, const UINT16 jdeadzone);
|
||||
|
||||
INT32 G_RemapGamepadEvent(event_t *event, INT32 *type);
|
||||
|
||||
// returns the name of a key
|
||||
const char *G_KeyNumToName(INT32 keynum);
|
||||
INT32 G_KeyNameToNum(const char *keystr);
|
||||
|
||||
const char *G_GetDisplayNameForKey(INT32 keynum);
|
||||
|
||||
// detach any keys associated to the given game control
|
||||
void G_ClearControlKeys(INT32 (*setupcontrols)[2], INT32 control);
|
||||
void G_ClearAllControlKeys(void);
|
||||
|
||||
void Command_Setcontrol_f(void);
|
||||
void Command_Setcontrol2_f(void);
|
||||
void G_DefineDefaultControls(void);
|
||||
|
|
|
@ -877,7 +877,7 @@ void HU_Ticker(void)
|
|||
hu_tick++;
|
||||
hu_tick &= 7; // currently only to blink chat input cursor
|
||||
|
||||
if (G_PlayerInputDown(0, GC_SCORES))
|
||||
if (PLAYER1INPUTDOWN(GC_SCORES))
|
||||
hu_showscores = !chat_on;
|
||||
else
|
||||
hu_showscores = false;
|
||||
|
@ -1052,6 +1052,26 @@ boolean HU_Responder(event_t *ev)
|
|||
|
||||
// only KeyDown events now...
|
||||
|
||||
/*// Shoot, to prevent P1 chatting from ruining the game for everyone else, it's either:
|
||||
// A. completely disallow opening chat entirely in online splitscreen
|
||||
// or B. iterate through all controls to make sure it's bound to player 1 before eating
|
||||
// You can see which one I chose.
|
||||
// (Unless if you're sharing a keyboard, since you probably establish when you start chatting that you have dibs on it...)
|
||||
// (Ahhh, the good ol days when I was a kid who couldn't afford an extra USB controller...)
|
||||
|
||||
if (ev->key >= KEY_MOUSE1)
|
||||
{
|
||||
INT32 i;
|
||||
for (i = 0; i < NUM_GAMECONTROLS; i++)
|
||||
{
|
||||
if (gamecontrol[i][0] == ev->key || gamecontrol[i][1] == ev->key)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == NUM_GAMECONTROLS)
|
||||
return false;
|
||||
}*/ //We don't actually care about that unless we get splitscreen netgames. :V
|
||||
|
||||
#ifndef NONET
|
||||
c = (INT32)ev->key;
|
||||
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file i_gamepad.h
|
||||
/// \brief Gamepads
|
||||
|
||||
#ifndef __I_GAMEPAD_H__
|
||||
#define __I_GAMEPAD_H__
|
||||
|
||||
#include "g_input.h"
|
||||
#include "p_haptic.h"
|
||||
|
||||
// So m_menu knows whether to store cv_usegamepad value or string
|
||||
#define GAMEPAD_HOTPLUG
|
||||
|
||||
// Value range for axes
|
||||
#define JOYAXISRANGE INT16_MAX
|
||||
#define OLDJOYAXISRANGE 1023
|
||||
|
||||
// Starts all gamepads
|
||||
void I_InitGamepads(void);
|
||||
|
||||
// Returns the number of gamepads on the system
|
||||
INT32 I_NumGamepads(void);
|
||||
|
||||
// Changes a gamepad's device
|
||||
void I_ChangeGamepad(UINT8 which);
|
||||
|
||||
// Toggles a gamepad's digital axis setting
|
||||
void I_SetGamepadDigital(UINT8 which, boolean enable);
|
||||
|
||||
// Shuts down all gamepads
|
||||
void I_ShutdownGamepads(void);
|
||||
|
||||
// Returns the name of a gamepad from its index
|
||||
const char *I_GetGamepadName(INT32 joyindex);
|
||||
|
||||
// Gamepad rumble interface
|
||||
boolean I_RumbleSupported(void);
|
||||
boolean I_RumbleGamepad(UINT8 which, const haptic_t *effect);
|
||||
|
||||
boolean I_GetGamepadRumblePaused(UINT8 which);
|
||||
|
||||
boolean I_SetGamepadLargeMotorFreq(UINT8 which, fixed_t freq);
|
||||
boolean I_SetGamepadSmallMotorFreq(UINT8 which, fixed_t freq);
|
||||
void I_SetGamepadRumblePaused(UINT8 which, boolean pause);
|
||||
|
||||
boolean I_GetGamepadRumbleSupported(UINT8 which);
|
||||
|
||||
void I_StopGamepadRumble(UINT8 which);
|
||||
|
||||
#endif // __I_GAMEPAD_H__
|
58
src/i_joy.h
Normal file
58
src/i_joy.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file i_joy.h
|
||||
/// \brief share joystick information with game control code
|
||||
|
||||
#ifndef __I_JOY_H__
|
||||
#define __I_JOY_H__
|
||||
|
||||
#include "g_input.h"
|
||||
|
||||
/*!
|
||||
\brief -JOYAXISRANGE to +JOYAXISRANGE for each axis
|
||||
|
||||
(1024-1) so we can do a right shift instead of division
|
||||
(doesnt matter anyway, just give enough precision)
|
||||
a gamepad will return -1, 0, or 1 in the event data
|
||||
an analog type joystick will return a value
|
||||
from -JOYAXISRANGE to +JOYAXISRANGE for each axis
|
||||
*/
|
||||
|
||||
#define JOYAXISRANGE 1023
|
||||
|
||||
// detect a bug if we increase JOYBUTTONS above DIJOYSTATE's number of buttons
|
||||
#if (JOYBUTTONS > 64)
|
||||
"JOYBUTTONS is greater than INT64 bits can hold"
|
||||
#endif
|
||||
|
||||
/** \brief The struct JoyType_s
|
||||
|
||||
share some joystick information (maybe 2 for splitscreen), to the game input code,
|
||||
actually, we need to know if it is a gamepad or analog controls
|
||||
*/
|
||||
|
||||
struct JoyType_s
|
||||
{
|
||||
/*! if true, we MUST Poll() to get new joystick data,
|
||||
that is: we NEED the DIRECTINPUTDEVICE2 ! (watchout NT compatibility) */
|
||||
INT32 bJoyNeedPoll;
|
||||
/*! this joystick is a gamepad, read: digital axes
|
||||
if FALSE, interpret the joystick event data as JOYAXISRANGE (see above) */
|
||||
INT32 bGamepadStyle;
|
||||
|
||||
};
|
||||
typedef struct JoyType_s JoyType_t;
|
||||
/** \brief Joystick info
|
||||
for palyer 1 and 2's joystick/gamepad
|
||||
*/
|
||||
|
||||
extern JoyType_t Joystick, Joystick2;
|
||||
|
||||
#endif // __I_JOY_H__
|
|
@ -101,6 +101,90 @@ ticcmd_t *I_BaseTiccmd2(void);
|
|||
*/
|
||||
void I_Quit(void) FUNCNORETURN;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EvilForce = -1,
|
||||
//Constant
|
||||
ConstantForce = 0,
|
||||
//Ramp
|
||||
RampForce,
|
||||
//Periodics
|
||||
SquareForce,
|
||||
SineForce,
|
||||
TriangleForce,
|
||||
SawtoothUpForce,
|
||||
SawtoothDownForce,
|
||||
//MAX
|
||||
NumberofForces,
|
||||
} FFType;
|
||||
|
||||
typedef struct JoyFF_s
|
||||
{
|
||||
INT32 ForceX; ///< The X of the Force's Vel
|
||||
INT32 ForceY; ///< The Y of the Force's Vel
|
||||
//All
|
||||
UINT32 Duration; ///< The total duration of the effect, in microseconds
|
||||
INT32 Gain; //< /The gain to be applied to the effect, in the range from 0 through 10,000.
|
||||
//All, CONSTANTFORCE -10,000 to 10,000
|
||||
INT32 Magnitude; ///< Magnitude of the effect, in the range from 0 through 10,000.
|
||||
//RAMPFORCE
|
||||
INT32 Start; ///< Magnitude at the start of the effect, in the range from -10,000 through 10,000.
|
||||
INT32 End; ///< Magnitude at the end of the effect, in the range from -10,000 through 10,000.
|
||||
//PERIODIC
|
||||
INT32 Offset; ///< Offset of the effect.
|
||||
UINT32 Phase; ///< Position in the cycle of the periodic effect at which playback begins, in the range from 0 through 35,999
|
||||
UINT32 Period; ///< Period of the effect, in microseconds.
|
||||
} JoyFF_t;
|
||||
|
||||
/** \brief Forcefeedback for the first joystick
|
||||
|
||||
\param Type what kind of Effect
|
||||
\param Effect Effect Info
|
||||
|
||||
\return void
|
||||
*/
|
||||
|
||||
void I_Tactile(FFType Type, const JoyFF_t *Effect);
|
||||
|
||||
/** \brief Forcefeedback for the second joystick
|
||||
|
||||
\param Type what kind of Effect
|
||||
\param Effect Effect Info
|
||||
|
||||
\return void
|
||||
*/
|
||||
void I_Tactile2(FFType Type, const JoyFF_t *Effect);
|
||||
|
||||
/** \brief to set up the first joystick scale
|
||||
*/
|
||||
void I_JoyScale(void);
|
||||
|
||||
/** \brief to set up the second joystick scale
|
||||
*/
|
||||
void I_JoyScale2(void);
|
||||
|
||||
// Called by D_SRB2Main.
|
||||
|
||||
/** \brief to startup the first joystick
|
||||
*/
|
||||
void I_InitJoystick(void);
|
||||
|
||||
/** \brief to startup the second joystick
|
||||
*/
|
||||
void I_InitJoystick2(void);
|
||||
|
||||
/** \brief return the number of joystick on the system
|
||||
*/
|
||||
INT32 I_NumJoys(void);
|
||||
|
||||
/** \brief The *I_GetJoyName function
|
||||
|
||||
\param joyindex which joystick
|
||||
|
||||
\return joystick name
|
||||
*/
|
||||
const char *I_GetJoyName(INT32 joyindex);
|
||||
|
||||
#ifndef NOMUMBLE
|
||||
#include "p_mobj.h" // mobj_t
|
||||
#include "s_sound.h" // listener_t
|
||||
|
@ -209,7 +293,15 @@ const CPUInfoFlags *I_CPUInfo(void);
|
|||
*/
|
||||
const char *I_LocateWad(void);
|
||||
|
||||
/** \brief Mice events
|
||||
/** \brief First Joystick's events
|
||||
*/
|
||||
void I_GetJoystickEvents(void);
|
||||
|
||||
/** \brief Second Joystick's events
|
||||
*/
|
||||
void I_GetJoystick2Events(void);
|
||||
|
||||
/** \brief Mouses events
|
||||
*/
|
||||
void I_GetMouseEvents(void);
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include "g_game.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "i_system.h"
|
||||
#include "i_gamepad.h"
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
@ -31,7 +30,7 @@ static int lib_gameControlDown(lua_State *L)
|
|||
int i = luaL_checkinteger(L, 1);
|
||||
if (i < 0 || i >= NUM_GAMECONTROLS)
|
||||
return luaL_error(L, "GC_* constant %d out of range (0 - %d)", i, NUM_GAMECONTROLS-1);
|
||||
lua_pushinteger(L, G_PlayerInputDown(0, i));
|
||||
lua_pushinteger(L, PLAYER1INPUTDOWN(i));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -40,7 +39,7 @@ static int lib_gameControl2Down(lua_State *L)
|
|||
int i = luaL_checkinteger(L, 1);
|
||||
if (i < 0 || i >= NUM_GAMECONTROLS)
|
||||
return luaL_error(L, "GC_* constant %d out of range (0 - %d)", i, NUM_GAMECONTROLS-1);
|
||||
lua_pushinteger(L, G_PlayerInputDown(1, i));
|
||||
lua_pushinteger(L, PLAYER2INPUTDOWN(i));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -67,14 +66,14 @@ static int lib_gameControl2ToKeyNum(lua_State *L)
|
|||
static int lib_joyAxis(lua_State *L)
|
||||
{
|
||||
int i = luaL_checkinteger(L, 1);
|
||||
lua_pushinteger(L, G_JoyAxis(0, i) / 32);
|
||||
lua_pushinteger(L, JoyAxis(i));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_joy2Axis(lua_State *L)
|
||||
{
|
||||
int i = luaL_checkinteger(L, 1);
|
||||
lua_pushinteger(L, G_JoyAxis(1, i) / 32);
|
||||
lua_pushinteger(L, Joy2Axis(i));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -199,41 +199,39 @@ static UINT8 cht_CheckCheat(cheatseq_t *cht, char key)
|
|||
|
||||
boolean cht_Responder(event_t *ev)
|
||||
{
|
||||
UINT8 ch = 0;
|
||||
UINT8 ret = 0, ch = 0;
|
||||
if (ev->type != ev_keydown)
|
||||
return false;
|
||||
|
||||
if (ev->type == ev_gamepad_down)
|
||||
if (ev->key > 0xFF)
|
||||
{
|
||||
// map some fake (joy) inputs into keys
|
||||
// map joy inputs into keys
|
||||
switch (ev->key)
|
||||
{
|
||||
case GAMEPAD_BUTTON_DPAD_UP:
|
||||
case KEY_JOY1:
|
||||
case KEY_JOY1 + 2:
|
||||
ch = KEY_ENTER;
|
||||
break;
|
||||
case KEY_HAT1:
|
||||
ch = KEY_UPARROW;
|
||||
break;
|
||||
case GAMEPAD_BUTTON_DPAD_DOWN:
|
||||
case KEY_HAT1 + 1:
|
||||
ch = KEY_DOWNARROW;
|
||||
break;
|
||||
case GAMEPAD_BUTTON_DPAD_LEFT:
|
||||
case KEY_HAT1 + 2:
|
||||
ch = KEY_LEFTARROW;
|
||||
break;
|
||||
case GAMEPAD_BUTTON_DPAD_RIGHT:
|
||||
case KEY_HAT1 + 3:
|
||||
ch = KEY_RIGHTARROW;
|
||||
break;
|
||||
case GAMEPAD_BUTTON_START:
|
||||
ch = KEY_ENTER;
|
||||
break;
|
||||
default:
|
||||
// no mapping
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (ev->type == ev_keydown)
|
||||
{
|
||||
if (ev->key > 0xFF)
|
||||
return false;
|
||||
|
||||
else
|
||||
ch = (UINT8)ev->key;
|
||||
}
|
||||
|
||||
UINT8 ret = 0;
|
||||
|
||||
ret += cht_CheckCheat(&cheat_ultimate, (char)ch);
|
||||
ret += cht_CheckCheat(&cheat_ultimate_joy, (char)ch);
|
||||
|
|
756
src/m_menu.c
756
src/m_menu.c
File diff suppressed because it is too large
Load diff
28
src/m_menu.h
28
src/m_menu.h
|
@ -223,9 +223,8 @@ typedef enum
|
|||
{
|
||||
MM_NOTHING = 0, // is just displayed until the user do someting
|
||||
MM_YESNO, // routine is called with only 'y' or 'n' in param
|
||||
MM_KEYHANDLER, // the same of above but without 'y' or 'n' restriction
|
||||
MM_EVENTHANDLER // the same of above but routine is void routine(event_t *)
|
||||
// (ex: set control)
|
||||
MM_EVENTHANDLER // the same of above but without 'y' or 'n' restriction
|
||||
// and routine is void routine(event_t *) (ex: set control)
|
||||
} menumessagetype_t;
|
||||
void M_StartMessage(const char *string, void *routine, menumessagetype_t itemtype);
|
||||
|
||||
|
@ -362,11 +361,9 @@ extern menu_t *currentMenu;
|
|||
extern menu_t MainDef;
|
||||
extern menu_t SP_LoadDef;
|
||||
|
||||
// Call when a gamepad is connected or disconnected
|
||||
void M_UpdateGamepadMenu(void);
|
||||
|
||||
// Returns true if the player is on the gamepad selection menu
|
||||
boolean M_OnGamepadMenu(void);
|
||||
// Call upon joystick hotplug
|
||||
void M_SetupJoystickMenu(INT32 choice);
|
||||
extern menu_t OP_JoystickSetDef;
|
||||
|
||||
// Stuff for customizing the player select screen
|
||||
typedef struct
|
||||
|
@ -541,19 +538,6 @@ void M_FreePlayerSetupColors(void);
|
|||
NULL\
|
||||
}
|
||||
|
||||
#define GAMEPADMENUSTYLE(id, header, source, prev, x, y)\
|
||||
{\
|
||||
id,\
|
||||
header,\
|
||||
sizeof(source)/sizeof(menuitem_t),\
|
||||
prev,\
|
||||
source,\
|
||||
M_DrawGamepadMenu,\
|
||||
x, y,\
|
||||
0,\
|
||||
NULL\
|
||||
}
|
||||
|
||||
#define MAPPLATTERMENUSTYLE(id, header, source)\
|
||||
{\
|
||||
id,\
|
||||
|
@ -574,7 +558,7 @@ void M_FreePlayerSetupColors(void);
|
|||
sizeof (source)/sizeof (menuitem_t),\
|
||||
prev,\
|
||||
source,\
|
||||
M_DrawControlConfigMenu,\
|
||||
M_DrawControl,\
|
||||
24, 40,\
|
||||
0,\
|
||||
NULL\
|
||||
|
|
115
src/p_haptic.c
115
src/p_haptic.c
|
@ -1,115 +0,0 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2021-2022 by Jaime "Lactozilla" Passos.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file p_haptic.c
|
||||
/// \brief Haptic feedback
|
||||
|
||||
#include "p_haptic.h"
|
||||
#include "g_game.h"
|
||||
#include "d_netcmd.h"
|
||||
#include "i_gamepad.h"
|
||||
#include "doomstat.h"
|
||||
|
||||
// Helper function: Returns the gamepad index for a player if it's enabled
|
||||
static INT16 GetGamepadIndex(player_t *player)
|
||||
{
|
||||
INT16 index = G_GetGamepadForPlayer(player);
|
||||
|
||||
if (index >= 0 && cv_usegamepad[index].value)
|
||||
return index;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Rumbles a player's gamepad, or all gamepads
|
||||
boolean P_DoRumble(player_t *player, fixed_t large_magnitude, fixed_t small_magnitude, tic_t duration)
|
||||
{
|
||||
if (!I_RumbleSupported())
|
||||
return false;
|
||||
|
||||
// Rumble every gamepad
|
||||
if (player == NULL)
|
||||
{
|
||||
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
|
||||
{
|
||||
if (cv_gamepad_rumble[i].value)
|
||||
G_RumbleGamepad(i, large_magnitude, small_magnitude, duration);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
INT16 which = GetGamepadIndex(player);
|
||||
if (which < 0 || !cv_gamepad_rumble[which].value)
|
||||
return false;
|
||||
|
||||
return G_RumbleGamepad((UINT8)which, large_magnitude, small_magnitude, duration);
|
||||
}
|
||||
|
||||
// Pauses or unpauses gamepad rumble for a player (or all of them)
|
||||
// Rumble is paused or unpaused regardless if it's enabled or not
|
||||
static void SetRumblePaused(player_t *player, boolean pause)
|
||||
{
|
||||
INT16 which = GetGamepadIndex(player);
|
||||
|
||||
if (which >= 0)
|
||||
G_SetGamepadRumblePaused((UINT8)which, pause);
|
||||
else if (player == NULL)
|
||||
{
|
||||
// Pause or unpause every gamepad
|
||||
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
|
||||
G_SetGamepadRumblePaused(i, pause);
|
||||
}
|
||||
}
|
||||
|
||||
void P_PauseRumble(player_t *player)
|
||||
{
|
||||
SetRumblePaused(player, true);
|
||||
}
|
||||
|
||||
void P_UnpauseRumble(player_t *player)
|
||||
{
|
||||
SetRumblePaused(player, false);
|
||||
}
|
||||
|
||||
boolean P_IsRumbleEnabled(player_t *player)
|
||||
{
|
||||
INT16 which = GetGamepadIndex(player);
|
||||
if (which < 0 || !cv_gamepad_rumble[which].value)
|
||||
return false;
|
||||
|
||||
return G_RumbleSupported((UINT8)which);
|
||||
}
|
||||
|
||||
boolean P_IsRumblePaused(player_t *player)
|
||||
{
|
||||
INT16 which = GetGamepadIndex(player);
|
||||
if (which < 0 || !cv_gamepad_rumble[which].value)
|
||||
return false;
|
||||
|
||||
return G_GetGamepadRumblePaused((UINT8)which);
|
||||
}
|
||||
|
||||
// Stops gamepad rumble for a player (or all of them)
|
||||
void P_StopRumble(player_t *player)
|
||||
{
|
||||
if (!I_RumbleSupported())
|
||||
return;
|
||||
|
||||
if (player)
|
||||
{
|
||||
INT16 which = GetGamepadIndex(player);
|
||||
if (which >= 0)
|
||||
G_StopGamepadRumble((UINT8)which);
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop every gamepad instead
|
||||
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
|
||||
G_StopGamepadRumble(i);
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2021-2022 by Jaime "Lactozilla" Passos.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file p_haptic.h
|
||||
/// \brief Haptic feedback
|
||||
|
||||
#ifndef __P_HAPTIC__
|
||||
#define __P_HAPTIC__
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "p_local.h"
|
||||
|
||||
boolean P_DoRumble(player_t *player, fixed_t large_magnitude, fixed_t small_magnitude, tic_t duration);
|
||||
void P_PauseRumble(player_t *player);
|
||||
void P_UnpauseRumble(player_t *player);
|
||||
boolean P_IsRumbleEnabled(player_t *player);
|
||||
boolean P_IsRumblePaused(player_t *player);
|
||||
void P_StopRumble(player_t *player);
|
||||
|
||||
#define P_DoRumbleCombined(player, magnitude, dur) P_DoRumble(player, magnitude, magnitude, dur);
|
||||
|
||||
#endif // __P_HAPTIC__
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
#include "doomdef.h"
|
||||
#include "i_system.h"
|
||||
#include "i_gamepad.h"
|
||||
#include "am_map.h"
|
||||
#include "g_game.h"
|
||||
#include "m_random.h"
|
||||
|
@ -25,7 +24,6 @@
|
|||
#include "lua_hook.h"
|
||||
#include "m_cond.h" // unlockables, emblems, etc
|
||||
#include "p_setup.h"
|
||||
#include "p_haptic.h"
|
||||
#include "m_cheat.h" // objectplace
|
||||
#include "m_misc.h"
|
||||
#include "v_video.h" // video flags for CEchos
|
||||
|
@ -35,6 +33,54 @@
|
|||
#define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : ""
|
||||
#define CTFTEAMENDCODE(pl) pl->ctfteam ? "\x80" : ""
|
||||
|
||||
void P_ForceFeed(const player_t *player, INT32 attack, INT32 fade, tic_t duration, INT32 period)
|
||||
{
|
||||
BasicFF_t Basicfeed;
|
||||
if (!player)
|
||||
return;
|
||||
Basicfeed.Duration = (UINT32)(duration * (100L/TICRATE));
|
||||
Basicfeed.ForceX = Basicfeed.ForceY = 1;
|
||||
Basicfeed.Gain = 25000;
|
||||
Basicfeed.Magnitude = period*10;
|
||||
Basicfeed.player = player;
|
||||
/// \todo test FFB
|
||||
P_RampConstant(&Basicfeed, attack, fade);
|
||||
}
|
||||
|
||||
void P_ForceConstant(const BasicFF_t *FFInfo)
|
||||
{
|
||||
JoyFF_t ConstantQuake;
|
||||
if (!FFInfo || !FFInfo->player)
|
||||
return;
|
||||
ConstantQuake.ForceX = FFInfo->ForceX;
|
||||
ConstantQuake.ForceY = FFInfo->ForceY;
|
||||
ConstantQuake.Duration = FFInfo->Duration;
|
||||
ConstantQuake.Gain = FFInfo->Gain;
|
||||
ConstantQuake.Magnitude = FFInfo->Magnitude;
|
||||
if (FFInfo->player == &players[consoleplayer])
|
||||
I_Tactile(ConstantForce, &ConstantQuake);
|
||||
else if (splitscreen && FFInfo->player == &players[secondarydisplayplayer])
|
||||
I_Tactile2(ConstantForce, &ConstantQuake);
|
||||
}
|
||||
void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End)
|
||||
{
|
||||
JoyFF_t RampQuake;
|
||||
if (!FFInfo || !FFInfo->player)
|
||||
return;
|
||||
RampQuake.ForceX = FFInfo->ForceX;
|
||||
RampQuake.ForceY = FFInfo->ForceY;
|
||||
RampQuake.Duration = FFInfo->Duration;
|
||||
RampQuake.Gain = FFInfo->Gain;
|
||||
RampQuake.Magnitude = FFInfo->Magnitude;
|
||||
RampQuake.Start = Start;
|
||||
RampQuake.End = End;
|
||||
if (FFInfo->player == &players[consoleplayer])
|
||||
I_Tactile(ConstantForce, &RampQuake);
|
||||
else if (splitscreen && FFInfo->player == &players[secondarydisplayplayer])
|
||||
I_Tactile2(ConstantForce, &RampQuake);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// GET STUFF
|
||||
//
|
||||
|
@ -3011,8 +3057,6 @@ static boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, IN
|
|||
player_t *player = target->player;
|
||||
(void)damage; //unused parm
|
||||
|
||||
P_DoRumbleCombined(player, FRACUNIT, TICRATE / 6);
|
||||
|
||||
// If flashing or invulnerable, ignore the tag,
|
||||
if (player->powers[pw_flashing] || player->powers[pw_invulnerability])
|
||||
return false;
|
||||
|
@ -3116,8 +3160,6 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou
|
|||
{
|
||||
player_t *player = target->player;
|
||||
|
||||
(void)damage;
|
||||
|
||||
if (!(damagetype & DMG_CANHURTSELF))
|
||||
{
|
||||
// You can't kill yourself, idiot...
|
||||
|
@ -3180,8 +3222,6 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou
|
|||
|
||||
static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
|
||||
{
|
||||
(void)damage;
|
||||
|
||||
player->pflags &= ~PF_SLIDING;
|
||||
|
||||
player->powers[pw_carry] = CR_NONE;
|
||||
|
@ -3202,7 +3242,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
|
|||
// Get rid of emeralds
|
||||
player->powers[pw_emeralds] = 0;
|
||||
|
||||
P_DoRumbleCombined(player, FRACUNIT, TICRATE / 3);
|
||||
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
||||
|
||||
P_ResetPlayer(player);
|
||||
|
||||
|
@ -3242,9 +3282,7 @@ static void P_SuperDamage(player_t *player, mobj_t *inflictor, mobj_t *source, I
|
|||
fixed_t fallbackspeed;
|
||||
angle_t ang;
|
||||
|
||||
(void)damage;
|
||||
|
||||
P_DoRumbleCombined(player, FRACUNIT, TICRATE / 6);
|
||||
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
player->mo->z--;
|
||||
|
@ -3325,14 +3363,12 @@ void P_RemoveShield(player_t *player)
|
|||
|
||||
static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype)
|
||||
{
|
||||
(void)damage;
|
||||
|
||||
// Must do pain first to set flashing -- P_RemoveShield can cause damage
|
||||
P_DoPlayerPain(player, source, inflictor);
|
||||
|
||||
P_RemoveShield(player);
|
||||
|
||||
P_DoRumbleCombined(player, FRACUNIT, TICRATE / 6);
|
||||
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
||||
|
||||
if (damagetype == DMG_SPIKE) // spikes
|
||||
S_StartSound(player->mo, sfx_spkdth);
|
||||
|
@ -3361,7 +3397,7 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN
|
|||
{
|
||||
P_DoPlayerPain(player, source, inflictor);
|
||||
|
||||
P_DoRumbleCombined(player, FRACUNIT, TICRATE / 6);
|
||||
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
||||
|
||||
if (damagetype == DMG_SPIKE) // spikes
|
||||
S_StartSound(player->mo, sfx_spkdth);
|
||||
|
@ -3692,6 +3728,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
|
|||
damage = 1;
|
||||
P_KillPlayer(player, source, damage);
|
||||
}
|
||||
|
||||
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
|
||||
}
|
||||
|
||||
// Killing dead. Just for kicks.
|
||||
|
|
|
@ -453,6 +453,18 @@ extern mobj_t **blocklinks; // for thing chains
|
|||
//
|
||||
// P_INTER
|
||||
//
|
||||
typedef struct BasicFF_s
|
||||
{
|
||||
INT32 ForceX; ///< The X of the Force's Vel
|
||||
INT32 ForceY; ///< The Y of the Force's Vel
|
||||
const player_t *player; ///< Player of Rumble
|
||||
//All
|
||||
UINT32 Duration; ///< The total duration of the effect, in microseconds
|
||||
INT32 Gain; ///< /The gain to be applied to the effect, in the range from 0 through 10,000.
|
||||
//All, CONSTANTFORCE <20>10,000 to 10,000
|
||||
INT32 Magnitude; ///< Magnitude of the effect, in the range from 0 through 10,000.
|
||||
} BasicFF_t;
|
||||
|
||||
/* Damage/death types, for P_DamageMobj and related */
|
||||
//// Damage types
|
||||
//#define DMG_NORMAL 0 (unneeded?)
|
||||
|
@ -473,6 +485,9 @@ extern mobj_t **blocklinks; // for thing chains
|
|||
#define DMG_CANHURTSELF 0x40 // Flag - can hurt self/team indirectly, such as through mines
|
||||
#define DMG_DEATHMASK DMG_INSTAKILL // if bit 7 is set, this is a death type instead of a damage type
|
||||
|
||||
void P_ForceFeed(const player_t *player, INT32 attack, INT32 fade, tic_t duration, INT32 period);
|
||||
void P_ForceConstant(const BasicFF_t *FFInfo);
|
||||
void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End);
|
||||
void P_RemoveShield(player_t *player);
|
||||
void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source);
|
||||
boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype);
|
||||
|
|
|
@ -5331,9 +5331,9 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
|
|||
// disabled because it seemed to disorient people and Z-targeting exists now
|
||||
/*if (!demoplayback)
|
||||
{
|
||||
if (player == &players[consoleplayer] && cv_cam_turnfacingability[0].value > 0 && !(G_PlayerInputDown(0, GC_TURNLEFT) || G_PlayerInputDown(0, GC_TURNRIGHT)))
|
||||
if (player == &players[consoleplayer] && cv_cam_turnfacingability[0].value > 0 && !(PLAYER1INPUTDOWN(GC_TURNLEFT) || PLAYER1INPUTDOWN(GC_TURNRIGHT)))
|
||||
P_SetPlayerAngle(player, player->mo->angle);;
|
||||
else if (player == &players[secondarydisplayplayer] && cv_cam_turnfacingability[1].value > 0 && !(G_PlayerInputDown(1, GC_TURNLEFT) || G_PlayerInputDown(1, GC_TURNRIGHT)))
|
||||
else if (player == &players[secondarydisplayplayer] && cv_cam_turnfacingability[1].value > 0 && !(PLAYER2INPUTDOWN(GC_TURNLEFT) || PLAYER2INPUTDOWN(GC_TURNRIGHT)))
|
||||
P_SetPlayerAngle(player, player->mo->angle);
|
||||
}*/
|
||||
}
|
||||
|
@ -7342,7 +7342,7 @@ static void P_NiGHTSMovement(player_t *player)
|
|||
else if (cmd->forwardmove < 0)
|
||||
newangle = 270;
|
||||
}
|
||||
else // AngleFixed(R_PointToAngle2()) results in slight inaccuracy! Don't use it unless movement is on both axes.
|
||||
else // AngleFixed(R_PointToAngle2()) results in slight inaccuracy! Don't use it unless movement is on both axises.
|
||||
newangle = (INT16)FixedInt(AngleFixed(R_PointToAngle2(0,0, cmd->sidemove*FRACUNIT, cmd->forwardmove*FRACUNIT)));
|
||||
|
||||
newangle -= player->viewrollangle / ANG1;
|
||||
|
|
|
@ -2,7 +2,6 @@ i_net.c
|
|||
i_system.c
|
||||
i_main.c
|
||||
i_video.c
|
||||
i_gamepad.c
|
||||
dosstr.c
|
||||
endtxt.c
|
||||
hwsym_sdl.c
|
||||
|
|
|
@ -1,914 +0,0 @@
|
|||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
// Copyright (C) 1999-2022 by Sonic Team Junior.
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file i_gamepad.c
|
||||
/// \brief Gamepads
|
||||
|
||||
#ifdef HAVE_SDL
|
||||
#include "../i_gamepad.h"
|
||||
#include "../i_system.h"
|
||||
#include "../doomdef.h"
|
||||
#include "../d_main.h"
|
||||
#include "../d_netcmd.h"
|
||||
#include "../g_game.h"
|
||||
#include "../m_argv.h"
|
||||
#include "../m_menu.h"
|
||||
#include "../z_zone.h"
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SDL_joystick.h"
|
||||
#include "sdlmain.h"
|
||||
|
||||
static void Controller_ChangeDevice(UINT8 num);
|
||||
static void Controller_Close(UINT8 num);
|
||||
static void Controller_StopRumble(UINT8 num);
|
||||
|
||||
static ControllerInfo controllers[NUM_GAMEPADS];
|
||||
|
||||
static boolean rumble_supported = false;
|
||||
static boolean rumble_paused = false;
|
||||
|
||||
// This attempts to initialize the gamepad subsystems
|
||||
static boolean InitGamepadSubsystems(void)
|
||||
{
|
||||
if (M_CheckParm("-noxinput"))
|
||||
SDL_SetHintWithPriority(SDL_HINT_XINPUT_ENABLED, "0", SDL_HINT_OVERRIDE);
|
||||
if (M_CheckParm("-nohidapi"))
|
||||
SDL_SetHintWithPriority(SDL_HINT_JOYSTICK_HIDAPI, "0", SDL_HINT_OVERRIDE);
|
||||
|
||||
if (SDL_WasInit(GAMEPAD_INIT_FLAGS) == 0)
|
||||
{
|
||||
if (SDL_InitSubSystem(GAMEPAD_INIT_FLAGS) == -1)
|
||||
{
|
||||
CONS_Printf(M_GetText("Couldn't initialize game controller subsystems: %s\n"), SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void I_InitGamepads(void)
|
||||
{
|
||||
if (M_CheckParm("-nojoy"))
|
||||
return;
|
||||
|
||||
CONS_Printf("I_InitGamepads()...\n");
|
||||
|
||||
if (!InitGamepadSubsystems())
|
||||
return;
|
||||
|
||||
rumble_supported = !M_CheckParm("-norumble");
|
||||
|
||||
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
|
||||
controllers[i].info = &gamepads[i];
|
||||
|
||||
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
|
||||
Controller_ChangeDevice(i);
|
||||
}
|
||||
|
||||
INT32 I_NumGamepads(void)
|
||||
{
|
||||
if (SDL_WasInit(GAMEPAD_INIT_FLAGS) == GAMEPAD_INIT_FLAGS)
|
||||
return SDL_NumJoysticks();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// From the SDL source code
|
||||
#define USB_VENDOR_MICROSOFT 0x045e
|
||||
#define USB_VENDOR_PDP 0x0e6f
|
||||
#define USB_VENDOR_POWERA_ALT 0x20d6
|
||||
|
||||
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_1 0x02e3
|
||||
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2 0x0b00
|
||||
#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH 0x0b05
|
||||
#define USB_PRODUCT_XBOX_SERIES_X 0x0b12
|
||||
#define USB_PRODUCT_XBOX_SERIES_X_BLE 0x0b13
|
||||
#define USB_PRODUCT_XBOX_SERIES_X_VICTRIX_GAMBIT 0x02d6
|
||||
#define USB_PRODUCT_XBOX_SERIES_X_PDP_BLUE 0x02d9
|
||||
#define USB_PRODUCT_XBOX_SERIES_X_PDP_AFTERGLOW 0x02da
|
||||
#define USB_PRODUCT_XBOX_SERIES_X_POWERA_FUSION_PRO2 0x4001
|
||||
#define USB_PRODUCT_XBOX_SERIES_X_POWERA_SPECTRA 0x4002
|
||||
|
||||
static boolean IsJoystickXboxOneElite(Uint16 vendor_id, Uint16 product_id)
|
||||
{
|
||||
if (vendor_id == USB_VENDOR_MICROSOFT) {
|
||||
if (product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_1 ||
|
||||
product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2 ||
|
||||
product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean IsJoystickXboxSeriesXS(Uint16 vendor_id, Uint16 product_id)
|
||||
{
|
||||
if (vendor_id == USB_VENDOR_MICROSOFT) {
|
||||
if (product_id == USB_PRODUCT_XBOX_SERIES_X ||
|
||||
product_id == USB_PRODUCT_XBOX_SERIES_X_BLE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (vendor_id == USB_VENDOR_PDP) {
|
||||
if (product_id == USB_PRODUCT_XBOX_SERIES_X_VICTRIX_GAMBIT ||
|
||||
product_id == USB_PRODUCT_XBOX_SERIES_X_PDP_BLUE ||
|
||||
product_id == USB_PRODUCT_XBOX_SERIES_X_PDP_AFTERGLOW) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (vendor_id == USB_VENDOR_POWERA_ALT) {
|
||||
if ((product_id >= 0x2001 && product_id <= 0x201a) ||
|
||||
product_id == USB_PRODUCT_XBOX_SERIES_X_POWERA_FUSION_PRO2 ||
|
||||
product_id == USB_PRODUCT_XBOX_SERIES_X_POWERA_SPECTRA) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Opens a controller device
|
||||
static boolean Controller_OpenDevice(UINT8 which, INT32 devindex)
|
||||
{
|
||||
if (SDL_WasInit(GAMEPAD_INIT_FLAGS) == 0)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText("Game controller subsystems not started\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (devindex <= 0)
|
||||
return false;
|
||||
|
||||
if (SDL_NumJoysticks() == 0)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText("Found no controllers on this system\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
devindex--;
|
||||
|
||||
if (!SDL_IsGameController(devindex))
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText("Device index %d isn't a game controller\n"), devindex);
|
||||
return false;
|
||||
}
|
||||
|
||||
ControllerInfo *controller = &controllers[which];
|
||||
SDL_GameController *newdev = SDL_GameControllerOpen(devindex);
|
||||
|
||||
// Handle the edge case where the device <-> controller index assignment can change due to hotplugging
|
||||
// This indexing is SDL's responsibility and there's not much we can do about it.
|
||||
//
|
||||
// Example:
|
||||
// 1. Plug Controller A -> Index 0 opened
|
||||
// 2. Plug Controller B -> Index 1 opened
|
||||
// 3. Unplug Controller A -> Index 0 closed, Index 1 active
|
||||
// 4. Unplug Controller B -> Index 0 inactive, Index 1 closed
|
||||
// 5. Plug Controller B -> Index 0 opened
|
||||
// 6. Plug Controller A -> Index 0 REPLACED, opened as Controller A; Index 1 is now Controller B
|
||||
if (controller->dev)
|
||||
{
|
||||
if (controller->dev == newdev // same device, nothing to do
|
||||
|| (newdev == NULL && SDL_GameControllerGetAttached(controller->dev))) // we failed, but already have a working device
|
||||
return true;
|
||||
|
||||
// Else, we're changing devices, so close the controller
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText("Controller %d device is changing; closing controller...\n"), which);
|
||||
Controller_Close(which);
|
||||
}
|
||||
|
||||
if (newdev == NULL)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText("Controller %d: Couldn't open device - %s\n"), which, SDL_GetError());
|
||||
controller->started = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->dev = newdev;
|
||||
controller->joydev = SDL_GameControllerGetJoystick(controller->dev);
|
||||
controller->started = true;
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText("Controller %d: %s\n"), which, SDL_GameControllerName(controller->dev));
|
||||
|
||||
#define GAMEPAD_TYPE_CASE(ctrl) \
|
||||
case SDL_CONTROLLER_TYPE_##ctrl: \
|
||||
controller->info->type = GAMEPAD_TYPE_##ctrl; \
|
||||
break
|
||||
|
||||
switch (SDL_GameControllerGetType(newdev))
|
||||
{
|
||||
GAMEPAD_TYPE_CASE(UNKNOWN);
|
||||
GAMEPAD_TYPE_CASE(XBOX360);
|
||||
GAMEPAD_TYPE_CASE(XBOXONE);
|
||||
GAMEPAD_TYPE_CASE(PS3);
|
||||
GAMEPAD_TYPE_CASE(PS4);
|
||||
GAMEPAD_TYPE_CASE(PS5);
|
||||
GAMEPAD_TYPE_CASE(NINTENDO_SWITCH_PRO);
|
||||
GAMEPAD_TYPE_CASE(GOOGLE_STADIA);
|
||||
GAMEPAD_TYPE_CASE(AMAZON_LUNA);
|
||||
GAMEPAD_TYPE_CASE(VIRTUAL);
|
||||
default: break;
|
||||
}
|
||||
|
||||
#undef GAMEPAD_BUTTON_CASE
|
||||
|
||||
// Check the device vendor and product to find out what controller this actually is
|
||||
Uint16 vendor = SDL_JoystickGetDeviceVendor(devindex);
|
||||
Uint16 product = SDL_JoystickGetDeviceProduct(devindex);
|
||||
|
||||
if (IsJoystickXboxSeriesXS(vendor, product))
|
||||
controller->info->type = GAMEPAD_TYPE_XBOX_SERIES_XS;
|
||||
else if (IsJoystickXboxOneElite(vendor, product))
|
||||
controller->info->type = GAMEPAD_TYPE_XBOX_ELITE;
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText(" Type: %s\n"), G_GamepadTypeToString(controller->info->type));
|
||||
|
||||
// Change the ring LEDs on Xbox 360 controllers
|
||||
// TODO: Doesn't seem to work?
|
||||
SDL_GameControllerSetPlayerIndex(controller->dev, which);
|
||||
|
||||
// Check if rumble is supported
|
||||
if (SDL_GameControllerHasRumble(controller->dev) == SDL_TRUE)
|
||||
{
|
||||
controller->info->rumble.supported = true;
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText(" Rumble supported: Yes\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->info->rumble.supported = false;
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText(" Rumble supported: No\n"));;
|
||||
}
|
||||
|
||||
controller->info->connected = true;
|
||||
}
|
||||
|
||||
return controller->started;
|
||||
}
|
||||
|
||||
// Initializes a controller
|
||||
static INT32 Controller_Init(SDL_GameController **newcontroller, UINT8 which, INT32 *index)
|
||||
{
|
||||
ControllerInfo *info = &controllers[which];
|
||||
SDL_GameController *controller = NULL;
|
||||
INT32 device = (*index);
|
||||
|
||||
if (device && SDL_IsGameController(device - 1))
|
||||
controller = SDL_GameControllerOpen(device - 1);
|
||||
if (newcontroller)
|
||||
(*newcontroller) = controller;
|
||||
|
||||
if (controller && info->dev == controller) // don't override an active device
|
||||
(*index) = I_GetControllerIndex(info->dev) + 1;
|
||||
else if (controller && Controller_OpenDevice(which, device))
|
||||
{
|
||||
// SDL's device indexes are unstable, so cv_usegamepad may not match
|
||||
// the actual device index. So let's cheat a bit and find the device's current index.
|
||||
info->lastindex = I_GetControllerIndex(info->dev) + 1;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*index) = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Changes a controller's device
|
||||
static void Controller_ChangeDevice(UINT8 num)
|
||||
{
|
||||
SDL_GameController *newjoy = NULL;
|
||||
|
||||
if (!Controller_Init(&newjoy, num, &cv_usegamepad[num].value) && controllers[num].lastindex)
|
||||
Controller_Close(num);
|
||||
|
||||
I_CloseInactiveController(newjoy);
|
||||
}
|
||||
|
||||
static boolean Controller_IsAnyUsingDevice(SDL_GameController *dev)
|
||||
{
|
||||
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
|
||||
{
|
||||
if (controllers[i].dev == dev)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean Controller_IsAnyOtherUsingDevice(SDL_GameController *dev, UINT8 thisjoy)
|
||||
{
|
||||
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
|
||||
{
|
||||
if (i == thisjoy)
|
||||
continue;
|
||||
else if (controllers[i].dev == dev)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void I_ControllerDeviceAdded(INT32 which)
|
||||
{
|
||||
if (!SDL_IsGameController(which))
|
||||
return;
|
||||
|
||||
SDL_GameController *newjoy = SDL_GameControllerOpen(which);
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Gamepad device index %d added\n", which + 1);
|
||||
|
||||
// Because SDL's device index is unstable, we're going to cheat here a bit:
|
||||
// For the first controller setting that is NOT active:
|
||||
// 1. Set cv_usegamepadX.value to the new device index (this does not change what is written to config.cfg)
|
||||
// 2. Set OTHERS' cv_usegamepadX.value to THEIR new device index, because it likely changed
|
||||
// * If device doesn't exist, switch cv_usegamepad back to default value (.string)
|
||||
// * BUT: If that default index is being occupied, use ANOTHER cv_usegamepad's default value!
|
||||
for (UINT8 this = 0; this < NUM_GAMEPADS && newjoy; this++)
|
||||
{
|
||||
if ((!controllers[this].dev || !SDL_GameControllerGetAttached(controllers[this].dev))
|
||||
&& !Controller_IsAnyOtherUsingDevice(newjoy, this)) // don't override a currently active device
|
||||
{
|
||||
cv_usegamepad[this].value = which + 1;
|
||||
|
||||
// Go through every other device
|
||||
for (UINT8 other = 0; other < NUM_GAMEPADS; other++)
|
||||
{
|
||||
if (other == this)
|
||||
{
|
||||
// Don't change this controller's index
|
||||
continue;
|
||||
}
|
||||
else if (controllers[other].dev)
|
||||
{
|
||||
// Update this controller's index if the device is open
|
||||
cv_usegamepad[other].value = I_GetControllerIndex(controllers[other].dev) + 1;
|
||||
}
|
||||
else if (atoi(cv_usegamepad[other].string) != controllers[this].lastindex
|
||||
&& atoi(cv_usegamepad[other].string) != cv_usegamepad[this].value)
|
||||
{
|
||||
// If the user-set index for the other controller doesn't
|
||||
// match this controller's current or former internal index,
|
||||
// then use the other controller's internal index
|
||||
cv_usegamepad[other].value = atoi(cv_usegamepad[other].string);
|
||||
}
|
||||
else if (atoi(cv_usegamepad[this].string) != controllers[this].lastindex
|
||||
&& atoi(cv_usegamepad[this].string) != cv_usegamepad[this].value)
|
||||
{
|
||||
// If the user-set index for this controller doesn't match
|
||||
// its current or former internal index, then use this
|
||||
// controller's internal index
|
||||
cv_usegamepad[other].value = atoi(cv_usegamepad[this].string);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try again
|
||||
cv_usegamepad[other].value = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Was cv_usegamepad disabled in settings?
|
||||
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
|
||||
{
|
||||
if (!strcmp(cv_usegamepad[i].string, "0") || !cv_usegamepad[i].value)
|
||||
cv_usegamepad[i].value = 0;
|
||||
else if (atoi(cv_usegamepad[i].string) <= I_NumGamepads() // don't mess if we intentionally set higher than NumJoys
|
||||
&& cv_usegamepad[i].value) // update the cvar ONLY if a device exists
|
||||
CV_SetValue(&cv_usegamepad[i], cv_usegamepad[i].value);
|
||||
}
|
||||
|
||||
// Update all gamepads' init states
|
||||
// This is a little wasteful since cv_usegamepad already calls this, but
|
||||
// we need to do this in case CV_SetValue did nothing because the string was already same.
|
||||
// if the device is already active, this should do nothing, effectively.
|
||||
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
|
||||
{
|
||||
Controller_ChangeDevice(i);
|
||||
CONS_Debug(DBG_GAMELOGIC, "Controller %d device index: %d\n", i, controllers[i].lastindex);
|
||||
}
|
||||
|
||||
if (M_OnGamepadMenu())
|
||||
M_UpdateGamepadMenu();
|
||||
|
||||
I_CloseInactiveController(newjoy);
|
||||
}
|
||||
|
||||
void I_ControllerDeviceRemoved(void)
|
||||
{
|
||||
for (UINT8 this = 0; this < NUM_GAMEPADS; this++)
|
||||
{
|
||||
if (controllers[this].dev && !SDL_GameControllerGetAttached(controllers[this].dev))
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Controller %d removed, device index: %d\n", this, controllers[this].lastindex);
|
||||
G_OnGamepadDisconnect(this);
|
||||
Controller_Close(this);
|
||||
}
|
||||
|
||||
// Update the device indexes, because they likely changed
|
||||
// * If device doesn't exist, switch cv_usegamepad back to default value (.string)
|
||||
// * BUT: If that default index is being occupied, use ANOTHER cv_usegamepad's default value!
|
||||
if (controllers[this].dev)
|
||||
cv_usegamepad[this].value = controllers[this].lastindex = I_GetControllerIndex(controllers[this].dev) + 1;
|
||||
else
|
||||
{
|
||||
for (UINT8 other = 0; other < NUM_GAMEPADS; other++)
|
||||
{
|
||||
if (other == this)
|
||||
continue;
|
||||
|
||||
if (atoi(cv_usegamepad[this].string) != controllers[other].lastindex)
|
||||
{
|
||||
// Update this internal index if this user-set index
|
||||
// doesn't match the other's former internal index
|
||||
cv_usegamepad[this].value = atoi(cv_usegamepad[this].string);
|
||||
}
|
||||
else if (atoi(cv_usegamepad[other].string) != controllers[other].lastindex)
|
||||
{
|
||||
// Otherwise, set this internal index to the other's
|
||||
// user-set index, if the other user-set index is not the
|
||||
// same as the other's former internal index
|
||||
cv_usegamepad[this].value = atoi(cv_usegamepad[other].string);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try again
|
||||
cv_usegamepad[this].value = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Was cv_usegamepad disabled in settings?
|
||||
if (!strcmp(cv_usegamepad[this].string, "0"))
|
||||
cv_usegamepad[this].value = 0;
|
||||
else if (atoi(cv_usegamepad[this].string) <= I_NumGamepads() // don't mess if we intentionally set higher than NumJoys
|
||||
&& cv_usegamepad[this].value) // update the cvar ONLY if a device exists
|
||||
CV_SetValue(&cv_usegamepad[this], cv_usegamepad[this].value);
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Controller %d device index: %d\n", this, controllers[this].lastindex);
|
||||
}
|
||||
|
||||
if (M_OnGamepadMenu())
|
||||
M_UpdateGamepadMenu();
|
||||
}
|
||||
|
||||
// Close the controller device if there isn't any controller using it
|
||||
void I_CloseInactiveController(SDL_GameController *dev)
|
||||
{
|
||||
if (!Controller_IsAnyUsingDevice(dev))
|
||||
SDL_GameControllerClose(dev);
|
||||
}
|
||||
|
||||
// Cheat to get the device index for a game controller handle
|
||||
INT32 I_GetControllerIndex(SDL_GameController *dev)
|
||||
{
|
||||
INT32 i, count = SDL_NumJoysticks();
|
||||
|
||||
for (i = 0; dev && i < count; i++)
|
||||
{
|
||||
SDL_GameController *test = SDL_GameControllerOpen(i);
|
||||
if (test && test == dev)
|
||||
return i;
|
||||
else
|
||||
I_CloseInactiveController(test);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Changes a gamepad's device
|
||||
void I_ChangeGamepad(UINT8 which)
|
||||
{
|
||||
if (which >= NUM_GAMEPADS)
|
||||
return;
|
||||
|
||||
if (controllers[which].started)
|
||||
Controller_StopRumble(which);
|
||||
|
||||
Controller_ChangeDevice(which);
|
||||
}
|
||||
|
||||
// Returns the name of a controller from its index
|
||||
const char *I_GetGamepadName(INT32 joyindex)
|
||||
{
|
||||
static char joyname[256];
|
||||
joyname[0] = '\0';
|
||||
|
||||
if (SDL_WasInit(GAMEPAD_INIT_FLAGS) == GAMEPAD_INIT_FLAGS)
|
||||
{
|
||||
const char *tempname = SDL_GameControllerNameForIndex(joyindex - 1);
|
||||
if (tempname)
|
||||
strlcpy(joyname, tempname, sizeof joyname);
|
||||
}
|
||||
|
||||
return joyname;
|
||||
}
|
||||
|
||||
// Toggles a gamepad's digital axis setting
|
||||
void I_SetGamepadDigital(UINT8 which, boolean enable)
|
||||
{
|
||||
if (which >= NUM_GAMEPADS)
|
||||
return;
|
||||
|
||||
gamepads[which].digital = enable;
|
||||
}
|
||||
|
||||
static gamepad_t *Controller_GetFromID(SDL_JoystickID which, UINT8 *found)
|
||||
{
|
||||
// Determine the joystick IDs for each current open controller
|
||||
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
|
||||
{
|
||||
if (which == SDL_JoystickInstanceID(controllers[i].joydev))
|
||||
{
|
||||
(*found) = i;
|
||||
return &gamepads[i];
|
||||
}
|
||||
}
|
||||
|
||||
(*found) = UINT8_MAX;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void I_HandleControllerButtonEvent(SDL_ControllerButtonEvent evt, Uint32 type)
|
||||
{
|
||||
event_t event;
|
||||
|
||||
gamepad_t *gamepad = Controller_GetFromID(evt.which, &event.which);
|
||||
if (gamepad == NULL)
|
||||
return;
|
||||
|
||||
if (type == SDL_CONTROLLERBUTTONUP)
|
||||
event.type = ev_gamepad_up;
|
||||
else if (type == SDL_CONTROLLERBUTTONDOWN)
|
||||
event.type = ev_gamepad_down;
|
||||
else
|
||||
return;
|
||||
|
||||
#define GAMEPAD_BUTTON_CASE(btn) \
|
||||
case SDL_CONTROLLER_BUTTON_##btn: \
|
||||
event.key = GAMEPAD_BUTTON_##btn; \
|
||||
break
|
||||
|
||||
switch (evt.button)
|
||||
{
|
||||
GAMEPAD_BUTTON_CASE(A);
|
||||
GAMEPAD_BUTTON_CASE(B);
|
||||
GAMEPAD_BUTTON_CASE(X);
|
||||
GAMEPAD_BUTTON_CASE(Y);
|
||||
GAMEPAD_BUTTON_CASE(BACK);
|
||||
GAMEPAD_BUTTON_CASE(GUIDE);
|
||||
GAMEPAD_BUTTON_CASE(START);
|
||||
GAMEPAD_BUTTON_CASE(LEFTSTICK);
|
||||
GAMEPAD_BUTTON_CASE(RIGHTSTICK);
|
||||
GAMEPAD_BUTTON_CASE(LEFTSHOULDER);
|
||||
GAMEPAD_BUTTON_CASE(RIGHTSHOULDER);
|
||||
GAMEPAD_BUTTON_CASE(DPAD_UP);
|
||||
GAMEPAD_BUTTON_CASE(DPAD_DOWN);
|
||||
GAMEPAD_BUTTON_CASE(DPAD_LEFT);
|
||||
GAMEPAD_BUTTON_CASE(DPAD_RIGHT);
|
||||
GAMEPAD_BUTTON_CASE(MISC1);
|
||||
GAMEPAD_BUTTON_CASE(PADDLE1);
|
||||
GAMEPAD_BUTTON_CASE(PADDLE2);
|
||||
GAMEPAD_BUTTON_CASE(PADDLE3);
|
||||
GAMEPAD_BUTTON_CASE(PADDLE4);
|
||||
GAMEPAD_BUTTON_CASE(TOUCHPAD);
|
||||
default: return;
|
||||
}
|
||||
|
||||
#undef GAMEPAD_BUTTON_CASE
|
||||
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
|
||||
void I_HandleControllerAxisEvent(SDL_ControllerAxisEvent evt)
|
||||
{
|
||||
event_t event;
|
||||
|
||||
gamepad_t *gamepad = Controller_GetFromID(evt.which, &event.which);
|
||||
if (gamepad == NULL)
|
||||
return;
|
||||
|
||||
#define GAMEPAD_AXIS_CASE(btn) \
|
||||
case SDL_CONTROLLER_AXIS_##btn: \
|
||||
event.key = GAMEPAD_AXIS_##btn; \
|
||||
break
|
||||
|
||||
switch (evt.axis)
|
||||
{
|
||||
GAMEPAD_AXIS_CASE(LEFTX);
|
||||
GAMEPAD_AXIS_CASE(LEFTY);
|
||||
GAMEPAD_AXIS_CASE(RIGHTX);
|
||||
GAMEPAD_AXIS_CASE(RIGHTY);
|
||||
GAMEPAD_AXIS_CASE(TRIGGERLEFT);
|
||||
GAMEPAD_AXIS_CASE(TRIGGERRIGHT);
|
||||
default: return;
|
||||
}
|
||||
|
||||
#undef GAMEPAD_AXIS_CASE
|
||||
|
||||
event.type = ev_gamepad_axis;
|
||||
event.x = evt.value;
|
||||
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
|
||||
static void Controller_StopRumble(UINT8 num)
|
||||
{
|
||||
ControllerInfo *controller = &controllers[num];
|
||||
|
||||
controller->rumble.large_magnitude = 0;
|
||||
controller->rumble.small_magnitude = 0;
|
||||
controller->rumble.time_left = 0;
|
||||
controller->rumble.expiration = 0;
|
||||
|
||||
gamepad_t *gamepad = controller->info;
|
||||
|
||||
gamepad->rumble.active = false;
|
||||
gamepad->rumble.paused = false;
|
||||
gamepad->rumble.data.large_magnitude = 0;
|
||||
gamepad->rumble.data.small_magnitude = 0;
|
||||
gamepad->rumble.data.duration = 0;
|
||||
|
||||
if (gamepad->rumble.supported)
|
||||
SDL_GameControllerRumble(controller->dev, 0, 0, 0);
|
||||
}
|
||||
|
||||
static void Controller_Close(UINT8 num)
|
||||
{
|
||||
ControllerInfo *controller = &controllers[num];
|
||||
|
||||
// Close the game controller device
|
||||
if (controller->dev)
|
||||
{
|
||||
Controller_StopRumble(num);
|
||||
SDL_GameControllerClose(controller->dev);
|
||||
}
|
||||
|
||||
controller->dev = NULL;
|
||||
controller->joydev = NULL;
|
||||
controller->lastindex = -1;
|
||||
controller->started = false;
|
||||
|
||||
// Reset gamepad info
|
||||
gamepad_t *gamepad = controller->info;
|
||||
|
||||
if (gamepad)
|
||||
{
|
||||
gamepad->type = GAMEPAD_TYPE_UNKNOWN;
|
||||
gamepad->connected = false;
|
||||
gamepad->digital = false;
|
||||
gamepad->rumble.supported = false;
|
||||
|
||||
for (UINT8 i = 0; i < NUM_GAMEPAD_BUTTONS; i++)
|
||||
gamepad->buttons[i] = 0;
|
||||
|
||||
for (UINT8 i = 0; i < NUM_GAMEPAD_AXES; i++)
|
||||
gamepad->axes[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void I_ShutdownGamepads(void)
|
||||
{
|
||||
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
|
||||
Controller_Close(i);
|
||||
}
|
||||
|
||||
boolean I_RumbleSupported(void)
|
||||
{
|
||||
return rumble_supported;
|
||||
}
|
||||
|
||||
static boolean Controller_Rumble(ControllerInfo *c)
|
||||
{
|
||||
if (SDL_GameControllerRumble(c->dev, c->rumble.large_magnitude, c->rumble.small_magnitude, 0) == -1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void I_ToggleControllerRumble(boolean unpause)
|
||||
{
|
||||
if (!I_RumbleSupported() || rumble_paused == !unpause)
|
||||
return;
|
||||
|
||||
rumble_paused = !unpause;
|
||||
|
||||
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
|
||||
{
|
||||
ControllerInfo *controller = &controllers[i];
|
||||
if (!controller->started || !controller->info->rumble.supported)
|
||||
continue;
|
||||
|
||||
if (rumble_paused)
|
||||
SDL_GameControllerRumble(controller->dev, 0, 0, 0);
|
||||
else if (!controller->info->rumble.paused)
|
||||
{
|
||||
if (!Controller_Rumble(controller))
|
||||
controller->rumble.expiration = controller->rumble.time_left = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void I_UpdateControllers(void)
|
||||
{
|
||||
if (SDL_WasInit(GAMEPAD_INIT_FLAGS) != GAMEPAD_INIT_FLAGS)
|
||||
return;
|
||||
|
||||
for (UINT8 i = 0; i < NUM_GAMEPADS; i++)
|
||||
{
|
||||
ControllerInfo *controller = &controllers[i];
|
||||
if (!controller->started || !controller->info->rumble.supported || controller->info->rumble.paused)
|
||||
continue;
|
||||
|
||||
if (controller->rumble.expiration &&
|
||||
SDL_TICKS_PASSED(SDL_GetTicks(), controller->rumble.expiration))
|
||||
{
|
||||
// Enough time has passed, so stop the effect
|
||||
Controller_StopRumble(i);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_JoystickUpdate();
|
||||
}
|
||||
|
||||
// Converts duration in tics to milliseconds
|
||||
#define TICS_TO_MS(tics) ((INT32)(tics * (1000.0f/TICRATE)))
|
||||
|
||||
boolean I_RumbleGamepad(UINT8 which, const haptic_t *effect)
|
||||
{
|
||||
if (!I_RumbleSupported() || which >= NUM_GAMEPADS)
|
||||
return false;
|
||||
|
||||
ControllerInfo *controller = &controllers[which];
|
||||
if (!controller->started || !controller->info->rumble.supported)
|
||||
return false;
|
||||
|
||||
UINT16 duration = min(TICS_TO_MS(effect->duration), UINT16_MAX);
|
||||
UINT16 large_magnitude = max(0, min(effect->large_magnitude, UINT16_MAX));
|
||||
UINT16 small_magnitude = max(0, min(effect->small_magnitude, UINT16_MAX));
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Starting rumble effect for controller %d:\n", which);
|
||||
CONS_Debug(DBG_GAMELOGIC, " Large motor magnitude: %f\n", large_magnitude / 65535.0f);
|
||||
CONS_Debug(DBG_GAMELOGIC, " Small motor magnitude: %f\n", small_magnitude / 65535.0f);
|
||||
|
||||
if (!duration)
|
||||
CONS_Debug(DBG_GAMELOGIC, " Duration: forever\n");
|
||||
else
|
||||
CONS_Debug(DBG_GAMELOGIC, " Duration: %dms\n", duration);
|
||||
|
||||
controller->rumble.large_magnitude = large_magnitude;
|
||||
controller->rumble.small_magnitude = small_magnitude;
|
||||
|
||||
if (!rumble_paused && !Controller_Rumble(controller))
|
||||
{
|
||||
Controller_StopRumble(which);
|
||||
return false;
|
||||
}
|
||||
|
||||
controller->rumble.time_left = 0;
|
||||
|
||||
if (duration)
|
||||
controller->rumble.expiration = SDL_GetTicks() + duration;
|
||||
else
|
||||
controller->rumble.expiration = 0;
|
||||
|
||||
// Update gamepad rumble info
|
||||
gamepad_t *gamepad = controller->info;
|
||||
|
||||
gamepad->rumble.active = true;
|
||||
gamepad->rumble.paused = false;
|
||||
gamepad->rumble.data.large_magnitude = effect->large_magnitude;
|
||||
gamepad->rumble.data.small_magnitude = effect->small_magnitude;
|
||||
gamepad->rumble.data.duration = effect->duration;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef TICS_TO_MS
|
||||
|
||||
#define SET_MOTOR_FREQ(type) \
|
||||
if (!I_RumbleSupported() || which >= NUM_GAMEPADS) \
|
||||
return false; \
|
||||
\
|
||||
ControllerInfo *controller = &controllers[which]; \
|
||||
if (!controller->started || !controller->info->rumble.supported) \
|
||||
return false; \
|
||||
\
|
||||
gamepad_t *gamepad = controller->info; \
|
||||
if (gamepad->rumble.data.type##_magnitude == freq) \
|
||||
return true; \
|
||||
\
|
||||
UINT16 frequency = max(0, min(freq, UINT16_MAX)); \
|
||||
\
|
||||
controller->rumble.type##_magnitude = frequency; \
|
||||
\
|
||||
if (!rumble_paused && !gamepad->rumble.paused && !Controller_Rumble(controller)) \
|
||||
{ \
|
||||
Controller_StopRumble(which); \
|
||||
return false; \
|
||||
} \
|
||||
\
|
||||
gamepad->rumble.data.type##_magnitude = freq; \
|
||||
gamepad->rumble.active = true; \
|
||||
return true
|
||||
|
||||
boolean I_SetGamepadLargeMotorFreq(UINT8 which, fixed_t freq)
|
||||
{
|
||||
SET_MOTOR_FREQ(large);
|
||||
}
|
||||
|
||||
boolean I_SetGamepadSmallMotorFreq(UINT8 which, fixed_t freq)
|
||||
{
|
||||
SET_MOTOR_FREQ(small);
|
||||
}
|
||||
|
||||
void I_SetGamepadRumblePaused(UINT8 which, boolean pause)
|
||||
{
|
||||
if (!I_RumbleSupported() || which >= NUM_GAMEPADS)
|
||||
return;
|
||||
|
||||
ControllerInfo *controller = &controllers[which];
|
||||
if (!controller->started || !controller->info->rumble.supported)
|
||||
return;
|
||||
|
||||
if (pause == controller->info->rumble.paused)
|
||||
return;
|
||||
else if (pause)
|
||||
{
|
||||
if (!rumble_paused)
|
||||
SDL_GameControllerRumble(controller->dev, 0, 0, 0);
|
||||
|
||||
if (controller->rumble.expiration)
|
||||
{
|
||||
controller->rumble.time_left = controller->rumble.expiration - SDL_GetTicks();
|
||||
controller->rumble.expiration = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!rumble_paused)
|
||||
SDL_GameControllerRumble(controller->dev, controller->rumble.large_magnitude, controller->rumble.small_magnitude, 0);
|
||||
|
||||
if (controller->rumble.time_left)
|
||||
controller->rumble.expiration = SDL_GetTicks() + controller->rumble.time_left;
|
||||
}
|
||||
|
||||
controller->info->rumble.paused = pause;
|
||||
}
|
||||
|
||||
boolean I_GetGamepadRumbleSupported(UINT8 which)
|
||||
{
|
||||
if (!I_RumbleSupported() || which >= NUM_GAMEPADS)
|
||||
return false;
|
||||
|
||||
ControllerInfo *controller = &controllers[which];
|
||||
if (!controller->started)
|
||||
return false;
|
||||
|
||||
return controller->info->rumble.supported;
|
||||
}
|
||||
|
||||
boolean I_GetGamepadRumblePaused(UINT8 which)
|
||||
{
|
||||
if (!I_RumbleSupported() || which >= NUM_GAMEPADS)
|
||||
return false;
|
||||
|
||||
ControllerInfo *controller = &controllers[which];
|
||||
if (!controller->started || !controller->info->rumble.supported)
|
||||
return false;
|
||||
|
||||
return controller->info->rumble.paused;
|
||||
}
|
||||
|
||||
void I_StopGamepadRumble(UINT8 which)
|
||||
{
|
||||
if (!I_RumbleSupported() || which >= NUM_GAMEPADS)
|
||||
return;
|
||||
|
||||
ControllerInfo *controller = &controllers[which];
|
||||
if (!controller->started || !controller->info->rumble.supported)
|
||||
return;
|
||||
|
||||
Controller_StopRumble(which);
|
||||
}
|
||||
#endif
|
|
@ -185,7 +185,6 @@ static char returnWadPath[256];
|
|||
#include "../i_video.h"
|
||||
#include "../i_sound.h"
|
||||
#include "../i_system.h"
|
||||
#include "../i_gamepad.h"
|
||||
#include "../i_threads.h"
|
||||
#include "../screen.h" //vid.WndParent
|
||||
#include "../d_net.h"
|
||||
|
@ -194,6 +193,8 @@ static char returnWadPath[256];
|
|||
#include "endtxt.h"
|
||||
#include "sdlmain.h"
|
||||
|
||||
#include "../i_joy.h"
|
||||
|
||||
#include "../m_argv.h"
|
||||
|
||||
#include "../r_main.h" // Frame interpolation/uncapped
|
||||
|
@ -211,6 +212,41 @@ static char returnWadPath[256];
|
|||
#include "../byteptr.h"
|
||||
#endif
|
||||
|
||||
/** \brief The JoyReset function
|
||||
|
||||
\param JoySet Joystick info to reset
|
||||
|
||||
\return void
|
||||
*/
|
||||
static void JoyReset(SDLJoyInfo_t *JoySet)
|
||||
{
|
||||
if (JoySet->dev)
|
||||
{
|
||||
SDL_JoystickClose(JoySet->dev);
|
||||
}
|
||||
JoySet->dev = NULL;
|
||||
JoySet->oldjoy = -1;
|
||||
JoySet->axises = JoySet->buttons = JoySet->hats = JoySet->balls = 0;
|
||||
//JoySet->scale
|
||||
}
|
||||
|
||||
/** \brief First joystick up and running
|
||||
*/
|
||||
static INT32 joystick_started = 0;
|
||||
|
||||
/** \brief SDL info about joystick 1
|
||||
*/
|
||||
SDLJoyInfo_t JoyInfo;
|
||||
|
||||
|
||||
/** \brief Second joystick up and running
|
||||
*/
|
||||
static INT32 joystick2_started = 0;
|
||||
|
||||
/** \brief SDL inof about joystick 2
|
||||
*/
|
||||
SDLJoyInfo_t JoyInfo2;
|
||||
|
||||
#ifdef HAVE_TERMIOS
|
||||
static INT32 fdmouse2 = -1;
|
||||
static INT32 mouse2_started = 0;
|
||||
|
@ -903,17 +939,721 @@ INT32 I_GetKey (void)
|
|||
return rc;
|
||||
}
|
||||
|
||||
//
|
||||
// I_JoyScale
|
||||
//
|
||||
void I_JoyScale(void)
|
||||
{
|
||||
Joystick.bGamepadStyle = cv_joyscale.value==0;
|
||||
JoyInfo.scale = Joystick.bGamepadStyle?1:cv_joyscale.value;
|
||||
}
|
||||
|
||||
void I_JoyScale2(void)
|
||||
{
|
||||
Joystick2.bGamepadStyle = cv_joyscale2.value==0;
|
||||
JoyInfo2.scale = Joystick2.bGamepadStyle?1:cv_joyscale2.value;
|
||||
}
|
||||
|
||||
// Cheat to get the device index for a joystick handle
|
||||
INT32 I_GetJoystickDeviceIndex(SDL_Joystick *dev)
|
||||
{
|
||||
INT32 i, count = SDL_NumJoysticks();
|
||||
|
||||
for (i = 0; dev && i < count; i++)
|
||||
{
|
||||
SDL_Joystick *test = SDL_JoystickOpen(i);
|
||||
if (test && test == dev)
|
||||
return i;
|
||||
else if (JoyInfo.dev != test && JoyInfo2.dev != test)
|
||||
SDL_JoystickClose(test);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** \brief Joystick 1 buttons states
|
||||
*/
|
||||
static UINT64 lastjoybuttons = 0;
|
||||
|
||||
/** \brief Joystick 1 hats state
|
||||
*/
|
||||
static UINT64 lastjoyhats = 0;
|
||||
|
||||
/** \brief Shuts down joystick 1
|
||||
|
||||
|
||||
\return void
|
||||
|
||||
|
||||
*/
|
||||
void I_ShutdownJoystick(void)
|
||||
{
|
||||
INT32 i;
|
||||
event_t event;
|
||||
event.type=ev_keyup;
|
||||
event.x = 0;
|
||||
event.y = 0;
|
||||
|
||||
lastjoybuttons = lastjoyhats = 0;
|
||||
|
||||
// emulate the up of all joystick buttons
|
||||
for (i=0;i<JOYBUTTONS;i++)
|
||||
{
|
||||
event.key=KEY_JOY1+i;
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
|
||||
// emulate the up of all joystick hats
|
||||
for (i=0;i<JOYHATS*4;i++)
|
||||
{
|
||||
event.key=KEY_HAT1+i;
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
|
||||
// reset joystick position
|
||||
event.type = ev_joystick;
|
||||
for (i=0;i<JOYAXISSET; i++)
|
||||
{
|
||||
event.key = i;
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
|
||||
joystick_started = 0;
|
||||
JoyReset(&JoyInfo);
|
||||
|
||||
// don't shut down the subsystem here, because hotplugging
|
||||
}
|
||||
|
||||
void I_GetJoystickEvents(void)
|
||||
{
|
||||
static event_t event = {0,0,0,0,false};
|
||||
INT32 i = 0;
|
||||
UINT64 joyhats = 0;
|
||||
#if 0
|
||||
UINT64 joybuttons = 0;
|
||||
Sint16 axisx, axisy;
|
||||
#endif
|
||||
|
||||
if (!joystick_started) return;
|
||||
|
||||
if (!JoyInfo.dev) //I_ShutdownJoystick();
|
||||
return;
|
||||
|
||||
#if 0
|
||||
//faB: look for as much buttons as g_input code supports,
|
||||
// we don't use the others
|
||||
for (i = JoyInfo.buttons - 1; i >= 0; i--)
|
||||
{
|
||||
joybuttons <<= 1;
|
||||
if (SDL_JoystickGetButton(JoyInfo.dev,i))
|
||||
joybuttons |= 1;
|
||||
}
|
||||
|
||||
if (joybuttons != lastjoybuttons)
|
||||
{
|
||||
INT64 j = 1; // keep only bits that changed since last time
|
||||
INT64 newbuttons = joybuttons ^ lastjoybuttons;
|
||||
lastjoybuttons = joybuttons;
|
||||
|
||||
for (i = 0; i < JOYBUTTONS; i++, j <<= 1)
|
||||
{
|
||||
if (newbuttons & j) // button changed state?
|
||||
{
|
||||
if (joybuttons & j)
|
||||
event.type = ev_keydown;
|
||||
else
|
||||
event.type = ev_keyup;
|
||||
event.key = KEY_JOY1 + i;
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = JoyInfo.hats - 1; i >= 0; i--)
|
||||
{
|
||||
Uint8 hat = SDL_JoystickGetHat(JoyInfo.dev, i);
|
||||
|
||||
if (hat & SDL_HAT_UP ) joyhats|=(UINT64)0x1<<(0 + 4*i);
|
||||
if (hat & SDL_HAT_DOWN ) joyhats|=(UINT64)0x1<<(1 + 4*i);
|
||||
if (hat & SDL_HAT_LEFT ) joyhats|=(UINT64)0x1<<(2 + 4*i);
|
||||
if (hat & SDL_HAT_RIGHT) joyhats|=(UINT64)0x1<<(3 + 4*i);
|
||||
}
|
||||
|
||||
if (joyhats != lastjoyhats)
|
||||
{
|
||||
INT64 j = 1; // keep only bits that changed since last time
|
||||
INT64 newhats = joyhats ^ lastjoyhats;
|
||||
lastjoyhats = joyhats;
|
||||
|
||||
for (i = 0; i < JOYHATS*4; i++, j <<= 1)
|
||||
{
|
||||
if (newhats & j) // hat changed state?
|
||||
{
|
||||
if (joyhats & j)
|
||||
event.type = ev_keydown;
|
||||
else
|
||||
event.type = ev_keyup;
|
||||
event.key = KEY_HAT1 + i;
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// send joystick axis positions
|
||||
event.type = ev_joystick;
|
||||
|
||||
for (i = JOYAXISSET - 1; i >= 0; i--)
|
||||
{
|
||||
event.key = i;
|
||||
if (i*2 + 1 <= JoyInfo.axises)
|
||||
axisx = SDL_JoystickGetAxis(JoyInfo.dev, i*2 + 0);
|
||||
else axisx = 0;
|
||||
if (i*2 + 2 <= JoyInfo.axises)
|
||||
axisy = SDL_JoystickGetAxis(JoyInfo.dev, i*2 + 1);
|
||||
else axisy = 0;
|
||||
|
||||
|
||||
// -32768 to 32767
|
||||
axisx = axisx/32;
|
||||
axisy = axisy/32;
|
||||
|
||||
|
||||
if (Joystick.bGamepadStyle)
|
||||
{
|
||||
// gamepad control type, on or off, live or die
|
||||
if (axisx < -(JOYAXISRANGE/2))
|
||||
event.x = -1;
|
||||
else if (axisx > (JOYAXISRANGE/2))
|
||||
event.x = 1;
|
||||
else event.x = 0;
|
||||
if (axisy < -(JOYAXISRANGE/2))
|
||||
event.y = -1;
|
||||
else if (axisy > (JOYAXISRANGE/2))
|
||||
event.y = 1;
|
||||
else event.y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
axisx = JoyInfo.scale?((axisx/JoyInfo.scale)*JoyInfo.scale):axisx;
|
||||
axisy = JoyInfo.scale?((axisy/JoyInfo.scale)*JoyInfo.scale):axisy;
|
||||
|
||||
#ifdef SDL_JDEADZONE
|
||||
if (-SDL_JDEADZONE <= axisx && axisx <= SDL_JDEADZONE) axisx = 0;
|
||||
if (-SDL_JDEADZONE <= axisy && axisy <= SDL_JDEADZONE) axisy = 0;
|
||||
#endif
|
||||
|
||||
// analog control style , just send the raw data
|
||||
event.x = axisx; // x axis
|
||||
event.y = axisy; // y axis
|
||||
}
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Open joystick handle
|
||||
|
||||
\param fname name of joystick
|
||||
|
||||
\return axises
|
||||
|
||||
|
||||
*/
|
||||
static int joy_open(int joyindex)
|
||||
{
|
||||
SDL_Joystick *newdev = NULL;
|
||||
int num_joy = 0;
|
||||
|
||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
|
||||
{
|
||||
CONS_Printf(M_GetText("Joystick subsystem not started\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (joyindex <= 0)
|
||||
return -1;
|
||||
|
||||
num_joy = SDL_NumJoysticks();
|
||||
|
||||
if (num_joy == 0)
|
||||
{
|
||||
CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
newdev = SDL_JoystickOpen(joyindex-1);
|
||||
|
||||
// Handle the edge case where the device <-> joystick index assignment can change due to hotplugging
|
||||
// This indexing is SDL's responsibility and there's not much we can do about it.
|
||||
//
|
||||
// Example:
|
||||
// 1. Plug Controller A -> Index 0 opened
|
||||
// 2. Plug Controller B -> Index 1 opened
|
||||
// 3. Unplug Controller A -> Index 0 closed, Index 1 active
|
||||
// 4. Unplug Controller B -> Index 0 inactive, Index 1 closed
|
||||
// 5. Plug Controller B -> Index 0 opened
|
||||
// 6. Plug Controller A -> Index 0 REPLACED, opened as Controller A; Index 1 is now Controller B
|
||||
if (JoyInfo.dev)
|
||||
{
|
||||
if (JoyInfo.dev == newdev // same device, nothing to do
|
||||
|| (newdev == NULL && SDL_JoystickGetAttached(JoyInfo.dev))) // we failed, but already have a working device
|
||||
return JoyInfo.axises;
|
||||
// Else, we're changing devices, so send neutral joy events
|
||||
CONS_Debug(DBG_GAMELOGIC, "Joystick1 device is changing; resetting events...\n");
|
||||
I_ShutdownJoystick();
|
||||
}
|
||||
|
||||
JoyInfo.dev = newdev;
|
||||
|
||||
if (JoyInfo.dev == NULL)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick1: Couldn't open device - %s\n"), SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick1: %s\n"), SDL_JoystickName(JoyInfo.dev));
|
||||
JoyInfo.axises = SDL_JoystickNumAxes(JoyInfo.dev);
|
||||
if (JoyInfo.axises > JOYAXISSET*2)
|
||||
JoyInfo.axises = JOYAXISSET*2;
|
||||
/* if (joyaxes<2)
|
||||
{
|
||||
I_OutputMsg("Not enought axes?\n");
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
JoyInfo.buttons = SDL_JoystickNumButtons(JoyInfo.dev);
|
||||
if (JoyInfo.buttons > JOYBUTTONS)
|
||||
JoyInfo.buttons = JOYBUTTONS;
|
||||
|
||||
JoyInfo.hats = SDL_JoystickNumHats(JoyInfo.dev);
|
||||
if (JoyInfo.hats > JOYHATS)
|
||||
JoyInfo.hats = JOYHATS;
|
||||
|
||||
JoyInfo.balls = SDL_JoystickNumBalls(JoyInfo.dev);
|
||||
|
||||
//Joystick.bGamepadStyle = !stricmp(SDL_JoystickName(JoyInfo.dev), "pad");
|
||||
|
||||
return JoyInfo.axises;
|
||||
}
|
||||
}
|
||||
|
||||
//Joystick2
|
||||
|
||||
/** \brief Joystick 2 buttons states
|
||||
*/
|
||||
static UINT64 lastjoy2buttons = 0;
|
||||
|
||||
/** \brief Joystick 2 hats state
|
||||
*/
|
||||
static UINT64 lastjoy2hats = 0;
|
||||
|
||||
/** \brief Shuts down joystick 2
|
||||
|
||||
|
||||
\return void
|
||||
*/
|
||||
void I_ShutdownJoystick2(void)
|
||||
{
|
||||
INT32 i;
|
||||
event_t event;
|
||||
event.type = ev_keyup;
|
||||
event.x = 0;
|
||||
event.y = 0;
|
||||
|
||||
lastjoy2buttons = lastjoy2hats = 0;
|
||||
|
||||
// emulate the up of all joystick buttons
|
||||
for (i = 0; i < JOYBUTTONS; i++)
|
||||
{
|
||||
event.key = KEY_2JOY1 + i;
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
|
||||
// emulate the up of all joystick hats
|
||||
for (i = 0; i < JOYHATS*4; i++)
|
||||
{
|
||||
event.key = KEY_2HAT1 + i;
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
|
||||
// reset joystick position
|
||||
event.type = ev_joystick2;
|
||||
for (i = 0; i < JOYAXISSET; i++)
|
||||
{
|
||||
event.key = i;
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
|
||||
joystick2_started = 0;
|
||||
JoyReset(&JoyInfo2);
|
||||
|
||||
// don't shut down the subsystem here, because hotplugging
|
||||
}
|
||||
|
||||
void I_GetJoystick2Events(void)
|
||||
{
|
||||
static event_t event = {0,0,0,0,false};
|
||||
INT32 i = 0;
|
||||
UINT64 joyhats = 0;
|
||||
#if 0
|
||||
INT64 joybuttons = 0;
|
||||
INT32 axisx, axisy;
|
||||
#endif
|
||||
|
||||
if (!joystick2_started)
|
||||
return;
|
||||
|
||||
if (!JoyInfo2.dev) //I_ShutdownJoystick2();
|
||||
return;
|
||||
|
||||
|
||||
#if 0
|
||||
//faB: look for as much buttons as g_input code supports,
|
||||
// we don't use the others
|
||||
for (i = JoyInfo2.buttons - 1; i >= 0; i--)
|
||||
{
|
||||
joybuttons <<= 1;
|
||||
if (SDL_JoystickGetButton(JoyInfo2.dev,i))
|
||||
joybuttons |= 1;
|
||||
}
|
||||
|
||||
if (joybuttons != lastjoy2buttons)
|
||||
{
|
||||
INT64 j = 1; // keep only bits that changed since last time
|
||||
INT64 newbuttons = joybuttons ^ lastjoy2buttons;
|
||||
lastjoy2buttons = joybuttons;
|
||||
|
||||
for (i = 0; i < JOYBUTTONS; i++, j <<= 1)
|
||||
{
|
||||
if (newbuttons & j) // button changed state?
|
||||
{
|
||||
if (joybuttons & j)
|
||||
event.type = ev_keydown;
|
||||
else
|
||||
event.type = ev_keyup;
|
||||
event.key = KEY_2JOY1 + i;
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = JoyInfo2.hats - 1; i >= 0; i--)
|
||||
{
|
||||
Uint8 hat = SDL_JoystickGetHat(JoyInfo2.dev, i);
|
||||
|
||||
if (hat & SDL_HAT_UP ) joyhats|=(UINT64)0x1<<(0 + 4*i);
|
||||
if (hat & SDL_HAT_DOWN ) joyhats|=(UINT64)0x1<<(1 + 4*i);
|
||||
if (hat & SDL_HAT_LEFT ) joyhats|=(UINT64)0x1<<(2 + 4*i);
|
||||
if (hat & SDL_HAT_RIGHT) joyhats|=(UINT64)0x1<<(3 + 4*i);
|
||||
}
|
||||
|
||||
if (joyhats != lastjoy2hats)
|
||||
{
|
||||
INT64 j = 1; // keep only bits that changed since last time
|
||||
INT64 newhats = joyhats ^ lastjoy2hats;
|
||||
lastjoy2hats = joyhats;
|
||||
|
||||
for (i = 0; i < JOYHATS*4; i++, j <<= 1)
|
||||
{
|
||||
if (newhats & j) // hat changed state?
|
||||
{
|
||||
if (joyhats & j)
|
||||
event.type = ev_keydown;
|
||||
else
|
||||
event.type = ev_keyup;
|
||||
event.key = KEY_2HAT1 + i;
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// send joystick axis positions
|
||||
event.type = ev_joystick2;
|
||||
|
||||
for (i = JOYAXISSET - 1; i >= 0; i--)
|
||||
{
|
||||
event.key = i;
|
||||
if (i*2 + 1 <= JoyInfo2.axises)
|
||||
axisx = SDL_JoystickGetAxis(JoyInfo2.dev, i*2 + 0);
|
||||
else axisx = 0;
|
||||
if (i*2 + 2 <= JoyInfo2.axises)
|
||||
axisy = SDL_JoystickGetAxis(JoyInfo2.dev, i*2 + 1);
|
||||
else axisy = 0;
|
||||
|
||||
// -32768 to 32767
|
||||
axisx = axisx/32;
|
||||
axisy = axisy/32;
|
||||
|
||||
if (Joystick2.bGamepadStyle)
|
||||
{
|
||||
// gamepad control type, on or off, live or die
|
||||
if (axisx < -(JOYAXISRANGE/2))
|
||||
event.x = -1;
|
||||
else if (axisx > (JOYAXISRANGE/2))
|
||||
event.x = 1;
|
||||
else
|
||||
event.x = 0;
|
||||
if (axisy < -(JOYAXISRANGE/2))
|
||||
event.y = -1;
|
||||
else if (axisy > (JOYAXISRANGE/2))
|
||||
event.y = 1;
|
||||
else
|
||||
event.y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
axisx = JoyInfo2.scale?((axisx/JoyInfo2.scale)*JoyInfo2.scale):axisx;
|
||||
axisy = JoyInfo2.scale?((axisy/JoyInfo2.scale)*JoyInfo2.scale):axisy;
|
||||
|
||||
#ifdef SDL_JDEADZONE
|
||||
if (-SDL_JDEADZONE <= axisx && axisx <= SDL_JDEADZONE) axisx = 0;
|
||||
if (-SDL_JDEADZONE <= axisy && axisy <= SDL_JDEADZONE) axisy = 0;
|
||||
#endif
|
||||
|
||||
// analog control style , just send the raw data
|
||||
event.x = axisx; // x axis
|
||||
event.y = axisy; // y axis
|
||||
}
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Open joystick handle
|
||||
|
||||
\param fname name of joystick
|
||||
|
||||
\return axises
|
||||
|
||||
|
||||
*/
|
||||
static int joy_open2(int joyindex)
|
||||
{
|
||||
SDL_Joystick *newdev = NULL;
|
||||
int num_joy = 0;
|
||||
|
||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
|
||||
{
|
||||
CONS_Printf(M_GetText("Joystick subsystem not started\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (joyindex <= 0)
|
||||
return -1;
|
||||
|
||||
num_joy = SDL_NumJoysticks();
|
||||
|
||||
if (num_joy == 0)
|
||||
{
|
||||
CONS_Printf("%s", M_GetText("Found no joysticks on this system\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
newdev = SDL_JoystickOpen(joyindex-1);
|
||||
|
||||
// Handle the edge case where the device <-> joystick index assignment can change due to hotplugging
|
||||
// This indexing is SDL's responsibility and there's not much we can do about it.
|
||||
//
|
||||
// Example:
|
||||
// 1. Plug Controller A -> Index 0 opened
|
||||
// 2. Plug Controller B -> Index 1 opened
|
||||
// 3. Unplug Controller A -> Index 0 closed, Index 1 active
|
||||
// 4. Unplug Controller B -> Index 0 inactive, Index 1 closed
|
||||
// 5. Plug Controller B -> Index 0 opened
|
||||
// 6. Plug Controller A -> Index 0 REPLACED, opened as Controller A; Index 1 is now Controller B
|
||||
if (JoyInfo2.dev)
|
||||
{
|
||||
if (JoyInfo2.dev == newdev // same device, nothing to do
|
||||
|| (newdev == NULL && SDL_JoystickGetAttached(JoyInfo2.dev))) // we failed, but already have a working device
|
||||
return JoyInfo.axises;
|
||||
// Else, we're changing devices, so send neutral joy events
|
||||
CONS_Debug(DBG_GAMELOGIC, "Joystick2 device is changing; resetting events...\n");
|
||||
I_ShutdownJoystick2();
|
||||
}
|
||||
|
||||
JoyInfo2.dev = newdev;
|
||||
|
||||
if (JoyInfo2.dev == NULL)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick2: couldn't open device - %s\n"), SDL_GetError());
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText("Joystick2: %s\n"), SDL_JoystickName(JoyInfo2.dev));
|
||||
JoyInfo2.axises = SDL_JoystickNumAxes(JoyInfo2.dev);
|
||||
if (JoyInfo2.axises > JOYAXISSET*2)
|
||||
JoyInfo2.axises = JOYAXISSET*2;
|
||||
/* if (joyaxes<2)
|
||||
{
|
||||
I_OutputMsg("Not enought axes?\n");
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
JoyInfo2.buttons = SDL_JoystickNumButtons(JoyInfo2.dev);
|
||||
if (JoyInfo2.buttons > JOYBUTTONS)
|
||||
JoyInfo2.buttons = JOYBUTTONS;
|
||||
|
||||
JoyInfo2.hats = SDL_JoystickNumHats(JoyInfo2.dev);
|
||||
if (JoyInfo2.hats > JOYHATS)
|
||||
JoyInfo2.hats = JOYHATS;
|
||||
|
||||
JoyInfo2.balls = SDL_JoystickNumBalls(JoyInfo2.dev);
|
||||
|
||||
//Joystick.bGamepadStyle = !stricmp(SDL_JoystickName(JoyInfo2.dev), "pad");
|
||||
|
||||
return JoyInfo2.axises;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// I_InitJoystick
|
||||
//
|
||||
void I_InitJoystick(void)
|
||||
{
|
||||
SDL_Joystick *newjoy = NULL;
|
||||
|
||||
//I_ShutdownJoystick();
|
||||
if (M_CheckParm("-nojoy"))
|
||||
return;
|
||||
|
||||
if (M_CheckParm("-noxinput"))
|
||||
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
|
||||
|
||||
if (M_CheckParm("-nohidapi"))
|
||||
SDL_SetHintWithPriority("SDL_JOYSTICK_HIDAPI", "0", SDL_HINT_OVERRIDE);
|
||||
|
||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
|
||||
{
|
||||
CONS_Printf("I_InitJoystick()...\n");
|
||||
|
||||
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
|
||||
{
|
||||
CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cv_usejoystick.value)
|
||||
newjoy = SDL_JoystickOpen(cv_usejoystick.value-1);
|
||||
|
||||
if (newjoy && JoyInfo2.dev == newjoy) // don't override an active device
|
||||
cv_usejoystick.value = I_GetJoystickDeviceIndex(JoyInfo.dev) + 1;
|
||||
else if (newjoy && joy_open(cv_usejoystick.value) != -1)
|
||||
{
|
||||
// SDL's device indexes are unstable, so cv_usejoystick may not match
|
||||
// the actual device index. So let's cheat a bit and find the device's current index.
|
||||
JoyInfo.oldjoy = I_GetJoystickDeviceIndex(JoyInfo.dev) + 1;
|
||||
joystick_started = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (JoyInfo.oldjoy)
|
||||
I_ShutdownJoystick();
|
||||
cv_usejoystick.value = 0;
|
||||
joystick_started = 0;
|
||||
}
|
||||
|
||||
if (JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy)
|
||||
SDL_JoystickClose(newjoy);
|
||||
}
|
||||
|
||||
void I_InitJoystick2(void)
|
||||
{
|
||||
SDL_Joystick *newjoy = NULL;
|
||||
|
||||
//I_ShutdownJoystick2();
|
||||
if (M_CheckParm("-nojoy"))
|
||||
return;
|
||||
|
||||
if (M_CheckParm("-noxinput"))
|
||||
SDL_SetHintWithPriority("SDL_XINPUT_ENABLED", "0", SDL_HINT_OVERRIDE);
|
||||
|
||||
if (M_CheckParm("-nohidapi"))
|
||||
SDL_SetHintWithPriority("SDL_JOYSTICK_HIDAPI", "0", SDL_HINT_OVERRIDE);
|
||||
|
||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
|
||||
{
|
||||
CONS_Printf("I_InitJoystick2()...\n");
|
||||
|
||||
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
|
||||
{
|
||||
CONS_Printf(M_GetText("Couldn't initialize joystick: %s\n"), SDL_GetError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cv_usejoystick2.value)
|
||||
newjoy = SDL_JoystickOpen(cv_usejoystick2.value-1);
|
||||
|
||||
if (newjoy && JoyInfo.dev == newjoy) // don't override an active device
|
||||
cv_usejoystick2.value = I_GetJoystickDeviceIndex(JoyInfo2.dev) + 1;
|
||||
else if (newjoy && joy_open2(cv_usejoystick2.value) != -1)
|
||||
{
|
||||
// SDL's device indexes are unstable, so cv_usejoystick may not match
|
||||
// the actual device index. So let's cheat a bit and find the device's current index.
|
||||
JoyInfo2.oldjoy = I_GetJoystickDeviceIndex(JoyInfo2.dev) + 1;
|
||||
joystick2_started = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (JoyInfo2.oldjoy)
|
||||
I_ShutdownJoystick2();
|
||||
cv_usejoystick2.value = 0;
|
||||
joystick2_started = 0;
|
||||
}
|
||||
|
||||
if (JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy)
|
||||
SDL_JoystickClose(newjoy);
|
||||
}
|
||||
|
||||
static void I_ShutdownInput(void)
|
||||
{
|
||||
I_ShutdownGamepads();
|
||||
// Yes, the name is misleading: these send neutral events to
|
||||
// clean up the unplugged joystick's input
|
||||
// Note these methods are internal to this file, not called elsewhere.
|
||||
I_ShutdownJoystick();
|
||||
I_ShutdownJoystick2();
|
||||
|
||||
if (SDL_WasInit(GAMEPAD_INIT_FLAGS) == GAMEPAD_INIT_FLAGS)
|
||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
|
||||
{
|
||||
CONS_Printf("Shutting down game controller subsystems\n");
|
||||
SDL_QuitSubSystem(GAMEPAD_INIT_FLAGS);
|
||||
CONS_Printf("Shutting down joy system\n");
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
I_OutputMsg("I_Joystick: SDL's Joystick system has been shutdown\n");
|
||||
}
|
||||
}
|
||||
|
||||
INT32 I_NumJoys(void)
|
||||
{
|
||||
INT32 numjoy = 0;
|
||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
|
||||
numjoy = SDL_NumJoysticks();
|
||||
return numjoy;
|
||||
}
|
||||
|
||||
static char joyname[255]; // joystick name is straight from the driver
|
||||
|
||||
const char *I_GetJoyName(INT32 joyindex)
|
||||
{
|
||||
const char *tempname = NULL;
|
||||
joyname[0] = 0;
|
||||
joyindex--; //SDL's Joystick System starts at 0, not 1
|
||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
|
||||
{
|
||||
tempname = SDL_JoystickNameForIndex(joyindex);
|
||||
if (tempname)
|
||||
strncpy(joyname, tempname, 255);
|
||||
}
|
||||
return joyname;
|
||||
}
|
||||
|
||||
#ifndef NOMUMBLE
|
||||
#ifdef HAVE_MUMBLE
|
||||
// Best Mumble positional audio settings:
|
||||
|
@ -1373,6 +2113,23 @@ void I_StartupMouse2(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// I_Tactile
|
||||
//
|
||||
void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect)
|
||||
{
|
||||
// UNUSED.
|
||||
(void)pFFType;
|
||||
(void)FFEffect;
|
||||
}
|
||||
|
||||
void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect)
|
||||
{
|
||||
// UNUSED.
|
||||
(void)pFFType;
|
||||
(void)FFEffect;
|
||||
}
|
||||
|
||||
/** \brief empty ticcmd for player 1
|
||||
*/
|
||||
static ticcmd_t emptycmd;
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
#include "../m_menu.h"
|
||||
#include "../d_main.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../i_gamepad.h"
|
||||
#include "../i_joy.h"
|
||||
#include "../st_stuff.h"
|
||||
#include "../hu_stuff.h"
|
||||
#include "../g_game.h"
|
||||
|
@ -449,10 +449,51 @@ static void SurfaceInfo(const SDL_Surface *infoSurface, const char *SurfaceText)
|
|||
|
||||
static void VID_Command_Info_f (void)
|
||||
{
|
||||
#if 0
|
||||
SDL2STUB();
|
||||
#else
|
||||
#if 0
|
||||
const SDL_VideoInfo *videoInfo;
|
||||
videoInfo = SDL_GetVideoInfo(); //Alam: Double-Check
|
||||
if (videoInfo)
|
||||
{
|
||||
CONS_Printf("%s", M_GetText("Video Interface Capabilities:\n"));
|
||||
if (videoInfo->hw_available)
|
||||
CONS_Printf("%s", M_GetText(" Hardware surfaces\n"));
|
||||
if (videoInfo->wm_available)
|
||||
CONS_Printf("%s", M_GetText(" Window manager\n"));
|
||||
//UnusedBits1 :6
|
||||
//UnusedBits2 :1
|
||||
if (videoInfo->blit_hw)
|
||||
CONS_Printf("%s", M_GetText(" Accelerated blits HW-2-HW\n"));
|
||||
if (videoInfo->blit_hw_CC)
|
||||
CONS_Printf("%s", M_GetText(" Accelerated blits HW-2-HW with Colorkey\n"));
|
||||
if (videoInfo->wm_available)
|
||||
CONS_Printf("%s", M_GetText(" Accelerated blits HW-2-HW with Alpha\n"));
|
||||
if (videoInfo->blit_sw)
|
||||
{
|
||||
CONS_Printf("%s", M_GetText(" Accelerated blits SW-2-HW\n"));
|
||||
if (!M_CheckParm("-noblit")) videoblitok = SDL_TRUE;
|
||||
}
|
||||
if (videoInfo->blit_sw_CC)
|
||||
CONS_Printf("%s", M_GetText(" Accelerated blits SW-2-HW with Colorkey\n"));
|
||||
if (videoInfo->blit_sw_A)
|
||||
CONS_Printf("%s", M_GetText(" Accelerated blits SW-2-HW with Alpha\n"));
|
||||
if (videoInfo->blit_fill)
|
||||
CONS_Printf("%s", M_GetText(" Accelerated Color filling\n"));
|
||||
//UnusedBits3 :16
|
||||
if (videoInfo->video_mem)
|
||||
CONS_Printf(M_GetText(" There is %i KB of video memory\n"), videoInfo->video_mem);
|
||||
else
|
||||
CONS_Printf("%s", M_GetText(" There no video memory for SDL\n"));
|
||||
//*vfmt
|
||||
}
|
||||
#else
|
||||
if (!M_CheckParm("-noblit")) videoblitok = SDL_TRUE;
|
||||
|
||||
#endif
|
||||
SurfaceInfo(bufSurface, M_GetText("Current Engine Mode"));
|
||||
SurfaceInfo(vidSurface, M_GetText("Current Video Mode"));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void VID_Command_ModeList_f(void)
|
||||
|
@ -487,6 +528,61 @@ static void VID_Command_Mode_f (void)
|
|||
setmodeneeded = modenum+1; // request vid mode change
|
||||
}
|
||||
|
||||
static inline void SDLJoyRemap(event_t *event)
|
||||
{
|
||||
(void)event;
|
||||
}
|
||||
|
||||
static INT32 SDLJoyAxis(const Sint16 axis, evtype_t which)
|
||||
{
|
||||
// -32768 to 32767
|
||||
INT32 raxis = axis/32;
|
||||
if (which == ev_joystick)
|
||||
{
|
||||
if (Joystick.bGamepadStyle)
|
||||
{
|
||||
// gamepad control type, on or off, live or die
|
||||
if (raxis < -(JOYAXISRANGE/2))
|
||||
raxis = -1;
|
||||
else if (raxis > (JOYAXISRANGE/2))
|
||||
raxis = 1;
|
||||
else
|
||||
raxis = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
raxis = JoyInfo.scale!=1?((raxis/JoyInfo.scale)*JoyInfo.scale):raxis;
|
||||
|
||||
#ifdef SDL_JDEADZONE
|
||||
if (-SDL_JDEADZONE <= raxis && raxis <= SDL_JDEADZONE)
|
||||
raxis = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (which == ev_joystick2)
|
||||
{
|
||||
if (Joystick2.bGamepadStyle)
|
||||
{
|
||||
// gamepad control type, on or off, live or die
|
||||
if (raxis < -(JOYAXISRANGE/2))
|
||||
raxis = -1;
|
||||
else if (raxis > (JOYAXISRANGE/2))
|
||||
raxis = 1;
|
||||
else raxis = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
raxis = JoyInfo2.scale!=1?((raxis/JoyInfo2.scale)*JoyInfo2.scale):raxis;
|
||||
|
||||
#ifdef SDL_JDEADZONE
|
||||
if (-SDL_JDEADZONE <= raxis && raxis <= SDL_JDEADZONE)
|
||||
raxis = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return raxis;
|
||||
}
|
||||
|
||||
static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
|
||||
{
|
||||
static SDL_bool firsttimeonmouse = SDL_TRUE;
|
||||
|
@ -518,13 +614,13 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
|
|||
// Tell game we got focus back, resume music if necessary
|
||||
window_notinfocus = false;
|
||||
if (!paused)
|
||||
S_ResumeAudio();
|
||||
S_ResumeAudio(); //resume it
|
||||
|
||||
I_ToggleControllerRumble(true);
|
||||
P_UnpauseRumble(NULL);
|
||||
|
||||
if (!firsttimeonmouse && cv_usemouse.value)
|
||||
I_StartupMouse();
|
||||
if (!firsttimeonmouse)
|
||||
{
|
||||
if (cv_usemouse.value) I_StartupMouse();
|
||||
}
|
||||
//else firsttimeonmouse = SDL_FALSE;
|
||||
|
||||
if (USE_MOUSEINPUT && !IgnoreMouse())
|
||||
SDLdoGrabMouse();
|
||||
|
@ -533,45 +629,43 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
|
|||
{
|
||||
// Tell game we lost focus, pause music
|
||||
window_notinfocus = true;
|
||||
|
||||
if (!cv_playmusicifunfocused.value)
|
||||
if (! cv_playmusicifunfocused.value)
|
||||
S_PauseAudio();
|
||||
if (!cv_playsoundsifunfocused.value)
|
||||
if (! cv_playsoundsifunfocused.value)
|
||||
S_StopSounds();
|
||||
|
||||
if (!disable_mouse)
|
||||
{
|
||||
SDLforceUngrabMouse();
|
||||
|
||||
}
|
||||
memset(gamekeydown, 0, NUMKEYS); // TODO this is a scary memset
|
||||
|
||||
I_ToggleControllerRumble(false);
|
||||
if (P_AutoPause())
|
||||
P_PauseRumble(NULL);
|
||||
|
||||
if (MOUSE_MENU)
|
||||
{
|
||||
SDLdoUngrabMouse();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void Impl_HandleKeyboardEvent(SDL_KeyboardEvent evt, Uint32 type)
|
||||
{
|
||||
event_t event;
|
||||
|
||||
if (type == SDL_KEYUP)
|
||||
{
|
||||
event.type = ev_keyup;
|
||||
}
|
||||
else if (type == SDL_KEYDOWN)
|
||||
{
|
||||
event.type = ev_keydown;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
event.key = Impl_SDL_Scancode_To_Keycode(evt.keysym.scancode);
|
||||
if (!event.key)
|
||||
return;
|
||||
|
||||
event.repeated = (evt.repeat != 0);
|
||||
event.which = 0;
|
||||
|
||||
D_PostEvent(&event);
|
||||
if (event.key) D_PostEvent(&event);
|
||||
}
|
||||
|
||||
static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt)
|
||||
|
@ -636,35 +730,32 @@ static void Impl_HandleMouseButtonEvent(SDL_MouseButtonEvent evt, Uint32 type)
|
|||
if (SDL_GetMouseFocus() != window || IgnoreMouse())
|
||||
return;
|
||||
|
||||
/// \todo inputEvent.button.which
|
||||
if (USE_MOUSEINPUT)
|
||||
{
|
||||
if (type == SDL_MOUSEBUTTONUP)
|
||||
event.type = ev_keyup;
|
||||
else if (type == SDL_MOUSEBUTTONDOWN)
|
||||
event.type = ev_keydown;
|
||||
else
|
||||
return;
|
||||
|
||||
switch (evt.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
event.key = KEY_MOUSE1+0;
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
event.key = KEY_MOUSE1+1;
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
event.key = KEY_MOUSE1+2;
|
||||
break;
|
||||
case SDL_BUTTON_X1:
|
||||
event.key = KEY_MOUSE1+3;
|
||||
break;
|
||||
case SDL_BUTTON_X2:
|
||||
event.key = KEY_MOUSE1+4;
|
||||
break;
|
||||
event.type = ev_keyup;
|
||||
}
|
||||
else if (type == SDL_MOUSEBUTTONDOWN)
|
||||
{
|
||||
event.type = ev_keydown;
|
||||
}
|
||||
else return;
|
||||
if (evt.button == SDL_BUTTON_MIDDLE)
|
||||
event.key = KEY_MOUSE1+2;
|
||||
else if (evt.button == SDL_BUTTON_RIGHT)
|
||||
event.key = KEY_MOUSE1+1;
|
||||
else if (evt.button == SDL_BUTTON_LEFT)
|
||||
event.key = KEY_MOUSE1;
|
||||
else if (evt.button == SDL_BUTTON_X1)
|
||||
event.key = KEY_MOUSE1+3;
|
||||
else if (evt.button == SDL_BUTTON_X2)
|
||||
event.key = KEY_MOUSE1+4;
|
||||
if (event.type == ev_keyup || event.type == ev_keydown)
|
||||
{
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -695,6 +786,111 @@ static void Impl_HandleMouseWheelEvent(SDL_MouseWheelEvent evt)
|
|||
}
|
||||
}
|
||||
|
||||
static void Impl_HandleJoystickAxisEvent(SDL_JoyAxisEvent evt)
|
||||
{
|
||||
event_t event;
|
||||
SDL_JoystickID joyid[2];
|
||||
|
||||
// Determine the Joystick IDs for each current open joystick
|
||||
joyid[0] = SDL_JoystickInstanceID(JoyInfo.dev);
|
||||
joyid[1] = SDL_JoystickInstanceID(JoyInfo2.dev);
|
||||
|
||||
evt.axis++;
|
||||
event.key = event.x = event.y = INT32_MAX;
|
||||
|
||||
if (evt.which == joyid[0])
|
||||
{
|
||||
event.type = ev_joystick;
|
||||
}
|
||||
else if (evt.which == joyid[1])
|
||||
{
|
||||
event.type = ev_joystick2;
|
||||
}
|
||||
else return;
|
||||
//axis
|
||||
if (evt.axis > JOYAXISSET*2)
|
||||
return;
|
||||
//vaule
|
||||
if (evt.axis%2)
|
||||
{
|
||||
event.key = evt.axis / 2;
|
||||
event.x = SDLJoyAxis(evt.value, event.type);
|
||||
}
|
||||
else
|
||||
{
|
||||
evt.axis--;
|
||||
event.key = evt.axis / 2;
|
||||
event.y = SDLJoyAxis(evt.value, event.type);
|
||||
}
|
||||
D_PostEvent(&event);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void Impl_HandleJoystickHatEvent(SDL_JoyHatEvent evt)
|
||||
{
|
||||
event_t event;
|
||||
SDL_JoystickID joyid[2];
|
||||
|
||||
// Determine the Joystick IDs for each current open joystick
|
||||
joyid[0] = SDL_JoystickInstanceID(JoyInfo.dev);
|
||||
joyid[1] = SDL_JoystickInstanceID(JoyInfo2.dev);
|
||||
|
||||
if (evt.hat >= JOYHATS)
|
||||
return; // ignore hats with too high an index
|
||||
|
||||
if (evt.which == joyid[0])
|
||||
{
|
||||
event.key = KEY_HAT1 + (evt.hat*4);
|
||||
}
|
||||
else if (evt.which == joyid[1])
|
||||
{
|
||||
event.key = KEY_2HAT1 + (evt.hat*4);
|
||||
}
|
||||
else return;
|
||||
|
||||
// NOTE: UNFINISHED
|
||||
}
|
||||
#endif
|
||||
|
||||
static void Impl_HandleJoystickButtonEvent(SDL_JoyButtonEvent evt, Uint32 type)
|
||||
{
|
||||
event_t event;
|
||||
SDL_JoystickID joyid[2];
|
||||
|
||||
// Determine the Joystick IDs for each current open joystick
|
||||
joyid[0] = SDL_JoystickInstanceID(JoyInfo.dev);
|
||||
joyid[1] = SDL_JoystickInstanceID(JoyInfo2.dev);
|
||||
|
||||
if (evt.which == joyid[0])
|
||||
{
|
||||
event.key = KEY_JOY1;
|
||||
}
|
||||
else if (evt.which == joyid[1])
|
||||
{
|
||||
event.key = KEY_2JOY1;
|
||||
}
|
||||
else return;
|
||||
if (type == SDL_JOYBUTTONUP)
|
||||
{
|
||||
event.type = ev_keyup;
|
||||
}
|
||||
else if (type == SDL_JOYBUTTONDOWN)
|
||||
{
|
||||
event.type = ev_keydown;
|
||||
}
|
||||
else return;
|
||||
if (evt.button < JOYBUTTONS)
|
||||
{
|
||||
event.key += evt.button;
|
||||
}
|
||||
else return;
|
||||
|
||||
SDLJoyRemap(&event);
|
||||
if (event.type != ev_console) D_PostEvent(&event);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void I_GetEvent(void)
|
||||
{
|
||||
SDL_Event evt;
|
||||
|
@ -732,18 +928,147 @@ void I_GetEvent(void)
|
|||
case SDL_MOUSEWHEEL:
|
||||
Impl_HandleMouseWheelEvent(evt.wheel);
|
||||
break;
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
I_HandleControllerAxisEvent(evt.caxis);
|
||||
case SDL_JOYAXISMOTION:
|
||||
Impl_HandleJoystickAxisEvent(evt.jaxis);
|
||||
break;
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
I_HandleControllerButtonEvent(evt.cbutton, evt.type);
|
||||
#if 0
|
||||
case SDL_JOYHATMOTION:
|
||||
Impl_HandleJoystickHatEvent(evt.jhat)
|
||||
break;
|
||||
case SDL_CONTROLLERDEVICEADDED:
|
||||
I_ControllerDeviceAdded(evt.cdevice.which);
|
||||
#endif
|
||||
case SDL_JOYBUTTONUP:
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
Impl_HandleJoystickButtonEvent(evt.jbutton, evt.type);
|
||||
break;
|
||||
case SDL_CONTROLLERDEVICEREMOVED:
|
||||
I_ControllerDeviceRemoved();
|
||||
case SDL_JOYDEVICEADDED:
|
||||
{
|
||||
SDL_Joystick *newjoy = SDL_JoystickOpen(evt.jdevice.which);
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Joystick device index %d added\n", evt.jdevice.which + 1);
|
||||
|
||||
// Because SDL's device index is unstable, we're going to cheat here a bit:
|
||||
// For the first joystick setting that is NOT active:
|
||||
// 1. Set cv_usejoystickX.value to the new device index (this does not change what is written to config.cfg)
|
||||
// 2. Set OTHERS' cv_usejoystickX.value to THEIR new device index, because it likely changed
|
||||
// * If device doesn't exist, switch cv_usejoystick back to default value (.string)
|
||||
// * BUT: If that default index is being occupied, use ANOTHER cv_usejoystick's default value!
|
||||
if (newjoy && (!JoyInfo.dev || !SDL_JoystickGetAttached(JoyInfo.dev))
|
||||
&& JoyInfo2.dev != newjoy) // don't override a currently active device
|
||||
{
|
||||
cv_usejoystick.value = evt.jdevice.which + 1;
|
||||
|
||||
if (JoyInfo2.dev)
|
||||
cv_usejoystick2.value = I_GetJoystickDeviceIndex(JoyInfo2.dev) + 1;
|
||||
else if (atoi(cv_usejoystick2.string) != JoyInfo.oldjoy
|
||||
&& atoi(cv_usejoystick2.string) != cv_usejoystick.value)
|
||||
cv_usejoystick2.value = atoi(cv_usejoystick2.string);
|
||||
else if (atoi(cv_usejoystick.string) != JoyInfo.oldjoy
|
||||
&& atoi(cv_usejoystick.string) != cv_usejoystick.value)
|
||||
cv_usejoystick2.value = atoi(cv_usejoystick.string);
|
||||
else // we tried...
|
||||
cv_usejoystick2.value = 0;
|
||||
}
|
||||
else if (newjoy && (!JoyInfo2.dev || !SDL_JoystickGetAttached(JoyInfo2.dev))
|
||||
&& JoyInfo.dev != newjoy) // don't override a currently active device
|
||||
{
|
||||
cv_usejoystick2.value = evt.jdevice.which + 1;
|
||||
|
||||
if (JoyInfo.dev)
|
||||
cv_usejoystick.value = I_GetJoystickDeviceIndex(JoyInfo.dev) + 1;
|
||||
else if (atoi(cv_usejoystick.string) != JoyInfo2.oldjoy
|
||||
&& atoi(cv_usejoystick.string) != cv_usejoystick2.value)
|
||||
cv_usejoystick.value = atoi(cv_usejoystick.string);
|
||||
else if (atoi(cv_usejoystick2.string) != JoyInfo2.oldjoy
|
||||
&& atoi(cv_usejoystick2.string) != cv_usejoystick2.value)
|
||||
cv_usejoystick.value = atoi(cv_usejoystick2.string);
|
||||
else // we tried...
|
||||
cv_usejoystick.value = 0;
|
||||
}
|
||||
|
||||
// Was cv_usejoystick disabled in settings?
|
||||
if (!strcmp(cv_usejoystick.string, "0") || !cv_usejoystick.value)
|
||||
cv_usejoystick.value = 0;
|
||||
else if (atoi(cv_usejoystick.string) <= I_NumJoys() // don't mess if we intentionally set higher than NumJoys
|
||||
&& cv_usejoystick.value) // update the cvar ONLY if a device exists
|
||||
CV_SetValue(&cv_usejoystick, cv_usejoystick.value);
|
||||
|
||||
if (!strcmp(cv_usejoystick2.string, "0") || !cv_usejoystick2.value)
|
||||
cv_usejoystick2.value = 0;
|
||||
else if (atoi(cv_usejoystick2.string) <= I_NumJoys() // don't mess if we intentionally set higher than NumJoys
|
||||
&& cv_usejoystick2.value) // update the cvar ONLY if a device exists
|
||||
CV_SetValue(&cv_usejoystick2, cv_usejoystick2.value);
|
||||
|
||||
// Update all joysticks' init states
|
||||
// This is a little wasteful since cv_usejoystick already calls this, but
|
||||
// we need to do this in case CV_SetValue did nothing because the string was already same.
|
||||
// if the device is already active, this should do nothing, effectively.
|
||||
I_InitJoystick();
|
||||
I_InitJoystick2();
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Joystick1 device index: %d\n", JoyInfo.oldjoy);
|
||||
CONS_Debug(DBG_GAMELOGIC, "Joystick2 device index: %d\n", JoyInfo2.oldjoy);
|
||||
|
||||
// update the menu
|
||||
if (currentMenu == &OP_JoystickSetDef)
|
||||
M_SetupJoystickMenu(0);
|
||||
|
||||
if (JoyInfo.dev != newjoy && JoyInfo2.dev != newjoy)
|
||||
SDL_JoystickClose(newjoy);
|
||||
}
|
||||
break;
|
||||
case SDL_JOYDEVICEREMOVED:
|
||||
if (JoyInfo.dev && !SDL_JoystickGetAttached(JoyInfo.dev))
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Joystick1 removed, device index: %d\n", JoyInfo.oldjoy);
|
||||
I_ShutdownJoystick();
|
||||
}
|
||||
|
||||
if (JoyInfo2.dev && !SDL_JoystickGetAttached(JoyInfo2.dev))
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "Joystick2 removed, device index: %d\n", JoyInfo2.oldjoy);
|
||||
I_ShutdownJoystick2();
|
||||
}
|
||||
|
||||
// Update the device indexes, because they likely changed
|
||||
// * If device doesn't exist, switch cv_usejoystick back to default value (.string)
|
||||
// * BUT: If that default index is being occupied, use ANOTHER cv_usejoystick's default value!
|
||||
if (JoyInfo.dev)
|
||||
cv_usejoystick.value = JoyInfo.oldjoy = I_GetJoystickDeviceIndex(JoyInfo.dev) + 1;
|
||||
else if (atoi(cv_usejoystick.string) != JoyInfo2.oldjoy)
|
||||
cv_usejoystick.value = atoi(cv_usejoystick.string);
|
||||
else if (atoi(cv_usejoystick2.string) != JoyInfo2.oldjoy)
|
||||
cv_usejoystick.value = atoi(cv_usejoystick2.string);
|
||||
else // we tried...
|
||||
cv_usejoystick.value = 0;
|
||||
|
||||
if (JoyInfo2.dev)
|
||||
cv_usejoystick2.value = JoyInfo2.oldjoy = I_GetJoystickDeviceIndex(JoyInfo2.dev) + 1;
|
||||
else if (atoi(cv_usejoystick2.string) != JoyInfo.oldjoy)
|
||||
cv_usejoystick2.value = atoi(cv_usejoystick2.string);
|
||||
else if (atoi(cv_usejoystick.string) != JoyInfo.oldjoy)
|
||||
cv_usejoystick2.value = atoi(cv_usejoystick.string);
|
||||
else // we tried...
|
||||
cv_usejoystick2.value = 0;
|
||||
|
||||
// Was cv_usejoystick disabled in settings?
|
||||
if (!strcmp(cv_usejoystick.string, "0"))
|
||||
cv_usejoystick.value = 0;
|
||||
else if (atoi(cv_usejoystick.string) <= I_NumJoys() // don't mess if we intentionally set higher than NumJoys
|
||||
&& cv_usejoystick.value) // update the cvar ONLY if a device exists
|
||||
CV_SetValue(&cv_usejoystick, cv_usejoystick.value);
|
||||
|
||||
if (!strcmp(cv_usejoystick2.string, "0"))
|
||||
cv_usejoystick2.value = 0;
|
||||
else if (atoi(cv_usejoystick2.string) <= I_NumJoys() // don't mess if we intentionally set higher than NumJoys
|
||||
&& cv_usejoystick2.value) // update the cvar ONLY if a device exists
|
||||
CV_SetValue(&cv_usejoystick2, cv_usejoystick2.value);
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, "Joystick1 device index: %d\n", JoyInfo.oldjoy);
|
||||
CONS_Debug(DBG_GAMELOGIC, "Joystick2 device index: %d\n", JoyInfo2.oldjoy);
|
||||
|
||||
// update the menu
|
||||
if (currentMenu == &OP_JoystickSetDef)
|
||||
M_SetupJoystickMenu(0);
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
LUA_HookBool(true, HOOK(GameQuit));
|
||||
|
@ -761,7 +1086,6 @@ void I_GetEvent(void)
|
|||
//SDL_memset(&event, 0, sizeof(event_t));
|
||||
event.type = ev_mouse;
|
||||
event.key = 0;
|
||||
event.which = 0;
|
||||
event.x = (INT32)lround(mousemovex * ((float)wwidth / (float)realwidth));
|
||||
event.y = (INT32)lround(mousemovey * ((float)wheight / (float)realheight));
|
||||
D_PostEvent(&event);
|
||||
|
@ -800,9 +1124,15 @@ void I_OsPolling(void)
|
|||
|
||||
if (consolevent)
|
||||
I_GetConsoleEvents();
|
||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
|
||||
{
|
||||
SDL_JoystickUpdate();
|
||||
I_GetJoystickEvents();
|
||||
I_GetJoystick2Events();
|
||||
}
|
||||
|
||||
I_UpdateControllers();
|
||||
I_GetMouseEvents();
|
||||
|
||||
I_GetEvent();
|
||||
|
||||
mod = SDL_GetModState();
|
||||
|
|
|
@ -23,41 +23,59 @@ extern SDL_bool consolevent;
|
|||
extern SDL_bool framebuffer;
|
||||
|
||||
#include "../m_fixed.h"
|
||||
#include "../i_gamepad.h"
|
||||
|
||||
// SDL info about all controllers
|
||||
typedef struct
|
||||
// SDL2 stub macro
|
||||
#ifdef _MSC_VER
|
||||
#define SDL2STUB() CONS_Printf("SDL2: stubbed: %s:%d\n", __FUNCTION__, __LINE__)
|
||||
#else
|
||||
#define SDL2STUB() CONS_Printf("SDL2: stubbed: %s:%d\n", __func__, __LINE__)
|
||||
#endif
|
||||
|
||||
// So m_menu knows whether to store cv_usejoystick value or string
|
||||
#define JOYSTICK_HOTPLUG
|
||||
|
||||
/** \brief The JoyInfo_s struct
|
||||
|
||||
info about joystick
|
||||
*/
|
||||
typedef struct SDLJoyInfo_s
|
||||
{
|
||||
boolean started; // started
|
||||
int lastindex; // last gamepad ID
|
||||
/// Joystick handle
|
||||
SDL_Joystick *dev;
|
||||
/// number of old joystick
|
||||
int oldjoy;
|
||||
/// number of axies
|
||||
int axises;
|
||||
/// scale of axises
|
||||
INT32 scale;
|
||||
/// number of buttons
|
||||
int buttons;
|
||||
/// number of hats
|
||||
int hats;
|
||||
/// number of balls
|
||||
int balls;
|
||||
|
||||
SDL_GameController *dev;
|
||||
SDL_Joystick *joydev;
|
||||
} SDLJoyInfo_t;
|
||||
|
||||
gamepad_t *info; // pointer to gamepad info
|
||||
/** \brief SDL info about joystick 1
|
||||
*/
|
||||
extern SDLJoyInfo_t JoyInfo;
|
||||
|
||||
struct {
|
||||
Uint16 large_magnitude;
|
||||
Uint16 small_magnitude;
|
||||
Uint32 expiration, time_left;
|
||||
} rumble;
|
||||
} ControllerInfo;
|
||||
/** \brief joystick axis deadzone
|
||||
*/
|
||||
#define SDL_JDEADZONE 153
|
||||
#undef SDL_JDEADZONE
|
||||
|
||||
#define GAMEPAD_INIT_FLAGS (SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER)
|
||||
/** \brief SDL inof about joystick 2
|
||||
*/
|
||||
extern SDLJoyInfo_t JoyInfo2;
|
||||
|
||||
void I_UpdateControllers(void);
|
||||
// So we can call this from i_video event loop
|
||||
void I_ShutdownJoystick(void);
|
||||
void I_ShutdownJoystick2(void);
|
||||
|
||||
void I_ControllerDeviceAdded(INT32 which);
|
||||
void I_ControllerDeviceRemoved(void);
|
||||
|
||||
void I_HandleControllerButtonEvent(SDL_ControllerButtonEvent evt, Uint32 type);
|
||||
void I_HandleControllerAxisEvent(SDL_ControllerAxisEvent evt);
|
||||
|
||||
INT32 I_GetControllerIndex(SDL_GameController *dev);
|
||||
void I_CloseInactiveController(SDL_GameController *dev);
|
||||
void I_CloseInactiveHapticDevice(SDL_Haptic *dev);
|
||||
|
||||
void I_ToggleControllerRumble(boolean unpause);
|
||||
// Cheat to get the device index for a joystick handle
|
||||
INT32 I_GetJoystickDeviceIndex(SDL_Joystick *dev);
|
||||
|
||||
void I_GetConsoleEvents(void);
|
||||
|
||||
|
|
Loading…
Reference in a new issue