mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-01-11 09:12:22 +00:00
Merge branch 'button-drawer' into 'master'
Embed button prompts in string drawers (ACS Dialogue support) Closes #943 See merge request KartKrew/Kart!1847
This commit is contained in:
commit
d20ef561b9
5 changed files with 235 additions and 10 deletions
|
|
@ -218,18 +218,20 @@ void Dialogue::SetSpeaker(std::string name, patch_t *patch, UINT8 *colormap, sfx
|
|||
typewriter.voiceSfx = voice;
|
||||
}
|
||||
|
||||
void Dialogue::NewText(std::string newText)
|
||||
void Dialogue::NewText(std::string_view rawText)
|
||||
{
|
||||
Init();
|
||||
|
||||
newText = V_ScaledWordWrap(
|
||||
char* newText = V_ScaledWordWrap(
|
||||
290 << FRACBITS,
|
||||
FRACUNIT, FRACUNIT, FRACUNIT,
|
||||
0, HU_FONT,
|
||||
newText.c_str()
|
||||
srb2::Draw::TextElement().parse(rawText).string().c_str() // parse special characters
|
||||
);
|
||||
|
||||
typewriter.NewText(newText);
|
||||
|
||||
Z_Free(newText);
|
||||
}
|
||||
|
||||
bool Dialogue::Active(void)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#define __K_DIALOGUE_HPP__
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "doomtype.h"
|
||||
|
|
@ -34,7 +35,7 @@ public:
|
|||
void SetSpeaker(std::string skinName, int portraitID);
|
||||
void SetSpeaker(std::string name, patch_t *patch, UINT8 *colormap, sfxenum_t voice);
|
||||
|
||||
void NewText(std::string newText);
|
||||
void NewText(std::string_view newText);
|
||||
|
||||
bool Active(void);
|
||||
bool TextDone(void);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "doomdef.h" // skincolornum_t
|
||||
#include "doomtype.h"
|
||||
#include "hu_stuff.h"
|
||||
|
|
@ -27,6 +29,96 @@ int Draw::TextElement::width() const
|
|||
return font_ ? font_width(*font_, default_font_flags(*font_) | flags_.value_or(0), string_.c_str()) / FRACUNIT : 0;
|
||||
}
|
||||
|
||||
Draw::TextElement& Draw::TextElement::parse(std::string_view raw)
|
||||
{
|
||||
static const std::unordered_map<std::string_view, char> translation = {
|
||||
#define BUTTON(str, lower_bits) \
|
||||
{str, 0xB0 | lower_bits},\
|
||||
{str "_animated", 0xA0 | lower_bits},\
|
||||
{str "_pressed", 0x90 | lower_bits}
|
||||
|
||||
BUTTON("up", 0x00),
|
||||
BUTTON("down", 0x01),
|
||||
BUTTON("right", 0x02),
|
||||
BUTTON("left", 0x03),
|
||||
|
||||
BUTTON("r", 0x07),
|
||||
BUTTON("l", 0x08),
|
||||
BUTTON("start", 0x09),
|
||||
|
||||
BUTTON("a", 0x0A),
|
||||
BUTTON("b", 0x0B),
|
||||
BUTTON("c", 0x0C),
|
||||
|
||||
BUTTON("x", 0x0D),
|
||||
BUTTON("y", 0x0E),
|
||||
BUTTON("z", 0x0F),
|
||||
|
||||
#undef BUTTON
|
||||
|
||||
{"white", 0x80},
|
||||
{"purple", 0x81},
|
||||
{"yellow", 0x82},
|
||||
{"green", 0x83},
|
||||
{"blue", 0x84},
|
||||
{"red", 0x85},
|
||||
{"gray", 0x86},
|
||||
{"orange", 0x87},
|
||||
{"sky", 0x88},
|
||||
{"lavender", 0x89},
|
||||
{"gold", 0x8A},
|
||||
{"aqua", 0x8B},
|
||||
{"magenta", 0x8C},
|
||||
{"pink", 0x8D},
|
||||
{"brown", 0x8E},
|
||||
{"tan", 0x8F},
|
||||
};
|
||||
|
||||
string_.clear();
|
||||
string_.reserve(raw.size());
|
||||
|
||||
using std::size_t;
|
||||
using std::string_view;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
size_t p = raw.find('<');
|
||||
|
||||
// Copy characters until the start tag
|
||||
string_.append(raw.substr(0, p));
|
||||
|
||||
if (p == raw.npos)
|
||||
{
|
||||
break; // end of string
|
||||
}
|
||||
|
||||
raw.remove_prefix(p);
|
||||
|
||||
// Find end tag
|
||||
p = raw.find('>');
|
||||
|
||||
if (p == raw.npos)
|
||||
{
|
||||
break; // no end tag
|
||||
}
|
||||
|
||||
string_view code = raw.substr(1, p - 1);
|
||||
|
||||
if (auto it = translation.find(code); it != translation.end())
|
||||
{
|
||||
string_.push_back(it->second); // replace with character code
|
||||
}
|
||||
else
|
||||
{
|
||||
string_.append(raw.substr(0, p + 1)); // code not found, leave text verbatim
|
||||
}
|
||||
|
||||
raw.remove_prefix(p + 1); // past end of tag
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Chain::patch(patch_t* patch) const
|
||||
{
|
||||
const auto _ = Clipper(*this);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#define __V_DRAW_HPP__
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
|
|
@ -75,6 +76,8 @@ public:
|
|||
class TextElement
|
||||
{
|
||||
public:
|
||||
explicit TextElement() {}
|
||||
|
||||
explicit TextElement(std::string string) : string_(string) {}
|
||||
|
||||
template <class... Args>
|
||||
|
|
@ -95,6 +98,14 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
TextElement& parse(std::string_view string);
|
||||
|
||||
template <class... Args>
|
||||
TextElement& parse(fmt::format_string<Args...> format, Args&&... args)
|
||||
{
|
||||
return parse(fmt::format(format, args...));
|
||||
}
|
||||
|
||||
TextElement& font(Font font)
|
||||
{
|
||||
font_ = font;
|
||||
|
|
@ -157,6 +168,8 @@ public:
|
|||
template <class... Args>
|
||||
void text(fmt::format_string<Args...> format, Args&&... args) const { text(fmt::format(format, args...)); }
|
||||
|
||||
TextElement text() const { return TextElement().font(font_).flags(flags_); }
|
||||
|
||||
void patch(patch_t* patch) const;
|
||||
void patch(const char* name) const;
|
||||
|
||||
|
|
@ -238,13 +251,14 @@ public:
|
|||
|
||||
#define VOID_METHOD(Name) \
|
||||
template <typename... Args>\
|
||||
void Name (Args&&... args) const { return chain_.Name(std::forward<Args>(args)...); }
|
||||
auto Name (Args&&... args) const { return chain_.Name(std::forward<Args>(args)...); }
|
||||
|
||||
VOID_METHOD(text);
|
||||
VOID_METHOD(patch);
|
||||
VOID_METHOD(thumbnail);
|
||||
VOID_METHOD(fill);
|
||||
VOID_METHOD(button);
|
||||
VOID_METHOD(small_button);
|
||||
|
||||
#undef VOID_METHOD
|
||||
|
||||
|
|
|
|||
126
src/v_video.cpp
126
src/v_video.cpp
|
|
@ -14,6 +14,7 @@
|
|||
/// Functions to blit a block to the screen.
|
||||
|
||||
#include <cmath>
|
||||
#include <optional>
|
||||
|
||||
#include <tracy/tracy/Tracy.hpp>
|
||||
|
||||
|
|
@ -45,6 +46,7 @@
|
|||
#include "k_hud.h"
|
||||
#include "k_boss.h"
|
||||
#include "i_time.h"
|
||||
#include "v_draw.hpp"
|
||||
|
||||
using namespace srb2;
|
||||
|
||||
|
|
@ -1796,7 +1798,7 @@ void V_DrawCharacterScaled(
|
|||
|
||||
if (notColored == true)
|
||||
{
|
||||
if (( c & 0x80 ))
|
||||
if (( c & 0xF0 ) == 0x80)
|
||||
{
|
||||
colormap = V_GetStringColormap(
|
||||
( ( c & 0x7f ) << V_CHARCOLORSHIFT ) & V_CHARCOLORMASK
|
||||
|
|
@ -2413,6 +2415,41 @@ static void V_GetFontSpecification(int fontno, INT32 flags, fontspec_t *result)
|
|||
}
|
||||
}
|
||||
|
||||
static UINT8 V_GetButtonCodeWidth(UINT8 c)
|
||||
{
|
||||
UINT8 x = 0;
|
||||
|
||||
switch (c & 0x0F)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
// arrows
|
||||
x = 12;
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
// shoulders, start
|
||||
x = 14;
|
||||
break;
|
||||
|
||||
case 0x0A:
|
||||
case 0x0B:
|
||||
case 0x0C:
|
||||
case 0x0D:
|
||||
case 0x0E:
|
||||
case 0x0F:
|
||||
// faces
|
||||
x = 10;
|
||||
break;
|
||||
}
|
||||
|
||||
return x + 2;
|
||||
}
|
||||
|
||||
void V_DrawStringScaled(
|
||||
fixed_t x,
|
||||
fixed_t y,
|
||||
|
|
@ -2427,6 +2464,7 @@ void V_DrawStringScaled(
|
|||
INT32 hchw;/* half-width for centering */
|
||||
|
||||
INT32 dupx;
|
||||
INT32 dupy;
|
||||
|
||||
fixed_t right;
|
||||
fixed_t bot;
|
||||
|
|
@ -2491,18 +2529,20 @@ void V_DrawStringScaled(
|
|||
if (( flags & V_NOSCALESTART ))
|
||||
{
|
||||
dupx = vid.dupx;
|
||||
dupy = vid.dupy;
|
||||
|
||||
hchw *= dupx;
|
||||
|
||||
fontspec.chw *= dupx;
|
||||
fontspec.spacew *= dupx;
|
||||
fontspec.lfh *= vid.dupy;
|
||||
fontspec.lfh *= dupy;
|
||||
|
||||
right = vid.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
dupx = 1;
|
||||
dupy = 1;
|
||||
|
||||
right = ( vid.width / vid.dupx );
|
||||
if (!( flags & V_SNAPTOLEFT ))
|
||||
|
|
@ -2530,7 +2570,7 @@ void V_DrawStringScaled(
|
|||
cx = x;
|
||||
break;
|
||||
default:
|
||||
if (( c & 0x80 ))
|
||||
if (( c & 0xF0 ) == 0x80)
|
||||
{
|
||||
if (notcolored)
|
||||
{
|
||||
|
|
@ -2572,6 +2612,68 @@ void V_DrawStringScaled(
|
|||
cyoff = V_DanceYOffset(dancecounter) * FRACUNIT;
|
||||
}
|
||||
|
||||
if (( c & 0xB0 ) & 0x80) // button prompts
|
||||
{
|
||||
using srb2::Draw;
|
||||
|
||||
struct BtConf
|
||||
{
|
||||
UINT8 x, y;
|
||||
Draw::Button type;
|
||||
};
|
||||
|
||||
auto bt_inst = [c]() -> std::optional<BtConf>
|
||||
{
|
||||
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 0x07: return {{0, 1, Draw::Button::r}};
|
||||
case 0x08: return {{0, 1, 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<bool>
|
||||
{
|
||||
switch (c & 0xB0)
|
||||
{
|
||||
default:
|
||||
case 0x90: return true;
|
||||
case 0xA0: return {};
|
||||
case 0xB0: return false;
|
||||
}
|
||||
};
|
||||
|
||||
Draw(
|
||||
FixedToFloat(cx) - (bt_inst->x * dupx),
|
||||
FixedToFloat(cy + cyoff) - (bt_inst->y * dupy))
|
||||
.flags(flags)
|
||||
.small_button(bt_inst->type, bt_translate_press());
|
||||
}
|
||||
|
||||
cw = V_GetButtonCodeWidth(c) * dupx;
|
||||
cx += cw * scale;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
c -= font->start;
|
||||
if (V_CharacterValid(font, c) == true)
|
||||
{
|
||||
|
|
@ -2662,9 +2764,17 @@ fixed_t V_StringScaledWidth(
|
|||
cx = 0;
|
||||
break;
|
||||
default:
|
||||
if (( c & 0x80 ))
|
||||
if (( c & 0xF0 ) == 0x80 || c == V_STRINGDANCE)
|
||||
continue;
|
||||
|
||||
if (( c & 0xB0 ) & 0x80)
|
||||
{
|
||||
cw = V_GetButtonCodeWidth(c) * dupx;
|
||||
cx += cw * scale;
|
||||
right = cx;
|
||||
break;
|
||||
}
|
||||
|
||||
if (uppercase)
|
||||
{
|
||||
c = toupper(c);
|
||||
|
|
@ -2794,8 +2904,14 @@ char * V_ScaledWordWrap(
|
|||
startwriter = 0;
|
||||
break;
|
||||
default:
|
||||
if (( c & 0x80 ))
|
||||
if (( c & 0xF0 ) == 0x80 || c == V_STRINGDANCE)
|
||||
;
|
||||
else if (( c & 0xB0 ) & 0x80) // button prompts
|
||||
{
|
||||
cw = V_GetButtonCodeWidth(c) * dupx;
|
||||
cx += cw * scale;
|
||||
right = cx;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (uppercase)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue