diff --git a/src/g_input.c b/src/g_input.c index 2eed40c88..948eca026 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -1270,7 +1270,7 @@ INT32 G_CheckDoubleUsage(INT32 keynum, INT32 playernum, boolean modify) INT32 G_FindPlayerBindForGameControl(INT32 player, gamecontrols_e control) { - profile_t *ourProfile = PR_GetLocalPlayerProfile(player); + profile_t *ourProfile = PR_GetPlayerProfile(&players[player]); if (ourProfile == NULL) ourProfile = PR_GetLocalPlayerProfile(0); @@ -1283,6 +1283,7 @@ INT32 G_FindPlayerBindForGameControl(INT32 player, gamecontrols_e control) INT32 bindindex = MAXINPUTMAPPING-1; + // PASS 1: Binds that are directly in our profile control mapping. while (bindindex >= 0) // Prefer earlier binds { INT32 possiblecontrol = ourProfile->controls[control][bindindex]; @@ -1304,12 +1305,12 @@ INT32 G_FindPlayerBindForGameControl(INT32 player, gamecontrols_e control) } } - // Still no matching device bind? Try defaults... + // PASS 2: Binds that are in the default controls. if (bestbind == -1) { bindindex = MAXINPUTMAPPING-1; - while (bindindex >= 0) // Prefer earlier binds + while (bindindex >= 0) { INT32 possiblecontrol = gamecontroldefault[control][bindindex]; @@ -1318,7 +1319,6 @@ INT32 G_FindPlayerBindForGameControl(INT32 player, gamecontrols_e control) 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)) { bestbind = possiblecontrol; @@ -1331,12 +1331,12 @@ INT32 G_FindPlayerBindForGameControl(INT32 player, gamecontrols_e control) } } - // STILL no matching device bind? Try menu reserved! + // PASS 3: "Safety" binds that are reserved by the menu system. if (bestbind == -1) { bindindex = MAXINPUTMAPPING-1; - while (bindindex >= 0) // Prefer earlier binds + while (bindindex >= 0) { INT32 possiblecontrol = menucontrolreserved[control][bindindex]; @@ -1345,7 +1345,6 @@ INT32 G_FindPlayerBindForGameControl(INT32 player, gamecontrols_e control) 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)) { bestbind = possiblecontrol; diff --git a/src/k_hud.cpp b/src/k_hud.cpp index 7fab59bdb..6cb5e2b2c 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -6360,12 +6360,7 @@ void K_AddMessageForPlayer(player_t *player, const char *msg, boolean interrupt, if (interrupt) state->clear(); - // FIXME: SUPER BAD HACK. - // Need a way to parse messages as a given player instead. - player_t *oldstplyr = stplyr; - stplyr = player; - std::string parsedmsg = srb2::Draw::TextElement().parse(msg).string(); - stplyr = oldstplyr; + std::string parsedmsg = srb2::Draw::TextElement().as(player - players).parse(msg).string(); if (persist) state->objective = parsedmsg; @@ -6946,12 +6941,7 @@ INT32 K_DrawGameControl(UINT16 x, UINT16 y, UINT8 player, const char *str, UINT8 { using srb2::Draw; - // FIXME: SUPER BAD HACK. - // Need a way to parse messages as a given player instead. - player_t *oldstplyr = stplyr; - stplyr = &players[player]; - Draw::TextElement text = Draw::TextElement().parse(str).font(Draw::Font::kMenu); - stplyr = oldstplyr; + Draw::TextElement text = Draw::TextElement().as(player).parse(str).font(Draw::Font::kMenu); INT32 width = text.width(); diff --git a/src/v_draw.cpp b/src/v_draw.cpp index ee2b940c8..46b3cf1b2 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -169,22 +169,24 @@ Draw::TextElement& Draw::TextElement::parse(std::string_view raw) if (auto id = inputdefinition.find(it->second & (~0xF0)); id != inputdefinition.end()) // This is a game control, do descriptive input translation! { // Grab our local controls - UINT8 localplayer = stplyr - players; + UINT8 targetplayer = as_.value_or(stplyr - players); // If not set in the call to parse(), use stplyr's controls + if (targetplayer >= MAXPLAYERS) + targetplayer = 0; - INT32 bind = G_FindPlayerBindForGameControl(localplayer, id->second); + INT32 bind = G_FindPlayerBindForGameControl(targetplayer, id->second); 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 generic = genericinputs.find(bind); generic != genericinputs.end()) // Gamepad input, display it to the player as they are + else if (auto generic = genericinputs.find(bind); generic != genericinputs.end()) // Non-directional gamepad input, display it to the player as they are { - string_.push_back(0xEF); + string_.push_back(0xEF); // Control code: "switch to descriptive input mode" - Saturn buttons will draw as generic gamepad buttons string_.push_back((it->second & 0xF0) | generic->second); // original invocation has the animation bits, but the glyph bits come from the table } else { - string_.push_back('\xEE'); + string_.push_back('\xEE'); // Control code: "toggle boxed drawing" if (bind == -1) string_.append("[NOT BOUND]"); diff --git a/src/v_draw.hpp b/src/v_draw.hpp index da3ccce2f..6035e2317 100644 --- a/src/v_draw.hpp +++ b/src/v_draw.hpp @@ -113,6 +113,7 @@ public: const std::string& string() const { return string_; } std::optional font() const { return font_; } std::optional flags() const { return flags_; } + std::optional as() const { return as_; } int width() const; @@ -142,10 +143,16 @@ public: return *this; } + TextElement& as(UINT8 as) + { + as_ = as; + return *this; + } private: std::string string_; std::optional font_; std::optional flags_; + std::optional as_; }; class Chain