From 23d4032eed1d8bc81b58c69cb37c8f0bb304f6d7 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Mon, 30 Dec 2024 12:04:39 +0100 Subject: [PATCH] Move LightFX into its own namespace (#23506) --- .../engines/HardwareDisplayDrawingEngine.cpp | 4 +- .../engines/opengl/OpenGLDrawingEngine.cpp | 2 +- src/openrct2/Context.cpp | 2 +- src/openrct2/drawing/Drawing.cpp | 5 +- src/openrct2/drawing/LightFX.cpp | 1942 ++++++++--------- src/openrct2/drawing/LightFX.h | 97 +- src/openrct2/drawing/X8DrawingEngine.cpp | 6 +- src/openrct2/entity/Peep.cpp | 7 +- src/openrct2/paint/Paint.Entity.cpp | 6 +- .../paint/tile_element/Paint.Entrance.cpp | 19 +- .../paint/tile_element/Paint.PathAddition.cpp | 13 +- src/openrct2/ride/TrackPaint.cpp | 7 +- .../ride/rtd/coaster/MineTrainCoaster.h | 2 +- src/openrct2/ride/rtd/coaster/WaterCoaster.h | 2 +- src/openrct2/ride/rtd/gentle/CarRide.h | 2 +- src/openrct2/ride/rtd/gentle/Dodgems.h | 2 +- src/openrct2/ride/rtd/gentle/GhostTrain.h | 2 +- .../ride/rtd/gentle/MiniHelicopters.h | 2 +- src/openrct2/ride/rtd/gentle/MonorailCycles.h | 2 +- src/openrct2/ride/rtd/gentle/MonsterTrucks.h | 2 +- .../ride/rtd/gentle/ObservationTower.h | 2 +- src/openrct2/ride/rtd/thrill/GoKarts.h | 2 +- src/openrct2/ride/rtd/transport/Chairlift.h | 2 +- .../ride/rtd/transport/MiniatureRailway.h | 2 +- src/openrct2/ride/rtd/transport/Monorail.h | 2 +- src/openrct2/ride/rtd/water/BoatHire.h | 2 +- src/openrct2/ride/rtd/water/SplashBoats.h | 2 +- src/openrct2/ride/rtd/water/SubmarineRide.h | 2 +- 28 files changed, 1079 insertions(+), 1063 deletions(-) diff --git a/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp index fbfb3dc6ea..ad912b1331 100644 --- a/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp @@ -193,7 +193,7 @@ public: if (Config::Get().general.EnableLightFx) { - auto& lightPalette = LightFXGetPalette(); + auto& lightPalette = LightFx::GetPalette(); for (int32_t i = 0; i < 256; i++) { const auto& src = lightPalette[i]; @@ -238,7 +238,7 @@ private: int32_t pitch; if (SDL_LockTexture(_screenTexture, nullptr, &pixels, &pitch) == 0) { - LightFXRenderToTexture(pixels, pitch, _bits, _width, _height, _paletteHWMapped, _lightPaletteHWMapped); + LightFx::RenderToTexture(pixels, pitch, _bits, _width, _height, _paletteHWMapped, _lightPaletteHWMapped); SDL_UnlockTexture(_screenTexture); } } diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp index fcc7e7fa46..333d0f5d95 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -206,7 +206,7 @@ public: { _window = static_cast(_uiContext->GetWindow()); _bitsDPI.DrawingEngine = this; - LightFXSetAvailable(false); + LightFx::SetAvailable(false); } ~OpenGLDrawingEngine() override diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 4484a78096..fbad4d5851 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -521,7 +521,7 @@ namespace OpenRCT2 { return false; } - LightFXInit(); + Drawing::LightFx::Init(); } ViewportInitAll(); diff --git a/src/openrct2/drawing/Drawing.cpp b/src/openrct2/drawing/Drawing.cpp index 11771eab9f..3acefccdab 100644 --- a/src/openrct2/drawing/Drawing.cpp +++ b/src/openrct2/drawing/Drawing.cpp @@ -32,6 +32,7 @@ #include using namespace OpenRCT2; +using namespace OpenRCT2::Drawing; static auto _defaultPaletteMapping = []() { std::array res; @@ -898,9 +899,9 @@ void UpdatePalette(std::span palette, int3 uint8_t g = colour.Green; uint8_t r = colour.Red; - if (LightFXIsAvailable()) + if (LightFx::IsAvailable()) { - LightFXApplyPaletteFilter(i, &r, &g, &b); + LightFx::ApplyPaletteFilter(i, &r, &g, &b); } else { diff --git a/src/openrct2/drawing/LightFX.cpp b/src/openrct2/drawing/LightFX.cpp index b8689cca36..5d345abee4 100644 --- a/src/openrct2/drawing/LightFX.cpp +++ b/src/openrct2/drawing/LightFX.cpp @@ -29,1034 +29,1034 @@ #include #include -using namespace OpenRCT2; -using namespace OpenRCT2::Drawing; - -static uint8_t _bakedLightTexture_lantern_0[32 * 32]; -static uint8_t _bakedLightTexture_lantern_1[64 * 64]; -static uint8_t _bakedLightTexture_lantern_2[128 * 128]; -static uint8_t _bakedLightTexture_lantern_3[256 * 256]; -static uint8_t _bakedLightTexture_spot_0[32 * 32]; -static uint8_t _bakedLightTexture_spot_1[64 * 64]; -static uint8_t _bakedLightTexture_spot_2[128 * 128]; -static uint8_t _bakedLightTexture_spot_3[256 * 256]; -static DrawPixelInfo _pixelInfo; -static bool _lightfxAvailable = false; - -static void* _light_rendered_buffer_back = nullptr; -static void* _light_rendered_buffer_front = nullptr; - -static uint32_t _lightPolution_back = 0; -static uint32_t _lightPolution_front = 0; - -enum class LightFXQualifier : uint8_t +namespace OpenRCT2::Drawing::LightFx { - Entity, - Map, -}; + static uint8_t _bakedLightTexture_lantern_0[32 * 32]; + static uint8_t _bakedLightTexture_lantern_1[64 * 64]; + static uint8_t _bakedLightTexture_lantern_2[128 * 128]; + static uint8_t _bakedLightTexture_lantern_3[256 * 256]; + static uint8_t _bakedLightTexture_spot_0[32 * 32]; + static uint8_t _bakedLightTexture_spot_1[64 * 64]; + static uint8_t _bakedLightTexture_spot_2[128 * 128]; + static uint8_t _bakedLightTexture_spot_3[256 * 256]; + static DrawPixelInfo _pixelInfo; + static bool _lightfxAvailable = false; -struct LightListEntry -{ - CoordsXYZ Position; - ScreenCoordsXY ViewCoords; - LightType Type; - uint8_t LightIntensity; - uint32_t LightHash; - LightFXQualifier Qualifier; - uint8_t LightID; - uint8_t LightLinger; -}; + static void* _light_rendered_buffer_back = nullptr; + static void* _light_rendered_buffer_front = nullptr; -static LightListEntry _LightListA[16000]; -static LightListEntry _LightListB[16000]; + static uint32_t _lightPolution_back = 0; + static uint32_t _lightPolution_front = 0; -static LightListEntry* _LightListBack; -static LightListEntry* _LightListFront; - -static uint32_t LightListCurrentCountBack; -static uint32_t LightListCurrentCountFront; - -static int16_t _current_view_x_front = 0; -static int16_t _current_view_y_front = 0; -static uint8_t _current_view_rotation_front = 0; -static ZoomLevel _current_view_zoom_front{ 0 }; -static int16_t _current_view_x_back = 0; -static int16_t _current_view_y_back = 0; -static uint8_t _current_view_rotation_back = 0; -static ZoomLevel _current_view_zoom_back{ 0 }; -static ZoomLevel _current_view_zoom_back_delay{ 0 }; - -static GamePalette gPalette_light; - -static uint8_t CalcLightIntensityLantern(int32_t x, int32_t y) -{ - double distance = static_cast(x * x + y * y); - - double light = 0.03 + std::pow(10.0 / (1.0 + distance / 100.0), 0.55); - light *= std::min(1.0, std::max(0.0, 2.0 - std::sqrt(distance) / 64)); - light *= 0.1f; - - return static_cast(std::min(255.0, light * 255.0)); -} - -static uint8_t CalcLightIntensitySpot(int32_t x, int32_t y) -{ - double distance = static_cast(x * x + y * y); - - double light = 0.3 + std::pow(10.0 / (1.0 + distance / 100.0), 0.75); - light *= std::min(1.0, std::max(0.0, 2.0 - std::sqrt(distance) / 64)); - light *= 0.5f; - - return static_cast(std::min(255.0, light * 255.0)) >> 4; -} - -static void CalcRescaleLightHalf(uint8_t* target, uint8_t* source, uint32_t targetWidth, uint32_t targetHeight) -{ - uint8_t* parcerRead = source; - uint8_t* parcerWrite = target; - - for (uint32_t y = 0; y < targetHeight; y++) + enum class Qualifier : uint8_t { - for (uint32_t x = 0; x < targetWidth; x++) - { - *parcerWrite = (*parcerRead); - parcerWrite++; - parcerRead += 2; - } - parcerRead += targetWidth * 2; - } -} + Entity, + Map, + }; -void LightFXSetAvailable(bool available) -{ - _lightfxAvailable = available; -} - -bool LightFXIsAvailable() -{ - return _lightfxAvailable && Config::Get().general.EnableLightFx; -} - -bool LightFXForVehiclesIsAvailable() -{ - return LightFXIsAvailable() && Config::Get().general.EnableLightFxForVehicles; -} - -void LightFXInit() -{ - _LightListBack = _LightListA; - _LightListFront = _LightListB; - - std::fill_n(_bakedLightTexture_lantern_0, 32 * 32, 0xFF); - std::fill_n(_bakedLightTexture_lantern_1, 64 * 64, 0xFF); - std::fill_n(_bakedLightTexture_lantern_2, 128 * 128, 0xFF); - std::fill_n(_bakedLightTexture_lantern_3, 256 * 256, 0xFF); - - uint8_t* parcer = _bakedLightTexture_lantern_3; - - for (int32_t y = 0; y < 256; y++) + struct LightListEntry { - for (int32_t x = 0; x < 256; x++) - { - *parcer = CalcLightIntensityLantern(x - 128, y - 128); - parcer++; - } + CoordsXYZ position; + ScreenCoordsXY viewCoords; + LightType type; + uint8_t lightIntensity; + uint32_t lightHash; + Qualifier qualifier; + uint8_t lightID; + uint8_t lightLinger; + }; + + static LightListEntry _LightListA[16000]; + static LightListEntry _LightListB[16000]; + + static LightListEntry* _LightListBack; + static LightListEntry* _LightListFront; + + static uint32_t LightListCurrentCountBack; + static uint32_t LightListCurrentCountFront; + + static int16_t _current_view_x_front = 0; + static int16_t _current_view_y_front = 0; + static uint8_t _current_view_rotation_front = 0; + static ZoomLevel _current_view_zoom_front{ 0 }; + static int16_t _current_view_x_back = 0; + static int16_t _current_view_y_back = 0; + static uint8_t _current_view_rotation_back = 0; + static ZoomLevel _current_view_zoom_back{ 0 }; + static ZoomLevel _current_view_zoom_back_delay{ 0 }; + + static GamePalette gPalette_light; + + static uint8_t CalcLightIntensityLantern(int32_t x, int32_t y) + { + double distance = static_cast(x * x + y * y); + + double light = 0.03 + std::pow(10.0 / (1.0 + distance / 100.0), 0.55); + light *= std::min(1.0, std::max(0.0, 2.0 - std::sqrt(distance) / 64)); + light *= 0.1f; + + return static_cast(std::min(255.0, light * 255.0)); } - parcer = _bakedLightTexture_spot_3; - - for (int32_t y = 0; y < 256; y++) + static uint8_t CalcLightIntensitySpot(int32_t x, int32_t y) { - for (int32_t x = 0; x < 256; x++) - { - *parcer = CalcLightIntensitySpot(x - 128, y - 128); - parcer++; - } + double distance = static_cast(x * x + y * y); + + double light = 0.3 + std::pow(10.0 / (1.0 + distance / 100.0), 0.75); + light *= std::min(1.0, std::max(0.0, 2.0 - std::sqrt(distance) / 64)); + light *= 0.5f; + + return static_cast(std::min(255.0, light * 255.0)) >> 4; } - CalcRescaleLightHalf(_bakedLightTexture_lantern_2, _bakedLightTexture_lantern_3, 128, 128); - CalcRescaleLightHalf(_bakedLightTexture_lantern_1, _bakedLightTexture_lantern_2, 64, 64); - CalcRescaleLightHalf(_bakedLightTexture_lantern_0, _bakedLightTexture_lantern_1, 32, 32); - - CalcRescaleLightHalf(_bakedLightTexture_spot_2, _bakedLightTexture_spot_3, 128, 128); - CalcRescaleLightHalf(_bakedLightTexture_spot_1, _bakedLightTexture_spot_2, 64, 64); - CalcRescaleLightHalf(_bakedLightTexture_spot_0, _bakedLightTexture_spot_1, 32, 32); -} - -void LightFXUpdateBuffers(DrawPixelInfo& info) -{ - _light_rendered_buffer_front = realloc(_light_rendered_buffer_front, info.width * info.height); - _light_rendered_buffer_back = realloc(_light_rendered_buffer_back, info.width * info.height); - _pixelInfo = info; -} - -void LightFXPrepareLightList() -{ - for (uint32_t light = 0; light < LightListCurrentCountFront; light++) + static void CalcRescaleLightHalf(uint8_t* target, uint8_t* source, uint32_t targetWidth, uint32_t targetHeight) { - LightListEntry* entry = &_LightListFront[light]; + uint8_t* parcerRead = source; + uint8_t* parcerWrite = target; - if (entry->Position.z == 0x7FFF) + for (uint32_t y = 0; y < targetHeight; y++) { - entry->LightIntensity = 0xFF; - continue; - } - - int32_t posOnScreenX = entry->ViewCoords.x - _current_view_x_front; - int32_t posOnScreenY = entry->ViewCoords.y - _current_view_y_front; - - posOnScreenX = _current_view_zoom_front.ApplyInversedTo(posOnScreenX); - posOnScreenY = _current_view_zoom_front.ApplyInversedTo(posOnScreenY); - - if ((posOnScreenX < -128) || (posOnScreenY < -128) || (posOnScreenX > _pixelInfo.width + 128) - || (posOnScreenY > _pixelInfo.height + 128)) - { - entry->Type = LightType::None; - continue; - } - - uint32_t lightIntensityOccluded = 0x0; - - int32_t dirVecX = 707; - int32_t dirVecY = 707; - - switch (_current_view_rotation_front) - { - case 0: - dirVecX = 707; - dirVecY = 707; - break; - case 1: - dirVecX = -707; - dirVecY = 707; - break; - case 2: - dirVecX = -707; - dirVecY = -707; - break; - case 3: - dirVecX = 707; - dirVecY = -707; - break; - default: - dirVecX = 0; - dirVecY = 0; - break; - } - - int32_t tileOffsetX = 0; - int32_t tileOffsetY = 0; - switch (_current_view_rotation_front) - { - case 0: - tileOffsetX = 0; - tileOffsetY = 0; - break; - case 1: - tileOffsetX = 16; - tileOffsetY = 0; - break; - case 2: - tileOffsetX = 32; - tileOffsetY = 32; - break; - case 3: - tileOffsetX = 0; - tileOffsetY = 16; - break; - } - - // clang-format off - static int16_t offsetPattern[26] = { - 0, 0, - -4, 0, 0, -3, 4, 0, 0, 3, - -2, -1, -1, -1, 2, 1, 1, 1, - -3, -2, -3, 2, 3, -2, 3, 2, - }; - // clang-format on - - // Light occlusion code - if (true) - { - int32_t totalSamplePoints = 5; - int32_t startSamplePoint = 1; - - if (entry->Qualifier == LightFXQualifier::Map) + for (uint32_t x = 0; x < targetWidth; x++) { - startSamplePoint = 0; - totalSamplePoints = 1; + *parcerWrite = (*parcerRead); + parcerWrite++; + parcerRead += 2; + } + parcerRead += targetWidth * 2; + } + } + + void SetAvailable(bool available) + { + _lightfxAvailable = available; + } + + bool IsAvailable() + { + return _lightfxAvailable && Config::Get().general.EnableLightFx; + } + + bool ForVehiclesIsAvailable() + { + return IsAvailable() && Config::Get().general.EnableLightFxForVehicles; + } + + void Init() + { + _LightListBack = _LightListA; + _LightListFront = _LightListB; + + std::fill_n(_bakedLightTexture_lantern_0, 32 * 32, 0xFF); + std::fill_n(_bakedLightTexture_lantern_1, 64 * 64, 0xFF); + std::fill_n(_bakedLightTexture_lantern_2, 128 * 128, 0xFF); + std::fill_n(_bakedLightTexture_lantern_3, 256 * 256, 0xFF); + + uint8_t* parcer = _bakedLightTexture_lantern_3; + + for (int32_t y = 0; y < 256; y++) + { + for (int32_t x = 0; x < 256; x++) + { + *parcer = CalcLightIntensityLantern(x - 128, y - 128); + parcer++; + } + } + + parcer = _bakedLightTexture_spot_3; + + for (int32_t y = 0; y < 256; y++) + { + for (int32_t x = 0; x < 256; x++) + { + *parcer = CalcLightIntensitySpot(x - 128, y - 128); + parcer++; + } + } + + CalcRescaleLightHalf(_bakedLightTexture_lantern_2, _bakedLightTexture_lantern_3, 128, 128); + CalcRescaleLightHalf(_bakedLightTexture_lantern_1, _bakedLightTexture_lantern_2, 64, 64); + CalcRescaleLightHalf(_bakedLightTexture_lantern_0, _bakedLightTexture_lantern_1, 32, 32); + + CalcRescaleLightHalf(_bakedLightTexture_spot_2, _bakedLightTexture_spot_3, 128, 128); + CalcRescaleLightHalf(_bakedLightTexture_spot_1, _bakedLightTexture_spot_2, 64, 64); + CalcRescaleLightHalf(_bakedLightTexture_spot_0, _bakedLightTexture_spot_1, 32, 32); + } + + void UpdateBuffers(DrawPixelInfo& info) + { + _light_rendered_buffer_front = realloc(_light_rendered_buffer_front, info.width * info.height); + _light_rendered_buffer_back = realloc(_light_rendered_buffer_back, info.width * info.height); + _pixelInfo = info; + } + + void PrepareLightList() + { + for (uint32_t light = 0; light < LightListCurrentCountFront; light++) + { + LightListEntry& entry = _LightListFront[light]; + + if (entry.position.z == 0x7FFF) + { + entry.lightIntensity = 0xFF; + continue; } - for (int32_t pat = startSamplePoint; pat < totalSamplePoints; pat++) + int32_t posOnScreenX = entry.viewCoords.x - _current_view_x_front; + int32_t posOnScreenY = entry.viewCoords.y - _current_view_y_front; + + posOnScreenX = _current_view_zoom_front.ApplyInversedTo(posOnScreenX); + posOnScreenY = _current_view_zoom_front.ApplyInversedTo(posOnScreenY); + + if ((posOnScreenX < -128) || (posOnScreenY < -128) || (posOnScreenX > _pixelInfo.width + 128) + || (posOnScreenY > _pixelInfo.height + 128)) { - CoordsXY mapCoord{}; + entry.type = LightType::None; + continue; + } - TileElement* tileElement = nullptr; + uint32_t lightIntensityOccluded = 0x0; - ViewportInteractionItem interactionType = ViewportInteractionItem::None; + int32_t dirVecX = 707; + int32_t dirVecY = 707; - auto* w = WindowGetMain(); - if (w != nullptr) - { - // based on GetMapCoordinatesFromPosWindow - DrawPixelInfo dpi; - dpi.zoom_level = _current_view_zoom_front; - dpi.x = _current_view_zoom_front.ApplyInversedTo(entry->ViewCoords.x + offsetPattern[0 + pat * 2]); - dpi.y = _current_view_zoom_front.ApplyInversedTo(entry->ViewCoords.y + offsetPattern[1 + pat * 2]); - dpi.height = 1; - dpi.width = 1; - - PaintSession* session = PaintSessionAlloc(dpi, w->viewport->flags, w->viewport->rotation); - PaintSessionGenerate(*session); - PaintSessionArrange(*session); - auto info = SetInteractionInfoFromPaintSession(session, w->viewport->flags, ViewportInteractionItemAll); - PaintSessionFree(session); - - // LOG_WARNING("[%i, %i]", dpi->x, dpi->y); - - mapCoord = info.Loc; - mapCoord.x += tileOffsetX; - mapCoord.y += tileOffsetY; - interactionType = info.interactionType; - tileElement = info.Element; - } - - int32_t minDist = 0; - int32_t baseHeight = (-999) * kCoordsZStep; - - if (interactionType != ViewportInteractionItem::Entity && tileElement != nullptr) - { - baseHeight = tileElement->GetBaseZ(); - } - - minDist = (baseHeight - entry->Position.z) / 2; - - int32_t deltaX = mapCoord.x - entry->Position.x; - int32_t deltaY = mapCoord.y - entry->Position.y; - - int32_t projDot = (dirVecX * deltaX + dirVecY * deltaY) / 1000; - - projDot = std::max(minDist, projDot); - - if (projDot < 5) - { - lightIntensityOccluded += 100; - } - else - { - lightIntensityOccluded += std::max(0, 200 - (projDot * 20)); - } - - // LOG_WARNING("light %i [%i, %i, %i], [%i, %i] minDist to %i: %i; projdot: %i", light, coord_3d.x, coord_3d.y, - // coord_3d.z, mapCoord.x, mapCoord.y, baseHeight, minDist, projDot); - - if (pat == 0) - { - if (lightIntensityOccluded == 100) - break; - if (_current_view_zoom_front > ZoomLevel{ 2 }) - break; - totalSamplePoints += 4; - } - else if (pat == 4) - { - if (_current_view_zoom_front > ZoomLevel{ 1 }) - break; - if (lightIntensityOccluded == 0 || lightIntensityOccluded == 500) - break; - // lastSampleCount = lightIntensityOccluded / 500; - // break; - totalSamplePoints += 4; - } - else if (pat == 8) - { + switch (_current_view_rotation_front) + { + case 0: + dirVecX = 707; + dirVecY = 707; + break; + case 1: + dirVecX = -707; + dirVecY = 707; + break; + case 2: + dirVecX = -707; + dirVecY = -707; + break; + case 3: + dirVecX = 707; + dirVecY = -707; + break; + default: + dirVecX = 0; + dirVecY = 0; break; - } } - totalSamplePoints -= startSamplePoint; - - if (lightIntensityOccluded == 0) + int32_t tileOffsetX = 0; + int32_t tileOffsetY = 0; + switch (_current_view_rotation_front) { - entry->Type = LightType::None; - continue; + case 0: + tileOffsetX = 0; + tileOffsetY = 0; + break; + case 1: + tileOffsetX = 16; + tileOffsetY = 0; + break; + case 2: + tileOffsetX = 32; + tileOffsetY = 32; + break; + case 3: + tileOffsetX = 0; + tileOffsetY = 16; + break; } - entry->LightIntensity = static_cast( - std::min(0xFF, (entry->LightIntensity * lightIntensityOccluded) / (totalSamplePoints * 100))); - } + // clang-format off + static int16_t offsetPattern[26] = { + 0, 0, + -4, 0, 0, -3, 4, 0, 0, 3, + -2, -1, -1, -1, 2, 1, 1, 1, + -3, -2, -3, 2, 3, -2, 3, 2, + }; + // clang-format on - if (_current_view_zoom_front > ZoomLevel{ 0 }) - { - const int8_t zoomNumber = static_cast(_current_view_zoom_front); - entry->LightIntensity -= 5 * zoomNumber; - if (GetLightTypeSize(entry->Type) < zoomNumber) + // Light occlusion code + if (true) { - entry->Type = LightType::None; - continue; - } + int32_t totalSamplePoints = 5; + int32_t startSamplePoint = 1; - entry->Type = SetLightTypeSize(entry->Type, GetLightTypeSize(entry->Type) - zoomNumber); - } - } -} - -void LightFXSwapBuffers() -{ - void* tmp = _light_rendered_buffer_back; - _light_rendered_buffer_back = _light_rendered_buffer_front; - _light_rendered_buffer_front = tmp; - - tmp = _light_rendered_buffer_back; - _light_rendered_buffer_back = _light_rendered_buffer_front; - _light_rendered_buffer_front = tmp; - - tmp = _LightListBack; - _LightListBack = _LightListFront; - _LightListFront = static_cast(tmp); - - LightListCurrentCountFront = LightListCurrentCountBack; - LightListCurrentCountBack = 0x0; - - uint32_t uTmp = _lightPolution_back; - _lightPolution_back = _lightPolution_front; - _lightPolution_front = uTmp; - - _current_view_x_front = _current_view_x_back; - _current_view_y_front = _current_view_y_back; - _current_view_rotation_front = _current_view_rotation_back; - _current_view_zoom_front = _current_view_zoom_back_delay; - _current_view_zoom_back_delay = _current_view_zoom_back; -} - -void LightFXUpdateViewportSettings() -{ - WindowBase* mainWindow = WindowGetMain(); - if (mainWindow != nullptr) - { - Viewport* viewport = WindowGetViewport(mainWindow); - _current_view_x_back = viewport->viewPos.x; - _current_view_y_back = viewport->viewPos.y; - _current_view_rotation_back = viewport->rotation; - _current_view_zoom_back = viewport->zoom; - } -} - -void LightFXRenderLightsToFrontBuffer() -{ - if (_light_rendered_buffer_front == nullptr) - { - return; - } - - std::memset(_light_rendered_buffer_front, 0, _pixelInfo.width * _pixelInfo.height); - - _lightPolution_back = 0; - - // LOG_WARNING("%i lights", LightListCurrentCountFront); - - for (uint32_t light = 0; light < LightListCurrentCountFront; light++) - { - const uint8_t* bufReadBase = nullptr; - uint8_t* bufWriteBase = static_cast(_light_rendered_buffer_front); - uint32_t bufReadWidth, bufReadHeight; - int32_t bufWriteX, bufWriteY; - int32_t bufWriteWidth, bufWriteHeight; - uint32_t bufReadSkip, bufWriteSkip; - - LightListEntry* entry = &_LightListFront[light]; - - int32_t inRectCentreX = entry->ViewCoords.x; - int32_t inRectCentreY = entry->ViewCoords.y; - - if (entry->Position.z != 0x7FFF) - { - inRectCentreX -= _current_view_x_front; - inRectCentreY -= _current_view_y_front; - inRectCentreX = _current_view_zoom_front.ApplyInversedTo(inRectCentreX); - inRectCentreY = _current_view_zoom_front.ApplyInversedTo(inRectCentreY); - } - - switch (entry->Type) - { - case LightType::Lantern0: - bufReadWidth = 32; - bufReadHeight = 32; - bufReadBase = _bakedLightTexture_lantern_0; - break; - case LightType::Lantern1: - bufReadWidth = 64; - bufReadHeight = 64; - bufReadBase = _bakedLightTexture_lantern_1; - break; - case LightType::Lantern2: - bufReadWidth = 128; - bufReadHeight = 128; - bufReadBase = _bakedLightTexture_lantern_2; - break; - case LightType::Lantern3: - bufReadWidth = 256; - bufReadHeight = 256; - bufReadBase = _bakedLightTexture_lantern_3; - break; - case LightType::Spot0: - bufReadWidth = 32; - bufReadHeight = 32; - bufReadBase = _bakedLightTexture_spot_0; - break; - case LightType::Spot1: - bufReadWidth = 64; - bufReadHeight = 64; - bufReadBase = _bakedLightTexture_spot_1; - break; - case LightType::Spot2: - bufReadWidth = 128; - bufReadHeight = 128; - bufReadBase = _bakedLightTexture_spot_2; - break; - case LightType::Spot3: - bufReadWidth = 256; - bufReadHeight = 256; - bufReadBase = _bakedLightTexture_spot_3; - break; - default: - continue; - } - - // Clamp the reads to be no larger than the buffer size - bufReadHeight = std::min(_pixelInfo.height, bufReadHeight); - bufReadWidth = std::min(_pixelInfo.width, bufReadWidth); - - bufWriteX = inRectCentreX - bufReadWidth / 2; - bufWriteY = inRectCentreY - bufReadHeight / 2; - - bufWriteWidth = bufReadWidth; - bufWriteHeight = bufReadHeight; - - if (bufWriteX < 0) - { - bufReadBase += -bufWriteX; - bufWriteWidth += bufWriteX; - } - else - { - bufWriteBase += bufWriteX; - } - - if (bufWriteWidth <= 0) - continue; - - if (bufWriteY < 0) - { - bufReadBase += -bufWriteY * bufReadWidth; - bufWriteHeight += bufWriteY; - } - else - { - bufWriteBase += bufWriteY * _pixelInfo.width; - } - - if (bufWriteHeight <= 0) - continue; - - int32_t rightEdge = bufWriteX + bufWriteWidth; - int32_t bottomEdge = bufWriteY + bufWriteHeight; - - if (rightEdge > _pixelInfo.width) - { - bufWriteWidth -= rightEdge - _pixelInfo.width; - } - if (bottomEdge > _pixelInfo.height) - { - bufWriteHeight -= bottomEdge - _pixelInfo.height; - } - - if (bufWriteWidth <= 0) - continue; - if (bufWriteHeight <= 0) - continue; - - _lightPolution_back += (bufWriteWidth * bufWriteHeight) / 256; - - bufReadSkip = bufReadWidth - bufWriteWidth; - bufWriteSkip = _pixelInfo.width - bufWriteWidth; - - if (entry->LightIntensity == 0xFF) - { - for (int32_t y = 0; y < bufWriteHeight; y++) - { - for (int32_t x = 0; x < bufWriteWidth; x++) + if (entry.qualifier == Qualifier::Map) { - *bufWriteBase = std::min(0xFF, *bufWriteBase + *bufReadBase); - bufWriteBase++; - bufReadBase++; + startSamplePoint = 0; + totalSamplePoints = 1; } - bufWriteBase += bufWriteSkip; - bufReadBase += bufReadSkip; - } - } - else - { - for (int32_t y = 0; y < bufWriteHeight; y++) - { - for (int32_t x = 0; x < bufWriteWidth; x++) + for (int32_t pat = startSamplePoint; pat < totalSamplePoints; pat++) { - *bufWriteBase = std::min(0xFF, *bufWriteBase + (((*bufReadBase) * (1 + entry->LightIntensity)) >> 8)); - bufWriteBase++; - bufReadBase++; + CoordsXY mapCoord{}; + + TileElement* tileElement = nullptr; + + ViewportInteractionItem interactionType = ViewportInteractionItem::None; + + auto* w = WindowGetMain(); + if (w != nullptr) + { + // based on GetMapCoordinatesFromPosWindow + DrawPixelInfo dpi; + dpi.zoom_level = _current_view_zoom_front; + dpi.x = _current_view_zoom_front.ApplyInversedTo(entry.viewCoords.x + offsetPattern[0 + pat * 2]); + dpi.y = _current_view_zoom_front.ApplyInversedTo(entry.viewCoords.y + offsetPattern[1 + pat * 2]); + dpi.height = 1; + dpi.width = 1; + + PaintSession* session = PaintSessionAlloc(dpi, w->viewport->flags, w->viewport->rotation); + PaintSessionGenerate(*session); + PaintSessionArrange(*session); + auto info = SetInteractionInfoFromPaintSession(session, w->viewport->flags, ViewportInteractionItemAll); + PaintSessionFree(session); + + // LOG_WARNING("[%i, %i]", dpi->x, dpi->y); + + mapCoord = info.Loc; + mapCoord.x += tileOffsetX; + mapCoord.y += tileOffsetY; + interactionType = info.interactionType; + tileElement = info.Element; + } + + int32_t minDist = 0; + int32_t baseHeight = (-999) * kCoordsZStep; + + if (interactionType != ViewportInteractionItem::Entity && tileElement != nullptr) + { + baseHeight = tileElement->GetBaseZ(); + } + + minDist = (baseHeight - entry.position.z) / 2; + + int32_t deltaX = mapCoord.x - entry.position.x; + int32_t deltaY = mapCoord.y - entry.position.y; + + int32_t projDot = (dirVecX * deltaX + dirVecY * deltaY) / 1000; + + projDot = std::max(minDist, projDot); + + if (projDot < 5) + { + lightIntensityOccluded += 100; + } + else + { + lightIntensityOccluded += std::max(0, 200 - (projDot * 20)); + } + + // LOG_WARNING("light %i [%i, %i, %i], [%i, %i] minDist to %i: %i; projdot: %i", light, coord_3d.x, + // coord_3d.y, coord_3d.z, mapCoord.x, mapCoord.y, baseHeight, minDist, projDot); + + if (pat == 0) + { + if (lightIntensityOccluded == 100) + break; + if (_current_view_zoom_front > ZoomLevel{ 2 }) + break; + totalSamplePoints += 4; + } + else if (pat == 4) + { + if (_current_view_zoom_front > ZoomLevel{ 1 }) + break; + if (lightIntensityOccluded == 0 || lightIntensityOccluded == 500) + break; + // lastSampleCount = lightIntensityOccluded / 500; + // break; + totalSamplePoints += 4; + } + else if (pat == 8) + { + break; + } } - bufWriteBase += bufWriteSkip; - bufReadBase += bufReadSkip; + totalSamplePoints -= startSamplePoint; + + if (lightIntensityOccluded == 0) + { + entry.type = LightType::None; + continue; + } + + entry.lightIntensity = static_cast( + std::min(0xFF, (entry.lightIntensity * lightIntensityOccluded) / (totalSamplePoints * 100))); + } + + if (_current_view_zoom_front > ZoomLevel{ 0 }) + { + const int8_t zoomNumber = static_cast(_current_view_zoom_front); + entry.lightIntensity -= 5 * zoomNumber; + if (GetLightTypeSize(entry.type) < zoomNumber) + { + entry.type = LightType::None; + continue; + } + + entry.type = SetLightTypeSize(entry.type, GetLightTypeSize(entry.type) - zoomNumber); } } } -} -void* LightFXGetFrontBuffer() -{ - return _light_rendered_buffer_front; -} - -const GamePalette& LightFXGetPalette() -{ - return gPalette_light; -} - -static void LightFXAdd3DLight( - const uint32_t lightHash, const LightFXQualifier qualifier, const uint8_t id, const CoordsXYZ& loc, - const LightType lightType) -{ - if (LightListCurrentCountBack == 15999) + void SwapBuffers() { - return; + void* tmp = _light_rendered_buffer_back; + _light_rendered_buffer_back = _light_rendered_buffer_front; + _light_rendered_buffer_front = tmp; + + tmp = _light_rendered_buffer_back; + _light_rendered_buffer_back = _light_rendered_buffer_front; + _light_rendered_buffer_front = tmp; + + tmp = _LightListBack; + _LightListBack = _LightListFront; + _LightListFront = static_cast(tmp); + + LightListCurrentCountFront = LightListCurrentCountBack; + LightListCurrentCountBack = 0x0; + + uint32_t uTmp = _lightPolution_back; + _lightPolution_back = _lightPolution_front; + _lightPolution_front = uTmp; + + _current_view_x_front = _current_view_x_back; + _current_view_y_front = _current_view_y_back; + _current_view_rotation_front = _current_view_rotation_back; + _current_view_zoom_front = _current_view_zoom_back_delay; + _current_view_zoom_back_delay = _current_view_zoom_back; } - // LOG_WARNING("%i lights in back", LightListCurrentCountBack); - - for (uint32_t i = 0; i < LightListCurrentCountBack; i++) + void UpdateViewportSettings() { - LightListEntry* entry = &_LightListBack[i]; - if (entry->LightHash != lightHash) - continue; - if (entry->Qualifier != qualifier) - continue; - if (entry->LightID != id) - continue; - - entry->Position = loc; - entry->ViewCoords = Translate3DTo2DWithZ(GetCurrentRotation(), loc); - entry->Type = lightType; - entry->LightIntensity = 0xFF; - entry->LightHash = lightHash; - entry->Qualifier = qualifier; - entry->LightID = id; - entry->LightLinger = 1; - - return; - } - - LightListEntry* entry = &_LightListBack[LightListCurrentCountBack++]; - - entry->Position = loc; - entry->ViewCoords = Translate3DTo2DWithZ(GetCurrentRotation(), loc); - entry->Type = lightType; - entry->LightIntensity = 0xFF; - entry->LightHash = lightHash; - entry->Qualifier = qualifier; - entry->LightID = id; - entry->LightLinger = 1; - - // LOG_WARNING("new 3d light"); -} - -static void LightFXAdd3DLight(const CoordsXYZ& loc, const LightType lightType) -{ - LightFXAdd3DLight(((loc.x << 16) | loc.y), LightFXQualifier::Map, loc.z, loc, lightType); -} - -void LightFXAdd3DLight(const EntityBase& entity, const uint8_t id, const CoordsXYZ& loc, const LightType lightType) -{ - LightFXAdd3DLight(entity.Id.ToUnderlying(), LightFXQualifier::Entity, id, loc, lightType); -} - -void LightFXAdd3DLightMagicFromDrawingTile( - const CoordsXY& mapPosition, int16_t offsetX, int16_t offsetY, int16_t offsetZ, LightType lightType) -{ - int16_t x = mapPosition.x + offsetX + 16; - int16_t y = mapPosition.y + offsetY + 16; - - LightFXAdd3DLight({ x, y, offsetZ }, lightType); -} - -uint32_t LightFXGetLightPolution() -{ - return _lightPolution_front; -} - -static constexpr int16_t offsetLookup[] = { - 10, 10, 9, 8, 7, 6, 4, 2, 0, -2, -4, -6, -7, -8, -9, -10, -10, -10, -9, -8, -7, -6, -4, -2, 0, 2, 4, 6, 7, 8, 9, 10, -}; -void LightFxAddLightsMagicVehicle_ObservationTower(const Vehicle* vehicle) -{ - LightFXAdd3DLight(*vehicle, 0, { vehicle->x, vehicle->y + 16, vehicle->z }, LightType::Spot3); - LightFXAdd3DLight(*vehicle, 1, { vehicle->x + 16, vehicle->y, vehicle->z }, LightType::Spot3); - LightFXAdd3DLight(*vehicle, 2, { vehicle->x - 16, vehicle->y, vehicle->z }, LightType::Spot3); - LightFXAdd3DLight(*vehicle, 3, { vehicle->x, vehicle->y - 16, vehicle->z }, LightType::Spot3); -} - -void LightFxAddLightsMagicVehicle_MineTrainCoaster(const Vehicle* vehicle) -{ - if (vehicle == vehicle->TrainHead()) - { - int16_t place_x = vehicle->x - offsetLookup[(vehicle->Orientation + 0) % 32] * 2; - int16_t place_y = vehicle->y - offsetLookup[(vehicle->Orientation + 8) % 32] * 2; - LightFXAdd3DLight(*vehicle, 0, { place_x, place_y, vehicle->z }, LightType::Spot3); - } -} - -void LightFxAddLightsMagicVehicle_ChairLift(const Vehicle* vehicle) -{ - LightFXAdd3DLight(*vehicle, 0, { vehicle->x, vehicle->y, vehicle->z - 16 }, LightType::Lantern2); -} -void LightFxAddLightsMagicVehicle_BoatHire(const Vehicle* vehicle) -{ - Vehicle* vehicle_draw = vehicle->TrainHead(); - auto* nextVeh = GetEntity(vehicle_draw->next_vehicle_on_train); - if (nextVeh != nullptr) - { - vehicle_draw = nextVeh; - } - int16_t place_x = vehicle_draw->x; - int16_t place_y = vehicle_draw->y; - place_x -= offsetLookup[(vehicle_draw->Orientation + 0) % 32]; - place_y -= offsetLookup[(vehicle_draw->Orientation + 8) % 32]; - LightFXAdd3DLight(*vehicle, 0, { place_x, place_y, vehicle_draw->z }, LightType::Spot2); - place_x -= offsetLookup[(vehicle_draw->Orientation + 0) % 32]; - place_y -= offsetLookup[(vehicle_draw->Orientation + 8) % 32]; - LightFXAdd3DLight(*vehicle, 1, { place_x, place_y, vehicle_draw->z }, LightType::Spot2); -} -void LightFxAddLightsMagicVehicle_Monorail(const Vehicle* vehicle) -{ - LightFXAdd3DLight(*vehicle, 0, { vehicle->x, vehicle->y, vehicle->z + 12 }, LightType::Spot2); - int16_t place_x = vehicle->x; - int16_t place_y = vehicle->y; - if (vehicle == vehicle->TrainHead()) - { - place_x -= offsetLookup[(vehicle->Orientation + 0) % 32] * 2; - place_y -= offsetLookup[(vehicle->Orientation + 8) % 32] * 2; - LightFXAdd3DLight(*vehicle, 1, { place_x, place_y, vehicle->z + 10 }, LightType::Lantern3); - place_x -= offsetLookup[(vehicle->Orientation + 0) % 32] * 3; - place_y -= offsetLookup[(vehicle->Orientation + 8) % 32] * 3; - LightFXAdd3DLight(*vehicle, 2, { place_x, place_y, vehicle->z + 2 }, LightType::Lantern3); - } - if (vehicle == vehicle->TrainTail()) - { - place_x += offsetLookup[(vehicle->Orientation + 0) % 32] * 2; - place_y += offsetLookup[(vehicle->Orientation + 8) % 32] * 2; - LightFXAdd3DLight(*vehicle, 3, { place_x, place_y, vehicle->z + 10 }, LightType::Lantern3); - place_x += offsetLookup[(vehicle->Orientation + 0) % 32] * 2; - place_y += offsetLookup[(vehicle->Orientation + 8) % 32] * 2; - LightFXAdd3DLight(*vehicle, 4, { place_x, place_y, vehicle->z + 2 }, LightType::Lantern3); - } -} -void LightFxAddLightsMagicVehicle_MiniatureRailway(const Vehicle* vehicle) -{ - if (vehicle == vehicle->TrainHead()) - { - int16_t place_x = vehicle->x - offsetLookup[(vehicle->Orientation + 0) % 32] * 2; - int16_t place_y = vehicle->y - offsetLookup[(vehicle->Orientation + 8) % 32] * 2; - LightFXAdd3DLight(*vehicle, 1, { place_x, place_y, vehicle->z + 10 }, LightType::Lantern3); - place_x -= offsetLookup[(vehicle->Orientation + 0) % 32] * 2; - place_y -= offsetLookup[(vehicle->Orientation + 8) % 32] * 2; - LightFXAdd3DLight(*vehicle, 2, { place_x, place_y, vehicle->z + 2 }, LightType::Lantern3); - } - else - { - LightFXAdd3DLight(*vehicle, 0, { vehicle->x, vehicle->y, vehicle->z + 10 }, LightType::Lantern3); - } -} - -void LightFXAddLightsMagicVehicle(const Vehicle* vehicle) -{ - auto ride = vehicle->GetRide(); - if (ride == nullptr) - return; - - const auto& rtd = GetRideTypeDescriptor(ride->type); - if (rtd.LightFXAddLightsMagicVehicle != nullptr) - rtd.LightFXAddLightsMagicVehicle(vehicle); -} - -void LightFxAddKioskLights(const CoordsXY& mapPosition, const int32_t height, const uint8_t zOffset) -{ - uint8_t relativeRotation = (4 - GetCurrentRotation()) % 4; - CoordsXY lanternOffset1 = CoordsXY(0, 16).Rotate(relativeRotation); - CoordsXY lanternOffset2 = CoordsXY(16, 0).Rotate(relativeRotation); - LightFXAdd3DLightMagicFromDrawingTile( - mapPosition, lanternOffset1.x, lanternOffset1.y, height + zOffset, LightType::Lantern3); - LightFXAdd3DLightMagicFromDrawingTile( - mapPosition, lanternOffset2.x, lanternOffset2.y, height + zOffset, LightType::Lantern3); - LightFXAdd3DLightMagicFromDrawingTile(mapPosition, 8, 32, height, LightType::Spot1); - LightFXAdd3DLightMagicFromDrawingTile(mapPosition, 32, 8, height, LightType::Spot1); - LightFXAdd3DLightMagicFromDrawingTile(mapPosition, -32, 8, height, LightType::Spot1); - LightFXAdd3DLightMagicFromDrawingTile(mapPosition, 8, -32, height, LightType::Spot1); - LightFXAdd3DLightMagicFromDrawingTile(mapPosition, -8, 32, height, LightType::Spot1); - LightFXAdd3DLightMagicFromDrawingTile(mapPosition, 32, -8, height, LightType::Spot1); - LightFXAdd3DLightMagicFromDrawingTile(mapPosition, -32, -8, height, LightType::Spot1); - LightFXAdd3DLightMagicFromDrawingTile(mapPosition, -8, -32, height, LightType::Spot1); -} - -void LightFxAddShopLights(const CoordsXY& mapPosition, const uint8_t direction, const int32_t height, const uint8_t zOffset) -{ - if (direction == (4 - GetCurrentRotation()) % 4) // Back Right Facing Stall - { - CoordsXY spotOffset1 = CoordsXY(-32, 8).Rotate(direction); - CoordsXY spotOffset2 = CoordsXY(-32, 4).Rotate(direction); - LightFXAdd3DLightMagicFromDrawingTile(mapPosition, spotOffset1.x, spotOffset1.y, height, LightType::Spot1); - LightFXAdd3DLightMagicFromDrawingTile(mapPosition, spotOffset2.x, spotOffset2.y, height, LightType::Spot2); - } - else if (direction == (7 - GetCurrentRotation()) % 4) // Back left Facing Stall - { - CoordsXY spotOffset1 = CoordsXY(-32, -8).Rotate(direction); - CoordsXY spotOffset2 = CoordsXY(-32, -4).Rotate(direction); - LightFXAdd3DLightMagicFromDrawingTile(mapPosition, spotOffset1.x, spotOffset1.y, height, LightType::Spot1); - LightFXAdd3DLightMagicFromDrawingTile(mapPosition, spotOffset2.x, spotOffset2.y, height, LightType::Spot2); - } - else // Forward Facing Stall - { - CoordsXY spotOffset1 = CoordsXY(-32, 8).Rotate(direction); - CoordsXY spotOffset2 = CoordsXY(-32, -8).Rotate(direction); - CoordsXY lanternOffset = CoordsXY(-16, 0).Rotate(direction); - LightFXAdd3DLightMagicFromDrawingTile( - mapPosition, lanternOffset.x, lanternOffset.y, height + zOffset, LightType::Lantern3); - LightFXAdd3DLightMagicFromDrawingTile(mapPosition, spotOffset1.x, spotOffset1.y, height, LightType::Spot1); - LightFXAdd3DLightMagicFromDrawingTile(mapPosition, spotOffset2.x, spotOffset2.y, height, LightType::Spot1); - } -} - -void LightFXApplyPaletteFilter(uint8_t i, uint8_t* r, uint8_t* g, uint8_t* b) -{ - auto& gameState = GetGameState(); - - float night = static_cast(pow(gDayNightCycle, 1.5)); - - float natLightR = 1.0f; - float natLightG = 1.0f; - float natLightB = 1.0f; - - float elecMultR = 1.0f; - float elecMultG = 0.95f; - float elecMultB = 0.45f; - - static float wetness = 0.0f; - static float fogginess = 0.0f; - static float lightPolution = 0.0f; - - float sunLight = std::max(0.0f, std::min(1.0f, 2.0f - night * 3.0f)); - - // Night version - natLightR = FLerp(natLightR * 4.0f, 0.635f, (std::pow(night, 0.035f + sunLight * 10.50f))); - natLightG = FLerp(natLightG * 4.0f, 0.650f, (std::pow(night, 0.100f + sunLight * 5.50f))); - natLightB = FLerp(natLightB * 4.0f, 0.850f, (std::pow(night, 0.200f + sunLight * 1.5f))); - - float overExpose = 0.0f; - float lightAvg = (natLightR + natLightG + natLightB) / 3.0f; -#ifdef LIGHTFX_UNKNOWN_PART_2 - float lightMax = (natLightR + natLightG + natLightB) / 3.0f; -#endif // LIGHTFX_UNKNOWN_PART_2 - - // overExpose += ((lightMax - lightAvg) / lightMax) * 0.01f; - - if (gameState.ClimateCurrent.Temperature > 20) - { - float offset = (static_cast(gameState.ClimateCurrent.Temperature - 20)) * 0.04f; - offset *= 1.0f - night; - lightAvg /= 1.0f + offset; - // overExpose += offset * 0.1f; - } - -#ifdef LIGHTFX_UNKNOWN_PART_2 - lightAvg += (lightMax - lightAvg) * 0.6f; -#endif // LIGHTFX_UNKNOWN_PART_2 - - if (lightAvg > 1.0f) - { - natLightR /= lightAvg; - natLightG /= lightAvg; - natLightB /= lightAvg; - } - - natLightR *= 1.0f + overExpose; - natLightG *= 1.0f + overExpose; - natLightB *= 1.0f + overExpose; - overExpose *= 255.0f; - - float targetFogginess = static_cast(gameState.ClimateCurrent.Level) / 8.0f; - targetFogginess += (night * night) * 0.15f; - - if (gameState.ClimateCurrent.Temperature < 10) - { - targetFogginess += (static_cast(10 - gameState.ClimateCurrent.Temperature)) * 0.01f; - } - - fogginess -= (fogginess - targetFogginess) * 0.00001f; - - wetness *= 0.999995f; - wetness += fogginess * 0.001f; - wetness = std::min(wetness, 1.0f); - - float boost = 1.0f; - float envFog = fogginess; - float lightFog = envFog; - - float addLightNatR = 0.0f; - float addLightNatG = 0.0f; - float addLightNatB = 0.0f; - - float reduceColourNat = 1.0f; - float reduceColourLit = 1.0f; - - reduceColourLit *= night / static_cast(std::pow(std::max(1.01f, 0.4f + lightAvg), 2.0)); - - float targetLightPollution = reduceColourLit - * std::max(0.0f, 0.0f + 0.000001f * static_cast(LightFXGetLightPolution())); - lightPolution -= (lightPolution - targetLightPollution) * 0.001f; - - // lightPollution /= 1.0f + fogginess * 1.0f; - - natLightR /= 1.0f + lightPolution * 20.0f; - natLightG /= 1.0f + lightPolution * 20.0f; - natLightB /= 1.0f + lightPolution * 20.0f; - natLightR += elecMultR * 0.6f * lightPolution; - natLightG += elecMultG * 0.6f * lightPolution; - natLightB += elecMultB * 0.6f * lightPolution; - natLightR /= 1.0f + lightPolution; - natLightG /= 1.0f + lightPolution; - natLightB /= 1.0f + lightPolution; - - reduceColourLit += static_cast(gameState.ClimateCurrent.Level) / 2.0f; - - reduceColourNat /= 1.0f + fogginess; - reduceColourLit /= 1.0f + fogginess; - - lightFog *= reduceColourLit; - - reduceColourNat *= 1.0f - envFog; - reduceColourLit *= 1.0f - lightFog; - - float fogR = 35.5f * natLightR * 1.3f; - float fogG = 45.0f * natLightG * 1.3f; - float fogB = 50.0f * natLightB * 1.3f; - lightFog *= 10.0f; - - float wetnessBoost = 1.0f; // 1.0f + wetness * wetness * 0.1f; - - if (night >= 0 && gClimateLightningFlash != 1) - { - *r = Lerp(*r, SoftLight(*r, 8), night); - *g = Lerp(*g, SoftLight(*g, 8), night); - *b = Lerp(*b, SoftLight(*b, 128), night); - - // if (i == 32) - // boost = 300000.0f; - if ((i % 32) == 0) - boost = 1.01f * wetnessBoost; - else if ((i % 16) < 7) - boost = 1.001f * wetnessBoost; - if (i > 230 && i < 232) - boost = (static_cast(*b)) / 64.0f; - - if (false) + WindowBase* mainWindow = WindowGetMain(); + if (mainWindow != nullptr) { - // This experiment shifts the colour of pixels as-if they are wet, but it is not a pretty solution at all - if ((i % 16)) - { - float iVal = (static_cast((i + 12) % 16)) / 16.0f; - float eff = (wetness * (static_cast(std::pow(iVal, 1.5)) * 0.85f)); - reduceColourNat *= 1.0f - eff; - addLightNatR += fogR * eff * 3.95f; - addLightNatG += fogR * eff * 3.95f; - addLightNatB += fogR * eff * 3.95f; - } + Viewport* viewport = WindowGetViewport(mainWindow); + _current_view_x_back = viewport->viewPos.x; + _current_view_y_back = viewport->viewPos.y; + _current_view_rotation_back = viewport->rotation; + _current_view_zoom_back = viewport->zoom; + } + } + + void RenderLightsToFrontBuffer() + { + if (_light_rendered_buffer_front == nullptr) + { + return; } - addLightNatR *= 1.0f - envFog; - addLightNatG *= 1.0f - envFog; - addLightNatB *= 1.0f - envFog; + std::memset(_light_rendered_buffer_front, 0, _pixelInfo.width * _pixelInfo.height); - *r = static_cast(std::min( - 255.0f, - std::max( - 0.0f, (-overExpose + static_cast(*r) * reduceColourNat * natLightR + envFog * fogR + addLightNatR)))); - *g = static_cast(std::min( - 255.0f, - std::max( - 0.0f, (-overExpose + static_cast(*g) * reduceColourNat * natLightG + envFog * fogG + addLightNatG)))); - *b = static_cast(std::min( - 255.0f, - std::max( - 0.0f, (-overExpose + static_cast(*b) * reduceColourNat * natLightB + envFog * fogB + addLightNatB)))); + _lightPolution_back = 0; - auto dstEntry = &gPalette_light[i]; - dstEntry->Red = static_cast( - std::min(0xFF, (static_cast(*r) * reduceColourLit * boost + lightFog) * elecMultR)); - dstEntry->Green = static_cast( - std::min(0xFF, (static_cast(*g) * reduceColourLit * boost + lightFog) * elecMultG)); - dstEntry->Blue = static_cast( - std::min(0xFF, (static_cast(*b) * reduceColourLit * boost + lightFog) * elecMultB)); - } -} + // LOG_WARNING("%i lights", LightListCurrentCountFront); -static uint8_t MixLight(uint32_t a, uint32_t b, uint32_t intensity) -{ - intensity = intensity * 6; - uint32_t bMul = (b * intensity) >> 8; - uint32_t ab = a + bMul; - uint8_t result = static_cast(std::min(255, ab)); - return result; -} - -void LightFXRenderToTexture( - void* dstPixels, uint32_t dstPitch, uint8_t* bits, uint32_t width, uint32_t height, const uint32_t* palette, - const uint32_t* lightPalette) -{ - LightFXUpdateViewportSettings(); - LightFXSwapBuffers(); - LightFXPrepareLightList(); - LightFXRenderLightsToFrontBuffer(); - - uint8_t* lightBits = static_cast(LightFXGetFrontBuffer()); - if (lightBits == nullptr) - { - return; - } - - for (uint32_t y = 0; y < height; y++) - { - uintptr_t dstOffset = static_cast(y * dstPitch); - uint32_t* dst = reinterpret_cast(reinterpret_cast(dstPixels) + dstOffset); - for (uint32_t x = 0; x < width; x++) + for (uint32_t light = 0; light < LightListCurrentCountFront; light++) { - uint8_t* src = &bits[y * width + x]; - uint32_t darkColour = palette[*src]; - uint32_t lightColour = lightPalette[*src]; - uint8_t lightIntensity = lightBits[y * width + x]; + const uint8_t* bufReadBase = nullptr; + uint8_t* bufWriteBase = static_cast(_light_rendered_buffer_front); + uint32_t bufReadWidth, bufReadHeight; + int32_t bufWriteX, bufWriteY; + int32_t bufWriteWidth, bufWriteHeight; + uint32_t bufReadSkip, bufWriteSkip; - uint32_t colour = 0; - if (lightIntensity == 0) + LightListEntry& entry = _LightListFront[light]; + + int32_t inRectCentreX = entry.viewCoords.x; + int32_t inRectCentreY = entry.viewCoords.y; + + if (entry.position.z != 0x7FFF) { - colour = darkColour; + inRectCentreX -= _current_view_x_front; + inRectCentreY -= _current_view_y_front; + inRectCentreX = _current_view_zoom_front.ApplyInversedTo(inRectCentreX); + inRectCentreY = _current_view_zoom_front.ApplyInversedTo(inRectCentreY); + } + + switch (entry.type) + { + case LightType::Lantern0: + bufReadWidth = 32; + bufReadHeight = 32; + bufReadBase = _bakedLightTexture_lantern_0; + break; + case LightType::Lantern1: + bufReadWidth = 64; + bufReadHeight = 64; + bufReadBase = _bakedLightTexture_lantern_1; + break; + case LightType::Lantern2: + bufReadWidth = 128; + bufReadHeight = 128; + bufReadBase = _bakedLightTexture_lantern_2; + break; + case LightType::Lantern3: + bufReadWidth = 256; + bufReadHeight = 256; + bufReadBase = _bakedLightTexture_lantern_3; + break; + case LightType::Spot0: + bufReadWidth = 32; + bufReadHeight = 32; + bufReadBase = _bakedLightTexture_spot_0; + break; + case LightType::Spot1: + bufReadWidth = 64; + bufReadHeight = 64; + bufReadBase = _bakedLightTexture_spot_1; + break; + case LightType::Spot2: + bufReadWidth = 128; + bufReadHeight = 128; + bufReadBase = _bakedLightTexture_spot_2; + break; + case LightType::Spot3: + bufReadWidth = 256; + bufReadHeight = 256; + bufReadBase = _bakedLightTexture_spot_3; + break; + default: + continue; + } + + // Clamp the reads to be no larger than the buffer size + bufReadHeight = std::min(_pixelInfo.height, bufReadHeight); + bufReadWidth = std::min(_pixelInfo.width, bufReadWidth); + + bufWriteX = inRectCentreX - bufReadWidth / 2; + bufWriteY = inRectCentreY - bufReadHeight / 2; + + bufWriteWidth = bufReadWidth; + bufWriteHeight = bufReadHeight; + + if (bufWriteX < 0) + { + bufReadBase += -bufWriteX; + bufWriteWidth += bufWriteX; } else { - colour |= MixLight((darkColour >> 0) & 0xFF, (lightColour >> 0) & 0xFF, lightIntensity); - colour |= MixLight((darkColour >> 8) & 0xFF, (lightColour >> 8) & 0xFF, lightIntensity) << 8; - colour |= MixLight((darkColour >> 16) & 0xFF, (lightColour >> 16) & 0xFF, lightIntensity) << 16; - colour |= MixLight((darkColour >> 24) & 0xFF, (lightColour >> 24) & 0xFF, lightIntensity) << 24; + bufWriteBase += bufWriteX; + } + + if (bufWriteWidth <= 0) + continue; + + if (bufWriteY < 0) + { + bufReadBase += -bufWriteY * bufReadWidth; + bufWriteHeight += bufWriteY; + } + else + { + bufWriteBase += bufWriteY * _pixelInfo.width; + } + + if (bufWriteHeight <= 0) + continue; + + int32_t rightEdge = bufWriteX + bufWriteWidth; + int32_t bottomEdge = bufWriteY + bufWriteHeight; + + if (rightEdge > _pixelInfo.width) + { + bufWriteWidth -= rightEdge - _pixelInfo.width; + } + if (bottomEdge > _pixelInfo.height) + { + bufWriteHeight -= bottomEdge - _pixelInfo.height; + } + + if (bufWriteWidth <= 0) + continue; + if (bufWriteHeight <= 0) + continue; + + _lightPolution_back += (bufWriteWidth * bufWriteHeight) / 256; + + bufReadSkip = bufReadWidth - bufWriteWidth; + bufWriteSkip = _pixelInfo.width - bufWriteWidth; + + if (entry.lightIntensity == 0xFF) + { + for (int32_t y = 0; y < bufWriteHeight; y++) + { + for (int32_t x = 0; x < bufWriteWidth; x++) + { + *bufWriteBase = std::min(0xFF, *bufWriteBase + *bufReadBase); + bufWriteBase++; + bufReadBase++; + } + + bufWriteBase += bufWriteSkip; + bufReadBase += bufReadSkip; + } + } + else + { + for (int32_t y = 0; y < bufWriteHeight; y++) + { + for (int32_t x = 0; x < bufWriteWidth; x++) + { + *bufWriteBase = std::min(0xFF, *bufWriteBase + (((*bufReadBase) * (1 + entry.lightIntensity)) >> 8)); + bufWriteBase++; + bufReadBase++; + } + + bufWriteBase += bufWriteSkip; + bufReadBase += bufReadSkip; + } } - *dst++ = colour; } } -} + + void* GetFrontBuffer() + { + return _light_rendered_buffer_front; + } + + const GamePalette& GetPalette() + { + return gPalette_light; + } + + static void Add3DLight( + const uint32_t lightHash, const Qualifier qualifier, const uint8_t id, const CoordsXYZ& loc, const LightType lightType) + { + if (LightListCurrentCountBack == 15999) + { + return; + } + + // LOG_WARNING("%i lights in back", LightListCurrentCountBack); + + for (uint32_t i = 0; i < LightListCurrentCountBack; i++) + { + LightListEntry& entry = _LightListBack[i]; + if (entry.lightHash != lightHash) + continue; + if (entry.qualifier != qualifier) + continue; + if (entry.lightID != id) + continue; + + entry.position = loc; + entry.viewCoords = Translate3DTo2DWithZ(GetCurrentRotation(), loc); + entry.type = lightType; + entry.lightIntensity = 0xFF; + entry.lightHash = lightHash; + entry.qualifier = qualifier; + entry.lightID = id; + entry.lightLinger = 1; + + return; + } + + LightListEntry* entry = &_LightListBack[LightListCurrentCountBack++]; + + entry->position = loc; + entry->viewCoords = Translate3DTo2DWithZ(GetCurrentRotation(), loc); + entry->type = lightType; + entry->lightIntensity = 0xFF; + entry->lightHash = lightHash; + entry->qualifier = qualifier; + entry->lightID = id; + entry->lightLinger = 1; + + // LOG_WARNING("new 3d light"); + } + + static void Add3DLight(const CoordsXYZ& loc, const LightType lightType) + { + Add3DLight(((loc.x << 16) | loc.y), Qualifier::Map, loc.z, loc, lightType); + } + + void Add3DLight(const EntityBase& entity, const uint8_t id, const CoordsXYZ& loc, const LightType lightType) + { + Add3DLight(entity.Id.ToUnderlying(), Qualifier::Entity, id, loc, lightType); + } + + void Add3DLightMagicFromDrawingTile( + const CoordsXY& mapPosition, int16_t offsetX, int16_t offsetY, int16_t offsetZ, LightType lightType) + { + int16_t x = mapPosition.x + offsetX + 16; + int16_t y = mapPosition.y + offsetY + 16; + + Add3DLight({ x, y, offsetZ }, lightType); + } + + uint32_t GetLightPolution() + { + return _lightPolution_front; + } + + static constexpr int16_t offsetLookup[] = { + 10, 10, 9, 8, 7, 6, 4, 2, 0, -2, -4, -6, -7, -8, -9, -10, -10, -10, -9, -8, -7, -6, -4, -2, 0, 2, 4, 6, 7, 8, 9, 10, + }; + void AddLightsMagicVehicle_ObservationTower(const Vehicle* vehicle) + { + Add3DLight(*vehicle, 0, { vehicle->x, vehicle->y + 16, vehicle->z }, LightType::Spot3); + Add3DLight(*vehicle, 1, { vehicle->x + 16, vehicle->y, vehicle->z }, LightType::Spot3); + Add3DLight(*vehicle, 2, { vehicle->x - 16, vehicle->y, vehicle->z }, LightType::Spot3); + Add3DLight(*vehicle, 3, { vehicle->x, vehicle->y - 16, vehicle->z }, LightType::Spot3); + } + + void AddLightsMagicVehicle_MineTrainCoaster(const Vehicle* vehicle) + { + if (vehicle == vehicle->TrainHead()) + { + int16_t place_x = vehicle->x - offsetLookup[(vehicle->Orientation + 0) % 32] * 2; + int16_t place_y = vehicle->y - offsetLookup[(vehicle->Orientation + 8) % 32] * 2; + Add3DLight(*vehicle, 0, { place_x, place_y, vehicle->z }, LightType::Spot3); + } + } + + void AddLightsMagicVehicle_ChairLift(const Vehicle* vehicle) + { + Add3DLight(*vehicle, 0, { vehicle->x, vehicle->y, vehicle->z - 16 }, LightType::Lantern2); + } + void AddLightsMagicVehicle_BoatHire(const Vehicle* vehicle) + { + Vehicle* vehicle_draw = vehicle->TrainHead(); + auto* nextVeh = GetEntity(vehicle_draw->next_vehicle_on_train); + if (nextVeh != nullptr) + { + vehicle_draw = nextVeh; + } + int16_t place_x = vehicle_draw->x; + int16_t place_y = vehicle_draw->y; + place_x -= offsetLookup[(vehicle_draw->Orientation + 0) % 32]; + place_y -= offsetLookup[(vehicle_draw->Orientation + 8) % 32]; + Add3DLight(*vehicle, 0, { place_x, place_y, vehicle_draw->z }, LightType::Spot2); + place_x -= offsetLookup[(vehicle_draw->Orientation + 0) % 32]; + place_y -= offsetLookup[(vehicle_draw->Orientation + 8) % 32]; + Add3DLight(*vehicle, 1, { place_x, place_y, vehicle_draw->z }, LightType::Spot2); + } + void AddLightsMagicVehicle_Monorail(const Vehicle* vehicle) + { + Add3DLight(*vehicle, 0, { vehicle->x, vehicle->y, vehicle->z + 12 }, LightType::Spot2); + int16_t place_x = vehicle->x; + int16_t place_y = vehicle->y; + if (vehicle == vehicle->TrainHead()) + { + place_x -= offsetLookup[(vehicle->Orientation + 0) % 32] * 2; + place_y -= offsetLookup[(vehicle->Orientation + 8) % 32] * 2; + Add3DLight(*vehicle, 1, { place_x, place_y, vehicle->z + 10 }, LightType::Lantern3); + place_x -= offsetLookup[(vehicle->Orientation + 0) % 32] * 3; + place_y -= offsetLookup[(vehicle->Orientation + 8) % 32] * 3; + Add3DLight(*vehicle, 2, { place_x, place_y, vehicle->z + 2 }, LightType::Lantern3); + } + if (vehicle == vehicle->TrainTail()) + { + place_x += offsetLookup[(vehicle->Orientation + 0) % 32] * 2; + place_y += offsetLookup[(vehicle->Orientation + 8) % 32] * 2; + Add3DLight(*vehicle, 3, { place_x, place_y, vehicle->z + 10 }, LightType::Lantern3); + place_x += offsetLookup[(vehicle->Orientation + 0) % 32] * 2; + place_y += offsetLookup[(vehicle->Orientation + 8) % 32] * 2; + Add3DLight(*vehicle, 4, { place_x, place_y, vehicle->z + 2 }, LightType::Lantern3); + } + } + void AddLightsMagicVehicle_MiniatureRailway(const Vehicle* vehicle) + { + if (vehicle == vehicle->TrainHead()) + { + int16_t place_x = vehicle->x - offsetLookup[(vehicle->Orientation + 0) % 32] * 2; + int16_t place_y = vehicle->y - offsetLookup[(vehicle->Orientation + 8) % 32] * 2; + Add3DLight(*vehicle, 1, { place_x, place_y, vehicle->z + 10 }, LightType::Lantern3); + place_x -= offsetLookup[(vehicle->Orientation + 0) % 32] * 2; + place_y -= offsetLookup[(vehicle->Orientation + 8) % 32] * 2; + Add3DLight(*vehicle, 2, { place_x, place_y, vehicle->z + 2 }, LightType::Lantern3); + } + else + { + Add3DLight(*vehicle, 0, { vehicle->x, vehicle->y, vehicle->z + 10 }, LightType::Lantern3); + } + } + + void AddLightsMagicVehicle(const Vehicle* vehicle) + { + auto ride = vehicle->GetRide(); + if (ride == nullptr) + return; + + const auto& rtd = GetRideTypeDescriptor(ride->type); + if (rtd.LightFXAddLightsMagicVehicle != nullptr) + rtd.LightFXAddLightsMagicVehicle(vehicle); + } + + void AddKioskLights(const CoordsXY& mapPosition, const int32_t height, const uint8_t zOffset) + { + uint8_t relativeRotation = (4 - GetCurrentRotation()) % 4; + CoordsXY lanternOffset1 = CoordsXY(0, 16).Rotate(relativeRotation); + CoordsXY lanternOffset2 = CoordsXY(16, 0).Rotate(relativeRotation); + Add3DLightMagicFromDrawingTile(mapPosition, lanternOffset1.x, lanternOffset1.y, height + zOffset, LightType::Lantern3); + Add3DLightMagicFromDrawingTile(mapPosition, lanternOffset2.x, lanternOffset2.y, height + zOffset, LightType::Lantern3); + Add3DLightMagicFromDrawingTile(mapPosition, 8, 32, height, LightType::Spot1); + Add3DLightMagicFromDrawingTile(mapPosition, 32, 8, height, LightType::Spot1); + Add3DLightMagicFromDrawingTile(mapPosition, -32, 8, height, LightType::Spot1); + Add3DLightMagicFromDrawingTile(mapPosition, 8, -32, height, LightType::Spot1); + Add3DLightMagicFromDrawingTile(mapPosition, -8, 32, height, LightType::Spot1); + Add3DLightMagicFromDrawingTile(mapPosition, 32, -8, height, LightType::Spot1); + Add3DLightMagicFromDrawingTile(mapPosition, -32, -8, height, LightType::Spot1); + Add3DLightMagicFromDrawingTile(mapPosition, -8, -32, height, LightType::Spot1); + } + + void AddShopLights(const CoordsXY& mapPosition, const uint8_t direction, const int32_t height, const uint8_t zOffset) + { + if (direction == (4 - GetCurrentRotation()) % 4) // Back Right Facing Stall + { + CoordsXY spotOffset1 = CoordsXY(-32, 8).Rotate(direction); + CoordsXY spotOffset2 = CoordsXY(-32, 4).Rotate(direction); + Add3DLightMagicFromDrawingTile(mapPosition, spotOffset1.x, spotOffset1.y, height, LightType::Spot1); + Add3DLightMagicFromDrawingTile(mapPosition, spotOffset2.x, spotOffset2.y, height, LightType::Spot2); + } + else if (direction == (7 - GetCurrentRotation()) % 4) // Back left Facing Stall + { + CoordsXY spotOffset1 = CoordsXY(-32, -8).Rotate(direction); + CoordsXY spotOffset2 = CoordsXY(-32, -4).Rotate(direction); + Add3DLightMagicFromDrawingTile(mapPosition, spotOffset1.x, spotOffset1.y, height, LightType::Spot1); + Add3DLightMagicFromDrawingTile(mapPosition, spotOffset2.x, spotOffset2.y, height, LightType::Spot2); + } + else // Forward Facing Stall + { + CoordsXY spotOffset1 = CoordsXY(-32, 8).Rotate(direction); + CoordsXY spotOffset2 = CoordsXY(-32, -8).Rotate(direction); + CoordsXY lanternOffset = CoordsXY(-16, 0).Rotate(direction); + Add3DLightMagicFromDrawingTile( + mapPosition, lanternOffset.x, lanternOffset.y, height + zOffset, LightType::Lantern3); + Add3DLightMagicFromDrawingTile(mapPosition, spotOffset1.x, spotOffset1.y, height, LightType::Spot1); + Add3DLightMagicFromDrawingTile(mapPosition, spotOffset2.x, spotOffset2.y, height, LightType::Spot1); + } + } + + void ApplyPaletteFilter(uint8_t i, uint8_t* r, uint8_t* g, uint8_t* b) + { + auto& gameState = GetGameState(); + + float night = static_cast(pow(gDayNightCycle, 1.5)); + + float natLightR = 1.0f; + float natLightG = 1.0f; + float natLightB = 1.0f; + + float elecMultR = 1.0f; + float elecMultG = 0.95f; + float elecMultB = 0.45f; + + static float wetness = 0.0f; + static float fogginess = 0.0f; + static float lightPolution = 0.0f; + + float sunLight = std::max(0.0f, std::min(1.0f, 2.0f - night * 3.0f)); + + // Night version + natLightR = FLerp(natLightR * 4.0f, 0.635f, (std::pow(night, 0.035f + sunLight * 10.50f))); + natLightG = FLerp(natLightG * 4.0f, 0.650f, (std::pow(night, 0.100f + sunLight * 5.50f))); + natLightB = FLerp(natLightB * 4.0f, 0.850f, (std::pow(night, 0.200f + sunLight * 1.5f))); + + float overExpose = 0.0f; + float lightAvg = (natLightR + natLightG + natLightB) / 3.0f; +#ifdef LIGHTFX_UNKNOWN_PART_2 + float lightMax = (natLightR + natLightG + natLightB) / 3.0f; +#endif // LIGHTFX_UNKNOWN_PART_2 + + // overExpose += ((lightMax - lightAvg) / lightMax) * 0.01f; + + if (gameState.ClimateCurrent.Temperature > 20) + { + float offset = (static_cast(gameState.ClimateCurrent.Temperature - 20)) * 0.04f; + offset *= 1.0f - night; + lightAvg /= 1.0f + offset; + // overExpose += offset * 0.1f; + } + +#ifdef LIGHTFX_UNKNOWN_PART_2 + lightAvg += (lightMax - lightAvg) * 0.6f; +#endif // LIGHTFX_UNKNOWN_PART_2 + + if (lightAvg > 1.0f) + { + natLightR /= lightAvg; + natLightG /= lightAvg; + natLightB /= lightAvg; + } + + natLightR *= 1.0f + overExpose; + natLightG *= 1.0f + overExpose; + natLightB *= 1.0f + overExpose; + overExpose *= 255.0f; + + float targetFogginess = static_cast(gameState.ClimateCurrent.Level) / 8.0f; + targetFogginess += (night * night) * 0.15f; + + if (gameState.ClimateCurrent.Temperature < 10) + { + targetFogginess += (static_cast(10 - gameState.ClimateCurrent.Temperature)) * 0.01f; + } + + fogginess -= (fogginess - targetFogginess) * 0.00001f; + + wetness *= 0.999995f; + wetness += fogginess * 0.001f; + wetness = std::min(wetness, 1.0f); + + float boost = 1.0f; + float envFog = fogginess; + float lightFog = envFog; + + float addLightNatR = 0.0f; + float addLightNatG = 0.0f; + float addLightNatB = 0.0f; + + float reduceColourNat = 1.0f; + float reduceColourLit = 1.0f; + + reduceColourLit *= night / static_cast(std::pow(std::max(1.01f, 0.4f + lightAvg), 2.0)); + + float targetLightPollution = reduceColourLit + * std::max(0.0f, 0.0f + 0.000001f * static_cast(GetLightPolution())); + lightPolution -= (lightPolution - targetLightPollution) * 0.001f; + + // lightPollution /= 1.0f + fogginess * 1.0f; + + natLightR /= 1.0f + lightPolution * 20.0f; + natLightG /= 1.0f + lightPolution * 20.0f; + natLightB /= 1.0f + lightPolution * 20.0f; + natLightR += elecMultR * 0.6f * lightPolution; + natLightG += elecMultG * 0.6f * lightPolution; + natLightB += elecMultB * 0.6f * lightPolution; + natLightR /= 1.0f + lightPolution; + natLightG /= 1.0f + lightPolution; + natLightB /= 1.0f + lightPolution; + + reduceColourLit += static_cast(gameState.ClimateCurrent.Level) / 2.0f; + + reduceColourNat /= 1.0f + fogginess; + reduceColourLit /= 1.0f + fogginess; + + lightFog *= reduceColourLit; + + reduceColourNat *= 1.0f - envFog; + reduceColourLit *= 1.0f - lightFog; + + float fogR = 35.5f * natLightR * 1.3f; + float fogG = 45.0f * natLightG * 1.3f; + float fogB = 50.0f * natLightB * 1.3f; + lightFog *= 10.0f; + + float wetnessBoost = 1.0f; // 1.0f + wetness * wetness * 0.1f; + + if (night >= 0 && gClimateLightningFlash != 1) + { + *r = Lerp(*r, SoftLight(*r, 8), night); + *g = Lerp(*g, SoftLight(*g, 8), night); + *b = Lerp(*b, SoftLight(*b, 128), night); + + // if (i == 32) + // boost = 300000.0f; + if ((i % 32) == 0) + boost = 1.01f * wetnessBoost; + else if ((i % 16) < 7) + boost = 1.001f * wetnessBoost; + if (i > 230 && i < 232) + boost = (static_cast(*b)) / 64.0f; + + if (false) + { + // This experiment shifts the colour of pixels as-if they are wet, but it is not a pretty solution at all + if ((i % 16)) + { + float iVal = (static_cast((i + 12) % 16)) / 16.0f; + float eff = (wetness * (static_cast(std::pow(iVal, 1.5)) * 0.85f)); + reduceColourNat *= 1.0f - eff; + addLightNatR += fogR * eff * 3.95f; + addLightNatG += fogR * eff * 3.95f; + addLightNatB += fogR * eff * 3.95f; + } + } + + addLightNatR *= 1.0f - envFog; + addLightNatG *= 1.0f - envFog; + addLightNatB *= 1.0f - envFog; + + *r = static_cast(std::min( + 255.0f, + std::max( + 0.0f, + (-overExpose + static_cast(*r) * reduceColourNat * natLightR + envFog * fogR + addLightNatR)))); + *g = static_cast(std::min( + 255.0f, + std::max( + 0.0f, + (-overExpose + static_cast(*g) * reduceColourNat * natLightG + envFog * fogG + addLightNatG)))); + *b = static_cast(std::min( + 255.0f, + std::max( + 0.0f, + (-overExpose + static_cast(*b) * reduceColourNat * natLightB + envFog * fogB + addLightNatB)))); + + auto dstEntry = &gPalette_light[i]; + dstEntry->Red = static_cast( + std::min(0xFF, (static_cast(*r) * reduceColourLit * boost + lightFog) * elecMultR)); + dstEntry->Green = static_cast( + std::min(0xFF, (static_cast(*g) * reduceColourLit * boost + lightFog) * elecMultG)); + dstEntry->Blue = static_cast( + std::min(0xFF, (static_cast(*b) * reduceColourLit * boost + lightFog) * elecMultB)); + } + } + + static uint8_t MixLight(uint32_t a, uint32_t b, uint32_t intensity) + { + intensity = intensity * 6; + uint32_t bMul = (b * intensity) >> 8; + uint32_t ab = a + bMul; + uint8_t result = static_cast(std::min(255, ab)); + return result; + } + + void RenderToTexture( + void* dstPixels, uint32_t dstPitch, uint8_t* bits, uint32_t width, uint32_t height, const uint32_t* palette, + const uint32_t* lightPalette) + { + UpdateViewportSettings(); + SwapBuffers(); + PrepareLightList(); + RenderLightsToFrontBuffer(); + + uint8_t* lightBits = static_cast(GetFrontBuffer()); + if (lightBits == nullptr) + { + return; + } + + for (uint32_t y = 0; y < height; y++) + { + uintptr_t dstOffset = static_cast(y * dstPitch); + uint32_t* dst = reinterpret_cast(reinterpret_cast(dstPixels) + dstOffset); + for (uint32_t x = 0; x < width; x++) + { + uint8_t* src = &bits[y * width + x]; + uint32_t darkColour = palette[*src]; + uint32_t lightColour = lightPalette[*src]; + uint8_t lightIntensity = lightBits[y * width + x]; + + uint32_t colour = 0; + if (lightIntensity == 0) + { + colour = darkColour; + } + else + { + colour |= MixLight((darkColour >> 0) & 0xFF, (lightColour >> 0) & 0xFF, lightIntensity); + colour |= MixLight((darkColour >> 8) & 0xFF, (lightColour >> 8) & 0xFF, lightIntensity) << 8; + colour |= MixLight((darkColour >> 16) & 0xFF, (lightColour >> 16) & 0xFF, lightIntensity) << 16; + colour |= MixLight((darkColour >> 24) & 0xFF, (lightColour >> 24) & 0xFF, lightIntensity) << 24; + } + *dst++ = colour; + } + } + } +} // namespace OpenRCT2::Drawing::LightFx diff --git a/src/openrct2/drawing/LightFX.h b/src/openrct2/drawing/LightFX.h index 1d42ff4729..50df03f642 100644 --- a/src/openrct2/drawing/LightFX.h +++ b/src/openrct2/drawing/LightFX.h @@ -19,65 +19,68 @@ struct DrawPixelInfo; struct CoordsXYZ; struct EntityBase; -enum class LightType : uint8_t +namespace OpenRCT2::Drawing::LightFx { - None = 0, + enum class LightType : uint8_t + { + None = 0, - Lantern0 = 4, - Lantern1 = 5, - Lantern2 = 6, - Lantern3 = 7, + Lantern0 = 4, + Lantern1 = 5, + Lantern2 = 6, + Lantern3 = 7, - Spot0 = 8, - Spot1 = 9, - Spot2 = 10, - Spot3 = 11, -}; + Spot0 = 8, + Spot1 = 9, + Spot2 = 10, + Spot3 = 11, + }; -constexpr uint8_t GetLightTypeSize(LightType type) -{ - return static_cast(type) & 0x3; -} -constexpr LightType SetLightTypeSize(LightType type, uint8_t size) -{ - return static_cast(((static_cast(type) & ~0x3) | size)); -} + constexpr uint8_t GetLightTypeSize(LightType type) + { + return static_cast(type) & 0x3; + } + constexpr LightType SetLightTypeSize(LightType type, uint8_t size) + { + return static_cast((static_cast(type) & ~0x3) | size); + } -void LightFXSetAvailable(bool available); -bool LightFXIsAvailable(); -bool LightFXForVehiclesIsAvailable(); + void SetAvailable(bool available); + bool IsAvailable(); + bool ForVehiclesIsAvailable(); -void LightFXInit(); + void Init(); -void LightFXUpdateBuffers(DrawPixelInfo&); + void UpdateBuffers(DrawPixelInfo&); -void LightFXPrepareLightList(); -void LightFXSwapBuffers(); -void LightFXRenderLightsToFrontBuffer(); -void LightFXUpdateViewportSettings(); + void PrepareLightList(); + void SwapBuffers(); + void RenderLightsToFrontBuffer(); + void UpdateViewportSettings(); -void* LightFXGetFrontBuffer(); -const OpenRCT2::Drawing::GamePalette& LightFXGetPalette(); + void* GetFrontBuffer(); + const GamePalette& GetPalette(); -void LightFXAdd3DLight(const EntityBase& entity, const uint8_t id, const CoordsXYZ& loc, const LightType lightType); + void Add3DLight(const EntityBase& entity, const uint8_t id, const CoordsXYZ& loc, const LightType lightType); -void LightFXAdd3DLightMagicFromDrawingTile( - const CoordsXY& mapPosition, int16_t offsetX, int16_t offsetY, int16_t offsetZ, LightType lightType); + void Add3DLightMagicFromDrawingTile( + const CoordsXY& mapPosition, int16_t offsetX, int16_t offsetY, int16_t offsetZ, LightType lightType); -void LightFXAddLightsMagicVehicle(const Vehicle* vehicle); -void LightFxAddLightsMagicVehicle_ObservationTower(const Vehicle* vehicle); -void LightFxAddLightsMagicVehicle_MineTrainCoaster(const Vehicle* vehicle); -void LightFxAddLightsMagicVehicle_ChairLift(const Vehicle* vehicle); -void LightFxAddLightsMagicVehicle_BoatHire(const Vehicle* vehicle); -void LightFxAddLightsMagicVehicle_Monorail(const Vehicle* vehicle); -void LightFxAddLightsMagicVehicle_MiniatureRailway(const Vehicle* vehicle); + void AddLightsMagicVehicle(const Vehicle* vehicle); + void AddLightsMagicVehicle_ObservationTower(const Vehicle* vehicle); + void AddLightsMagicVehicle_MineTrainCoaster(const Vehicle* vehicle); + void AddLightsMagicVehicle_ChairLift(const Vehicle* vehicle); + void AddLightsMagicVehicle_BoatHire(const Vehicle* vehicle); + void AddLightsMagicVehicle_Monorail(const Vehicle* vehicle); + void AddLightsMagicVehicle_MiniatureRailway(const Vehicle* vehicle); -void LightFxAddKioskLights(const CoordsXY& mapPosition, const int32_t height, const uint8_t zOffset); -void LightFxAddShopLights(const CoordsXY& mapPosition, const uint8_t direction, const int32_t height, const uint8_t zOffset); + void AddKioskLights(const CoordsXY& mapPosition, const int32_t height, const uint8_t zOffset); + void AddShopLights(const CoordsXY& mapPosition, const uint8_t direction, const int32_t height, const uint8_t zOffset); -uint32_t LightFXGetLightPolution(); + uint32_t GetLightPolution(); -void LightFXApplyPaletteFilter(uint8_t i, uint8_t* r, uint8_t* g, uint8_t* b); -void LightFXRenderToTexture( - void* dstPixels, uint32_t dstPitch, uint8_t* bits, uint32_t width, uint32_t height, const uint32_t* palette, - const uint32_t* lightPalette); + void ApplyPaletteFilter(uint8_t i, uint8_t* r, uint8_t* g, uint8_t* b); + void RenderToTexture( + void* dstPixels, uint32_t dstPitch, uint8_t* bits, uint32_t width, uint32_t height, const uint32_t* palette, + const uint32_t* lightPalette); +} // namespace OpenRCT2::Drawing::LightFx diff --git a/src/openrct2/drawing/X8DrawingEngine.cpp b/src/openrct2/drawing/X8DrawingEngine.cpp index 0e27671018..d74f74e8d9 100644 --- a/src/openrct2/drawing/X8DrawingEngine.cpp +++ b/src/openrct2/drawing/X8DrawingEngine.cpp @@ -120,7 +120,7 @@ X8DrawingEngine::X8DrawingEngine([[maybe_unused]] const std::shared_ptr()) { @@ -2872,7 +2875,7 @@ void Peep::Paint(PaintSession& session, int32_t imageDirection) const return; } - LightFXAdd3DLight(*this, 0, loc, LightType::Spot1); + LightFx::Add3DLight(*this, 0, loc, LightType::Spot1); } } diff --git a/src/openrct2/paint/Paint.Entity.cpp b/src/openrct2/paint/Paint.Entity.cpp index aa5b3d7cfa..2e70325db7 100644 --- a/src/openrct2/paint/Paint.Entity.cpp +++ b/src/openrct2/paint/Paint.Entity.cpp @@ -32,6 +32,8 @@ #include +using namespace OpenRCT2::Drawing; + /** * Paint Quadrant * rct2: 0x0069E8B0 @@ -124,9 +126,9 @@ void EntityPaintSetup(PaintSession& session, const CoordsXY& pos) { case EntityType::Vehicle: spr->As()->Paint(session, image_direction); - if (LightFXForVehiclesIsAvailable()) + if (LightFx::ForVehiclesIsAvailable()) { - LightFXAddLightsMagicVehicle(spr->As()); + LightFx::AddLightsMagicVehicle(spr->As()); } break; case EntityType::Guest: diff --git a/src/openrct2/paint/tile_element/Paint.Entrance.cpp b/src/openrct2/paint/tile_element/Paint.Entrance.cpp index 4968e61b9a..86d2059623 100644 --- a/src/openrct2/paint/tile_element/Paint.Entrance.cpp +++ b/src/openrct2/paint/tile_element/Paint.Entrance.cpp @@ -35,6 +35,9 @@ #include "Segment.h" using namespace OpenRCT2; +using namespace OpenRCT2::Drawing; + +using OpenRCT2::Drawing::LightFx::LightType; static void PaintRideEntranceExitScrollingText( PaintSession& session, const EntranceElement& entranceEl, const StationObject& stationObj, Direction direction, @@ -84,26 +87,26 @@ static void PaintRideEntranceExitLightEffects(PaintSession& session, int32_t hei { PROFILED_FUNCTION(); - if (LightFXIsAvailable()) + if (LightFx::IsAvailable()) { if (entranceEl.GetEntranceType() == ENTRANCE_TYPE_RIDE_ENTRANCE) { - LightFXAdd3DLightMagicFromDrawingTile(session.MapPosition, 0, 0, height + 45, LightType::Lantern3); + LightFx::Add3DLightMagicFromDrawingTile(session.MapPosition, 0, 0, height + 45, LightType::Lantern3); } switch (entranceEl.GetDirection()) { case 0: - LightFXAdd3DLightMagicFromDrawingTile(session.MapPosition, 16, 0, height + 16, LightType::Lantern2); + LightFx::Add3DLightMagicFromDrawingTile(session.MapPosition, 16, 0, height + 16, LightType::Lantern2); break; case 1: - LightFXAdd3DLightMagicFromDrawingTile(session.MapPosition, 0, -16, height + 16, LightType::Lantern2); + LightFx::Add3DLightMagicFromDrawingTile(session.MapPosition, 0, -16, height + 16, LightType::Lantern2); break; case 2: - LightFXAdd3DLightMagicFromDrawingTile(session.MapPosition, -16, 0, height + 16, LightType::Lantern2); + LightFx::Add3DLightMagicFromDrawingTile(session.MapPosition, -16, 0, height + 16, LightType::Lantern2); break; case 3: - LightFXAdd3DLightMagicFromDrawingTile(session.MapPosition, 0, 16, height + 16, LightType::Lantern2); + LightFx::Add3DLightMagicFromDrawingTile(session.MapPosition, 0, 16, height + 16, LightType::Lantern2); break; } } @@ -258,9 +261,9 @@ static void PaintParkEntranceLightEffects(PaintSession& session) { PROFILED_FUNCTION(); - if (LightFXIsAvailable()) + if (LightFx::IsAvailable()) { - LightFXAdd3DLightMagicFromDrawingTile(session.MapPosition, 0, 0, 155, LightType::Lantern3); + LightFx::Add3DLightMagicFromDrawingTile(session.MapPosition, 0, 0, 155, LightType::Lantern3); } } diff --git a/src/openrct2/paint/tile_element/Paint.PathAddition.cpp b/src/openrct2/paint/tile_element/Paint.PathAddition.cpp index 7578140bc6..f5d9f13e9e 100644 --- a/src/openrct2/paint/tile_element/Paint.PathAddition.cpp +++ b/src/openrct2/paint/tile_element/Paint.PathAddition.cpp @@ -18,6 +18,9 @@ #include "Paint.TileElement.h" using namespace OpenRCT2; +using namespace OpenRCT2::Drawing; + +using OpenRCT2::Drawing::LightFx::LightType; static ImageIndex GetEdgeImageOffset(edge_t edge) { @@ -270,7 +273,7 @@ void PaintLampLightEffects(PaintSession& session, const PathElement& pathEl, uin { PROFILED_FUNCTION(); - if (LightFXIsAvailable()) + if (LightFx::IsAvailable()) { if (pathEl.HasAddition() && !(pathEl.IsBroken())) { @@ -279,19 +282,19 @@ void PaintLampLightEffects(PaintSession& session, const PathElement& pathEl, uin { if (!(pathEl.GetEdges() & EDGE_NE)) { - LightFXAdd3DLightMagicFromDrawingTile(session.MapPosition, -16, 0, height + 23, LightType::Lantern3); + LightFx::Add3DLightMagicFromDrawingTile(session.MapPosition, -16, 0, height + 23, LightType::Lantern3); } if (!(pathEl.GetEdges() & EDGE_SE)) { - LightFXAdd3DLightMagicFromDrawingTile(session.MapPosition, 0, 16, height + 23, LightType::Lantern3); + LightFx::Add3DLightMagicFromDrawingTile(session.MapPosition, 0, 16, height + 23, LightType::Lantern3); } if (!(pathEl.GetEdges() & EDGE_SW)) { - LightFXAdd3DLightMagicFromDrawingTile(session.MapPosition, 16, 0, height + 23, LightType::Lantern3); + LightFx::Add3DLightMagicFromDrawingTile(session.MapPosition, 16, 0, height + 23, LightType::Lantern3); } if (!(pathEl.GetEdges() & EDGE_NW)) { - LightFXAdd3DLightMagicFromDrawingTile(session.MapPosition, 0, -16, height + 23, LightType::Lantern3); + LightFx::Add3DLightMagicFromDrawingTile(session.MapPosition, 0, -16, height + 23, LightType::Lantern3); } } } diff --git a/src/openrct2/ride/TrackPaint.cpp b/src/openrct2/ride/TrackPaint.cpp index e2cd280d7b..09bb7b9c76 100644 --- a/src/openrct2/ride/TrackPaint.cpp +++ b/src/openrct2/ride/TrackPaint.cpp @@ -37,6 +37,7 @@ #include "TrackStyle.h" using namespace OpenRCT2; +using namespace OpenRCT2::Drawing; using namespace OpenRCT2::TrackMetaData; /* rct2: 0x007667AC */ @@ -1969,7 +1970,7 @@ void PaintTrack(PaintSession& session, Direction direction, int32_t height, cons } } - if (LightFXIsAvailable()) + if (LightFx::IsAvailable()) { uint8_t zOffset = 16; const auto& rtd = ride->GetRideTypeDescriptor(); @@ -1979,9 +1980,9 @@ void PaintTrack(PaintSession& session, Direction direction, int32_t height, cons const auto* originElement = ride->GetOriginElement(StationIndex::FromUnderlying(0)); if (originElement != nullptr && originElement->GetTrackType() == TrackElemType::FlatTrack1x1B) - LightFxAddKioskLights(session.MapPosition, height, zOffset); + LightFx::AddKioskLights(session.MapPosition, height, zOffset); else if (RideTypeDescriptors[ride->type].HasFlag(RtdFlag::isShopOrFacility)) - LightFxAddShopLights(session.MapPosition, trackElement.GetDirection(), height, zOffset); + LightFx::AddShopLights(session.MapPosition, trackElement.GetDirection(), height, zOffset); } session.InteractionType = ViewportInteractionItem::Ride; diff --git a/src/openrct2/ride/rtd/coaster/MineTrainCoaster.h b/src/openrct2/ride/rtd/coaster/MineTrainCoaster.h index 388053125f..0fd90078d2 100644 --- a/src/openrct2/ride/rtd/coaster/MineTrainCoaster.h +++ b/src/openrct2/ride/rtd/coaster/MineTrainCoaster.h @@ -82,6 +82,6 @@ constexpr RideTypeDescriptor MineTrainCoasterRTD = }, }, .UpdateRotating = UpdateRotatingDefault, - .LightFXAddLightsMagicVehicle = LightFxAddLightsMagicVehicle_MineTrainCoaster, + .LightFXAddLightsMagicVehicle = OpenRCT2::Drawing::LightFx::AddLightsMagicVehicle_MineTrainCoaster, }; // clang-format on diff --git a/src/openrct2/ride/rtd/coaster/WaterCoaster.h b/src/openrct2/ride/rtd/coaster/WaterCoaster.h index 4039bccdfa..5fa266c2cc 100644 --- a/src/openrct2/ride/rtd/coaster/WaterCoaster.h +++ b/src/openrct2/ride/rtd/coaster/WaterCoaster.h @@ -97,7 +97,7 @@ constexpr RideTypeDescriptor WaterCoasterRTD = }, }, .UpdateRotating = UpdateRotatingDefault, - .LightFXAddLightsMagicVehicle = LightFxAddLightsMagicVehicle_BoatHire, + .LightFXAddLightsMagicVehicle = OpenRCT2::Drawing::LightFx::AddLightsMagicVehicle_BoatHire, .StartRideMusic = OpenRCT2::RideAudio::DefaultStartRideMusicChannel, .DesignCreateMode = TrackDesignCreateMode::Default, .MusicUpdateFunction = DefaultMusicUpdate, diff --git a/src/openrct2/ride/rtd/gentle/CarRide.h b/src/openrct2/ride/rtd/gentle/CarRide.h index e7e4749734..27a10db3e3 100644 --- a/src/openrct2/ride/rtd/gentle/CarRide.h +++ b/src/openrct2/ride/rtd/gentle/CarRide.h @@ -85,6 +85,6 @@ constexpr RideTypeDescriptor CarRideRTD = }, }, .UpdateRotating = UpdateRotatingDefault, - .LightFXAddLightsMagicVehicle = LightFxAddLightsMagicVehicle_BoatHire, + .LightFXAddLightsMagicVehicle = OpenRCT2::Drawing::LightFx::AddLightsMagicVehicle_BoatHire, }; // clang-format on diff --git a/src/openrct2/ride/rtd/gentle/Dodgems.h b/src/openrct2/ride/rtd/gentle/Dodgems.h index e1318ce19e..b4d7d1434b 100644 --- a/src/openrct2/ride/rtd/gentle/Dodgems.h +++ b/src/openrct2/ride/rtd/gentle/Dodgems.h @@ -72,6 +72,6 @@ constexpr RideTypeDescriptor DodgemsRTD = }, }, .UpdateRotating = UpdateRotatingDefault, - .LightFXAddLightsMagicVehicle = LightFxAddLightsMagicVehicle_BoatHire, + .LightFXAddLightsMagicVehicle = OpenRCT2::Drawing::LightFx::AddLightsMagicVehicle_BoatHire, }; // clang-format on diff --git a/src/openrct2/ride/rtd/gentle/GhostTrain.h b/src/openrct2/ride/rtd/gentle/GhostTrain.h index 4beb5896f8..b024d31f48 100644 --- a/src/openrct2/ride/rtd/gentle/GhostTrain.h +++ b/src/openrct2/ride/rtd/gentle/GhostTrain.h @@ -80,7 +80,7 @@ constexpr RideTypeDescriptor GhostTrainRTD = }, }, .UpdateRotating = UpdateRotatingDefault, - .LightFXAddLightsMagicVehicle = LightFxAddLightsMagicVehicle_MineTrainCoaster, + .LightFXAddLightsMagicVehicle = OpenRCT2::Drawing::LightFx::AddLightsMagicVehicle_MineTrainCoaster, .StartRideMusic = OpenRCT2::RideAudio::DefaultStartRideMusicChannel, .DesignCreateMode = TrackDesignCreateMode::Default, .MusicUpdateFunction = DefaultMusicUpdate, diff --git a/src/openrct2/ride/rtd/gentle/MiniHelicopters.h b/src/openrct2/ride/rtd/gentle/MiniHelicopters.h index 3e88af0a14..1c8874dbb6 100644 --- a/src/openrct2/ride/rtd/gentle/MiniHelicopters.h +++ b/src/openrct2/ride/rtd/gentle/MiniHelicopters.h @@ -81,6 +81,6 @@ constexpr RideTypeDescriptor MiniHelicoptersRTD = }, }, .UpdateRotating = UpdateRotatingDefault, - .LightFXAddLightsMagicVehicle = LightFxAddLightsMagicVehicle_BoatHire, + .LightFXAddLightsMagicVehicle = OpenRCT2::Drawing::LightFx::AddLightsMagicVehicle_BoatHire, }; // clang-format on diff --git a/src/openrct2/ride/rtd/gentle/MonorailCycles.h b/src/openrct2/ride/rtd/gentle/MonorailCycles.h index 4620f092d2..77a72df846 100644 --- a/src/openrct2/ride/rtd/gentle/MonorailCycles.h +++ b/src/openrct2/ride/rtd/gentle/MonorailCycles.h @@ -77,6 +77,6 @@ constexpr RideTypeDescriptor MonorailCyclesRTD = }, }, .UpdateRotating = UpdateRotatingDefault, - .LightFXAddLightsMagicVehicle = LightFxAddLightsMagicVehicle_BoatHire, + .LightFXAddLightsMagicVehicle = OpenRCT2::Drawing::LightFx::AddLightsMagicVehicle_BoatHire, }; // clang-format on diff --git a/src/openrct2/ride/rtd/gentle/MonsterTrucks.h b/src/openrct2/ride/rtd/gentle/MonsterTrucks.h index 7c10c41910..6c343ab2ff 100644 --- a/src/openrct2/ride/rtd/gentle/MonsterTrucks.h +++ b/src/openrct2/ride/rtd/gentle/MonsterTrucks.h @@ -80,6 +80,6 @@ constexpr RideTypeDescriptor MonsterTrucksRTD = }, }, .UpdateRotating = UpdateRotatingDefault, - .LightFXAddLightsMagicVehicle = LightFxAddLightsMagicVehicle_BoatHire, + .LightFXAddLightsMagicVehicle = OpenRCT2::Drawing::LightFx::AddLightsMagicVehicle_BoatHire, }; // clang-format on diff --git a/src/openrct2/ride/rtd/gentle/ObservationTower.h b/src/openrct2/ride/rtd/gentle/ObservationTower.h index aceae80fcc..733972d897 100644 --- a/src/openrct2/ride/rtd/gentle/ObservationTower.h +++ b/src/openrct2/ride/rtd/gentle/ObservationTower.h @@ -68,6 +68,6 @@ constexpr RideTypeDescriptor ObservationTowerRTD = }, }, .UpdateRotating = UpdateRotatingDefault, - .LightFXAddLightsMagicVehicle = LightFxAddLightsMagicVehicle_ObservationTower, + .LightFXAddLightsMagicVehicle = OpenRCT2::Drawing::LightFx::AddLightsMagicVehicle_ObservationTower, }; // clang-format on diff --git a/src/openrct2/ride/rtd/thrill/GoKarts.h b/src/openrct2/ride/rtd/thrill/GoKarts.h index 69e9c2c963..97149d4b5b 100644 --- a/src/openrct2/ride/rtd/thrill/GoKarts.h +++ b/src/openrct2/ride/rtd/thrill/GoKarts.h @@ -74,6 +74,6 @@ constexpr RideTypeDescriptor GoKartsRTD = }, }, .UpdateRotating = UpdateRotatingDefault, - .LightFXAddLightsMagicVehicle = LightFxAddLightsMagicVehicle_BoatHire, + .LightFXAddLightsMagicVehicle = OpenRCT2::Drawing::LightFx::AddLightsMagicVehicle_BoatHire, }; // clang-format on diff --git a/src/openrct2/ride/rtd/transport/Chairlift.h b/src/openrct2/ride/rtd/transport/Chairlift.h index 29decac63b..64be1e7a1d 100644 --- a/src/openrct2/ride/rtd/transport/Chairlift.h +++ b/src/openrct2/ride/rtd/transport/Chairlift.h @@ -79,7 +79,7 @@ constexpr RideTypeDescriptor ChairliftRTD = }, }, .UpdateRotating = UpdateRotatingDefault, - .LightFXAddLightsMagicVehicle = LightFxAddLightsMagicVehicle_ChairLift, + .LightFXAddLightsMagicVehicle = OpenRCT2::Drawing::LightFx::AddLightsMagicVehicle_ChairLift, .StartRideMusic = OpenRCT2::RideAudio::DefaultStartRideMusicChannel, .DesignCreateMode = TrackDesignCreateMode::Default, .MusicUpdateFunction = DefaultMusicUpdate, diff --git a/src/openrct2/ride/rtd/transport/MiniatureRailway.h b/src/openrct2/ride/rtd/transport/MiniatureRailway.h index eaebd64aa1..8a7170dbbc 100644 --- a/src/openrct2/ride/rtd/transport/MiniatureRailway.h +++ b/src/openrct2/ride/rtd/transport/MiniatureRailway.h @@ -76,6 +76,6 @@ constexpr RideTypeDescriptor MiniatureRailwayRTD = }, }, .UpdateRotating = UpdateRotatingDefault, - .LightFXAddLightsMagicVehicle = LightFxAddLightsMagicVehicle_MiniatureRailway, + .LightFXAddLightsMagicVehicle = OpenRCT2::Drawing::LightFx::AddLightsMagicVehicle_MiniatureRailway, }; // clang-format on diff --git a/src/openrct2/ride/rtd/transport/Monorail.h b/src/openrct2/ride/rtd/transport/Monorail.h index cbe3d8917f..f43e289ab9 100644 --- a/src/openrct2/ride/rtd/transport/Monorail.h +++ b/src/openrct2/ride/rtd/transport/Monorail.h @@ -79,6 +79,6 @@ constexpr RideTypeDescriptor MonorailRTD = }, }, .UpdateRotating = UpdateRotatingDefault, - .LightFXAddLightsMagicVehicle = LightFxAddLightsMagicVehicle_Monorail, + .LightFXAddLightsMagicVehicle = OpenRCT2::Drawing::LightFx::AddLightsMagicVehicle_Monorail, }; // clang-format on diff --git a/src/openrct2/ride/rtd/water/BoatHire.h b/src/openrct2/ride/rtd/water/BoatHire.h index 194e4d9949..945ffe8c74 100644 --- a/src/openrct2/ride/rtd/water/BoatHire.h +++ b/src/openrct2/ride/rtd/water/BoatHire.h @@ -73,6 +73,6 @@ constexpr RideTypeDescriptor BoatHireRTD = }, }, .UpdateRotating = UpdateRotatingDefault, - .LightFXAddLightsMagicVehicle = LightFxAddLightsMagicVehicle_BoatHire, + .LightFXAddLightsMagicVehicle = OpenRCT2::Drawing::LightFx::AddLightsMagicVehicle_BoatHire, }; // clang-format on diff --git a/src/openrct2/ride/rtd/water/SplashBoats.h b/src/openrct2/ride/rtd/water/SplashBoats.h index 0733427f90..8c33d02a2b 100644 --- a/src/openrct2/ride/rtd/water/SplashBoats.h +++ b/src/openrct2/ride/rtd/water/SplashBoats.h @@ -76,6 +76,6 @@ constexpr RideTypeDescriptor SplashBoatsRTD = }, }, .UpdateRotating = UpdateRotatingDefault, - .LightFXAddLightsMagicVehicle = LightFxAddLightsMagicVehicle_BoatHire, + .LightFXAddLightsMagicVehicle = OpenRCT2::Drawing::LightFx::AddLightsMagicVehicle_BoatHire, }; // clang-format on diff --git a/src/openrct2/ride/rtd/water/SubmarineRide.h b/src/openrct2/ride/rtd/water/SubmarineRide.h index 916025c1e8..f588d5f697 100644 --- a/src/openrct2/ride/rtd/water/SubmarineRide.h +++ b/src/openrct2/ride/rtd/water/SubmarineRide.h @@ -67,6 +67,6 @@ constexpr RideTypeDescriptor SubmarineRideRTD = }, }, .UpdateRotating = UpdateRotatingDefault, - .LightFXAddLightsMagicVehicle = LightFxAddLightsMagicVehicle_BoatHire, + .LightFXAddLightsMagicVehicle = OpenRCT2::Drawing::LightFx::AddLightsMagicVehicle_BoatHire, }; // clang-format on