diff --git a/src/k_hud.cpp b/src/k_hud.cpp index 79842bf29..ab8bfb577 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -1009,7 +1009,7 @@ void K_LoadKartHUDGraphics(void) K_LoadGenericButtonGraphics(gen_button_rs, 'U'); HU_UpdatePatch(&gen_button_keyleft[0], "TLK_L"); - HU_UpdatePatch(&gen_button_keyleft[1], "TLK_R"); + 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"); @@ -6496,16 +6496,14 @@ void K_drawKartHUD(void) #if 1 using srb2::Draw; - if (0) + if (1) { - Draw::TextElement text = Draw::TextElement().parse("A B C X Y Z \nST L R U D L R "); + // Draw::TextElement text = Draw::TextElement().parse("A B C X Y Z \nST L R U D L R "); + Draw::TextElement text = Draw::TextElement().parse("Unpressed Pressed Animated "); - 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, 35).align((srb2::Draw::Align)0).font(Draw::Font::kThin).text(text); - stplyr = oldstplyr; + UINT8 fakeoff = (stplyr - players)*40; + Draw(5, 5+fakeoff).align((srb2::Draw::Align)0).font(Draw::Font::kMenu).text(text); + Draw(5, 20+fakeoff).align((srb2::Draw::Align)0).font(Draw::Font::kThin).text(text); } @@ -6514,13 +6512,8 @@ void K_drawKartHUD(void) 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; - - player_t *oldstplyr = stplyr; - stplyr = &players[0]; Draw(160+offset, 5).align((srb2::Draw::Align)1).font(Draw::Font::kThin).text(text); - stplyr = &players[1]; Draw(55+offset, 5).align((srb2::Draw::Align)1).font(Draw::Font::kMenu).text(text); - stplyr = oldstplyr; } /* diff --git a/src/k_menudraw.c b/src/k_menudraw.c index ff042ce20..459148362 100644 --- a/src/k_menudraw.c +++ b/src/k_menudraw.c @@ -2464,11 +2464,11 @@ void M_DrawCharacterSelect(void) //K_drawButton((x += 22) * FRACUNIT, (kTop - 3) * FRACUNIT, 0, kp_button_r, M_MenuButtonPressed(pid, MBT_R)); // x += K_DrawGameControl(x, kTop, 0, "", 0); // V_DrawThinString((x), kTop, 0, "Info"); - K_DrawGameControl(BASEVIDWIDTH/2, kTop, 0, " Info Default", 1, 0); + K_DrawGameControl(BASEVIDWIDTH/2, kTop, 0, " Info Default", 1, 0); } else { - K_DrawGameControl(BASEVIDWIDTH/2, kTop, 0, " Accept Back Default", 1, 0); + K_DrawGameControl(BASEVIDWIDTH/2, kTop, 0, " Accept Back Default", 1, 0); } x += 58; diff --git a/src/v_draw.cpp b/src/v_draw.cpp index b387a2fa8..73f78f147 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -61,6 +61,8 @@ Draw::TextElement& Draw::TextElement::parse(std::string_view raw) #undef BUTTON + {"large", 0xEB}, + {"white", 0x80}, {"purple", 0x81}, {"yellow", 0x82}, @@ -166,7 +168,7 @@ Draw::TextElement& Draw::TextElement::parse(std::string_view raw) // FIXME: This isn't how v_video.cpp checks for buttons and I don't know why. if (cv_descriptiveinput.value && ((it->second & 0xF0) != 0x80)) // Should we do game control translation? { - if (auto id = inputdefinition.find(it->second & (~0xF0)); id != inputdefinition.end()) // This is a game control, do descriptive input 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 UINT8 localplayer = 0; @@ -193,14 +195,22 @@ Draw::TextElement& Draw::TextElement::parse(std::string_view raw) } else { - string_.push_back('\xEE'); // Control code: "toggle boxed drawing" + 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("[NOT BOUND]"); else string_.append((G_KeynumToShortString(bind))); - string_.push_back('\xEE'); + string_.push_back(code); } } else // This is a color code or some other generic glyph, treat it as is. diff --git a/src/v_draw.hpp b/src/v_draw.hpp index 6035e2317..a1c2a86c0 100644 --- a/src/v_draw.hpp +++ b/src/v_draw.hpp @@ -218,7 +218,7 @@ 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_button(GenericButton type, std::optional press = {}) const { generic_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; diff --git a/src/v_video.cpp b/src/v_video.cpp index 90b5ee48e..1ba86ecae 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -2606,6 +2606,8 @@ void V_DrawStringScaled( boolean nodanceoverride; INT32 dancecounter; + boolean largebutton = false; + fixed_t cx, cy; fixed_t cxsave; @@ -2703,41 +2705,66 @@ void V_DrawStringScaled( return; cx = x; break; + case '\xEB': + 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 { - // TODO animate cy -= 2*FRACUNIT; - Draw(FixedToFloat(cx), FixedToFloat(cy)-3).patch(gen_button_keyleft[0]); + + Draw(FixedToFloat(cx), FixedToFloat(cy)-3).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; - // TODO animate - Draw(FixedToFloat(working), FixedToFloat(cy)-3) - .width(FixedToFloat(cx - working)) - .stretch(Draw::Stretch::kWidth).patch(gen_button_keycenter[0]); - Draw(FixedToFloat(cx), FixedToFloat(cy)-3).patch(gen_button_keyright[0]); + + Draw(FixedToFloat(working)+1, FixedToFloat(cy)-3) + .width(FixedToFloat(cx - working)-1) + .stretch(Draw::Stretch::kWidth).patch(gen_button_keycenter[anim]); + Draw(FixedToFloat(cx), FixedToFloat(cy)-3).patch(gen_button_keyright[anim]); + s = ssave; cx = cxsave; - boxed = 2; + + // 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) { @@ -2836,13 +2863,21 @@ void V_DrawStringScaled( cw = V_GetButtonCodeWidth(c) * dupx; cxoff = (*fontspec.dim_fn)(scale, fontspec.chw, hchw, dupx, &cw); - Draw( + + 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 @@ -2890,73 +2925,23 @@ void V_DrawStringScaled( cw = V_GetGenericButtonCodeWidth(c) * dupx; cxoff = (*fontspec.dim_fn)(scale, fontspec.chw, hchw, dupx, &cw); - Draw( + + Draw bt = 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()); + .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; } - using srb2::Draw; - - struct BtConf - { - UINT8 x, y; - Draw::Button type; - }; - - auto bt_inst = [c]() -> std::optional - { - switch (c & 0x0F) - { - 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}}; - - 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; } @@ -2970,16 +2955,14 @@ void V_DrawStringScaled( if (boxed != 1) { - V_DrawFixedPatch(cx + cxoff + patchxofs, cy + cyoff, scale, - flags | ((boxed == 2) ? V_40TRANS : 0), font->font[c], colormap); + V_DrawFixedPatch(cx + cxoff + patchxofs, cy + cyoff + (boxed == 3 ? 2*FRACUNIT : 0), scale, + flags | ((!!boxed) ? V_40TRANS : 0), font->font[c], colormap); } cx += cw; } else cx += fontspec.spacew; - - descriptive = false; } } } @@ -3001,7 +2984,8 @@ fixed_t V_StringScaledWidth( boolean uppercase; boolean boxed = false; - boolean descriptive = false;; + boolean descriptive = false; + boolean largebutton = false; fixed_t cx; fixed_t right; @@ -3060,10 +3044,14 @@ fixed_t V_StringScaledWidth( case '\n': cx = 0; break; + case '\xEB': + largebutton = true; case '\xEF': descriptive = true; break; case '\xEE': + case '\xED': + case '\xEC': if (boxed) cx += 3*FRACUNIT; else @@ -3081,15 +3069,17 @@ fixed_t V_StringScaledWidth( cw = V_GetGenericButtonCodeWidth(c) * dupx; cx += cw * scale; right = cx; - break; } else { cw = V_GetButtonCodeWidth(c) * dupx; cx += cw * scale; right = cx; - break; } + + largebutton = false; + descriptive = false; + break; } if (uppercase)