mirror of
https://github.com/fabiangreffrath/woof.git
synced 2025-09-22 11:22:18 -04:00
Add custom weapon slots feature (#1923)
* Lower priority of shortcut responder * Raise priority of chat, cheat, automap responders * Add custom weapon slots * Disable weapon slots by default
This commit is contained in:
parent
d225e33c3f
commit
796c0d01c3
@ -146,6 +146,7 @@ set(WOOF_SOURCES
|
|||||||
w_zip.c
|
w_zip.c
|
||||||
wi_stuff.c wi_stuff.h
|
wi_stuff.c wi_stuff.h
|
||||||
wi_interlvl.c wi_interlvl.h
|
wi_interlvl.c wi_interlvl.h
|
||||||
|
ws_stuff.c ws_stuff.h
|
||||||
z_zone.c z_zone.h)
|
z_zone.c z_zone.h)
|
||||||
|
|
||||||
# Standard target definition
|
# Standard target definition
|
||||||
|
24
src/am_map.c
24
src/am_map.c
@ -48,6 +48,7 @@
|
|||||||
#include "v_flextran.h"
|
#include "v_flextran.h"
|
||||||
#include "v_fmt.h"
|
#include "v_fmt.h"
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
|
#include "ws_stuff.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
|
|
||||||
//jff 1/7/98 default automap colors added
|
//jff 1/7/98 default automap colors added
|
||||||
@ -794,7 +795,7 @@ boolean AM_Responder
|
|||||||
|
|
||||||
if (!automapactive)
|
if (!automapactive)
|
||||||
{
|
{
|
||||||
if (M_InputActivated(input_map))
|
if (M_InputActivated(input_map) && !WS_Override())
|
||||||
{
|
{
|
||||||
AM_Start ();
|
AM_Start ();
|
||||||
viewactive = false;
|
viewactive = false;
|
||||||
@ -808,22 +809,22 @@ boolean AM_Responder
|
|||||||
rc = true;
|
rc = true;
|
||||||
// phares
|
// phares
|
||||||
if (M_InputActivated(input_map_right)) // |
|
if (M_InputActivated(input_map_right)) // |
|
||||||
if (!followplayer) // V
|
if (!followplayer && !WS_HoldOverride()) // V
|
||||||
buttons_state[PAN_RIGHT] = 1;
|
buttons_state[PAN_RIGHT] = 1;
|
||||||
else
|
else
|
||||||
rc = false;
|
rc = false;
|
||||||
else if (M_InputActivated(input_map_left))
|
else if (M_InputActivated(input_map_left))
|
||||||
if (!followplayer)
|
if (!followplayer && !WS_HoldOverride())
|
||||||
buttons_state[PAN_LEFT] = 1;
|
buttons_state[PAN_LEFT] = 1;
|
||||||
else
|
else
|
||||||
rc = false;
|
rc = false;
|
||||||
else if (M_InputActivated(input_map_up))
|
else if (M_InputActivated(input_map_up))
|
||||||
if (!followplayer)
|
if (!followplayer && !WS_HoldOverride())
|
||||||
buttons_state[PAN_UP] = 1;
|
buttons_state[PAN_UP] = 1;
|
||||||
else
|
else
|
||||||
rc = false;
|
rc = false;
|
||||||
else if (M_InputActivated(input_map_down))
|
else if (M_InputActivated(input_map_down))
|
||||||
if (!followplayer)
|
if (!followplayer && !WS_HoldOverride())
|
||||||
buttons_state[PAN_DOWN] = 1;
|
buttons_state[PAN_DOWN] = 1;
|
||||||
else
|
else
|
||||||
rc = false;
|
rc = false;
|
||||||
@ -851,9 +852,16 @@ boolean AM_Responder
|
|||||||
}
|
}
|
||||||
else if (M_InputActivated(input_map))
|
else if (M_InputActivated(input_map))
|
||||||
{
|
{
|
||||||
bigstate = 0;
|
if (!WS_Override())
|
||||||
viewactive = true;
|
{
|
||||||
AM_Stop ();
|
bigstate = 0;
|
||||||
|
viewactive = true;
|
||||||
|
AM_Stop ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (M_InputActivated(input_map_gobig))
|
else if (M_InputActivated(input_map_gobig))
|
||||||
{
|
{
|
||||||
|
@ -84,6 +84,7 @@
|
|||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
#include "wi_stuff.h"
|
#include "wi_stuff.h"
|
||||||
|
#include "ws_stuff.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
|
|
||||||
// DEHacked support - Ty 03/09/97
|
// DEHacked support - Ty 03/09/97
|
||||||
@ -2439,6 +2440,7 @@ void D_DoomMain(void)
|
|||||||
G_UpdateGamepadVariables();
|
G_UpdateGamepadVariables();
|
||||||
G_UpdateMouseVariables();
|
G_UpdateMouseVariables();
|
||||||
R_UpdateViewAngleFunction();
|
R_UpdateViewAngleFunction();
|
||||||
|
WS_Init();
|
||||||
|
|
||||||
MN_ResetTimeScale();
|
MN_ResetTimeScale();
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
// This is the stuff configured by Setup.Exe.
|
// This is the stuff configured by Setup.Exe.
|
||||||
// Most key data are simple ascii (uppercased).
|
// Most key data are simple ascii (uppercased).
|
||||||
//
|
//
|
||||||
|
#define NUMKEYS 256
|
||||||
#define KEY_RIGHTARROW 0xae
|
#define KEY_RIGHTARROW 0xae
|
||||||
#define KEY_LEFTARROW 0xac
|
#define KEY_LEFTARROW 0xac
|
||||||
#define KEY_UPARROW 0xad
|
#define KEY_UPARROW 0xad
|
||||||
|
31
src/g_game.c
31
src/g_game.c
@ -90,6 +90,7 @@
|
|||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
#include "wi_stuff.h"
|
#include "wi_stuff.h"
|
||||||
|
#include "ws_stuff.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
|
|
||||||
#define SAVEGAMESIZE 0x20000
|
#define SAVEGAMESIZE 0x20000
|
||||||
@ -188,7 +189,6 @@ static boolean dclick_use;
|
|||||||
#define TURBOTHRESHOLD 0x32
|
#define TURBOTHRESHOLD 0x32
|
||||||
#define SLOWTURNTICS 6
|
#define SLOWTURNTICS 6
|
||||||
#define QUICKREVERSE 32768 // 180 degree reverse // phares
|
#define QUICKREVERSE 32768 // 180 degree reverse // phares
|
||||||
#define NUMKEYS 256
|
|
||||||
|
|
||||||
fixed_t forwardmove[2] = {0x19, 0x32};
|
fixed_t forwardmove[2] = {0x19, 0x32};
|
||||||
fixed_t default_sidemove[2] = {0x18, 0x28};
|
fixed_t default_sidemove[2] = {0x18, 0x28};
|
||||||
@ -857,6 +857,10 @@ void G_BuildTiccmd(ticcmd_t* cmd)
|
|||||||
boom_weapon_state_injection = false;
|
boom_weapon_state_injection = false;
|
||||||
newweapon = P_SwitchWeapon(&players[consoleplayer]); // phares
|
newweapon = P_SwitchWeapon(&players[consoleplayer]); // phares
|
||||||
}
|
}
|
||||||
|
else if (WS_SlotSelected())
|
||||||
|
{
|
||||||
|
newweapon = WS_SlotWeapon();
|
||||||
|
}
|
||||||
else if (M_InputGameActive(input_lastweapon))
|
else if (M_InputGameActive(input_lastweapon))
|
||||||
{
|
{
|
||||||
newweapon = LastWeapon();
|
newweapon = LastWeapon();
|
||||||
@ -899,6 +903,7 @@ void G_BuildTiccmd(ticcmd_t* cmd)
|
|||||||
|
|
||||||
// [FG] prev/next weapon keys and buttons
|
// [FG] prev/next weapon keys and buttons
|
||||||
next_weapon = 0;
|
next_weapon = 0;
|
||||||
|
WS_ClearSharedEvent();
|
||||||
|
|
||||||
// [FG] double click acts as "use"
|
// [FG] double click acts as "use"
|
||||||
if (dclick)
|
if (dclick)
|
||||||
@ -946,6 +951,7 @@ void G_ClearInput(void)
|
|||||||
memset(&basecmd, 0, sizeof(basecmd));
|
memset(&basecmd, 0, sizeof(basecmd));
|
||||||
I_ResetRelativeMouseState();
|
I_ResetRelativeMouseState();
|
||||||
I_ResetAllRumbleChannels();
|
I_ResetAllRumbleChannels();
|
||||||
|
WS_Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -1316,6 +1322,23 @@ boolean G_MovementResponder(event_t *ev)
|
|||||||
|
|
||||||
boolean G_Responder(event_t* ev)
|
boolean G_Responder(event_t* ev)
|
||||||
{
|
{
|
||||||
|
WS_UpdateState(ev);
|
||||||
|
|
||||||
|
// killough 9/29/98: reformatted
|
||||||
|
if (gamestate == GS_LEVEL
|
||||||
|
&& (HU_Responder(ev) || // chat ate the event
|
||||||
|
ST_Responder(ev) || // status window ate it
|
||||||
|
AM_Responder(ev) || // automap ate it
|
||||||
|
WS_Responder(ev))) // weapon slots ate it
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (M_ShortcutResponder(ev))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// allow spy mode changes even during the demo
|
// allow spy mode changes even during the demo
|
||||||
// killough 2/22/98: even during DM demo
|
// killough 2/22/98: even during DM demo
|
||||||
//
|
//
|
||||||
@ -1346,12 +1369,6 @@ boolean G_Responder(event_t* ev)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// killough 9/29/98: reformatted
|
|
||||||
if (gamestate == GS_LEVEL && (HU_Responder(ev) || // chat ate the event
|
|
||||||
ST_Responder(ev) || // status window ate it
|
|
||||||
AM_Responder(ev))) // automap ate it
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// any other key pops up menu if in demos
|
// any other key pops up menu if in demos
|
||||||
//
|
//
|
||||||
// killough 8/2/98: enable automap in -timedemo demos
|
// killough 8/2/98: enable automap in -timedemo demos
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
static SDL_GameController *gamepad;
|
static SDL_GameController *gamepad;
|
||||||
static boolean gyro_supported;
|
static boolean gyro_supported;
|
||||||
|
static joy_platform_t platform;
|
||||||
|
|
||||||
// [FG] adapt joystick button and axis handling from Chocolate Doom 3.0
|
// [FG] adapt joystick button and axis handling from Chocolate Doom 3.0
|
||||||
|
|
||||||
@ -265,9 +266,27 @@ static joy_platform_t GetSwitchSubPlatform(void)
|
|||||||
return PLATFORM_SWITCH_PRO;
|
return PLATFORM_SWITCH_PRO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void I_GetFaceButtons(int *buttons)
|
||||||
|
{
|
||||||
|
if (platform < PLATFORM_SWITCH)
|
||||||
|
{
|
||||||
|
buttons[0] = GAMEPAD_Y;
|
||||||
|
buttons[1] = GAMEPAD_A;
|
||||||
|
buttons[2] = GAMEPAD_X;
|
||||||
|
buttons[3] = GAMEPAD_B;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buttons[0] = GAMEPAD_X;
|
||||||
|
buttons[1] = GAMEPAD_B;
|
||||||
|
buttons[2] = GAMEPAD_Y;
|
||||||
|
buttons[3] = GAMEPAD_A;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void UpdatePlatform(void)
|
static void UpdatePlatform(void)
|
||||||
{
|
{
|
||||||
joy_platform_t platform = joy_platform;
|
platform = joy_platform;
|
||||||
|
|
||||||
if (platform == PLATFORM_AUTO)
|
if (platform == PLATFORM_AUTO)
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,7 @@ enum evtype_e;
|
|||||||
int I_GetAxisState(int axis);
|
int I_GetAxisState(int axis);
|
||||||
boolean I_UseGamepad(void);
|
boolean I_UseGamepad(void);
|
||||||
boolean I_GyroSupported(void);
|
boolean I_GyroSupported(void);
|
||||||
|
void I_GetFaceButtons(int *buttons);
|
||||||
void I_FlushGamepadSensorEvents(void);
|
void I_FlushGamepadSensorEvents(void);
|
||||||
void I_FlushGamepadEvents(void);
|
void I_FlushGamepadEvents(void);
|
||||||
void I_SetSensorEventState(boolean condition);
|
void I_SetSensorEventState(boolean condition);
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
#include "tables.h"
|
#include "tables.h"
|
||||||
#include "u_mapinfo.h"
|
#include "u_mapinfo.h"
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
|
#include "ws_stuff.h"
|
||||||
|
|
||||||
#define plyr (players+consoleplayer) /* the console player */
|
#define plyr (players+consoleplayer) /* the console player */
|
||||||
|
|
||||||
@ -1312,6 +1313,9 @@ boolean M_CheatResponder(event_t *ev)
|
|||||||
if (ev->type == ev_keydown && M_FindCheats(ev->data1.i))
|
if (ev->type == ev_keydown && M_FindCheats(ev->data1.i))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (WS_Override())
|
||||||
|
return false;
|
||||||
|
|
||||||
for (i = 0; i < arrlen(cheat_input); ++i)
|
for (i = 0; i < arrlen(cheat_input); ++i)
|
||||||
{
|
{
|
||||||
if (M_InputActivated(cheat_input[i].input))
|
if (M_InputActivated(cheat_input[i].input))
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
#include "r_main.h"
|
#include "r_main.h"
|
||||||
#include "st_stuff.h"
|
#include "st_stuff.h"
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
|
#include "ws_stuff.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -133,6 +134,7 @@ void M_InitConfig(void)
|
|||||||
G_BindEnemVariables();
|
G_BindEnemVariables();
|
||||||
G_BindCompVariables();
|
G_BindCompVariables();
|
||||||
G_BindWeapVariables();
|
G_BindWeapVariables();
|
||||||
|
WS_BindVariables();
|
||||||
|
|
||||||
HU_BindHUDVariables();
|
HU_BindHUDVariables();
|
||||||
ST_BindSTSVariables();
|
ST_BindSTSVariables();
|
||||||
|
@ -2108,7 +2108,7 @@ void M_Ticker(void)
|
|||||||
// action based on the state of the system.
|
// action based on the state of the system.
|
||||||
//
|
//
|
||||||
|
|
||||||
static boolean ShortcutResponder(const event_t *ev)
|
boolean M_ShortcutResponder(const event_t *ev)
|
||||||
{
|
{
|
||||||
// If there is no active menu displayed...
|
// If there is no active menu displayed...
|
||||||
|
|
||||||
@ -2823,11 +2823,6 @@ boolean M_Responder(event_t *ev)
|
|||||||
G_ScreenShot();
|
G_ScreenShot();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ShortcutResponder(ev))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pop-up Main menu?
|
// Pop-up Main menu?
|
||||||
|
|
||||||
if (!menuactive)
|
if (!menuactive)
|
||||||
|
@ -35,6 +35,8 @@ struct event_s;
|
|||||||
|
|
||||||
boolean M_Responder(struct event_s *ev);
|
boolean M_Responder(struct event_s *ev);
|
||||||
|
|
||||||
|
boolean M_ShortcutResponder(const struct event_s *ev);
|
||||||
|
|
||||||
// Called by main loop,
|
// Called by main loop,
|
||||||
// only used for menu (skull cursor) animation.
|
// only used for menu (skull cursor) animation.
|
||||||
|
|
||||||
|
196
src/mn_setup.c
196
src/mn_setup.c
@ -57,6 +57,7 @@
|
|||||||
#include "v_fmt.h"
|
#include "v_fmt.h"
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
|
#include "ws_stuff.h"
|
||||||
#include "z_zone.h"
|
#include "z_zone.h"
|
||||||
|
|
||||||
static int M_GetKeyString(int c, int offset);
|
static int M_GetKeyString(int c, int offset);
|
||||||
@ -132,6 +133,9 @@ static boolean default_reset;
|
|||||||
#define MI_GAP \
|
#define MI_GAP \
|
||||||
{NULL, S_SKIP, 0, M_SPC}
|
{NULL, S_SKIP, 0, M_SPC}
|
||||||
|
|
||||||
|
#define MI_GAP_HALF \
|
||||||
|
{NULL, S_SKIP, 0, M_SPC / 2}
|
||||||
|
|
||||||
static void DisableItem(boolean condition, setup_menu_t *menu, const char *item)
|
static void DisableItem(boolean condition, setup_menu_t *menu, const char *item)
|
||||||
{
|
{
|
||||||
while (!(menu->m_flags & S_END))
|
while (!(menu->m_flags & S_END))
|
||||||
@ -322,6 +326,9 @@ enum
|
|||||||
str_overlay,
|
str_overlay,
|
||||||
str_automap_preset,
|
str_automap_preset,
|
||||||
str_automap_keyed_door,
|
str_automap_keyed_door,
|
||||||
|
str_weapon_slots_activation,
|
||||||
|
str_weapon_slots_selection,
|
||||||
|
str_weapon_slots,
|
||||||
|
|
||||||
str_resolution_scale,
|
str_resolution_scale,
|
||||||
str_midi_player,
|
str_midi_player,
|
||||||
@ -1508,6 +1515,7 @@ void MN_DrawKeybnd(void)
|
|||||||
|
|
||||||
static setup_tab_t weap_tabs[] = {
|
static setup_tab_t weap_tabs[] = {
|
||||||
{"cosmetic"},
|
{"cosmetic"},
|
||||||
|
{"slots"},
|
||||||
{"preferences"},
|
{"preferences"},
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
@ -1542,7 +1550,160 @@ static setup_menu_t weap_settings1[] = {
|
|||||||
MI_END
|
MI_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *weapon_slots_activation_strings[] = {
|
||||||
|
"Off", "Hold \"Last\"", "Always On"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *weapon_slots_selection_strings[] = {
|
||||||
|
"D-Pad", "Face Buttons", "1-4 Keys"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char **GetWeaponSlotStrings(void)
|
||||||
|
{
|
||||||
|
static const char *vanilla_doom_strings[] = {
|
||||||
|
"--", "Chainsaw/Fist", "Pistol", "Shotgun", "Chaingun",
|
||||||
|
"Rocket", "Plasma", "BFG", "Chainsaw/Fist", "Shotgun"
|
||||||
|
};
|
||||||
|
static const char *vanilla_doom2_strings[] = {
|
||||||
|
"--", "Chainsaw/Fist", "Pistol", "SSG/Shotgun", "Chaingun",
|
||||||
|
"Rocket", "Plasma", "BFG", "Chainsaw/Fist", "SSG/Shotgun"
|
||||||
|
};
|
||||||
|
static const char *full_doom2_strings[] = {
|
||||||
|
"--", "Fist", "Pistol", "Shotgun", "Chaingun",
|
||||||
|
"Rocket", "Plasma", "BFG", "Chainsaw", "SSG"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (force_complevel == CL_VANILLA || default_complevel == CL_VANILLA)
|
||||||
|
{
|
||||||
|
return (ALLOW_SSG ? vanilla_doom2_strings : vanilla_doom_strings);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return full_doom2_strings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WS_BUF_SiZE 80
|
||||||
|
static char slot_labels[NUM_WS_SLOTS * NUM_WS_WEAPS][WS_BUF_SiZE];
|
||||||
|
|
||||||
|
static void UpdateWeaponSlotLabels(void)
|
||||||
|
{
|
||||||
|
const char *keys[NUM_WS_SLOTS];
|
||||||
|
int buttons[NUM_WS_SLOTS];
|
||||||
|
|
||||||
|
switch (WS_Selection())
|
||||||
|
{
|
||||||
|
case WS_SELECT_DPAD:
|
||||||
|
keys[0] = M_GetPlatformName(GAMEPAD_DPAD_UP);
|
||||||
|
keys[1] = M_GetPlatformName(GAMEPAD_DPAD_DOWN);
|
||||||
|
keys[2] = M_GetPlatformName(GAMEPAD_DPAD_LEFT);
|
||||||
|
keys[3] = M_GetPlatformName(GAMEPAD_DPAD_RIGHT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WS_SELECT_FACE_BUTTONS:
|
||||||
|
I_GetFaceButtons(buttons);
|
||||||
|
keys[0] = M_GetPlatformName(buttons[0]);
|
||||||
|
keys[1] = M_GetPlatformName(buttons[1]);
|
||||||
|
keys[2] = M_GetPlatformName(buttons[2]);
|
||||||
|
keys[3] = M_GetPlatformName(buttons[3]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: // WS_SELECT_1234
|
||||||
|
keys[0] = "1-Key";
|
||||||
|
keys[1] = "2-Key";
|
||||||
|
keys[2] = "3-Key";
|
||||||
|
keys[3] = "4-Key";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *pos[NUM_WS_WEAPS] = {"1st", "2nd", "3rd"};
|
||||||
|
int num = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_WS_SLOTS; i++)
|
||||||
|
{
|
||||||
|
M_snprintf(slot_labels[num++], WS_BUF_SiZE, "%s %s", keys[i], pos[0]);
|
||||||
|
|
||||||
|
for (int j = 1; j < NUM_WS_WEAPS; j++)
|
||||||
|
{
|
||||||
|
M_snprintf(slot_labels[num++], WS_BUF_SiZE, "%s", pos[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdateWeaponSlotItems(void);
|
||||||
|
|
||||||
|
static void UpdateWeaponSlotActivation(void)
|
||||||
|
{
|
||||||
|
WS_Reset();
|
||||||
|
UpdateWeaponSlotItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdateWeaponSlotSelection(void)
|
||||||
|
{
|
||||||
|
WS_UpdateSelection();
|
||||||
|
WS_Reset();
|
||||||
|
UpdateWeaponSlotLabels();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdateWeaponSlots(void)
|
||||||
|
{
|
||||||
|
WS_UpdateSlots();
|
||||||
|
WS_Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MI_WEAPON_SLOT(i, s) \
|
||||||
|
{slot_labels[i], S_CHOICE, CNTR_X, M_SPC, {s}, \
|
||||||
|
.strings_id = str_weapon_slots, .action = UpdateWeaponSlots}
|
||||||
|
|
||||||
static setup_menu_t weap_settings2[] = {
|
static setup_menu_t weap_settings2[] = {
|
||||||
|
|
||||||
|
{"Enable Slots", S_CHOICE, CNTR_X, M_SPC, {"weapon_slots_activation"},
|
||||||
|
.strings_id = str_weapon_slots_activation,
|
||||||
|
.action = UpdateWeaponSlotActivation},
|
||||||
|
|
||||||
|
{"Select Slots", S_CHOICE, CNTR_X, M_SPC, {"weapon_slots_selection"},
|
||||||
|
.strings_id = str_weapon_slots_selection,
|
||||||
|
.action = UpdateWeaponSlotSelection},
|
||||||
|
|
||||||
|
MI_GAP_HALF,
|
||||||
|
MI_WEAPON_SLOT(0, "weapon_slots_1_1"),
|
||||||
|
MI_WEAPON_SLOT(1, "weapon_slots_1_2"),
|
||||||
|
MI_WEAPON_SLOT(2, "weapon_slots_1_3"),
|
||||||
|
MI_GAP_HALF,
|
||||||
|
MI_WEAPON_SLOT(3, "weapon_slots_2_1"),
|
||||||
|
MI_WEAPON_SLOT(4, "weapon_slots_2_2"),
|
||||||
|
MI_WEAPON_SLOT(5, "weapon_slots_2_3"),
|
||||||
|
MI_GAP_HALF,
|
||||||
|
MI_WEAPON_SLOT(6, "weapon_slots_3_1"),
|
||||||
|
MI_WEAPON_SLOT(7, "weapon_slots_3_2"),
|
||||||
|
MI_WEAPON_SLOT(8, "weapon_slots_3_3"),
|
||||||
|
MI_GAP_HALF,
|
||||||
|
MI_WEAPON_SLOT(9, "weapon_slots_4_1"),
|
||||||
|
MI_WEAPON_SLOT(10, "weapon_slots_4_2"),
|
||||||
|
MI_WEAPON_SLOT(11, "weapon_slots_4_3"),
|
||||||
|
MI_END
|
||||||
|
};
|
||||||
|
|
||||||
|
static void UpdateWeaponSlotItems(void)
|
||||||
|
{
|
||||||
|
const boolean condition = !WS_Enabled();
|
||||||
|
|
||||||
|
DisableItem(condition, weap_settings2, "weapon_slots_selection");
|
||||||
|
DisableItem(condition, weap_settings2, "weapon_slots_1_1");
|
||||||
|
DisableItem(condition, weap_settings2, "weapon_slots_1_2");
|
||||||
|
DisableItem(condition, weap_settings2, "weapon_slots_1_3");
|
||||||
|
DisableItem(condition, weap_settings2, "weapon_slots_2_1");
|
||||||
|
DisableItem(condition, weap_settings2, "weapon_slots_2_2");
|
||||||
|
DisableItem(condition, weap_settings2, "weapon_slots_2_3");
|
||||||
|
DisableItem(condition, weap_settings2, "weapon_slots_3_1");
|
||||||
|
DisableItem(condition, weap_settings2, "weapon_slots_3_2");
|
||||||
|
DisableItem(condition, weap_settings2, "weapon_slots_3_3");
|
||||||
|
DisableItem(condition, weap_settings2, "weapon_slots_4_1");
|
||||||
|
DisableItem(condition, weap_settings2, "weapon_slots_4_2");
|
||||||
|
DisableItem(condition, weap_settings2, "weapon_slots_4_3");
|
||||||
|
}
|
||||||
|
|
||||||
|
static setup_menu_t weap_settings3[] = {
|
||||||
{"1St Choice Weapon", S_WEAP | S_BOOM, M_X, M_SPC, {"weapon_choice_1"}},
|
{"1St Choice Weapon", S_WEAP | S_BOOM, M_X, M_SPC, {"weapon_choice_1"}},
|
||||||
{"2Nd Choice Weapon", S_WEAP | S_BOOM, M_X, M_SPC, {"weapon_choice_2"}},
|
{"2Nd Choice Weapon", S_WEAP | S_BOOM, M_X, M_SPC, {"weapon_choice_2"}},
|
||||||
{"3Rd Choice Weapon", S_WEAP | S_BOOM, M_X, M_SPC, {"weapon_choice_3"}},
|
{"3Rd Choice Weapon", S_WEAP | S_BOOM, M_X, M_SPC, {"weapon_choice_3"}},
|
||||||
@ -1561,7 +1722,9 @@ static setup_menu_t weap_settings2[] = {
|
|||||||
MI_END
|
MI_END
|
||||||
};
|
};
|
||||||
|
|
||||||
static setup_menu_t *weap_settings[] = {weap_settings1, weap_settings2, NULL};
|
static setup_menu_t *weap_settings[] = {
|
||||||
|
weap_settings1, weap_settings2, weap_settings3, NULL
|
||||||
|
};
|
||||||
|
|
||||||
static void UpdateCenteredWeaponItem(void)
|
static void UpdateCenteredWeaponItem(void)
|
||||||
{
|
{
|
||||||
@ -2013,12 +2176,19 @@ static const char *default_complevel_strings[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void UpdateInterceptsEmuItem(void);
|
static void UpdateInterceptsEmuItem(void);
|
||||||
|
static void UpdateWeaponSlotStrings(void);
|
||||||
|
|
||||||
|
static void UpdateDefaultCompatibilityLevel(void)
|
||||||
|
{
|
||||||
|
UpdateInterceptsEmuItem();
|
||||||
|
UpdateWeaponSlotStrings();
|
||||||
|
}
|
||||||
|
|
||||||
setup_menu_t comp_settings1[] = {
|
setup_menu_t comp_settings1[] = {
|
||||||
|
|
||||||
{"Default Compatibility Level", S_CHOICE | S_LEVWARN, M_X, M_SPC,
|
{"Default Compatibility Level", S_CHOICE | S_LEVWARN, M_X, M_SPC,
|
||||||
{"default_complevel"}, .strings_id = str_default_complevel,
|
{"default_complevel"}, .strings_id = str_default_complevel,
|
||||||
.action = UpdateInterceptsEmuItem},
|
.action = UpdateDefaultCompatibilityLevel},
|
||||||
|
|
||||||
{"Strict Mode", S_ONOFF | S_LEVWARN, M_X, M_SPC, {"strictmode"}},
|
{"Strict Mode", S_ONOFF | S_LEVWARN, M_X, M_SPC, {"strictmode"}},
|
||||||
|
|
||||||
@ -2383,18 +2553,17 @@ static const char *equalizer_preset_strings[] = {
|
|||||||
|
|
||||||
#define M_THRM_SPC_EQ (M_THRM_HEIGHT - 1)
|
#define M_THRM_SPC_EQ (M_THRM_HEIGHT - 1)
|
||||||
#define M_SPC_EQ 8
|
#define M_SPC_EQ 8
|
||||||
#define MI_GAP_EQ {NULL, S_SKIP, 0, 4}
|
|
||||||
|
|
||||||
static setup_menu_t eq_settings1[] = {
|
static setup_menu_t eq_settings1[] = {
|
||||||
{"Preset", S_CHOICE, CNTR_X, M_SPC_EQ, {"snd_equalizer"},
|
{"Preset", S_CHOICE, CNTR_X, M_SPC_EQ, {"snd_equalizer"},
|
||||||
.strings_id = str_equalizer_preset, .action = I_OAL_EqualizerPreset},
|
.strings_id = str_equalizer_preset, .action = I_OAL_EqualizerPreset},
|
||||||
|
|
||||||
MI_GAP_EQ,
|
MI_GAP_HALF,
|
||||||
|
|
||||||
{"Preamp dB", S_THERMO, CNTR_X, M_THRM_SPC_EQ,
|
{"Preamp dB", S_THERMO, CNTR_X, M_THRM_SPC_EQ,
|
||||||
{"snd_eq_preamp"}, .action = I_OAL_EqualizerPreset},
|
{"snd_eq_preamp"}, .action = I_OAL_EqualizerPreset},
|
||||||
|
|
||||||
MI_GAP_EQ,
|
MI_GAP_HALF,
|
||||||
|
|
||||||
{"Low Gain dB", S_THERMO, CNTR_X, M_THRM_SPC_EQ,
|
{"Low Gain dB", S_THERMO, CNTR_X, M_THRM_SPC_EQ,
|
||||||
{"snd_eq_low_gain"}, .action = I_OAL_EqualizerPreset},
|
{"snd_eq_low_gain"}, .action = I_OAL_EqualizerPreset},
|
||||||
@ -2408,7 +2577,7 @@ static setup_menu_t eq_settings1[] = {
|
|||||||
{"High Gain dB", S_THERMO, CNTR_X, M_THRM_SPC_EQ,
|
{"High Gain dB", S_THERMO, CNTR_X, M_THRM_SPC_EQ,
|
||||||
{"snd_eq_high_gain"}, .action = I_OAL_EqualizerPreset},
|
{"snd_eq_high_gain"}, .action = I_OAL_EqualizerPreset},
|
||||||
|
|
||||||
MI_GAP_EQ,
|
MI_GAP_HALF,
|
||||||
|
|
||||||
{"Low Cutoff Hz", S_THERMO, CNTR_X, M_THRM_SPC_EQ,
|
{"Low Cutoff Hz", S_THERMO, CNTR_X, M_THRM_SPC_EQ,
|
||||||
{"snd_eq_low_cutoff"}, .action = I_OAL_EqualizerPreset},
|
{"snd_eq_low_cutoff"}, .action = I_OAL_EqualizerPreset},
|
||||||
@ -2863,6 +3032,7 @@ static void UpdateGyroItems(void)
|
|||||||
|
|
||||||
void MN_UpdateAllGamepadItems(void)
|
void MN_UpdateAllGamepadItems(void)
|
||||||
{
|
{
|
||||||
|
UpdateWeaponSlotSelection();
|
||||||
UpdateGamepadItems();
|
UpdateGamepadItems();
|
||||||
UpdateGyroItems();
|
UpdateGyroItems();
|
||||||
}
|
}
|
||||||
@ -4488,6 +4658,9 @@ static const char **selectstrings[] = {
|
|||||||
overlay_strings,
|
overlay_strings,
|
||||||
automap_preset_strings,
|
automap_preset_strings,
|
||||||
automap_keyed_door_strings,
|
automap_keyed_door_strings,
|
||||||
|
weapon_slots_activation_strings,
|
||||||
|
weapon_slots_selection_strings,
|
||||||
|
NULL, // str_weapon_slots
|
||||||
NULL, // str_resolution_scale
|
NULL, // str_resolution_scale
|
||||||
NULL, // str_midi_player
|
NULL, // str_midi_player
|
||||||
gamma_strings,
|
gamma_strings,
|
||||||
@ -4524,6 +4697,11 @@ static void UpdateHUDModeStrings(void)
|
|||||||
selectstrings[str_hudmode] = GetHUDModeStrings();
|
selectstrings[str_hudmode] = GetHUDModeStrings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void UpdateWeaponSlotStrings(void)
|
||||||
|
{
|
||||||
|
selectstrings[str_weapon_slots] = GetWeaponSlotStrings();
|
||||||
|
}
|
||||||
|
|
||||||
static const char **GetMidiPlayerStrings(void)
|
static const char **GetMidiPlayerStrings(void)
|
||||||
{
|
{
|
||||||
return I_DeviceList();
|
return I_DeviceList();
|
||||||
@ -4532,6 +4710,8 @@ static const char **GetMidiPlayerStrings(void)
|
|||||||
void MN_InitMenuStrings(void)
|
void MN_InitMenuStrings(void)
|
||||||
{
|
{
|
||||||
UpdateHUDModeStrings();
|
UpdateHUDModeStrings();
|
||||||
|
UpdateWeaponSlotLabels();
|
||||||
|
UpdateWeaponSlotStrings();
|
||||||
selectstrings[str_resolution_scale] = GetResolutionScaleStrings();
|
selectstrings[str_resolution_scale] = GetResolutionScaleStrings();
|
||||||
selectstrings[str_midi_player] = GetMidiPlayerStrings();
|
selectstrings[str_midi_player] = GetMidiPlayerStrings();
|
||||||
selectstrings[str_mouse_accel] = GetMouseAccelStrings();
|
selectstrings[str_mouse_accel] = GetMouseAccelStrings();
|
||||||
@ -4554,7 +4734,9 @@ void MN_SetupResetMenu(void)
|
|||||||
UpdateInterceptsEmuItem();
|
UpdateInterceptsEmuItem();
|
||||||
UpdateCrosshairItems();
|
UpdateCrosshairItems();
|
||||||
UpdateCenteredWeaponItem();
|
UpdateCenteredWeaponItem();
|
||||||
MN_UpdateAllGamepadItems();
|
UpdateGamepadItems();
|
||||||
|
UpdateGyroItems();
|
||||||
|
UpdateWeaponSlotItems();
|
||||||
MN_UpdateEqualizerItems();
|
MN_UpdateEqualizerItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
774
src/ws_stuff.c
Normal file
774
src/ws_stuff.c
Normal file
@ -0,0 +1,774 @@
|
|||||||
|
//
|
||||||
|
// Copyright(C) 2024 ceski
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// DESCRIPTION:
|
||||||
|
// Weapon slots.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "SDL.h"
|
||||||
|
|
||||||
|
#include "g_game.h"
|
||||||
|
#include "i_input.h"
|
||||||
|
#include "i_timer.h"
|
||||||
|
#include "m_config.h"
|
||||||
|
#include "m_input.h"
|
||||||
|
#include "r_main.h"
|
||||||
|
#include "ws_stuff.h"
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
WS_OFF,
|
||||||
|
WS_HOLD_LAST,
|
||||||
|
WS_ALWAYS_ON,
|
||||||
|
NUM_WS_ACTIVATION
|
||||||
|
} weapon_slots_activation_t;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
WS_TYPE_NONE,
|
||||||
|
WS_TYPE_FIST,
|
||||||
|
WS_TYPE_PISTOL,
|
||||||
|
WS_TYPE_SHOTGUN,
|
||||||
|
WS_TYPE_CHAINGUN,
|
||||||
|
WS_TYPE_ROCKET,
|
||||||
|
WS_TYPE_PLASMA,
|
||||||
|
WS_TYPE_BFG,
|
||||||
|
WS_TYPE_CHAINSAW,
|
||||||
|
WS_TYPE_SSG,
|
||||||
|
NUM_WS_TYPES
|
||||||
|
} weapon_slots_type_t;
|
||||||
|
|
||||||
|
static weapon_slots_activation_t weapon_slots_activation;
|
||||||
|
static weapon_slots_selection_t weapon_slots_selection;
|
||||||
|
static weapon_slots_type_t weapon_slots_1_1;
|
||||||
|
static weapon_slots_type_t weapon_slots_1_2;
|
||||||
|
static weapon_slots_type_t weapon_slots_1_3;
|
||||||
|
static weapon_slots_type_t weapon_slots_2_1;
|
||||||
|
static weapon_slots_type_t weapon_slots_2_2;
|
||||||
|
static weapon_slots_type_t weapon_slots_2_3;
|
||||||
|
static weapon_slots_type_t weapon_slots_3_1;
|
||||||
|
static weapon_slots_type_t weapon_slots_3_2;
|
||||||
|
static weapon_slots_type_t weapon_slots_3_3;
|
||||||
|
static weapon_slots_type_t weapon_slots_4_1;
|
||||||
|
static weapon_slots_type_t weapon_slots_4_2;
|
||||||
|
static weapon_slots_type_t weapon_slots_4_3;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int time; // Time when activator was pressed (tics).
|
||||||
|
int input_key; // Key that triggered this event (doomkeys.h).
|
||||||
|
boolean *state; // Pointer to input key's on/off state.
|
||||||
|
boolean restored; // Was this event restored?
|
||||||
|
} shared_event_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
weapontype_t weapons[NUM_WS_WEAPS]; // Weapons for this slot.
|
||||||
|
int num_weapons; // Number of weapons in this slot.
|
||||||
|
int input_key; // Key that selects slot (doomkeys.h).
|
||||||
|
} weapon_slot_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
boolean enabled; // State initially updated in WS_UpdateState.
|
||||||
|
boolean key_match; // Event input key matches any slot's input key?
|
||||||
|
int index; // Index of the slot that matches the event.
|
||||||
|
boolean override; // Give gamepad higher priority.
|
||||||
|
boolean hold_override; // Give gamepad higher priority with hold "last".
|
||||||
|
|
||||||
|
boolean activated; // Activated weapon slots?
|
||||||
|
boolean pressed; // Pressed a weapon slot while activated?
|
||||||
|
boolean selected; // Selected a weapon slot while activated?
|
||||||
|
int input_key; // Input key for selected slot, tracked separately.
|
||||||
|
const weapon_slot_t *current_slot; // Slot selected while activated.
|
||||||
|
} weapon_slots_state_t;
|
||||||
|
|
||||||
|
static shared_event_t shared_event; // Event shared with activator.
|
||||||
|
static weapon_slot_t slots[NUM_WS_SLOTS]; // Parameters for each slot.
|
||||||
|
static weapon_slots_state_t state; // Weapon slots state.
|
||||||
|
|
||||||
|
static void ResetState(void)
|
||||||
|
{
|
||||||
|
state.enabled = false;
|
||||||
|
state.key_match = false;
|
||||||
|
state.index = -1;
|
||||||
|
state.override = false;
|
||||||
|
state.hold_override = false;
|
||||||
|
|
||||||
|
state.activated = false;
|
||||||
|
state.pressed = false;
|
||||||
|
state.selected = false;
|
||||||
|
state.input_key = -1;
|
||||||
|
state.current_slot = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ResetSharedEvent(void)
|
||||||
|
{
|
||||||
|
if (shared_event.state != NULL)
|
||||||
|
{
|
||||||
|
*shared_event.state = false;
|
||||||
|
shared_event.state = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_event.time = 0;
|
||||||
|
shared_event.input_key = -1;
|
||||||
|
shared_event.restored = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WS_Reset
|
||||||
|
//
|
||||||
|
void WS_Reset(void)
|
||||||
|
{
|
||||||
|
ResetSharedEvent();
|
||||||
|
ResetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WS_Enabled
|
||||||
|
//
|
||||||
|
boolean WS_Enabled(void)
|
||||||
|
{
|
||||||
|
return (weapon_slots_activation != WS_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WS_Selection
|
||||||
|
//
|
||||||
|
weapon_slots_selection_t WS_Selection(void)
|
||||||
|
{
|
||||||
|
return weapon_slots_selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WS_UpdateSelection
|
||||||
|
//
|
||||||
|
void WS_UpdateSelection(void)
|
||||||
|
{
|
||||||
|
int buttons[NUM_WS_SLOTS];
|
||||||
|
const int translate[] = SCANCODE_TO_KEYS_ARRAY;
|
||||||
|
|
||||||
|
switch (weapon_slots_selection)
|
||||||
|
{
|
||||||
|
case WS_SELECT_DPAD:
|
||||||
|
slots[0].input_key = GAMEPAD_DPAD_UP;
|
||||||
|
slots[1].input_key = GAMEPAD_DPAD_DOWN;
|
||||||
|
slots[2].input_key = GAMEPAD_DPAD_LEFT;
|
||||||
|
slots[3].input_key = GAMEPAD_DPAD_RIGHT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WS_SELECT_FACE_BUTTONS:
|
||||||
|
I_GetFaceButtons(buttons);
|
||||||
|
slots[0].input_key = buttons[0];
|
||||||
|
slots[1].input_key = buttons[1];
|
||||||
|
slots[2].input_key = buttons[2];
|
||||||
|
slots[3].input_key = buttons[3];
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: // WS_SELECT_1234
|
||||||
|
slots[0].input_key = translate[SDL_SCANCODE_1];
|
||||||
|
slots[1].input_key = translate[SDL_SCANCODE_2];
|
||||||
|
slots[2].input_key = translate[SDL_SCANCODE_3];
|
||||||
|
slots[3].input_key = translate[SDL_SCANCODE_4];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WS_UpdateSlots
|
||||||
|
//
|
||||||
|
void WS_UpdateSlots(void)
|
||||||
|
{
|
||||||
|
const weapon_slots_type_t types[NUM_WS_SLOTS][NUM_WS_WEAPS] = {
|
||||||
|
{weapon_slots_1_1, weapon_slots_1_2, weapon_slots_1_3},
|
||||||
|
{weapon_slots_2_1, weapon_slots_2_2, weapon_slots_2_3},
|
||||||
|
{weapon_slots_3_1, weapon_slots_3_2, weapon_slots_3_3},
|
||||||
|
{weapon_slots_4_1, weapon_slots_4_2, weapon_slots_4_3},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_WS_SLOTS; i++)
|
||||||
|
{
|
||||||
|
int count[NUMWEAPONS] = {0};
|
||||||
|
slots[i].num_weapons = 0;
|
||||||
|
|
||||||
|
for (int j = 0; j < NUM_WS_WEAPS; j++)
|
||||||
|
{
|
||||||
|
if (types[i][j] == WS_TYPE_NONE)
|
||||||
|
{
|
||||||
|
continue; // Skip "none" weapon type.
|
||||||
|
}
|
||||||
|
|
||||||
|
const weapontype_t weapon = types[i][j] - WS_TYPE_FIST;
|
||||||
|
|
||||||
|
if (++count[weapon] > 1)
|
||||||
|
{
|
||||||
|
continue; // Skip duplicate weapons.
|
||||||
|
}
|
||||||
|
|
||||||
|
slots[i].weapons[slots[i].num_weapons++] = weapon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WS_Init
|
||||||
|
//
|
||||||
|
void WS_Init(void)
|
||||||
|
{
|
||||||
|
WS_UpdateSelection();
|
||||||
|
WS_UpdateSlots();
|
||||||
|
WS_Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Weapon slots responder functions.
|
||||||
|
//
|
||||||
|
|
||||||
|
static boolean SearchSlotMatch(const event_t *ev, int *index)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NUM_WS_SLOTS; i++)
|
||||||
|
{
|
||||||
|
if (ev->data1.i == slots[i].input_key)
|
||||||
|
{
|
||||||
|
*index = i;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*index = -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean InputKeyMatch(const event_t *ev, int *index)
|
||||||
|
{
|
||||||
|
switch (ev->type)
|
||||||
|
{
|
||||||
|
case ev_joyb_down:
|
||||||
|
case ev_joyb_up:
|
||||||
|
if (weapon_slots_selection != WS_SELECT_1234)
|
||||||
|
{
|
||||||
|
return SearchSlotMatch(ev, index);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ev_keydown:
|
||||||
|
case ev_keyup:
|
||||||
|
if (weapon_slots_selection == WS_SELECT_1234)
|
||||||
|
{
|
||||||
|
return SearchSlotMatch(ev, index);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*index = -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WS_UpdateState
|
||||||
|
//
|
||||||
|
void WS_UpdateState(const event_t *ev)
|
||||||
|
{
|
||||||
|
if (WS_Enabled()
|
||||||
|
// If using gamepad weapon slots, then also using a gamepad.
|
||||||
|
&& (weapon_slots_selection == WS_SELECT_1234 || I_UseGamepad())
|
||||||
|
// Playing the game.
|
||||||
|
&& (!menuactive && !demoplayback && gamestate == GS_LEVEL && !paused))
|
||||||
|
{
|
||||||
|
state.enabled = true;
|
||||||
|
state.key_match = (InputKeyMatch(ev, &state.index)
|
||||||
|
&& slots[state.index].num_weapons > 0);
|
||||||
|
|
||||||
|
const boolean override = (
|
||||||
|
// Only a gamepad can override other responders.
|
||||||
|
(I_UseGamepad() && weapon_slots_selection != WS_SELECT_1234)
|
||||||
|
// The current input key matches a weapon slot key.
|
||||||
|
&& state.key_match);
|
||||||
|
|
||||||
|
state.override =
|
||||||
|
(override
|
||||||
|
// Weapon slots selected directly or hold "last" is activated.
|
||||||
|
&& (weapon_slots_activation == WS_ALWAYS_ON || state.activated));
|
||||||
|
|
||||||
|
state.hold_override =
|
||||||
|
(override
|
||||||
|
// Weapon slots are activated using hold "last" only.
|
||||||
|
&& (weapon_slots_activation == WS_HOLD_LAST && state.activated));
|
||||||
|
}
|
||||||
|
else if (state.enabled)
|
||||||
|
{
|
||||||
|
WS_Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WS_Override
|
||||||
|
//
|
||||||
|
boolean WS_Override(void)
|
||||||
|
{
|
||||||
|
return state.override;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WS_HoldOverride
|
||||||
|
//
|
||||||
|
boolean WS_HoldOverride(void)
|
||||||
|
{
|
||||||
|
return state.hold_override;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WS_ClearSharedEvent
|
||||||
|
//
|
||||||
|
void WS_ClearSharedEvent(void)
|
||||||
|
{
|
||||||
|
if (shared_event.restored)
|
||||||
|
{
|
||||||
|
ResetSharedEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RestoreSharedEvent(void)
|
||||||
|
{
|
||||||
|
// Restore the shared event if the activator was pressed and then quickly
|
||||||
|
// released without pressing a weapon slot.
|
||||||
|
#define MAX_RESTORE_TICS 21 // 600 ms
|
||||||
|
|
||||||
|
if ((state.activated && !state.pressed)
|
||||||
|
&& (!shared_event.restored && shared_event.state != NULL)
|
||||||
|
&& (I_GetTime() - shared_event.time <= MAX_RESTORE_TICS))
|
||||||
|
{
|
||||||
|
shared_event.time = 0;
|
||||||
|
shared_event.input_key = -1;
|
||||||
|
*shared_event.state = true;
|
||||||
|
shared_event.restored = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ResetSharedEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetSharedEvent(const event_t *ev, boolean *buttons, int32_t size)
|
||||||
|
{
|
||||||
|
if (ev->data1.i >= 0 && ev->data1.i < size)
|
||||||
|
{
|
||||||
|
shared_event.time = I_GetTime();
|
||||||
|
shared_event.input_key = ev->data1.i;
|
||||||
|
shared_event.state = &buttons[ev->data1.i];
|
||||||
|
shared_event.restored = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ResetSharedEvent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BackupSharedEvent(const event_t *ev)
|
||||||
|
{
|
||||||
|
switch (ev->type)
|
||||||
|
{
|
||||||
|
case ev_joyb_down:
|
||||||
|
SetSharedEvent(ev, joybuttons, NUM_GAMEPAD_BUTTONS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ev_keydown:
|
||||||
|
SetSharedEvent(ev, gamekeydown, NUMKEYS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ev_mouseb_down:
|
||||||
|
SetSharedEvent(ev, mousebuttons, NUM_MOUSE_BUTTONS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ResetSharedEvent();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean UpdateSelection(const event_t *ev)
|
||||||
|
{
|
||||||
|
if (!state.key_match)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ev->type)
|
||||||
|
{
|
||||||
|
case ev_joyb_down:
|
||||||
|
case ev_keydown:
|
||||||
|
if (!state.selected)
|
||||||
|
{
|
||||||
|
state.pressed = true;
|
||||||
|
state.selected = true;
|
||||||
|
state.input_key = ev->data1.i;
|
||||||
|
state.current_slot = &slots[state.index];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ev_joyb_up:
|
||||||
|
case ev_keyup:
|
||||||
|
if (state.selected && ev->data1.i == state.input_key)
|
||||||
|
{
|
||||||
|
state.selected = false;
|
||||||
|
state.input_key = -1;
|
||||||
|
state.current_slot = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WS_Responder
|
||||||
|
//
|
||||||
|
boolean WS_Responder(const event_t *ev)
|
||||||
|
{
|
||||||
|
if (!state.enabled)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (weapon_slots_activation)
|
||||||
|
{
|
||||||
|
case WS_ALWAYS_ON:
|
||||||
|
return UpdateSelection(ev);
|
||||||
|
|
||||||
|
case WS_HOLD_LAST:
|
||||||
|
if (M_InputActivated(input_lastweapon))
|
||||||
|
{
|
||||||
|
if (!state.activated)
|
||||||
|
{
|
||||||
|
BackupSharedEvent(ev);
|
||||||
|
ResetState();
|
||||||
|
state.activated = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (M_InputDeactivated(input_lastweapon))
|
||||||
|
{
|
||||||
|
if (state.activated && ev->data1.i == shared_event.input_key)
|
||||||
|
{
|
||||||
|
RestoreSharedEvent();
|
||||||
|
ResetState();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (state.activated)
|
||||||
|
{
|
||||||
|
return UpdateSelection(ev);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Weapon slots switching functions.
|
||||||
|
//
|
||||||
|
|
||||||
|
static weapontype_t FinalWeapon(const player_t *player,
|
||||||
|
weapontype_t current_weapon,
|
||||||
|
weapontype_t final_slot_weapon)
|
||||||
|
{
|
||||||
|
switch (final_slot_weapon)
|
||||||
|
{
|
||||||
|
case wp_fist:
|
||||||
|
case wp_chainsaw:
|
||||||
|
if (player->weaponowned[wp_chainsaw]
|
||||||
|
&& current_weapon != wp_chainsaw && current_weapon == wp_fist)
|
||||||
|
{
|
||||||
|
return wp_chainsaw;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wp_shotgun:
|
||||||
|
case wp_supershotgun:
|
||||||
|
if (ALLOW_SSG && player->weaponowned[wp_supershotgun]
|
||||||
|
&& player->weaponowned[wp_shotgun]
|
||||||
|
&& current_weapon == wp_shotgun)
|
||||||
|
{
|
||||||
|
return wp_shotgun; // wp_supershotgun
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wp_nochange;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean Selectable(const player_t *player, weapontype_t slot_weapon)
|
||||||
|
{
|
||||||
|
if ((slot_weapon == wp_plasma || slot_weapon == wp_bfg)
|
||||||
|
&& gamemission == doom && gamemode == shareware)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!player->weaponowned[slot_weapon])
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean NextWeapon(const player_t *player, weapontype_t current_weapon,
|
||||||
|
weapontype_t slot_weapon, weapontype_t *next_weapon)
|
||||||
|
{
|
||||||
|
switch (slot_weapon)
|
||||||
|
{
|
||||||
|
case wp_fist:
|
||||||
|
case wp_chainsaw:
|
||||||
|
if (player->weaponowned[wp_chainsaw]
|
||||||
|
&& current_weapon != wp_chainsaw && current_weapon != wp_fist)
|
||||||
|
{
|
||||||
|
*next_weapon = wp_chainsaw;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (current_weapon != wp_fist
|
||||||
|
&& (!player->weaponowned[wp_chainsaw]
|
||||||
|
|| (current_weapon == wp_chainsaw
|
||||||
|
&& player->powers[pw_strength])))
|
||||||
|
{
|
||||||
|
*next_weapon = wp_fist;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wp_shotgun:
|
||||||
|
case wp_supershotgun:
|
||||||
|
if (ALLOW_SSG && player->weaponowned[wp_supershotgun]
|
||||||
|
&& current_weapon != wp_supershotgun
|
||||||
|
&& current_weapon != wp_shotgun)
|
||||||
|
{
|
||||||
|
*next_weapon = wp_shotgun; // wp_supershotgun
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (player->weaponowned[wp_shotgun]
|
||||||
|
&& current_weapon != wp_shotgun
|
||||||
|
&& (current_weapon == wp_supershotgun || !ALLOW_SSG
|
||||||
|
|| !player->weaponowned[wp_supershotgun]))
|
||||||
|
{
|
||||||
|
*next_weapon = wp_shotgun;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (Selectable(player, slot_weapon))
|
||||||
|
{
|
||||||
|
*next_weapon = slot_weapon;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CurrentPosition(weapontype_t current_weapon,
|
||||||
|
const weapontype_t *slot_weapons, int num_weapons)
|
||||||
|
{
|
||||||
|
for (int pos = 0; pos < num_weapons; pos++)
|
||||||
|
{
|
||||||
|
const int next_pos = (pos + 1) % num_weapons;
|
||||||
|
const weapontype_t next_weapon = slot_weapons[next_pos];
|
||||||
|
|
||||||
|
switch (slot_weapons[pos])
|
||||||
|
{
|
||||||
|
case wp_fist:
|
||||||
|
case wp_chainsaw:
|
||||||
|
if (next_weapon == wp_fist || next_weapon == wp_chainsaw)
|
||||||
|
{
|
||||||
|
continue; // Skip duplicates.
|
||||||
|
}
|
||||||
|
else if (current_weapon == wp_fist
|
||||||
|
|| current_weapon == wp_chainsaw)
|
||||||
|
{
|
||||||
|
return pos; // Start in current position.
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case wp_shotgun:
|
||||||
|
case wp_supershotgun:
|
||||||
|
if (next_weapon == wp_shotgun || next_weapon == wp_supershotgun)
|
||||||
|
{
|
||||||
|
continue; // Skip duplicates.
|
||||||
|
}
|
||||||
|
else if (current_weapon == wp_shotgun
|
||||||
|
|| current_weapon == wp_supershotgun)
|
||||||
|
{
|
||||||
|
return pos; // Start in current position.
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (current_weapon == slot_weapons[pos])
|
||||||
|
{
|
||||||
|
return next_pos; // Start in next position.
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; // Start in first position.
|
||||||
|
}
|
||||||
|
|
||||||
|
static weapontype_t SlotWeaponVanilla(const player_t *player,
|
||||||
|
weapontype_t current_weapon,
|
||||||
|
const weapontype_t *slot_weapons,
|
||||||
|
int num_weapons)
|
||||||
|
{
|
||||||
|
int pos = CurrentPosition(current_weapon, slot_weapons, num_weapons) - 1;
|
||||||
|
weapontype_t next_weapon;
|
||||||
|
|
||||||
|
for (int i = 0; i < num_weapons; i++)
|
||||||
|
{
|
||||||
|
pos = (pos + 1) % num_weapons;
|
||||||
|
|
||||||
|
if (NextWeapon(player, current_weapon, slot_weapons[pos], &next_weapon))
|
||||||
|
{
|
||||||
|
return next_weapon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FinalWeapon(player, current_weapon, slot_weapons[num_weapons - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static weapontype_t SlotWeapon(const player_t *player,
|
||||||
|
weapontype_t current_weapon,
|
||||||
|
const weapontype_t *slot_weapons,
|
||||||
|
int num_weapons)
|
||||||
|
{
|
||||||
|
int pos = -1;
|
||||||
|
|
||||||
|
for (int i = 0; i < num_weapons; i++)
|
||||||
|
{
|
||||||
|
if (current_weapon == slot_weapons[i])
|
||||||
|
{
|
||||||
|
pos = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < num_weapons; i++)
|
||||||
|
{
|
||||||
|
pos = (pos + 1) % num_weapons;
|
||||||
|
|
||||||
|
if (slot_weapons[pos] == wp_supershotgun && !ALLOW_SSG)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Selectable(player, slot_weapons[pos]))
|
||||||
|
{
|
||||||
|
return slot_weapons[pos];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return wp_nochange;
|
||||||
|
}
|
||||||
|
|
||||||
|
static weapontype_t CurrentWeapon(const player_t *player)
|
||||||
|
{
|
||||||
|
if (player->pendingweapon == wp_nochange)
|
||||||
|
{
|
||||||
|
return player->readyweapon;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return player->pendingweapon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WS_SlotSelected
|
||||||
|
//
|
||||||
|
boolean WS_SlotSelected(void)
|
||||||
|
{
|
||||||
|
return (state.current_slot != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WS_SlotWeapon
|
||||||
|
//
|
||||||
|
weapontype_t WS_SlotWeapon(void)
|
||||||
|
{
|
||||||
|
const player_t *player = &players[consoleplayer];
|
||||||
|
const weapontype_t current_weapon = CurrentWeapon(player);
|
||||||
|
const weapontype_t *slot_weapons = state.current_slot->weapons;
|
||||||
|
const int num_weapons = state.current_slot->num_weapons;
|
||||||
|
state.current_slot = NULL;
|
||||||
|
|
||||||
|
if (!demo_compatibility)
|
||||||
|
{
|
||||||
|
return SlotWeapon(player, current_weapon, slot_weapons, num_weapons);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return SlotWeaponVanilla(player, current_weapon, slot_weapons,
|
||||||
|
num_weapons);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// WS_BindVariables
|
||||||
|
//
|
||||||
|
|
||||||
|
#define BIND_NUM_WEAP(name, v, a, b, help) \
|
||||||
|
M_BindNum(#name, &name, NULL, (v), (a), (b), ss_weap, wad_no, help)
|
||||||
|
|
||||||
|
#define BIND_SLOT(name, v, help) \
|
||||||
|
BIND_NUM_WEAP(name, (v), WS_TYPE_NONE, NUM_WS_TYPES - 1, help)
|
||||||
|
|
||||||
|
void WS_BindVariables(void)
|
||||||
|
{
|
||||||
|
BIND_NUM_WEAP(weapon_slots_activation,
|
||||||
|
WS_OFF, WS_OFF, NUM_WS_ACTIVATION - 1,
|
||||||
|
"Weapon slots activation (0 = Off; 1 = Hold \"Last\"; 2 = Always On)");
|
||||||
|
|
||||||
|
BIND_NUM_WEAP(weapon_slots_selection,
|
||||||
|
WS_SELECT_DPAD, WS_SELECT_DPAD, NUM_WS_SELECT - 1,
|
||||||
|
"Weapon slots selection (0 = D-Pad; 1 = Face Buttons; 2 = 1-4 Keys)");
|
||||||
|
|
||||||
|
BIND_SLOT(weapon_slots_1_1, WS_TYPE_SSG, "Slot 1, weapon 1");
|
||||||
|
BIND_SLOT(weapon_slots_1_2, WS_TYPE_SHOTGUN, "Slot 1, weapon 2");
|
||||||
|
BIND_SLOT(weapon_slots_1_3, WS_TYPE_NONE, "Slot 1, weapon 3");
|
||||||
|
|
||||||
|
BIND_SLOT(weapon_slots_2_1, WS_TYPE_ROCKET, "Slot 2, weapon 1");
|
||||||
|
BIND_SLOT(weapon_slots_2_2, WS_TYPE_CHAINSAW, "Slot 2, weapon 2");
|
||||||
|
BIND_SLOT(weapon_slots_2_3, WS_TYPE_FIST, "Slot 2, weapon 3");
|
||||||
|
|
||||||
|
BIND_SLOT(weapon_slots_3_1, WS_TYPE_PLASMA, "Slot 3, weapon 1");
|
||||||
|
BIND_SLOT(weapon_slots_3_2, WS_TYPE_BFG, "Slot 3, weapon 2");
|
||||||
|
BIND_SLOT(weapon_slots_3_3, WS_TYPE_NONE, "Slot 3, weapon 3");
|
||||||
|
|
||||||
|
BIND_SLOT(weapon_slots_4_1, WS_TYPE_CHAINGUN, "Slot 4, weapon 1");
|
||||||
|
BIND_SLOT(weapon_slots_4_2, WS_TYPE_PISTOL, "Slot 4, weapon 2");
|
||||||
|
BIND_SLOT(weapon_slots_4_3, WS_TYPE_NONE, "Slot 4, weapon 3");
|
||||||
|
}
|
56
src/ws_stuff.h
Normal file
56
src/ws_stuff.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
//
|
||||||
|
// Copyright(C) 2024 ceski
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// DESCRIPTION:
|
||||||
|
// Weapon slots.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __WS_STUFF__
|
||||||
|
#define __WS_STUFF__
|
||||||
|
|
||||||
|
#include "doomdef.h"
|
||||||
|
#include "doomtype.h"
|
||||||
|
|
||||||
|
struct event_s;
|
||||||
|
|
||||||
|
#define NUM_WS_SLOTS 4
|
||||||
|
#define NUM_WS_WEAPS 3
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
WS_SELECT_DPAD,
|
||||||
|
WS_SELECT_FACE_BUTTONS,
|
||||||
|
WS_SELECT_1234,
|
||||||
|
NUM_WS_SELECT
|
||||||
|
} weapon_slots_selection_t;
|
||||||
|
|
||||||
|
void WS_Reset(void);
|
||||||
|
boolean WS_Enabled(void);
|
||||||
|
weapon_slots_selection_t WS_Selection(void);
|
||||||
|
void WS_UpdateSelection(void);
|
||||||
|
void WS_UpdateSlots(void);
|
||||||
|
void WS_Init(void);
|
||||||
|
|
||||||
|
void WS_UpdateState(const struct event_s *ev);
|
||||||
|
boolean WS_Override(void);
|
||||||
|
boolean WS_HoldOverride(void);
|
||||||
|
|
||||||
|
void WS_ClearSharedEvent(void);
|
||||||
|
boolean WS_Responder(const struct event_s *ev);
|
||||||
|
|
||||||
|
boolean WS_SlotSelected(void);
|
||||||
|
weapontype_t WS_SlotWeapon(void);
|
||||||
|
|
||||||
|
void WS_BindVariables(void);
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user