Rework how entity export works to allow for easier changes in future

This commit is contained in:
duncanspumpkin 2021-02-21 12:39:52 +00:00
parent 3f8386e122
commit b9173642ba
2 changed files with 244 additions and 206 deletions

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();
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<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;
@ -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<RCT2SpriteVehicle*>(dst);
const auto* ride = src->GetRide();
ExportSpriteCommonProperties(dst, static_cast<const SpriteBase*>(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<uint8_t>(src->BoatLocation.x / COORDS_XY_STEP),
static_cast<uint8_t>(src->BoatLocation.y / COORDS_XY_STEP) };
cdst->boat_location = { static_cast<uint8_t>(src->BoatLocation.x / COORDS_XY_STEP),
static_cast<uint8_t>(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<uint8_t>(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<uint8_t>(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<uint8_t>(src->sound1_id);
dst->sound1_volume = src->sound1_volume;
dst->sound2_id = static_cast<uint8_t>(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<uint8_t>(src->scream_sound_id);
dst->TrackSubposition = static_cast<uint8_t>(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<uint8_t>(src->sound1_id);
cdst->sound1_volume = src->sound1_volume;
cdst->sound2_id = static_cast<uint8_t>(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<uint8_t>(src->scream_sound_id);
cdst->TrackSubposition = static_cast<uint8_t>(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<RCT2SpritePeep*>(dst), src);
}
template<> void S6Exporter::ExportEntity(RCT12SpriteBase* dst, const Staff* src)
{
ExportSpritePeep(static_cast<RCT2SpritePeep*>(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<uint32_t>(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<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;
}
auto* cdst = static_cast<RCT12SpriteSteamParticle*>(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<RCT12SpriteMoneyEffect*>(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<RCT12SpriteCrashedVehicleParticle*>(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<RCT12SpriteJumpingFountain*>(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<RCT12SpriteBalloon*>(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<RCT12SpriteDuck*>(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<RCT12SpriteParticle*>(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<RCT12SpriteParticle*>(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<RCT12SpriteParticle*>(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<RCT12SpriteLitter*>(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<Guest>(EntityListId::Peep))
{
ExportEntity<Guest>(&_s6.sprites[entity->sprite_index].unknown, entity);
}
for (auto* entity : EntityList<Staff>(EntityListId::Peep))
{
ExportEntity<Staff>(&_s6.sprites[entity->sprite_index].unknown, entity);
}
for (auto* entity : EntityList<Vehicle>(EntityListId::Vehicle))
{
ExportEntity<Vehicle>(&_s6.sprites[entity->sprite_index].unknown, entity);
}
for (auto* entity : EntityList<Vehicle>(EntityListId::TrainHead))
{
ExportEntity<Vehicle>(&_s6.sprites[entity->sprite_index].unknown, entity);
}
for (auto* entity : EntityList<Litter>(EntityListId::Litter))
{
ExportEntity<Litter>(&_s6.sprites[entity->sprite_index].unknown, entity);
}
for (auto* entity : EntityList<Duck>(EntityListId::Misc))
{
ExportEntity<Duck>(&_s6.sprites[entity->sprite_index].unknown, entity);
}
for (auto* entity : EntityList<SteamParticle>(EntityListId::Misc))
{
ExportEntity<SteamParticle>(&_s6.sprites[entity->sprite_index].unknown, entity);
}
for (auto* entity : EntityList<MoneyEffect>(EntityListId::Misc))
{
ExportEntity<MoneyEffect>(&_s6.sprites[entity->sprite_index].unknown, entity);
}
for (auto* entity : EntityList<VehicleCrashParticle>(EntityListId::Misc))
{
ExportEntity<VehicleCrashParticle>(&_s6.sprites[entity->sprite_index].unknown, entity);
}
for (auto* entity : EntityList<JumpingFountain>(EntityListId::Misc))
{
ExportEntity<JumpingFountain>(&_s6.sprites[entity->sprite_index].unknown, entity);
}
for (auto* entity : EntityList<Balloon>(EntityListId::Misc))
{
ExportEntity<Balloon>(&_s6.sprites[entity->sprite_index].unknown, entity);
}
for (auto* entity : EntityList<ExplosionCloud>(EntityListId::Misc))
{
ExportEntity<ExplosionCloud>(&_s6.sprites[entity->sprite_index].unknown, entity);
}
for (auto* entity : EntityList<ExplosionFlare>(EntityListId::Misc))
{
ExportEntity<ExplosionFlare>(&_s6.sprites[entity->sprite_index].unknown, entity);
}
for (auto* entity : EntityList<CrashSplashParticle>(EntityListId::Misc))
{
ExportEntity<CrashSplashParticle>(&_s6.sprites[entity->sprite_index].unknown, entity);
}
RebuildEntityLinks();
}
void S6Exporter::ExportBanners()

View File

@ -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<typename T> 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{};