mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'descriptive-controls' into 'master'
Descriptive controls See merge request KartKrew/Kart!2460
This commit is contained in:
commit
c357f544d5
37 changed files with 1624 additions and 348 deletions
|
|
@ -102,6 +102,18 @@ CV_PossibleValue_t gpdifficulty_cons_t[] = {
|
|||
{KARTGP_MASTER, "Master"},
|
||||
{0, NULL}
|
||||
};
|
||||
CV_PossibleValue_t descriptiveinput_cons_t[] = {
|
||||
{0, "\"Emulator\""},
|
||||
{1, "Modern"},
|
||||
{2, "Modern Flip"},
|
||||
{3, "6Bt. (Auto)"},
|
||||
{4, "6Bt. (A)"},
|
||||
{5, "6Bt. (B)"},
|
||||
{6, "6Bt. (C)"},
|
||||
{7, "6Bt. (D)"},
|
||||
{8, "6Bt. (E)"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
// Filter consvars by EXECVERSION
|
||||
// First implementation is 2 (1.0.2), so earlier configs default at 1 (1.0.0)
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ extern CV_PossibleValue_t CV_TrueFalse[];
|
|||
|
||||
// SRB2kart
|
||||
// the KARTSPEED and KARTGP were previously defined here, but moved to doomstat to avoid circular dependencies
|
||||
extern CV_PossibleValue_t kartspeed_cons_t[], dummykartspeed_cons_t[], gpdifficulty_cons_t[];
|
||||
extern CV_PossibleValue_t kartspeed_cons_t[], dummykartspeed_cons_t[], gpdifficulty_cons_t[], descriptiveinput_cons_t[];
|
||||
|
||||
extern consvar_t cv_cheats;
|
||||
extern consvar_t cv_execversion;
|
||||
|
|
|
|||
|
|
@ -914,6 +914,7 @@ consvar_t cv_debugvirtualkeyboard = PlayerCheat("debugvirtualkeyboard", "Off").o
|
|||
consvar_t cv_devmode_screen = PlayerCheat("devmode_screen", "1").min_max(1, 4).description("Choose which splitscreen player devmode applies to");
|
||||
consvar_t cv_drawpickups = PlayerCheat("drawpickups", "Yes").yes_no().description("Hide rings, spheres, item capsules, prison capsules (visual only)");
|
||||
consvar_t cv_drawtimer = PlayerCheat("drawtimer", "No").yes_no().description("Always draw the timer (race checkpoint timing, etc)");
|
||||
consvar_t cv_debugfonts = PlayerCheat("debugfonts", "No").yes_no().description("Draw font bounding boxes (integer precision, beware centered text!)");
|
||||
|
||||
void lua_profile_OnChange(void);
|
||||
consvar_t cv_lua_profile = PlayerCheat("lua_profile", "0").values(CV_Unsigned).onchange(lua_profile_OnChange).description("Show hook timings over an average of N tics");
|
||||
|
|
@ -979,6 +980,7 @@ consvar_t cv_dummymenuplayer = MenuDummy("dummymenuplayer", "P1").onchange(Dummy
|
|||
consvar_t cv_dummyprofileautoroulette = MenuDummy("dummyprofileautoroulette", "Off").on_off();
|
||||
consvar_t cv_dummyprofilefov = MenuDummy("dummyprofilefov", "100").min_max(70, 110);
|
||||
consvar_t cv_dummyprofilelitesteer = MenuDummy("dummyprofilelitesteer", "Off").on_off();
|
||||
consvar_t cv_dummyprofiledescriptiveinput = Player("dummyprofiledescriptiveinput", "Modern").values(descriptiveinput_cons_t);
|
||||
consvar_t cv_dummyprofileautoring = MenuDummy("dummyprofileautoring", "Off").on_off();
|
||||
consvar_t cv_dummyprofilekickstart = MenuDummy("dummyprofilekickstart", "Off").on_off();
|
||||
consvar_t cv_dummyprofilename = MenuDummy("dummyprofilename", "");
|
||||
|
|
@ -1113,6 +1115,14 @@ consvar_t cv_cam_height[MAXSPLITSCREENPLAYERS] = {
|
|||
Player("cam4_height", "95").floating_point(),
|
||||
};
|
||||
|
||||
consvar_t cv_descriptiveinput[MAXSPLITSCREENPLAYERS] = {
|
||||
Player("descriptiveinput", "Modern").values(descriptiveinput_cons_t),
|
||||
Player("descriptiveinput2", "Modern").values(descriptiveinput_cons_t),
|
||||
Player("descriptiveinput3", "Modern").values(descriptiveinput_cons_t),
|
||||
Player("descriptiveinput4", "Modern").values(descriptiveinput_cons_t),
|
||||
};
|
||||
|
||||
|
||||
void CV_CamRotate_OnChange(void);
|
||||
void CV_CamRotate2_OnChange(void);
|
||||
void CV_CamRotate3_OnChange(void);
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@
|
|||
// cl loading screen
|
||||
#include "v_video.h"
|
||||
#include "f_finale.h"
|
||||
#include "k_hud.h"
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
#include "discord.h"
|
||||
|
|
@ -685,7 +686,7 @@ static inline void CL_DrawConnectionStatus(void)
|
|||
|
||||
// Draw bottom box
|
||||
M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-24-8, 32, 1);
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-24, V_YELLOWMAP, "Press \xAB or \xAD to abort");
|
||||
K_DrawGameControl(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-24, 0, "Press <b_animated> or <x_animated> to abort", 1, 2, V_YELLOWMAP);
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-24, 16, 8, palstart + ((animtime - i) & 15));
|
||||
|
|
@ -758,7 +759,7 @@ static inline void CL_DrawConnectionStatus(void)
|
|||
INT32 checkednum = 0;
|
||||
INT32 i;
|
||||
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-24, V_YELLOWMAP, "Press \xAB or \xAD to abort");
|
||||
K_DrawGameControl(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-24, 0, "Press <b_animated> or <x_animated> to abort", 1, 2, V_YELLOWMAP);
|
||||
|
||||
//ima just count files here
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
|
|
@ -780,7 +781,7 @@ static inline void CL_DrawConnectionStatus(void)
|
|||
INT32 loadcompletednum = 0;
|
||||
INT32 i;
|
||||
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-24, V_YELLOWMAP, "Press \xAB or \xAD to abort");
|
||||
K_DrawGameControl(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-24, 0, "Press <b_animated> or <x_animated> to abort", 1, 2, V_YELLOWMAP);
|
||||
|
||||
//ima just count files here
|
||||
for (i = 0; i < fileneedednum; i++)
|
||||
|
|
@ -807,7 +808,7 @@ static inline void CL_DrawConnectionStatus(void)
|
|||
|
||||
// Draw the bottom box.
|
||||
M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-58-8, 32, 1);
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-58-14, V_YELLOWMAP, "Press \xAB or \xAD to abort");
|
||||
K_DrawGameControl(BASEVIDWIDTH/2, BASEVIDHEIGHT-58-14, 0, "Press <b_animated> or <x_animated> to abort", 1, 2, V_YELLOWMAP);
|
||||
|
||||
Net_GetNetStat();
|
||||
dldlength = (INT32)((file->currentsize/(double)file->totalsize) * 256);
|
||||
|
|
@ -873,7 +874,7 @@ static inline void CL_DrawConnectionStatus(void)
|
|||
|
||||
//Draw bottom box
|
||||
M_DrawTextBox(BASEVIDWIDTH/2-128-8, BASEVIDHEIGHT-24-8, 32, 1);
|
||||
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-24, V_YELLOWMAP, "Press \xAB or \xAD to abort");
|
||||
K_DrawGameControl(BASEVIDWIDTH/2, BASEVIDHEIGHT-24-24, 0, "Press <b_animated> or <x_animated> to abort", 1, 2, V_YELLOWMAP);
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
V_DrawFill((BASEVIDWIDTH/2-128) + (i * 16), BASEVIDHEIGHT-24, 16, 8, palstart + ((animtime - i) & 15));
|
||||
|
|
|
|||
|
|
@ -42,8 +42,11 @@ typedef enum
|
|||
|
||||
// Lua garbage, replace with freeslottable buttons some day
|
||||
BT_LUAA = 1<<13,
|
||||
BT_LUA1 = 1<<13,
|
||||
BT_LUAB = 1<<14,
|
||||
BT_LUA2 = 1<<14,
|
||||
BT_LUAC = 1<<15,
|
||||
BT_LUA3 = 1<<15,
|
||||
} buttoncode_t;
|
||||
|
||||
// The data sampled per tick (single player)
|
||||
|
|
|
|||
|
|
@ -5003,6 +5003,9 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"BT_LUAA",BT_LUAA}, // Lua customizable
|
||||
{"BT_LUAB",BT_LUAB}, // Lua customizable
|
||||
{"BT_LUAC",BT_LUAC}, // Lua customizable
|
||||
{"BT_LUA1",BT_LUA1}, // Lua customizable
|
||||
{"BT_LUA2",BT_LUA2}, // Lua customizable
|
||||
{"BT_LUA3",BT_LUA3}, // Lua customizable
|
||||
|
||||
// Lua command registration flags
|
||||
{"COM_ADMIN",COM_ADMIN},
|
||||
|
|
|
|||
|
|
@ -408,9 +408,9 @@ class TiccmdBuilder
|
|||
map(gc_vote, BT_VOTE); // mp general function button
|
||||
|
||||
// lua buttons a thru c
|
||||
map(gc_luaa, BT_LUAA);
|
||||
map(gc_luab, BT_LUAB);
|
||||
map(gc_luac, BT_LUAC);
|
||||
map(gc_lua1, BT_LUA1);
|
||||
map(gc_lua2, BT_LUA2);
|
||||
map(gc_lua3, BT_LUA3);
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
|||
14
src/g_game.c
14
src/g_game.c
|
|
@ -848,6 +848,15 @@ static INT32 G_GetValueFromControlTable(INT32 deviceID, INT32 deadzone, INT32 *c
|
|||
return failret;
|
||||
}
|
||||
|
||||
static void G_SetGamepadPrompts(UINT8 p, boolean prompts)
|
||||
{
|
||||
if (showgamepadprompts[p] != prompts)
|
||||
{
|
||||
// CONS_Printf("Setting player %d to gamepadprompts %d\n", p, prompts);
|
||||
showgamepadprompts[p] = prompts;
|
||||
}
|
||||
}
|
||||
|
||||
INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, UINT8 menuPlayers)
|
||||
{
|
||||
const INT32 deadzone = (JOYAXISRANGE * cv_deadzone[p].value) / FRACUNIT;
|
||||
|
|
@ -879,6 +888,7 @@ INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, UINT8 menuPlayers)
|
|||
// This is only intended for P1.
|
||||
if (main_player == true)
|
||||
{
|
||||
G_SetGamepadPrompts(p, false);
|
||||
return value;
|
||||
}
|
||||
else
|
||||
|
|
@ -898,6 +908,7 @@ INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, UINT8 menuPlayers)
|
|||
value = G_GetValueFromControlTable(deviceID, deadzone, &(gamecontrol[p][gc][0]));
|
||||
if (value > 0)
|
||||
{
|
||||
G_SetGamepadPrompts(p, (deviceID != KEYBOARD_MOUSE_DEVICE));
|
||||
return value;
|
||||
}
|
||||
if (value != NO_BINDS_REACHABLE)
|
||||
|
|
@ -911,6 +922,7 @@ INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, UINT8 menuPlayers)
|
|||
value = G_GetValueFromControlTable(KEYBOARD_MOUSE_DEVICE, deadzone, &(gamecontrol[p][gc][0]));
|
||||
if (value > 0)
|
||||
{
|
||||
G_SetGamepadPrompts(p, false);
|
||||
return value;
|
||||
}
|
||||
if (value != NO_BINDS_REACHABLE)
|
||||
|
|
@ -951,6 +963,7 @@ INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, UINT8 menuPlayers)
|
|||
value = G_GetValueFromControlTable(tryDevice, deadzone, &(gamecontrol[p][gc][0]));
|
||||
if (value > 0)
|
||||
{
|
||||
G_SetGamepadPrompts(p, (tryDevice != KEYBOARD_MOUSE_DEVICE));
|
||||
return value;
|
||||
}
|
||||
if (value != NO_BINDS_REACHABLE)
|
||||
|
|
@ -967,6 +980,7 @@ INT32 G_PlayerInputAnalog(UINT8 p, INT32 gc, UINT8 menuPlayers)
|
|||
value = G_GetValueFromControlTable(deviceID, deadzone, &(gamecontroldefault[gc][0]));
|
||||
if (value > 0)
|
||||
{
|
||||
G_SetGamepadPrompts(p, (deviceID != KEYBOARD_MOUSE_DEVICE));
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ extern consvar_t cv_shrinkme[MAXSPLITSCREENPLAYERS];
|
|||
|
||||
extern consvar_t cv_deadzone[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
extern consvar_t cv_descriptiveinput[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
extern consvar_t cv_ghost_besttime, cv_ghost_bestlap, cv_ghost_last, cv_ghost_guest, cv_ghost_staff;
|
||||
|
||||
// mouseaiming (looking up/down with the mouse or keyboard)
|
||||
|
|
|
|||
216
src/g_input.c
216
src/g_input.c
|
|
@ -33,6 +33,7 @@ INT32 gamekeydown[MAXDEVICES][NUMINPUTS];
|
|||
// two key codes (or virtual key) per game control
|
||||
INT32 gamecontrol[MAXSPLITSCREENPLAYERS][num_gamecontrols][MAXINPUTMAPPING];
|
||||
UINT8 gamecontrolflags[MAXSPLITSCREENPLAYERS];
|
||||
UINT8 showgamepadprompts[MAXSPLITSCREENPLAYERS];
|
||||
INT32 gamecontroldefault[num_gamecontrols][MAXINPUTMAPPING]; // default control storage
|
||||
INT32 menucontrolreserved[num_gamecontrols][MAXINPUTMAPPING];
|
||||
|
||||
|
|
@ -759,6 +760,129 @@ static keyname_t keynames[] =
|
|||
{KEY_AXIS1+9, "R TRIGGER"},
|
||||
};
|
||||
|
||||
static keyname_t shortkeynames[] =
|
||||
{
|
||||
{KEY_SPACE, "SPC"},
|
||||
{KEY_CAPSLOCK, "CAPS"},
|
||||
{KEY_ENTER, "ENTER"},
|
||||
{KEY_TAB, "TAB"},
|
||||
{KEY_ESCAPE, "ESC"},
|
||||
{KEY_BACKSPACE, "BKSP"},
|
||||
|
||||
{KEY_NUMLOCK, "NLOK"},
|
||||
{KEY_SCROLLLOCK, "SLOK"},
|
||||
|
||||
// bill gates keys
|
||||
{KEY_LEFTWIN, "LWIN"},
|
||||
{KEY_RIGHTWIN, "RWIN"},
|
||||
{KEY_MENU, "MENU"},
|
||||
|
||||
{KEY_LSHIFT, "LSFT"},
|
||||
{KEY_RSHIFT, "RSFT"},
|
||||
{KEY_LSHIFT, "SFT"},
|
||||
{KEY_LCTRL, "LCTRL"},
|
||||
{KEY_RCTRL, "RCTRL"},
|
||||
{KEY_LCTRL, "CTRL"},
|
||||
{KEY_LALT, "LALT"},
|
||||
{KEY_RALT, "RALT"},
|
||||
{KEY_LALT, "ALT"},
|
||||
|
||||
// keypad keys
|
||||
{KEY_KPADSLASH, "/"},
|
||||
{KEY_KEYPAD7, "7"},
|
||||
{KEY_KEYPAD8, "8"},
|
||||
{KEY_KEYPAD9, "9"},
|
||||
{KEY_MINUSPAD, "-"},
|
||||
{KEY_KEYPAD4, "4"},
|
||||
{KEY_KEYPAD5, "5"},
|
||||
{KEY_KEYPAD6, "6"},
|
||||
{KEY_PLUSPAD, "+"},
|
||||
{KEY_KEYPAD1, "1"},
|
||||
{KEY_KEYPAD2, "2"},
|
||||
{KEY_KEYPAD3, "3"},
|
||||
{KEY_KEYPAD0, "0"},
|
||||
{KEY_KPADDEL, "."},
|
||||
|
||||
// extended keys (not keypad)
|
||||
{KEY_HOME, "HOME"},
|
||||
{KEY_UPARROW, "UP"},
|
||||
{KEY_PGUP, "PGUP"},
|
||||
{KEY_LEFTARROW, "LEFT"},
|
||||
{KEY_RIGHTARROW, "RIGHT"},
|
||||
{KEY_END, "END"},
|
||||
{KEY_DOWNARROW, "DOWN"},
|
||||
{KEY_PGDN, "PGDN"},
|
||||
{KEY_INS, "INS"},
|
||||
{KEY_DEL, "DEL"},
|
||||
|
||||
// other keys
|
||||
{KEY_F1, "F1"},
|
||||
{KEY_F2, "F2"},
|
||||
{KEY_F3, "F3"},
|
||||
{KEY_F4, "F4"},
|
||||
{KEY_F5, "F5"},
|
||||
{KEY_F6, "F6"},
|
||||
{KEY_F7, "F7"},
|
||||
{KEY_F8, "F8"},
|
||||
{KEY_F9, "F9"},
|
||||
{KEY_F10, "F10"},
|
||||
{KEY_F11, "F11"},
|
||||
{KEY_F12, "F12"},
|
||||
|
||||
// KEY_CONSOLE has an exception in the keyname code
|
||||
{'`', "TILDE"},
|
||||
{KEY_PAUSE, "PAUSE"},
|
||||
|
||||
// virtual keys for mouse buttons and joystick buttons
|
||||
{KEY_MOUSE1+0,"M1"},
|
||||
{KEY_MOUSE1+1,"M2"},
|
||||
{KEY_MOUSE1+2,"M3"},
|
||||
{KEY_MOUSE1+3,"M4"},
|
||||
{KEY_MOUSE1+4,"M5"},
|
||||
{KEY_MOUSE1+5,"M6"},
|
||||
{KEY_MOUSE1+6,"M7"},
|
||||
{KEY_MOUSE1+7,"M8"},
|
||||
{KEY_MOUSEMOVE+0,"Mouse Up"},
|
||||
{KEY_MOUSEMOVE+1,"Mouse Down"},
|
||||
{KEY_MOUSEMOVE+2,"Mouse Left"},
|
||||
{KEY_MOUSEMOVE+3,"Mouse Right"},
|
||||
{KEY_MOUSEWHEELUP, "Wheel Up"},
|
||||
{KEY_MOUSEWHEELDOWN, "Wheel Down"},
|
||||
|
||||
{KEY_JOY1+0, "A"},
|
||||
{KEY_JOY1+1, "B"},
|
||||
{KEY_JOY1+2, "X"},
|
||||
{KEY_JOY1+3, "Y"},
|
||||
{KEY_JOY1+4, "BACK"},
|
||||
{KEY_JOY1+5, "GUIDE"},
|
||||
{KEY_JOY1+6, "START"},
|
||||
{KEY_JOY1+7, "LS"},
|
||||
{KEY_JOY1+8, "RS"},
|
||||
{KEY_JOY1+9, "LB"},
|
||||
{KEY_JOY1+10, "RB"},
|
||||
{KEY_JOY1+11, "D-UP"},
|
||||
{KEY_JOY1+12, "D-DOWN"},
|
||||
{KEY_JOY1+13, "D-LEFT"},
|
||||
{KEY_JOY1+14, "D-RIGHT"},
|
||||
{KEY_JOY1+15, "MISC."},
|
||||
{KEY_JOY1+16, "PADDLE1"},
|
||||
{KEY_JOY1+17, "PADDLE2"},
|
||||
{KEY_JOY1+18, "PADDLE3"},
|
||||
{KEY_JOY1+19, "PADDLE4"},
|
||||
{KEY_JOY1+20, "TOUCHPAD"},
|
||||
|
||||
{KEY_AXIS1+0, "LS LEFT"},
|
||||
{KEY_AXIS1+1, "LS RIGHT"},
|
||||
{KEY_AXIS1+2, "LS UP"},
|
||||
{KEY_AXIS1+3, "LS DOWN"},
|
||||
{KEY_AXIS1+4, "RS LEFT"},
|
||||
{KEY_AXIS1+5, "RS RIGHT"},
|
||||
{KEY_AXIS1+6, "RS UP"},
|
||||
{KEY_AXIS1+7, "RS DOWN"},
|
||||
{KEY_AXIS1+8, "LT"},
|
||||
{KEY_AXIS1+9, "RT"},
|
||||
};
|
||||
|
||||
static const char *gamecontrolname[num_gamecontrols] =
|
||||
{
|
||||
"null", // a key/button mapped to gc_null has no effect
|
||||
|
|
@ -879,7 +1003,7 @@ const char *G_KeynumToString(INT32 keynum)
|
|||
// return a string with the ascii char if displayable
|
||||
if (keynum > ' ' && keynum <= 'z' && keynum != KEY_CONSOLE)
|
||||
{
|
||||
keynamestr[0] = (char)keynum;
|
||||
keynamestr[0] = toupper(keynum); // Uppercase looks better!
|
||||
keynamestr[1] = '\0';
|
||||
return keynamestr;
|
||||
}
|
||||
|
|
@ -894,6 +1018,30 @@ const char *G_KeynumToString(INT32 keynum)
|
|||
return keynamestr;
|
||||
}
|
||||
|
||||
const char *G_KeynumToShortString(INT32 keynum)
|
||||
{
|
||||
static char keynamestr[8];
|
||||
|
||||
UINT32 j;
|
||||
|
||||
// return a string with the ascii char if displayable
|
||||
if (keynum > ' ' && keynum <= 'z' && keynum != KEY_CONSOLE)
|
||||
{
|
||||
keynamestr[0] = toupper(keynum); // Uppercase looks better!
|
||||
keynamestr[1] = '\0';
|
||||
return keynamestr;
|
||||
}
|
||||
|
||||
// find a description for special keys
|
||||
for (j = 0; j < NUMKEYNAMES; j++)
|
||||
if (shortkeynames[j].keynum == keynum)
|
||||
return shortkeynames[j].name;
|
||||
|
||||
// create a name for unknown keys
|
||||
sprintf(keynamestr, "KEY%d", keynum);
|
||||
return keynamestr;
|
||||
}
|
||||
|
||||
INT32 G_KeyStringtoNum(const char *keystr)
|
||||
{
|
||||
UINT32 j;
|
||||
|
|
@ -1121,6 +1269,72 @@ INT32 G_CheckDoubleUsage(INT32 keynum, INT32 playernum, boolean modify)
|
|||
return result;
|
||||
}
|
||||
|
||||
INT32 G_FindPlayerBindForGameControl(INT32 player, gamecontrols_e control)
|
||||
{
|
||||
INT32 device = showgamepadprompts[player] ? 1 : KEYBOARD_MOUSE_DEVICE;
|
||||
|
||||
INT32 bestbind = -1; // Bind that matches our input device
|
||||
INT32 anybind = -1; // Bind that doesn't match, but is at least for this control
|
||||
|
||||
INT32 bindindex = MAXINPUTMAPPING-1;
|
||||
|
||||
// CONS_Printf("Check bind %d for player %d device %d\n", control, player, device);
|
||||
|
||||
// PASS 1: Binds that are directly in our active control mapping.
|
||||
while (bindindex >= 0) // Prefer earlier binds
|
||||
{
|
||||
INT32 possiblecontrol = gamecontrol[player][control][bindindex];
|
||||
|
||||
bindindex--;
|
||||
|
||||
if (possiblecontrol == 0)
|
||||
continue;
|
||||
|
||||
// if (device is gamepad) == (bound control is in gamepad range) - e.g. if bind matches device
|
||||
if ((device != KEYBOARD_MOUSE_DEVICE) == (possiblecontrol >= KEY_JOY1 && possiblecontrol < JOYINPUTEND))
|
||||
{
|
||||
// CONS_Printf("PASS1 found %s\n", G_KeynumToShortString(possiblecontrol));
|
||||
bestbind = possiblecontrol;
|
||||
anybind = possiblecontrol;
|
||||
}
|
||||
else
|
||||
{
|
||||
// CONS_Printf("PASS1 considering %s\n", G_KeynumToShortString(possiblecontrol));
|
||||
anybind = possiblecontrol;
|
||||
}
|
||||
}
|
||||
|
||||
// PASS 3: "Safety" binds that are reserved by the menu system.
|
||||
if (bestbind == -1)
|
||||
{
|
||||
bindindex = MAXINPUTMAPPING-1;
|
||||
|
||||
while (bindindex >= 0)
|
||||
{
|
||||
INT32 possiblecontrol = menucontrolreserved[control][bindindex];
|
||||
|
||||
bindindex--;
|
||||
|
||||
if (possiblecontrol == 0)
|
||||
continue;
|
||||
|
||||
if ((device != KEYBOARD_MOUSE_DEVICE) == (possiblecontrol >= KEY_JOY1 && possiblecontrol < JOYINPUTEND))
|
||||
{
|
||||
// CONS_Printf("PASS2 found %s\n", G_KeynumToShortString(possiblecontrol));
|
||||
bestbind = possiblecontrol;
|
||||
anybind = possiblecontrol;
|
||||
}
|
||||
else
|
||||
{
|
||||
// CONS_Printf("PASS2 considering %s\n", G_KeynumToShortString(possiblecontrol));
|
||||
anybind = possiblecontrol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (bestbind != -1) ? bestbind : anybind; // If we couldn't find a device-appropriate bind, try to at least use something
|
||||
}
|
||||
|
||||
static void setcontrol(UINT8 player)
|
||||
{
|
||||
INT32 numctrl;
|
||||
|
|
|
|||
|
|
@ -56,6 +56,33 @@ typedef enum
|
|||
NUMINPUTS = MOUSEINPUTEND,
|
||||
} key_input_e;
|
||||
|
||||
// Helper to keep descriptive input setup slightly more readable
|
||||
typedef enum
|
||||
{
|
||||
nc_a = KEY_JOY1,
|
||||
nc_b,
|
||||
nc_x,
|
||||
nc_y,
|
||||
nc_back,
|
||||
nc_guide,
|
||||
nc_start,
|
||||
nc_ls,
|
||||
nc_rs,
|
||||
nc_lb,
|
||||
nc_rb,
|
||||
nc_hatup,
|
||||
nc_hatdown,
|
||||
nc_hatleft,
|
||||
nc_hatright,
|
||||
nc_touch = KEY_JOY1+20,
|
||||
nc_lsleft = KEY_AXIS1+0,
|
||||
nc_lsright,
|
||||
nc_lsup,
|
||||
nc_lsdown,
|
||||
nc_lt = KEY_AXIS1+8,
|
||||
nc_rt,
|
||||
} named_controls_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
gc_null = 0, // a key/button mapped to gc_null has no effect
|
||||
|
|
@ -77,9 +104,9 @@ typedef enum
|
|||
|
||||
// special keys
|
||||
gc_abc,
|
||||
gc_luaa,
|
||||
gc_luab,
|
||||
gc_luac,
|
||||
gc_lua1,
|
||||
gc_lua2,
|
||||
gc_lua3,
|
||||
gc_console,
|
||||
gc_talk,
|
||||
gc_teamtalk,
|
||||
|
|
@ -120,6 +147,7 @@ extern INT32 gamekeydown[MAXDEVICES][NUMINPUTS];
|
|||
// several key codes (or virtual key) per game control
|
||||
extern INT32 gamecontrol[MAXSPLITSCREENPLAYERS][num_gamecontrols][MAXINPUTMAPPING];
|
||||
extern UINT8 gamecontrolflags[MAXSPLITSCREENPLAYERS];
|
||||
extern UINT8 showgamepadprompts[MAXSPLITSCREENPLAYERS];
|
||||
extern INT32 gamecontroldefault[num_gamecontrols][MAXINPUTMAPPING]; // default control storage
|
||||
extern INT32 menucontrolreserved[num_gamecontrols][MAXINPUTMAPPING];
|
||||
|
||||
|
|
@ -187,6 +215,7 @@ void G_MapEventsToControls(event_t *ev);
|
|||
|
||||
// returns the name of a key
|
||||
const char *G_KeynumToString(INT32 keynum);
|
||||
const char *G_KeynumToShortString(INT32 keynum);
|
||||
INT32 G_KeyStringtoNum(const char *keystr);
|
||||
|
||||
boolean G_KeyBindIsNecessary(INT32 gc);
|
||||
|
|
@ -205,6 +234,8 @@ void G_ApplyControlScheme(UINT8 splitplayer, INT32 (*fromcontrols)[MAXINPUTMAPPI
|
|||
void G_SaveKeySetting(FILE *f, INT32 (*fromcontrolsa)[MAXINPUTMAPPING], INT32 (*fromcontrolsb)[MAXINPUTMAPPING], INT32 (*fromcontrolsc)[MAXINPUTMAPPING], INT32 (*fromcontrolsd)[MAXINPUTMAPPING]);
|
||||
INT32 G_CheckDoubleUsage(INT32 keynum, INT32 playernum, boolean modify);
|
||||
|
||||
INT32 G_FindPlayerBindForGameControl(INT32 player, gamecontrols_e control);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -39,10 +39,9 @@ struct List
|
|||
{
|
||||
struct Field
|
||||
{
|
||||
Field(const char* label, Draw::Button button, std::optional<bool> pressed = {}) :
|
||||
Field(const char* label, const char* button = {}) :
|
||||
label_(Draw::TextElement(label).font(Draw::Font::kThin)),
|
||||
button_(button),
|
||||
pressed_(pressed)
|
||||
btlabel_(Draw::TextElement().parse(button).font(Draw::Font::kThin))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -55,29 +54,7 @@ struct List
|
|||
col.text(label_);
|
||||
col = col.x(left ? -(kButtonWidth + kButtonMargin) : width() - (kButtonWidth + kFieldSpacing));
|
||||
|
||||
//if (r_splitscreen)
|
||||
{
|
||||
auto small_button_offset = [&]
|
||||
{
|
||||
switch (button_)
|
||||
{
|
||||
case Draw::Button::l:
|
||||
case Draw::Button::r:
|
||||
return -4;
|
||||
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
};
|
||||
|
||||
col.y(small_button_offset()).small_button(button_, pressed_);
|
||||
}
|
||||
#if 0
|
||||
else
|
||||
{
|
||||
col.y(-4).button(button_, pressed_);
|
||||
}
|
||||
#endif
|
||||
col.text(btlabel_);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -86,8 +63,7 @@ struct List
|
|||
static constexpr int kFieldSpacing = 8;
|
||||
|
||||
Draw::TextElement label_;
|
||||
Draw::Button button_;
|
||||
std::optional<bool> pressed_;
|
||||
Draw::TextElement btlabel_;
|
||||
};
|
||||
|
||||
List(int x, int y) : row_(split_draw(x, y, left_)) {}
|
||||
|
|
@ -209,7 +185,7 @@ void K_drawSpectatorHUD(boolean director)
|
|||
label += fmt::format(" [{}/{}]", numingame, cv_maxplayers.value);
|
||||
}
|
||||
|
||||
list.insert({{label.c_str(), Draw::Button::l}});
|
||||
list.insert({{label.c_str(), "<l_animated>"}});
|
||||
}
|
||||
|
||||
if (director || camera[viewnum].freecam)
|
||||
|
|
@ -217,14 +193,14 @@ void K_drawSpectatorHUD(boolean director)
|
|||
// Not locked into freecam -- can toggle it.
|
||||
if (director)
|
||||
{
|
||||
list.insert({{"Freecam", Draw::Button::c}});
|
||||
list.insert({{"Freecam", "<c_animated>"}});
|
||||
}
|
||||
else
|
||||
{
|
||||
bool press = D_LocalTiccmd(viewnum)->buttons & BT_RESPAWN;
|
||||
const char* label = (press && I_GetTime() % 16 < 8) ? "> <" : ">< ";
|
||||
|
||||
list.insert({{label, Draw::Button::y, press}, {"Exit", Draw::Button::c}});
|
||||
list.insert({{label, press ? "<y_pressed>" : "<y>"}, {"Exit", "<c_animated>"}});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -232,19 +208,19 @@ void K_drawSpectatorHUD(boolean director)
|
|||
{
|
||||
if (numingame > 1)
|
||||
{
|
||||
list.insert({{"+", Draw::Button::a}, {"-", Draw::Button::x}});
|
||||
list.insert({{"+", "<a_animated>"}, {"-", "<x_animated>"}});
|
||||
}
|
||||
|
||||
if (player)
|
||||
{
|
||||
list.insert({{K_DirectorIsEnabled(viewnum) ? "\x82" "Director" : "Director", Draw::Button::r}});
|
||||
list.insert({{K_DirectorIsEnabled(viewnum) ? "\x82" "Director" : "Director", "<r_animated>"}});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto bt = D_LocalTiccmd(viewnum)->buttons;
|
||||
|
||||
list.insert({{"", Draw::Button::r, bt & BT_DRIFT}, {"Pivot", Draw::Button::b, bt & BT_LOOKBACK}});
|
||||
list.insert({{"+", Draw::Button::a, bt & BT_ACCELERATE}, {"-", Draw::Button::x, bt & BT_BRAKE}});
|
||||
list.insert({{"", bt & BT_DRIFT ? "<r_pressed>" : "<r>"}, {"Pivot", bt & BT_LOOKBACK ? "<b_pressed>" : "<b>"}});
|
||||
list.insert({{"+", bt & BT_ACCELERATE ? "<a_pressed>" : "<a>"}, {"-", bt & BT_BRAKE ? "<x_pressed>" : "<x>"}});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ void Dialogue::NewText(std::string_view rawText)
|
|||
Init();
|
||||
|
||||
char* newText = V_ScaledWordWrap(
|
||||
290 << FRACBITS,
|
||||
275 << FRACBITS,
|
||||
FRACUNIT, FRACUNIT, FRACUNIT,
|
||||
0, HU_FONT,
|
||||
srb2::Draw::TextElement().parse(rawText).string().c_str() // parse special characters
|
||||
|
|
@ -472,32 +472,25 @@ void Dialogue::Draw(void)
|
|||
.flags(V_VFLIP|V_FLIP)
|
||||
.patch(patchCache["TUTDIAGE"]);
|
||||
|
||||
std::string intertext = "<large>";
|
||||
|
||||
drawer
|
||||
.xy(10 - BASEVIDWIDTH, -3-32)
|
||||
.font(srb2::Draw::Font::kConsole)
|
||||
.text( typewriter.text.c_str() );
|
||||
|
||||
if (Dismissable())
|
||||
{
|
||||
if (TextDone())
|
||||
{
|
||||
drawer
|
||||
.xy(-14, -7-5)
|
||||
.xy(-18 - 3, -7-5)
|
||||
.patch(patchCache["TUTDIAG2"]);
|
||||
}
|
||||
|
||||
auto bt_translate_press = [this]() -> std::optional<bool>
|
||||
{
|
||||
if (Held())
|
||||
return true;
|
||||
if (TextDone())
|
||||
return {};
|
||||
return false;
|
||||
};
|
||||
intertext += "<z_pressed>";
|
||||
else
|
||||
intertext += "<z_animated>";
|
||||
|
||||
drawer
|
||||
.xy(17-14 - BASEVIDWIDTH, -39-16)
|
||||
.button(srb2::Draw::Button::z, bt_translate_press());
|
||||
drawer.xy(-18, -7-8 - 14).align(Draw::Align::kCenter).font(Draw::Font::kMenu).text(srb2::Draw::TextElement().parse(intertext).string());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
168
src/k_hud.cpp
168
src/k_hud.cpp
|
|
@ -235,19 +235,49 @@ patch_t *kp_button_c[2][2];
|
|||
patch_t *kp_button_x[2][2];
|
||||
patch_t *kp_button_y[2][2];
|
||||
patch_t *kp_button_z[2][2];
|
||||
patch_t *kp_button_start[2];
|
||||
patch_t *kp_button_l[2];
|
||||
patch_t *kp_button_r[2];
|
||||
patch_t *kp_button_up[2];
|
||||
patch_t *kp_button_down[2];
|
||||
patch_t *kp_button_right[2];
|
||||
patch_t *kp_button_left[2];
|
||||
patch_t *kp_button_dpad[2];
|
||||
patch_t *kp_button_start[2][2];
|
||||
patch_t *kp_button_l[2][2];
|
||||
patch_t *kp_button_r[2][2];
|
||||
patch_t *kp_button_up[2][2];
|
||||
patch_t *kp_button_down[2][2];
|
||||
patch_t *kp_button_right[2][2];
|
||||
patch_t *kp_button_left[2][2];
|
||||
patch_t *kp_button_lua1[2][2];
|
||||
patch_t *kp_button_lua2[2][2];
|
||||
patch_t *kp_button_lua3[2][2];
|
||||
|
||||
static void K_LoadButtonGraphics(patch_t *kp[2], int letter)
|
||||
patch_t *gen_button_a[2][2];
|
||||
patch_t *gen_button_b[2][2];
|
||||
patch_t *gen_button_x[2][2];
|
||||
patch_t *gen_button_y[2][2];
|
||||
patch_t *gen_button_lb[2][2];
|
||||
patch_t *gen_button_rb[2][2];
|
||||
patch_t *gen_button_lt[2][2];
|
||||
patch_t *gen_button_rt[2][2];
|
||||
patch_t *gen_button_start[2][2];
|
||||
patch_t *gen_button_back[2][2];
|
||||
patch_t *gen_button_ls[2][2];
|
||||
patch_t *gen_button_rs[2][2];
|
||||
patch_t *gen_button_dpad[2][2];
|
||||
|
||||
patch_t *gen_button_keyleft[2];
|
||||
patch_t *gen_button_keyright[2];
|
||||
patch_t *gen_button_keycenter[2];
|
||||
|
||||
static void K_LoadButtonGraphics(patch_t *kp[2][2], const char* code)
|
||||
{
|
||||
HU_UpdatePatch(&kp[0], "TLB_%c", letter);
|
||||
HU_UpdatePatch(&kp[1], "TLB_%cB", letter);
|
||||
HU_UpdatePatch(&kp[0][0], "TLB_%s", code);
|
||||
HU_UpdatePatch(&kp[0][1], "TLB_%sB", code);
|
||||
HU_UpdatePatch(&kp[1][0], "TLBS%s", code);
|
||||
HU_UpdatePatch(&kp[1][1], "TLBS%sB", code);
|
||||
}
|
||||
|
||||
static void K_LoadGenericButtonGraphics(patch_t *kp[2][2], const char* code)
|
||||
{
|
||||
HU_UpdatePatch(&kp[0][0], "TLG_%s", code);
|
||||
HU_UpdatePatch(&kp[0][1], "TLG_%sB", code);
|
||||
HU_UpdatePatch(&kp[1][0], "TLGS%s", code);
|
||||
HU_UpdatePatch(&kp[1][1], "TLGS%sB", code);
|
||||
}
|
||||
|
||||
void K_LoadKartHUDGraphics(void)
|
||||
|
|
@ -942,26 +972,44 @@ void K_LoadKartHUDGraphics(void)
|
|||
HU_UpdatePatch(&kp_spraycantarget_near[1][i], "%s", buffer);
|
||||
}
|
||||
|
||||
K_LoadButtonGraphics(kp_button_a[0], 'A');
|
||||
K_LoadButtonGraphics(kp_button_a[1], 'N');
|
||||
K_LoadButtonGraphics(kp_button_b[0], 'B');
|
||||
K_LoadButtonGraphics(kp_button_b[1], 'O');
|
||||
K_LoadButtonGraphics(kp_button_c[0], 'C');
|
||||
K_LoadButtonGraphics(kp_button_c[1], 'P');
|
||||
K_LoadButtonGraphics(kp_button_x[0], 'D');
|
||||
K_LoadButtonGraphics(kp_button_x[1], 'Q');
|
||||
K_LoadButtonGraphics(kp_button_y[0], 'E');
|
||||
K_LoadButtonGraphics(kp_button_y[1], 'R');
|
||||
K_LoadButtonGraphics(kp_button_z[0], 'F');
|
||||
K_LoadButtonGraphics(kp_button_z[1], 'S');
|
||||
K_LoadButtonGraphics(kp_button_start, 'G');
|
||||
K_LoadButtonGraphics(kp_button_l, 'H');
|
||||
K_LoadButtonGraphics(kp_button_r, 'I');
|
||||
K_LoadButtonGraphics(kp_button_up, 'J');
|
||||
K_LoadButtonGraphics(kp_button_down, 'K');
|
||||
K_LoadButtonGraphics(kp_button_right, 'L');
|
||||
K_LoadButtonGraphics(kp_button_left, 'M');
|
||||
K_LoadButtonGraphics(kp_button_dpad, 'T');
|
||||
K_LoadButtonGraphics(kp_button_a, "A");
|
||||
K_LoadButtonGraphics(kp_button_b, "B");
|
||||
K_LoadButtonGraphics(kp_button_c, "C");
|
||||
K_LoadButtonGraphics(kp_button_x, "X");
|
||||
K_LoadButtonGraphics(kp_button_y, "Y");
|
||||
K_LoadButtonGraphics(kp_button_z, "Z");
|
||||
K_LoadButtonGraphics(kp_button_l, "L1");
|
||||
K_LoadButtonGraphics(kp_button_r, "R1");
|
||||
K_LoadButtonGraphics(kp_button_up, "ARU");
|
||||
K_LoadButtonGraphics(kp_button_down, "ARD");
|
||||
K_LoadButtonGraphics(kp_button_right, "ARR");
|
||||
K_LoadButtonGraphics(kp_button_left, "ARL");
|
||||
K_LoadButtonGraphics(kp_button_start, "S");
|
||||
|
||||
K_LoadGenericButtonGraphics(kp_button_lua1, "LU1");
|
||||
K_LoadGenericButtonGraphics(kp_button_lua2, "LU2");
|
||||
K_LoadGenericButtonGraphics(kp_button_lua3, "LU3");
|
||||
|
||||
HU_UpdatePatch(&gen_button_keyleft[0], "TLK_L");
|
||||
HU_UpdatePatch(&gen_button_keyleft[1], "TLK_LB");
|
||||
HU_UpdatePatch(&gen_button_keyright[0], "TLK_R");
|
||||
HU_UpdatePatch(&gen_button_keyright[1], "TLK_RB");
|
||||
HU_UpdatePatch(&gen_button_keycenter[0], "TLK_M");
|
||||
HU_UpdatePatch(&gen_button_keycenter[1], "TLK_MB");
|
||||
|
||||
K_LoadGenericButtonGraphics(gen_button_dpad, "DP");
|
||||
K_LoadGenericButtonGraphics(gen_button_a, "A");
|
||||
K_LoadGenericButtonGraphics(gen_button_b, "B");
|
||||
K_LoadGenericButtonGraphics(gen_button_x, "X");
|
||||
K_LoadGenericButtonGraphics(gen_button_y, "Y");
|
||||
K_LoadGenericButtonGraphics(gen_button_lb, "L1");
|
||||
K_LoadGenericButtonGraphics(gen_button_rb, "R1");
|
||||
K_LoadGenericButtonGraphics(gen_button_lt, "L2");
|
||||
K_LoadGenericButtonGraphics(gen_button_rt, "R2");
|
||||
K_LoadGenericButtonGraphics(gen_button_ls, "L3");
|
||||
K_LoadGenericButtonGraphics(gen_button_rs, "R3");
|
||||
K_LoadGenericButtonGraphics(gen_button_start, "S");
|
||||
K_LoadGenericButtonGraphics(gen_button_back, "I");
|
||||
}
|
||||
|
||||
// For the item toggle menu
|
||||
|
|
@ -6303,7 +6351,7 @@ void K_ClearPersistentMessages()
|
|||
}
|
||||
|
||||
// Return value can be used for "paired" splitscreen messages, true = was displayed
|
||||
void K_AddMessageForPlayer(const player_t *player, const char *msg, boolean interrupt, boolean persist)
|
||||
void K_AddMessageForPlayer(player_t *player, const char *msg, boolean interrupt, boolean persist)
|
||||
{
|
||||
if (!player)
|
||||
return;
|
||||
|
|
@ -6319,7 +6367,7 @@ void K_AddMessageForPlayer(const player_t *player, const char *msg, boolean inte
|
|||
if (interrupt)
|
||||
state->clear();
|
||||
|
||||
std::string parsedmsg = srb2::Draw::TextElement().parse(msg).string();
|
||||
std::string parsedmsg = srb2::Draw::TextElement().as(player - players).parse(msg).string();
|
||||
|
||||
if (persist)
|
||||
state->objective = parsedmsg;
|
||||
|
|
@ -6379,7 +6427,7 @@ static void K_DrawMessageFeed(void)
|
|||
|
||||
text.font(Draw::Font::kMenu);
|
||||
|
||||
UINT8 x = 160;
|
||||
UINT8 x = BASEVIDWIDTH/2;
|
||||
UINT8 y = 10;
|
||||
SINT8 shift = 0;
|
||||
if (r_splitscreen >= 2)
|
||||
|
|
@ -6403,6 +6451,7 @@ static void K_DrawMessageFeed(void)
|
|||
if (i >= 1)
|
||||
y += BASEVIDHEIGHT / 2;
|
||||
}
|
||||
|
||||
UINT16 sw = text.width();
|
||||
|
||||
K_DrawSticker(x - sw/2, y, sw, 0, true);
|
||||
|
|
@ -6439,6 +6488,40 @@ void K_drawKartHUD(void)
|
|||
K_drawEmeraldWin(false);
|
||||
}
|
||||
|
||||
// In case of font debugging break glass
|
||||
#if 0
|
||||
using srb2::Draw;
|
||||
|
||||
if (1)
|
||||
{
|
||||
CV_StealthSetValue(cv_descriptiveinput, 0);
|
||||
Draw::TextElement text = Draw::TextElement().parse("Hamburger <a><b><c><x><y><z><l><r><lua1><lua2><lua3><start><left><up><right><down> Hamburger\n\nHamburger <large><a><large><b><large><c><large><x><large><y><large><z><large><l><large><r><large><lua1><large><lua2><large><lua3><large><start><large><left><large><up><large><right><large><down> Hamburger\n\nHamburger \xEB\xEF\xA0\xEB\xEF\xA1\xEB\xEF\xA2\xEB\xEF\xA3\xEB\xEF\xA4\xEB\xEF\xA5\xEB\xEF\xA6\xEB\xEF\xA7\xEB\xEF\xA8\xEB\xEF\xA9\xEB\xEF\xAA\xEB\xEF\xAB\xEB\xEF\xAC Hamburger");
|
||||
|
||||
UINT8 fakeoff = (stplyr - players)*40;
|
||||
Draw(5, 5+fakeoff).align((srb2::Draw::Align)0).font(Draw::Font::kMenu).text(text);
|
||||
Draw(40, 80+fakeoff).align((srb2::Draw::Align)0).font(Draw::Font::kThin).text(text);
|
||||
}
|
||||
|
||||
if (0)
|
||||
{
|
||||
Draw::TextElement text = Draw::TextElement().parse("\xEELEFTSPACE\xEE\n\xEESPC\xEE \xEETAB\xEE\nA \xEF\xA0 A\nB \xEF\xA1 B\nX \xEF\xA2 X\nY \xEF\xA3 Y\nLB \xEF\xA4 LB\nRB \xEF\xA5 RB\nLT \xEF\xA6 LT\nRT \xEF\xA7 RT\nST \xEF\xA8 ST\nBK \xEF\xA9 BK\nLS \xEF\xAA LS\nRS \xEF\xAB RS\n");
|
||||
|
||||
UINT8 offset = 0;
|
||||
Draw(160+offset, 5).align((srb2::Draw::Align)1).font(Draw::Font::kThin).text(text);
|
||||
Draw(55+offset, 5).align((srb2::Draw::Align)1).font(Draw::Font::kMenu).text(text);
|
||||
}
|
||||
|
||||
if (0)
|
||||
{
|
||||
Draw::TextElement text = Draw::TextElement().parse("\xEELEFTSPACE\xEE\n\xEESPC\xEE \xEETAB\xEE\nA \xEB\xEF\xA0 A\nB \xEB\xEF\xA1 B\nX \xEB\xEF\xA2 X\nY \xEB\xEF\xA3 Y\nLB \xEB\xEF\xA4 LB\nRB \xEB\xEF\xA5 RB\nLT \xEB\xEF\xA6 LT\nRT \xEB\xEF\xA7 RT\nST \xEB\xEF\xA8 ST\nBK \xEB\xEF\xA9 BK\nLS \xEB\xEF\xAA LS\nRS \xEB\xEF\xAB RS\n");
|
||||
|
||||
UINT8 offset = 0;
|
||||
Draw(160+offset, 5).align((srb2::Draw::Align)1).font(Draw::Font::kThin).text(text);
|
||||
Draw(55+offset, 5).align((srb2::Draw::Align)1).font(Draw::Font::kMenu).text(text);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (!demo.attract)
|
||||
{
|
||||
// Draw the CHECK indicator before the other items, so it's overlapped by everything else
|
||||
|
|
@ -6502,10 +6585,11 @@ void K_drawKartHUD(void)
|
|||
if (ta)
|
||||
{
|
||||
using srb2::Draw;
|
||||
Draw::TextElement text = Draw::TextElement().parse("<y> Restart");
|
||||
Draw(BASEVIDWIDTH - 19, 2)
|
||||
.flags(flags | V_YELLOWMAP)
|
||||
.align(Draw::Align::kRight)
|
||||
.text("\xBE Restart");
|
||||
.text(text.string());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -6849,3 +6933,17 @@ void K_DrawMarginSticker(INT32 x, INT32 y, INT32 width, INT32 flags, boolean isS
|
|||
if (!leftedge)
|
||||
V_DrawFixedPatch((x + width)*FRACUNIT, y*FRACUNIT, FRACUNIT, flags|V_FLIP, stickerEnd, NULL);
|
||||
}
|
||||
|
||||
// common fonts: 0 = thin, 8 = menu. sorry we have to launder a C++ enum in here
|
||||
INT32 K_DrawGameControl(UINT16 x, UINT16 y, UINT8 player, const char *str, UINT8 alignment, UINT8 font, UINT32 flags)
|
||||
{
|
||||
using srb2::Draw;
|
||||
|
||||
Draw::TextElement text = Draw::TextElement().as(player).parse(str).font((Draw::Font)font);
|
||||
|
||||
INT32 width = text.width();
|
||||
|
||||
Draw(x, y).align((srb2::Draw::Align)alignment).flags(flags).text(text);
|
||||
|
||||
return width;
|
||||
}
|
||||
44
src/k_hud.h
44
src/k_hud.h
|
|
@ -94,14 +94,38 @@ extern patch_t *kp_button_c[2][2];
|
|||
extern patch_t *kp_button_x[2][2];
|
||||
extern patch_t *kp_button_y[2][2];
|
||||
extern patch_t *kp_button_z[2][2];
|
||||
extern patch_t *kp_button_start[2];
|
||||
extern patch_t *kp_button_l[2];
|
||||
extern patch_t *kp_button_r[2];
|
||||
extern patch_t *kp_button_up[2];
|
||||
extern patch_t *kp_button_down[2];
|
||||
extern patch_t *kp_button_right[2];
|
||||
extern patch_t *kp_button_left[2];
|
||||
extern patch_t *kp_button_dpad[2];
|
||||
extern patch_t *kp_button_start[2][2];
|
||||
extern patch_t *kp_button_l[2][2];
|
||||
extern patch_t *kp_button_r[2][2];
|
||||
extern patch_t *kp_button_up[2][2];
|
||||
extern patch_t *kp_button_down[2][2];
|
||||
extern patch_t *kp_button_right[2][2];
|
||||
extern patch_t *kp_button_left[2][2];
|
||||
extern patch_t *kp_button_lua1[2][2];
|
||||
extern patch_t *kp_button_lua2[2][2];
|
||||
extern patch_t *kp_button_lua3[2][2];
|
||||
|
||||
extern patch_t *gen_button_a[2][2];
|
||||
extern patch_t *gen_button_b[2][2];
|
||||
extern patch_t *gen_button_x[2][2];
|
||||
extern patch_t *gen_button_y[2][2];
|
||||
extern patch_t *gen_button_lb[2][2];
|
||||
extern patch_t *gen_button_rb[2][2];
|
||||
extern patch_t *gen_button_lt[2][2];
|
||||
extern patch_t *gen_button_rt[2][2];
|
||||
extern patch_t *gen_button_start[2][2];
|
||||
extern patch_t *gen_button_back[2][2];
|
||||
extern patch_t *gen_button_ls[2][2];
|
||||
extern patch_t *gen_button_rs[2][2];
|
||||
extern patch_t *gen_button_dpad[2][2];
|
||||
|
||||
extern patch_t *gen_button_keyleft[2];
|
||||
extern patch_t *gen_button_keyright[2];
|
||||
extern patch_t *gen_button_keycenter[2];
|
||||
|
||||
extern patch_t *gen_button_keyleft[2];
|
||||
extern patch_t *gen_button_keyright[2];
|
||||
extern patch_t *gen_button_keycenter[2];
|
||||
|
||||
extern patch_t *kp_eggnum[6];
|
||||
extern patch_t *kp_facenum[MAXPLAYERS+1];
|
||||
|
|
@ -109,7 +133,7 @@ extern patch_t *kp_facenum[MAXPLAYERS+1];
|
|||
extern patch_t *kp_unknownminimap;
|
||||
|
||||
void K_AddMessage(const char *msg, boolean interrupt, boolean persist);
|
||||
void K_AddMessageForPlayer(const player_t *player, const char *msg, boolean interrupt, boolean persist);
|
||||
void K_AddMessageForPlayer(player_t *player, const char *msg, boolean interrupt, boolean persist);
|
||||
void K_ClearPersistentMessages(void);
|
||||
void K_ClearPersistentMessageForPlayer(player_t *player);
|
||||
void K_TickMessages(void);
|
||||
|
|
@ -133,6 +157,8 @@ INT32 K_GetMinimapTransFlags(const boolean usingProgressBar);
|
|||
INT32 K_GetMinimapSplitFlags(const boolean usingProgressBar);
|
||||
position_t K_GetKartObjectPosToMinimapPos(fixed_t objx, fixed_t objy);
|
||||
|
||||
INT32 K_DrawGameControl(UINT16 x, UINT16 y, UINT8 player, const char *str, UINT8 alignment, UINT8 font, UINT32 flags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -433,13 +433,18 @@ std::optional<TargetTracking::Tooltip> object_tooltip(const mobj_t* mobj)
|
|||
case MT_GARDENTOP:
|
||||
return conditional(
|
||||
mobj->tracer == stplyr->mo && Obj_GardenTopPlayerNeedsHelp(mobj),
|
||||
[&] { return TextElement("Try \xA7!").font(splitfont); }
|
||||
[&] { return TextElement().parse("Try <r>!").font(splitfont); }
|
||||
);
|
||||
|
||||
case MT_PLAYER:
|
||||
return conditional(
|
||||
mobj->player == stplyr && stplyr->icecube.frozen,
|
||||
[&] { return Tooltip(TextElement("\xA7")).offset3d(0, 0, 64 * mobj->scale * P_MobjFlip(mobj)); }
|
||||
[&] { return Tooltip(TextElement(
|
||||
(leveltime/(TICRATE/2)%2) ?
|
||||
TextElement().parse("<r_animated>").font(splitfont) :
|
||||
TextElement().parse("<a_animated>").font(splitfont)
|
||||
)).offset3d(0, 0, 64 * mobj->scale * P_MobjFlip(mobj)); }
|
||||
// I will be trying to figure out why the return value didn't accept a straightforward call to parse() for the rest of my life (apprx. 15 seconds)
|
||||
);
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -9502,7 +9502,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
if (!player->bigwaypointgap)
|
||||
K_DoIngameRespawn(player);
|
||||
else if (player->bigwaypointgap == AUTORESPAWN_THRESHOLD)
|
||||
K_AddMessageForPlayer(player, "Press \xAE to respawn", true, false);
|
||||
K_AddMessageForPlayer(player, "Press <y> to respawn", true, false);
|
||||
}
|
||||
|
||||
if (player->tripwireUnstuck && !player->mo->hitlag)
|
||||
|
|
|
|||
|
|
@ -1124,6 +1124,7 @@ extern consvar_t cv_dummyprofileplayername;
|
|||
extern consvar_t cv_dummyprofilekickstart;
|
||||
extern consvar_t cv_dummyprofileautoroulette;
|
||||
extern consvar_t cv_dummyprofilelitesteer;
|
||||
extern consvar_t cv_dummyprofiledescriptiveinput;
|
||||
extern consvar_t cv_dummyprofileautoring;
|
||||
extern consvar_t cv_dummyprofilerumble;
|
||||
extern consvar_t cv_dummyprofilefov;
|
||||
|
|
|
|||
212
src/k_menudraw.c
212
src/k_menudraw.c
|
|
@ -755,6 +755,8 @@ static void M_DrawMenuTyping(void)
|
|||
|
||||
}
|
||||
|
||||
// Largely replaced by boxed drawing mode in K_DrawGameControl and rich text
|
||||
/*
|
||||
static void M_DrawMediocreKeyboardKey(const char *text, INT32 *workx, INT32 worky, boolean push, boolean rightaligned)
|
||||
{
|
||||
INT32 buttonwidth = V_StringWidth(text, 0) + 2;
|
||||
|
|
@ -779,6 +781,7 @@ static void M_DrawMediocreKeyboardKey(const char *text, INT32 *workx, INT32 work
|
|||
0, text
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
// Draw the message popup submenu
|
||||
void M_DrawMenuMessage(void)
|
||||
|
|
@ -806,10 +809,6 @@ void M_DrawMenuMessage(void)
|
|||
INT32 workx = x + menumessage.x;
|
||||
INT32 worky = y + menumessage.y;
|
||||
|
||||
boolean standardbuttons = (
|
||||
cv_currprofile.value != -1 || G_GetNumAvailableGamepads()
|
||||
);
|
||||
|
||||
boolean push;
|
||||
|
||||
if (menumessage.closing)
|
||||
|
|
@ -830,27 +829,12 @@ void M_DrawMenuMessage(void)
|
|||
|
||||
workx -= 2;
|
||||
|
||||
if (standardbuttons)
|
||||
{
|
||||
workx -= SHORT(kp_button_x[1][0]->width);
|
||||
K_drawButton(
|
||||
workx * FRACUNIT, worky * FRACUNIT,
|
||||
0, kp_button_x[1],
|
||||
push
|
||||
workx -= K_DrawGameControl(
|
||||
workx+2, worky+2,
|
||||
0, "<b_animated> <x_animated> ",
|
||||
2, 8, 0
|
||||
);
|
||||
|
||||
workx -= SHORT(kp_button_b[1][0]->width);
|
||||
K_drawButton(
|
||||
workx * FRACUNIT, worky * FRACUNIT,
|
||||
0, kp_button_b[1],
|
||||
push
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
M_DrawMediocreKeyboardKey("ESC", &workx, worky, push, true);
|
||||
}
|
||||
|
||||
if (menumessage.confirmstr)
|
||||
{
|
||||
workx -= 12;
|
||||
|
|
@ -869,20 +853,12 @@ void M_DrawMenuMessage(void)
|
|||
workx -= 2;
|
||||
}
|
||||
|
||||
if (standardbuttons)
|
||||
{
|
||||
workx -= SHORT(kp_button_a[1][0]->width);
|
||||
K_drawButton(
|
||||
workx * FRACUNIT, worky * FRACUNIT,
|
||||
0, kp_button_a[1],
|
||||
push
|
||||
workx -= K_DrawGameControl(
|
||||
workx+2, worky+2,
|
||||
0, "<a_animated> ",
|
||||
2, 8, 0
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
M_DrawMediocreKeyboardKey("ENTER", &workx, worky, push, true);
|
||||
}
|
||||
}
|
||||
|
||||
x -= 4;
|
||||
y += 4;
|
||||
|
|
@ -1264,7 +1240,7 @@ static INT32 M_DrawRejoinIP(INT32 x, INT32 y, INT32 tx)
|
|||
V_DrawMenuString(x - 10 - (skullAnimCounter/5), y, f, "\x1C"); // left arrow
|
||||
V_DrawMenuString(x + w + 2+ (skullAnimCounter/5), y, f, "\x1D"); // right arrow
|
||||
V_DrawThinString(x, y, f, text);
|
||||
V_DrawRightAlignedThinString(BASEVIDWIDTH + 4 + tx, y, V_ORANGEMAP, "\xAC Rejoin");
|
||||
K_DrawGameControl(BASEVIDWIDTH + 4 + tx, y, 0, "<c> Rejoin", 2, 0, V_ORANGEMAP);
|
||||
|
||||
return shift;
|
||||
}
|
||||
|
|
@ -2462,19 +2438,16 @@ void M_DrawCharacterSelect(void)
|
|||
}
|
||||
|
||||
{
|
||||
const int kLeft = 76;
|
||||
const int kTop = 6;
|
||||
const int kButtonWidth = 16;
|
||||
INT32 x = basex + kLeft;
|
||||
|
||||
if (!optionsmenu.profile) // Does nothing on this screen
|
||||
{
|
||||
K_drawButton((x += 22) * FRACUNIT, (kTop - 3) * FRACUNIT, 0, kp_button_r, M_MenuButtonPressed(pid, MBT_R));
|
||||
V_DrawThinString((x += kButtonWidth), kTop, 0, "Info");
|
||||
K_DrawGameControl(BASEVIDWIDTH/2, kTop, pid, "<r_animated> Info <c_animated> Default", 1, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
K_DrawGameControl(BASEVIDWIDTH/2+62, kTop, pid, "<a_animated> Accept <x_animated> Back <c_animated> Default", 1, 0, 0);
|
||||
}
|
||||
|
||||
K_drawButton((x += 58) * FRACUNIT, (kTop - 1) * FRACUNIT, 0, kp_button_c[1], M_MenuButtonPressed(pid, MBT_C));
|
||||
V_DrawThinString((x += kButtonWidth), kTop, 0, "Default");
|
||||
}
|
||||
|
||||
// We have to loop twice -- first time to draw the drop shadows, a second time to draw the icons.
|
||||
|
|
@ -2584,6 +2557,11 @@ void M_DrawCharacterSelect(void)
|
|||
// Draw the priority player over the other ones
|
||||
M_DrawCharSelectCursor(priority);
|
||||
}
|
||||
|
||||
if (setup_numplayers > 1)
|
||||
{
|
||||
V_DrawCenteredThinString(BASEVIDWIDTH/2, BASEVIDHEIGHT-12, V_30TRANS, "\x85""Double-input problems?\x80 Close Steam, DS4Windows, and other controller wrappers!");
|
||||
}
|
||||
}
|
||||
|
||||
// DIFFICULTY SELECT
|
||||
|
|
@ -2744,21 +2722,16 @@ void M_DrawRaceDifficulty(void)
|
|||
V_DrawMappedPatch(cx, cy, 0, W_CachePatchName("OFF_TOGG", PU_CACHE), NULL);
|
||||
}
|
||||
|
||||
patch_t **bt = NULL;
|
||||
switch (it->mvar2)
|
||||
{
|
||||
case MBT_Y:
|
||||
bt = kp_button_y[1];
|
||||
K_DrawGameControl(cx + 24, cy + 22, 0, activated ? "<y_pressed>" : "<y>", 0, 8, 0);
|
||||
break;
|
||||
|
||||
case MBT_Z:
|
||||
bt = kp_button_z[1];
|
||||
K_DrawGameControl(cx + 24, cy + 22, 0, activated ? "<z_pressed>" : "<z>", 0, 8, 0);
|
||||
break;
|
||||
}
|
||||
if (bt)
|
||||
{
|
||||
K_drawButton((cx + 24) * FRACUNIT, (cy + 22) * FRACUNIT, 0, bt, activated);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -3662,7 +3635,7 @@ void M_DrawTimeAttack(void)
|
|||
|
||||
if (M_EncoreAttackTogglePermitted())
|
||||
{
|
||||
K_drawButtonAnim(buttonx + 35, buttony - 3, 0, kp_button_r, timeattackmenu.ticker);
|
||||
K_DrawGameControl(buttonx + 35, buttony - 3, 0, "<r_animated>", 0, 8, 0);
|
||||
}
|
||||
|
||||
if ((timeattackmenu.spbflicker == 0 || timeattackmenu.ticker % 2) == (cv_dummyspbattack.value == 1))
|
||||
|
|
@ -5008,6 +4981,8 @@ static void M_DrawBindMediumString(INT32 y, INT32 flags, const char *string)
|
|||
);
|
||||
}
|
||||
|
||||
// largely replaced by K_DrawGameControl
|
||||
/*
|
||||
static INT32 M_DrawProfileLegend(INT32 x, INT32 y, const char *legend, const char *mediocre_key)
|
||||
{
|
||||
INT32 w = V_ThinStringWidth(legend, 0);
|
||||
|
|
@ -5017,6 +4992,7 @@ static INT32 M_DrawProfileLegend(INT32 x, INT32 y, const char *legend, const cha
|
|||
M_DrawMediocreKeyboardKey(mediocre_key, &x, y, false, true);
|
||||
return x;
|
||||
}
|
||||
*/
|
||||
|
||||
// the control stuff.
|
||||
// Dear god.
|
||||
|
|
@ -5106,12 +5082,12 @@ void M_DrawProfileControls(void)
|
|||
V_DrawMenuString(x, y+2, (i == itemOn ? highlightflags : 0), currentMenu->menuitems[i].text);
|
||||
|
||||
if (currentMenu->menuitems[i].status & IT_CVAR) // not the proper way to check but this menu only has normal onoff cvars.
|
||||
{
|
||||
{ // (bitch you thought - Tyron 2024-09-22)
|
||||
INT32 w;
|
||||
consvar_t *cv = currentMenu->menuitems[i].itemaction.cvar;
|
||||
|
||||
w = V_MenuStringWidth(cv->string, 0);
|
||||
V_DrawMenuString(x + 12, y + 13, ((cv->flags & CV_CHEAT) && !CV_IsSetToDefault(cv) ? warningflags : highlightflags), cv->string);
|
||||
V_DrawMenuString(x + 12, y + 13, (!CV_IsSetToDefault(cv) ? warningflags : highlightflags), cv->string);
|
||||
if (i == itemOn)
|
||||
{
|
||||
V_DrawMenuString(x - (skullAnimCounter/5), y+12, highlightflags, "\x1C"); // left arrow
|
||||
|
|
@ -5300,13 +5276,50 @@ void M_DrawProfileControls(void)
|
|||
if (currentMenu->menuitems[itemOn].tooltip != NULL)
|
||||
{
|
||||
INT32 ypos = BASEVIDHEIGHT + hintofs - 9 - 12;
|
||||
V_DrawThinString(12, ypos, V_YELLOWMAP, currentMenu->menuitems[itemOn].tooltip);
|
||||
|
||||
boolean standardbuttons = gamedata->gonerlevel > GDGONER_PROFILE;
|
||||
if (!strcmp(currentMenu->menuitems[itemOn].tooltip, "DESCRIPTIVEINPUT-SENTINEL"))
|
||||
{
|
||||
char* help = va("Modern: Standard console controller/keyboard prompts.");
|
||||
switch (cv_dummyprofiledescriptiveinput.value)
|
||||
{
|
||||
case 0:
|
||||
help = va("\"Emulator\": Display the default (Saturn) controls.");
|
||||
break;
|
||||
case 2:
|
||||
help = va("Modern Flip: Swap A+X/B+Y. Use if Modern is wrong.");
|
||||
break;
|
||||
case 3:
|
||||
help = va("6Bt. (Auto): Tries to guess your 6-button pad's layout.");
|
||||
break;
|
||||
case 4:
|
||||
help = va("6Bt. (A): Saturn buttons, Retro-Bit Wired DInput layout.");
|
||||
break;
|
||||
case 5:
|
||||
help = va("6Bt. (B): Saturn buttons, Retro-Bit Wireless DInput layout.");
|
||||
break;
|
||||
case 6:
|
||||
help = va("6Bt. (C): Saturn buttons, Retro-Bit XInput layout.");
|
||||
break;
|
||||
case 7:
|
||||
help = va("6Bt. (D): Saturn buttons, arcade/8BitDo layout. (C/Z = RT/RB)");
|
||||
break;
|
||||
case 8:
|
||||
help = va("6Bt. (E): Saturn buttons, Hori/M30X layout. (LB/LT = LS/RS)");
|
||||
break;
|
||||
}
|
||||
|
||||
V_DrawThinString(12, ypos, V_YELLOWMAP, help);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawThinString(12, ypos, V_YELLOWMAP, currentMenu->menuitems[itemOn].tooltip);
|
||||
}
|
||||
|
||||
UINT16 oldsetting = cv_descriptiveinput->value;
|
||||
CV_StealthSetValue(cv_descriptiveinput, cv_dummyprofiledescriptiveinput.value);
|
||||
INT32 xpos = BASEVIDWIDTH - 12;
|
||||
xpos = standardbuttons ?
|
||||
M_DrawProfileLegend(xpos, ypos, "\xB2 / \xBC Clear", NULL) :
|
||||
M_DrawProfileLegend(xpos, ypos, "Clear", "BKSP");
|
||||
xpos = K_DrawGameControl(xpos, ypos, 0, "<right> / <c> Clear", 2, 0, 0);
|
||||
CV_StealthSetValue(cv_descriptiveinput, oldsetting);
|
||||
}
|
||||
|
||||
// Overlay for control binding
|
||||
|
|
@ -6093,6 +6106,19 @@ void M_DrawPause(void)
|
|||
|
||||
Y_RoundQueueDrawer(&standings, offset/2, false, false);
|
||||
}
|
||||
else if (gametype == GT_TUTORIAL)
|
||||
{
|
||||
K_DrawGameControl(4, 184 - 60 + offset/2, 0, "<left> <right> <up> <down> Steering", 0, 0, 0);
|
||||
K_DrawGameControl(4, 184 - 45 + offset/2, 0, "<a> Accelerate", 0, 0, 0);
|
||||
K_DrawGameControl(4, 184 - 30 + offset/2, 0, "<b> Look Back", 0, 0, 0);
|
||||
K_DrawGameControl(4, 184 - 15 + offset/2, 0, "<c> Spindash", 0, 0, 0);
|
||||
K_DrawGameControl(4, 184 - 0 + offset/2, 0, "<l> Item/Rings", 0, 0, 0);
|
||||
|
||||
K_DrawGameControl(90, 184 - 45 + offset/2, 0, "<x> Brake", 0, 0, 0);
|
||||
K_DrawGameControl(90, 184 - 30 + offset/2, 0, "<y> Respawn", 0, 0, 0);
|
||||
K_DrawGameControl(90, 184 - 15 + offset/2, 0, "<z> Dialogue / Action", 0, 0, 0);
|
||||
K_DrawGameControl(90, 184 - 0 + offset/2, 0, "<r> Drift", 0, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawMenuString(4, 188 + offset/2, V_YELLOWMAP, M_GetGameplayMode());
|
||||
|
|
@ -6190,12 +6216,12 @@ void M_DrawKickHandler(void)
|
|||
//V_DrawFill(32 + (playerkickmenu.player & 8), 32 + (playerkickmenu.player & 7)*8, 8, 8, playeringame[playerkickmenu.player] ? 0 : 16);
|
||||
|
||||
V_DrawFixedPatch(0, 0, FRACUNIT, 0, W_CachePatchName("MENUHINT", PU_CACHE), NULL);
|
||||
V_DrawCenteredThinString(
|
||||
BASEVIDWIDTH/2, 12,
|
||||
0,
|
||||
K_DrawGameControl(
|
||||
BASEVIDWIDTH/2, 12, 0,
|
||||
(playerkickmenu.adminpowered)
|
||||
? "You are using ""\x85""Admin Tools""\x80"", ""\x83""(A)""\x80"" to kick and ""\x84""(C)""\x80"" to ban"
|
||||
: K_GetMidVoteLabel(menucallvote)
|
||||
? "You are using <red>Admin Tools<white>. <a> Kick <c> Ban"
|
||||
: K_GetMidVoteLabel(menucallvote),
|
||||
1, 0, 0
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -7262,9 +7288,10 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
|
|||
y = BASEVIDHEIGHT-16;
|
||||
V_DrawGamemodeString(x, y - 33, 0, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_MENUCACHE), M_UseAlternateTitleScreen() ? "On" : "Off");
|
||||
|
||||
K_drawButtonAnim(x, y, 0, kp_button_a[1], challengesmenu.ticker);
|
||||
x += SHORT(kp_button_a[1][0]->width);
|
||||
V_DrawThinString(x, y + 1, highlightflags, "Toggle");
|
||||
K_DrawGameControl(x, y, 0, "<a_animated> Toggle", 0, 0, 0);
|
||||
// K_drawButtonAnim(x, y, 0, kp_button_a[1], challengesmenu.ticker);
|
||||
// x += SHORT(kp_button_a[1][0]->width);
|
||||
// V_DrawThinString(x, y + 1, highlightflags, "Toggle");
|
||||
|
||||
|
||||
break;
|
||||
|
|
@ -7327,9 +7354,13 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
|
|||
pushed = strcmp(song, mapheaderinfo[map]->encoremusname[musicid]) == 0;
|
||||
}
|
||||
|
||||
K_drawButton(x&FRACUNIT, y*FRACUNIT, 0, kp_button_l, pushed);
|
||||
x += SHORT(kp_button_l[0]->width);
|
||||
V_DrawThinString(x, y + 1, (pushed ? V_GRAYMAP : highlightflags), "E Side");
|
||||
if (!pushed)
|
||||
K_DrawGameControl(x, y, 0, "<l> <sky>E Side", 0, 0, 0);
|
||||
else
|
||||
K_DrawGameControl(x, y, 0, "<l_pressed> <gray>E Side", 0, 0, 0);
|
||||
// K_drawButton(x&FRACUNIT, y*FRACUNIT, 0, kp_button_l, pushed);
|
||||
// x += SHORT(kp_button_l[0]->width);
|
||||
// V_DrawThinString(x, y + 1, (pushed ? V_GRAYMAP : highlightflags), "E Side");
|
||||
|
||||
x = 8;
|
||||
y -= 10;
|
||||
|
|
@ -7348,9 +7379,13 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
|
|||
pushed = strcmp(song, mapheaderinfo[map]->musname[musicid]) == 0;
|
||||
}
|
||||
|
||||
K_drawButton(x*FRACUNIT, y*FRACUNIT, 0, kp_button_a[1], pushed);
|
||||
x += SHORT(kp_button_a[1][0]->width);
|
||||
V_DrawThinString(x, y + 1, (pushed ? V_GRAYMAP : highlightflags), "Play CD");
|
||||
if (!pushed)
|
||||
K_DrawGameControl(x, y, 0, "<a> <sky>Play CD", 0, 0, 0);
|
||||
else
|
||||
K_DrawGameControl(x, y, 0, "<a_pressed> <gray>Play CD", 0, 0, 0);
|
||||
// K_drawButton(x*FRACUNIT, y*FRACUNIT, 0, kp_button_a[1], pushed);
|
||||
// x += SHORT(kp_button_a[1][0]->width);
|
||||
// V_DrawThinString(x, y + 1, (pushed ? V_GRAYMAP : highlightflags), "Play CD");
|
||||
}
|
||||
}
|
||||
default:
|
||||
|
|
@ -7427,11 +7462,10 @@ static void M_DrawChallengeKeys(INT32 tilex, INT32 tiley)
|
|||
const boolean keybuttonpress = (menumessage.active == false && M_MenuExtraHeld(pid) == true);
|
||||
|
||||
// Button prompt
|
||||
K_drawButton(
|
||||
24 << FRACBITS,
|
||||
16 << FRACBITS,
|
||||
0, kp_button_c[1],
|
||||
keybuttonpress
|
||||
K_DrawGameControl(
|
||||
24, 16,
|
||||
0, keybuttonpress ? "<c_pressed>" : "<c>",
|
||||
0, 0, 0
|
||||
);
|
||||
|
||||
// Metyr of rounds played that contribute to Chao Key generation
|
||||
|
|
@ -9092,8 +9126,6 @@ void M_DrawDiscordRequests(void)
|
|||
patch_t *hand = NULL;
|
||||
|
||||
const char *wantText = "...would like to join!";
|
||||
const char *acceptText = "Accept" ;
|
||||
const char *declineText = "Decline";
|
||||
|
||||
INT32 x = 100;
|
||||
INT32 y = 133;
|
||||
|
|
@ -9135,29 +9167,31 @@ void M_DrawDiscordRequests(void)
|
|||
K_DrawSticker(x, y + 12, V_ThinStringWidth(wantText, 0), 0, true);
|
||||
V_DrawThinString(x, y + 10, 0, wantText);
|
||||
|
||||
INT32 confirmButtonWidth = SHORT(kp_button_a[1][0]->width);
|
||||
INT32 declineButtonWidth = SHORT(kp_button_b[1][0]->width);
|
||||
INT32 altDeclineButtonWidth = SHORT(kp_button_x[1][0]->width);
|
||||
INT32 acceptTextWidth = V_ThinStringWidth(acceptText, 0);
|
||||
INT32 declineTextWidth = V_ThinStringWidth(declineText, 0);
|
||||
INT32 stickerWidth = (confirmButtonWidth + declineButtonWidth + altDeclineButtonWidth + acceptTextWidth + declineTextWidth);
|
||||
|
||||
/*
|
||||
K_DrawSticker(x, y + 26, stickerWidth, 0, true);
|
||||
K_drawButtonAnim(x, y + 22, V_SNAPTORIGHT, kp_button_a[1], discordrequestmenu.ticker);
|
||||
K_DrawGameControl(x, y+22, 0, "<a_animated>", 0, 0, V_SNAPTORIGHT);
|
||||
// K_drawButtonAnim(x, y + 22, V_SNAPTORIGHT, kp_button_a[1], discordrequestmenu.ticker);
|
||||
*/
|
||||
|
||||
INT32 xoffs = confirmButtonWidth;
|
||||
UINT32 bigwidth = K_DrawGameControl(x, y+22, 0, "<a_animated> Accept <b_animated> <x_animated> Decline", 0, 0, V_SNAPTORIGHT);
|
||||
K_DrawSticker(x, y + 26, bigwidth, 0, true);
|
||||
K_DrawGameControl(x, y+22, 0, "<a_animated> Accept <b_animated> <x_animated> Decline", 0, 0, V_SNAPTORIGHT);
|
||||
|
||||
/*
|
||||
V_DrawThinString((x + xoffs), y + 24, 0, acceptText);
|
||||
xoffs += acceptTextWidth;
|
||||
|
||||
K_drawButtonAnim((x + xoffs), y + 22, V_SNAPTORIGHT, kp_button_b[1], discordrequestmenu.ticker);
|
||||
xoffs += declineButtonWidth;
|
||||
|
||||
xoffs += K_DrawGameControl(x + xoffs, y+22, 0, "<x_animated>", 0, 0, V_SNAPTORIGHT);
|
||||
K_drawButtonAnim((x + xoffs), y + 22, V_SNAPTORIGHT, kp_button_x[1], discordrequestmenu.ticker);
|
||||
xoffs += altDeclineButtonWidth;
|
||||
|
||||
V_DrawThinString((x + xoffs), y + 24, 0, declineText);
|
||||
|
||||
*/
|
||||
|
||||
y -= 18;
|
||||
|
||||
while (curRequest->next != NULL)
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ profile_t* PR_MakeProfile(
|
|||
newprofile->kickstartaccel = false;
|
||||
newprofile->autoroulette = false;
|
||||
newprofile->litesteer = false;
|
||||
newprofile->descriptiveinput = 1;
|
||||
newprofile->autoring = false;
|
||||
newprofile->rumble = true;
|
||||
newprofile->fov = atoi(cv_dummyprofilefov.defaultvalue);
|
||||
|
|
@ -104,6 +105,7 @@ profile_t* PR_MakeProfileFromPlayer(const char *prname, const char *pname, const
|
|||
newprofile->kickstartaccel = cv_kickstartaccel[pnum].value;
|
||||
newprofile->autoroulette = cv_autoroulette[pnum].value;
|
||||
newprofile->litesteer = cv_litesteer[pnum].value;
|
||||
newprofile->descriptiveinput = cv_descriptiveinput[pnum].value;
|
||||
newprofile->autoring = cv_autoring[pnum].value;
|
||||
newprofile->rumble = cv_rumble[pnum].value;
|
||||
newprofile->fov = cv_fov[pnum].value / FRACUNIT;
|
||||
|
|
@ -301,6 +303,7 @@ void PR_SaveProfiles(void)
|
|||
jsonprof.preferences.kickstartaccel = cprof->kickstartaccel;
|
||||
jsonprof.preferences.autoroulette = cprof->autoroulette;
|
||||
jsonprof.preferences.litesteer = cprof->litesteer;
|
||||
jsonprof.preferences.descriptiveinput = cprof->descriptiveinput;
|
||||
jsonprof.preferences.autoring = cprof->autoring;
|
||||
jsonprof.preferences.rumble = cprof->rumble;
|
||||
jsonprof.preferences.fov = cprof->fov;
|
||||
|
|
@ -486,6 +489,7 @@ void PR_LoadProfiles(void)
|
|||
newprof->kickstartaccel = jsprof.preferences.kickstartaccel;
|
||||
newprof->autoroulette = jsprof.preferences.autoroulette;
|
||||
newprof->litesteer = jsprof.preferences.litesteer;
|
||||
newprof->descriptiveinput = jsprof.preferences.descriptiveinput;
|
||||
newprof->autoring = jsprof.preferences.autoring;
|
||||
newprof->rumble = jsprof.preferences.rumble;
|
||||
newprof->fov = jsprof.preferences.fov;
|
||||
|
|
@ -541,6 +545,12 @@ void PR_LoadProfiles(void)
|
|||
converted = true;
|
||||
}
|
||||
|
||||
if (jsprof.version < 4)
|
||||
{
|
||||
newprof->descriptiveinput = 1;
|
||||
converted = true;
|
||||
}
|
||||
|
||||
if (converted)
|
||||
{
|
||||
CONS_Printf("Profile '%s' was converted from version %d to version %d\n",
|
||||
|
|
@ -568,6 +578,7 @@ static void PR_ApplyProfile_Settings(profile_t *p, UINT8 playernum)
|
|||
CV_StealthSetValue(&cv_kickstartaccel[playernum], p->kickstartaccel);
|
||||
CV_StealthSetValue(&cv_autoroulette[playernum], p->autoroulette);
|
||||
CV_StealthSetValue(&cv_litesteer[playernum], p->litesteer);
|
||||
CV_StealthSetValue(&cv_descriptiveinput[playernum], p->descriptiveinput);
|
||||
CV_StealthSetValue(&cv_autoring[playernum], p->autoring);
|
||||
CV_StealthSetValue(&cv_rumble[playernum], p->rumble);
|
||||
CV_StealthSetValue(&cv_fov[playernum], p->fov);
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ struct ProfilePreferencesJson
|
|||
bool kickstartaccel;
|
||||
bool autoroulette;
|
||||
bool litesteer;
|
||||
uint8_t descriptiveinput;
|
||||
bool autoring;
|
||||
bool rumble;
|
||||
uint8_t fov;
|
||||
|
|
@ -56,6 +57,7 @@ struct ProfilePreferencesJson
|
|||
kickstartaccel,
|
||||
autoroulette,
|
||||
litesteer,
|
||||
descriptiveinput,
|
||||
autoring,
|
||||
rumble,
|
||||
fov
|
||||
|
|
@ -116,7 +118,8 @@ extern "C" {
|
|||
// 2 - litesteer is off by default, old profiles litesteer
|
||||
// 3 - auto roulette is switched off again
|
||||
// option is reset to default
|
||||
#define PROFILEVER 3
|
||||
// 4 - Descriptive Input - set everyone to Modern!
|
||||
#define PROFILEVER 4
|
||||
#define MAXPROFILES 16
|
||||
#define PROFILESFILE "ringprofiles.prf"
|
||||
#define PROFILE_GUEST 0
|
||||
|
|
@ -162,6 +165,7 @@ struct profile_t
|
|||
boolean kickstartaccel; // cv_kickstartaccel
|
||||
boolean autoroulette; // cv_autoroulette
|
||||
boolean litesteer; // cv_litesteer
|
||||
UINT8 descriptiveinput; // cv_descriptiveinput
|
||||
boolean autoring; // cv_autoring
|
||||
boolean rumble; // cv_rumble
|
||||
UINT8 fov; // cv_fov
|
||||
|
|
|
|||
|
|
@ -1103,12 +1103,19 @@ void K_DrawMidVote(void)
|
|||
V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SPLITSCREEN,
|
||||
exc, NULL
|
||||
);
|
||||
K_DrawGameControl(
|
||||
x/FRACUNIT - 4, y/FRACUNIT + exc->height - 8,
|
||||
id, pressed ? "<z_pressed>" : "<z>",
|
||||
0, 8, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SPLITSCREEN
|
||||
);
|
||||
/*
|
||||
K_drawButton(
|
||||
x - (4 * FRACUNIT),
|
||||
y + ((exc->height - kp_button_z[1][0]->height) * FRACUNIT),
|
||||
V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SPLITSCREEN,
|
||||
kp_button_z[1], pressed
|
||||
);
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1219,12 +1226,19 @@ void K_DrawMidVote(void)
|
|||
|
||||
if (drawButton == true)
|
||||
{
|
||||
K_DrawGameControl(
|
||||
x/FRACUNIT-20, y/FRACUNIT + 2, id,
|
||||
pressed ? "<z_pressed>" : "<z>",
|
||||
0, 8, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SPLITSCREEN
|
||||
);
|
||||
/*
|
||||
K_drawButton(
|
||||
x - (20 * FRACUNIT),
|
||||
y - (2 * FRACUNIT),
|
||||
V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SPLITSCREEN,
|
||||
kp_button_z[0], pressed
|
||||
);
|
||||
*/
|
||||
}
|
||||
|
||||
// Vote count
|
||||
|
|
|
|||
|
|
@ -964,6 +964,21 @@ static int libd_stringWidth(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int libd_parseText(lua_State *L)
|
||||
{
|
||||
HUDONLY
|
||||
|
||||
const char *rawText = luaL_checkstring(L, 1);
|
||||
|
||||
if (!rawText)
|
||||
return luaL_error(L, "no string provided to v.parseText");
|
||||
|
||||
char *newText = V_ParseText(rawText);
|
||||
lua_pushstring(gL, newText);
|
||||
Z_Free(newText);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int libd_getColormap(lua_State *L)
|
||||
{
|
||||
INT32 skinnum = TC_DEFAULT;
|
||||
|
|
@ -1162,6 +1177,7 @@ static luaL_Reg lib_draw[] = {
|
|||
// misc
|
||||
{"stringWidth", libd_stringWidth},
|
||||
{"titleCardStringWidth", libd_titleCardStringWidth},
|
||||
{"parseText", libd_parseText},
|
||||
// m_random
|
||||
{"RandomFixed",libd_RandomFixed},
|
||||
{"RandomByte",libd_RandomByte},
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ void M_StartEditProfile(INT32 c)
|
|||
CV_StealthSetValue(&cv_dummyprofilekickstart, optionsmenu.profile->kickstartaccel);
|
||||
CV_StealthSetValue(&cv_dummyprofileautoroulette, optionsmenu.profile->autoroulette);
|
||||
CV_StealthSetValue(&cv_dummyprofilelitesteer, optionsmenu.profile->litesteer);
|
||||
CV_StealthSetValue(&cv_dummyprofiledescriptiveinput, optionsmenu.profile->descriptiveinput);
|
||||
CV_StealthSetValue(&cv_dummyprofileautoring, optionsmenu.profile->autoring);
|
||||
CV_StealthSetValue(&cv_dummyprofilerumble, optionsmenu.profile->rumble);
|
||||
CV_StealthSetValue(&cv_dummyprofilefov, optionsmenu.profile->fov);
|
||||
|
|
@ -113,6 +114,7 @@ void M_StartEditProfile(INT32 c)
|
|||
CV_StealthSetValue(&cv_dummyprofilekickstart, 0); // off
|
||||
CV_StealthSetValue(&cv_dummyprofileautoroulette, 0); // off
|
||||
CV_StealthSetValue(&cv_dummyprofilelitesteer, 1); // on
|
||||
CV_StealthSetValue(&cv_dummyprofiledescriptiveinput, 1); // Modern
|
||||
CV_StealthSetValue(&cv_dummyprofileautoring, 0); // on
|
||||
CV_StealthSetValue(&cv_dummyprofilerumble, 1); // on
|
||||
CV_StealthSetValue(&cv_dummyprofilefov, 90);
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ static void M_ProfileEditApply(void)
|
|||
optionsmenu.profile->kickstartaccel = cv_dummyprofilekickstart.value;
|
||||
optionsmenu.profile->autoroulette = cv_dummyprofileautoroulette.value;
|
||||
optionsmenu.profile->litesteer = cv_dummyprofilelitesteer.value;
|
||||
optionsmenu.profile->descriptiveinput = cv_dummyprofiledescriptiveinput.value;
|
||||
optionsmenu.profile->autoring = cv_dummyprofileautoring.value;
|
||||
optionsmenu.profile->rumble = cv_dummyprofilerumble.value;
|
||||
optionsmenu.profile->fov = cv_dummyprofilefov.value;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,12 @@
|
|||
|
||||
menuitem_t OPTIONS_ProfileControls[] = {
|
||||
|
||||
{IT_HEADER, "DEVICE SETTINGS", "",
|
||||
NULL, {NULL}, 0, 0},
|
||||
|
||||
{IT_STRING2 | IT_CVAR, "Button Display", "DESCRIPTIVEINPUT-SENTINEL",
|
||||
NULL, {.cvar = &cv_dummyprofiledescriptiveinput}, 0, 0},
|
||||
|
||||
{IT_HEADER, "MAIN CONTROLS", "That's the stuff on the controller!!",
|
||||
NULL, {NULL}, 0, 0},
|
||||
|
||||
|
|
@ -31,34 +37,34 @@ menuitem_t OPTIONS_ProfileControls[] = {
|
|||
"TLB_C", {.routine = M_ProfileSetControl}, gc_c, 0},
|
||||
|
||||
{IT_CONTROL, "Brake / Go back", "Brake / Go back",
|
||||
"TLB_D", {.routine = M_ProfileSetControl}, gc_x, 0},
|
||||
"TLB_X", {.routine = M_ProfileSetControl}, gc_x, 0},
|
||||
|
||||
{IT_CONTROL, "Respawn", "Respawn",
|
||||
"TLB_E", {.routine = M_ProfileSetControl}, gc_y, 0},
|
||||
"TLB_Y", {.routine = M_ProfileSetControl}, gc_y, 0},
|
||||
|
||||
{IT_CONTROL, "Action", "Multiplayer quick-chat / quick-vote",
|
||||
"TLB_F", {.routine = M_ProfileSetControl}, gc_z, 0},
|
||||
"TLB_Z", {.routine = M_ProfileSetControl}, gc_z, 0},
|
||||
|
||||
{IT_CONTROL, "Use Item", "Use item",
|
||||
"TLB_H", {.routine = M_ProfileSetControl}, gc_l, 0},
|
||||
"TLB_L1", {.routine = M_ProfileSetControl}, gc_l, 0},
|
||||
|
||||
{IT_CONTROL, "Drift", "Drift",
|
||||
"TLB_I", {.routine = M_ProfileSetControl}, gc_r, 0},
|
||||
"TLB_R1", {.routine = M_ProfileSetControl}, gc_r, 0},
|
||||
|
||||
{IT_CONTROL, "Turn Left", "Turn left",
|
||||
"TLB_M", {.routine = M_ProfileSetControl}, gc_left, 0},
|
||||
"TLB_ARL", {.routine = M_ProfileSetControl}, gc_left, 0},
|
||||
|
||||
{IT_CONTROL, "Turn Right", "Turn right",
|
||||
"TLB_L", {.routine = M_ProfileSetControl}, gc_right, 0},
|
||||
"TLB_ARR", {.routine = M_ProfileSetControl}, gc_right, 0},
|
||||
|
||||
{IT_CONTROL, "Aim Forward", "Aim forwards",
|
||||
"TLB_J", {.routine = M_ProfileSetControl}, gc_up, 0},
|
||||
"TLB_ARU", {.routine = M_ProfileSetControl}, gc_up, 0},
|
||||
|
||||
{IT_CONTROL, "Aim Backwards", "Aim backwards",
|
||||
"TLB_K", {.routine = M_ProfileSetControl}, gc_down, 0},
|
||||
"TLB_ARD", {.routine = M_ProfileSetControl}, gc_down, 0},
|
||||
|
||||
{IT_CONTROL, "Open pause menu", "Open pause menu",
|
||||
"TLB_G", {.routine = M_ProfileSetControl}, gc_start, 0},
|
||||
"TLB_S", {.routine = M_ProfileSetControl}, gc_start, 0},
|
||||
|
||||
{IT_HEADER, "OPTIONAL CONTROLS", "Take a screenshot, chat...",
|
||||
NULL, {NULL}, 0, 0},
|
||||
|
|
@ -81,14 +87,14 @@ menuitem_t OPTIONS_ProfileControls[] = {
|
|||
{IT_CONTROL, "OPEN TEAM CHAT", "Opens team-only full chat for online games.",
|
||||
NULL, {.routine = M_ProfileSetControl}, gc_teamtalk, 0},
|
||||
|
||||
{IT_CONTROL, "LUA/A", "May be used by add-ons.",
|
||||
NULL, {.routine = M_ProfileSetControl}, gc_luaa, 0},
|
||||
{IT_CONTROL, "LUA/1", "May be used by add-ons.",
|
||||
NULL, {.routine = M_ProfileSetControl}, gc_lua1, 0},
|
||||
|
||||
{IT_CONTROL, "LUA/B", "May be used by add-ons.",
|
||||
NULL, {.routine = M_ProfileSetControl}, gc_luab, 0},
|
||||
{IT_CONTROL, "LUA/2", "May be used by add-ons.",
|
||||
NULL, {.routine = M_ProfileSetControl}, gc_lua2, 0},
|
||||
|
||||
{IT_CONTROL, "LUA/C", "May be used by add-ons.",
|
||||
NULL, {.routine = M_ProfileSetControl}, gc_luac, 0},
|
||||
{IT_CONTROL, "LUA/3", "May be used by add-ons.",
|
||||
NULL, {.routine = M_ProfileSetControl}, gc_lua3, 0},
|
||||
|
||||
{IT_CONTROL, "OPEN CONSOLE", "Opens the developer options console.",
|
||||
NULL, {.routine = M_ProfileSetControl}, gc_console, 0},
|
||||
|
|
|
|||
|
|
@ -29,12 +29,6 @@ using srb2::Draw;
|
|||
namespace
|
||||
{
|
||||
|
||||
bool basic_options()
|
||||
{
|
||||
// M_GameTrulyStarted
|
||||
return gamedata && gamestartchallenge < MAXUNLOCKABLES && !netgame && gamedata->gonerlevel <= GDGONER_PROFILE;
|
||||
}
|
||||
|
||||
int flip_delay = 0;
|
||||
|
||||
struct Slider
|
||||
|
|
@ -68,10 +62,8 @@ struct Slider
|
|||
arrows.x(-10 - ofs).text("\x1C");
|
||||
arrows.x(kWidth + 2 + ofs).text("\x1D");
|
||||
|
||||
if (!basic_options())
|
||||
{
|
||||
h.xy(kWidth + 9, -3).small_button(Draw::Button::z, false);
|
||||
}
|
||||
Draw::TextElement tx = Draw::TextElement().parse("<z_animated>");
|
||||
h.xy(kWidth + 9, -2).text(tx.string());
|
||||
}
|
||||
|
||||
h = h.y(1);
|
||||
|
|
@ -251,7 +243,7 @@ boolean input_routine(INT32)
|
|||
|
||||
const menuitem_t& it = currentMenu->menuitems[itemOn];
|
||||
|
||||
if (M_MenuButtonPressed(pid, MBT_Z) && (it.status & IT_TYPE) == IT_ARROWS && !basic_options())
|
||||
if (M_MenuButtonPressed(pid, MBT_Z) && (it.status & IT_TYPE) == IT_ARROWS)
|
||||
{
|
||||
sliders.at(it.mvar2).toggle_(true);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ void list_commands()
|
|||
if (flags & COM_NOSHOWHELP)
|
||||
continue;
|
||||
|
||||
g_menu.push_back(menuitem_t {IT_STRING | IT_CALL, cmd->name, "Press \xAA to execute this command", nullptr, {.routine = call}, 0, 8});
|
||||
g_menu.push_back(menuitem_t {IT_STRING | IT_CALL, cmd->name, "No information available for commands. Press to execute.", nullptr, {.routine = call}, 0, 8});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -264,7 +264,8 @@ void draw_menu()
|
|||
|
||||
draw.x(BASEVIDWIDTH/2).font(Draw::Font::kGamemode).text(mode_strings[menu_mode()]);
|
||||
if (server || IsPlayerAdmin(consoleplayer))
|
||||
K_drawButton((draw.x() + 8) * FRACUNIT, (draw.y() + 8) * FRACUNIT, 0, kp_button_y[0], M_MenuButtonHeld(0, MBT_Y));
|
||||
K_DrawGameControl(draw.x() + 8, draw.y()-6, 0, M_MenuButtonHeld(0, MBT_Y) ? "<y_pressed> Switch Page" : "<y> Switch Page", 0, 8, 0);
|
||||
// K_drawButton((draw.x() + 8) * FRACUNIT, (draw.y() + 8) * FRACUNIT, 0, kp_button_y[0], M_MenuButtonHeld(0, MBT_Y));
|
||||
draw = draw.y(32 + kMargin);
|
||||
|
||||
currentMenu->y = std::min(static_cast<INT32>(draw.y()), (BASEVIDHEIGHT/2) - g_menu_offsets[itemOn]);
|
||||
|
|
|
|||
|
|
@ -208,7 +208,8 @@ void draw_menu()
|
|||
draw = draw.y(27 + kMargin);
|
||||
|
||||
draw.x(BASEVIDWIDTH/2).font(Draw::Font::kGamemode).text(mode_strings[menu_mode()]);
|
||||
K_drawButton((draw.x() + 8) * FRACUNIT, (draw.y() + 8) * FRACUNIT, 0, kp_button_y[0], M_MenuButtonHeld(0, MBT_Y));
|
||||
K_DrawGameControl(draw.x() + 8, draw.y()-6, 0, M_MenuButtonHeld(0, MBT_Y) ? "<y_pressed> Switch Page" : "<y> Switch Page", 0, 8, 0);
|
||||
// K_drawButton((draw.x() + 8) * FRACUNIT, (draw.y() + 8) * FRACUNIT, 0, kp_button_y[0], M_MenuButtonHeld(0, MBT_Y));
|
||||
draw = draw.y(32 + kMargin);
|
||||
|
||||
currentMenu->y = std::min(static_cast<INT32>(draw.y()), (BASEVIDHEIGHT/2) - g_menu_offsets[itemOn]);
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ extern consvar_t cv_drawpickups;
|
|||
extern consvar_t cv_debugfinishline;
|
||||
extern consvar_t cv_drawinput;
|
||||
extern consvar_t cv_drawtimer;
|
||||
extern consvar_t cv_debugfonts;
|
||||
|
||||
// debugging
|
||||
|
||||
|
|
|
|||
|
|
@ -1498,10 +1498,10 @@ void ST_DrawServerSplash(boolean timelimited)
|
|||
|
||||
void ST_DrawSaveReplayHint(INT32 flags)
|
||||
{
|
||||
V_DrawRightAlignedThinString(
|
||||
BASEVIDWIDTH - 2, 2,
|
||||
flags|V_YELLOWMAP,
|
||||
(demo.willsave && demo.titlename[0]) ? "Replay will be saved. \xAB Change title" : "\xAB or \xAD Save replay"
|
||||
K_DrawGameControl(
|
||||
BASEVIDWIDTH - 2, 2, 0,
|
||||
(demo.willsave && demo.titlename[0]) ? "Replay will be saved. <b> Change title" : "<b> or <x> Save replay",
|
||||
2, 0, flags|V_YELLOWMAP
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
288
src/v_draw.cpp
288
src/v_draw.cpp
|
|
@ -21,6 +21,8 @@
|
|||
#include "v_video.h"
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
#include "k_profiles.h" // controls
|
||||
#include "p_local.h" // stplyr
|
||||
|
||||
using srb2::Draw;
|
||||
using Chain = Draw::Chain;
|
||||
|
|
@ -38,27 +40,35 @@ Draw::TextElement& Draw::TextElement::parse(std::string_view raw)
|
|||
{str "_animated", 0xA0 | lower_bits},\
|
||||
{str "_pressed", 0x90 | lower_bits}
|
||||
|
||||
BUTTON("up", 0x00),
|
||||
BUTTON("down", 0x01),
|
||||
BUTTON("right", 0x02),
|
||||
BUTTON("left", 0x03),
|
||||
BUTTON("up", sb_up),
|
||||
BUTTON("down", sb_down),
|
||||
BUTTON("right", sb_right),
|
||||
BUTTON("left", sb_left),
|
||||
|
||||
BUTTON("dpad", 0x04),
|
||||
BUTTON("lua1", sb_lua1),
|
||||
BUTTON("lua2", sb_lua2),
|
||||
BUTTON("lua3", sb_lua3),
|
||||
|
||||
BUTTON("r", 0x07),
|
||||
BUTTON("l", 0x08),
|
||||
BUTTON("start", 0x09),
|
||||
BUTTON("r", sb_r),
|
||||
BUTTON("l", sb_l),
|
||||
BUTTON("start", sb_start),
|
||||
|
||||
BUTTON("a", 0x0A),
|
||||
BUTTON("b", 0x0B),
|
||||
BUTTON("c", 0x0C),
|
||||
BUTTON("a", sb_a),
|
||||
BUTTON("b", sb_b),
|
||||
BUTTON("c", sb_c),
|
||||
|
||||
BUTTON("x", 0x0D),
|
||||
BUTTON("y", 0x0E),
|
||||
BUTTON("z", 0x0F),
|
||||
BUTTON("x", sb_x),
|
||||
BUTTON("y", sb_y),
|
||||
BUTTON("z", sb_z),
|
||||
|
||||
#undef BUTTON
|
||||
|
||||
{"large", 0xEB},
|
||||
|
||||
{"box", 0xEC},
|
||||
{"box_pressed", 0xED},
|
||||
{"box_animated", 0xEE},
|
||||
|
||||
{"white", 0x80},
|
||||
{"purple", 0x81},
|
||||
{"yellow", 0x82},
|
||||
|
|
@ -77,6 +87,48 @@ Draw::TextElement& Draw::TextElement::parse(std::string_view raw)
|
|||
{"tan", 0x8F},
|
||||
};
|
||||
|
||||
// When we encounter a Saturn button, what gamecontrol does it represent?
|
||||
static const std::unordered_map<char, gamecontrols_e> inputdefinition = {
|
||||
{sb_up, gc_up},
|
||||
{sb_down, gc_down},
|
||||
{sb_right, gc_right},
|
||||
{sb_left, gc_left},
|
||||
|
||||
{sb_lua1, gc_lua1},
|
||||
{sb_lua2, gc_lua2},
|
||||
{sb_lua3, gc_lua3},
|
||||
|
||||
{sb_r, gc_r},
|
||||
{sb_l, gc_l},
|
||||
{sb_start, gc_start},
|
||||
|
||||
{sb_a, gc_a},
|
||||
{sb_b, gc_b},
|
||||
{sb_c, gc_c},
|
||||
|
||||
{sb_x, gc_x},
|
||||
{sb_y, gc_y},
|
||||
{sb_z, gc_z},
|
||||
};
|
||||
|
||||
// What physical binds should appear as Saturn icons anyway?
|
||||
// (We don't have generic binds for stick/dpad directions, so
|
||||
// using the existing arrow graphics is the best thing here.)
|
||||
static const std::unordered_map<INT32, char> prettyinputs = {
|
||||
{KEY_UPARROW, sb_up},
|
||||
{KEY_DOWNARROW, sb_down},
|
||||
{KEY_LEFTARROW, sb_left},
|
||||
{KEY_RIGHTARROW, sb_right},
|
||||
{nc_hatup, sb_up},
|
||||
{nc_hatdown, sb_down},
|
||||
{nc_hatleft, sb_left},
|
||||
{nc_hatright, sb_right},
|
||||
{nc_lsup, sb_up},
|
||||
{nc_lsdown, sb_down},
|
||||
{nc_lsleft, sb_left},
|
||||
{nc_lsright, sb_right},
|
||||
};
|
||||
|
||||
string_.clear();
|
||||
string_.reserve(raw.size());
|
||||
|
||||
|
|
@ -107,10 +159,156 @@ Draw::TextElement& Draw::TextElement::parse(std::string_view raw)
|
|||
|
||||
string_view code = raw.substr(1, p - 1);
|
||||
|
||||
if (auto it = translation.find(code); it != translation.end())
|
||||
if (code == "dpad" || code == "dpad_pressed" || code == "dpad_animated")
|
||||
{
|
||||
// SPECIAL: Generic button that we invoke explicitly, not via gamecontrol reference.
|
||||
// If we ever add anything else to this category, I promise I will create a real abstraction,
|
||||
// but for now, just hardcode the character replacements and pray for forgiveness.
|
||||
|
||||
string_.push_back(0xEF); // Control code: "switch to descriptive input mode"
|
||||
string_.push_back(0xEB); // Control code: "large button"
|
||||
if (code == "dpad")
|
||||
string_.push_back(0xBC);
|
||||
else if (code == "dpad_pressed")
|
||||
string_.push_back(0x9C);
|
||||
else
|
||||
string_.push_back(0xAC);
|
||||
}
|
||||
else if (auto it = translation.find(code); it != translation.end()) // This represents a gamecontrol, turn into Saturn button or generic button.
|
||||
{
|
||||
|
||||
UINT8 localplayer = 0;
|
||||
UINT8 indexedplayer = as_.value_or(stplyr - players);
|
||||
for (UINT8 i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
if (g_localplayers[i] == indexedplayer)
|
||||
{
|
||||
localplayer = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// This isn't how v_video.cpp checks for buttons and I don't know why.
|
||||
if (cv_descriptiveinput[localplayer].value && ((it->second & 0xF0) != 0x80)) // Should we do game control translation?
|
||||
{
|
||||
if (auto id = inputdefinition.find(it->second & (~0xB0)); id != inputdefinition.end()) // This is a game control, do descriptive input translation!
|
||||
{
|
||||
// Grab our local controls - if pid set in the call to parse(), use stplyr's controls
|
||||
INT32 bind = G_FindPlayerBindForGameControl(localplayer, id->second);
|
||||
|
||||
// EXTRA: descriptiveinput values above 1 translate binds back to Saturn buttons,
|
||||
// with various modes for various fucked up 6bt pads
|
||||
std::unordered_map<INT32, char> padconfig = {};
|
||||
switch (cv_descriptiveinput[localplayer].value)
|
||||
{
|
||||
case 1:
|
||||
padconfig = standardpad;
|
||||
break;
|
||||
case 2:
|
||||
padconfig = flippedpad;
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
// Most players will map gc_L to their physical L button,
|
||||
// and gc_R to their physical R button. Assuming this is
|
||||
// true, try to guess their physical layout based on what
|
||||
// they've chosen.
|
||||
|
||||
INT32 leftbumper = G_FindPlayerBindForGameControl(localplayer, gc_l);
|
||||
INT32 rightbumper = G_FindPlayerBindForGameControl(localplayer, gc_r);
|
||||
|
||||
if (leftbumper == nc_lb && rightbumper == nc_lt)
|
||||
{
|
||||
padconfig = saturntypeA;
|
||||
}
|
||||
else if (leftbumper == nc_lt && rightbumper == nc_rt)
|
||||
{
|
||||
padconfig = saturntypeB;
|
||||
}
|
||||
else if (leftbumper == nc_lb && rightbumper == nc_rb)
|
||||
{
|
||||
padconfig = saturntypeC;
|
||||
}
|
||||
else if (leftbumper == nc_ls && rightbumper == nc_lb)
|
||||
{
|
||||
padconfig = saturntypeE;
|
||||
}
|
||||
else if (leftbumper == nc_rs && rightbumper == nc_lt)
|
||||
{
|
||||
padconfig = saturntypeE; // Not a typo! Users might bind a Hori layout pad to either bumpers or triggers
|
||||
}
|
||||
else
|
||||
{
|
||||
padconfig = saturntypeA; // :( ???
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
padconfig = saturntypeA;
|
||||
break;
|
||||
case 5:
|
||||
padconfig = saturntypeB;
|
||||
break;
|
||||
case 6:
|
||||
padconfig = saturntypeC;
|
||||
break;
|
||||
case 7:
|
||||
padconfig = saturntypeD;
|
||||
break;
|
||||
case 8:
|
||||
padconfig = saturntypeE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (auto pretty = prettyinputs.find(bind); pretty != prettyinputs.end()) // Gamepad direction or keyboard arrow, use something nice-looking
|
||||
{
|
||||
string_.push_back((it->second & 0xF0) | pretty->second); // original invocation has the animation bits, but the glyph bits come from the table
|
||||
}
|
||||
else if (auto pad = padconfig.find(bind); pad != padconfig.end())
|
||||
{
|
||||
// If high bits are set, this is meant to be a generic button.
|
||||
if (pad->second & 0xF0)
|
||||
{
|
||||
string_.push_back(0xEF); // Control code: "switch to descriptive input mode" - buttons will draw as generics
|
||||
string_.push_back(0xEB); // Control code: "large button"
|
||||
}
|
||||
|
||||
// Clear high bits so we can add animation bits back cleanly.
|
||||
pad->second = pad->second & (0x0F);
|
||||
|
||||
// original invocation has the animation bits, but the glyph bits come from the table
|
||||
string_.push_back((it->second & 0xF0) | pad->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8 fragment = (it->second & 0xB0);
|
||||
UINT8 code = '\xEE'; // Control code: "toggle boxed drawing"
|
||||
|
||||
if (fragment == 0xA0)
|
||||
code = '\xED'; // ... but animated
|
||||
else if (fragment == 0x90)
|
||||
code = '\xEC'; // ... but pressed
|
||||
|
||||
string_.push_back(code);
|
||||
|
||||
if (bind == -1)
|
||||
string_.append("N/A");
|
||||
else
|
||||
string_.append((G_KeynumToShortString(bind)));
|
||||
|
||||
string_.push_back(code);
|
||||
}
|
||||
}
|
||||
else // This is a color code or some other generic glyph, treat it as is.
|
||||
{
|
||||
string_.push_back(it->second); // replace with character code
|
||||
}
|
||||
}
|
||||
else // We don't care whether this is a generic glyph, because input translation isn't on.
|
||||
{
|
||||
string_.push_back(it->second); // replace with character code
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string_.append(raw.substr(0, p + 1)); // code not found, leave text verbatim
|
||||
|
|
@ -192,14 +390,16 @@ patch_t** get_button_patch(Draw::Button type, int ver)
|
|||
X(x)[ver];
|
||||
X(y)[ver];
|
||||
X(z)[ver];
|
||||
X(start);
|
||||
X(l);
|
||||
X(r);
|
||||
X(up);
|
||||
X(down);
|
||||
X(right);
|
||||
X(left);
|
||||
X(dpad);
|
||||
X(start)[ver];
|
||||
X(l)[ver];
|
||||
X(r)[ver];
|
||||
X(up)[ver];
|
||||
X(down)[ver];
|
||||
X(right)[ver];
|
||||
X(left)[ver];
|
||||
X(lua1)[ver];
|
||||
X(lua2)[ver];
|
||||
X(lua3)[ver];
|
||||
|
||||
#undef X
|
||||
}
|
||||
|
|
@ -223,6 +423,48 @@ void Chain::button_(Button type, int ver, std::optional<bool> press) const
|
|||
}
|
||||
}
|
||||
|
||||
patch_t** get_button_patch(Draw::GenericButton type, int ver)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
#define X(x) \
|
||||
case Draw::GenericButton::x:\
|
||||
return gen_button_ ## x
|
||||
|
||||
X(a)[ver];
|
||||
X(b)[ver];
|
||||
X(x)[ver];
|
||||
X(y)[ver];
|
||||
X(lb)[ver];
|
||||
X(rb)[ver];
|
||||
X(lt)[ver];
|
||||
X(rt)[ver];
|
||||
X(start)[ver];
|
||||
X(back)[ver];
|
||||
X(ls)[ver];
|
||||
X(rs)[ver];
|
||||
X(dpad)[ver];
|
||||
|
||||
#undef X
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
void Chain::generic_button_(GenericButton type, int ver, std::optional<bool> press) const
|
||||
{
|
||||
const auto _ = Clipper(*this);
|
||||
|
||||
if (press)
|
||||
{
|
||||
K_drawButton(FloatToFixed(x_), FloatToFixed(y_), flags_, get_button_patch(type, ver), *press);
|
||||
}
|
||||
else
|
||||
{
|
||||
K_drawButtonAnim(x_, y_, flags_, get_button_patch(type, ver), I_GetTime());
|
||||
}
|
||||
}
|
||||
|
||||
void Chain::sticker(patch_t* end_graphic, UINT8 color) const
|
||||
{
|
||||
const auto _ = Clipper(*this);
|
||||
|
|
|
|||
193
src/v_draw.hpp
193
src/v_draw.hpp
|
|
@ -23,6 +23,165 @@
|
|||
#include "screen.h" // BASEVIDWIDTH
|
||||
#include "typedef.h"
|
||||
#include "v_video.h"
|
||||
#include "g_input.h"
|
||||
|
||||
// Helpers for setting up pad napping nonsense
|
||||
typedef enum
|
||||
{
|
||||
gb_mask = 0xF0,
|
||||
gb_a = 0xF0,
|
||||
gb_b,
|
||||
gb_x,
|
||||
gb_y,
|
||||
gb_lb,
|
||||
gb_rb,
|
||||
gb_lt,
|
||||
gb_rt,
|
||||
gb_start,
|
||||
gb_back,
|
||||
gb_ls,
|
||||
gb_rs,
|
||||
gb_dpad
|
||||
} generic_buttons_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
sb_up = 0x00,
|
||||
sb_down,
|
||||
sb_right,
|
||||
sb_left,
|
||||
sb_lua1,
|
||||
sb_lua2,
|
||||
sb_lua3,
|
||||
sb_r,
|
||||
sb_l,
|
||||
sb_start,
|
||||
sb_a,
|
||||
sb_b,
|
||||
sb_c,
|
||||
sb_x,
|
||||
sb_y,
|
||||
sb_z
|
||||
} saturn_buttons_e;
|
||||
|
||||
// Garden-variety standard gamepad
|
||||
static const std::unordered_map<INT32, char> standardpad = {
|
||||
{nc_a, gb_a},
|
||||
{nc_b, gb_b},
|
||||
{nc_x, gb_x},
|
||||
{nc_y, gb_y},
|
||||
{nc_lb, gb_lb},
|
||||
{nc_rb, gb_rb},
|
||||
{nc_lt, gb_lt},
|
||||
{nc_rt, gb_rt},
|
||||
{nc_start, gb_start},
|
||||
{nc_back, gb_back},
|
||||
{nc_ls, gb_ls},
|
||||
{nc_rs, gb_rs},
|
||||
};
|
||||
|
||||
// Standard gamepad, but evil Nintendo layout flip was applied by your
|
||||
// controller firmware or Steam Input—swap B/A and X/Y
|
||||
static const std::unordered_map<INT32, char> flippedpad = {
|
||||
{nc_a, gb_b},
|
||||
{nc_b, gb_a},
|
||||
{nc_x, gb_y},
|
||||
{nc_y, gb_x},
|
||||
{nc_lb, gb_lb},
|
||||
{nc_rb, gb_rb},
|
||||
{nc_lt, gb_lt},
|
||||
{nc_rt, gb_rt},
|
||||
{nc_start, gb_start},
|
||||
{nc_back, gb_back},
|
||||
{nc_ls, gb_ls},
|
||||
{nc_rs, gb_rs},
|
||||
};
|
||||
|
||||
// Saturn Type A - Retrobit Wired Dinput, RB RT LB LT (CZLR)
|
||||
static const std::unordered_map<INT32, char> saturntypeA = {
|
||||
{nc_a, sb_a},
|
||||
{nc_b, sb_b},
|
||||
{nc_x, sb_x},
|
||||
{nc_y, sb_y},
|
||||
{nc_rb, sb_c},
|
||||
{nc_rt, sb_z},
|
||||
{nc_lb, sb_l},
|
||||
{nc_lt, sb_r},
|
||||
{nc_start, gb_start},
|
||||
{nc_back, gb_back},
|
||||
{nc_ls, gb_ls},
|
||||
{nc_rs, gb_rs},
|
||||
};
|
||||
|
||||
// Saturn Type B - Retrobit Wireless Dinput, LB RB LT RT (CZLR)
|
||||
static const std::unordered_map<INT32, char> saturntypeB = {
|
||||
{nc_a, sb_a},
|
||||
{nc_b, sb_b},
|
||||
{nc_x, sb_x},
|
||||
{nc_y, sb_y},
|
||||
{nc_lb, sb_c},
|
||||
{nc_rb, sb_z},
|
||||
{nc_lt, sb_l},
|
||||
{nc_rt, sb_r},
|
||||
{nc_start, gb_start},
|
||||
{nc_back, gb_back},
|
||||
{nc_ls, gb_ls},
|
||||
{nc_rs, gb_rs},
|
||||
};
|
||||
|
||||
// Saturn Type C - Retrobit Xinput, RT LT LB RB (CZLR)
|
||||
static const std::unordered_map<INT32, char> saturntypeC = {
|
||||
{nc_a, sb_a},
|
||||
{nc_b, sb_b},
|
||||
{nc_x, sb_x},
|
||||
{nc_y, sb_y},
|
||||
{nc_rt, sb_c},
|
||||
{nc_lt, sb_z},
|
||||
{nc_lb, sb_l},
|
||||
{nc_rb, sb_r},
|
||||
{nc_start, gb_start},
|
||||
{nc_back, gb_back},
|
||||
{nc_ls, gb_ls},
|
||||
{nc_rs, gb_rs},
|
||||
};
|
||||
|
||||
// Saturn Type D - 8BitDo M30 / arcade, RT RB LB LT (CZLR)
|
||||
// This cannot be disambiguated (shares L/R with type 1)
|
||||
// but is more spatially correct w/r/t SDL expectations
|
||||
// and standard arcade mapping (Z on top, C on bottom)
|
||||
static const std::unordered_map<INT32, char> saturntypeD = {
|
||||
{nc_a, sb_a},
|
||||
{nc_b, sb_b},
|
||||
{nc_x, sb_x},
|
||||
{nc_y, sb_y},
|
||||
{nc_rt, sb_c},
|
||||
{nc_rb, sb_z},
|
||||
{nc_lb, sb_l},
|
||||
{nc_lt, sb_r},
|
||||
{nc_start, gb_start},
|
||||
{nc_back, gb_back},
|
||||
{nc_ls, gb_ls},
|
||||
{nc_rs, gb_rs},
|
||||
};
|
||||
|
||||
// Saturn Type E - Hori, RT RB (CZ) with some fucked up bumpers/triggers
|
||||
// The Hori layout is, to my knowledge, the only 6bt one that has fully
|
||||
// unique buttons in every slot while having both bumpers and triggers,
|
||||
// so there's no way to accurately portray it without using generics.
|
||||
static const std::unordered_map<INT32, char> saturntypeE = {
|
||||
{nc_a, sb_a},
|
||||
{nc_b, sb_b},
|
||||
{nc_x, sb_x},
|
||||
{nc_y, sb_y},
|
||||
{nc_rt, sb_c},
|
||||
{nc_rb, sb_z},
|
||||
{nc_lb, gb_rb},
|
||||
{nc_lt, gb_rt},
|
||||
{nc_ls, gb_lb},
|
||||
{nc_rs, gb_lt},
|
||||
{nc_start, gb_start},
|
||||
{nc_back, gb_back},
|
||||
};
|
||||
|
||||
namespace srb2
|
||||
{
|
||||
|
|
@ -76,7 +235,26 @@ public:
|
|||
down,
|
||||
right,
|
||||
left,
|
||||
dpad,
|
||||
lua1,
|
||||
lua2,
|
||||
lua3,
|
||||
};
|
||||
|
||||
enum class GenericButton
|
||||
{
|
||||
a,
|
||||
b,
|
||||
x,
|
||||
y,
|
||||
lb,
|
||||
rb,
|
||||
lt,
|
||||
rt,
|
||||
start,
|
||||
back,
|
||||
ls,
|
||||
rs,
|
||||
dpad
|
||||
};
|
||||
|
||||
class TextElement
|
||||
|
|
@ -95,6 +273,7 @@ public:
|
|||
const std::string& string() const { return string_; }
|
||||
std::optional<Font> font() const { return font_; }
|
||||
std::optional<INT32> flags() const { return flags_; }
|
||||
std::optional<UINT8> as() const { return as_; }
|
||||
|
||||
int width() const;
|
||||
|
||||
|
|
@ -124,10 +303,16 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
TextElement& as(UINT8 as)
|
||||
{
|
||||
as_ = as;
|
||||
return *this;
|
||||
}
|
||||
private:
|
||||
std::string string_;
|
||||
std::optional<Font> font_;
|
||||
std::optional<INT32> flags_;
|
||||
std::optional<UINT8> as_;
|
||||
};
|
||||
|
||||
class Chain
|
||||
|
|
@ -193,6 +378,9 @@ public:
|
|||
void button(Button type, std::optional<bool> press = {}) const { button_(type, 0, press); }
|
||||
void small_button(Button type, std::optional<bool> press = {}) const { button_(type, 1, press); }
|
||||
|
||||
void generic_button(GenericButton type, std::optional<bool> press = {}) const { generic_button_(type, 0, press); }
|
||||
void generic_small_button(GenericButton type, std::optional<bool> press = {}) const { generic_button_(type, 1, press); }
|
||||
|
||||
void sticker(patch_t* end_graphic, UINT8 color) const;
|
||||
void sticker() const { sticker(Draw::cache_patch("K_STIKEN"), 24); }
|
||||
void small_sticker() const { sticker(Draw::cache_patch("K_STIKE2"), 24); }
|
||||
|
|
@ -234,6 +422,7 @@ public:
|
|||
|
||||
void string(const char* str, INT32 flags, Font font) const;
|
||||
void button_(Button type, int ver, std::optional<bool> press = {}) const;
|
||||
void generic_button_(GenericButton type, int ver, std::optional<bool> press = {}) const;
|
||||
|
||||
friend Draw;
|
||||
};
|
||||
|
|
@ -283,6 +472,8 @@ public:
|
|||
VOID_METHOD(fill);
|
||||
VOID_METHOD(button);
|
||||
VOID_METHOD(small_button);
|
||||
VOID_METHOD(generic_button);
|
||||
VOID_METHOD(generic_small_button);
|
||||
VOID_METHOD(sticker);
|
||||
VOID_METHOD(small_sticker);
|
||||
|
||||
|
|
|
|||
448
src/v_video.cpp
448
src/v_video.cpp
|
|
@ -2272,6 +2272,7 @@ typedef struct
|
|||
fixed_t lfh;
|
||||
fixed_t (*dim_fn)(fixed_t,fixed_t,INT32,INT32,fixed_t *);
|
||||
UINT8 button_yofs;
|
||||
UINT8 right_outline;
|
||||
} fontspec_t;
|
||||
|
||||
static void V_GetFontSpecification(int fontno, INT32 flags, fontspec_t *result)
|
||||
|
|
@ -2285,6 +2286,8 @@ static void V_GetFontSpecification(int fontno, INT32 flags, fontspec_t *result)
|
|||
result->chw = 0;
|
||||
result->button_yofs = 0;
|
||||
|
||||
result->right_outline = 1;
|
||||
|
||||
const INT32 spacing = ( flags & V_SPACINGMASK );
|
||||
|
||||
switch (fontno)
|
||||
|
|
@ -2482,42 +2485,94 @@ static void V_GetFontSpecification(int fontno, INT32 flags, fontspec_t *result)
|
|||
result->button_yofs = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (fontno)
|
||||
{
|
||||
case MENU_FONT:
|
||||
result->right_outline = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static UINT8 V_GetButtonCodeWidth(UINT8 c)
|
||||
static UINT8 V_GetButtonCodeWidth(UINT8 c, boolean largebutton)
|
||||
{
|
||||
UINT8 x = 0;
|
||||
UINT8 x = 14;
|
||||
|
||||
switch (c & 0x0F)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
// arrows
|
||||
x = 12;
|
||||
case sb_up:
|
||||
case sb_down:
|
||||
case sb_left:
|
||||
case sb_right:
|
||||
x -= largebutton ? 2 : 4;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
// shoulders, start
|
||||
x = 14;
|
||||
case sb_l:
|
||||
case sb_r:
|
||||
x -= largebutton ? 1 : 4;
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
// dpad
|
||||
x = 14;
|
||||
case sb_start:
|
||||
x -= largebutton ? 0 : 4;
|
||||
break;
|
||||
|
||||
case 0x0A:
|
||||
case 0x0B:
|
||||
case 0x0C:
|
||||
case 0x0D:
|
||||
case 0x0E:
|
||||
case 0x0F:
|
||||
// faces
|
||||
x = 10;
|
||||
case sb_lua1:
|
||||
case sb_lua2:
|
||||
case sb_lua3:
|
||||
x -= largebutton ? 0 : 4;
|
||||
break;
|
||||
|
||||
case sb_a:
|
||||
case sb_b:
|
||||
case sb_c:
|
||||
case sb_x:
|
||||
case sb_y:
|
||||
case sb_z:
|
||||
x -= largebutton ? 0 : 4;
|
||||
break;
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
static UINT8 V_GetGenericButtonCodeWidth(UINT8 c, boolean largebutton)
|
||||
{
|
||||
UINT8 x = 16;
|
||||
|
||||
switch ((c & 0x0F) | gb_mask)
|
||||
{
|
||||
case gb_a:
|
||||
case gb_b:
|
||||
case gb_x:
|
||||
case gb_y:
|
||||
x -= largebutton ? 0 : 2;
|
||||
break;
|
||||
|
||||
case gb_lb:
|
||||
case gb_rb:
|
||||
x -= largebutton ? 2 : 6;
|
||||
break;
|
||||
|
||||
case gb_lt:
|
||||
case gb_rt:
|
||||
x -= largebutton ? 2 : 6;
|
||||
break;
|
||||
|
||||
case gb_start:
|
||||
x -= largebutton ? 2 : 6;
|
||||
break;
|
||||
|
||||
case gb_back:
|
||||
x -= largebutton ? 2 : 6;
|
||||
break;
|
||||
|
||||
case gb_ls:
|
||||
case gb_rs:
|
||||
x -= largebutton ? 1 : 4;
|
||||
break;
|
||||
|
||||
case gb_dpad:
|
||||
x -= largebutton ? 2 : 5;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2547,12 +2602,25 @@ void V_DrawStringScaled(
|
|||
|
||||
boolean uppercase;
|
||||
boolean notcolored;
|
||||
int boxed = 0;
|
||||
boolean descriptive = false;
|
||||
|
||||
boolean debugalternation = false;
|
||||
UINT8 debugcolor1 = 181;
|
||||
UINT8 debugcolor2 = 96;
|
||||
|
||||
boolean dance;
|
||||
boolean nodanceoverride;
|
||||
INT32 dancecounter;
|
||||
|
||||
INT32 boxedflags = ((flags) & (~V_HUDTRANS)) | (V_40TRANS);
|
||||
|
||||
boolean largebutton = false;
|
||||
|
||||
fixed_t cx, cy;
|
||||
fixed_t cxsave;
|
||||
|
||||
const char *ssave;
|
||||
|
||||
fixed_t cxoff, cyoff;
|
||||
fixed_t cw;
|
||||
|
|
@ -2563,6 +2631,7 @@ void V_DrawStringScaled(
|
|||
|
||||
uppercase = ((flags & V_FORCEUPPERCASE) == V_FORCEUPPERCASE);
|
||||
flags &= ~(V_FLIP);/* These two (V_FORCEUPPERCASE) share a bit. */
|
||||
boxed = false;
|
||||
|
||||
dance = (flags & V_STRINGDANCE) != 0;
|
||||
nodanceoverride = !dance;
|
||||
|
|
@ -2638,11 +2707,75 @@ void V_DrawStringScaled(
|
|||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
if (boxed)
|
||||
continue;
|
||||
cy += fontspec.lfh;
|
||||
if (cy >= bot)
|
||||
return;
|
||||
cx = x;
|
||||
break;
|
||||
case '\xEB':
|
||||
if (fontno != TINY_FONT && fontno != HU_FONT)
|
||||
largebutton = true;
|
||||
break;
|
||||
case '\xEF':
|
||||
descriptive = true;
|
||||
break;
|
||||
case '\xEE':
|
||||
case '\xED':
|
||||
case '\xEC':
|
||||
{
|
||||
UINT8 anim_duration = 16;
|
||||
boolean anim = ((I_GetTime() % (anim_duration * 2)) < anim_duration);
|
||||
if (c == '\xEE')
|
||||
anim = false;
|
||||
else if (c == '\xEC')
|
||||
anim = true;
|
||||
|
||||
// For bullshit text outlining reasons, we cannot draw this background character-by-character.
|
||||
// Thinking about doing string manipulation and calling out to V_StringWidth made me drink water.
|
||||
// So instead, we just draw this section of the string twice—invisibly the first time, to measure the width.
|
||||
|
||||
if (boxed == 0) // Save our position and start no-op drawing
|
||||
{
|
||||
cy -= 2*FRACUNIT;
|
||||
|
||||
Draw(FixedToFloat(cx), FixedToFloat(cy)-3).flags(flags).patch(gen_button_keyleft[anim]);
|
||||
|
||||
cx += 3*FRACUNIT;
|
||||
ssave = s;
|
||||
cxsave = cx;
|
||||
|
||||
boxed = 1;
|
||||
}
|
||||
else if (boxed == 1) // Draw box from saved pos to current pos and roll back
|
||||
{
|
||||
cx += (fontspec.right_outline)*FRACUNIT;
|
||||
fixed_t working = cxsave - 1*FRACUNIT;
|
||||
|
||||
Draw(FixedToFloat(working)+1, FixedToFloat(cy)-3)
|
||||
.width(FixedToFloat(cx - working)-1)
|
||||
.flags(flags)
|
||||
.stretch(Draw::Stretch::kWidth).patch(gen_button_keycenter[anim]);
|
||||
Draw(FixedToFloat(cx), FixedToFloat(cy)-3).flags(flags).patch(gen_button_keyright[anim]);
|
||||
|
||||
s = ssave;
|
||||
cx = cxsave;
|
||||
|
||||
// This is a little gross, but this is our way of smuggling text offset to
|
||||
// the standard character drawing case. boxed=3 means we're drawing a pressed button.
|
||||
boxed = 2 + anim;
|
||||
}
|
||||
else // Meeting the ending tag the second time, space away and resume standard parsing
|
||||
{
|
||||
boxed = 0;
|
||||
|
||||
cx += (3)*FRACUNIT;
|
||||
cy += 2*FRACUNIT;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if (( c & 0xF0 ) == 0x80)
|
||||
{
|
||||
|
|
@ -2687,6 +2820,8 @@ void V_DrawStringScaled(
|
|||
}
|
||||
|
||||
if (( c & 0xB0 ) & 0x80) // button prompts
|
||||
{
|
||||
if (!descriptive)
|
||||
{
|
||||
using srb2::Draw;
|
||||
|
||||
|
|
@ -2700,30 +2835,65 @@ void V_DrawStringScaled(
|
|||
{
|
||||
switch (c & 0x0F)
|
||||
{
|
||||
case 0x00: return {{0, 3, Draw::Button::up}};
|
||||
case 0x01: return {{0, 3, Draw::Button::down}};
|
||||
case 0x02: return {{0, 3, Draw::Button::right}};
|
||||
case 0x03: return {{0, 3, Draw::Button::left}};
|
||||
case sb_up: return {{2, 2, Draw::Button::up}};
|
||||
case sb_down: return {{2, 2, Draw::Button::down}};
|
||||
case sb_right: return {{2, 2, Draw::Button::right}};
|
||||
case sb_left: return {{2, 2, Draw::Button::left}};
|
||||
|
||||
case 0x04: return {{0, 4, Draw::Button::dpad}};
|
||||
case sb_lua1: return {{2, 2, Draw::Button::lua1}};
|
||||
case sb_lua2: return {{2, 2, Draw::Button::lua2}};
|
||||
case sb_lua3: return {{2, 2, Draw::Button::lua3}};
|
||||
|
||||
case 0x07: return {{0, 2, Draw::Button::r}};
|
||||
case 0x08: return {{0, 2, Draw::Button::l}};
|
||||
case sb_r: return {{2, 2, Draw::Button::r}};
|
||||
case sb_l: return {{2, 2, Draw::Button::l}};
|
||||
|
||||
case 0x09: return {{0, 1, Draw::Button::start}};
|
||||
case sb_start: return {{2, 2, Draw::Button::start}};
|
||||
|
||||
case 0x0A: return {{2, 1, Draw::Button::a}};
|
||||
case 0x0B: return {{2, 1, Draw::Button::b}};
|
||||
case 0x0C: return {{2, 1, Draw::Button::c}};
|
||||
case sb_a: return {{2, 2, Draw::Button::a}};
|
||||
case sb_b: return {{2, 2, Draw::Button::b}};
|
||||
case sb_c: return {{2, 2, Draw::Button::c}};
|
||||
|
||||
case 0x0D: return {{2, 1, Draw::Button::x}};
|
||||
case 0x0E: return {{2, 1, Draw::Button::y}};
|
||||
case 0x0F: return {{2, 1, Draw::Button::z}};
|
||||
case sb_x: return {{2, 2, Draw::Button::x}};
|
||||
case sb_y: return {{2, 2, Draw::Button::y}};
|
||||
case sb_z: return {{2, 2, Draw::Button::z}};
|
||||
|
||||
default: return {};
|
||||
}
|
||||
}();
|
||||
|
||||
if (largebutton)
|
||||
{
|
||||
bt_inst = [c]() -> std::optional<BtConf>
|
||||
{
|
||||
switch (c & 0x0F)
|
||||
{
|
||||
case sb_up: return {{2, 4, Draw::Button::up}};
|
||||
case sb_down: return {{2, 4, Draw::Button::down}};
|
||||
case sb_right: return {{2, 4, Draw::Button::right}};
|
||||
case sb_left: return {{2, 4, Draw::Button::left}};
|
||||
|
||||
case sb_lua1: return {{1, 4, Draw::Button::lua1}};
|
||||
case sb_lua2: return {{1, 4, Draw::Button::lua2}};
|
||||
case sb_lua3: return {{1, 4, Draw::Button::lua3}};
|
||||
|
||||
case sb_r: return {{1, 4, Draw::Button::r}};
|
||||
case sb_l: return {{1, 4, Draw::Button::l}};
|
||||
|
||||
case sb_start: return {{1, 4, Draw::Button::start}};
|
||||
|
||||
case sb_a: return {{1, 4, Draw::Button::a}};
|
||||
case sb_b: return {{1, 4, Draw::Button::b}};
|
||||
case sb_c: return {{1, 4, Draw::Button::c}};
|
||||
|
||||
case sb_x: return {{1, 4, Draw::Button::x}};
|
||||
case sb_y: return {{1, 4, Draw::Button::y}};
|
||||
case sb_z: return {{1, 4, Draw::Button::z}};
|
||||
|
||||
default: return {};
|
||||
}
|
||||
}();
|
||||
}
|
||||
|
||||
if (bt_inst)
|
||||
{
|
||||
auto bt_translate_press = [c]() -> std::optional<bool>
|
||||
|
|
@ -2737,15 +2907,126 @@ void V_DrawStringScaled(
|
|||
}
|
||||
};
|
||||
|
||||
cw = V_GetButtonCodeWidth(c) * dupx;
|
||||
cw = V_GetButtonCodeWidth(c, largebutton) * dupx;
|
||||
|
||||
cxoff = (*fontspec.dim_fn)(scale, fontspec.chw, hchw, dupx, &cw);
|
||||
Draw(
|
||||
|
||||
if (cv_debugfonts.value)
|
||||
{
|
||||
V_DrawFill(cx/FRACUNIT, cy/FRACUNIT, cw/FRACUNIT, fontspec.lfh/FRACUNIT, debugalternation ? debugcolor1 : debugcolor2);
|
||||
debugalternation = !debugalternation;
|
||||
}
|
||||
|
||||
Draw bt = Draw(
|
||||
FixedToFloat(cx + cxoff) - (bt_inst->x * dupx),
|
||||
FixedToFloat(cy + cyoff) - ((bt_inst->y + fontspec.button_yofs) * dupy))
|
||||
.flags(flags)
|
||||
.small_button(bt_inst->type, bt_translate_press());
|
||||
.flags(flags);
|
||||
|
||||
if (largebutton)
|
||||
bt.button(bt_inst->type, bt_translate_press());
|
||||
else
|
||||
bt.small_button(bt_inst->type, bt_translate_press());
|
||||
|
||||
cx += cw;
|
||||
}
|
||||
descriptive = false;
|
||||
largebutton = false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
using srb2::Draw;
|
||||
|
||||
struct BtConf
|
||||
{
|
||||
UINT8 x, y;
|
||||
Draw::GenericButton type;
|
||||
};
|
||||
|
||||
auto bt_inst = [c]() -> std::optional<BtConf>
|
||||
{
|
||||
switch ((c & 0x0F) | gb_mask)
|
||||
{
|
||||
case gb_a: return {{0, 1, Draw::GenericButton::a}};
|
||||
case gb_b: return {{0, 1, Draw::GenericButton::b}};
|
||||
case gb_x: return {{0, 1, Draw::GenericButton::x}};
|
||||
case gb_y: return {{0, 1, Draw::GenericButton::y}};
|
||||
case gb_lb: return {{2, 2, Draw::GenericButton::lb}};
|
||||
case gb_rb: return {{2, 2, Draw::GenericButton::rb}};
|
||||
case gb_lt: return {{2, 2, Draw::GenericButton::lt}};
|
||||
case gb_rt: return {{2, 2, Draw::GenericButton::rt}};
|
||||
case gb_start: return {{2, 2, Draw::GenericButton::start}};
|
||||
case gb_back: return {{2, 2, Draw::GenericButton::back}};
|
||||
case gb_ls: return {{1, 2, Draw::GenericButton::ls}};
|
||||
case gb_rs: return {{1, 2, Draw::GenericButton::rs}};
|
||||
case gb_dpad: return {{2, 2, Draw::GenericButton::dpad}};
|
||||
default: return {};
|
||||
}
|
||||
}();
|
||||
|
||||
if (largebutton)
|
||||
{
|
||||
bt_inst = [c]() -> std::optional<BtConf>
|
||||
{
|
||||
switch ((c & 0x0F) | gb_mask)
|
||||
{
|
||||
case gb_a: return {{0, 3, Draw::GenericButton::a}};
|
||||
case gb_b: return {{0, 3, Draw::GenericButton::b}};
|
||||
case gb_x: return {{0, 3, Draw::GenericButton::x}};
|
||||
case gb_y: return {{0, 3, Draw::GenericButton::y}};
|
||||
case gb_lb: return {{1, 3, Draw::GenericButton::lb}};
|
||||
case gb_rb: return {{1, 3, Draw::GenericButton::rb}};
|
||||
case gb_lt: return {{1, 4, Draw::GenericButton::lt}};
|
||||
case gb_rt: return {{1, 4, Draw::GenericButton::rt}};
|
||||
case gb_start: return {{1, 6, Draw::GenericButton::start}};
|
||||
case gb_back: return {{1, 6, Draw::GenericButton::back}};
|
||||
case gb_ls: return {{1, 5, Draw::GenericButton::ls}};
|
||||
case gb_rs: return {{1, 5, Draw::GenericButton::rs}};
|
||||
case gb_dpad: return {{1, 4, Draw::GenericButton::dpad}};
|
||||
default: return {};
|
||||
}
|
||||
}();
|
||||
}
|
||||
|
||||
if (bt_inst)
|
||||
{
|
||||
auto bt_translate_press = [c]() -> std::optional<bool>
|
||||
{
|
||||
switch (c & 0xB0)
|
||||
{
|
||||
default:
|
||||
case 0x90: return true;
|
||||
case 0xA0: return {};
|
||||
case 0xB0: return false;
|
||||
}
|
||||
};
|
||||
|
||||
cw = V_GetGenericButtonCodeWidth(c, largebutton) * dupx;
|
||||
|
||||
cxoff = (*fontspec.dim_fn)(scale, fontspec.chw, hchw, dupx, &cw);
|
||||
|
||||
if (cv_debugfonts.value)
|
||||
{
|
||||
V_DrawFill(cx/FRACUNIT, cy/FRACUNIT, cw/FRACUNIT, fontspec.lfh/FRACUNIT, debugalternation ? debugcolor1 : debugcolor2);
|
||||
debugalternation = !debugalternation;
|
||||
}
|
||||
|
||||
Draw bt = Draw(
|
||||
FixedToFloat(cx + cxoff) - (bt_inst->x * dupx),
|
||||
FixedToFloat(cy + cyoff) - ((bt_inst->y + fontspec.button_yofs) * dupy))
|
||||
.flags(flags);
|
||||
|
||||
if (largebutton)
|
||||
bt.generic_button(bt_inst->type, bt_translate_press());
|
||||
else
|
||||
bt.generic_small_button(bt_inst->type, bt_translate_press());
|
||||
|
||||
cx += cw;
|
||||
}
|
||||
descriptive = false;
|
||||
largebutton = false;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2756,8 +3037,19 @@ void V_DrawStringScaled(
|
|||
fixed_t patchxofs = SHORT (font->font[c]->leftoffset) * dupx * scale;
|
||||
cw = SHORT (font->font[c]->width) * dupx;
|
||||
cxoff = (*fontspec.dim_fn)(scale, fontspec.chw, hchw, dupx, &cw);
|
||||
V_DrawFixedPatch(cx + cxoff + patchxofs, cy + cyoff, scale,
|
||||
flags, font->font[c], colormap);
|
||||
|
||||
if (cv_debugfonts.value)
|
||||
{
|
||||
V_DrawFill(cx/FRACUNIT, cy/FRACUNIT, cw/FRACUNIT, fontspec.lfh/FRACUNIT, debugalternation ? debugcolor1 : debugcolor2);
|
||||
debugalternation = !debugalternation;
|
||||
}
|
||||
|
||||
if (boxed != 1)
|
||||
{
|
||||
V_DrawFixedPatch(cx + cxoff + patchxofs, cy + cyoff + (boxed == 3 ? 2*FRACUNIT : 0), scale,
|
||||
boxed ? boxedflags : flags, font->font[c], boxed ? 0 : colormap);
|
||||
}
|
||||
|
||||
cx += cw;
|
||||
}
|
||||
else
|
||||
|
|
@ -2782,6 +3074,9 @@ fixed_t V_StringScaledWidth(
|
|||
font_t *font;
|
||||
|
||||
boolean uppercase;
|
||||
boolean boxed = false;
|
||||
boolean descriptive = false;
|
||||
boolean largebutton = false;
|
||||
|
||||
fixed_t cx;
|
||||
fixed_t right;
|
||||
|
|
@ -2840,15 +3135,43 @@ fixed_t V_StringScaledWidth(
|
|||
case '\n':
|
||||
cx = 0;
|
||||
break;
|
||||
case '\xEB':
|
||||
if (fontno != TINY_FONT && fontno != HU_FONT)
|
||||
largebutton = true;
|
||||
break;
|
||||
case '\xEF':
|
||||
descriptive = true;
|
||||
break;
|
||||
case '\xEE':
|
||||
case '\xED':
|
||||
case '\xEC':
|
||||
if (boxed)
|
||||
cx += 3*FRACUNIT;
|
||||
else
|
||||
cx += 3*FRACUNIT;
|
||||
boxed = !boxed;
|
||||
break;
|
||||
default:
|
||||
if (( c & 0xF0 ) == 0x80 || c == V_STRINGDANCE)
|
||||
continue;
|
||||
|
||||
if (( c & 0xB0 ) & 0x80)
|
||||
{
|
||||
cw = V_GetButtonCodeWidth(c) * dupx;
|
||||
if (descriptive)
|
||||
{
|
||||
cw = V_GetGenericButtonCodeWidth(c, largebutton) * dupx;
|
||||
cx += cw * scale;
|
||||
right = cx;
|
||||
}
|
||||
else
|
||||
{
|
||||
cw = V_GetButtonCodeWidth(c, largebutton) * dupx;
|
||||
cx += cw * scale;
|
||||
right = cx;
|
||||
}
|
||||
|
||||
largebutton = false;
|
||||
descriptive = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2884,6 +3207,7 @@ fixed_t V_StringScaledWidth(
|
|||
}
|
||||
else
|
||||
cx += fontspec.spacew;
|
||||
descriptive = false;
|
||||
}
|
||||
|
||||
fullwidth = std::max(right, std::max(cx, fullwidth));
|
||||
|
|
@ -2909,6 +3233,9 @@ char * V_ScaledWordWrap(
|
|||
font_t *font;
|
||||
|
||||
boolean uppercase;
|
||||
boolean largebutton = false;
|
||||
boolean descriptive = false;
|
||||
boolean boxed = false;
|
||||
|
||||
fixed_t cx;
|
||||
fixed_t right;
|
||||
|
|
@ -2980,14 +3307,36 @@ char * V_ScaledWordWrap(
|
|||
cxatstart = 0;
|
||||
startwriter = 0;
|
||||
break;
|
||||
case '\xEB':
|
||||
if (fontno != TINY_FONT && fontno != HU_FONT)
|
||||
largebutton = true;
|
||||
case '\xEF':
|
||||
descriptive = true;
|
||||
break;
|
||||
case '\xEE':
|
||||
case '\xED':
|
||||
case '\xEC':
|
||||
if (boxed)
|
||||
cx += 3*FRACUNIT;
|
||||
else
|
||||
cx += 3*FRACUNIT;
|
||||
boxed = !boxed;
|
||||
break;
|
||||
default:
|
||||
if (( c & 0xF0 ) == 0x80 || c == V_STRINGDANCE)
|
||||
;
|
||||
else if (( c & 0xB0 ) & 0x80) // button prompts
|
||||
{
|
||||
cw = V_GetButtonCodeWidth(c) * dupx;
|
||||
if (descriptive)
|
||||
cw = V_GetGenericButtonCodeWidth(c, largebutton) * dupx;
|
||||
else
|
||||
cw = V_GetButtonCodeWidth(c, largebutton) * dupx;
|
||||
|
||||
cx += cw * scale;
|
||||
right = cx;
|
||||
|
||||
descriptive = false;
|
||||
boxed = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -3479,3 +3828,10 @@ void VID_DisplaySoftwareScreen()
|
|||
// Post-process blit to the 'default' framebuffer
|
||||
hw_state->blit_postimg_screens->draw(*rhi, ctx);
|
||||
}
|
||||
|
||||
char *V_ParseText(const char *rawText)
|
||||
{
|
||||
using srb2::Draw;
|
||||
|
||||
return Z_StrDup(srb2::Draw::TextElement().parse(rawText).string().c_str());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -442,6 +442,9 @@ void VID_BlitLinearScreen(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT3
|
|||
*/
|
||||
void VID_DisplaySoftwareScreen(void);
|
||||
|
||||
char *V_ParseText(const char *rawText); // Launder srb2::draw::TextElement.parse() through C code!
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2406,6 +2406,8 @@ int W_VerifyNMUSlumps(const char *filename, boolean exit_on_error)
|
|||
{"K_", 2}, // Kart graphic changes
|
||||
{"MUSICDEF", 8}, // Kart song definitions
|
||||
|
||||
{"TLG_", 4}, // Generic button legends
|
||||
|
||||
#ifdef HWRENDER
|
||||
{"SHADERS", 7},
|
||||
{"SH_", 3},
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@
|
|||
#include "m_easing.h"
|
||||
#include "music.h"
|
||||
|
||||
#include "v_draw.hpp"
|
||||
|
||||
#ifdef HWRENDER
|
||||
#include "hardware/hw_main.h"
|
||||
#endif
|
||||
|
|
@ -1474,6 +1476,13 @@ void Y_DrawIntermissionButton(INT32 startslide, INT32 through, boolean widescree
|
|||
);
|
||||
}
|
||||
|
||||
using srb2::Draw;
|
||||
|
||||
Draw::TextElement text = Draw::TextElement().parse(pressed ? "<a_pressed>" : "<a>");
|
||||
Draw draw = Draw(FixedToFloat(2*FRACUNIT - offset), FixedToFloat((BASEVIDHEIGHT - 16)*FRACUNIT)).flags(widescreen ? (V_SNAPTOLEFT|V_SNAPTOBOTTOM) : 0);
|
||||
draw.text(text.string());
|
||||
|
||||
/*
|
||||
K_drawButton(
|
||||
2*FRACUNIT - offset,
|
||||
(BASEVIDHEIGHT - 16)*FRACUNIT,
|
||||
|
|
@ -1484,6 +1493,7 @@ void Y_DrawIntermissionButton(INT32 startslide, INT32 through, boolean widescree
|
|||
kp_button_a[1],
|
||||
pressed
|
||||
);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue