Skip to content

Commit

Permalink
Implement RoadObject load
Browse files Browse the repository at this point in the history
Also fix unload issues
  • Loading branch information
duncanspumpkin committed Feb 14, 2023
1 parent ed02ba9 commit ac4b2c2
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 19 deletions.
109 changes: 103 additions & 6 deletions src/OpenLoco/src/Objects/RoadObject.cpp
Expand Up @@ -2,6 +2,9 @@
#include "Drawing/SoftwareDrawingEngine.h"
#include "Graphics/Colour.h"
#include "Graphics/Gfx.h"
#include "ObjectImageTable.h"
#include "ObjectManager.h"
#include "ObjectStringTable.h"
#include <OpenLoco/Interop/Interop.hpp>

namespace OpenLoco
Expand Down Expand Up @@ -61,19 +64,113 @@ namespace OpenLoco
// 0x00477BCF
void RoadObject::load(const LoadedObjectHandle& handle, stdx::span<const std::byte> data, ObjectManager::DependentObjects* dependencies)
{
Interop::registers regs;
regs.esi = Interop::X86Pointer(this);
regs.ebx = handle.id;
regs.ecx = enumValue(handle.type);
Interop::call(0x00477BCF, regs);
auto remainingData = data.subspan(sizeof(RoadObject));

auto strRes = ObjectManager::loadStringTable(remainingData, handle, 0);
name = strRes.str;
remainingData = remainingData.subspan(strRes.tableLength);

// NOTE: These aren't dependent (objects unless otherwise stated) as this object can load without the
// related object.
// Load compatible roads/tracks
compatibleTracks = 0;
compatibleRoads = 0;
for (auto i = 0; i < numCompatible; ++i)
{
ObjectHeader modHeader = *reinterpret_cast<const ObjectHeader*>(remainingData.data());
auto res = ObjectManager::findObjectHandle(modHeader);
if (res.has_value())
{
if (res->type == ObjectType::track)
{
compatibleTracks |= 1U << res->id;
}
else if (res->type == ObjectType::road)
{
compatibleRoads |= 1U << res->id;
}
}
remainingData = remainingData.subspan(sizeof(ObjectHeader));
}

// Load Extra
std::fill(std::begin(mods), std::end(mods), 0xFF);
for (auto i = 0U, index = 0U; i < numMods; ++i)
{
ObjectHeader modHeader = *reinterpret_cast<const ObjectHeader*>(remainingData.data());
auto res = ObjectManager::findObjectHandle(modHeader);
if (res.has_value() && res->type == ObjectType::roadExtra)
{
mods[index++] = res->id;
}
remainingData = remainingData.subspan(sizeof(ObjectHeader));
}

// Load Tunnel (DEPENDENT OBJECT)
tunnel = 0xFF;
{
ObjectHeader unkHeader = *reinterpret_cast<const ObjectHeader*>(remainingData.data());
if (dependencies != nullptr)
{
dependencies->required.push_back(unkHeader);
}
auto res = ObjectManager::findObjectHandle(unkHeader);
if (res.has_value())
{
tunnel = res->id;
}
remainingData = remainingData.subspan(sizeof(ObjectHeader));
}

// Load bridges (DEPENDENT OBJECT)
std::fill(std::begin(bridges), std::end(bridges), 0xFF);
for (auto i = 0U; i < numBridges; ++i)
{
ObjectHeader bridgeHeader = *reinterpret_cast<const ObjectHeader*>(remainingData.data());
if (dependencies != nullptr)
{
dependencies->required.push_back(bridgeHeader);
}
auto res = ObjectManager::findObjectHandle(bridgeHeader);
if (res.has_value())
{
bridges[i] = res->id;
}
remainingData = remainingData.subspan(sizeof(ObjectHeader));
}

// Load stations (DEPENDENT OBJECT)
std::fill(std::begin(stations), std::end(stations), 0xFF);
for (auto i = 0U; i < numStations; ++i)
{
ObjectHeader stationHeader = *reinterpret_cast<const ObjectHeader*>(remainingData.data());
if (dependencies != nullptr)
{
dependencies->required.push_back(stationHeader);
}
auto res = ObjectManager::findObjectHandle(stationHeader);
if (res.has_value())
{
stations[i] = res->id;
}
remainingData = remainingData.subspan(sizeof(ObjectHeader));
}

auto imgRes = ObjectManager::loadImageTable(remainingData);
image = imgRes.imageOffset;
assert(remainingData.size() == imgRes.tableLength);
}

// 0x00477D9E
void RoadObject::unload()
{
name = 0;
var_0B = 0;
tunnel = 0;
image = 0;
std::fill(std::begin(bridges), std::end(bridges), 0);
std::fill(std::begin(mods), std::end(mods), 0);
std::fill(std::begin(stations), std::end(stations), 0);
compatibleTracks = 0;
compatibleRoads = 0;
}
}
29 changes: 16 additions & 13 deletions src/OpenLoco/src/Objects/RoadObject.h
Expand Up @@ -53,19 +53,22 @@ namespace OpenLoco
int16_t sellCostFactor; // 0x06
int16_t tunnelCostFactor; // 0x08
uint8_t costIndex; // 0x0A
uint8_t var_0B;
Speed16 maxSpeed; // 0x0C
uint32_t image; // 0x0E
RoadObjectFlags flags; // 0x12
uint8_t numBridges; // 0x14
uint8_t bridges[7]; // 0x15
uint8_t numStations; // 0x1C
uint8_t stations[7]; // 0x1D
uint8_t paintStyle; // 0x24
uint8_t numMods; // 0x25
uint8_t mods[2]; // 0x26
uint8_t numCompatible; // 0x28
uint8_t pad_29[0x30 - 0x29];
uint8_t tunnel; // 0x0B
Speed16 maxSpeed; // 0x0C
uint32_t image; // 0x0E
RoadObjectFlags flags; // 0x12
uint8_t numBridges; // 0x14
uint8_t bridges[7]; // 0x15
uint8_t numStations; // 0x1C
uint8_t stations[7]; // 0x1D
uint8_t paintStyle; // 0x24
uint8_t numMods; // 0x25
uint8_t mods[2]; // 0x26
uint8_t numCompatible; // 0x28
uint8_t pad_29;
uint16_t compatibleRoads; // 0x2A
uint16_t compatibleTracks; // 0x2C
uint8_t pad_2E[0x30 - 0x2E];

void drawPreviewImage(Gfx::RenderTarget& rt, const int16_t x, const int16_t y) const;
bool validate() const;
Expand Down

0 comments on commit ac4b2c2

Please sign in to comment.