From 2449b7dbf01315663eac9e7524a2b25cf23164cc Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 25 Jun 2016 12:30:20 +0100 Subject: [PATCH] add reading of entrance objects --- openrct2.vcxproj | 2 + src/object/EntranceObject.cpp | 12 +++++- src/object/EntranceObject.h | 5 ++- src/object/Object.h | 5 ++- src/object/ObjectFactory.cpp | 71 +++++++++++++++++++++++++++++++++ src/object/ObjectFactory.h | 27 +++++++++++++ src/object/ObjectRepository.cpp | 10 ++--- src/object/StringTable.cpp | 34 ++++++++++++---- src/object/StringTable.h | 1 + 9 files changed, 150 insertions(+), 17 deletions(-) create mode 100644 src/object/ObjectFactory.cpp create mode 100644 src/object/ObjectFactory.h diff --git a/openrct2.vcxproj b/openrct2.vcxproj index 641b84d74f..34dfd4296f 100644 --- a/openrct2.vcxproj +++ b/openrct2.vcxproj @@ -121,6 +121,7 @@ + @@ -426,6 +427,7 @@ + diff --git a/src/object/EntranceObject.cpp b/src/object/EntranceObject.cpp index 8a95e905d3..73149bcb11 100644 --- a/src/object/EntranceObject.cpp +++ b/src/object/EntranceObject.cpp @@ -17,7 +17,7 @@ #include "../core/IStream.hpp" #include "EntranceObject.h" -void EntranceObject::Load(IStream * stream) +void EntranceObject::ReadLegacy(IStream * stream) { _legacyType.string_idx = stream->ReadValue(); _legacyType.image_id = stream->ReadValue(); @@ -27,3 +27,13 @@ void EntranceObject::Load(IStream * stream) LoadStringTable(stream, 0); LoadImageTable(stream); } + +void EntranceObject::Load() +{ + +} + +void EntranceObject::Unload() +{ + +} diff --git a/src/object/EntranceObject.h b/src/object/EntranceObject.h index 608cbe788a..e9586a5de1 100644 --- a/src/object/EntranceObject.h +++ b/src/object/EntranceObject.h @@ -33,6 +33,7 @@ public: const rct_object_entry * GetObjectEntry() override { return &_objectEntry; } void * GetLegacyData() override { return &_legacyType; } -protected: - void Load(IStream * stream) override; + void ReadLegacy(IStream * stream) override; + void Load() override; + void Unload() override; }; diff --git a/src/object/Object.h b/src/object/Object.h index 00c85cf5f9..0f5548eeca 100644 --- a/src/object/Object.h +++ b/src/object/Object.h @@ -40,10 +40,11 @@ public: virtual const rct_object_entry * GetObjectEntry() abstract; virtual void * GetLegacyData() abstract; -protected: - virtual void Load(IStream * stream) abstract; + virtual void ReadLegacy(IStream * stream) abstract; + virtual void Load() abstract; virtual void Unload() abstract; +protected: void LoadStringTable(IStream * stream, uint8 id); void LoadImageTable(IStream * stream); }; diff --git a/src/object/ObjectFactory.cpp b/src/object/ObjectFactory.cpp new file mode 100644 index 0000000000..aa926e3b0b --- /dev/null +++ b/src/object/ObjectFactory.cpp @@ -0,0 +1,71 @@ +#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/FileStream.hpp" +#include "../core/Memory.hpp" +#include "../core/MemoryStream.h" +#include "EntranceObject.h" +#include "Object.h" +#include "ObjectFactory.h" + +extern "C" +{ + #include "../object.h" + #include "../util/sawyercoding.h" +} + +namespace ObjectFactory +{ + Object * CreateObjectFromLegacyFile(utf8 * path) + { + Object * result = nullptr; + + SDL_RWops * file = SDL_RWFromFile(path, "rb"); + if (file != nullptr) + { + rct_object_entry entry; + if (SDL_RWread(file, &entry, sizeof(entry), 1) == 1) + { + uint8 objectType = entry.flags & 0x0F; + result = CreateObject(objectType); + if (result != nullptr) + { + size_t bufferSize = 0x600000; + void * buffer = Memory::Allocate(bufferSize); + bufferSize = sawyercoding_read_chunk_with_size(file, (uint8 *)buffer, bufferSize); + buffer = Memory::Reallocate(buffer, bufferSize); + auto ms = MemoryStream(buffer, bufferSize); + result->ReadLegacy(&ms); + } + } + SDL_RWclose(file); + } + return result; + } + + Object * CreateObject(uint8 type) + { + Object * result = nullptr; + + switch (type) { + case OBJECT_TYPE_PARK_ENTRANCE: + result = new EntranceObject(); + break; + } + + return result; + } +} diff --git a/src/object/ObjectFactory.h b/src/object/ObjectFactory.h new file mode 100644 index 0000000000..5819adf242 --- /dev/null +++ b/src/object/ObjectFactory.h @@ -0,0 +1,27 @@ +#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 "../common.h" + +class Object; + +namespace ObjectFactory +{ + Object * CreateObjectFromLegacyFile(utf8 * path); + Object * CreateObject(uint8 type); +} diff --git a/src/object/ObjectRepository.cpp b/src/object/ObjectRepository.cpp index 72527c4532..954814940b 100644 --- a/src/object/ObjectRepository.cpp +++ b/src/object/ObjectRepository.cpp @@ -23,6 +23,8 @@ #include "../core/Memory.hpp" #include "../core/Path.hpp" #include "../core/String.hpp" +#include "Object.h" +#include "ObjectFactory.h" #include "ObjectRepository.h" extern "C" @@ -135,13 +137,11 @@ private: void ScanObject(utf8 * path) { - rct_object_entry entry; - if (!object_load_entry(path, &entry)) + Object * object = ObjectFactory::CreateObjectFromLegacyFile(path); + if (object != nullptr) { - return; + // TODO } - - __nop(); } bool Load() diff --git a/src/object/StringTable.cpp b/src/object/StringTable.cpp index 578dc28bc4..9a0c823b3e 100644 --- a/src/object/StringTable.cpp +++ b/src/object/StringTable.cpp @@ -36,6 +36,14 @@ bool StringIsBlank(utf8 * str) return true; } +StringTable::~StringTable() +{ + for (auto entry : _strings) + { + Memory::Free(entry.Text); + } +} + void StringTable::Read(IStream * stream, uint8 id) { uint8 languageId; @@ -58,24 +66,36 @@ void StringTable::Read(IStream * stream, uint8 id) void StringTable::Sort() { - std::sort(_strings.begin(), _strings.end(), [](const StringTableEntry &a, const StringTableEntry &b) -> int + std::sort(_strings.begin(), _strings.end(), [](const StringTableEntry &a, const StringTableEntry &b) -> bool { if (a.Id == b.Id) { if (a.LanguageId == b.LanguageId) { - return _strcmpi(a.Text, b.Text); + return _strcmpi(a.Text, b.Text) == -1; } - if (a.LanguageId == LanguagesDescriptors[gCurrentLanguage].rct2_original_id) + + uint8 currentLanguage = LanguagesDescriptors[gCurrentLanguage].rct2_original_id; + if (a.LanguageId == currentLanguage) { - return -1; + return true; } + if (b.LanguageId == currentLanguage) + { + return false; + } + if (a.LanguageId == RCT2_LANGUAGE_ID_ENGLISH_UK) { - return -1; + return true; } - return 1; + if (b.LanguageId == RCT2_LANGUAGE_ID_ENGLISH_UK) + { + return false; + } + + return a.LanguageId < b.LanguageId; } - return a.Id - b.Id; + return a.Id < b.Id; }); } diff --git a/src/object/StringTable.h b/src/object/StringTable.h index 4b14755d8a..8458a63346 100644 --- a/src/object/StringTable.h +++ b/src/object/StringTable.h @@ -34,6 +34,7 @@ private: std::vector _strings; public: + ~StringTable(); void Read(IStream * stream, uint8 id); private: