diff --git a/src/g_input.c b/src/g_input.c index db06e8ee8..09a6204d2 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -1283,8 +1283,6 @@ INT32 G_FindPlayerBindForGameControl(INT32 player, gamecontrols_e control) INT32 bindindex = MAXINPUTMAPPING-1; - CONS_Printf("Searcrhing for gamecontrol %d on player %d device %d...\n", control, player, device); - while (bindindex >= 0) // Prefer earlier binds { INT32 possiblecontrol = ourProfile->controls[control][bindindex]; @@ -1299,12 +1297,10 @@ INT32 G_FindPlayerBindForGameControl(INT32 player, gamecontrols_e control) { bestbind = possiblecontrol; anybind = possiblecontrol; - CONS_Printf("Matching control %s\n", G_KeynumToShortString(possiblecontrol)); } else { anybind = possiblecontrol; - CONS_Printf("Speculative control %s\n", G_KeynumToShortString(possiblecontrol)); } } @@ -1327,12 +1323,10 @@ INT32 G_FindPlayerBindForGameControl(INT32 player, gamecontrols_e control) { bestbind = possiblecontrol; anybind = possiblecontrol; - CONS_Printf("Matching default control %s\n", G_KeynumToShortString(possiblecontrol)); } else { anybind = possiblecontrol; - CONS_Printf("Speculative default control %s\n", G_KeynumToShortString(possiblecontrol)); } } } @@ -1356,12 +1350,10 @@ INT32 G_FindPlayerBindForGameControl(INT32 player, gamecontrols_e control) { bestbind = possiblecontrol; anybind = possiblecontrol; - CONS_Printf("Matching reserved control %s\n", G_KeynumToShortString(possiblecontrol)); } else { anybind = possiblecontrol; - CONS_Printf("Speculative reserved control %s\n", G_KeynumToShortString(possiblecontrol)); } } } diff --git a/src/k_hud.cpp b/src/k_hud.cpp index bf94398ea..bf5c52e57 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -244,12 +244,31 @@ patch_t *kp_button_right[2]; patch_t *kp_button_left[2]; patch_t *kp_button_dpad[2]; +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]; +patch_t *gen_button_rb[2]; +patch_t *gen_button_lt[2]; +patch_t *gen_button_rt[2]; +patch_t *gen_button_start[2]; +patch_t *gen_button_back[2]; +patch_t *gen_button_ls[2]; +patch_t *gen_button_rs[2]; + static void K_LoadButtonGraphics(patch_t *kp[2], int letter) { HU_UpdatePatch(&kp[0], "TLB_%c", letter); HU_UpdatePatch(&kp[1], "TLB_%cB", letter); } +static void K_LoadGenericButtonGraphics(patch_t *kp[2], int letter) +{ + HU_UpdatePatch(&kp[0], "TLG_%c", letter); + HU_UpdatePatch(&kp[1], "TLG_%cB", letter); +} + void K_LoadKartHUDGraphics(void) { INT32 i, j, k; @@ -962,6 +981,28 @@ void K_LoadKartHUDGraphics(void) K_LoadButtonGraphics(kp_button_right, 'L'); K_LoadButtonGraphics(kp_button_left, 'M'); K_LoadButtonGraphics(kp_button_dpad, 'T'); + + K_LoadGenericButtonGraphics(gen_button_a[0], 'A'); + K_LoadGenericButtonGraphics(gen_button_b[0], 'B'); + K_LoadGenericButtonGraphics(gen_button_x[0], 'D'); + K_LoadGenericButtonGraphics(gen_button_y[0], 'E'); + + K_LoadGenericButtonGraphics(gen_button_a[1], 'K'); + K_LoadGenericButtonGraphics(gen_button_b[1], 'M'); + K_LoadGenericButtonGraphics(gen_button_x[1], 'L'); + K_LoadGenericButtonGraphics(gen_button_y[1], 'J'); + + K_LoadGenericButtonGraphics(gen_button_lb, 'H'); + K_LoadGenericButtonGraphics(gen_button_rb, 'I'); + + K_LoadGenericButtonGraphics(gen_button_lt, 'C'); + K_LoadGenericButtonGraphics(gen_button_rt, 'F'); + + K_LoadGenericButtonGraphics(gen_button_start, 'G'); + K_LoadGenericButtonGraphics(gen_button_back, 'G'); // FIXME + + K_LoadGenericButtonGraphics(gen_button_ls, 'T'); + K_LoadGenericButtonGraphics(gen_button_rs, 'U'); } // For the item toggle menu @@ -6445,16 +6486,35 @@ void K_drawKartHUD(void) } // In case of font debugging break glass -#if 0 +#if 1 using srb2::Draw; - Draw::TextElement text = Draw::TextElement().parse("ABCxyz / 012 - Use + to Krungle!"); - + if (0) + { + Draw::TextElement text = Draw::TextElement().parse("A B C X Y Z \nST L R U D L R "); + player_t *oldstplyr = stplyr; stplyr = &players[0]; Draw(5, 5).align((srb2::Draw::Align)0).font(Draw::Font::kMenu).text(text); stplyr = &players[1]; - Draw(5, 15).align((srb2::Draw::Align)0).font(Draw::Font::kThin).text(text); + Draw(5, 35).align((srb2::Draw::Align)0).font(Draw::Font::kThin).text(text); + stplyr = oldstplyr; + } + + + if (1) + { + Draw::TextElement text = Draw::TextElement().parse("A \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"); + + player_t *oldstplyr = stplyr; + stplyr = &players[0]; + Draw(160, 5).align((srb2::Draw::Align)0).font(Draw::Font::kMenu).text(text); + stplyr = &players[1]; + Draw(55, 5).align((srb2::Draw::Align)0).font(Draw::Font::kThin).text(text); + stplyr = oldstplyr; + } + + /* stplyr = &players[2]; Draw(5, 25).align((srb2::Draw::Align)0).font(Draw::Font::kConsole).text(text); stplyr = &players[3]; @@ -6466,7 +6526,7 @@ void K_drawKartHUD(void) Draw(5, 105).align((srb2::Draw::Align)0).font(Draw::Font::kThinTimer).text(text); Draw(5, 115).align((srb2::Draw::Align)0).font(Draw::Font::kTimer).text(text); Draw(5, 145).align((srb2::Draw::Align)0).font(Draw::Font::kZVote).text(text); - stplyr = oldstplyr; + */ #endif diff --git a/src/k_hud.h b/src/k_hud.h index 2f8a6ddc8..db2ff421b 100644 --- a/src/k_hud.h +++ b/src/k_hud.h @@ -103,6 +103,19 @@ extern patch_t *kp_button_right[2]; extern patch_t *kp_button_left[2]; extern patch_t *kp_button_dpad[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]; +extern patch_t *gen_button_rb[2]; +extern patch_t *gen_button_lt[2]; +extern patch_t *gen_button_rt[2]; +extern patch_t *gen_button_start[2]; +extern patch_t *gen_button_back[2]; +extern patch_t *gen_button_ls[2]; +extern patch_t *gen_button_rs[2]; + extern patch_t *kp_eggnum[6]; extern patch_t *kp_facenum[MAXPLAYERS+1]; diff --git a/src/k_menudraw.c b/src/k_menudraw.c index de3c3ebab..72b4483c4 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -834,7 +834,7 @@ void M_DrawMenuMessage(void) { workx -= K_DrawGameControl( workx+2, worky, - 0, " ", 2 + 0, "", 2 ); } else @@ -864,7 +864,7 @@ void M_DrawMenuMessage(void) { workx -= K_DrawGameControl( workx+2, worky, - 0, " ", 2 + 0, "", 2 ); } else diff --git a/src/v_draw.cpp b/src/v_draw.cpp index b3559a41c..d2be8526f 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -100,6 +100,7 @@ Draw::TextElement& Draw::TextElement::parse(std::string_view raw) }; // What physical binds should always be rewritten as glyphs anyway? + static const std::unordered_map prettyinputs = { {KEY_UPARROW, 0x00}, {KEY_DOWNARROW, 0x01}, @@ -115,6 +116,21 @@ Draw::TextElement& Draw::TextElement::parse(std::string_view raw) {KEY_AXIS1+3, 0x01}, // Down }; + static const std::unordered_map genericinputs = { + {KEY_JOY1+0, 0x00}, + {KEY_JOY1+1, 0x01}, + {KEY_JOY1+2, 0x02}, + {KEY_JOY1+3, 0x03}, + {KEY_JOY1+9, 0x04}, + {KEY_JOY1+10, 0x05}, + {KEY_AXIS1+8, 0x06}, + {KEY_AXIS1+9, 0x07}, + {KEY_JOY1+6, 0x08}, + {KEY_JOY1+4, 0x09}, + {KEY_JOY1+7, 0x0A}, + {KEY_JOY1+8, 0x0B}, + }; + string_.clear(); string_.reserve(raw.size()); @@ -161,6 +177,11 @@ Draw::TextElement& Draw::TextElement::parse(std::string_view raw) { string_.push_back(0xB0 | pretty->second); // take high bits from glyph invoked and low bits from control } + else if (auto generic = genericinputs.find(bind); generic != genericinputs.end()) // Gamepad direction or keyboard arrow, use something nice-looking + { + string_.push_back(0xEF); + string_.push_back(0xB0 | generic->second); // take high bits from glyph invoked and low bits from control + } else { // string_.append("\x8D"); @@ -298,6 +319,47 @@ void Chain::button_(Button type, int ver, std::optional 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); + X(rb); + X(lt); + X(rt); + X(start); + X(back); + X(ls); + X(rs); + +#undef X + } + + return nullptr; +}; + +void Chain::generic_button_(GenericButton type, int ver, std::optional 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); diff --git a/src/v_draw.hpp b/src/v_draw.hpp index ec8d22800..da3ccce2f 100644 --- a/src/v_draw.hpp +++ b/src/v_draw.hpp @@ -81,6 +81,22 @@ public: dpad, }; + enum class GenericButton + { + a, + b, + x, + y, + lb, + rb, + lt, + rt, + start, + back, + ls, + rs + }; + class TextElement { public: @@ -195,6 +211,9 @@ public: void button(Button type, std::optional press = {}) const { button_(type, 0, press); } void small_button(Button type, std::optional press = {}) const { button_(type, 1, press); } + void generic_button(Button type, std::optional press = {}) const { button_(type, 0, press); } + void generic_small_button(GenericButton type, std::optional 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); } @@ -236,6 +255,7 @@ public: void string(const char* str, INT32 flags, Font font) const; void button_(Button type, int ver, std::optional press = {}) const; + void generic_button_(GenericButton type, int ver, std::optional press = {}) const; friend Draw; }; @@ -285,6 +305,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); diff --git a/src/v_video.cpp b/src/v_video.cpp index 2fcc129a3..49f0e5233 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -2534,6 +2534,48 @@ static UINT8 V_GetButtonCodeWidth(UINT8 c) return x; } +static UINT8 V_GetGenericButtonCodeWidth(UINT8 c) +{ + UINT8 x = 0; + + switch (c & 0x0F) + { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + // buttons + x = 14; + break; + + case 0x04: + case 0x05: + // bumpers + x = 14; + break; + + case 0x06: + case 0x07: + // triggers + x = 14; + break; + + case 0x08: + case 0x09: + // nav + x = 16; + break; + + case 0x0A: + case 0x0B: + // stick click + x = 18; + break; + } + + return x; +} + void V_DrawStringScaled( fixed_t x, fixed_t y, @@ -2561,6 +2603,7 @@ void V_DrawStringScaled( boolean uppercase; boolean notcolored; boolean boxed; + boolean descriptive = false; boolean dance; boolean nodanceoverride; @@ -2658,7 +2701,11 @@ void V_DrawStringScaled( return; cx = x; break; + case '\xEF': + descriptive = true; + break; case '\xEE': + cx += FRACUNIT*dupx; boxed = !boxed; if (boxed) // draw caps { @@ -2716,6 +2763,122 @@ void V_DrawStringScaled( if (( c & 0xB0 ) & 0x80) // button prompts { + if (!descriptive) + { + using srb2::Draw; + + struct BtConf + { + UINT8 x, y; + Draw::Button type; + }; + + auto bt_inst = [c]() -> std::optional + { + 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 0x04: return {{0, 4, Draw::Button::dpad}}; + + case 0x07: return {{0, 2, Draw::Button::r}}; + case 0x08: return {{0, 2, Draw::Button::l}}; + + case 0x09: return {{0, 1, 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 0x0D: return {{2, 1, Draw::Button::x}}; + case 0x0E: return {{2, 1, Draw::Button::y}}; + case 0x0F: return {{2, 1, Draw::Button::z}}; + + default: return {}; + } + }(); + + if (bt_inst) + { + auto bt_translate_press = [c]() -> std::optional + { + switch (c & 0xB0) + { + default: + case 0x90: return true; + case 0xA0: return {}; + case 0xB0: return false; + } + }; + + cw = V_GetButtonCodeWidth(c) * dupx; + cxoff = (*fontspec.dim_fn)(scale, fontspec.chw, hchw, dupx, &cw); + 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()); + cx += cw; + } + break; + } + else + { + using srb2::Draw; + + struct BtConf + { + UINT8 x, y; + Draw::GenericButton type; + }; + + auto bt_inst = [c]() -> std::optional + { + switch (c & 0x0F) + { + case 0x00: return {{0, 2, Draw::GenericButton::a}}; + case 0x01: return {{0, 2, Draw::GenericButton::b}}; + case 0x02: return {{0, 2, Draw::GenericButton::x}}; + case 0x03: return {{0, 2, Draw::GenericButton::y}}; + case 0x04: return {{1, 3, Draw::GenericButton::lb}}; + case 0x05: return {{1, 3, Draw::GenericButton::rb}}; + case 0x06: return {{1, 4, Draw::GenericButton::lt}}; + case 0x07: return {{1, 4, Draw::GenericButton::rt}}; + case 0x08: return {{1, 6, Draw::GenericButton::start}}; + case 0x09: return {{1, 6, Draw::GenericButton::back}}; + case 0x0A: return {{0, 5, Draw::GenericButton::ls}}; + case 0x0B: return {{0, 5, Draw::GenericButton::rs}}; + default: return {}; + } + }(); + + if (bt_inst) + { + auto bt_translate_press = [c]() -> std::optional + { + switch (c & 0xB0) + { + default: + case 0x90: return true; + case 0xA0: return {}; + case 0xB0: return false; + } + }; + + cw = V_GetGenericButtonCodeWidth(c) * dupx; + cxoff = (*fontspec.dim_fn)(scale, fontspec.chw, hchw, dupx, &cw); + Draw( + FixedToFloat(cx + cxoff) - (bt_inst->x * dupx), + FixedToFloat(cy + cyoff) - ((bt_inst->y + fontspec.button_yofs) * dupy)) + .flags(flags) + .generic_small_button(bt_inst->type, bt_translate_press()); + cx += cw; + } + break; + } using srb2::Draw; struct BtConf @@ -2728,10 +2891,10 @@ 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 0x00: return {{1, 3, Draw::Button::up}}; + case 0x01: return {{1, 3, Draw::Button::down}}; + case 0x02: return {{1, 3, Draw::Button::right}}; + case 0x03: return {{1, 3, Draw::Button::left}}; case 0x04: return {{0, 4, Draw::Button::dpad}}; @@ -2797,6 +2960,8 @@ void V_DrawStringScaled( } else cx += fontspec.spacew; + + descriptive = false; } } } @@ -2817,6 +2982,7 @@ fixed_t V_StringScaledWidth( font_t *font; boolean uppercase; + boolean descriptive = false;; fixed_t cx; fixed_t right; @@ -2875,7 +3041,11 @@ fixed_t V_StringScaledWidth( case '\n': cx = 0; break; + case '\xEF': + descriptive = true; + break; case '\xEE': + cx += FRACUNIT*dupx; break; default: if (( c & 0xF0 ) == 0x80 || c == V_STRINGDANCE) @@ -2883,10 +3053,20 @@ fixed_t V_StringScaledWidth( if (( c & 0xB0 ) & 0x80) { - cw = V_GetButtonCodeWidth(c) * dupx; - cx += cw * scale; - right = cx; - break; + if (descriptive) + { + cw = V_GetGenericButtonCodeWidth(c) * dupx; + cx += cw * scale; + right = cx; + break; + } + else + { + cw = V_GetButtonCodeWidth(c) * dupx; + cx += cw * scale; + right = cx; + break; + } } if (uppercase) @@ -2921,6 +3101,7 @@ fixed_t V_StringScaledWidth( } else cx += fontspec.spacew; + descriptive = false; } fullwidth = std::max(right, std::max(cx, fullwidth));