Merge pull request #14134 from duncanspumpkin/reorg_entityexport

Rework how entity export works to allow for easier changes in future
This commit is contained in:
Michael Steenbeek 2021-02-26 13:08:56 +01:00 committed by GitHub
commit 9397feaa44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 175 additions and 147 deletions

View File

@ -763,6 +763,7 @@ public:
RCT12SpriteCrashedVehicleParticle crashed_vehicle_particle;
RCT12SpriteCrashSplash crash_splash;
RCT12SpriteSteamParticle steam_particle;
RCT12SpriteParticle misc_particle;
};
assert_struct_size(RCT2Sprite, 0x100);

View File

@ -188,7 +188,7 @@ void S6Exporter::Export()
// Map elements must be reorganised prior to saving otherwise save may be invalid
map_reorganise_elements();
ExportTileElements();
ExportSprites();
ExportEntities();
ExportParkName();
_s6.initial_cash = gInitialCash;
@ -937,21 +937,6 @@ void S6Exporter::ExportMarketingCampaigns()
}
}
void S6Exporter::ExportSprites()
{
// Sprites needs to be reset before they get used.
// Might as well reset them in here to zero out the space and improve
// compression ratios. Especially useful for multiplayer servers that
// use zlib on the sent stream.
sprite_clear_all_unused();
for (int32_t i = 0; i < RCT2_MAX_SPRITES; i++)
{
ExportSprite(&_s6.sprites[i], reinterpret_cast<const rct_sprite*>(GetEntity(i)));
}
RebuildEntityLinks();
}
void S6Exporter::RebuildEntityLinks()
{
// Rebuild next/previous linked list entity indexs
@ -1002,33 +987,6 @@ void S6Exporter::RebuildEntityLinks()
}
}
void S6Exporter::ExportSprite(RCT2Sprite* dst, const rct_sprite* src)
{
std::memset(dst, 0, sizeof(rct_sprite));
switch (src->misc.sprite_identifier)
{
case SpriteIdentifier::Null:
ExportSpriteCommonProperties(&dst->unknown, &src->misc);
break;
case SpriteIdentifier::Vehicle:
ExportSpriteVehicle(&dst->vehicle, &src->vehicle);
break;
case SpriteIdentifier::Peep:
ExportSpritePeep(&dst->peep, &src->peep);
break;
case SpriteIdentifier::Misc:
ExportSpriteMisc(&dst->unknown, &src->misc);
break;
case SpriteIdentifier::Litter:
ExportSpriteLitter(&dst->litter, &src->litter);
break;
default:
ExportSpriteCommonProperties(&dst->unknown, &src->misc);
log_warning("Sprite identifier %d can not be exported.", src->misc.sprite_identifier);
break;
}
}
constexpr RCT12EntityLinkListOffset GetRCT2LinkListOffset(const SpriteBase* src)
{
RCT12EntityLinkListOffset output = RCT12EntityLinkListOffset::Free;
@ -1062,7 +1020,7 @@ constexpr RCT12EntityLinkListOffset GetRCT2LinkListOffset(const SpriteBase* src)
return output;
}
void S6Exporter::ExportSpriteCommonProperties(RCT12SpriteBase* dst, const SpriteBase* src)
void S6Exporter::ExportEntityCommonProperties(RCT12SpriteBase* dst, const SpriteBase* src)
{
dst->sprite_identifier = src->sprite_identifier;
dst->linked_list_type_offset = GetRCT2LinkListOffset(src);
@ -1082,11 +1040,11 @@ void S6Exporter::ExportSpriteCommonProperties(RCT12SpriteBase* dst, const Sprite
dst->sprite_direction = src->sprite_direction;
}
void S6Exporter::ExportSpriteVehicle(RCT2SpriteVehicle* dst, const Vehicle* src)
template<> void S6Exporter::ExportEntity(RCT2SpriteVehicle* dst, const Vehicle* src)
{
const auto* ride = src->GetRide();
ExportSpriteCommonProperties(dst, static_cast<const SpriteBase*>(src));
ExportEntityCommonProperties(dst, src);
dst->type = EnumValue(src->SubType);
dst->vehicle_sprite_type = src->vehicle_sprite_type;
dst->bank_rotation = src->bank_rotation;
@ -1170,9 +1128,18 @@ void S6Exporter::ExportSpriteVehicle(RCT2SpriteVehicle* dst, const Vehicle* src)
dst->target_seat_rotation = src->target_seat_rotation;
}
void S6Exporter::ExportSpritePeep(RCT2SpritePeep* dst, const Peep* src)
template<> void S6Exporter::ExportEntity(RCT2SpritePeep* dst, const Guest* src)
{
ExportSpriteCommonProperties(dst, static_cast<const SpriteBase*>(src));
ExportEntityPeep(dst, src);
}
template<> void S6Exporter::ExportEntity(RCT2SpritePeep* dst, const Staff* src)
{
ExportEntityPeep(dst, src);
}
void S6Exporter::ExportEntityPeep(RCT2SpritePeep* dst, const Peep* src)
{
ExportEntityCommonProperties(dst, src);
auto generateName = true;
if (src->Name != nullptr)
@ -1322,106 +1289,169 @@ void S6Exporter::ExportSpritePeep(RCT2SpritePeep* dst, const Peep* src)
dst->item_standard_flags = static_cast<uint32_t>(src->GetItemFlags());
}
void S6Exporter::ExportSpriteMisc(RCT12SpriteBase* cdst, const MiscEntity* csrc)
template<> void S6Exporter::ExportEntity(RCT12SpriteSteamParticle* dst, const SteamParticle* src)
{
ExportSpriteCommonProperties(cdst, csrc);
cdst->type = EnumValue(csrc->SubType);
switch (csrc->SubType)
{
case MiscEntityType::SteamParticle:
{
auto src = static_cast<const SteamParticle*>(csrc);
auto dst = static_cast<RCT12SpriteSteamParticle*>(cdst);
dst->time_to_move = src->time_to_move;
dst->frame = src->frame;
break;
}
case MiscEntityType::MoneyEffect:
{
auto src = static_cast<const MoneyEffect*>(csrc);
auto dst = static_cast<RCT12SpriteMoneyEffect*>(cdst);
dst->move_delay = src->MoveDelay;
dst->num_movements = src->NumMovements;
dst->vertical = src->Vertical;
dst->value = src->Value;
dst->offset_x = src->OffsetX;
dst->wiggle = src->Wiggle;
break;
}
case MiscEntityType::CrashedVehicleParticle:
{
auto src = static_cast<const VehicleCrashParticle*>(csrc);
auto dst = static_cast<RCT12SpriteCrashedVehicleParticle*>(cdst);
dst->frame = src->frame;
dst->time_to_live = src->time_to_live;
dst->frame = src->frame;
dst->colour[0] = src->colour[0];
dst->colour[1] = src->colour[1];
dst->crashed_sprite_base = src->crashed_sprite_base;
dst->velocity_x = src->velocity_x;
dst->velocity_y = src->velocity_y;
dst->velocity_z = src->velocity_z;
dst->acceleration_x = src->acceleration_x;
dst->acceleration_y = src->acceleration_y;
dst->acceleration_z = src->acceleration_z;
break;
}
case MiscEntityType::ExplosionCloud:
case MiscEntityType::ExplosionFlare:
case MiscEntityType::CrashSplash:
{
auto src = static_cast<const MiscEntity*>(csrc);
auto dst = static_cast<RCT12SpriteParticle*>(cdst);
dst->frame = src->frame;
break;
}
case MiscEntityType::JumpingFountainWater:
case MiscEntityType::JumpingFountainSnow:
{
auto* src = static_cast<const JumpingFountain*>(csrc);
auto* dst = static_cast<RCT12SpriteJumpingFountain*>(cdst);
dst->num_ticks_alive = src->NumTicksAlive;
dst->frame = src->frame;
dst->fountain_flags = src->FountainFlags;
dst->target_x = src->TargetX;
dst->target_y = src->TargetY;
dst->target_y = src->TargetY;
dst->iteration = src->Iteration;
break;
}
case MiscEntityType::Balloon:
{
auto src = static_cast<const Balloon*>(csrc);
auto dst = static_cast<RCT12SpriteBalloon*>(cdst);
dst->popped = src->popped;
dst->time_to_move = src->time_to_move;
dst->frame = src->frame;
dst->colour = src->colour;
break;
}
case MiscEntityType::Duck:
{
auto src = static_cast<const Duck*>(csrc);
auto dst = static_cast<RCT12SpriteDuck*>(cdst);
dst->frame = src->frame;
dst->target_x = src->target_x;
dst->target_y = src->target_y;
dst->state = EnumValue(src->state);
break;
}
default:
log_warning("Misc. sprite type %d can not be exported.", cdst->type);
break;
}
ExportEntityCommonProperties(dst, src);
dst->type = EnumValue(src->SubType);
dst->time_to_move = src->time_to_move;
dst->frame = src->frame;
}
template<> void S6Exporter::ExportEntity(RCT12SpriteMoneyEffect* dst, const MoneyEffect* src)
{
ExportEntityCommonProperties(dst, src);
dst->type = EnumValue(src->SubType);
dst->move_delay = src->MoveDelay;
dst->num_movements = src->NumMovements;
dst->vertical = src->Vertical;
dst->value = src->Value;
dst->offset_x = src->OffsetX;
dst->wiggle = src->Wiggle;
}
template<> void S6Exporter::ExportEntity(RCT12SpriteCrashedVehicleParticle* dst, const VehicleCrashParticle* src)
{
ExportEntityCommonProperties(dst, src);
dst->type = EnumValue(src->SubType);
dst->frame = src->frame;
dst->time_to_live = src->time_to_live;
dst->frame = src->frame;
dst->colour[0] = src->colour[0];
dst->colour[1] = src->colour[1];
dst->crashed_sprite_base = src->crashed_sprite_base;
dst->velocity_x = src->velocity_x;
dst->velocity_y = src->velocity_y;
dst->velocity_z = src->velocity_z;
dst->acceleration_x = src->acceleration_x;
dst->acceleration_y = src->acceleration_y;
dst->acceleration_z = src->acceleration_z;
}
template<> void S6Exporter::ExportEntity(RCT12SpriteJumpingFountain* dst, const JumpingFountain* src)
{
ExportEntityCommonProperties(dst, src);
dst->type = EnumValue(src->SubType);
dst->num_ticks_alive = src->NumTicksAlive;
dst->frame = src->frame;
dst->fountain_flags = src->FountainFlags;
dst->target_x = src->TargetX;
dst->target_y = src->TargetY;
dst->target_y = src->TargetY;
dst->iteration = src->Iteration;
}
template<> void S6Exporter::ExportEntity(RCT12SpriteBalloon* dst, const Balloon* src)
{
ExportEntityCommonProperties(dst, src);
dst->type = EnumValue(src->SubType);
dst->popped = src->popped;
dst->time_to_move = src->time_to_move;
dst->frame = src->frame;
dst->colour = src->colour;
}
template<> void S6Exporter::ExportEntity(RCT12SpriteDuck* dst, const Duck* src)
{
ExportEntityCommonProperties(dst, src);
dst->type = EnumValue(src->SubType);
dst->frame = src->frame;
dst->target_x = src->target_x;
dst->target_y = src->target_y;
dst->state = EnumValue(src->state);
}
template<> void S6Exporter::ExportEntity(RCT12SpriteParticle* dst, const ExplosionCloud* src)
{
ExportEntityCommonProperties(dst, src);
dst->type = EnumValue(src->SubType);
dst->frame = src->frame;
}
template<> void S6Exporter::ExportEntity(RCT12SpriteParticle* dst, const ExplosionFlare* src)
{
ExportEntityCommonProperties(dst, src);
dst->type = EnumValue(src->SubType);
dst->frame = src->frame;
}
template<> void S6Exporter::ExportEntity(RCT12SpriteParticle* dst, const CrashSplashParticle* src)
{
ExportEntityCommonProperties(dst, src);
dst->type = EnumValue(src->SubType);
dst->frame = src->frame;
}
void S6Exporter::ExportSpriteLitter(RCT12SpriteLitter* dst, const Litter* src)
template<> void S6Exporter::ExportEntity(RCT12SpriteLitter* dst, const Litter* src)
{
ExportSpriteCommonProperties(dst, src);
ExportEntityCommonProperties(dst, src);
dst->type = EnumValue(src->SubType);
dst->creationTick = src->creationTick;
}
void S6Exporter::ExportEntities()
{
// Clear everything to free
for (int32_t i = 0; i < RCT2_MAX_SPRITES; i++)
{
auto& entity = _s6.sprites[i];
std::memset(&entity, 0, sizeof(entity));
entity.unknown.sprite_identifier = SpriteIdentifier::Null;
entity.unknown.sprite_index = i;
entity.unknown.linked_list_type_offset = RCT12EntityLinkListOffset::Free;
}
for (auto* entity : EntityList<Guest>(EntityListId::Peep))
{
ExportEntity(&_s6.sprites[entity->sprite_index].peep, entity);
}
for (auto* entity : EntityList<Staff>(EntityListId::Peep))
{
ExportEntity(&_s6.sprites[entity->sprite_index].peep, entity);
}
for (auto* entity : EntityList<Vehicle>(EntityListId::Vehicle))
{
ExportEntity(&_s6.sprites[entity->sprite_index].vehicle, entity);
}
for (auto* entity : EntityList<Vehicle>(EntityListId::TrainHead))
{
ExportEntity(&_s6.sprites[entity->sprite_index].vehicle, entity);
}
for (auto* entity : EntityList<Litter>(EntityListId::Litter))
{
ExportEntity(&_s6.sprites[entity->sprite_index].litter, entity);
}
for (auto* entity : EntityList<Duck>(EntityListId::Misc))
{
ExportEntity(&_s6.sprites[entity->sprite_index].duck, entity);
}
for (auto* entity : EntityList<SteamParticle>(EntityListId::Misc))
{
ExportEntity(&_s6.sprites[entity->sprite_index].steam_particle, entity);
}
for (auto* entity : EntityList<MoneyEffect>(EntityListId::Misc))
{
ExportEntity(&_s6.sprites[entity->sprite_index].money_effect, entity);
}
for (auto* entity : EntityList<VehicleCrashParticle>(EntityListId::Misc))
{
ExportEntity(&_s6.sprites[entity->sprite_index].crashed_vehicle_particle, entity);
}
for (auto* entity : EntityList<JumpingFountain>(EntityListId::Misc))
{
ExportEntity(&_s6.sprites[entity->sprite_index].jumping_fountain, entity);
}
for (auto* entity : EntityList<Balloon>(EntityListId::Misc))
{
ExportEntity(&_s6.sprites[entity->sprite_index].balloon, entity);
}
for (auto* entity : EntityList<ExplosionCloud>(EntityListId::Misc))
{
ExportEntity(&_s6.sprites[entity->sprite_index].misc_particle, entity);
}
for (auto* entity : EntityList<ExplosionFlare>(EntityListId::Misc))
{
ExportEntity(&_s6.sprites[entity->sprite_index].misc_particle, entity);
}
for (auto* entity : EntityList<CrashSplashParticle>(EntityListId::Misc))
{
ExportEntity(&_s6.sprites[entity->sprite_index].misc_particle, entity);
}
RebuildEntityLinks();
}
void S6Exporter::ExportBanners()
{
for (BannerIndex i = 0; i < RCT2_MAX_BANNERS_IN_PARK; i++)

View File

@ -48,13 +48,10 @@ public:
void ExportParkName();
void ExportRides();
void ExportRide(rct2_ride* dst, const Ride* src);
void ExportSprites();
void ExportSprite(RCT2Sprite* dst, const rct_sprite* src);
void ExportSpriteCommonProperties(RCT12SpriteBase* dst, const SpriteBase* src);
void ExportSpriteVehicle(RCT2SpriteVehicle* dst, const Vehicle* src);
void ExportSpritePeep(RCT2SpritePeep* dst, const Peep* src);
void ExportSpriteMisc(RCT12SpriteBase* dst, const MiscEntity* src);
void ExportSpriteLitter(RCT12SpriteLitter* dst, const Litter* src);
void ExportEntities();
template<typename RCT12_T, typename OpenRCT2_T> void ExportEntity(RCT12_T* dst, const OpenRCT2_T* src);
void ExportEntityCommonProperties(RCT12SpriteBase* dst, const SpriteBase* src);
void ExportEntityPeep(RCT2SpritePeep* dst, const Peep* src);
private:
rct_s6_data _s6{};