From 129ef12d6dee10354176b3768c5aa340867399b9 Mon Sep 17 00:00:00 2001 From: Duncan Date: Wed, 17 Mar 2021 08:35:39 +0000 Subject: [PATCH] Refactor paint entity (#14342) --- src/openrct2/paint/sprite/Paint.Litter.cpp | 2 +- src/openrct2/paint/sprite/Paint.Misc.cpp | 260 ++++++++++----------- src/openrct2/paint/sprite/Paint.Peep.cpp | 2 +- src/openrct2/paint/sprite/Paint.Sprite.cpp | 25 +- src/openrct2/paint/sprite/Paint.Sprite.h | 7 +- src/openrct2/ride/VehiclePaint.cpp | 3 +- src/openrct2/ride/VehiclePaint.h | 2 - src/openrct2/ride/water/SplashBoats.cpp | 3 +- 8 files changed, 144 insertions(+), 160 deletions(-) diff --git a/src/openrct2/paint/sprite/Paint.Litter.cpp b/src/openrct2/paint/sprite/Paint.Litter.cpp index 17a4218499..d1baf68e6d 100644 --- a/src/openrct2/paint/sprite/Paint.Litter.cpp +++ b/src/openrct2/paint/sprite/Paint.Litter.cpp @@ -65,7 +65,7 @@ static constexpr const litter_sprite litter_sprites[] = { * Litter Paint Setup * rct2: 0x006736FC */ -void litter_paint(paint_session* session, const Litter* litter, int32_t imageDirection) +template<> void PaintEntity(paint_session* session, const Litter* litter, int32_t imageDirection) { rct_drawpixelinfo* dpi; diff --git a/src/openrct2/paint/sprite/Paint.Misc.cpp b/src/openrct2/paint/sprite/Paint.Misc.cpp index 8f2c51e805..07e676671b 100644 --- a/src/openrct2/paint/sprite/Paint.Misc.cpp +++ b/src/openrct2/paint/sprite/Paint.Misc.cpp @@ -26,154 +26,128 @@ const uint32_t vehicle_particle_base_sprites[] = { 22577, 22589, 22601, 22613, 22625, }; -/** - * rct2: 0x00672AC9 - */ -void misc_paint(paint_session* session, const MiscEntity* misc, int32_t imageDirection) +template<> void PaintEntity(paint_session* session, const SteamParticle* particle, int32_t imageDirection) +{ + uint32_t imageId = 22637 + (particle->frame / 256); + PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, particle->z); +} + +template<> void PaintEntity(paint_session* session, const MoneyEffect* moneyEffect, int32_t imageDirection) { rct_drawpixelinfo* dpi = &session->DPI; - switch (misc->SubType) + if (dpi->zoom_level > 0) { - case MiscEntityType::SteamParticle: // 0 + return; + } + if (moneyEffect == nullptr) + return; + auto [stringId, value] = moneyEffect->GetStringId(); + PaintFloatingMoneyEffect( + session, value, stringId, moneyEffect->y, moneyEffect->z, const_cast(&money_wave[moneyEffect->Wiggle % 22]), + moneyEffect->OffsetX, session->CurrentRotation); +} + +template<> void PaintEntity(paint_session* session, const VehicleCrashParticle* particle, int32_t imageDirection) +{ + rct_drawpixelinfo* dpi = &session->DPI; + if (dpi->zoom_level > 0) + { + return; + } + + if (particle == nullptr) + return; + uint32_t imageId = vehicle_particle_base_sprites[particle->crashed_sprite_base] + particle->frame / 256; + imageId = imageId | (particle->colour[0] << 19) | (particle->colour[1] << 24) | IMAGE_TYPE_REMAP | IMAGE_TYPE_REMAP_2_PLUS; + PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, particle->z); +} + +template<> void PaintEntity(paint_session* session, const ExplosionCloud* particle, int32_t imageDirection) +{ + if (particle == nullptr) + return; + uint32_t imageId = 22878 + (particle->frame / 256); + PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, particle->z); +} + +template<> void PaintEntity(paint_session* session, const CrashSplashParticle* crashSplash, int32_t imageDirection) +{ + if (crashSplash == nullptr) + return; + uint32_t imageId = 22927 + (crashSplash->frame / 256); + PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, crashSplash->z); +} + +template<> void PaintEntity(paint_session* session, const ExplosionFlare* flare, int32_t imageDirection) +{ + // Like a flare + if (flare == nullptr) + return; + uint32_t imageId = 22896 + (flare->frame / 256); + PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, flare->z); +} + +template<> void PaintEntity(paint_session* session, const JumpingFountain* jumpingFountain, int32_t imageDirection) +{ + rct_drawpixelinfo* dpi = &session->DPI; + if (dpi->zoom_level > 0) + { + return; + } + + if (jumpingFountain == nullptr) + return; + uint16_t height = jumpingFountain->z + 6; + int32_t ebx = imageDirection / 8; + + // Fountain is firing anti clockwise + bool reversed = (jumpingFountain->FountainFlags & FOUNTAIN_FLAG::DIRECTION); + // Fountain rotation + bool rotated = (jumpingFountain->sprite_direction / 16) & 1; + bool isAntiClockwise = (ebx / 2) & 1; // Clockwise or Anti-clockwise + + // These cancel each other out + if (reversed != rotated) + { + isAntiClockwise = !isAntiClockwise; + } + + uint32_t baseImageId = (jumpingFountain->SubType == MiscEntityType::JumpingFountainSnow) ? 23037 : 22973; + uint32_t imageId = baseImageId + ebx * 16 + jumpingFountain->frame; + constexpr std::array antiClockWiseBoundingBoxes = { CoordsXY{ -COORDS_XY_STEP, -3 }, CoordsXY{ 0, -3 } }; + constexpr std::array clockWiseBoundingBoxes = { CoordsXY{ -COORDS_XY_STEP, 3 }, CoordsXY{ 0, 3 } }; + + auto bb = isAntiClockwise ? antiClockWiseBoundingBoxes : clockWiseBoundingBoxes; + + PaintAddImageAsParentRotated(session, ebx, imageId, 0, 0, 32, 1, 3, height, bb[ebx & 1].x, bb[ebx & 1].y, height); +} + +template<> void PaintEntity(paint_session* session, const Balloon* balloon, int32_t imageDirection) +{ + if (balloon == nullptr) + return; + uint32_t imageId = 22651 + (balloon->frame & 7); + if (balloon->popped != 0) + { + imageId += 8; + } + + imageId = imageId | (balloon->colour << 19) | IMAGE_TYPE_REMAP; + PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, balloon->z); +} + +template<> void PaintEntity(paint_session* session, const Duck* duck, int32_t imageDirection) +{ + rct_drawpixelinfo* dpi = &session->DPI; + if (dpi->zoom_level <= 1) + { + if (duck == nullptr) + return; + uint32_t imageId = duck->GetFrameImage(imageDirection); + if (imageId != 0) { - auto particle = misc->As(); - if (particle == nullptr) - return; - uint32_t imageId = 22637 + (particle->frame / 256); - PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, particle->z); - break; + PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, duck->z); } - - case MiscEntityType::MoneyEffect: // 1 - { - if (dpi->zoom_level > 0) - { - return; - } - auto moneyEffect = misc->As(); - if (moneyEffect == nullptr) - return; - auto [stringId, value] = moneyEffect->GetStringId(); - PaintFloatingMoneyEffect( - session, value, stringId, moneyEffect->y, moneyEffect->z, - const_cast(&money_wave[moneyEffect->Wiggle % 22]), moneyEffect->OffsetX, session->CurrentRotation); - break; - } - - case MiscEntityType::CrashedVehicleParticle: // 2 - { - if (dpi->zoom_level > 0) - { - return; - } - auto particle = misc->As(); - if (particle == nullptr) - return; - uint32_t imageId = vehicle_particle_base_sprites[particle->crashed_sprite_base] + particle->frame / 256; - imageId = imageId | (particle->colour[0] << 19) | (particle->colour[1] << 24) | IMAGE_TYPE_REMAP - | IMAGE_TYPE_REMAP_2_PLUS; - PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, particle->z); - break; - } - - case MiscEntityType::ExplosionCloud: // 3 - { - auto particle = misc->As(); - if (particle == nullptr) - return; - uint32_t imageId = 22878 + (particle->frame / 256); - PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, particle->z); - break; - } - - case MiscEntityType::CrashSplash: // 4 - { - auto crashSplash = misc->As(); - if (crashSplash == nullptr) - return; - uint32_t imageId = 22927 + (crashSplash->frame / 256); - PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, crashSplash->z); - break; - } - - case MiscEntityType::ExplosionFlare: // 5 - { - // Like a flare - auto flare = misc->As(); - if (flare == nullptr) - return; - uint32_t imageId = 22896 + (flare->frame / 256); - PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, flare->z); - break; - } - - case MiscEntityType::JumpingFountainWater: // 6 - case MiscEntityType::JumpingFountainSnow: // 9 - { - if (dpi->zoom_level > 0) - { - return; - } - - auto jumpingFountain = misc->As(); - if (jumpingFountain == nullptr) - return; - uint16_t height = jumpingFountain->z + 6; - int32_t ebx = imageDirection / 8; - - // Fountain is firing anti clockwise - bool reversed = (jumpingFountain->FountainFlags & FOUNTAIN_FLAG::DIRECTION); - // Fountain rotation - bool rotated = (jumpingFountain->sprite_direction / 16) & 1; - bool isAntiClockwise = (ebx / 2) & 1; // Clockwise or Anti-clockwise - - // These cancel each other out - if (reversed != rotated) - { - isAntiClockwise = !isAntiClockwise; - } - - uint32_t baseImageId = (jumpingFountain->SubType == MiscEntityType::JumpingFountainSnow) ? 23037 : 22973; - uint32_t imageId = baseImageId + ebx * 16 + jumpingFountain->frame; - constexpr std::array antiClockWiseBoundingBoxes = { CoordsXY{ -COORDS_XY_STEP, -3 }, - CoordsXY{ 0, -3 } }; - constexpr std::array clockWiseBoundingBoxes = { CoordsXY{ -COORDS_XY_STEP, 3 }, CoordsXY{ 0, 3 } }; - - auto bb = isAntiClockwise ? antiClockWiseBoundingBoxes : clockWiseBoundingBoxes; - - PaintAddImageAsParentRotated(session, ebx, imageId, 0, 0, 32, 1, 3, height, bb[ebx & 1].x, bb[ebx & 1].y, height); - break; - } - - case MiscEntityType::Balloon: // 7 - { - auto balloon = misc->As(); - if (balloon == nullptr) - return; - uint32_t imageId = 22651 + (balloon->frame & 7); - if (balloon->popped != 0) - { - imageId += 8; - } - - imageId = imageId | (balloon->colour << 19) | IMAGE_TYPE_REMAP; - PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, balloon->z); - break; - } - - case MiscEntityType::Duck: - if (dpi->zoom_level <= 1) - { - const Duck* duck = misc->As(); - if (duck == nullptr) - return; - uint32_t imageId = duck->GetFrameImage(imageDirection); - if (imageId != 0) - { - PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, duck->z); - } - } - break; } } diff --git a/src/openrct2/paint/sprite/Paint.Peep.cpp b/src/openrct2/paint/sprite/Paint.Peep.cpp index 93b268ed17..2c87eaaade 100644 --- a/src/openrct2/paint/sprite/Paint.Peep.cpp +++ b/src/openrct2/paint/sprite/Paint.Peep.cpp @@ -19,7 +19,7 @@ * * rct2: 0x0068F0FB */ -void peep_paint(paint_session* session, const Peep* peep, int32_t imageDirection) +template<> void PaintEntity(paint_session* session, const Peep* peep, int32_t imageDirection) { #ifdef __ENABLE_LIGHTFX__ if (lightfx_is_available()) diff --git a/src/openrct2/paint/sprite/Paint.Sprite.cpp b/src/openrct2/paint/sprite/Paint.Sprite.cpp index c3a4f41201..f0d2af6e07 100644 --- a/src/openrct2/paint/sprite/Paint.Sprite.cpp +++ b/src/openrct2/paint/sprite/Paint.Sprite.cpp @@ -103,7 +103,7 @@ void sprite_paint_setup(paint_session* session, const uint16_t x, const uint16_t switch (spr->Type) { case EntityType::Vehicle: - vehicle_paint(session, spr->As(), image_direction); + PaintEntity(session, spr->As(), image_direction); #ifdef __ENABLE_LIGHTFX__ if (lightfx_for_vehicles_is_available()) { @@ -113,22 +113,37 @@ void sprite_paint_setup(paint_session* session, const uint16_t x, const uint16_t break; case EntityType::Guest: case EntityType::Staff: - peep_paint(session, spr->As(), image_direction); + PaintEntity(session, spr->As(), image_direction); break; case EntityType::SteamParticle: + PaintEntity(session, spr->As(), image_direction); + break; case EntityType::MoneyEffect: + PaintEntity(session, spr->As(), image_direction); + break; case EntityType::CrashedVehicleParticle: + PaintEntity(session, spr->As(), image_direction); + break; case EntityType::ExplosionCloud: + PaintEntity(session, spr->As(), image_direction); + break; case EntityType::CrashSplash: + PaintEntity(session, spr->As(), image_direction); + break; case EntityType::ExplosionFlare: + PaintEntity(session, spr->As(), image_direction); + break; case EntityType::JumpingFountain: + PaintEntity(session, spr->As(), image_direction); + break; case EntityType::Balloon: + PaintEntity(session, spr->As(), image_direction); + break; case EntityType::Duck: - // TODO: Update misc_paint to take a specific sprite type - misc_paint(session, spr->As(), image_direction); + PaintEntity(session, spr->As(), image_direction); break; case EntityType::Litter: - litter_paint(session, spr->As(), image_direction); + PaintEntity(session, spr->As(), image_direction); break; default: assert(false); diff --git a/src/openrct2/paint/sprite/Paint.Sprite.h b/src/openrct2/paint/sprite/Paint.Sprite.h index c69b31b8ef..1c038aa53a 100644 --- a/src/openrct2/paint/sprite/Paint.Sprite.h +++ b/src/openrct2/paint/sprite/Paint.Sprite.h @@ -13,15 +13,10 @@ #include "../../common.h" struct paint_session; -struct Litter; -struct MiscEntity; -struct Peep; void sprite_paint_setup(paint_session* session, const uint16_t x, const uint16_t y); -void misc_paint(paint_session* session, const MiscEntity* misc, int32_t imageDirection); -void litter_paint(paint_session* session, const Litter* litter, int32_t imageDirection); -void peep_paint(paint_session* session, const Peep* peep, int32_t imageDirection); +template void PaintEntity(paint_session* session, const T* entity, int32_t imageDirection); extern const uint32_t vehicle_particle_base_sprites[5]; diff --git a/src/openrct2/ride/VehiclePaint.cpp b/src/openrct2/ride/VehiclePaint.cpp index 0fb8460eb1..d7a1d4b05c 100644 --- a/src/openrct2/ride/VehiclePaint.cpp +++ b/src/openrct2/ride/VehiclePaint.cpp @@ -14,6 +14,7 @@ #include "../drawing/LightFX.h" #include "../interface/Viewport.h" #include "../paint/Paint.h" +#include "../paint/sprite/Paint.Sprite.h" #include "../ride/RideData.h" #include "../world/Sprite.h" #include "Track.h" @@ -3131,7 +3132,7 @@ void vehicle_visual_default( * * rct2: 0x006D4244 */ -void vehicle_paint(paint_session* session, const Vehicle* vehicle, int32_t imageDirection) +template<> void PaintEntity(paint_session* session, const Vehicle* vehicle, int32_t imageDirection) { const rct_ride_entry_vehicle* vehicleEntry; diff --git a/src/openrct2/ride/VehiclePaint.h b/src/openrct2/ride/VehiclePaint.h index 91fadaa035..5bbe90dc61 100644 --- a/src/openrct2/ride/VehiclePaint.h +++ b/src/openrct2/ride/VehiclePaint.h @@ -28,8 +28,6 @@ struct vehicle_boundbox extern const vehicle_boundbox VehicleBoundboxes[16][224]; -void vehicle_paint(paint_session* session, const Vehicle* vehicle, int32_t imageDirection); - void vehicle_visual_default( paint_session* session, int32_t imageDirection, int32_t z, const Vehicle* vehicle, const rct_ride_entry_vehicle* vehicleEntry); diff --git a/src/openrct2/ride/water/SplashBoats.cpp b/src/openrct2/ride/water/SplashBoats.cpp index 935449548d..5df1975729 100644 --- a/src/openrct2/ride/water/SplashBoats.cpp +++ b/src/openrct2/ride/water/SplashBoats.cpp @@ -11,6 +11,7 @@ #include "../../interface/Viewport.h" #include "../../paint/Paint.h" #include "../../paint/Supports.h" +#include "../../paint/sprite/Paint.Sprite.h" #include "../../world/Sprite.h" #include "../Track.h" #include "../TrackPaint.h" @@ -1269,6 +1270,6 @@ void vehicle_visual_splash_boats_or_water_coaster( imageDirection = ((session->CurrentRotation * 8) + vehicle->sprite_direction) & 0x1F; session->SpritePosition.x = vehicle->x; session->SpritePosition.y = vehicle->y; - vehicle_paint(session, vehicle, imageDirection); + PaintEntity(session, vehicle, imageDirection); } #endif