mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-26 06:11:01 +00:00
Merge branch 'next' into font_drawer
This commit is contained in:
commit
8228275cf8
56 changed files with 3184 additions and 4250 deletions
|
@ -265,14 +265,8 @@ universalfields
|
|||
|
||||
triggerer
|
||||
{
|
||||
type = 0;
|
||||
default = 0;
|
||||
enum
|
||||
{
|
||||
0 = "Player";
|
||||
1 = "All players";
|
||||
2 = "Object";
|
||||
}
|
||||
type = 2;
|
||||
default = "Player";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4546,7 +4546,7 @@ udmf
|
|||
sprite = "EMBMA0";
|
||||
width = 16;
|
||||
height = 30;
|
||||
arg0
|
||||
arg1
|
||||
{
|
||||
title = "Float?";
|
||||
type = 11;
|
||||
|
|
|
@ -127,7 +127,9 @@ endif()
|
|||
# Compatibility flag with later versions of GCC
|
||||
# We should really fix our code to not need this
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
target_compile_options(SRB2SDL2 PRIVATE -mno-ms-bitfields)
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|x64|amd64|AMD64|em64t|EM64T)")
|
||||
target_compile_options(SRB2SDL2 PRIVATE -mno-ms-bitfields)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Compiler warnings configuration
|
||||
|
|
|
@ -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
|
||||
|
|
177
src/command.c
177
src/command.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);
|
||||
|
||||
|
@ -2181,48 +2182,131 @@ static void CV_EnforceExecVersion(void)
|
|||
CV_StealthSetValue(&cv_execversion, EXECVERSION);
|
||||
}
|
||||
|
||||
#ifndef OLD_GAMEPAD_AXES
|
||||
static boolean CV_ConvertOldJoyAxisVars(consvar_t *v, const char *valstr)
|
||||
static boolean CV_FilterJoyAxisVars(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 ALL axis settings are previous defaults, set them to the new defaults
|
||||
// EXECVERSION < 26 (2.1.21)
|
||||
|
||||
if (v->PossibleValue != joyaxis_cons_t)
|
||||
return true;
|
||||
|
||||
for (unsigned i = 0;; i++)
|
||||
if (joyaxis_default)
|
||||
{
|
||||
if (axis_names[i].old == NULL)
|
||||
if (!stricmp(v->name, "joyaxis_turn"))
|
||||
{
|
||||
CV_SetCVar(v, "None", false);
|
||||
return false;
|
||||
if (joyaxis_count > 6) return false;
|
||||
// we're currently setting the new defaults, don't interfere
|
||||
else if (joyaxis_count == 6) return true;
|
||||
|
||||
if (!stricmp(valstr, "X-Axis")) joyaxis_count++;
|
||||
else joyaxis_default = false;
|
||||
}
|
||||
else if (!stricmp(valstr, axis_names[i].old))
|
||||
if (!stricmp(v->name, "joyaxis_move"))
|
||||
{
|
||||
CV_SetCVar(v, axis_names[i].new, false);
|
||||
if (joyaxis_count > 6) return false;
|
||||
else if (joyaxis_count == 6) return true;
|
||||
|
||||
if (!stricmp(valstr, "Y-Axis")) joyaxis_count++;
|
||||
else joyaxis_default = false;
|
||||
}
|
||||
if (!stricmp(v->name, "joyaxis_side"))
|
||||
{
|
||||
if (joyaxis_count > 6) return false;
|
||||
else if (joyaxis_count == 6) return true;
|
||||
|
||||
if (!stricmp(valstr, "Z-Axis")) joyaxis_count++;
|
||||
else joyaxis_default = false;
|
||||
}
|
||||
if (!stricmp(v->name, "joyaxis_look"))
|
||||
{
|
||||
if (joyaxis_count > 6) return false;
|
||||
else if (joyaxis_count == 6) return true;
|
||||
|
||||
if (!stricmp(valstr, "None")) joyaxis_count++;
|
||||
else joyaxis_default = false;
|
||||
}
|
||||
if (!stricmp(v->name, "joyaxis_fire")
|
||||
|| !stricmp(v->name, "joyaxis_firenormal"))
|
||||
{
|
||||
if (joyaxis_count > 6) return false;
|
||||
else if (joyaxis_count == 6) return true;
|
||||
|
||||
if (!stricmp(valstr, "None")) joyaxis_count++;
|
||||
else joyaxis_default = false;
|
||||
}
|
||||
// reset all axis settings to defaults
|
||||
if (joyaxis_count == 6)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (joyaxis2_default)
|
||||
{
|
||||
if (!stricmp(v->name, "joyaxis2_turn"))
|
||||
{
|
||||
if (joyaxis2_count > 6) return false;
|
||||
// we're currently setting the new defaults, don't interfere
|
||||
else if (joyaxis2_count == 6) return true;
|
||||
|
||||
if (!stricmp(valstr, "X-Axis")) joyaxis2_count++;
|
||||
else joyaxis2_default = false;
|
||||
}
|
||||
if (!stricmp(v->name, "joyaxis2_move"))
|
||||
{
|
||||
if (joyaxis2_count > 6) return false;
|
||||
else if (joyaxis2_count == 6) return true;
|
||||
|
||||
if (!stricmp(valstr, "Y-Axis")) joyaxis2_count++;
|
||||
else joyaxis2_default = false;
|
||||
}
|
||||
if (!stricmp(v->name, "joyaxis2_side"))
|
||||
{
|
||||
if (joyaxis2_count > 6) return false;
|
||||
else if (joyaxis2_count == 6) return true;
|
||||
|
||||
if (!stricmp(valstr, "Z-Axis")) joyaxis2_count++;
|
||||
else joyaxis2_default = false;
|
||||
}
|
||||
if (!stricmp(v->name, "joyaxis2_look"))
|
||||
{
|
||||
if (joyaxis2_count > 6) return false;
|
||||
else if (joyaxis2_count == 6) return true;
|
||||
|
||||
if (!stricmp(valstr, "None")) joyaxis2_count++;
|
||||
else joyaxis2_default = false;
|
||||
}
|
||||
if (!stricmp(v->name, "joyaxis2_fire")
|
||||
|| !stricmp(v->name, "joyaxis2_firenormal"))
|
||||
{
|
||||
if (joyaxis2_count > 6) return false;
|
||||
else if (joyaxis2_count == 6) return true;
|
||||
|
||||
if (!stricmp(valstr, "None")) joyaxis2_count++;
|
||||
else joyaxis2_default = false;
|
||||
}
|
||||
|
||||
// reset all axis settings to defaults
|
||||
if (joyaxis2_count == 6)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// we haven't reached our counts yet, or we're not default
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr)
|
||||
{
|
||||
|
@ -2233,14 +2317,39 @@ static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr)
|
|||
if (!(v->flags & CV_SAVE))
|
||||
return true;
|
||||
|
||||
#ifndef OLD_GAMEPAD_AXES
|
||||
if (GETMAJOREXECVERSION(cv_execversion.value) <= 51 && GETMINOREXECVERSION(cv_execversion.value) < 1)
|
||||
if (GETMAJOREXECVERSION(cv_execversion.value) < 26) // 26 = 2.1.21
|
||||
{
|
||||
if (!CV_ConvertOldJoyAxisVars(v, valstr))
|
||||
// MOUSE SETTINGS
|
||||
// alwaysfreelook split between first and third person (chasefreelook)
|
||||
// mousemove was on by default, which invalidates the current approach
|
||||
if (!stricmp(v->name, "alwaysmlook")
|
||||
|| !stricmp(v->name, "alwaysmlook2")
|
||||
|| !stricmp(v->name, "mousemove")
|
||||
|| !stricmp(v->name, "mousemove2"))
|
||||
return false;
|
||||
|
||||
// mousesens was changed from 35 to 20 due to oversensitivity
|
||||
if ((!stricmp(v->name, "mousesens")
|
||||
|| !stricmp(v->name, "mousesens2")
|
||||
|| !stricmp(v->name, "mouseysens")
|
||||
|| !stricmp(v->name, "mouseysens2"))
|
||||
&& atoi(valstr) == 35)
|
||||
return false;
|
||||
|
||||
// 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"))
|
||||
&& atoi(valstr) == 0)
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// axis defaults were changed to be friendly to 360 controllers
|
||||
// if ALL axis settings are defaults, then change them to new values
|
||||
if (!CV_FilterJoyAxisVars(v, valstr))
|
||||
return false;
|
||||
}
|
||||
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();
|
||||
|
||||
|
|
133
src/d_netcmd.c
133
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,18 +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_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);
|
||||
|
@ -834,6 +807,7 @@ void D_RegisterClientCommands(void)
|
|||
#if defined (__unix__) || defined (__APPLE__) || defined (UNIXCOMMON)
|
||||
CV_RegisterVar(&cv_mouse2opt);
|
||||
#endif
|
||||
CV_RegisterVar(&cv_controlperkey);
|
||||
|
||||
CV_RegisterVar(&cv_usemouse);
|
||||
CV_RegisterVar(&cv_usemouse2);
|
||||
|
@ -846,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]);
|
||||
|
@ -2242,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();
|
||||
|
@ -4644,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,13 +5642,18 @@ 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},
|
||||
{"JA_LOOK",JA_LOOK},
|
||||
{"JA_STRAFE",JA_STRAFE},
|
||||
{"JOYAXISRANGE",OLDJOYAXISRANGE},
|
||||
{"JA_DIGITAL",JA_DIGITAL},
|
||||
{"JA_JUMP",JA_JUMP},
|
||||
{"JA_SPIN",JA_SPIN},
|
||||
{"JA_FIRE",JA_FIRE},
|
||||
{"JA_FIRENORMAL",JA_FIRENORMAL},
|
||||
{"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;
|
||||
|
|
702
src/g_game.c
702
src/g_game.c
File diff suppressed because it is too large
Load diff
33
src/g_game.h
33
src/g_game.h
|
@ -68,13 +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_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],
|
||||
|
@ -87,19 +84,25 @@ 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,
|
||||
JA_STRAFE,
|
||||
|
||||
JA_DIGITAL, // axes henceforth use digital deadzone
|
||||
|
||||
JA_JUMP = JA_DIGITAL,
|
||||
JA_SPIN,
|
||||
JA_FIRE,
|
||||
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)
|
||||
|
@ -119,18 +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 connected
|
||||
void G_OnGamepadConnect(UINT8 which);
|
||||
|
||||
// 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);
|
||||
|
|
1537
src/g_input.c
1537
src/g_input.c
File diff suppressed because it is too large
Load diff
220
src/g_input.h
220
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,179 +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)
|
||||
#define GAMEPAD_AXIS(key) (KEY_AXES + GAMEPAD_AXIS_##key)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GC_NULL = 0, // a key/button mapped to GC_NULL has no effect
|
||||
|
@ -249,6 +115,7 @@ typedef enum
|
|||
// mouse values are used once
|
||||
extern consvar_t cv_mousesens, cv_mouseysens;
|
||||
extern consvar_t cv_mousesens2, cv_mouseysens2;
|
||||
extern consvar_t cv_controlperkey;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -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,44 +181,20 @@ 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);
|
||||
INT32 G_GetControlScheme(INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gclen);
|
||||
void G_CopyControls(INT32 (*setupcontrols)[2], INT32 (*fromcontrols)[2], const INT32 *gclist, INT32 gclen);
|
||||
void G_SaveKeySetting(FILE *f, INT32 (*fromcontrols)[2], INT32 (*fromcontrolsbis)[2]);
|
||||
INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify, UINT8 player);
|
||||
INT32 G_CheckDoubleUsage(INT32 keynum, boolean modify);
|
||||
|
||||
// sets the members of a mouse_t given position deltas
|
||||
void G_SetMouseDeltas(INT32 dx, INT32 dy, UINT8 ssplayer);
|
||||
|
|
|
@ -5180,7 +5180,15 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
if (thing->rollangle
|
||||
&& !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE)))
|
||||
{
|
||||
rollangle = R_GetRollAngle(thing->rollangle);
|
||||
if (papersprite)
|
||||
{
|
||||
// a positive rollangle should should pitch papersprites upwards relative to their facing angle
|
||||
rollangle = R_GetRollAngle(InvAngle(thing->rollangle));
|
||||
}
|
||||
else
|
||||
{
|
||||
rollangle = R_GetRollAngle(thing->rollangle);
|
||||
}
|
||||
rotsprite = Patch_GetRotatedSprite(sprframe, (thing->frame & FF_FRAMEMASK), rot, flip, false, sprinfo, rollangle);
|
||||
|
||||
if (rotsprite != NULL)
|
||||
|
@ -5234,7 +5242,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
{
|
||||
interpmobjstate_t casterinterp = { 0 };
|
||||
fixed_t groundz;
|
||||
fixed_t floordiff;
|
||||
fixed_t floordiff;
|
||||
|
||||
if (R_UsingFrameInterpolation() && !paused)
|
||||
{
|
||||
|
@ -5244,7 +5252,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
|||
{
|
||||
R_InterpolateMobjState(caster, FRACUNIT, &casterinterp);
|
||||
}
|
||||
|
||||
|
||||
groundz = R_GetShadowZ(thing, NULL);
|
||||
floordiff = abs(((thing->eflags & MFE_VERTICALFLIP) ? caster->height : 0) + casterinterp.z - groundz);
|
||||
|
||||
|
|
|
@ -86,13 +86,8 @@ Contact_error (void)
|
|||
static void
|
||||
get_user_agent(char *buf, size_t len)
|
||||
{
|
||||
#if defined(__STDC__) && __STDC_VERSION__ >= 201112L
|
||||
if (sprintf_s(buf, len, "%s/%s (%s; %s; %i; %i) SRB2BASE/%i", SRB2APPLICATION, VERSIONSTRING, compbranch, comprevision, MODID, MODVERSION, CODEBASE) < 1)
|
||||
if (snprintf(buf, len, "%s/%s (%s; %s; %i; %i) SRB2BASE/%i", SRB2APPLICATION, VERSIONSTRING, compbranch, comprevision, MODID, MODVERSION, CODEBASE) < 0)
|
||||
I_Error("http-mserv: get_user_agent failed");
|
||||
#else
|
||||
if (sprintf(buf, "%s/%s (%s; %s; %i; %i) SRB2BASE/%i", SRB2APPLICATION, VERSIONSTRING, compbranch, comprevision, MODID, MODVERSION, CODEBASE) < 0)
|
||||
I_Error("http-mserv: get_user_agent failed");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -840,7 +840,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;
|
||||
|
@ -1015,6 +1015,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);
|
||||
|
||||
|
|
|
@ -3429,10 +3429,10 @@ state_t states[NUMSTATES] =
|
|||
{SPR_LCKN, 2|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_LOCKONINF3
|
||||
{SPR_LCKN, 3|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_LOCKONINF4
|
||||
|
||||
{SPR_TTAG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_TTAG
|
||||
{SPR_TTAG, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_TTAG
|
||||
|
||||
// CTF Sign
|
||||
{SPR_GFLG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTFLAG
|
||||
{SPR_GFLG, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_GOTFLAG
|
||||
|
||||
// Finish flag
|
||||
{SPR_FNSF, FF_TRANS30, -1, {NULL}, 0, 0, S_NULL}, // S_FINISHFLAG
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include "p_local.h"
|
||||
#include "p_setup.h" // So we can have P_SetupLevelSky
|
||||
#include "p_slopes.h" // P_GetSlopeZAt
|
||||
#include "p_haptic.h"
|
||||
#include "z_zone.h"
|
||||
#include "r_main.h"
|
||||
#include "r_draw.h"
|
||||
|
@ -221,7 +220,6 @@ static const struct {
|
|||
{META_LUABANKS, "luabanks[]"},
|
||||
|
||||
{META_KEYEVENT, "keyevent_t"},
|
||||
{META_GAMEPAD, "gamepad_t"},
|
||||
{META_MOUSE, "mouse_t"},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
@ -1734,78 +1732,6 @@ static int lib_pPlayerShouldUseSpinHeight(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// P_HAPTIC
|
||||
///////////
|
||||
#define GET_OPTIONAL_PLAYER(arg) \
|
||||
player_t *player = NULL; \
|
||||
if (!lua_isnoneornil(L, arg)) { \
|
||||
player = *((player_t **)luaL_checkudata(L, arg, META_PLAYER)); \
|
||||
if (!player) \
|
||||
return LUA_ErrInvalid(L, "player_t"); \
|
||||
}
|
||||
|
||||
static int lib_pDoRumble(lua_State *L)
|
||||
{
|
||||
GET_OPTIONAL_PLAYER(1);
|
||||
fixed_t large_magnitude = luaL_checkfixed(L, 2);
|
||||
fixed_t small_magnitude = luaL_optfixed(L, 3, large_magnitude);
|
||||
tic_t duration = luaL_optinteger(L, 4, 0);
|
||||
|
||||
#define CHECK_MAGNITUDE(which) \
|
||||
if (which##_magnitude < 0 || which##_magnitude > FRACUNIT) \
|
||||
return luaL_error(L, va(#which " motor frequency %f out of range (minimum is 0.0, maximum is 1.0)", \
|
||||
FixedToFloat(which##_magnitude)))
|
||||
|
||||
CHECK_MAGNITUDE(large);
|
||||
CHECK_MAGNITUDE(small);
|
||||
|
||||
#undef CHECK_MAGNITUDE
|
||||
|
||||
lua_pushboolean(L, P_DoRumble(player, large_magnitude, small_magnitude, duration));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pPauseRumble(lua_State *L)
|
||||
{
|
||||
GET_OPTIONAL_PLAYER(1);
|
||||
P_PauseRumble(player);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pUnpauseRumble(lua_State *L)
|
||||
{
|
||||
GET_OPTIONAL_PLAYER(1);
|
||||
P_UnpauseRumble(player);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pIsRumbleEnabled(lua_State *L)
|
||||
{
|
||||
GET_OPTIONAL_PLAYER(1);
|
||||
if (player && P_IsLocalPlayer(player))
|
||||
lua_pushboolean(L, P_IsRumbleEnabled(player));
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pIsRumblePaused(lua_State *L)
|
||||
{
|
||||
GET_OPTIONAL_PLAYER(1);
|
||||
if (player && P_IsLocalPlayer(player))
|
||||
lua_pushboolean(L, P_IsRumblePaused(player));
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pStopRumble(lua_State *L)
|
||||
{
|
||||
GET_OPTIONAL_PLAYER(1);
|
||||
P_StopRumble(player);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// P_MAP
|
||||
///////////
|
||||
|
||||
|
@ -2335,6 +2261,18 @@ static int lib_pMobjTouchingSectorSpecial(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pThingOnSpecial3DFloor(lua_State *L)
|
||||
{
|
||||
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!mo)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
LUA_Deprecated(L, "P_ThingOnSpecial3DFloor", "P_MobjTouchingSectorSpecial\" or \"P_MobjTouchingSectorSpecialFlag");
|
||||
LUA_PushUserdata(L, P_ThingOnSpecial3DFloor(mo), META_SECTOR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pMobjTouchingSectorSpecialFlag(lua_State *L)
|
||||
{
|
||||
mobj_t *mo = *((mobj_t**)luaL_checkudata(L, 1, META_MOBJ));
|
||||
|
@ -3442,6 +3380,7 @@ static int lib_sResumeMusic(lua_State *L)
|
|||
// G_GAME
|
||||
////////////
|
||||
|
||||
// Copypasted from lib_cvRegisterVar :]
|
||||
static int lib_gAddGametype(lua_State *L)
|
||||
{
|
||||
const char *k;
|
||||
|
@ -4163,14 +4102,6 @@ static luaL_Reg lib[] = {
|
|||
{"P_PlayerCanEnterSpinGaps",lib_pPlayerCanEnterSpinGaps},
|
||||
{"P_PlayerShouldUseSpinHeight",lib_pPlayerShouldUseSpinHeight},
|
||||
|
||||
// p_haptic
|
||||
{"P_DoRumble",lib_pDoRumble},
|
||||
{"P_PauseRumble",lib_pPauseRumble},
|
||||
{"P_UnpauseRumble",lib_pUnpauseRumble},
|
||||
{"P_IsRumbleEnabled",lib_pIsRumbleEnabled},
|
||||
{"P_IsRumblePaused",lib_pIsRumblePaused},
|
||||
{"P_StopRumble",lib_pStopRumble},
|
||||
|
||||
// p_map
|
||||
{"P_CheckPosition",lib_pCheckPosition},
|
||||
{"P_TryMove",lib_pTryMove},
|
||||
|
@ -4213,6 +4144,7 @@ static luaL_Reg lib[] = {
|
|||
{"P_DoSuperTransformation",lib_pDoSuperTransformation},
|
||||
{"P_ExplodeMissile",lib_pExplodeMissile},
|
||||
{"P_MobjTouchingSectorSpecial",lib_pMobjTouchingSectorSpecial},
|
||||
{"P_ThingOnSpecial3DFloor",lib_pThingOnSpecial3DFloor},
|
||||
{"P_MobjTouchingSectorSpecialFlag",lib_pMobjTouchingSectorSpecialFlag},
|
||||
{"P_PlayerTouchingSectorSpecial",lib_pPlayerTouchingSectorSpecial},
|
||||
{"P_PlayerTouchingSectorSpecialFlag",lib_pPlayerTouchingSectorSpecialFlag},
|
||||
|
|
|
@ -74,10 +74,6 @@ automatically.
|
|||
X (PlayerCanEnterSpinGaps),\
|
||||
X (KeyDown),\
|
||||
X (KeyUp),\
|
||||
X (GamepadButtonDown),\
|
||||
X (GamepadButtonUp),\
|
||||
X (GamepadAdded),\
|
||||
X (GamepadRemoved),\
|
||||
|
||||
#define STRING_HOOK_LIST(X) \
|
||||
X (BotAI),/* B_BuildTailsTiccmd by skin name */\
|
||||
|
@ -129,8 +125,6 @@ void LUA_HookBool(boolean value, int hook);
|
|||
int LUA_HookPlayer(player_t *, int hook);
|
||||
int LUA_HookTiccmd(player_t *, ticcmd_t *, int hook);
|
||||
int LUA_HookKey(event_t *event, int hook); // Hooks for key events
|
||||
int LUA_HookGamepadButton(event_t *event, int hook);
|
||||
void LUA_HookGamepadEvent(UINT8 which, int hook);
|
||||
|
||||
void LUA_HookThinkFrame(void);
|
||||
int LUA_HookMobjLineCollide(mobj_t *, line_t *);
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include "doomstat.h"
|
||||
#include "p_mobj.h"
|
||||
#include "g_game.h"
|
||||
#include "g_input.h"
|
||||
#include "r_skins.h"
|
||||
#include "b_bot.h"
|
||||
#include "z_zone.h"
|
||||
|
@ -647,28 +646,6 @@ int LUA_HookKey(event_t *event, int hook_type)
|
|||
return hook.status;
|
||||
}
|
||||
|
||||
int LUA_HookGamepadButton(event_t *event, int hook_type)
|
||||
{
|
||||
Hook_State hook;
|
||||
if (prepare_hook(&hook, false, hook_type))
|
||||
{
|
||||
LUA_PushUserdata(gL, &gamepads[event->which], META_GAMEPAD);
|
||||
lua_pushstring(gL, gamepad_button_names[event->key]);
|
||||
call_hooks(&hook, 1, res_true);
|
||||
}
|
||||
return hook.status;
|
||||
}
|
||||
|
||||
void LUA_HookGamepadEvent(UINT8 which, int hook_type)
|
||||
{
|
||||
Hook_State hook;
|
||||
if (prepare_hook(&hook, 0, hook_type))
|
||||
{
|
||||
LUA_PushUserdata(gL, &gamepads[which], META_GAMEPAD);
|
||||
call_hooks(&hook, 0, res_none);
|
||||
}
|
||||
}
|
||||
|
||||
void LUA_HookHUD(int hook_type, huddrawlist_h list)
|
||||
{
|
||||
const hook_t * map = &hudHookIds[hook_type];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -129,21 +128,6 @@ static int lib_getCursorPosition(lua_State *L)
|
|||
return 2;
|
||||
}
|
||||
|
||||
static int lib_getPlayerGamepad(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
INT16 which = G_GetGamepadForPlayer(player);
|
||||
if (which >= 0)
|
||||
LUA_PushUserdata(L, &gamepads[which], META_GAMEPAD);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static luaL_Reg lib[] = {
|
||||
{"gameControlDown", lib_gameControlDown},
|
||||
{"gameControl2Down", lib_gameControl2Down},
|
||||
|
@ -158,7 +142,6 @@ static luaL_Reg lib[] = {
|
|||
{"getMouseGrab", lib_getMouseGrab},
|
||||
{"setMouseGrab", lib_setMouseGrab},
|
||||
{"getCursorPosition", lib_getCursorPosition},
|
||||
{"getPlayerGamepad", lib_getPlayerGamepad},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -214,341 +197,6 @@ static int keyevent_get(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/////////////
|
||||
// GAMEPAD //
|
||||
/////////////
|
||||
|
||||
enum gamepad_leftright_e {
|
||||
gamepad_opt_left,
|
||||
gamepad_opt_right
|
||||
};
|
||||
|
||||
static const char *const gamepad_leftright_opt[] = {
|
||||
"left",
|
||||
"right",
|
||||
NULL};
|
||||
|
||||
// Buttons
|
||||
static int gamepad_isButtonDown(lua_State *L)
|
||||
{
|
||||
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
|
||||
gamepad_button_e button = luaL_checkoption(L, 2, NULL, gamepad_button_names);
|
||||
lua_pushboolean(L, gamepad->buttons[button] == 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Axes
|
||||
static int gamepad_getAxis(lua_State *L)
|
||||
{
|
||||
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
|
||||
gamepad_axis_e axis = luaL_checkoption(L, 2, NULL, gamepad_axis_names);
|
||||
boolean applyDeadzone = luaL_opt(L, luaL_checkboolean, 3, true);
|
||||
lua_pushfixed(L, G_GetAdjustedGamepadAxis(gamepad->num, axis, applyDeadzone));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Sticks
|
||||
static int gamepad_getStick(lua_State *L)
|
||||
{
|
||||
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
|
||||
enum gamepad_leftright_e stick = luaL_checkoption(L, 2, NULL, gamepad_leftright_opt);
|
||||
boolean applyDeadzone = luaL_opt(L, luaL_checkboolean, 3, true);
|
||||
|
||||
switch (stick)
|
||||
{
|
||||
case gamepad_opt_left:
|
||||
lua_pushfixed(L, G_GetAdjustedGamepadAxis(gamepad->num, GAMEPAD_AXIS_LEFTX, applyDeadzone));
|
||||
lua_pushfixed(L, G_GetAdjustedGamepadAxis(gamepad->num, GAMEPAD_AXIS_LEFTY, applyDeadzone));
|
||||
break;
|
||||
case gamepad_opt_right:
|
||||
lua_pushfixed(L, G_GetAdjustedGamepadAxis(gamepad->num, GAMEPAD_AXIS_RIGHTX, applyDeadzone));
|
||||
lua_pushfixed(L, G_GetAdjustedGamepadAxis(gamepad->num, GAMEPAD_AXIS_RIGHTY, applyDeadzone));
|
||||
break;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Triggers
|
||||
static int gamepad_getTrigger(lua_State *L)
|
||||
{
|
||||
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
|
||||
enum gamepad_leftright_e stick = luaL_checkoption(L, 2, NULL, gamepad_leftright_opt);
|
||||
boolean applyDeadzone = luaL_opt(L, luaL_checkboolean, 3, true);
|
||||
gamepad_axis_e axis = 0;
|
||||
|
||||
switch (stick)
|
||||
{
|
||||
case gamepad_opt_left:
|
||||
axis = GAMEPAD_AXIS_TRIGGERLEFT;
|
||||
break;
|
||||
case gamepad_opt_right:
|
||||
axis = GAMEPAD_AXIS_TRIGGERRIGHT;
|
||||
break;
|
||||
}
|
||||
|
||||
lua_pushfixed(L, G_GetAdjustedGamepadAxis(gamepad->num, axis, applyDeadzone));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Button and axis names
|
||||
static int gamepad_getButtonName(lua_State *L)
|
||||
{
|
||||
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
|
||||
gamepad_button_e button = luaL_checkoption(L, 2, NULL, gamepad_button_names);
|
||||
lua_pushstring(L, G_GetGamepadButtonString(gamepad->type, button, GAMEPAD_STRING_DEFAULT));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int gamepad_getAxisName(lua_State *L)
|
||||
{
|
||||
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
|
||||
gamepad_axis_e axis = luaL_checkoption(L, 2, NULL, gamepad_axis_names);
|
||||
lua_pushstring(L, G_GetGamepadAxisString(gamepad->type, axis, GAMEPAD_STRING_DEFAULT, false));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int gamepad_getTriggerName(lua_State *L)
|
||||
{
|
||||
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
|
||||
enum gamepad_leftright_e stick = luaL_checkoption(L, 2, NULL, gamepad_leftright_opt);
|
||||
gamepad_axis_e axis = 0;
|
||||
|
||||
switch (stick)
|
||||
{
|
||||
case gamepad_opt_left:
|
||||
axis = GAMEPAD_AXIS_TRIGGERLEFT;
|
||||
break;
|
||||
case gamepad_opt_right:
|
||||
axis = GAMEPAD_AXIS_TRIGGERRIGHT;
|
||||
break;
|
||||
}
|
||||
|
||||
lua_pushstring(L, G_GetGamepadAxisString(gamepad->type, axis, GAMEPAD_STRING_DEFAULT, false));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Rumble
|
||||
static int gamepad_doRumble(lua_State *L)
|
||||
{
|
||||
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
|
||||
fixed_t large_magnitude = luaL_checkfixed(L, 2);
|
||||
fixed_t small_magnitude = luaL_optfixed(L, 3, large_magnitude);
|
||||
tic_t duration = luaL_optinteger(L, 4, 0);
|
||||
|
||||
#define CHECK_MAGNITUDE(which) \
|
||||
if (which##_magnitude < 0 || which##_magnitude > FRACUNIT) \
|
||||
return luaL_error(L, va(#which " motor frequency %f out of range (minimum is 0.0, maximum is 1.0)", \
|
||||
FixedToFloat(which##_magnitude)))
|
||||
|
||||
CHECK_MAGNITUDE(large);
|
||||
CHECK_MAGNITUDE(small);
|
||||
|
||||
#undef CHECK_MAGNITUDE
|
||||
|
||||
lua_pushboolean(L, G_RumbleGamepad(gamepad->num, large_magnitude, small_magnitude, duration));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int gamepad_stopRumble(lua_State *L)
|
||||
{
|
||||
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
|
||||
G_StopGamepadRumble(gamepad->num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Accessing gamepad userdata
|
||||
enum gamepad_opt_e {
|
||||
gamepad_opt_connected,
|
||||
gamepad_opt_type,
|
||||
gamepad_opt_isXbox,
|
||||
gamepad_opt_isPlayStation,
|
||||
gamepad_opt_isNintendoSwitch,
|
||||
gamepad_opt_isJoyCon,
|
||||
gamepad_opt_hasRumble,
|
||||
gamepad_opt_isRumbling,
|
||||
gamepad_opt_isRumblePaused,
|
||||
gamepad_opt_largeMotorFrequency,
|
||||
gamepad_opt_smallMotorFrequency,
|
||||
gamepad_opt_isButtonDown,
|
||||
gamepad_opt_getAxis,
|
||||
gamepad_opt_getStick,
|
||||
gamepad_opt_getTrigger,
|
||||
gamepad_opt_getButtonName,
|
||||
gamepad_opt_getAxisName,
|
||||
gamepad_opt_getTriggerName,
|
||||
gamepad_opt_rumble,
|
||||
gamepad_opt_stopRumble
|
||||
};
|
||||
|
||||
static const char *const gamepad_opt[] = {
|
||||
"connected",
|
||||
"type",
|
||||
"isXbox",
|
||||
"isPlayStation",
|
||||
"isNintendoSwitch",
|
||||
"isJoyCon",
|
||||
"hasRumble",
|
||||
"isRumbling",
|
||||
"isRumblePaused",
|
||||
"largeMotorFrequency",
|
||||
"smallMotorFrequency",
|
||||
"isButtonDown",
|
||||
"getAxis",
|
||||
"getStick",
|
||||
"getTrigger",
|
||||
"getButtonName",
|
||||
"getAxisName",
|
||||
"getTriggerName",
|
||||
"rumble",
|
||||
"stopRumble",
|
||||
NULL};
|
||||
|
||||
static int (*gamepad_fn_list[9])(lua_State *L) = {
|
||||
gamepad_isButtonDown,
|
||||
gamepad_getAxis,
|
||||
gamepad_getStick,
|
||||
gamepad_getTrigger,
|
||||
gamepad_getButtonName,
|
||||
gamepad_getAxisName,
|
||||
gamepad_getTriggerName,
|
||||
gamepad_doRumble,
|
||||
gamepad_stopRumble
|
||||
};
|
||||
|
||||
static int gamepad_get(lua_State *L)
|
||||
{
|
||||
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
|
||||
enum gamepad_opt_e field = luaL_checkoption(L, 2, NULL, gamepad_opt);
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case gamepad_opt_connected:
|
||||
lua_pushboolean(L, gamepad->connected);
|
||||
break;
|
||||
case gamepad_opt_type:
|
||||
lua_pushstring(L, G_GamepadTypeToString(gamepad->type));
|
||||
break;
|
||||
case gamepad_opt_isXbox:
|
||||
lua_pushboolean(L, G_GamepadTypeIsXbox(gamepad->type));
|
||||
break;
|
||||
case gamepad_opt_isPlayStation:
|
||||
lua_pushboolean(L, G_GamepadTypeIsPlayStation(gamepad->type));
|
||||
break;
|
||||
case gamepad_opt_isNintendoSwitch:
|
||||
lua_pushboolean(L, G_GamepadTypeIsNintendoSwitch(gamepad->type));
|
||||
break;
|
||||
case gamepad_opt_isJoyCon:
|
||||
// No, this does not include the grip.
|
||||
lua_pushboolean(L, G_GamepadTypeIsJoyCon(gamepad->type));
|
||||
break;
|
||||
case gamepad_opt_hasRumble:
|
||||
lua_pushboolean(L, G_RumbleSupported(gamepad->num));
|
||||
break;
|
||||
case gamepad_opt_isRumbling:
|
||||
lua_pushboolean(L, gamepad->rumble.active);
|
||||
break;
|
||||
case gamepad_opt_isRumblePaused:
|
||||
lua_pushboolean(L, G_GetGamepadRumblePaused(gamepad->num));
|
||||
break;
|
||||
case gamepad_opt_largeMotorFrequency:
|
||||
lua_pushfixed(L, G_GetLargeMotorFreq(gamepad->num));
|
||||
break;
|
||||
case gamepad_opt_smallMotorFrequency:
|
||||
lua_pushfixed(L, G_GetSmallMotorFreq(gamepad->num));
|
||||
break;
|
||||
case gamepad_opt_isButtonDown:
|
||||
case gamepad_opt_getAxis:
|
||||
case gamepad_opt_getStick:
|
||||
case gamepad_opt_getTrigger:
|
||||
case gamepad_opt_getButtonName:
|
||||
case gamepad_opt_getAxisName:
|
||||
case gamepad_opt_getTriggerName:
|
||||
case gamepad_opt_rumble:
|
||||
case gamepad_opt_stopRumble:
|
||||
lua_pushcfunction(L, gamepad_fn_list[field - gamepad_opt_isButtonDown]);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int gamepad_set(lua_State *L)
|
||||
{
|
||||
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
|
||||
enum gamepad_opt_e field = luaL_checkoption(L, 2, NULL, gamepad_opt);
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case gamepad_opt_isRumblePaused:
|
||||
G_SetGamepadRumblePaused(gamepad->num, luaL_checkboolean(L, 3));
|
||||
break;
|
||||
case gamepad_opt_largeMotorFrequency:
|
||||
G_SetLargeMotorFreq(gamepad->num, luaL_checkfixed(L, 3));
|
||||
break;
|
||||
case gamepad_opt_smallMotorFrequency:
|
||||
G_SetSmallMotorFreq(gamepad->num, luaL_checkfixed(L, 3));
|
||||
break;
|
||||
default:
|
||||
return luaL_error(L, LUA_QL("gamepad") " field " LUA_QS " should not be set directly.", gamepad_opt[field]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int gamepad_num(lua_State *L)
|
||||
{
|
||||
gamepad_t *gamepad = *((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD));
|
||||
lua_pushinteger(L, gamepad->num + 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_iterateGamepads(lua_State *L)
|
||||
{
|
||||
INT32 i = -1;
|
||||
if (lua_gettop(L) < 2)
|
||||
{
|
||||
lua_pushcfunction(L, lib_iterateGamepads);
|
||||
return 1;
|
||||
}
|
||||
lua_settop(L, 2);
|
||||
lua_remove(L, 1); // State is unused
|
||||
if (!lua_isnil(L, 1))
|
||||
i = (INT32)(*((gamepad_t **)luaL_checkudata(L, 1, META_GAMEPAD)) - gamepads);
|
||||
for (i++; i < NUM_GAMEPADS; i++)
|
||||
{
|
||||
if (!gamepads[i].connected)
|
||||
continue;
|
||||
LUA_PushUserdata(L, &gamepads[i], META_GAMEPAD);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_getGamepad(lua_State *L)
|
||||
{
|
||||
if (lua_type(L, 2) == LUA_TNUMBER)
|
||||
{
|
||||
lua_Integer i = luaL_checkinteger(L, 2);
|
||||
if (i < 1 || i > NUM_GAMEPADS)
|
||||
return luaL_error(L, "gamepads[] index %d out of range (1 - %d)", i, NUM_GAMEPADS);
|
||||
LUA_PushUserdata(L, &gamepads[i - 1], META_GAMEPAD);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fastcmp(luaL_checkstring(L, 2), "iterate"))
|
||||
{
|
||||
lua_pushcfunction(L, lib_iterateGamepads);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_lenGamepad(lua_State *L)
|
||||
{
|
||||
lua_pushinteger(L, NUM_GAMEPADS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
///////////
|
||||
// MOUSE //
|
||||
///////////
|
||||
|
@ -609,27 +257,6 @@ int LUA_InputLib(lua_State *L)
|
|||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_GAMEPAD);
|
||||
lua_pushcfunction(L, gamepad_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, gamepad_set);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
|
||||
lua_pushcfunction(L, gamepad_num);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_newuserdata(L, 0);
|
||||
lua_createtable(L, 0, 2);
|
||||
lua_pushcfunction(L, lib_getGamepad);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, lib_lenGamepad);
|
||||
lua_setfield(L, -2, "__len");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_setglobal(L, "gamepads");
|
||||
|
||||
luaL_newmetatable(L, META_MOUSE);
|
||||
lua_pushcfunction(L, mouse_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
|
|
@ -91,7 +91,6 @@ extern boolean mousegrabbedbylua;
|
|||
#define META_LUABANKS "LUABANKS[]*"
|
||||
|
||||
#define META_KEYEVENT "KEYEVENT_T*"
|
||||
#define META_GAMEPAD "GAMEPAD_T*"
|
||||
#define META_MOUSE "MOUSE_T*"
|
||||
|
||||
boolean luaL_checkboolean(lua_State *L, int narg);
|
||||
|
|
|
@ -949,7 +949,6 @@ enum
|
|||
ARCH_MAPHEADER,
|
||||
ARCH_SKINCOLOR,
|
||||
ARCH_MOUSE,
|
||||
ARCH_GAMEPAD,
|
||||
|
||||
ARCH_TEND=0xFF,
|
||||
};
|
||||
|
@ -977,7 +976,6 @@ static const struct {
|
|||
{META_SLOPE, ARCH_SLOPE},
|
||||
{META_MAPHEADER, ARCH_MAPHEADER},
|
||||
{META_SKINCOLOR, ARCH_SKINCOLOR},
|
||||
{META_GAMEPAD, ARCH_GAMEPAD},
|
||||
{META_MOUSE, ARCH_MOUSE},
|
||||
{NULL, ARCH_NULL}
|
||||
};
|
||||
|
@ -1293,13 +1291,6 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
|
|||
WRITEUINT16(save_p, info - skincolors);
|
||||
break;
|
||||
}
|
||||
case ARCH_GAMEPAD:
|
||||
{
|
||||
gamepad_t *gamepad = *((gamepad_t **)lua_touserdata(gL, myindex));
|
||||
WRITEUINT8(save_p, ARCH_GAMEPAD);
|
||||
WRITEUINT8(save_p, gamepad->num);
|
||||
break;
|
||||
}
|
||||
case ARCH_MOUSE:
|
||||
{
|
||||
mouse_t *m = *((mouse_t **)lua_touserdata(gL, myindex));
|
||||
|
@ -1550,15 +1541,6 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
|
|||
case ARCH_SKINCOLOR:
|
||||
LUA_PushUserdata(gL, &skincolors[READUINT16(save_p)], META_SKINCOLOR);
|
||||
break;
|
||||
case ARCH_GAMEPAD:
|
||||
{
|
||||
UINT8 which = READUINT8(save_p);
|
||||
if (which < NUM_GAMEPADS)
|
||||
LUA_PushUserdata(gL, &gamepads[which], META_GAMEPAD);
|
||||
else // Wait, what?
|
||||
lua_pushnil(gL);
|
||||
break;
|
||||
}
|
||||
case ARCH_MOUSE:
|
||||
LUA_PushUserdata(gL, READUINT16(save_p) == 1 ? &mouse : &mouse2, META_MOUSE);
|
||||
break;
|
||||
|
|
|
@ -30,13 +30,11 @@
|
|||
// TODO add some distinction between fixed numbers and integer numbers
|
||||
// for at least the purpose of printing and maybe math.
|
||||
#define luaL_checkfixed(L, i) luaL_checkinteger(L, i)
|
||||
#define luaL_optfixed(L, i, o) luaL_optinteger(L, i, o)
|
||||
#define lua_pushfixed(L, f) lua_pushinteger(L, f)
|
||||
|
||||
// angle_t casting
|
||||
// TODO deal with signedness
|
||||
#define luaL_checkangle(L, i) ((angle_t)luaL_checkinteger(L, i))
|
||||
#define luaL_optangle(L, i, o) ((angle_t)luaL_optinteger(L, i, o))
|
||||
#define lua_pushangle(L, a) lua_pushinteger(L, a)
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
|
|
@ -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);
|
||||
|
|
797
src/m_menu.c
797
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\
|
||||
|
|
|
@ -2671,7 +2671,7 @@ void A_LobShot(mobj_t *actor)
|
|||
fixed_t z;
|
||||
fixed_t dist;
|
||||
fixed_t vertical, horizontal;
|
||||
fixed_t airtime = var2 & 65535;
|
||||
fixed_t airtime = max(1, var2 & 65535);
|
||||
|
||||
if (LUA_CallAction(A_LOBSHOT, actor))
|
||||
return;
|
||||
|
@ -13460,6 +13460,9 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing)
|
|||
if (!player)
|
||||
return true;
|
||||
|
||||
if (player->spectator)
|
||||
return true;
|
||||
|
||||
if (player->powers[pw_carry] != CR_DUSTDEVIL && (player->powers[pw_ignorelatch] & (1<<15)))
|
||||
return true;
|
||||
|
||||
|
|
|
@ -1660,7 +1660,7 @@ void EV_DoFloor(mtag_t tag, line_t *line, floor_e floortype)
|
|||
// chained linedef executing ability
|
||||
// Only set it on one of the moving sectors (the smallest numbered)
|
||||
if (line->args[3])
|
||||
dofloor->tag = firstone ? (INT16)line->args[3] : -1;
|
||||
dofloor->tag = firstone ? (INT16)line->args[3] : 0;
|
||||
|
||||
// flat changing ability
|
||||
dofloor->texture = line->args[4] ? line->frontsector->floorpic : -1;
|
||||
|
|
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);
|
||||
|
|
|
@ -262,13 +262,15 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
|
|||
}
|
||||
else
|
||||
{
|
||||
INT32 pflags = object->player->pflags & (PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_THOKKED|PF_BOUNCING); // Not identical to below...
|
||||
INT32 pflags = object->player->pflags & (PF_JUMPED|PF_NOJUMPDAMAGE|PF_SPINNING|PF_THOKKED|PF_BOUNCING|PF_CANCARRY); // Not identical to below...
|
||||
UINT8 secondjump = object->player->secondjump;
|
||||
UINT16 tailsfly = object->player->powers[pw_tailsfly];
|
||||
if (object->player->pflags & PF_GLIDING)
|
||||
P_SetPlayerMobjState(object, S_PLAY_FALL);
|
||||
P_ResetPlayer(object->player);
|
||||
object->player->pflags |= pflags;
|
||||
object->player->secondjump = secondjump;
|
||||
object->player->powers[pw_tailsfly] = tailsfly;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
30
src/p_mobj.c
30
src/p_mobj.c
|
@ -3989,12 +3989,11 @@ void P_NullPrecipThinker(precipmobj_t *mobj)
|
|||
{
|
||||
//(void)mobj;
|
||||
mobj->precipflags &= ~PCF_THUNK;
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
}
|
||||
|
||||
void P_SnowThinker(precipmobj_t *mobj)
|
||||
{
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
|
||||
P_CycleStateAnimation((mobj_t *)mobj);
|
||||
|
||||
// adjust height
|
||||
|
@ -4007,8 +4006,6 @@ void P_SnowThinker(precipmobj_t *mobj)
|
|||
|
||||
void P_RainThinker(precipmobj_t *mobj)
|
||||
{
|
||||
R_ResetPrecipitationMobjInterpolationState(mobj);
|
||||
|
||||
P_CycleStateAnimation((mobj_t *)mobj);
|
||||
|
||||
if (mobj->state != &states[S_RAIN1])
|
||||
|
@ -11852,7 +11849,6 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt
|
|||
case MT_EMERHUNT:
|
||||
case MT_EMERALDSPAWN:
|
||||
case MT_TOKEN:
|
||||
case MT_EMBLEM:
|
||||
case MT_RING:
|
||||
case MT_REDTEAMRING:
|
||||
case MT_BLUETEAMRING:
|
||||
|
@ -11864,6 +11860,10 @@ fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mt
|
|||
offset += mthing->args[0] ? 0 : 24*FRACUNIT;
|
||||
break;
|
||||
|
||||
case MT_EMBLEM:
|
||||
offset += mthing->args[1] ? 0 : 24 * FRACUNIT;
|
||||
break;
|
||||
|
||||
// Remaining objects.
|
||||
default:
|
||||
if (P_WeaponOrPanel(mobjtype))
|
||||
|
@ -13280,6 +13280,23 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
|
|||
return true;
|
||||
}
|
||||
|
||||
// Pre-UDMF backwards compatibility stuff. Remove for 2.3
|
||||
static void P_SetAmbush(mapthing_t *mthing, mobj_t *mobj)
|
||||
{
|
||||
if (mobj->type == MT_NIGHTSBUMPER
|
||||
|| mobj->type == MT_AXIS
|
||||
|| mobj->type == MT_AXISTRANSFER
|
||||
|| mobj->type == MT_AXISTRANSFERLINE
|
||||
|| mobj->type == MT_NIGHTSBUMPER
|
||||
|| mobj->type == MT_STARPOST)
|
||||
return;
|
||||
|
||||
if ((mthing->options & MTF_OBJECTSPECIAL) && (mobj->flags & MF_PUSHABLE))
|
||||
return;
|
||||
|
||||
mobj->flags2 |= MF2_AMBUSH;
|
||||
}
|
||||
|
||||
static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t z, mobjtype_t i)
|
||||
{
|
||||
mobj_t *mobj = NULL;
|
||||
|
@ -13302,6 +13319,9 @@ static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y,
|
|||
|
||||
mthing->mobj = mobj;
|
||||
|
||||
if (!udmf && (mthing->options & MTF_AMBUSH))
|
||||
P_SetAmbush(mthing, mobj);
|
||||
|
||||
// Generic reverse gravity for individual objects flag.
|
||||
if (mthing->options & MTF_OBJECTFLIP)
|
||||
{
|
||||
|
|
|
@ -1761,7 +1761,14 @@ static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char
|
|||
else if (fastcmp(param, "triggertag"))
|
||||
sectors[i].triggertag = atol(val);
|
||||
else if (fastcmp(param, "triggerer"))
|
||||
sectors[i].triggerer = atol(val);
|
||||
{
|
||||
if (fastcmp(val, "Player"))
|
||||
sectors[i].triggerer = TO_PLAYER;
|
||||
if (fastcmp(val, "AllPlayers"))
|
||||
sectors[i].triggerer = TO_ALLPLAYERS;
|
||||
if (fastcmp(val, "Mobj"))
|
||||
sectors[i].triggerer = TO_MOBJ;
|
||||
}
|
||||
}
|
||||
|
||||
static void ParseTextmapSidedefParameter(UINT32 i, const char *param, const char *val)
|
||||
|
@ -2263,6 +2270,9 @@ static void P_WriteTextmap(void)
|
|||
case 10:
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Sector %s has ring drainer effect, which is not supported in UDMF. Use linedef type 462 instead.\n"), sizeu1(i));
|
||||
break;
|
||||
case 15:
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Sector %s has bouncy FOF effect, which is not supported in UDMF. Use linedef type 76 instead.\n"), sizeu1(i));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2278,6 +2288,12 @@ static void P_WriteTextmap(void)
|
|||
case 9:
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Sector %s has Egg Capsule type, which is not supported in UDMF. Use linedef type 464 instead.\n"), sizeu1(i));
|
||||
break;
|
||||
case 10:
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Sector %s has special stage time/spheres requirements effect, which is not supported in UDMF. Use the SpecialStageTime and SpecialStageSpheres level header options instead.\n"), sizeu1(i));
|
||||
break;
|
||||
case 11:
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Sector %s has custom global gravity effect, which is not supported in UDMF. Use the Gravity level header option instead.\n"), sizeu1(i));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2633,7 +2649,22 @@ static void P_WriteTextmap(void)
|
|||
if (wsectors[i].triggertag != 0)
|
||||
fprintf(f, "triggertag = %d;\n", wsectors[i].triggertag);
|
||||
if (wsectors[i].triggerer != 0)
|
||||
fprintf(f, "triggerer = %d;\n", wsectors[i].triggerer);
|
||||
{
|
||||
switch (wsectors[i].triggerer)
|
||||
{
|
||||
case TO_PLAYER:
|
||||
fprintf(f, "triggerer = \"Player\";\n");
|
||||
break;
|
||||
case TO_ALLPLAYERS:
|
||||
fprintf(f, "triggerer = \"AllPlayers\";\n");
|
||||
break;
|
||||
case TO_MOBJ:
|
||||
fprintf(f, "triggerer = \"Mobj\";\n");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
fprintf(f, "}\n");
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
@ -4187,7 +4218,8 @@ static void P_ConvertBinaryLinedefTypes(void)
|
|||
lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
|
||||
lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS;
|
||||
lines[i].args[2] = !!(lines[i].flags & ML_SKEWTD);
|
||||
P_WriteConstant(sides[lines[i].sidenum[0]].toptexture, &lines[i].stringargs[0]);
|
||||
if (sides[lines[i].sidenum[0]].toptexture)
|
||||
P_WriteConstant(sides[lines[i].sidenum[0]].toptexture, &lines[i].stringargs[0]);
|
||||
break;
|
||||
case 16: //Minecart parameters
|
||||
lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
|
||||
|
@ -5986,6 +6018,9 @@ static void P_ConvertBinarySectorTypes(void)
|
|||
case 14: //Non-ramp sector
|
||||
sectors[i].specialflags |= SSF_NOSTEPDOWN;
|
||||
break;
|
||||
case 15: //Bouncy FOF
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Deprecated bouncy FOF sector type detected. Please use linedef type 76 instead.\n"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -6018,11 +6053,13 @@ static void P_ConvertBinarySectorTypes(void)
|
|||
sectors[i].triggerer = TO_PLAYER;
|
||||
break;
|
||||
case 6: //Trigger linedef executor (Emerald check)
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Deprecated emerald check sector type detected. Please use linedef types 337-339 instead.\n"));
|
||||
sectors[i].triggertag = tag;
|
||||
sectors[i].flags &= ~MSF_TRIGGERLINE_PLANE;
|
||||
sectors[i].triggerer = TO_PLAYEREMERALDS;
|
||||
break;
|
||||
case 7: //Trigger linedef executor (NiGHTS mare)
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Deprecated NiGHTS mare sector type detected. Please use linedef types 340-342 instead.\n"));
|
||||
sectors[i].triggertag = tag;
|
||||
sectors[i].flags &= ~MSF_TRIGGERLINE_PLANE;
|
||||
sectors[i].triggerer = TO_PLAYERNIGHTS;
|
||||
|
@ -6030,6 +6067,12 @@ static void P_ConvertBinarySectorTypes(void)
|
|||
case 8: //Check for linedef executor on FOFs
|
||||
sectors[i].flags |= MSF_TRIGGERLINE_MOBJ;
|
||||
break;
|
||||
case 10: //Special stage time/spheres requirements
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Deprecated sector type for special stage requirements detected. Please use the SpecialStageTime and SpecialStageSpheres level header options instead.\n"));
|
||||
break;
|
||||
case 11: //Custom global gravity
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Deprecated sector type for global gravity detected. Please use the Gravity level header option instead.\n"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -6266,7 +6309,6 @@ static void P_ConvertBinaryThingTypes(void)
|
|||
case 312: //Emerald token
|
||||
case 320: //Emerald hunt location
|
||||
case 321: //Match chaos emerald spawn
|
||||
case 322: //Emblem
|
||||
case 330: //Bounce ring panel
|
||||
case 331: //Rail ring panel
|
||||
case 332: //Automatic ring panel
|
||||
|
@ -6279,6 +6321,9 @@ static void P_ConvertBinaryThingTypes(void)
|
|||
case 1800: //Coin
|
||||
mapthings[i].args[0] = !(mapthings[i].options & MTF_AMBUSH);
|
||||
break;
|
||||
case 322: //Emblem
|
||||
mapthings[i].args[1] = !(mapthings[i].options & MTF_AMBUSH);
|
||||
break;
|
||||
case 409: //Extra life monitor
|
||||
mapthings[i].args[2] = !(mapthings[i].options & (MTF_AMBUSH|MTF_OBJECTSPECIAL));
|
||||
break;
|
||||
|
|
59
src/p_spec.c
59
src/p_spec.c
|
@ -1760,13 +1760,11 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|
|||
{
|
||||
if (caller->triggerer == TO_PLAYEREMERALDS)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Deprecated emerald check sector type detected. Please use linedef types 337-339 instead.\n"));
|
||||
if (!(ALL7EMERALDS(emeralds)))
|
||||
return false;
|
||||
}
|
||||
else if (caller->triggerer == TO_PLAYERNIGHTS)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Deprecated NiGHTS mare sector type detected. Please use linedef types 340-342 instead.\n"));
|
||||
if (!P_CheckPlayerMareOld(triggerline))
|
||||
return false;
|
||||
}
|
||||
|
@ -4180,6 +4178,29 @@ sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// Deprecated in favor of P_MobjTouchingSectorSpecial
|
||||
// Kept for Lua backwards compatibility only
|
||||
sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
|
||||
for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!rover->master->frontsector->special)
|
||||
continue;
|
||||
|
||||
if (!(rover->fofflags & FOF_EXISTS))
|
||||
continue;
|
||||
|
||||
if (!P_IsMobjTouching3DFloor(mo, rover, mo->subsector->sector))
|
||||
continue;
|
||||
|
||||
return rover->master->frontsector;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sector_t *P_MobjTouchingSectorSpecialFlag(mobj_t *mo, sectorspecialflags_t flag)
|
||||
{
|
||||
msecnode_t *node;
|
||||
|
@ -4375,7 +4396,7 @@ sector_t *P_FindPlayerTrigger(player_t *player, line_t *sourceline)
|
|||
return loopsector;
|
||||
}
|
||||
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
boolean P_IsPlayerValid(size_t playernum)
|
||||
|
@ -4579,6 +4600,9 @@ static void P_ProcessExitSector(player_t *player, mtag_t sectag)
|
|||
if (player->bot)
|
||||
return;
|
||||
|
||||
if (G_IsSpecialStage(gamemap) && !(maptol & TOL_NIGHTS))
|
||||
return;
|
||||
|
||||
// Exit (for FOF exits; others are handled in P_PlayerThink in p_user.c)
|
||||
P_DoPlayerFinish(player);
|
||||
|
||||
|
@ -4627,7 +4651,7 @@ static void P_ProcessTeamBase(player_t *player, boolean redteam)
|
|||
|
||||
// Make sure the team still has their own
|
||||
// flag at their base so they can score.
|
||||
if (!P_IsFlagAtBase(redteam ? MT_BLUEFLAG : MT_REDFLAG))
|
||||
if (!P_IsFlagAtBase(redteam ? MT_REDFLAG : MT_BLUEFLAG))
|
||||
return;
|
||||
|
||||
HU_SetCEchoFlags(V_AUTOFADEOUT|V_ALLOWLOWERCASE);
|
||||
|
@ -5944,8 +5968,6 @@ static inline void P_AddCameraScanner(sector_t *sourcesec, sector_t *actionsecto
|
|||
{
|
||||
elevator_t *elevator; // Why not? LOL
|
||||
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Detected a camera scanner effect (linedef type 5). This effect is deprecated and will be removed in the future!\n"));
|
||||
|
||||
// create and initialize new elevator thinker
|
||||
elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL);
|
||||
P_AddThinker(THINK_MAIN, &elevator->thinker);
|
||||
|
@ -6200,22 +6222,21 @@ void P_SpawnSpecials(boolean fromnetsave)
|
|||
circuitmap = true;
|
||||
}
|
||||
|
||||
if (!sector->special)
|
||||
if (sector->damagetype == SD_SPIKE) {
|
||||
//Terrible hack to replace an even worse hack:
|
||||
//Spike damage automatically sets MSF_TRIGGERSPECIAL_TOUCH.
|
||||
//Yes, this also affects other specials on the same sector. Sorry.
|
||||
sector->flags |= MSF_TRIGGERSPECIAL_TOUCH;
|
||||
}
|
||||
|
||||
// Process deprecated binary sector specials
|
||||
if (udmf || !sector->special)
|
||||
continue;
|
||||
|
||||
// Process Section 1
|
||||
switch(GETSECSPECIAL(sector->special, 1))
|
||||
{
|
||||
case 5: // Spikes
|
||||
//Terrible hack to replace an even worse hack:
|
||||
//Spike damage automatically sets MSF_TRIGGERSPECIAL_TOUCH.
|
||||
//Yes, this also affects other specials on the same sector. Sorry.
|
||||
sector->flags |= MSF_TRIGGERSPECIAL_TOUCH;
|
||||
break;
|
||||
case 15: // Bouncy FOF
|
||||
if (udmf)
|
||||
break;
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Deprecated bouncy FOF sector type detected. Please use linedef type 76 instead.\n"));
|
||||
CheckForBouncySector = true;
|
||||
break;
|
||||
}
|
||||
|
@ -6224,17 +6245,11 @@ void P_SpawnSpecials(boolean fromnetsave)
|
|||
switch(GETSECSPECIAL(sector->special, 2))
|
||||
{
|
||||
case 10: // Time for special stage
|
||||
if (udmf)
|
||||
break;
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Deprecated sector type for special stage requirements detected. Please use the SpecialStageTime and SpecialStageSpheres level header options instead.\n"));
|
||||
sstimer = (sector->floorheight>>FRACBITS) * TICRATE + 6; // Time to finish
|
||||
ssspheres = sector->ceilingheight>>FRACBITS; // Ring count for special stage
|
||||
break;
|
||||
|
||||
case 11: // Custom global gravity!
|
||||
if (udmf)
|
||||
break;
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Deprecated sector type for global gravity detected. Please use the Gravity level header option instead.\n"));
|
||||
gravity = sector->floorheight/1000;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -496,6 +496,7 @@ void P_SpawnSpecials(boolean fromnetsave);
|
|||
// every tic
|
||||
void P_UpdateSpecials(void);
|
||||
sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number);
|
||||
sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo);
|
||||
sector_t *P_MobjTouchingSectorSpecialFlag(mobj_t *mo, sectorspecialflags_t flag);
|
||||
sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 number);
|
||||
sector_t *P_PlayerTouchingSectorSpecialFlag(player_t *player, sectorspecialflags_t flag);
|
||||
|
|
82
src/p_user.c
82
src/p_user.c
|
@ -1,4 +1,3 @@
|
|||
|
||||
// SONIC ROBO BLAST 2
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
|
@ -3108,14 +3107,25 @@ static void P_DoPlayerHeadSigns(player_t *player)
|
|||
if (G_TagGametype())
|
||||
{
|
||||
// If you're "IT", show a big "IT" over your head for others to see.
|
||||
if (player->pflags & PF_TAGIT)
|
||||
if (player->pflags & PF_TAGIT && !P_IsLocalPlayer(player))
|
||||
{
|
||||
if (!P_IsLocalPlayer(player)) // Don't display it on your own view.
|
||||
mobj_t* it = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_TAG);
|
||||
it->x = player->mo->x;
|
||||
it->y = player->mo->y;
|
||||
it->z = player->mo->z;
|
||||
it->old_x = player->mo->old_x;
|
||||
it->old_y = player->mo->old_y;
|
||||
it->old_z = player->mo->old_z;
|
||||
|
||||
if (!(player->mo->eflags & MFE_VERTICALFLIP))
|
||||
{
|
||||
if (!(player->mo->eflags & MFE_VERTICALFLIP))
|
||||
P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height, MT_TAG);
|
||||
else
|
||||
P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z - mobjinfo[MT_TAG].height, MT_TAG)->eflags |= MFE_VERTICALFLIP;
|
||||
it->z += player->mo->height;
|
||||
it->old_z += player->mo->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
it->z -= mobjinfo[MT_TAG].height;
|
||||
it->old_z -= mobjinfo[MT_TAG].height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3125,15 +3135,32 @@ static void P_DoPlayerHeadSigns(player_t *player)
|
|||
// has it (but not on your own screen if you have the flag).
|
||||
if (splitscreen || player != &players[consoleplayer])
|
||||
{
|
||||
mobj_t *sign = P_SpawnMobj(player->mo->x+player->mo->momx, player->mo->y+player->mo->momy,
|
||||
player->mo->z+player->mo->momz, MT_GOTFLAG);
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
fixed_t zofs;
|
||||
mobj_t *sign;
|
||||
boolean player_is_flipped = (player->mo->eflags & MFE_VERTICALFLIP) > 0;
|
||||
|
||||
zofs = player->mo->momz;
|
||||
if (player_is_flipped)
|
||||
{
|
||||
sign->z += player->mo->height-P_GetPlayerHeight(player)-mobjinfo[MT_GOTFLAG].height-FixedMul(16*FRACUNIT, player->mo->scale);
|
||||
sign->eflags |= MFE_VERTICALFLIP;
|
||||
zofs += player->mo->height - P_GetPlayerHeight(player) - mobjinfo[MT_GOTFLAG].height - FixedMul(16 * FRACUNIT, player->mo->scale);
|
||||
}
|
||||
else
|
||||
sign->z += P_GetPlayerHeight(player)+FixedMul(16*FRACUNIT, player->mo->scale);
|
||||
{
|
||||
zofs += P_GetPlayerHeight(player) + FixedMul(16 * FRACUNIT, player->mo->scale);
|
||||
}
|
||||
|
||||
sign = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_GOTFLAG);
|
||||
sign->x = player->mo->x;
|
||||
sign->y = player->mo->y;
|
||||
sign->z = player->mo->z + zofs;
|
||||
sign->old_x = player->mo->old_x;
|
||||
sign->old_y = player->mo->old_y;
|
||||
sign->old_z = player->mo->old_z + zofs;
|
||||
|
||||
if (player_is_flipped)
|
||||
{
|
||||
sign->eflags |= MFE_VERTICALFLIP;
|
||||
}
|
||||
|
||||
if (player->gotflag & GF_REDFLAG)
|
||||
sign->frame = 1|FF_FULLBRIGHT;
|
||||
|
@ -5331,9 +5358,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 +7369,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;
|
||||
|
@ -11038,6 +11065,21 @@ static void P_MinecartThink(player_t *player)
|
|||
S_StartSound(minecart, minecart->info->activesound);
|
||||
}
|
||||
}
|
||||
|
||||
// Mark interpolation; the old positions need to be relative to the displacement from the minecart _after_ it's moved.
|
||||
// This isn't quite correct (it captures the landing wobble) but it works well enough
|
||||
if (detleft)
|
||||
{
|
||||
detleft->old_x = detleft->x - (minecart->old_x - minecart->old_x2);
|
||||
detleft->old_y = detleft->y - (minecart->old_y - minecart->old_y2);
|
||||
detleft->old_z = detleft->z - (minecart->old_z - minecart->old_z2);
|
||||
}
|
||||
if (detright)
|
||||
{
|
||||
detright->old_x = detright->x - (minecart->old_x - minecart->old_x2);
|
||||
detright->old_y = detright->y - (minecart->old_y - minecart->old_y2);
|
||||
detright->old_z = detright->z - (minecart->old_z - minecart->old_z2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -11266,6 +11308,11 @@ static void P_DoTailsOverlay(player_t *player, mobj_t *tails)
|
|||
tails->y = player->mo->y + P_ReturnThrustY(tails, tails->angle, FixedMul(backwards, tails->scale));
|
||||
tails->z = player->mo->z + zoffs;
|
||||
P_SetThingPosition(tails);
|
||||
|
||||
if (player->mo->flags2 & MF2_SHADOW)
|
||||
tails->flags2 |= MF2_SHADOW;
|
||||
else
|
||||
tails->flags2 &= ~MF2_SHADOW;
|
||||
}
|
||||
|
||||
// Metal Sonic's jet fume
|
||||
|
@ -12013,7 +12060,6 @@ void P_PlayerThink(player_t *player)
|
|||
P_DoBubbleBreath(player); // Spawn Sonic's bubbles
|
||||
P_CheckUnderwaterAndSpaceTimer(player); // Display the countdown drown numbers!
|
||||
P_CheckInvincibilityTimer(player); // Spawn Invincibility Sparkles
|
||||
P_DoPlayerHeadSigns(player); // Spawn Tag/CTF signs over player's head
|
||||
|
||||
#if 1
|
||||
// "Blur" a bit when you have speed shoes and are going fast enough
|
||||
|
@ -12878,6 +12924,8 @@ void P_PlayerAfterThink(player_t *player)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
P_DoPlayerHeadSigns(player); // Spawn Tag/CTF signs over player's head
|
||||
}
|
||||
|
||||
void P_SetPlayerAngle(player_t *player, angle_t angle)
|
||||
|
|
|
@ -621,7 +621,13 @@ void SCR_ClosedCaptions(void)
|
|||
y = basey-((i + 2)*10);
|
||||
|
||||
if (closedcaptions[i].b)
|
||||
y -= (closedcaptions[i].b--)*vid.dupy;
|
||||
{
|
||||
y -= closedcaptions[i].b * vid.dupy;
|
||||
if (renderisnewtic)
|
||||
{
|
||||
closedcaptions[i].b--;
|
||||
}
|
||||
}
|
||||
|
||||
if (closedcaptions[i].t < CAPTIONFADETICS)
|
||||
flags |= (((CAPTIONFADETICS-closedcaptions[i].t)/2)*V_10TRANS);
|
||||
|
|
|
@ -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,963 +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 SDL_VERSION_ATLEAST(2,0,9)
|
||||
if (M_CheckParm("-nohidapi"))
|
||||
SDL_SetHintWithPriority(SDL_HINT_JOYSTICK_HIDAPI, "0", SDL_HINT_OVERRIDE);
|
||||
#endif
|
||||
|
||||
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;
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,9)
|
||||
rumble_supported = !M_CheckParm("-norumble");
|
||||
#else
|
||||
rumble_supported = false;
|
||||
#endif
|
||||
|
||||
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
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,6)
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
// 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));
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,12)
|
||||
#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);
|
||||
#if SDL_VERSION_ATLEAST(2,0,14)
|
||||
GAMEPAD_TYPE_CASE(PS5);
|
||||
#endif
|
||||
GAMEPAD_TYPE_CASE(NINTENDO_SWITCH_PRO);
|
||||
#if SDL_VERSION_ATLEAST(2,0,16)
|
||||
GAMEPAD_TYPE_CASE(GOOGLE_STADIA);
|
||||
GAMEPAD_TYPE_CASE(AMAZON_LUNA);
|
||||
#endif
|
||||
GAMEPAD_TYPE_CASE(VIRTUAL);
|
||||
default: break;
|
||||
}
|
||||
#undef GAMEPAD_BUTTON_CASE
|
||||
#else
|
||||
// Under older versions of SDL, we aren't provided controller type information.
|
||||
controller->info->type = GAMEPAD_TYPE_UNKNOWN;
|
||||
#endif // SDL_VERSION_ATLEAST(2,0,12)
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,6)
|
||||
// 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;
|
||||
#endif
|
||||
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText(" Type: %s\n"), G_GamepadTypeToString(controller->info->type));
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,12)
|
||||
// Change the ring LEDs on Xbox 360 controllers
|
||||
// FIXME: Doesn't seem to work?
|
||||
SDL_GameControllerSetPlayerIndex(controller->dev, which);
|
||||
#endif
|
||||
|
||||
#if SDL_VERSION_ATLEAST(2,0,18)
|
||||
// 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"));
|
||||
}
|
||||
#else
|
||||
controller->info->rumble.supported = true;
|
||||
CONS_Debug(DBG_GAMELOGIC, M_GetText(" Rumble supported: Maybe\n"));
|
||||
#endif // SDL_VERSION_ATLEAST(2,0,18)
|
||||
|
||||
if (!controller->info->connected)
|
||||
{
|
||||
controller->info->connected = true;
|
||||
G_OnGamepadConnect(which);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
#if SDL_VERSION_ATLEAST(2,0,14)
|
||||
GAMEPAD_BUTTON_CASE(MISC1);
|
||||
GAMEPAD_BUTTON_CASE(PADDLE1);
|
||||
GAMEPAD_BUTTON_CASE(PADDLE2);
|
||||
GAMEPAD_BUTTON_CASE(PADDLE3);
|
||||
GAMEPAD_BUTTON_CASE(PADDLE4);
|
||||
GAMEPAD_BUTTON_CASE(TOUCHPAD);
|
||||
#endif
|
||||
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 SDL_VERSION_ATLEAST(2,0,9)
|
||||
if (gamepad->rumble.supported)
|
||||
SDL_GameControllerRumble(controller->dev, 0, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
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_VERSION_ATLEAST(2,0,9)
|
||||
if (SDL_GameControllerRumble(c->dev, c->rumble.large_magnitude, c->rumble.small_magnitude, 0) == -1)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
#else
|
||||
(void)c;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void I_ToggleControllerRumble(boolean unpause)
|
||||
{
|
||||
#if SDL_VERSION_ATLEAST(2,0,9)
|
||||
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;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)unpause;
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
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 SDL_VERSION_ATLEAST(2,0,9)
|
||||
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;
|
||||
#else
|
||||
(void)which;
|
||||
(void)pause;
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ hudinfo_t hudinfo[NUMHUDITEMS] =
|
|||
{ 288, 176, V_SNAPTORIGHT|V_SNAPTOBOTTOM}, // HUD_POWERUPS
|
||||
};
|
||||
|
||||
static huddrawlist_h luahuddrawlist_game;
|
||||
static huddrawlist_h luahuddrawlist_game[2];
|
||||
static huddrawlist_h luahuddrawlist_titlecard;
|
||||
|
||||
//
|
||||
|
@ -427,7 +427,8 @@ void ST_Init(void)
|
|||
|
||||
ST_LoadGraphics();
|
||||
|
||||
luahuddrawlist_game = LUA_HUD_CreateDrawList();
|
||||
luahuddrawlist_game[0] = LUA_HUD_CreateDrawList();
|
||||
luahuddrawlist_game[1] = LUA_HUD_CreateDrawList();
|
||||
luahuddrawlist_titlecard = LUA_HUD_CreateDrawList();
|
||||
}
|
||||
|
||||
|
@ -2757,10 +2758,13 @@ static void ST_overlayDrawer(void)
|
|||
|
||||
if (!(netgame || multiplayer) || !hu_showscores)
|
||||
{
|
||||
INT32 hooklistindex = splitscreen && stplyr == &players[secondarydisplayplayer] ? 1 : 0;
|
||||
if (renderisnewtic)
|
||||
{
|
||||
LUA_HUDHOOK(game, luahuddrawlist_game);
|
||||
LUA_HUD_ClearDrawList(luahuddrawlist_game[hooklistindex]);
|
||||
LUA_HUDHOOK(game, luahuddrawlist_game[hooklistindex]);
|
||||
}
|
||||
LUA_HUD_DrawList(luahuddrawlist_game[hooklistindex]);
|
||||
}
|
||||
|
||||
// draw level title Tails
|
||||
|
@ -2839,10 +2843,6 @@ void ST_Drawer(void)
|
|||
|
||||
if (st_overlay)
|
||||
{
|
||||
if (renderisnewtic)
|
||||
{
|
||||
LUA_HUD_ClearDrawList(luahuddrawlist_game);
|
||||
}
|
||||
// No deadview!
|
||||
stplyr = &players[displayplayer];
|
||||
ST_overlayDrawer();
|
||||
|
@ -2852,7 +2852,5 @@ void ST_Drawer(void)
|
|||
stplyr = &players[secondarydisplayplayer];
|
||||
ST_overlayDrawer();
|
||||
}
|
||||
|
||||
LUA_HUD_DrawList(luahuddrawlist_game);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -472,5 +472,5 @@ mtag_t Tag_NextUnused(mtag_t start)
|
|||
start++;
|
||||
}
|
||||
|
||||
return MAXTAGS;
|
||||
return (mtag_t)MAXTAGS;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue