diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 8946ac321c..a637f8c18b 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -240,6 +240,7 @@ C685E51B1F8907850090598F /* Guest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C685E5161F8907840090598F /* Guest.cpp */; }; C685E51C1F8907850090598F /* Map.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C685E5171F8907840090598F /* Map.cpp */; }; C685E51D1F8907850090598F /* Research.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C685E5181F8907840090598F /* Research.cpp */; }; + C651A8D91F30204300443BCA /* Text.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C651A8D71F30204300443BCA /* Text.cpp */; }; C6CB94F21EFFBF860065888F /* libfreetype.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B41CF3006400659A24 /* libfreetype.dylib */; }; C6E96E361E0408B40076A04F /* libzip.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C6E96E351E0408B40076A04F /* libzip.dylib */; }; C6E96E371E040E040076A04F /* libzip.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C6E96E351E0408B40076A04F /* libzip.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; @@ -848,6 +849,8 @@ C685E5161F8907840090598F /* Guest.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Guest.cpp; sourceTree = ""; }; C685E5171F8907840090598F /* Map.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Map.cpp; sourceTree = ""; }; C685E5181F8907840090598F /* Research.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Research.cpp; sourceTree = ""; }; + C651A8D71F30204300443BCA /* Text.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Text.cpp; sourceTree = ""; }; + C651A8D81F30204300443BCA /* Text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Text.h; sourceTree = ""; }; C686F8E91CDBC3B7009F9BFC /* observation_tower.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = observation_tower.c; sourceTree = ""; }; C686F8EA1CDBC3B7009F9BFC /* space_rings.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = space_rings.c; sourceTree = ""; }; C686F8EB1CDBC3B7009F9BFC /* spiral_slide.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = spiral_slide.c; sourceTree = ""; }; @@ -2011,6 +2014,7 @@ F76C839D1EC4E7CC00FA49E2 /* drawing */ = { isa = PBXGroup; children = ( + F76C83A01EC4E7CC00FA49E2 /* drawing_fast.cpp */, F76C839E1EC4E7CC00FA49E2 /* drawing.c */, F76C839F1EC4E7CC00FA49E2 /* drawing.h */, F76C83A01EC4E7CC00FA49E2 /* DrawingFast.cpp */, @@ -2030,9 +2034,11 @@ F76C83AE1EC4E7CC00FA49E2 /* scrolling_text.c */, F76C83AF1EC4E7CC00FA49E2 /* Sprite.cpp */, F76C83B01EC4E7CC00FA49E2 /* string.c */, + C651A8D71F30204300443BCA /* Text.cpp */, + C651A8D81F30204300443BCA /* Text.h */, + 4CB832A81EFFB8D100B88761 /* ttf_sdlport.c */, 4CB832A91EFFB8D100B88761 /* ttf.c */, 4CB832AA1EFFB8D100B88761 /* ttf.h */, - 4CB832A81EFFB8D100B88761 /* ttf_sdlport.c */, 4C8B426E1EEB1ABD00F015CA /* X8DrawingEngine.cpp */, 4C8B426F1EEB1ABD00F015CA /* X8DrawingEngine.h */, ); @@ -3218,6 +3224,8 @@ 4C8667821EEFDCDF0024AAB8 /* RideGroupManager.cpp in Sources */, 4C93F18F1F8B747A00A9330D /* PirateShip.cpp in Sources */, C654DF381F69C0430040F43D /* StaffFirePrompt.cpp in Sources */, + F7CB86431EEDA0F50030C877 /* shortcut_key_change.c in Sources */, + C651A8D91F30204300443BCA /* Text.cpp in Sources */, F76C88801EC5324E00FA49E2 /* DrawImageShader.cpp in Sources */, C685E51D1F8907850090598F /* Research.cpp in Sources */, C64644FB1F3FA4120026AC2D /* EditorScenarioOptions.cpp in Sources */, diff --git a/src/openrct2/drawing/Text.cpp b/src/openrct2/drawing/Text.cpp new file mode 100644 index 0000000000..f54a63317c --- /dev/null +++ b/src/openrct2/drawing/Text.cpp @@ -0,0 +1,246 @@ +#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers +/***************************************************************************** + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * OpenRCT2 is the work of many authors, a full list can be found in contributors.md + * For more information, visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * A full copy of the GNU General Public License can be found in licence.txt + *****************************************************************************/ +#pragma endregion + +#include "Text.h" + +extern "C" +{ + #include "../localisation/localisation.h" +} + +static TextPaint _legacyPaint; + +static void DrawText(rct_drawpixelinfo * dpi, sint32 x, sint32 y, TextPaint * paint, utf8string text); +static void DrawText(rct_drawpixelinfo * dpi, sint32 x, sint32 y, TextPaint * paint, rct_string_id format, void * args); + +StaticLayout::StaticLayout(utf8string source, TextPaint paint, sint32 width) +{ + _buffer = source; + _paint = paint; + + sint32 fontSpriteBase; + + gCurrentFontSpriteBase = paint.SpriteBase; + _maxWidth = gfx_wrap_string(_buffer, width, &_lineCount, &fontSpriteBase); + _lineCount += 1; + _lineHeight = font_get_line_height(fontSpriteBase); +} + +void StaticLayout::Draw(rct_drawpixelinfo * dpi, sint32 x, sint32 y) +{ + gCurrentFontFlags = 0; + gCurrentFontSpriteBase = _paint.SpriteBase; + + TextPaint tempPaint = _paint; + + gCurrentFontFlags = 0; + sint32 lineY = y; + sint32 lineX = x; + switch (_paint.Alignment) { + case TextAlignment::LEFT: + lineX = x; + break; + case TextAlignment::CENTRE: + lineX = x + _maxWidth / 2; + break; + case TextAlignment::RIGHT: + lineX = x + _maxWidth; + break; + } + utf8 * buffer = _buffer; + for (sint32 line = 0; line < _lineCount; ++line) + { + DrawText(dpi, lineX, lineY, &tempPaint, buffer); + tempPaint.Colour = TEXT_COLOUR_254; + buffer = get_string_end(buffer) + 1; + lineY += _lineHeight; + } +} + +sint32 StaticLayout::GetHeight() +{ + return _lineHeight * _lineCount; +} + +sint32 StaticLayout::GetWidth() +{ + return _maxWidth; +} + +sint32 StaticLayout::GetLineCount() +{ + return _lineCount; +} + +static void DrawText(rct_drawpixelinfo * dpi, sint32 x, sint32 y, TextPaint * paint, utf8string text) +{ + sint32 width = gfx_get_string_width(text); + + switch (paint->Alignment) { + case TextAlignment::LEFT: + break; + case TextAlignment::CENTRE: + x -= width / 2; + break; + case TextAlignment::RIGHT: + x -= width; + break; + } + + ttf_draw_string(dpi, text, paint->Colour, x, y); + + if (paint->UnderlineText) + { + gfx_fill_rect(dpi, x, y + 11, x + width, y + 11, text_palette[1]); + if (text_palette[2] != 0) + { + gfx_fill_rect(dpi, x + 1, y + 12, x + width + 1, y + 12, text_palette[2]); + } + } +} + +static void DrawText(rct_drawpixelinfo * dpi, sint32 x, sint32 y, TextPaint * paint, rct_string_id format, void * args) +{ + utf8 buffer[256]; + format_string(buffer, sizeof(buffer), format, args); + DrawText(dpi, x, y, paint, buffer); +} + +static void DrawTextCompat(rct_drawpixelinfo * dpi, sint32 x, sint32 y, rct_string_id format, void * args, uint8 colour, + TextAlignment alignment, bool underline = false) +{ + _legacyPaint.UnderlineText = underline; + _legacyPaint.Colour = colour; + _legacyPaint.Alignment = alignment; + _legacyPaint.SpriteBase = FONT_SPRITE_BASE_MEDIUM; + gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; + DrawText(dpi, x, y, &_legacyPaint, format, args); +} + +static void DrawTextEllipsisedCompat(rct_drawpixelinfo * dpi, sint32 x, sint32 y, sint32 width, rct_string_id format, void * args, + uint8 colour, + TextAlignment alignment, bool underline = false) +{ + _legacyPaint.UnderlineText = underline; + _legacyPaint.Colour = colour; + _legacyPaint.Alignment = alignment; + _legacyPaint.SpriteBase = FONT_SPRITE_BASE_MEDIUM; + gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; + + utf8 buffer[256]; + format_string(buffer, sizeof(buffer), format, args); + gfx_clip_string(buffer, width); + + DrawText(dpi, x, y, &_legacyPaint, buffer); +} + +extern "C" +{ + void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, uint8 colour, sint32 x, sint32 y) + { + _legacyPaint.UnderlineText = false; + _legacyPaint.Colour = colour; + _legacyPaint.Alignment = TextAlignment::LEFT; + _legacyPaint.SpriteBase = gCurrentFontSpriteBase; + DrawText(dpi, x, y, &_legacyPaint, buffer); + } + + // Basic + void gfx_draw_string_left(rct_drawpixelinfo * dpi, rct_string_id format, void * args, uint8 colour, sint32 x, sint32 y) + { + DrawTextCompat(dpi, x, y, format, args, colour, TextAlignment::LEFT); + } + + void gfx_draw_string_centred(rct_drawpixelinfo * dpi, rct_string_id format, sint32 x, sint32 y, uint8 colour, void * args) + { + DrawTextCompat(dpi, x, y, format, args, colour, TextAlignment::CENTRE); + } + + void gfx_draw_string_right(rct_drawpixelinfo * dpi, rct_string_id format, void * args, uint8 colour, sint32 x, sint32 y) + { + DrawTextCompat(dpi, x, y, format, args, colour, TextAlignment::RIGHT); + } + + // Underline + void draw_string_left_underline(rct_drawpixelinfo * dpi, rct_string_id format, void * args, uint8 colour, sint32 x, sint32 y) + { + DrawTextCompat(dpi, x, y, format, args, colour, TextAlignment::LEFT, true); + } + + void draw_string_centred_underline(rct_drawpixelinfo * dpi, rct_string_id format, void * args, uint8 colour, sint32 x, sint32 y) + { + DrawTextCompat(dpi, x, y, format, args, colour, TextAlignment::CENTRE, true); + } + + void draw_string_right_underline(rct_drawpixelinfo * dpi, rct_string_id format, void * args, uint8 colour, sint32 x, sint32 y) + { + DrawTextCompat(dpi, x, y, format, args, colour, TextAlignment::RIGHT, true); + } + + // Ellipsised + void gfx_draw_string_left_clipped(rct_drawpixelinfo * dpi, rct_string_id format, void * args, uint8 colour, sint32 x, sint32 y, sint32 width) + { + DrawTextEllipsisedCompat(dpi, x, y, width, format, args, colour, TextAlignment::LEFT); + } + + void gfx_draw_string_centred_clipped(rct_drawpixelinfo * dpi, rct_string_id format, void * args, uint8 colour, sint32 x, sint32 y, sint32 width) + { + DrawTextEllipsisedCompat(dpi, x, y, width, format, args, colour, TextAlignment::CENTRE); + } + + // Wrapping + sint32 gfx_draw_string_left_wrapped(rct_drawpixelinfo * dpi, void * args, sint32 x, sint32 y, sint32 width, rct_string_id format, uint8 colour) + { + utf8 buffer[256]; + format_string(buffer, sizeof(buffer), format, args); + + gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; + + _legacyPaint.UnderlineText = false; + _legacyPaint.Colour = colour; + _legacyPaint.Alignment = TextAlignment::LEFT; + _legacyPaint.SpriteBase = gCurrentFontSpriteBase; + + StaticLayout layout(buffer, _legacyPaint, width); + layout.Draw(dpi, x, y); + + return layout.GetHeight(); + } + + sint32 gfx_draw_string_centred_wrapped(rct_drawpixelinfo * dpi, void * args, sint32 x, sint32 y, sint32 width, rct_string_id format, uint8 colour) + { + utf8 buffer[256]; + format_string(buffer, sizeof(buffer), format, args); + + gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; + + _legacyPaint.UnderlineText = false; + _legacyPaint.Colour = colour; + _legacyPaint.Alignment = TextAlignment::CENTRE; + _legacyPaint.SpriteBase = gCurrentFontSpriteBase; + + StaticLayout layout(buffer, _legacyPaint, width); + + // The original tried to vertically centre the text, but used line count - 1 + sint32 lineCount = layout.GetLineCount(); + sint32 lineHeight = layout.GetHeight() / lineCount; + sint32 yOffset = (lineCount - 1) * lineHeight / 2; + + layout.Draw(dpi, x - layout.GetWidth() / 2, y - yOffset); + + return layout.GetHeight(); + } +} diff --git a/src/openrct2/drawing/Text.h b/src/openrct2/drawing/Text.h new file mode 100644 index 0000000000..c971c9ab0f --- /dev/null +++ b/src/openrct2/drawing/Text.h @@ -0,0 +1,55 @@ +#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers +/***************************************************************************** + * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. + * + * OpenRCT2 is the work of many authors, a full list can be found in contributors.md + * For more information, visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * A full copy of the GNU General Public License can be found in licence.txt + *****************************************************************************/ +#pragma endregion + +#pragma once + +#include "../common.h" +#include "drawing.h" + +enum class TextAlignment +{ + LEFT, + CENTRE, + RIGHT +}; + +struct TextPaint +{ + uint8 Colour; + sint16 SpriteBase; + bool UnderlineText; + TextAlignment Alignment; +}; + +class StaticLayout +{ +private: + utf8string _buffer; + TextPaint _paint; + sint32 _lineCount; + sint32 _lineHeight; + sint32 _maxWidth; + + StaticLayout(); + StaticLayout(const StaticLayout &); + +public: + StaticLayout(utf8string source, TextPaint paint, sint32 width); + void Draw(rct_drawpixelinfo * dpi, sint32 x, sint32 y); + sint32 GetHeight(); + sint32 GetWidth(); + sint32 GetLineCount(); +}; diff --git a/src/openrct2/drawing/drawing.h b/src/openrct2/drawing/drawing.h index 9c87ec34cb..719ab1e7da 100644 --- a/src/openrct2/drawing/drawing.h +++ b/src/openrct2/drawing/drawing.h @@ -343,28 +343,34 @@ void FASTCALL gfx_draw_sprite_palette_set_software(rct_drawpixelinfo *dpi, sint3 void FASTCALL gfx_draw_sprite_raw_masked_software(rct_drawpixelinfo *dpi, sint32 x, sint32 y, sint32 maskImage, sint32 colourImage); // string -sint32 clip_text(char *buffer, sint32 width); +void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, uint8 colour, sint32 x, sint32 y); + +void gfx_draw_string_left(rct_drawpixelinfo *dpi, rct_string_id format, void *args, uint8 colour, sint32 x, sint32 y); +void gfx_draw_string_centred(rct_drawpixelinfo *dpi, rct_string_id format, sint32 x, sint32 y, uint8 colour, void *args); +void gfx_draw_string_right(rct_drawpixelinfo *dpi, rct_string_id format, void *args, uint8 colour, sint32 x, sint32 y); + +void draw_string_left_underline(rct_drawpixelinfo *dpi, rct_string_id format, void *args, uint8 colour, sint32 x, sint32 y); +void draw_string_centred_underline(rct_drawpixelinfo *dpi, rct_string_id format, void *args, uint8 colour, sint32 x, sint32 y); +void draw_string_right_underline(rct_drawpixelinfo *dpi, rct_string_id format, void *args, uint8 colour, sint32 x, sint32 y); + +void gfx_draw_string_left_clipped(rct_drawpixelinfo *dpi, rct_string_id format, void *args, uint8 colour, sint32 x, sint32 y, sint32 width); +void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, rct_string_id format, void *args, uint8 colour, sint32 x, sint32 y, sint32 width); + +sint32 gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, sint32 x, sint32 y, sint32 width, rct_string_id format, uint8 colour); +sint32 gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, sint32 x, sint32 y, sint32 width, rct_string_id format, uint8 colour); + +void gfx_draw_string_left_centred(rct_drawpixelinfo *dpi, rct_string_id format, void *args, sint32 colour, sint32 x, sint32 y); +void draw_string_centred_raw(rct_drawpixelinfo *dpi, sint32 x, sint32 y, sint32 numLines, char *text); +void gfx_draw_string_centred_wrapped_partial(rct_drawpixelinfo *dpi, sint32 x, sint32 y, sint32 width, sint32 colour, rct_string_id format, void *args, sint32 ticks); +void gfx_draw_string_with_y_offsets(rct_drawpixelinfo *dpi, const utf8 *text, sint32 colour, sint32 x, sint32 y, const sint8 *yOffsets, bool forceSpriteFont); + sint32 gfx_wrap_string(char* buffer, sint32 width, sint32* num_lines, sint32* font_height); sint32 gfx_get_string_width(const utf8 * buffer); sint32 gfx_get_string_width_new_lined(char* buffer); -void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, sint32 colour, sint32 x, sint32 y); -void gfx_draw_string_left(rct_drawpixelinfo *dpi, rct_string_id format, void *args, sint32 colour, sint32 x, sint32 y); -void gfx_draw_string_left_clipped(rct_drawpixelinfo *dpi, rct_string_id format, void *args, sint32 colour, sint32 x, sint32 y, sint32 width); -sint32 gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, sint32 x, sint32 y, sint32 width, rct_string_id format, sint32 colour); -void draw_string_left_underline(rct_drawpixelinfo *dpi, rct_string_id format, void *args, sint32 colour, sint32 x, sint32 y); -void gfx_draw_string_left_centred(rct_drawpixelinfo *dpi, rct_string_id format, void *args, sint32 colour, sint32 x, sint32 y); -void gfx_draw_string_centred(rct_drawpixelinfo *dpi, rct_string_id format, sint32 x, sint32 y, sint32 colour, void *args); -void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, rct_string_id format, void *args, sint32 colour, sint32 x, sint32 y, sint32 width); -void draw_string_centred_underline(rct_drawpixelinfo *dpi, rct_string_id format, void *args, sint32 colour, sint32 x, sint32 y); -sint32 gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, sint32 x, sint32 y, sint32 width, rct_string_id format, sint32 colour); -void draw_string_centred_raw(rct_drawpixelinfo *dpi, sint32 x, sint32 y, sint32 numLines, char *text); -void gfx_draw_string_right(rct_drawpixelinfo *dpi, rct_string_id format, void *args, sint32 colour, sint32 x, sint32 y); -void draw_string_right_underline(rct_drawpixelinfo *dpi, rct_string_id format, void *args, sint32 colour, sint32 x, sint32 y); sint32 string_get_height_raw(char *buffer); -void gfx_draw_string_centred_wrapped_partial(rct_drawpixelinfo *dpi, sint32 x, sint32 y, sint32 width, sint32 colour, rct_string_id format, void *args, sint32 ticks); -void gfx_draw_string_with_y_offsets(rct_drawpixelinfo *dpi, const utf8 *text, sint32 colour, sint32 x, sint32 y, const sint8 *yOffsets, bool forceSpriteFont); sint32 gfx_clip_string(char* buffer, sint32 width); void shorten_path(utf8 *buffer, size_t bufferSize, const utf8 *path, sint32 availableWidth); +void ttf_draw_string(rct_drawpixelinfo *dpi, char *text, sint32 colour, sint32 x, sint32 y); typedef struct paint_session paint_session; diff --git a/src/openrct2/drawing/scrolling_text.c b/src/openrct2/drawing/scrolling_text.c index bd21b0afdd..8607432199 100644 --- a/src/openrct2/drawing/scrolling_text.c +++ b/src/openrct2/drawing/scrolling_text.c @@ -32,7 +32,7 @@ typedef struct rct_draw_scroll_text { uint16 position; // 0x0A uint16 mode; // 0x0C uint32 id; // 0x0E - uint8 bitmap[64 * 8 * 5]; // 0x12 + uint8 bitmap[64 * 40]; // 0x12 } rct_draw_scroll_text; assert_struct_size(rct_draw_scroll_text, 0xA12); #pragma pack(pop) @@ -40,7 +40,7 @@ assert_struct_size(rct_draw_scroll_text, 0xA12); #define MAX_SCROLLING_TEXT_ENTRIES 32 static rct_draw_scroll_text _drawScrollTextList[MAX_SCROLLING_TEXT_ENTRIES]; -static uint8 _characterBitmaps[224 * 8]; +static uint8 _characterBitmaps[FONT_SPRITE_GLYPH_COUNT][8]; static uint32 _drawSCrollNextIndex = 0; void scrolling_text_set_bitmap_for_sprite(utf8 *text, sint32 scroll, uint8 *bitmap, const sint16 *scrollPositionOffsets); @@ -60,7 +60,7 @@ void scrolling_text_initialise_bitmaps() }; - for (sint32 i = 0; i < 224; i++) { + for (sint32 i = 0; i < FONT_SPRITE_GLYPH_COUNT; i++) { memset(drawingSurface, 0, sizeof(drawingSurface)); gfx_draw_sprite_software(&dpi, SPR_CHAR_START + FONT_SPRITE_BASE_TINY + i, -1, 0, 0); @@ -73,7 +73,7 @@ void scrolling_text_initialise_bitmaps() val |= 0x80; } } - _characterBitmaps[i * 8 + x] = val; + _characterBitmaps[i][x] = val; } } @@ -93,7 +93,7 @@ void scrolling_text_initialise_bitmaps() static uint8 *font_sprite_get_codepoint_bitmap(sint32 codepoint) { - return &_characterBitmaps[font_sprite_get_codepoint_offset(codepoint) * 8]; + return _characterBitmaps[font_sprite_get_codepoint_offset(codepoint)]; } diff --git a/src/openrct2/drawing/string.c b/src/openrct2/drawing/string.c index 580ce97fad..77be6f3d73 100644 --- a/src/openrct2/drawing/string.c +++ b/src/openrct2/drawing/string.c @@ -34,7 +34,6 @@ enum { }; static sint32 ttf_get_string_width(const utf8 *text); -static void ttf_draw_string(rct_drawpixelinfo *dpi, char *buffer, sint32 colour, sint32 x, sint32 y); /** * @@ -212,202 +211,6 @@ sint32 gfx_wrap_string(utf8 *text, sint32 width, sint32 *outNumLines, sint32 *ou return maxWidth == 0 ? lineWidth : maxWidth; } -/** - * Draws i formatted text string left aligned at i specified position but clips - * the text with an ellipsis if the text width exceeds the specified width. - * rct2: 0x006C1B83 - * dpi (edi) - * format (bx) - * args (esi) - * colour (al) - * x (cx) - * y (dx) - * width (bp) - */ -void gfx_draw_string_left_clipped(rct_drawpixelinfo* dpi, rct_string_id format, void* args, sint32 colour, sint32 x, sint32 y, sint32 width) -{ - char* buffer = gCommonStringFormatBuffer; - format_string(buffer, 256, format, args); - - gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; - - // Clip text - return value is not needed - gfx_clip_string(buffer, width); - - gfx_draw_string(dpi, buffer, colour, x, y); -} - -/** - * Draws i formatted text string centred at i specified position but clips the - * text with an ellipsis if the text width exceeds the specified width. - * rct2: 0x006C1BBA - * dpi (edi) - * format (bx) - * args (esi) - * colour (al) - * x (cx) - * y (dx) - * width (bp) - */ -void gfx_draw_string_centred_clipped(rct_drawpixelinfo *dpi, rct_string_id format, void *args, sint32 colour, sint32 x, sint32 y, sint32 width) -{ - char* buffer = gCommonStringFormatBuffer; - format_string(buffer, 256, format, args); - - gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; - - // Clip text - sint32 text_width = gfx_clip_string(buffer, width); - - // Draw the text centred - if (text_width <= 0xFFFF && text_width >= 0) { - x -= (text_width - 1) / 2; - gfx_draw_string(dpi, buffer, colour, x, y); - } else { - log_warning("improper text width %d for string %s", text_width, buffer); - } -} - -/** - * Draws i formatted text string right aligned. - * rct2: 0x006C1BFC - * dpi (edi) - * format (bx) - * args (esi) - * colour (al) - * x (cx) - * y (dx) - */ -void gfx_draw_string_right(rct_drawpixelinfo* dpi, rct_string_id format, void* args, sint32 colour, sint32 x, sint32 y) -{ - char* buffer = gCommonStringFormatBuffer; - format_string(buffer, 256, format, args); - - // Measure text width - sint16 text_width = gfx_get_string_width(buffer); - - // Draw the text right aligned - x -= text_width; - gfx_draw_string(dpi, buffer, colour, x, y); -} - -/** - * Draws i formatted text string centred at i specified position. - * rct2: 0x006C1D6C - * dpi (edi) - * format (bx) - * x (cx) - * y (dx) - * colour (al) - * args (esi) - */ -void gfx_draw_string_centred(rct_drawpixelinfo *dpi, rct_string_id format, sint32 x, sint32 y, sint32 colour, void *args) -{ - gfx_draw_string_centred_wrapped(dpi, args, x, y, INT32_MAX, format, colour); -} - -/** - * - * rct2: 0x006C1E53 - * dpi (edi) - * args (esi) - * x (cx) - * y (dx) - * width (bp) - * colour (al) - * format (ebx) - */ -sint32 gfx_draw_string_centred_wrapped(rct_drawpixelinfo *dpi, void *args, sint32 x, sint32 y, sint32 width, rct_string_id format, sint32 colour) -{ - sint32 font_height, line_height, line_y, num_lines; - - if (gCurrentFontSpriteBase >= 0) { - gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; - } - - char *buffer = gCommonStringFormatBuffer; - gfx_draw_string(dpi, "", colour, dpi->x, dpi->y); - format_string(buffer, 256, format, args); - - gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; - - gfx_wrap_string(buffer, width, &num_lines, &font_height); - line_height = font_get_line_height(font_height); - - if (*buffer == FORMAT_OUTLINE) { - line_height = line_height + 1; - } - - font_height = (line_height / 2) * num_lines; - line_y = y - font_height; - - gCurrentFontFlags = 0; - - for (sint32 line = 0; line <= num_lines; ++line) { - sint32 half_width = gfx_get_string_width(buffer) / 2; - gfx_draw_string(dpi, buffer, TEXT_COLOUR_254, x - half_width, line_y); - - buffer = get_string_end(buffer) + 1; - line_y += line_height; - } - - return line_y - y; -} - -/** - * - * rct2: 0x006C2105 - * dpi (edi) - * args (esi) - * x (cx) - * y (dx) - * width (bp) - * format (bx) - * colour (al) - */ -sint32 gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *args, sint32 x, sint32 y, sint32 width, rct_string_id format, sint32 colour) -{ - // font height might actually be something else - sint32 fontSpriteBase, lineHeight, lineY, numLines; - - gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; - - char *buffer = gCommonStringFormatBuffer; - gfx_draw_string(dpi, "", colour, dpi->x, dpi->y); - format_string(buffer, 256, format, args); - - gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; - gfx_wrap_string(buffer, width, &numLines, &fontSpriteBase); - lineHeight = font_get_line_height(fontSpriteBase); - - gCurrentFontFlags = 0; - lineY = y; - for (sint32 line = 0; line <= numLines; ++line) { - gfx_draw_string(dpi, buffer, TEXT_COLOUR_254, x, lineY); - buffer = get_string_end(buffer) + 1; - lineY += lineHeight; - } - return lineY - y; -} - -/** - * Draws i formatted text string. - * rct2: 0x006C1B2F - * dpi (edi) - * format (bx) - * args (esi) - * colour (al) - * x (cx) - * y (dx) - */ -void gfx_draw_string_left(rct_drawpixelinfo *dpi, rct_string_id format, void *args, sint32 colour, sint32 x, sint32 y) -{ - char* buffer = gCommonStringFormatBuffer; - format_string(buffer, 256, format, args); - gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; - gfx_draw_string(dpi, buffer, colour, x, y); -} - /** * Draws text that is left aligned and vertically centred. */ @@ -460,64 +263,6 @@ static void colour_char_window(uint8 colour, uint16* current_font_flags,uint8* p palette_pointer[4] = (eax >> 24) & 0xFF; } -/** - * - * rct2: 0x00682702 - * dpi (edi) - * buffer (esi) - * colour (al) - * x (cx) - * y (dx) - */ -void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, sint32 colour, sint32 x, sint32 y) -{ - ttf_draw_string(dpi, buffer, colour, x, y); -} - -void draw_string_left_underline(rct_drawpixelinfo *dpi, rct_string_id format, void *args, sint32 colour, sint32 x, sint32 y) -{ - char buffer[128]; - sint32 width; - - format_string(buffer, 128, format, args); - gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; - width = gfx_get_string_width(buffer); - gfx_draw_string(dpi, buffer, colour, x, y); - gfx_fill_rect(dpi, x, y + 11, x + width, y + 11, text_palette[1]); - if (text_palette[2] != 0) - gfx_fill_rect(dpi, x + 1, y + 12, x + width + 1, y + 12, text_palette[2]); -} - -void draw_string_right_underline(rct_drawpixelinfo *dpi, rct_string_id format, void *args, sint32 colour, sint32 x, sint32 y) -{ - char buffer[128]; - sint32 width; - - format_string(buffer, 128, format, args); - gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; - width = gfx_get_string_width(buffer); - x -= width; - gfx_draw_string(dpi, buffer, colour, x, y); - gfx_fill_rect(dpi, x, y + 11, x + width, y + 11, text_palette[1]); - if (text_palette[2] != 0) - gfx_fill_rect(dpi, x + 1, y + 12, x + width + 1, y + 12, text_palette[2]); -} - -void draw_string_centred_underline(rct_drawpixelinfo *dpi, rct_string_id format, void *args, sint32 colour, sint32 x, sint32 y) -{ - char buffer[128]; - sint32 width; - - format_string(buffer, 128, format, args); - gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM; - width = gfx_get_string_width(buffer); - x -= width / 2; - gfx_draw_string(dpi, buffer, colour, x, y); - gfx_fill_rect(dpi, x, y + 11, x + width, y + 11, text_palette[1]); - if (text_palette[2] != 0) - gfx_fill_rect(dpi, x + 1, y + 12, x + width + 1, y + 12, text_palette[2]); -} - /** * * rct2: 0x006C1DB7 @@ -566,36 +311,36 @@ sint32 string_get_height_raw(char *buffer) char c = *ch++; switch (c) { case FORMAT_NEWLINE: - if (fontBase <= 224) { + if (fontBase == FONT_SPRITE_BASE_SMALL || fontBase == FONT_SPRITE_BASE_MEDIUM) { height += 10; break; - } else if (fontBase == 448) { + } else if (fontBase == FONT_SPRITE_BASE_TINY) { height += 6; break; } height += 18; break; case FORMAT_NEWLINE_SMALLER: - if (fontBase <= 224) { + if (fontBase == FONT_SPRITE_BASE_SMALL || fontBase == FONT_SPRITE_BASE_MEDIUM) { height += 5; break; - } else if (fontBase == 448) { + } else if (fontBase == FONT_SPRITE_BASE_TINY) { height += 3; break; } height += 9; break; case FORMAT_TINYFONT: - fontBase = 448; + fontBase = FONT_SPRITE_BASE_TINY; break; case FORMAT_BIGFONT: - fontBase = 672; + fontBase = FONT_SPRITE_BASE_BIG; break; case FORMAT_MEDIUMFONT: - fontBase = 224; + fontBase = FONT_SPRITE_BASE_MEDIUM; break; case FORMAT_SMALLFONT: - fontBase = 0; + fontBase = FONT_SPRITE_BASE_SMALL; break; default: if (c >= 32) continue; @@ -871,8 +616,8 @@ static const utf8 *ttf_process_format_code(rct_drawpixelinfo *dpi, const utf8 *t memcpy(info->palette + 5, &(g1Element->offset[250]), 2); break; } - case 3: - case 4: + case FORMAT_3: + case FORMAT_4: nextCh++; break; case FORMAT_NEWLINE: @@ -884,13 +629,13 @@ static const utf8 *ttf_process_format_code(rct_drawpixelinfo *dpi, const utf8 *t info->y += font_get_line_height_small(info->font_sprite_base); break; case FORMAT_TINYFONT: - info->font_sprite_base = 448; + info->font_sprite_base = FONT_SPRITE_BASE_TINY; break; case FORMAT_SMALLFONT: - info->font_sprite_base = 0; + info->font_sprite_base = FONT_SPRITE_BASE_SMALL; break; case FORMAT_MEDIUMFONT: - info->font_sprite_base = 224; + info->font_sprite_base = FONT_SPRITE_BASE_MEDIUM; break; case FORMAT_BIGFONT: info->font_sprite_base = 672; @@ -919,7 +664,7 @@ static const utf8 *ttf_process_format_code(rct_drawpixelinfo *dpi, const utf8 *t colour_char_window(gCurrentWindowColours[2], &flags, info->palette); break; } - case 0x10: + case FORMAT_16: break; case FORMAT_INLINE_SPRITE: { @@ -1053,7 +798,7 @@ static void ttf_process_initial_colour(sint32 colour, text_draw_info *info) } } -static void ttf_draw_string(rct_drawpixelinfo *dpi, char *text, sint32 colour, sint32 x, sint32 y) +void ttf_draw_string(rct_drawpixelinfo *dpi, char *text, sint32 colour, sint32 x, sint32 y) { if (text == NULL) return; diff --git a/src/openrct2/interface/widget.c b/src/openrct2/interface/widget.c index 027ee18476..82d9b9593f 100644 --- a/src/openrct2/interface/widget.c +++ b/src/openrct2/interface/widget.c @@ -537,7 +537,10 @@ static void widget_groupbox_draw(rct_drawpixelinfo *dpi, rct_window *w, rct_widg uint8 colour = w->colours[widget->colour] & 0x7F; if (widget_is_disabled(w, widgetIndex)) colour |= 0x40; - gfx_draw_string_left(dpi, widget->text, gCommonFormatArgs, colour, l, t); + + format_string(gCommonStringFormatBuffer, sizeof(gCommonStringFormatBuffer), widget->text, gCommonFormatArgs); + set_format_arg(0, uintptr_t, gCommonStringFormatBuffer); + gfx_draw_string_left(dpi, STR_STRING, gCommonFormatArgs, colour, l, t); textRight = l + gfx_get_string_width(gCommonStringFormatBuffer) + 1; } diff --git a/src/openrct2/localisation/format_codes.h b/src/openrct2/localisation/format_codes.h index 6780cc9ce0..8ea86472f1 100644 --- a/src/openrct2/localisation/format_codes.h +++ b/src/openrct2/localisation/format_codes.h @@ -36,6 +36,9 @@ enum { // The next byte specifies the palette FORMAT_ADJUST_PALETTE, + FORMAT_3, + FORMAT_4, + // Moves to the next line FORMAT_NEWLINE = 5, // Moves less than NEWLINE @@ -54,6 +57,8 @@ enum { FORMAT_WINDOW_COLOUR_2, FORMAT_WINDOW_COLOUR_3, + FORMAT_16, + // The next 2 bytes specify the X and Y coordinates FORMAT_NEWLINE_X_Y = 17,