From 958dfa662381feaa0e3849542f6fba5f48348038 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 25 Jun 2016 22:47:09 +0100 Subject: [PATCH] add large scenery object loading --- openrct2.vcxproj | 2 + src/object/LargeSceneryObject.cpp | 121 ++++++++++++++++++++++++++++++ src/object/LargeSceneryObject.h | 48 ++++++++++++ src/object/ObjectFactory.cpp | 4 + 4 files changed, 175 insertions(+) create mode 100644 src/object/LargeSceneryObject.cpp create mode 100644 src/object/LargeSceneryObject.h diff --git a/openrct2.vcxproj b/openrct2.vcxproj index 0bce3c36a8..2bbbb5b06a 100644 --- a/openrct2.vcxproj +++ b/openrct2.vcxproj @@ -122,6 +122,7 @@ + @@ -433,6 +434,7 @@ + diff --git a/src/object/LargeSceneryObject.cpp b/src/object/LargeSceneryObject.cpp new file mode 100644 index 0000000000..4eb3ccf754 --- /dev/null +++ b/src/object/LargeSceneryObject.cpp @@ -0,0 +1,121 @@ +#pragma region Copyright (c) 2014-2016 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 "../core/IStream.hpp" +#include "../core/Memory.hpp" +#include "LargeSceneryObject.h" + +extern "C" +{ + #include "../drawing/drawing.h" + #include "../localisation/localisation.h" +} + +enum OBJ_STRING_ID +{ + OBJ_STRING_ID_NAME, +}; + +LargeSceneryObject::~LargeSceneryObject() +{ + Memory::Free(_3dFont); + Memory::Free(_tiles); +} + +void LargeSceneryObject::ReadLegacy(IStream * stream) +{ + _legacyType.name = stream->ReadValue(); + _legacyType.image = stream->ReadValue(); + + _legacyType.large_scenery.tool_id = stream->ReadValue(); + _legacyType.large_scenery.flags = stream->ReadValue(); + _legacyType.large_scenery.price = stream->ReadValue(); + _legacyType.large_scenery.removal_price = stream->ReadValue(); + stream->Seek(4, STREAM_SEEK_CURRENT); + _legacyType.large_scenery.scenery_tab_id = 0xFF; + _legacyType.large_scenery.var_11 = stream->ReadValue(); + stream->Seek(5, STREAM_SEEK_CURRENT); + + StringTable.Read(stream, OBJ_STRING_ID_NAME); + + _sceneryTabEntry = stream->ReadValue(); + + if (_legacyType.large_scenery.flags & (1 << 2)) + { + _3dFont = Memory::Allocate(); + stream->Read(_3dFont); + _legacyType.large_scenery.text = _3dFont; + } + + _tiles = ReadTiles(stream); + + ImageTable.Read(stream); +} + +void LargeSceneryObject::Load() +{ + _legacyType.name = language_allocate_object_string(GetName()); + _legacyType.image = gfx_object_allocate_images(ImageTable.GetImages(), ImageTable.GetCount()); + + _legacyType.large_scenery.scenery_tab_id = 0xFF; + if ((_sceneryTabEntry.flags & 0xFF) != 0xFF) + { + uint8 entryType, entryIndex; + if (find_object_in_entry_group(&_sceneryTabEntry, &entryType, &entryIndex)) + { + _legacyType.large_scenery.scenery_tab_id = entryIndex; + } + } + + if (_legacyType.large_scenery.flags & (1 << 2)) + { + _legacyType.large_scenery.text_image = _legacyType.image; + if (_3dFont->var_C & (1 << 0)) + { + _legacyType.image += (_3dFont->var_C >> 8) * 2; + } + else + { + _legacyType.image += (_3dFont->var_C >> 8) * 4; + } + } +} + +void LargeSceneryObject::Unload() +{ + language_free_object_string(_legacyType.name); + gfx_object_free_images(_legacyType.image, ImageTable.GetCount()); +} + +const utf8 * LargeSceneryObject::GetName() +{ + return StringTable.GetString(OBJ_STRING_ID_NAME); +} + +rct_large_scenery_tile * LargeSceneryObject::ReadTiles(IStream * stream) +{ + auto tiles = std::vector(); + + uint16 tilesEndMarker; + while ((tilesEndMarker = stream->ReadValue()) != 0xFFFF) + { + stream->Seek(-2, STREAM_SEEK_CURRENT); + auto tile = stream->ReadValue(); + tiles.push_back(tile); + } + + return Memory::DuplicateArray(tiles.data(), tiles.size()); +} diff --git a/src/object/LargeSceneryObject.h b/src/object/LargeSceneryObject.h new file mode 100644 index 0000000000..3222844175 --- /dev/null +++ b/src/object/LargeSceneryObject.h @@ -0,0 +1,48 @@ +#pragma region Copyright (c) 2014-2016 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 "Object.h" + +extern "C" +{ + #include "../world/scenery.h" +} + +class LargeSceneryObject : public Object +{ +private: + rct_scenery_entry _legacyType; + rct_object_entry _sceneryTabEntry; + rct_large_scenery_text * _3dFont; + rct_large_scenery_tile * _tiles; + +public: + explicit LargeSceneryObject(const rct_object_entry &entry) : Object(entry) { }; + ~LargeSceneryObject(); + + void * GetLegacyData() override { return &_legacyType; } + + void ReadLegacy(IStream * stream) override; + void Load() override; + void Unload() override; + + const utf8 * GetName() override; + +private: + static rct_large_scenery_tile * ReadTiles(IStream * stream); +}; diff --git a/src/object/ObjectFactory.cpp b/src/object/ObjectFactory.cpp index 9d3a1ccc34..f5ed13dcc1 100644 --- a/src/object/ObjectFactory.cpp +++ b/src/object/ObjectFactory.cpp @@ -20,6 +20,7 @@ #include "EntranceObject.h" #include "FootpathItemObject.h" #include "FootpathObject.h" +#include "LargeSceneryObject.h" #include "Object.h" #include "ObjectFactory.h" #include "RideObject.h" @@ -72,6 +73,9 @@ namespace ObjectFactory case OBJECT_TYPE_SMALL_SCENERY: result = new SmallSceneryObject(entry); break; + case OBJECT_TYPE_LARGE_SCENERY: + result = new LargeSceneryObject(entry); + break; case OBJECT_TYPE_PATHS: result = new FootpathObject(entry); break;