mirror of https://github.com/OpenRCT2/OpenRCT2.git
Close #6326: Add support for RCTC SV6 files with 15000 entities
This commit is contained in:
parent
2062084dab
commit
fdf6e1fca7
|
@ -1,5 +1,6 @@
|
|||
0.4.2 (in development)
|
||||
------------------------------------------------------------------------
|
||||
- Feature: [#6326] Ability to load .SV6 files from RCT Classic that have more than 9601 guests.
|
||||
- Feature: [#13634] Add ability to sell merchandise in random colours.
|
||||
- Feature: [#16164] Add new track elements for Flying Coaster and Lay-Down Coaster and add paint code for more elements.
|
||||
- Feature: [#16283] Added parkinfo command line tool to list objects in a save file.
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace RCT2::Limits
|
|||
constexpr const uint8_t MaxTrainsPerRide = 32;
|
||||
constexpr const uint8_t DowntimeHistorySize = 8;
|
||||
constexpr const uint16_t MaxEntities = 10000;
|
||||
constexpr const uint16_t MaxEntitiesFlag15 = 15000;
|
||||
constexpr const uint32_t MaxTileElements = 0x30000;
|
||||
constexpr const uint16_t MaxAnimatedObjects = 2000;
|
||||
constexpr const uint8_t MaxResearchedRideTypeQuads = 8; // With 32 bits per uint32_t, this means there is room for
|
||||
|
|
|
@ -834,7 +834,7 @@ namespace RCT2
|
|||
|
||||
// SC6[6]
|
||||
uint32_t next_free_tile_element_pointer_index;
|
||||
Entity sprites[Limits::MaxEntities];
|
||||
Entity sprites[Limits::MaxEntitiesFlag15];
|
||||
uint16_t sprite_lists_head[static_cast<uint8_t>(EntityListId::Count)];
|
||||
uint16_t sprite_lists_count[static_cast<uint8_t>(EntityListId::Count)];
|
||||
StringId park_name;
|
||||
|
@ -1019,7 +1019,7 @@ namespace RCT2
|
|||
uint16_t wide_path_tile_loop_y;
|
||||
uint8_t pad_13CE778[434];
|
||||
};
|
||||
assert_struct_size(S6Data, 0x46b44a);
|
||||
assert_struct_size(S6Data, 0x5a3c4a);
|
||||
|
||||
struct StexEntry
|
||||
{
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "../core/Console.hpp"
|
||||
#include "../core/FileStream.h"
|
||||
#include "../core/IStream.hpp"
|
||||
#include "../core/MemoryStream.h"
|
||||
#include "../core/Numerics.hpp"
|
||||
#include "../core/Path.hpp"
|
||||
#include "../core/Random.hpp"
|
||||
|
@ -166,11 +167,6 @@ namespace RCT2
|
|||
}
|
||||
}
|
||||
|
||||
if (_s6.header.classic_flag == 0xf)
|
||||
{
|
||||
throw UnsupportedRCTCFlagException(_s6.header.classic_flag);
|
||||
}
|
||||
|
||||
// Read packed objects
|
||||
// TODO try to contain this more and not store objects until later
|
||||
for (uint16_t i = 0; i < _s6.header.num_packed_objects; i++)
|
||||
|
@ -190,7 +186,7 @@ namespace RCT2
|
|||
{
|
||||
chunkReader.ReadChunk(&_s6.elapsed_months, 16);
|
||||
chunkReader.ReadChunk(&_s6.tile_elements, sizeof(_s6.tile_elements));
|
||||
chunkReader.ReadChunk(&_s6.next_free_tile_element_pointer_index, 2560076);
|
||||
ReadChunk6(chunkReader, 76);
|
||||
chunkReader.ReadChunk(&_s6.guests_in_park, 4);
|
||||
chunkReader.ReadChunk(&_s6.last_guests_in_park, 8);
|
||||
chunkReader.ReadChunk(&_s6.park_rating, 2);
|
||||
|
@ -203,7 +199,7 @@ namespace RCT2
|
|||
{
|
||||
chunkReader.ReadChunk(&_s6.elapsed_months, 16);
|
||||
chunkReader.ReadChunk(&_s6.tile_elements, sizeof(_s6.tile_elements));
|
||||
chunkReader.ReadChunk(&_s6.next_free_tile_element_pointer_index, 3048816);
|
||||
ReadChunk6(chunkReader, 488816);
|
||||
}
|
||||
|
||||
_isScenario = isScenario;
|
||||
|
@ -212,6 +208,22 @@ namespace RCT2
|
|||
return ParkLoadResult(GetRequiredObjects());
|
||||
}
|
||||
|
||||
void ReadChunk6(SawyerChunkReader& chunkReader, uint32_t sizeWithoutEntities)
|
||||
{
|
||||
uint32_t entitiesSize = GetMaxEntities() * sizeof(Entity);
|
||||
auto bufferSize = sizeWithoutEntities + entitiesSize;
|
||||
uint8_t buffer[bufferSize];
|
||||
chunkReader.ReadChunk(&buffer, bufferSize);
|
||||
auto stream = OpenRCT2::MemoryStream(&buffer, bufferSize);
|
||||
|
||||
uint32_t preEntitiesSize = sizeof(_s6.next_free_tile_element_pointer_index);
|
||||
uint32_t postEntitiesSize = sizeWithoutEntities - preEntitiesSize;
|
||||
|
||||
stream.Read(&_s6.next_free_tile_element_pointer_index, preEntitiesSize);
|
||||
stream.Read(&_s6.sprites, entitiesSize);
|
||||
stream.Read(&_s6.sprite_lists_head, postEntitiesSize);
|
||||
}
|
||||
|
||||
bool GetDetails(scenario_index_entry* dst) override
|
||||
{
|
||||
*dst = {};
|
||||
|
@ -1168,8 +1180,9 @@ namespace RCT2
|
|||
{
|
||||
// The number of riders might have overflown or underflown. Re-calculate the value.
|
||||
uint16_t numRiders = 0;
|
||||
for (const auto& sprite : _s6.sprites)
|
||||
for (int32_t i = 0; i < GetMaxEntities(); i++)
|
||||
{
|
||||
const auto& sprite = _s6.sprites[i];
|
||||
if (sprite.unknown.sprite_identifier == RCT12SpriteIdentifier::Peep)
|
||||
{
|
||||
if (sprite.peep.current_ride == static_cast<RCT12RideId>(rideIndex.ToUnderlying())
|
||||
|
@ -1592,12 +1605,17 @@ namespace RCT2
|
|||
|
||||
void ImportEntities()
|
||||
{
|
||||
for (int32_t i = 0; i < Limits::MaxEntities; i++)
|
||||
for (int32_t i = 0; i < GetMaxEntities(); i++)
|
||||
{
|
||||
ImportEntity(_s6.sprites[i].unknown);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t GetMaxEntities()
|
||||
{
|
||||
return (_s6.header.classic_flag == 0xf) ? Limits::MaxEntitiesFlag15 : Limits::MaxEntities;
|
||||
}
|
||||
|
||||
template<typename OpenRCT2_T> void ImportEntity(const RCT12SpriteBase& src);
|
||||
|
||||
void ImportEntityPeep(::Peep* dst, const Peep* src)
|
||||
|
|
Loading…
Reference in New Issue