mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-04 13:42:55 +01:00
start getting object loading working
This commit is contained in:
@@ -123,6 +123,7 @@
|
||||
<ClCompile Include="src\object\Object.cpp" />
|
||||
<ClCompile Include="src\object\ObjectFactory.cpp" />
|
||||
<ClCompile Include="src\object\ObjectRepository.cpp" />
|
||||
<ClCompile Include="src\object\StexObject.cpp" />
|
||||
<ClCompile Include="src\object\StringTable.cpp" />
|
||||
<ClCompile Include="src\object_list.c" />
|
||||
<ClCompile Include="src\openrct2.c" />
|
||||
@@ -429,6 +430,7 @@
|
||||
<ClInclude Include="src\object\Object.h" />
|
||||
<ClInclude Include="src\object\ObjectFactory.h" />
|
||||
<ClInclude Include="src\object\ObjectRepository.h" />
|
||||
<ClInclude Include="src\object\StexObject.h" />
|
||||
<ClInclude Include="src\object\StringTable.h" />
|
||||
<ClInclude Include="src\object_list.h" />
|
||||
<ClInclude Include="src\openrct2.h" />
|
||||
|
||||
@@ -176,6 +176,8 @@ int gfx_load_g2();
|
||||
void gfx_unload_g1();
|
||||
void gfx_unload_g2();
|
||||
rct_g1_element* gfx_get_g1_element(int image_id);
|
||||
uint32 gfx_object_allocate_images(const rct_g1_element * images, uint32 count);
|
||||
void gfx_object_free_images(uint32 baseImageId, uint32 count);
|
||||
void sub_68371D();
|
||||
void FASTCALL gfx_rle_sprite_to_buffer(const uint8* RESTRICT source_bits_pointer, uint8* RESTRICT dest_bits_pointer, const uint8* RESTRICT palette_pointer, const rct_drawpixelinfo * RESTRICT dpi, int image_type, int source_y_start, int height, int source_x_start, int width);
|
||||
void FASTCALL gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 tertiary_colour);
|
||||
|
||||
@@ -173,6 +173,29 @@ int gfx_load_g2()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32 _nextImageId = 29294;
|
||||
|
||||
uint32 gfx_object_allocate_images(const rct_g1_element * images, uint32 count)
|
||||
{
|
||||
uint32 baseImageId = _nextImageId;
|
||||
for (uint32 i = 0; i < count; i++) {
|
||||
uint32 imageId = _nextImageId;
|
||||
if (imageId >= 291438) {
|
||||
log_error("Reached maximum image limit.");
|
||||
break;
|
||||
}
|
||||
|
||||
g1Elements[imageId] = images[i];
|
||||
drawing_engine_invalidate_image(imageId);
|
||||
_nextImageId++;
|
||||
}
|
||||
return baseImageId;
|
||||
}
|
||||
|
||||
void gfx_object_free_images(uint32 baseImageId, uint32 count)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This function looks like it initialises the 0x009E3CE4 array which references sprites used for background / palette mixing or
|
||||
* something. Further investigation is needed.
|
||||
|
||||
@@ -455,4 +455,17 @@ bool language_get_localised_scenario_strings(const utf8 *scenarioFilename, rct_s
|
||||
outStringIds[2] != STR_NONE;
|
||||
}
|
||||
|
||||
static rct_string_id _nextObjectStringId = NONSTEX_BASE_STRING_ID;
|
||||
|
||||
rct_string_id language_allocate_object_string(const utf8 * target)
|
||||
{
|
||||
rct_string_id stringId = _nextObjectStringId++;
|
||||
_languageCurrent->SetString(stringId, target);
|
||||
return stringId;
|
||||
}
|
||||
|
||||
void language_free_object_string(rct_string_id stringId)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -82,5 +82,7 @@ wchar_t *utf8_to_widechar(const utf8 *src);
|
||||
utf8 *widechar_to_utf8(const wchar_t *src);
|
||||
|
||||
bool language_get_localised_scenario_strings(const utf8 *scenarioFilename, rct_string_id *outStringIds);
|
||||
rct_string_id language_allocate_object_string(const utf8 * target);
|
||||
void language_free_object_string(rct_string_id stringId);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -149,7 +149,7 @@ int object_load_file(int groupIndex, const rct_object_entry *entry, int* chunkSi
|
||||
*
|
||||
* rct2: 0x006A985D
|
||||
*/
|
||||
int object_load_chunk(int groupIndex, rct_object_entry *entry, int* chunkSize)
|
||||
int object_load_chunk_old(int groupIndex, rct_object_entry *entry, int* chunkSize)
|
||||
{
|
||||
// Alow chunkSize to be null
|
||||
int tempChunkSize;
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
#include "../core/IStream.hpp"
|
||||
#include "EntranceObject.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../drawing/drawing.h"
|
||||
#include "../localisation/localisation.h"
|
||||
}
|
||||
|
||||
enum OBJ_STRING_ID
|
||||
{
|
||||
OBJ_STRING_ID_NAME,
|
||||
@@ -35,12 +41,13 @@ void EntranceObject::ReadLegacy(IStream * stream)
|
||||
|
||||
void EntranceObject::Load()
|
||||
{
|
||||
|
||||
_legacyType.string_idx = language_allocate_object_string(GetName());
|
||||
_legacyType.image_id = gfx_object_allocate_images(ImageTable.GetImages(), ImageTable.GetCount());
|
||||
}
|
||||
|
||||
void EntranceObject::Unload()
|
||||
{
|
||||
|
||||
language_free_object_string(_legacyType.string_idx);
|
||||
}
|
||||
|
||||
const utf8 * EntranceObject::GetName()
|
||||
|
||||
@@ -36,5 +36,7 @@ private:
|
||||
public:
|
||||
~ImageTable();
|
||||
|
||||
void Read(IStream * stream);
|
||||
void Read(IStream * stream);
|
||||
const rct_g1_element * GetImages() const { return _entries.data(); }
|
||||
uint32 GetCount() const { return _entries.size(); };
|
||||
};
|
||||
@@ -48,5 +48,6 @@ public:
|
||||
virtual void Load() abstract;
|
||||
virtual void Unload() abstract;
|
||||
|
||||
virtual const utf8 * GetName() abstract;
|
||||
virtual uint8 GetObjectType() { return _objectEntry.flags & 0x0F; }
|
||||
virtual const utf8 * GetName() abstract;
|
||||
};
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "EntranceObject.h"
|
||||
#include "Object.h"
|
||||
#include "ObjectFactory.h"
|
||||
#include "StexObject.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@@ -29,7 +30,7 @@ extern "C"
|
||||
|
||||
namespace ObjectFactory
|
||||
{
|
||||
Object * CreateObjectFromLegacyFile(utf8 * path)
|
||||
Object * CreateObjectFromLegacyFile(const utf8 * path)
|
||||
{
|
||||
Object * result = nullptr;
|
||||
|
||||
@@ -64,6 +65,9 @@ namespace ObjectFactory
|
||||
case OBJECT_TYPE_PARK_ENTRANCE:
|
||||
result = new EntranceObject(entry);
|
||||
break;
|
||||
case OBJECT_TYPE_SCENARIO_TEXT:
|
||||
result = new StexObject(entry);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -22,6 +22,6 @@ class Object;
|
||||
|
||||
namespace ObjectFactory
|
||||
{
|
||||
Object * CreateObjectFromLegacyFile(utf8 * path);
|
||||
Object * CreateObjectFromLegacyFile(const utf8 * path);
|
||||
Object * CreateObject(const rct_object_entry &entry);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "../common.h"
|
||||
#include "../core/Console.hpp"
|
||||
#include "../core/FileStream.hpp"
|
||||
#include "../core/Guard.hpp"
|
||||
#include "../core/IStream.hpp"
|
||||
@@ -26,11 +27,14 @@
|
||||
#include "Object.h"
|
||||
#include "ObjectFactory.h"
|
||||
#include "ObjectRepository.h"
|
||||
#include "StexObject.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../object.h"
|
||||
#include "../platform/platform.h"
|
||||
#include "../scenario.h"
|
||||
}
|
||||
|
||||
constexpr uint16 OBJECT_REPOSITORY_VERSION = 6;
|
||||
@@ -87,6 +91,17 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Object * LoadObject(const rct_object_entry * objectEntry) override
|
||||
{
|
||||
Object * object = nullptr;
|
||||
const ObjectRepositoryItem * item = FindObject(objectEntry);
|
||||
if (item != nullptr)
|
||||
{
|
||||
object = ObjectFactory::CreateObjectFromLegacyFile(item->Path);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
private:
|
||||
void ClearItems()
|
||||
{
|
||||
@@ -329,4 +344,77 @@ extern "C"
|
||||
{
|
||||
IObjectRepository * objRepo = GetObjectRepository();
|
||||
}
|
||||
|
||||
int object_load_chunk(int groupIndex, rct_object_entry * entry, int * chunkSize)
|
||||
{
|
||||
IObjectRepository * objRepo = GetObjectRepository();
|
||||
Object * object = objRepo->LoadObject(entry);
|
||||
if (object == nullptr)
|
||||
{
|
||||
utf8 objName[9] = { 0 };
|
||||
Memory::Copy(objName, entry->name, 8);
|
||||
Console::Error::WriteFormat("[%s]: Object not found or could not be loaded.", objName);
|
||||
Console::Error::WriteLine();
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 objectType = object->GetObjectType();
|
||||
void * * chunkList = object_entry_groups[objectType].chunks;
|
||||
if (groupIndex == -1)
|
||||
{
|
||||
for (groupIndex = 0; chunkList[groupIndex] != (void*)-1; groupIndex++)
|
||||
{
|
||||
if (groupIndex + 1 >= object_entry_group_counts[objectType])
|
||||
{
|
||||
log_error("Object Load failed due to too many objects of a certain type.");
|
||||
delete object;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
chunkList[groupIndex] = object->GetLegacyData();
|
||||
|
||||
rct_object_entry_extended * extendedEntry = &object_entry_groups[objectType].entries[groupIndex];
|
||||
Memory::Copy<void>(extendedEntry, object->GetObjectEntry(), sizeof(rct_object_entry));
|
||||
extendedEntry->chunk_size = 0;
|
||||
|
||||
object->Load();
|
||||
return 1;
|
||||
}
|
||||
|
||||
void scenario_translate(scenario_index_entry * scenarioEntry, const rct_object_entry * stexObjectEntry)
|
||||
{
|
||||
rct_string_id localisedStringIds[3];
|
||||
if (language_get_localised_scenario_strings(scenarioEntry->name, localisedStringIds))
|
||||
{
|
||||
if (localisedStringIds[0] != STR_NONE)
|
||||
{
|
||||
String::Set(scenarioEntry->name, sizeof(scenarioEntry->name), language_get_string(localisedStringIds[0]));
|
||||
}
|
||||
if (localisedStringIds[2] != STR_NONE)
|
||||
{
|
||||
String::Set(scenarioEntry->details, sizeof(scenarioEntry->details), language_get_string(localisedStringIds[2]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Checks for a scenario string object (possibly for localisation)
|
||||
if ((stexObjectEntry->flags & 0xFF) != 255)
|
||||
{
|
||||
IObjectRepository * objRepo = GetObjectRepository();
|
||||
Object * object = objRepo->LoadObject(stexObjectEntry);
|
||||
if (object != nullptr)
|
||||
{
|
||||
StexObject * stexObject = static_cast<StexObject*>(object);
|
||||
const utf8 * scenarioName = stexObject->GetScenarioName();
|
||||
const utf8 * scenarioDetails = stexObject->GetScenarioDetails();
|
||||
|
||||
String::Set(scenarioEntry->name, sizeof(scenarioEntry->name), scenarioName);
|
||||
String::Set(scenarioEntry->details, sizeof(scenarioEntry->details), scenarioDetails);
|
||||
|
||||
delete object;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,8 @@ interface IObjectRepository
|
||||
{
|
||||
virtual ~IObjectRepository() { }
|
||||
|
||||
virtual const ObjectRepositoryItem * FindObject(const rct_object_entry * objectEntry) abstract;
|
||||
virtual const ObjectRepositoryItem * FindObject(const rct_object_entry * objectEntry) abstract;
|
||||
virtual Object * LoadObject(const rct_object_entry * objectEntry) abstract;
|
||||
};
|
||||
|
||||
IObjectRepository * GetObjectRepository();
|
||||
|
||||
77
src/object/StexObject.cpp
Normal file
77
src/object/StexObject.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#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 "StexObject.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../localisation/localisation.h"
|
||||
}
|
||||
|
||||
enum OBJ_STRING_ID
|
||||
{
|
||||
OBJ_STRING_ID_SCENARIO_NAME,
|
||||
OBJ_STRING_ID_PARK_NAME,
|
||||
OBJ_STRING_ID_SCENARIO_DETAILS,
|
||||
};
|
||||
|
||||
void StexObject::ReadLegacy(IStream * stream)
|
||||
{
|
||||
_legacyType.scenario_name = stream->ReadValue<rct_string_id>();
|
||||
_legacyType.park_name = stream->ReadValue<rct_string_id>();
|
||||
_legacyType.details = stream->ReadValue<rct_string_id>();
|
||||
_legacyType.var_06 = stream->ReadValue<uint8>();
|
||||
stream->Seek(1, STREAM_SEEK_CURRENT);
|
||||
|
||||
StringTable.Read(stream, OBJ_STRING_ID_SCENARIO_NAME);
|
||||
StringTable.Read(stream, OBJ_STRING_ID_PARK_NAME);
|
||||
StringTable.Read(stream, OBJ_STRING_ID_SCENARIO_DETAILS);
|
||||
}
|
||||
|
||||
void StexObject::Load()
|
||||
{
|
||||
_legacyType.scenario_name = language_allocate_object_string(GetScenarioName());
|
||||
_legacyType.park_name = language_allocate_object_string(GetParkName());
|
||||
_legacyType.details = language_allocate_object_string(GetScenarioDetails());
|
||||
}
|
||||
|
||||
void StexObject::Unload()
|
||||
{
|
||||
language_free_object_string(_legacyType.scenario_name);
|
||||
language_free_object_string(_legacyType.park_name);
|
||||
language_free_object_string(_legacyType.details);
|
||||
}
|
||||
|
||||
const utf8 * StexObject::GetName()
|
||||
{
|
||||
return GetScenarioName();
|
||||
}
|
||||
|
||||
const utf8 * StexObject::GetScenarioName()
|
||||
{
|
||||
return StringTable.GetString(OBJ_STRING_ID_SCENARIO_NAME);
|
||||
}
|
||||
|
||||
const utf8 * StexObject::GetScenarioDetails()
|
||||
{
|
||||
return StringTable.GetString(OBJ_STRING_ID_SCENARIO_DETAILS);
|
||||
}
|
||||
|
||||
const utf8 * StexObject::GetParkName()
|
||||
{
|
||||
return StringTable.GetString(OBJ_STRING_ID_PARK_NAME);
|
||||
}
|
||||
45
src/object/StexObject.h
Normal file
45
src/object/StexObject.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#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 "../scenario.h"
|
||||
}
|
||||
|
||||
class StexObject : public Object
|
||||
{
|
||||
private:
|
||||
rct_stex_entry _legacyType;
|
||||
|
||||
public:
|
||||
explicit StexObject(const rct_object_entry &entry) : Object(entry) { };
|
||||
|
||||
void * GetLegacyData() override { return &_legacyType; }
|
||||
|
||||
void ReadLegacy(IStream * stream) override;
|
||||
void Load() override;
|
||||
void Unload() override;
|
||||
|
||||
const utf8 * GetName() override;
|
||||
|
||||
const utf8 * GetScenarioName();
|
||||
const utf8 * GetScenarioDetails();
|
||||
const utf8 * GetParkName();
|
||||
};
|
||||
@@ -490,6 +490,8 @@ bool scenario_get_source_desc(const utf8 *name, source_desc *outDesc);
|
||||
bool scenario_get_source_desc_by_id(uint8 id, source_desc *outDesc);
|
||||
void scenario_normalise_name(utf8 *name);
|
||||
|
||||
void scenario_translate(scenario_index_entry *scenarioEntry, const rct_object_entry *stexObjectEntry);
|
||||
|
||||
// RCT1 scenario index map
|
||||
enum {
|
||||
SC_UNIDENTIFIED = 255,
|
||||
|
||||
@@ -36,7 +36,6 @@ static void scenario_list_add(const utf8 *path, uint64 timestamp);
|
||||
static void scenario_list_sort();
|
||||
static int scenario_list_sort_by_category(const void *a, const void *b);
|
||||
static int scenario_list_sort_by_index(const void *a, const void *b);
|
||||
static void scenario_translate(scenario_index_entry *scenarioEntry, const rct_object_entry *stexObjectEntry);
|
||||
|
||||
static bool scenario_scores_load();
|
||||
static void scenario_scores_legacy_get_path(utf8 *outPath);
|
||||
@@ -183,29 +182,6 @@ static void scenario_list_add(const utf8 *path, uint64 timestamp)
|
||||
scenario_translate(newEntry, &s6Info.entry);
|
||||
}
|
||||
|
||||
static void scenario_translate(scenario_index_entry *scenarioEntry, const rct_object_entry *stexObjectEntry)
|
||||
{
|
||||
rct_string_id localisedStringIds[3];
|
||||
if (language_get_localised_scenario_strings(scenarioEntry->name, localisedStringIds)) {
|
||||
if (localisedStringIds[0] != STR_NONE) {
|
||||
safe_strcpy(scenarioEntry->name, language_get_string(localisedStringIds[0]), 64);
|
||||
}
|
||||
if (localisedStringIds[2] != STR_NONE) {
|
||||
safe_strcpy(scenarioEntry->details, language_get_string(localisedStringIds[2]), 256);
|
||||
}
|
||||
} else {
|
||||
// Checks for a scenario string object (possibly for localisation)
|
||||
if ((stexObjectEntry->flags & 0xFF) != 255) {
|
||||
if (object_get_scenario_text((rct_object_entry*)stexObjectEntry)) {
|
||||
rct_stex_entry* stex_entry = gStexTempChunk;
|
||||
format_string(scenarioEntry->name, stex_entry->scenario_name, NULL);
|
||||
format_string(scenarioEntry->details, stex_entry->details, NULL);
|
||||
object_free_scenario_text();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void scenario_list_dispose()
|
||||
{
|
||||
gScenarioListCapacity = 0;
|
||||
|
||||
Reference in New Issue
Block a user