From b9173642ba456283d1052e5c3bfbbc91fcfaf561 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sun, 21 Feb 2021 12:39:52 +0000 Subject: [PATCH] Rework how entity export works to allow for easier changes in future --- src/openrct2/rct2/S6Exporter.cpp | 443 +++++++++++++++++-------------- src/openrct2/rct2/S6Exporter.h | 7 +- 2 files changed, 244 insertions(+), 206 deletions(-) diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index ef672e6195..cb801a3be4 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -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(); + ExportEntitys(); 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(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; @@ -1082,92 +1040,102 @@ 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(RCT12SpriteBase* dst, const Vehicle* src) { + auto* cdst = static_cast(dst); const auto* ride = src->GetRide(); ExportSpriteCommonProperties(dst, static_cast(src)); - dst->type = EnumValue(src->SubType); - dst->vehicle_sprite_type = src->vehicle_sprite_type; - dst->bank_rotation = src->bank_rotation; - dst->remaining_distance = src->remaining_distance; - dst->velocity = src->velocity; - dst->acceleration = src->acceleration; - dst->ride = src->ride; - dst->vehicle_type = src->vehicle_type; - dst->colours = src->colours; - dst->track_progress = src->track_progress; + cdst->type = EnumValue(src->SubType); + cdst->vehicle_sprite_type = src->vehicle_sprite_type; + cdst->bank_rotation = src->bank_rotation; + cdst->remaining_distance = src->remaining_distance; + cdst->velocity = src->velocity; + cdst->acceleration = src->acceleration; + cdst->ride = src->ride; + cdst->vehicle_type = src->vehicle_type; + cdst->colours = src->colours; + cdst->track_progress = src->track_progress; if (ride != nullptr && ride->mode == RideMode::BoatHire && src->status == Vehicle::Status::TravellingBoat) { if (src->BoatLocation.isNull()) { - dst->boat_location.setNull(); + cdst->boat_location.setNull(); } else { - dst->boat_location = { static_cast(src->BoatLocation.x / COORDS_XY_STEP), - static_cast(src->BoatLocation.y / COORDS_XY_STEP) }; + cdst->boat_location = { static_cast(src->BoatLocation.x / COORDS_XY_STEP), + static_cast(src->BoatLocation.y / COORDS_XY_STEP) }; } } else { auto trackType = OpenRCT2TrackTypeToRCT2(src->GetTrackType()); // Track direction and type are in the same field - dst->SetTrackType(trackType); - dst->SetTrackDirection(src->GetTrackDirection()); + cdst->SetTrackType(trackType); + cdst->SetTrackDirection(src->GetTrackDirection()); } - dst->track_x = src->TrackLocation.x; - dst->track_y = src->TrackLocation.y; - dst->track_z = src->TrackLocation.z; - dst->next_vehicle_on_train = src->next_vehicle_on_train; - dst->prev_vehicle_on_ride = src->prev_vehicle_on_ride; - dst->next_vehicle_on_ride = src->next_vehicle_on_ride; - dst->var_44 = src->var_44; - dst->mass = src->mass; - dst->update_flags = src->update_flags; - dst->SwingSprite = src->SwingSprite; - dst->current_station = src->current_station; - dst->current_time = src->current_time; - dst->crash_z = src->crash_z; - dst->status = static_cast(src->status); - dst->sub_state = src->sub_state; + cdst->track_x = src->TrackLocation.x; + cdst->track_y = src->TrackLocation.y; + cdst->track_z = src->TrackLocation.z; + cdst->next_vehicle_on_train = src->next_vehicle_on_train; + cdst->prev_vehicle_on_ride = src->prev_vehicle_on_ride; + cdst->next_vehicle_on_ride = src->next_vehicle_on_ride; + cdst->var_44 = src->var_44; + cdst->mass = src->mass; + cdst->update_flags = src->update_flags; + cdst->SwingSprite = src->SwingSprite; + cdst->current_station = src->current_station; + cdst->current_time = src->current_time; + cdst->crash_z = src->crash_z; + cdst->status = static_cast(src->status); + cdst->sub_state = src->sub_state; for (size_t i = 0; i < std::size(src->peep); i++) { - dst->peep[i] = src->peep[i]; - dst->peep_tshirt_colours[i] = src->peep_tshirt_colours[i]; + cdst->peep[i] = src->peep[i]; + cdst->peep_tshirt_colours[i] = src->peep_tshirt_colours[i]; } - dst->num_seats = src->num_seats; - dst->num_peeps = src->num_peeps; - dst->next_free_seat = src->next_free_seat; - dst->restraints_position = src->restraints_position; - dst->crash_x = src->crash_x; - dst->sound2_flags = src->sound2_flags; - dst->spin_sprite = src->spin_sprite; - dst->sound1_id = static_cast(src->sound1_id); - dst->sound1_volume = src->sound1_volume; - dst->sound2_id = static_cast(src->sound2_id); - dst->sound2_volume = src->sound2_volume; - dst->sound_vector_factor = src->sound_vector_factor; - dst->time_waiting = src->time_waiting; - dst->speed = src->speed; - dst->powered_acceleration = src->powered_acceleration; - dst->dodgems_collision_direction = src->dodgems_collision_direction; - dst->animation_frame = src->animation_frame; - dst->var_C8 = src->var_C8; - dst->var_CA = src->var_CA; - dst->scream_sound_id = static_cast(src->scream_sound_id); - dst->TrackSubposition = static_cast(src->TrackSubposition); - dst->var_CE = src->var_CE; - dst->var_CF = src->var_CF; - dst->lost_time_out = src->lost_time_out; - dst->vertical_drop_countdown = src->vertical_drop_countdown; - dst->var_D3 = src->var_D3; - dst->mini_golf_current_animation = src->mini_golf_current_animation; - dst->mini_golf_flags = src->mini_golf_flags; - dst->ride_subtype = OpenRCT2EntryIndexToRCTEntryIndex(src->ride_subtype); - dst->colours_extended = src->colours_extended; - dst->seat_rotation = src->seat_rotation; - dst->target_seat_rotation = src->target_seat_rotation; + cdst->num_seats = src->num_seats; + cdst->num_peeps = src->num_peeps; + cdst->next_free_seat = src->next_free_seat; + cdst->restraints_position = src->restraints_position; + cdst->crash_x = src->crash_x; + cdst->sound2_flags = src->sound2_flags; + cdst->spin_sprite = src->spin_sprite; + cdst->sound1_id = static_cast(src->sound1_id); + cdst->sound1_volume = src->sound1_volume; + cdst->sound2_id = static_cast(src->sound2_id); + cdst->sound2_volume = src->sound2_volume; + cdst->sound_vector_factor = src->sound_vector_factor; + cdst->time_waiting = src->time_waiting; + cdst->speed = src->speed; + cdst->powered_acceleration = src->powered_acceleration; + cdst->dodgems_collision_direction = src->dodgems_collision_direction; + cdst->animation_frame = src->animation_frame; + cdst->var_C8 = src->var_C8; + cdst->var_CA = src->var_CA; + cdst->scream_sound_id = static_cast(src->scream_sound_id); + cdst->TrackSubposition = static_cast(src->TrackSubposition); + cdst->var_CE = src->var_CE; + cdst->var_CF = src->var_CF; + cdst->lost_time_out = src->lost_time_out; + cdst->vertical_drop_countdown = src->vertical_drop_countdown; + cdst->var_D3 = src->var_D3; + cdst->mini_golf_current_animation = src->mini_golf_current_animation; + cdst->mini_golf_flags = src->mini_golf_flags; + cdst->ride_subtype = OpenRCT2EntryIndexToRCTEntryIndex(src->ride_subtype); + cdst->colours_extended = src->colours_extended; + cdst->seat_rotation = src->seat_rotation; + cdst->target_seat_rotation = src->target_seat_rotation; +} + +template<> void S6Exporter::ExportEntity(RCT12SpriteBase* dst, const Guest* src) +{ + ExportSpritePeep(static_cast(dst), src); +} +template<> void S6Exporter::ExportEntity(RCT12SpriteBase* dst, const Staff* src) +{ + ExportSpritePeep(static_cast(dst), src); } void S6Exporter::ExportSpritePeep(RCT2SpritePeep* dst, const Peep* src) @@ -1322,104 +1290,177 @@ void S6Exporter::ExportSpritePeep(RCT2SpritePeep* dst, const Peep* src) dst->item_standard_flags = static_cast(src->GetItemFlags()); } -void S6Exporter::ExportSpriteMisc(RCT12SpriteBase* cdst, const MiscEntity* csrc) +template<> void S6Exporter::ExportEntity(RCT12SpriteBase* dst, const SteamParticle* src) { - ExportSpriteCommonProperties(cdst, csrc); - cdst->type = EnumValue(csrc->SubType); - switch (csrc->SubType) - { - case MiscEntityType::SteamParticle: - { - auto src = static_cast(csrc); - auto dst = static_cast(cdst); - dst->time_to_move = src->time_to_move; - dst->frame = src->frame; - break; - } - case MiscEntityType::MoneyEffect: - { - auto src = static_cast(csrc); - auto dst = static_cast(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(csrc); - auto dst = static_cast(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(csrc); - auto dst = static_cast(cdst); - dst->frame = src->frame; - break; - } - case MiscEntityType::JumpingFountainWater: - case MiscEntityType::JumpingFountainSnow: - { - auto* src = static_cast(csrc); - auto* dst = static_cast(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(csrc); - auto dst = static_cast(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(csrc); - auto dst = static_cast(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; - } + auto* cdst = static_cast(dst); + ExportSpriteCommonProperties(dst, src); + cdst->type = EnumValue(src->SubType); + cdst->time_to_move = src->time_to_move; + cdst->frame = src->frame; +} +template<> void S6Exporter::ExportEntity(RCT12SpriteBase* dst, const MoneyEffect* src) +{ + auto* cdst = static_cast(dst); + ExportSpriteCommonProperties(dst, src); + cdst->type = EnumValue(src->SubType); + cdst->move_delay = src->MoveDelay; + cdst->num_movements = src->NumMovements; + cdst->vertical = src->Vertical; + cdst->value = src->Value; + cdst->offset_x = src->OffsetX; + cdst->wiggle = src->Wiggle; +} +template<> void S6Exporter::ExportEntity(RCT12SpriteBase* dst, const VehicleCrashParticle* src) +{ + auto* cdst = static_cast(dst); + ExportSpriteCommonProperties(dst, src); + cdst->type = EnumValue(src->SubType); + cdst->frame = src->frame; + cdst->time_to_live = src->time_to_live; + cdst->frame = src->frame; + cdst->colour[0] = src->colour[0]; + cdst->colour[1] = src->colour[1]; + cdst->crashed_sprite_base = src->crashed_sprite_base; + cdst->velocity_x = src->velocity_x; + cdst->velocity_y = src->velocity_y; + cdst->velocity_z = src->velocity_z; + cdst->acceleration_x = src->acceleration_x; + cdst->acceleration_y = src->acceleration_y; + cdst->acceleration_z = src->acceleration_z; +} +template<> void S6Exporter::ExportEntity(RCT12SpriteBase* dst, const JumpingFountain* src) +{ + auto* cdst = static_cast(dst); + ExportSpriteCommonProperties(dst, src); + cdst->type = EnumValue(src->SubType); + cdst->num_ticks_alive = src->NumTicksAlive; + cdst->frame = src->frame; + cdst->fountain_flags = src->FountainFlags; + cdst->target_x = src->TargetX; + cdst->target_y = src->TargetY; + cdst->target_y = src->TargetY; + cdst->iteration = src->Iteration; +} +template<> void S6Exporter::ExportEntity(RCT12SpriteBase* dst, const Balloon* src) +{ + auto* cdst = static_cast(dst); + ExportSpriteCommonProperties(dst, src); + cdst->type = EnumValue(src->SubType); + cdst->popped = src->popped; + cdst->time_to_move = src->time_to_move; + cdst->frame = src->frame; + cdst->colour = src->colour; +} +template<> void S6Exporter::ExportEntity(RCT12SpriteBase* dst, const Duck* src) +{ + auto* cdst = static_cast(dst); + ExportSpriteCommonProperties(dst, src); + cdst->type = EnumValue(src->SubType); + cdst->frame = src->frame; + cdst->target_x = src->target_x; + cdst->target_y = src->target_y; + cdst->state = EnumValue(src->state); +} +template<> void S6Exporter::ExportEntity(RCT12SpriteBase* dst, const ExplosionCloud* src) +{ + auto* cdst = static_cast(dst); + ExportSpriteCommonProperties(dst, src); + cdst->type = EnumValue(src->SubType); + cdst->frame = src->frame; +} +template<> void S6Exporter::ExportEntity(RCT12SpriteBase* dst, const ExplosionFlare* src) +{ + auto* cdst = static_cast(dst); + ExportSpriteCommonProperties(dst, src); + cdst->type = EnumValue(src->SubType); + cdst->frame = src->frame; +} +template<> void S6Exporter::ExportEntity(RCT12SpriteBase* dst, const CrashSplashParticle* src) +{ + auto* cdst = static_cast(dst); + ExportSpriteCommonProperties(dst, src); + cdst->type = EnumValue(src->SubType); + cdst->frame = src->frame; } -void S6Exporter::ExportSpriteLitter(RCT12SpriteLitter* dst, const Litter* src) +template<> void S6Exporter::ExportEntity(RCT12SpriteBase* dst, const Litter* src) { + auto* cdst = static_cast(dst); ExportSpriteCommonProperties(dst, src); - dst->type = EnumValue(src->SubType); - dst->creationTick = src->creationTick; + cdst->type = EnumValue(src->SubType); + cdst->creationTick = src->creationTick; +} + +void S6Exporter::ExportEntitys() +{ + // 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(EntityListId::Peep)) + { + ExportEntity(&_s6.sprites[entity->sprite_index].unknown, entity); + } + for (auto* entity : EntityList(EntityListId::Peep)) + { + ExportEntity(&_s6.sprites[entity->sprite_index].unknown, entity); + } + for (auto* entity : EntityList(EntityListId::Vehicle)) + { + ExportEntity(&_s6.sprites[entity->sprite_index].unknown, entity); + } + for (auto* entity : EntityList(EntityListId::TrainHead)) + { + ExportEntity(&_s6.sprites[entity->sprite_index].unknown, entity); + } + for (auto* entity : EntityList(EntityListId::Litter)) + { + ExportEntity(&_s6.sprites[entity->sprite_index].unknown, entity); + } + for (auto* entity : EntityList(EntityListId::Misc)) + { + ExportEntity(&_s6.sprites[entity->sprite_index].unknown, entity); + } + for (auto* entity : EntityList(EntityListId::Misc)) + { + ExportEntity(&_s6.sprites[entity->sprite_index].unknown, entity); + } + for (auto* entity : EntityList(EntityListId::Misc)) + { + ExportEntity(&_s6.sprites[entity->sprite_index].unknown, entity); + } + for (auto* entity : EntityList(EntityListId::Misc)) + { + ExportEntity(&_s6.sprites[entity->sprite_index].unknown, entity); + } + for (auto* entity : EntityList(EntityListId::Misc)) + { + ExportEntity(&_s6.sprites[entity->sprite_index].unknown, entity); + } + for (auto* entity : EntityList(EntityListId::Misc)) + { + ExportEntity(&_s6.sprites[entity->sprite_index].unknown, entity); + } + for (auto* entity : EntityList(EntityListId::Misc)) + { + ExportEntity(&_s6.sprites[entity->sprite_index].unknown, entity); + } + for (auto* entity : EntityList(EntityListId::Misc)) + { + ExportEntity(&_s6.sprites[entity->sprite_index].unknown, entity); + } + for (auto* entity : EntityList(EntityListId::Misc)) + { + ExportEntity(&_s6.sprites[entity->sprite_index].unknown, entity); + } + + RebuildEntityLinks(); } void S6Exporter::ExportBanners() diff --git a/src/openrct2/rct2/S6Exporter.h b/src/openrct2/rct2/S6Exporter.h index fc1d2e0155..16dd711d21 100644 --- a/src/openrct2/rct2/S6Exporter.h +++ b/src/openrct2/rct2/S6Exporter.h @@ -46,13 +46,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 ExportEntitys(); + template void ExportEntity(RCT12SpriteBase* dst, const T* 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); private: rct_s6_data _s6{};