1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-15 06:52:34 +02:00

rwengine+rwgame: convert utf8 to GameString depending on used font

This commit is contained in:
Anonymous Maarten 2017-09-07 19:00:16 +02:00
parent 12afe81a35
commit 640af372ba
17 changed files with 122 additions and 94 deletions

View File

@ -86,7 +86,7 @@ void Payphone::tick(float dt) {
if (!message.empty()) { if (!message.empty()) {
const auto& text = const auto& text =
ScreenText::format(engine->data->texts.text(message)); ScreenText::format(engine->data->texts.text(message), FONT_ARIAL);
engine->state->text.clear<ScreenTextType::HighPriority>(); engine->state->text.clear<ScreenTextType::HighPriority>();
engine->state->text.addText<ScreenTextType::HighPriority>( engine->state->text.addText<ScreenTextType::HighPriority>(
@ -124,4 +124,4 @@ void Payphone::tick(float dt) {
default: { break; } default: { break; }
} }
} }

View File

@ -2,6 +2,8 @@
#include <rw/debug.hpp> #include <rw/debug.hpp>
#include "fonts/FontMapGta3.hpp"
void ScreenText::tick(float dt) { void ScreenText::tick(float dt) {
int millis = dt * 1000; int millis = dt * 1000;
@ -35,7 +37,7 @@ ScreenTextEntry ScreenTextEntry::makeBig(const GameStringKey& id,
case 1: case 1:
return {str, return {str,
{320.f, 252.f}, {320.f, 252.f},
1, FONT_PRICEDOWN,
50, 50,
{2, 0, 0, 0}, {2, 0, 0, 0},
{58, 119, 133}, {58, 119, 133},
@ -54,7 +56,7 @@ ScreenTextEntry ScreenTextEntry::makeBig(const GameStringKey& id,
case 2: case 2:
return {str, return {str,
{620.f, 380.f}, {620.f, 380.f},
1, FONT_PRICEDOWN,
30, 30,
{2, 3, 0, 0}, {2, 3, 0, 0},
{214, 171, 9}, {214, 171, 9},
@ -73,7 +75,7 @@ ScreenTextEntry ScreenTextEntry::makeBig(const GameStringKey& id,
case 3: case 3:
return {str, return {str,
{320.f, 400.f}, {320.f, 400.f},
1, FONT_PRICEDOWN,
50, 50,
{5, 5, 0, 0}, {5, 5, 0, 0},
{169, 123, 88}, /// @todo verify {169, 123, 88}, /// @todo verify
@ -93,7 +95,7 @@ ScreenTextEntry ScreenTextEntry::makeBig(const GameStringKey& id,
case 5: case 5:
return {str, return {str,
{320.f, 176.f}, {320.f, 176.f},
2, FONT_ARIAL,
50, 50,
((style == 4) ? glm::u8vec4({2, 2, 0, 0}) ((style == 4) ? glm::u8vec4({2, 2, 0, 0})
: glm::u8vec4({-2, -2, 0, 0})), : glm::u8vec4({-2, -2, 0, 0})),
@ -113,7 +115,7 @@ ScreenTextEntry ScreenTextEntry::makeBig(const GameStringKey& id,
case 6: case 6:
return {str, return {str,
{320.f, 240.f}, {320.f, 240.f},
2, FONT_ARIAL,
50, 50,
{2, 2, 0, 0}, {2, 2, 0, 0},
{152, 89, 39}, {152, 89, 39},
@ -128,9 +130,9 @@ ScreenTextEntry ScreenTextEntry::makeBig(const GameStringKey& id,
break; break;
} }
return {GameStringUtil::fromString("Error, style " + std::to_string(style)), return {GameStringUtil::fromString("Error, style " + std::to_string(style), FONT_PRICEDOWN),
{320.f, 400.f}, {320.f, 400.f},
2, FONT_ARIAL,
50, 50,
{20, 20, 0, 0}, {20, 20, 0, 0},
{20, 20, 200}, {20, 20, 200},
@ -152,7 +154,7 @@ ScreenTextEntry ScreenTextEntry::makeHighPriority(const GameStringKey& id,
// @todo verify: Size: 15 Pixel high letters ('S', 'l') // @todo verify: Size: 15 Pixel high letters ('S', 'l')
return {str, return {str,
{320.f, 420.f}, {320.f, 420.f},
2, FONT_ARIAL,
18, 18,
{1, 0, 0, 0}, {1, 0, 0, 0},
{255, 255, 255}, {255, 255, 255},
@ -165,7 +167,7 @@ ScreenTextEntry ScreenTextEntry::makeHighPriority(const GameStringKey& id,
ScreenTextEntry ScreenTextEntry::makeHelp(const GameStringKey& id, ScreenTextEntry ScreenTextEntry::makeHelp(const GameStringKey& id,
const GameString& str) { const GameString& str) {
return {str, {20.f, 20.f}, 2, 18, {0, 0, 0, 255}, {255, 255, 255}, 0, 5000, return {str, {20.f, 20.f}, FONT_ARIAL, 18, {0, 0, 0, 255}, {255, 255, 255}, 0, 5000,
0, 35, id}; 0, 35, id};
} }
@ -173,7 +175,7 @@ ScreenTextEntry ScreenTextEntry::makeHiddenPackageText(const GameStringKey& id,
const GameString& str) { const GameString& str) {
return {str, return {str,
{318.f, 138.f}, {318.f, 138.f},
2, FONT_ARIAL,
33, 33,
{2, 2, 0, 0}, {2, 2, 0, 0},
{0x59, 0x73, 0x96}, {0x59, 0x73, 0x96},

View File

@ -143,8 +143,8 @@ public:
} }
template <class... Args> template <class... Args>
static GameString format(GameString format, Args&&... args) { static GameString format(GameString format, font_t font, Args&&... args) {
static auto kReplacementMarker = GameStringUtil::fromString("~1~"); static auto kReplacementMarker = GameStringUtil::fromString("~1~", font);
const std::array<GameString, sizeof...(args)> vals = {{args...}}; const std::array<GameString, sizeof...(args)> vals = {{args...}};
size_t x = 0, val = 0; size_t x = 0, val = 0;
// We're only looking for numerical replacement markers // We're only looking for numerical replacement markers

View File

@ -404,10 +404,11 @@ bool CollectablePickup::onPlayerTouch() {
auto text = ScreenText::format( auto text = ScreenText::format(
engine->data->texts.text(gxtEntry), engine->data->texts.text(gxtEntry),
FONT_PRICEDOWN,
GameStringUtil::fromString( GameStringUtil::fromString(
std::to_string(state->playerInfo.hiddenPackagesCollected)), std::to_string(state->playerInfo.hiddenPackagesCollected), FONT_PRICEDOWN),
GameStringUtil::fromString( GameStringUtil::fromString(
std::to_string(state->playerInfo.hiddenPackageCount))); std::to_string(state->playerInfo.hiddenPackageCount), FONT_PRICEDOWN));
state->text.addText<ScreenTextType::HiddenPackageText>( state->text.addText<ScreenTextType::HiddenPackageText>(
ScreenTextEntry::makeHiddenPackageText(gxtEntry, text)); ScreenTextEntry::makeHiddenPackageText(gxtEntry, text));
@ -448,4 +449,4 @@ bool BigNVeinyPickup::onPlayerVehicleTouch() {
engine->state->bigNVeinyPickupsCollected++; engine->state->bigNVeinyPickupsCollected++;
return true; return true;
} }

View File

@ -76,7 +76,7 @@ public:
* should be controlled via a different mechanism. * should be controlled via a different mechanism.
*/ */
struct DrawParameters { struct DrawParameters {
/// Number of indicies /// Number of indices
size_t count{}; size_t count{};
/// Start index. /// Start index.
unsigned int start{}; unsigned int start{};

View File

@ -18,10 +18,10 @@ int charToIndex(uint16_t g) {
return g - 32; return g - 32;
} }
glm::vec4 indexToCoord(int font, int index) { glm::vec4 indexToCoord(font_t font, int index) {
float x = static_cast<int>(index % 16); float x = static_cast<int>(index % 16);
float y = static_cast<int>(index / 16) + 0.01f; float y = static_cast<int>(index / 16) + 0.01f;
float fontHeight = ((font == 0) ? 16.f : 13.f); float fontHeight = ((font == FONT_PAGER) ? 16.f : 13.f);
glm::vec2 gsize(1.f / 16.f, 1.f / fontHeight); glm::vec2 gsize(1.f / 16.f, 1.f / fontHeight);
return glm::vec4(x, y, x + 1, y + 0.98f) * glm::vec4(gsize, gsize); return glm::vec4(x, y, x + 1, y + 0.98f) * glm::vec4(gsize, gsize);
} }
@ -100,31 +100,25 @@ TextRenderer::TextRenderer(GameRenderer* renderer) : renderer(renderer) {
glyphData[charToIndex(g)].widthFrac = 0.65f; glyphData[charToIndex(g)].widthFrac = 0.65f;
} }
// Assumes contigious a-z character encoding // Assumes contiguous a-z character encoding
for (char g = 0; g <= ('z' - 'a'); g++) { for (char g = 0; g <= ('z' - 'a'); g++) {
switch (('a' + g)) { glyphData[charToIndex('a' + g)].widthFrac = 0.7f;
case 'i': glyphData[charToIndex('A' + g)].widthFrac = 0.7f;
glyphData[charToIndex('a' + g)].widthFrac = 0.4f;
glyphData[charToIndex('A' + g)].widthFrac = 0.4f;
break;
case 'l':
glyphData[charToIndex('a' + g)].widthFrac = 0.5f;
glyphData[charToIndex('A' + g)].widthFrac = 0.5f;
break;
case 'm':
glyphData[charToIndex('a' + g)].widthFrac = 1.0f;
glyphData[charToIndex('A' + g)].widthFrac = 1.0f;
break;
case 'w':
glyphData[charToIndex('a' + g)].widthFrac = 1.0f;
glyphData[charToIndex('A' + g)].widthFrac = 1.0f;
break;
default:
glyphData[charToIndex('a' + g)].widthFrac = 0.7f;
glyphData[charToIndex('A' + g)].widthFrac = 0.7f;
break;
}
} }
// case 'i':
glyphData[charToIndex('i')].widthFrac = 0.4f;
glyphData[charToIndex('I')].widthFrac = 0.4f;
// case 'l':
glyphData[charToIndex('l')].widthFrac = 0.5f;
glyphData[charToIndex('L')].widthFrac = 0.5f;
// case 'm':
glyphData[charToIndex('m')].widthFrac = 1.0f;
glyphData[charToIndex('M')].widthFrac = 1.0f;
// case 'w':
glyphData[charToIndex('w')].widthFrac = 1.0f;
glyphData[charToIndex('W')].widthFrac = 1.0f;
// case 'accent aigu'
glyphData[0x91].widthFrac = 0.6f;
} }
void TextRenderer::setFontTexture(int index, const std::string& texture) { void TextRenderer::setFontTexture(int index, const std::string& texture) {

View File

@ -33,7 +33,7 @@ public:
enum TextAlignment { Left = 0, Right = 1, Center = 2 }; enum TextAlignment { Left = 0, Right = 1, Center = 2 };
/// Font index @see TextRenderer::setFontTexture /// Font index @see TextRenderer::setFontTexture
int font{0}; font_t font{FONT_PAGER};
/// Message to be displayed (including markup) /// Message to be displayed (including markup)
GameString text; GameString text;
/// On screen position /// On screen position

View File

@ -5376,13 +5376,13 @@ void opcode_01e2(const ScriptArguments& args, const ScriptInt arg1, const Script
*/ */
void opcode_01e3(const ScriptArguments& args, const ScriptString gxtEntry, const ScriptInt arg2, const ScriptInt time, const ScriptInt style) { void opcode_01e3(const ScriptArguments& args, const ScriptString gxtEntry, const ScriptInt arg2, const ScriptInt time, const ScriptInt style) {
auto str = auto str =
ScreenText::format( ScreenText::format(
script::gxt(args, gxtEntry), script::gxt(args, gxtEntry),
GameStringUtil::fromString(std::to_string(arg2))); FONT_PRICEDOWN,
GameStringUtil::fromString(std::to_string(arg2), FONT_PRICEDOWN));
args.getState()->text.addText<ScreenTextType::Big>( args.getState()->text.addText<ScreenTextType::Big>(
ScreenTextEntry::makeBig( ScreenTextEntry::makeBig(
gxtEntry, str, style, time gxtEntry, str, style, time));
));
} }
/** /**
@ -9763,8 +9763,9 @@ void opcode_036d(const ScriptArguments& args, const ScriptString gxtEntry, const
auto str = auto str =
ScreenText::format(script::gxt(args, gxtEntry), ScreenText::format(script::gxt(args, gxtEntry),
GameStringUtil::fromString(std::to_string(arg2)), FONT_PRICEDOWN,
GameStringUtil::fromString(std::to_string(arg3))); GameStringUtil::fromString(std::to_string(arg2), FONT_PRICEDOWN),
GameStringUtil::fromString(std::to_string(arg3), FONT_PRICEDOWN));
auto textEntry = ScreenTextEntry::makeBig(gxtEntry, str, style, time); auto textEntry = ScreenTextEntry::makeBig(gxtEntry, str, style, time);
world->state->text.addText<ScreenTextType::Big>(textEntry); world->state->text.addText<ScreenTextType::Big>(textEntry);

View File

@ -42,7 +42,7 @@ void drawScriptTimer(GameWorld* world, GameRenderer* render) {
float scriptTimerTextY = ui_scriptTimerHeight; float scriptTimerTextY = ui_scriptTimerHeight;
TextRenderer::TextInfo ti; TextRenderer::TextInfo ti;
ti.font = 1; ti.font = FONT_PRICEDOWN;
ti.size = ui_textSize; ti.size = ui_textSize;
ti.align = TextRenderer::TextInfo::Right; ti.align = TextRenderer::TextInfo::Right;
@ -52,7 +52,7 @@ void drawScriptTimer(GameWorld* world, GameRenderer* render) {
ss << std::setw(2) << std::setfill('0') << seconds / 60 ss << std::setw(2) << std::setfill('0') << seconds / 60
<< std::setw(0) << ":" << std::setw(2) << seconds % 60; << std::setw(0) << ":" << std::setw(2) << seconds % 60;
ti.text = GameStringUtil::fromString(ss.str()); ti.text = GameStringUtil::fromString(ss.str(), ti.font);
} }
ti.baseColour = ui_shadowColour; ti.baseColour = ui_shadowColour;
@ -107,7 +107,7 @@ void drawPlayerInfo(PlayerController* player, GameWorld* world,
float wantedY = ui_wantedLevelHeight; float wantedY = ui_wantedLevelHeight;
TextRenderer::TextInfo ti; TextRenderer::TextInfo ti;
ti.font = 1; ti.font = FONT_PRICEDOWN;
ti.size = ui_textSize; ti.size = ui_textSize;
ti.align = TextRenderer::TextInfo::Right; ti.align = TextRenderer::TextInfo::Right;
@ -116,7 +116,7 @@ void drawPlayerInfo(PlayerController* player, GameWorld* world,
ss << std::setw(2) << std::setfill('0') << world->getHour() ss << std::setw(2) << std::setfill('0') << world->getHour()
<< std::setw(0) << ":" << std::setw(2) << world->getMinute(); << std::setw(0) << ":" << std::setw(2) << world->getMinute();
ti.text = GameStringUtil::fromString(ss.str()); ti.text = GameStringUtil::fromString(ss.str(), ti.font);
} }
ti.baseColour = ui_shadowColour; ti.baseColour = ui_shadowColour;
@ -135,7 +135,7 @@ void drawPlayerInfo(PlayerController* player, GameWorld* world,
ss << std::setw(8) << std::setfill('0') ss << std::setw(8) << std::setfill('0')
<< world->state->playerInfo.displayedMoney; << world->state->playerInfo.displayedMoney;
ti.text = GameSymbols::Money + GameStringUtil::fromString(ss.str()); ti.text = GameSymbols::Money + GameStringUtil::fromString(ss.str(), ti.font);
} }
ti.baseColour = ui_shadowColour; ti.baseColour = ui_shadowColour;
@ -157,7 +157,7 @@ void drawPlayerInfo(PlayerController* player, GameWorld* world,
ss << std::setw(3) << std::setfill('0') ss << std::setw(3) << std::setfill('0')
<< static_cast<int>( << static_cast<int>(
player->getCharacter()->getCurrentState().health); player->getCharacter()->getCurrentState().health);
ti.text = GameSymbols::Heart + GameStringUtil::fromString(ss.str()); ti.text = GameSymbols::Heart + GameStringUtil::fromString(ss.str(), ti.font);
ti.baseColour = ui_shadowColour; ti.baseColour = ui_shadowColour;
ti.screenPosition = glm::vec2(infoTextX + 1.f, infoTextY + 1.f); ti.screenPosition = glm::vec2(infoTextX + 1.f, infoTextY + 1.f);
@ -174,7 +174,7 @@ void drawPlayerInfo(PlayerController* player, GameWorld* world,
ss << std::setw(3) << std::setfill('0') ss << std::setw(3) << std::setfill('0')
<< static_cast<int>( << static_cast<int>(
player->getCharacter()->getCurrentState().armour); player->getCharacter()->getCurrentState().armour);
ti.text = GameSymbols::Armour + GameStringUtil::fromString(ss.str()); ti.text = GameSymbols::Armour + GameStringUtil::fromString(ss.str(), ti.font);
ti.baseColour = ui_shadowColour; ti.baseColour = ui_shadowColour;
ti.screenPosition = ti.screenPosition =
@ -249,7 +249,7 @@ void drawPlayerInfo(PlayerController* player, GameWorld* world,
displayBulletsTotal += slotInfo.bulletsClip; displayBulletsTotal += slotInfo.bulletsClip;
ti.text = ti.text =
GameStringUtil::fromString(std::to_string(displayBulletsTotal)); GameStringUtil::fromString(std::to_string(displayBulletsTotal), ti.font);
} else { } else {
// Limit the maximal displayed length for the total bullet count // Limit the maximal displayed length for the total bullet count
if (slotInfo.bulletsTotal > 9999) { if (slotInfo.bulletsTotal > 9999) {
@ -258,11 +258,11 @@ void drawPlayerInfo(PlayerController* player, GameWorld* world,
ti.text = GameStringUtil::fromString( ti.text = GameStringUtil::fromString(
std::to_string(displayBulletsTotal) + "-" + std::to_string(displayBulletsTotal) + "-" +
std::to_string(slotInfo.bulletsClip)); std::to_string(slotInfo.bulletsClip), ti.font);
} }
ti.baseColour = ui_shadowColour; ti.baseColour = ui_shadowColour;
ti.font = 2; ti.font = FONT_ARIAL;
ti.size = ui_ammoSize; ti.size = ui_ammoSize;
ti.align = TextRenderer::TextInfo::Center; ti.align = TextRenderer::TextInfo::Center;
ti.screenPosition = glm::vec2(iconX + ui_weaponSize / 2.f, ti.screenPosition = glm::vec2(iconX + ui_weaponSize / 2.f,
@ -284,7 +284,7 @@ void drawOnScreenText(GameWorld* world, GameRenderer* renderer) {
const auto vp = glm::vec2(renderer->getRenderer()->getViewport()); const auto vp = glm::vec2(renderer->getRenderer()->getViewport());
TextRenderer::TextInfo ti; TextRenderer::TextInfo ti;
ti.font = 2; ti.font = FONT_ARIAL;
ti.screenPosition = glm::vec2(10.f, 10.f); ti.screenPosition = glm::vec2(10.f, 10.f);
ti.size = 20.f; ti.size = 20.f;

View File

@ -40,13 +40,13 @@ public:
public: public:
MenuEntry(const std::string& n, const std::function<void(void)>& cb) MenuEntry(const std::string& n, const std::function<void(void)>& cb)
: text(GameStringUtil::fromString(n)), callback(cb) { : text(GameStringUtil::fromString(n, FONT_PRICEDOWN)), callback(cb) {
} }
MenuEntry(const GameString& n, const std::function<void(void)>& cb) MenuEntry(const GameString& n, const std::function<void(void)>& cb)
: text(n), callback(cb) { : text(n), callback(cb) {
} }
void draw(int font, float size, bool active, GameRenderer* r, void draw(font_t font, float size, bool active, GameRenderer* r,
glm::vec2& basis) { glm::vec2& basis) {
TextRenderer::TextInfo ti; TextRenderer::TextInfo ti;
ti.font = font; ti.font = font;
@ -90,7 +90,7 @@ public:
} }
Menu& lambda(const std::string& n, std::function<void(void)> callback) { Menu& lambda(const std::string& n, std::function<void(void)> callback) {
entries.emplace_back(GameStringUtil::fromString(n), callback); entries.emplace_back(GameStringUtil::fromString(n, FONT_PRICEDOWN), callback);
return *this; return *this;
} }

View File

@ -663,8 +663,8 @@ void RWGame::renderDebugStats(float time) {
<< "Timescale: " << world->state->basic.timeScale; << "Timescale: " << world->state->basic.timeScale;
TextRenderer::TextInfo ti; TextRenderer::TextInfo ti;
ti.text = GameStringUtil::fromString(ss.str()); ti.font = FONT_ARIAL;
ti.font = 2; ti.text = GameStringUtil::fromString(ss.str(), FONT_ARIAL);
ti.screenPosition = glm::vec2(10.f, 10.f); ti.screenPosition = glm::vec2(10.f, 10.f);
ti.size = 15.f; ti.size = 15.f;
ti.baseColour = glm::u8vec3(255); ti.baseColour = glm::u8vec3(255);
@ -786,8 +786,8 @@ void RWGame::renderDebugObjects(float time, ViewCamera& camera) {
<< " Peds: " << world->pedestrianPool.objects.size() << "\n"; << " Peds: " << world->pedestrianPool.objects.size() << "\n";
TextRenderer::TextInfo ti; TextRenderer::TextInfo ti;
ti.text = GameStringUtil::fromString(ss.str()); ti.font = FONT_ARIAL;
ti.font = 2; ti.text = GameStringUtil::fromString(ss.str(), FONT_ARIAL);
ti.screenPosition = glm::vec2(10.f, 10.f); ti.screenPosition = glm::vec2(10.f, 10.f);
ti.size = 15.f; ti.size = 15.f;
ti.baseColour = glm::u8vec3(255); ti.baseColour = glm::u8vec3(255);
@ -809,7 +809,7 @@ void RWGame::renderDebugObjects(float time, ViewCamera& camera) {
if (screen.z >= 1.f) { if (screen.z >= 1.f) {
return; return;
} }
ti.text = GameStringUtil::fromString(ss.str()); ti.text = GameStringUtil::fromString(ss.str(), FONT_ARIAL);
screen.y = viewport.w - screen.y; screen.y = viewport.w - screen.y;
ti.screenPosition = glm::vec2(screen); ti.screenPosition = glm::vec2(screen);
ti.size = 10.f; ti.size = 10.f;
@ -863,7 +863,7 @@ void RWGame::renderProfile() {
float xscale = renderer.getRenderer()->getViewport().x / upperlimit; float xscale = renderer.getRenderer()->getViewport().x / upperlimit;
TextRenderer::TextInfo ti; TextRenderer::TextInfo ti;
ti.align = TextRenderer::TextInfo::Left; ti.align = TextRenderer::TextInfo::Left;
ti.font = 2; ti.font = FONT_ARIAL;
ti.size = lineHeight - 2.f; ti.size = lineHeight - 2.f;
ti.baseColour = glm::u8vec3(255); ti.baseColour = glm::u8vec3(255);
std::function<void(const perf::ProfileEntry&, int)> renderEntry = std::function<void(const perf::ProfileEntry&, int)> renderEntry =
@ -880,14 +880,14 @@ void RWGame::renderProfile() {
ti.screenPosition.x = xscale * (event.start); ti.screenPosition.x = xscale * (event.start);
ti.screenPosition.y = y + 2.f; ti.screenPosition.y = y + 2.f;
ti.text = GameStringUtil::fromString( ti.text = GameStringUtil::fromString(
event.label + " " + std::to_string(duration) + " us "); event.label + " " + std::to_string(duration) + " us ", ti.font);
renderer.text.renderText(ti); renderer.text.renderText(ti);
renderEntry(event, depth + 1); renderEntry(event, depth + 1);
} }
}; };
renderEntry(frame, 0); renderEntry(frame, 0);
ti.screenPosition = glm::vec2(xscale * (16000), 40.f); ti.screenPosition = glm::vec2(xscale * (16000), 40.f);
ti.text = GameStringUtil::fromString(".16 ms"); ti.text = GameStringUtil::fromString(".16 ms", ti.font);
renderer.text.renderText(ti); renderer.text.renderText(ti);
#endif #endif
} }

View File

@ -375,8 +375,8 @@ void DebugState::draw(GameRenderer* r) {
ss << (zone ? zone->name : "No Zone") << "\n"; ss << (zone ? zone->name : "No Zone") << "\n";
TextRenderer::TextInfo ti; TextRenderer::TextInfo ti;
ti.text = GameStringUtil::fromString(ss.str()); ti.font = FONT_ARIAL;
ti.font = 2; ti.text = GameStringUtil::fromString(ss.str(), ti.font);
ti.screenPosition = glm::vec2(10.f, 10.f); ti.screenPosition = glm::vec2(10.f, 10.f);
ti.size = 15.f; ti.size = 15.f;
ti.baseColour = glm::u8vec3(255); ti.baseColour = glm::u8vec3(255);

View File

@ -28,14 +28,14 @@ void LoadingState::handleEvent(const SDL_Event& e) {
} }
void LoadingState::draw(GameRenderer* r) { void LoadingState::draw(GameRenderer* r) {
static auto kLoadingString = GameStringUtil::fromString("Loading..."); static auto kLoadingString = GameStringUtil::fromString("Loading...", FONT_ARIAL);
// Display some manner of loading screen. // Display some manner of loading screen.
TextRenderer::TextInfo ti; TextRenderer::TextInfo ti;
ti.text = kLoadingString; ti.text = kLoadingString;
auto size = r->getRenderer()->getViewport(); auto size = r->getRenderer()->getViewport();
ti.size = 25.f; ti.size = 25.f;
ti.screenPosition = glm::vec2(50.f, size.y - ti.size - 50.f); ti.screenPosition = glm::vec2(50.f, size.y - ti.size - 50.f);
ti.font = 2; ti.font = FONT_PRICEDOWN;
ti.baseColour = glm::u8vec3(255); ti.baseColour = glm::u8vec3(255);
r->text.renderText(ti); r->text.renderText(ti);
} }

View File

@ -40,7 +40,7 @@ void MenuState::enterLoadMenu() {
<< save.basicState.saveTime.day << " " << save.basicState.saveTime.day << " "
<< save.basicState.saveTime.hour << ":" << save.basicState.saveTime.hour << ":"
<< save.basicState.saveTime.minute << " "; << save.basicState.saveTime.minute << " ";
auto name = GameStringUtil::fromString(ss.str()); auto name = GameStringUtil::fromString(ss.str(), FONT_ARIAL);
name += save.basicState.saveName; name += save.basicState.saveName;
auto loadsave = [=] { auto loadsave = [=] {
StateManager::get().enter<IngameState>(game, false); StateManager::get().enter<IngameState>(game, false);

View File

@ -1,9 +1,15 @@
#include "GameTexts.hpp" #include "GameTexts.hpp"
GameString GameStringUtil::fromString(const std::string& str) { // FIXME: Update for GTA VC
GameString s; #include "FontMapGta3.hpp"
for (const char &i : str) {
s += i; #include "rw/debug.hpp"
}
return s; GameString GameStringUtil::fromString(const std::string& str, font_t font) {
RW_ASSERT(font < FONTS_COUNT);
return maps_gta3_font[font].to_GameString(str);
}
std::string GameStringUtil::toString(const GameString& str, font_t font) {
return maps_gta3_font[font].to_string(str);
} }

View File

@ -4,6 +4,8 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <sstream>
#include <string>
/** /**
* Each GXT char is just a 16-bit index into the font map. * Each GXT char is just a 16-bit index into the font map.
@ -12,7 +14,7 @@ using GameStringChar = std::uint16_t;
/** /**
* The game stores strings as 16-bit indexes into the font * The game stores strings as 16-bit indexes into the font
* texture, which is something simllar to ASCII. * texture, which is something similar to ASCII.
*/ */
using GameString = std::basic_string<GameStringChar>; using GameString = std::basic_string<GameStringChar>;
@ -22,6 +24,16 @@ using GameString = std::basic_string<GameStringChar>;
*/ */
using GameStringKey = std::string; using GameStringKey = std::string;
/**
* Index to used font.
*/
using font_t = size_t;
static const font_t FONT_PAGER = 0;
static const font_t FONT_PRICEDOWN = 1;
static const font_t FONT_ARIAL = 2;
static const font_t FONTS_COUNT = 3;
namespace GameStringUtil { namespace GameStringUtil {
/** /**
* @brief fromString Converts a string to a GameString * @brief fromString Converts a string to a GameString
@ -29,7 +41,15 @@ namespace GameStringUtil {
* Encoding of GameStrings depends on the font, only simple ASCII chars will map * Encoding of GameStrings depends on the font, only simple ASCII chars will map
* well * well
*/ */
GameString fromString(const std::string& str); GameString fromString(const std::string& str, font_t font);
/**
* @brief fromString Converts a string to a GameString
*
* Encoding of GameStrings depends on the font, only simple ASCII chars will map
* well
*/
std::string toString(const GameString& str, font_t font);
} }
/** /**
@ -58,7 +78,11 @@ public:
if (a != m_strings.end()) { if (a != m_strings.end()) {
return a->second; return a->second;
} }
return GameStringUtil::fromString("MISSING: " + id); return GameStringUtil::fromString("MISSING: " + id, FONT_ARIAL);
}
const StringTable &getStringTable() const {
return m_strings;
} }
}; };

View File

@ -4,7 +4,7 @@
#include <loaders/LoaderGXT.hpp> #include <loaders/LoaderGXT.hpp>
#include "test_Globals.hpp" #include "test_Globals.hpp"
#define T(x) GameStringUtil::fromString(x) #define T(x) GameStringUtil::fromString(x, FONT_PRICEDOWN)
BOOST_AUTO_TEST_SUITE(TextTests) BOOST_AUTO_TEST_SUITE(TextTests)
@ -22,6 +22,7 @@ BOOST_AUTO_TEST_CASE(load_test) {
BOOST_CHECK_EQUAL(texts.text("1008"), T("BUSTED")); BOOST_CHECK_EQUAL(texts.text("1008"), T("BUSTED"));
} }
} }
#endif
BOOST_AUTO_TEST_CASE(special_chars) { BOOST_AUTO_TEST_CASE(special_chars) {
{ {
@ -108,16 +109,16 @@ BOOST_AUTO_TEST_CASE(format_test) {
const auto codeStr2 = T("~1~Hello ~1~ world~1~"); const auto codeStr2 = T("~1~Hello ~1~ world~1~");
const auto codeStr3 = T("Hello world~1~"); const auto codeStr3 = T("Hello world~1~");
auto f1 = ScreenText::format(codeStr1, T("r")); auto f1 = ScreenText::format(codeStr1, FONT_PRICEDOWN, T("r"));
BOOST_CHECK_EQUAL(f1, T("Hello r world")); BOOST_CHECK_EQUAL(f1, T("Hello r world"));
auto f2 = ScreenText::format(codeStr2, T("k"), T("h")); auto f2 = ScreenText::format(codeStr2, FONT_PRICEDOWN, T("k"), T("h"));
BOOST_CHECK_EQUAL(f2, T("kHello h world~1~")); BOOST_CHECK_EQUAL(f2, T("kHello h world~1~"));
auto f3 = ScreenText::format(codeStr3, T("x")); auto f3 = ScreenText::format(codeStr3, FONT_PRICEDOWN, T("x"));
BOOST_CHECK_EQUAL(f3, T("Hello worldx")); BOOST_CHECK_EQUAL(f3, T("Hello worldx"));
auto f4 = ScreenText::format(codeStr3, T("x"), T("k")); auto f4 = ScreenText::format(codeStr3, FONT_PRICEDOWN, T("x"), T("k"));
BOOST_CHECK_EQUAL(f4, T("Hello worldx")); BOOST_CHECK_EQUAL(f4, T("Hello worldx"));
} }
@ -140,6 +141,5 @@ BOOST_AUTO_TEST_CASE(format_remove) {
BOOST_CHECK_EQUAL(1, st.getText<ScreenTextType::Big>().size()); BOOST_CHECK_EQUAL(1, st.getText<ScreenTextType::Big>().size());
} }
#endif
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()