mirror of https://github.com/OpenRCT2/OpenRCT2.git
Fix nested arrays and ride measurement
This commit is contained in:
parent
ccb2eed939
commit
48f5515a55
|
@ -548,6 +548,16 @@ namespace OpenRCT2
|
|||
|
||||
// Stats
|
||||
if (cs.GetMode() == OrcaStream::Mode::READING)
|
||||
{
|
||||
auto hasMeasurement = cs.Read<uint8_t>();
|
||||
if (hasMeasurement != 0)
|
||||
{
|
||||
ride.measurement = std::make_unique<RideMeasurement>();
|
||||
ride.measurement->ride = &ride;
|
||||
ReadWriteRideMeasurement(cs, *ride.measurement);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ride.measurement == nullptr)
|
||||
{
|
||||
|
@ -559,18 +569,6 @@ namespace OpenRCT2
|
|||
ReadWriteRideMeasurement(cs, *ride.measurement);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto hasMeasurement = cs.Read<uint8_t>();
|
||||
if (hasMeasurement)
|
||||
{
|
||||
ride.measurement = std::make_unique<RideMeasurement>();
|
||||
ride.measurement->ride = &ride;
|
||||
ReadWriteRideMeasurement(cs, *ride.measurement);
|
||||
}
|
||||
}
|
||||
|
||||
cs.ReadWrite(ride.measurement);
|
||||
|
||||
cs.ReadWrite(ride.special_track_elements);
|
||||
cs.ReadWrite(ride.max_speed);
|
||||
|
@ -673,12 +671,6 @@ namespace OpenRCT2
|
|||
|
||||
static void ReadWriteRideMeasurement(OrcaStream::ChunkStream& cs, RideMeasurement& measurement)
|
||||
{
|
||||
if (cs.GetMode() == OrcaStream::Mode::READING)
|
||||
{
|
||||
// Initialise measurement (mainly just for the fixed arrays)
|
||||
measurement = {};
|
||||
}
|
||||
|
||||
cs.ReadWrite(measurement.flags);
|
||||
cs.ReadWrite(measurement.last_use_tick);
|
||||
cs.ReadWrite(measurement.num_items);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
|
||||
namespace OpenRCT2
|
||||
|
@ -189,12 +190,17 @@ namespace OpenRCT2
|
|||
class ChunkStream
|
||||
{
|
||||
private:
|
||||
struct ArrayState
|
||||
{
|
||||
std::streampos StartPos{};
|
||||
std::streampos LastPos{};
|
||||
size_t Count{};
|
||||
size_t ElementSize{};
|
||||
};
|
||||
|
||||
std::stringstream& _buffer;
|
||||
Mode _mode;
|
||||
std::streampos _currentArrayStartPos;
|
||||
std::streampos _currentArrayLastPos;
|
||||
size_t _currentArrayCount;
|
||||
size_t _currentArrayElementSize;
|
||||
std::stack<ArrayState> _arrayStack;
|
||||
|
||||
public:
|
||||
ChunkStream(std::stringstream& buffer, Mode mode)
|
||||
|
@ -388,78 +394,82 @@ namespace OpenRCT2
|
|||
|
||||
size_t BeginArray()
|
||||
{
|
||||
auto& arrayState = _arrayStack.emplace();
|
||||
if (_mode == Mode::READING)
|
||||
{
|
||||
_currentArrayCount = Read<uint32_t>();
|
||||
_currentArrayElementSize = Read<uint32_t>();
|
||||
_currentArrayLastPos = _buffer.tellg();
|
||||
return _currentArrayCount;
|
||||
arrayState.Count = Read<uint32_t>();
|
||||
arrayState.ElementSize = Read<uint32_t>();
|
||||
arrayState.LastPos = _buffer.tellg();
|
||||
return arrayState.Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentArrayCount = 0;
|
||||
_currentArrayElementSize = 0;
|
||||
_currentArrayStartPos = _buffer.tellp();
|
||||
arrayState.Count = 0;
|
||||
arrayState.ElementSize = 0;
|
||||
arrayState.StartPos = _buffer.tellp();
|
||||
Write<uint32_t>(0);
|
||||
Write<uint32_t>(0);
|
||||
_currentArrayLastPos = _buffer.tellp();
|
||||
arrayState.LastPos = _buffer.tellp();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool NextArrayElement()
|
||||
{
|
||||
auto& arrayState = _arrayStack.top();
|
||||
if (_mode == Mode::READING)
|
||||
{
|
||||
if (_currentArrayCount == 0)
|
||||
if (arrayState.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (_currentArrayElementSize != 0)
|
||||
if (arrayState.ElementSize != 0)
|
||||
{
|
||||
_currentArrayLastPos += _currentArrayElementSize;
|
||||
_buffer.seekg(_currentArrayLastPos);
|
||||
arrayState.LastPos += arrayState.ElementSize;
|
||||
_buffer.seekg(arrayState.LastPos);
|
||||
}
|
||||
_currentArrayCount--;
|
||||
return _currentArrayCount == 0;
|
||||
arrayState.Count--;
|
||||
return arrayState.Count == 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto lastElSize = (size_t)_buffer.tellp() - _currentArrayLastPos;
|
||||
if (_currentArrayCount == 0)
|
||||
auto lastElSize = (size_t)_buffer.tellp() - arrayState.LastPos;
|
||||
if (arrayState.Count == 0)
|
||||
{
|
||||
// Set array element size based on first element size
|
||||
_currentArrayElementSize = lastElSize;
|
||||
arrayState.ElementSize = lastElSize;
|
||||
}
|
||||
else if (_currentArrayElementSize != lastElSize)
|
||||
else if (arrayState.ElementSize != lastElSize)
|
||||
{
|
||||
// Array element size was different from first element so reset it
|
||||
// to dynamic
|
||||
_currentArrayElementSize = 0;
|
||||
arrayState.ElementSize = 0;
|
||||
}
|
||||
_currentArrayCount++;
|
||||
_currentArrayLastPos = _buffer.tellp();
|
||||
arrayState.Count++;
|
||||
arrayState.LastPos = _buffer.tellp();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void EndArray()
|
||||
{
|
||||
auto& arrayState = _arrayStack.top();
|
||||
if (_mode == Mode::READING)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
auto backupPos = _buffer.tellp();
|
||||
if ((size_t)backupPos != (size_t)_currentArrayStartPos + 8 && _currentArrayCount == 0)
|
||||
if ((size_t)backupPos != (size_t)arrayState.StartPos + 8 && arrayState.Count == 0)
|
||||
{
|
||||
throw std::runtime_error("Array data was written but no elements were added.");
|
||||
}
|
||||
_buffer.seekp(_currentArrayStartPos);
|
||||
Write((uint32_t)_currentArrayCount);
|
||||
Write((uint32_t)_currentArrayElementSize);
|
||||
_buffer.seekp(arrayState.StartPos);
|
||||
Write((uint32_t)arrayState.Count);
|
||||
Write((uint32_t)arrayState.ElementSize);
|
||||
_buffer.seekp(backupPos);
|
||||
}
|
||||
_arrayStack.pop();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue