From 44e2f1d57786c9a798e8913ff10bdf817d77a9f5 Mon Sep 17 00:00:00 2001 From: Ted John Date: Tue, 19 Dec 2017 11:31:35 +0000 Subject: [PATCH] Add JSON loading for 3D fonts in large scenery --- src/openrct2/object/LargeSceneryObject.cpp | 67 ++++++++++++++++++++-- src/openrct2/object/LargeSceneryObject.h | 2 + src/openrct2/world/Scenery.h | 2 +- 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/src/openrct2/object/LargeSceneryObject.cpp b/src/openrct2/object/LargeSceneryObject.cpp index f8c53da10d..2cdee4e975 100644 --- a/src/openrct2/object/LargeSceneryObject.cpp +++ b/src/openrct2/object/LargeSceneryObject.cpp @@ -16,8 +16,10 @@ #pragma warning(disable : 4706) // assignment within conditional expression +#include #include "../core/IStream.hpp" #include "../core/Memory.hpp" +#include "../core/Util.hpp" #include "../drawing/Drawing.h" #include "../interface/Cursors.h" #include "../localisation/Language.h" @@ -82,12 +84,13 @@ void LargeSceneryObject::Load() _legacyType.large_scenery.text_image = _legacyType.image; if (_3dFont->flags & LARGE_SCENERY_TEXT_FLAG_VERTICAL) { - _legacyType.image += _3dFont->var_D * 2; + _legacyType.image += _3dFont->num_images * 2; } else { - _legacyType.image += _3dFont->var_D * 4; + _legacyType.image += _3dFont->num_images * 4; } + _legacyType.large_scenery.text = _3dFont.get(); } } @@ -206,8 +209,62 @@ std::vector LargeSceneryObject::ReadJsonTiles(const json return tiles; } -std::unique_ptr LargeSceneryObject::ReadJson3dFont(const json_t * j3dText) +std::unique_ptr LargeSceneryObject::ReadJson3dFont(const json_t * j3dFont) { - // TODO - return std::make_unique(); + auto font = std::make_unique(); + + auto jOffsets = json_object_get(j3dFont, "offsets"); + if (jOffsets != nullptr) + { + auto offsets = ReadJsonOffsets(jOffsets); + auto numOffsets = std::min(Util::CountOf(font->offset), offsets.size()); + std::copy_n(offsets.data(), numOffsets, font->offset); + } + + font->max_width = json_integer_value(json_object_get(j3dFont, "maxWidth")); + font->num_images = json_integer_value(json_object_get(j3dFont, "numImages")); + font->flags = ObjectJsonHelpers::GetFlags(j3dFont, { + { "isVertical", LARGE_SCENERY_TEXT_FLAG_VERTICAL }, + { "isTwoLine", LARGE_SCENERY_TEXT_FLAG_TWO_LINE } }); + + auto jGlyphs = json_object_get(j3dFont, "glyphs"); + if (jGlyphs != nullptr) + { + auto glyphs = ReadJsonGlyphs(jGlyphs); + auto numGlyphs = std::min(Util::CountOf(font->glyphs), glyphs.size()); + std::copy_n(glyphs.data(), numGlyphs, font->glyphs); + } + + return font; +} + +std::vector LargeSceneryObject::ReadJsonOffsets(const json_t * jOffsets) +{ + std::vector offsets; + size_t index; + const json_t * jOffset; + json_array_foreach(jOffsets, index, jOffset) + { + LocationXY16 offset = { 0 }; + offset.x = json_integer_value(json_object_get(jOffset, "x")); + offset.y = json_integer_value(json_object_get(jOffset, "y")); + offsets.push_back(offset); + } + return offsets; +} + +std::vector LargeSceneryObject::ReadJsonGlyphs(const json_t * jGlpyhs) +{ + std::vector glyphs; + size_t index; + const json_t * jGlyph; + json_array_foreach(jGlpyhs, index, jGlyph) + { + rct_large_scenery_text_glyph glyph; + glyph.image_offset = json_integer_value(json_object_get(jGlyph, "image")); + glyph.width = json_integer_value(json_object_get(jGlyph, "width")); + glyph.height = json_integer_value(json_object_get(jGlyph, "height")); + glyphs.push_back(glyph); + } + return glyphs; } diff --git a/src/openrct2/object/LargeSceneryObject.h b/src/openrct2/object/LargeSceneryObject.h index 3d60f0333e..27d6a232df 100644 --- a/src/openrct2/object/LargeSceneryObject.h +++ b/src/openrct2/object/LargeSceneryObject.h @@ -45,4 +45,6 @@ private: static std::vector ReadTiles(IStream * stream); static std::vector ReadJsonTiles(const json_t * jTiles); static std::unique_ptr ReadJson3dFont(const json_t * j3dFont); + static std::vector ReadJsonOffsets(const json_t * jOffsets); + static std::vector ReadJsonGlyphs(const json_t * jGlpyhs); }; diff --git a/src/openrct2/world/Scenery.h b/src/openrct2/world/Scenery.h index 312343db94..afd723e395 100644 --- a/src/openrct2/world/Scenery.h +++ b/src/openrct2/world/Scenery.h @@ -80,7 +80,7 @@ struct rct_large_scenery_text { uint16 max_width; // 0x8 uint16 pad_A; // 0xA uint8 flags; // 0xC - uint8 var_D; // 0xD + uint8 num_images; // 0xD rct_large_scenery_text_glyph glyphs[256]; // 0xE }; assert_struct_size(rct_large_scenery_text, 14 + 4 * 256);