1
0
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:
Ted John
2016-06-25 16:34:35 +01:00
parent e93b2141a1
commit 78e15b1d56
17 changed files with 277 additions and 32 deletions

View File

@@ -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" />

View File

@@ -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);

View File

@@ -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.

View File

@@ -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)
{
}
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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()

View File

@@ -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(); };
};

View File

@@ -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;
};

View File

@@ -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;

View File

@@ -22,6 +22,6 @@ class Object;
namespace ObjectFactory
{
Object * CreateObjectFromLegacyFile(utf8 * path);
Object * CreateObjectFromLegacyFile(const utf8 * path);
Object * CreateObject(const rct_object_entry &entry);
}

View File

@@ -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;
}
}
}
}
}

View File

@@ -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
View 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
View 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();
};

View File

@@ -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,

View File

@@ -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;