#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 "ImageTable.h" #include "StringTable.h" // First 0xF of rct_object_entry->flags enum OBJECT_TYPE { OBJECT_TYPE_RIDE, OBJECT_TYPE_SMALL_SCENERY, OBJECT_TYPE_LARGE_SCENERY, OBJECT_TYPE_WALLS, OBJECT_TYPE_BANNERS, OBJECT_TYPE_PATHS, OBJECT_TYPE_PATH_BITS, OBJECT_TYPE_SCENERY_GROUP, OBJECT_TYPE_PARK_ENTRANCE, OBJECT_TYPE_WATER, OBJECT_TYPE_SCENARIO_TEXT, OBJECT_TYPE_COUNT }; enum OBJECT_SELECTION_FLAGS { OBJECT_SELECTION_FLAG_SELECTED = (1 << 0), OBJECT_SELECTION_FLAG_2 = (1 << 1), OBJECT_SELECTION_FLAG_IN_USE = (1 << 2), // OBJECT_SELECTION_FLAG_REQUIRED = (1 << 3), // Unused feature OBJECT_SELECTION_FLAG_ALWAYS_REQUIRED = (1 << 4), OBJECT_SELECTION_FLAG_6 = (1 << 5), OBJECT_SELECTION_FLAG_7 = (1 << 6), OBJECT_SELECTION_FLAG_8 = (1 << 7), OBJECT_SELECTION_FLAG_ALL = 0xFF, }; #define OBJECT_SELECTION_NOT_SELECTED_OR_REQUIRED 0 enum OBJECT_SOURCE_GAME { OBJECT_SOURCE_CUSTOM, OBJECT_SOURCE_WACKY_WORLDS, OBJECT_SOURCE_TIME_TWISTER, OBJECT_SOURCE_OPENRCT2_OFFICIAL, OBJECT_SOURCE_RCT1, OBJECT_SOURCE_ADDED_ATTRACTIONS, OBJECT_SOURCE_LOOPY_LANDSCAPES, OBJECT_SOURCE_RCT2 = 8 }; #define OBJECT_ENTRY_COUNT 721 #pragma pack(push, 1) /** * Object entry structure. * size: 0x10 */ struct rct_object_entry { union { uint8 end_flag; // needed not to read past allocated buffer. uint32 flags; }; union { char nameWOC[12]; struct { char name[8]; uint32 checksum; }; }; }; assert_struct_size(rct_object_entry, 0x10); struct rct_object_entry_group { void **chunks; rct_object_entry *entries; }; #ifdef PLATFORM_32BIT assert_struct_size(rct_object_entry_group, 8); #endif struct rct_ride_filters { uint8 category[2]; uint8 ride_type; }; assert_struct_size(rct_ride_filters, 3); struct rct_object_filters { union { rct_ride_filters ride; }; }; assert_struct_size(rct_object_filters, 3); #pragma pack(pop) enum OBJ_STRING_ID { OBJ_STRING_ID_NAME, OBJ_STRING_ID_DESCRIPTION, OBJ_STRING_ID_SCENARIO_NAME = 0, OBJ_STRING_ID_PARK_NAME = 1, OBJ_STRING_ID_SCENARIO_DETAILS = 2, OBJ_STRING_ID_CAPACITY = 2, }; interface IStream; struct ObjectRepositoryItem; struct rct_drawpixelinfo; interface IReadObjectContext { virtual ~IReadObjectContext() = default; virtual void LogWarning(uint32 code, const utf8 * text) abstract; virtual void LogError(uint32 code, const utf8 * text) abstract; }; #ifdef __WARN_SUGGEST_FINAL_TYPES__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wsuggest-final-types" #pragma GCC diagnostic ignored "-Wsuggest-final-methods" #endif class Object { private: char * _identifier; rct_object_entry _objectEntry; StringTable _stringTable; ImageTable _imageTable; protected: StringTable * GetStringTable() { return &_stringTable; } const StringTable * GetStringTable() const { return &_stringTable; } ImageTable * GetImageTable() { return &_imageTable; } std::string GetOverrideString(uint8 index) const; std::string GetString(uint8 index) const; void SetSourceGame(const uint8 sourceGame); bool IsRCT1Object(); bool IsAAObject(); bool IsLLObject(); bool IsOpenRCT2OfficialObject(); public: explicit Object(const rct_object_entry &entry); virtual ~Object(); // Legacy data structures const char * GetIdentifier() const { return _identifier; } const rct_object_entry * GetObjectEntry() const { return &_objectEntry; } virtual void * GetLegacyData() abstract; virtual void ReadLegacy(IReadObjectContext * context, IStream * stream) abstract; virtual void Load() abstract; virtual void Unload() abstract; virtual void DrawPreview(rct_drawpixelinfo * dpi, sint32 width, sint32 height) const { } virtual uint8 GetObjectType() const final { return _objectEntry.flags & 0x0F; } virtual std::string GetName() const; virtual void SetRepositoryItem(ObjectRepositoryItem * item) const { } rct_object_entry GetScgWallsHeader(); rct_object_entry GetScgPathXHeader(); rct_object_entry CreateHeader(const char name[9], uint32 flags, uint32 checksum); }; #ifdef __WARN_SUGGEST_FINAL_TYPES__ #pragma GCC diagnostic pop #endif enum OBJECT_ERROR : uint32 { OBJECT_ERROR_OK, OBJECT_ERROR_UNKNOWN, OBJECT_ERROR_BAD_ENCODING, OBJECT_ERROR_INVALID_PROPERTY, OBJECT_ERROR_BAD_STRING_TABLE, OBJECT_ERROR_BAD_IMAGE_TABLE, OBJECT_ERROR_UNEXPECTED_EOF, }; extern sint32 object_entry_group_counts[]; extern sint32 object_entry_group_encoding[]; void object_list_load(); bool object_entry_is_empty(const rct_object_entry *entry); bool object_entry_compare(const rct_object_entry *a, const rct_object_entry *b); sint32 object_calculate_checksum(const rct_object_entry * entry, const void * data, size_t dataLength); bool find_object_in_entry_group(const rct_object_entry* entry, uint8* entry_type, uint8* entry_index); void object_create_identifier_name(char* string_buffer, size_t size, const rct_object_entry* object); const rct_object_entry * object_list_find_by_name(const char *name); const rct_object_entry * object_list_find(rct_object_entry *entry); void object_entry_get_name_fixed(utf8 * buffer, size_t bufferSize, const rct_object_entry * entry); void * object_entry_get_chunk(sint32 objectType, size_t index); const rct_object_entry * object_entry_get_entry(sint32 objectType, size_t index);