diff --git a/Source/engine/lighting_defs.hpp b/Source/engine/lighting_defs.hpp index b775d7f12..458c4be83 100644 --- a/Source/engine/lighting_defs.hpp +++ b/Source/engine/lighting_defs.hpp @@ -10,6 +10,9 @@ namespace devilution { constexpr char LightsMax = 15; +/** @brief A light table maps palette indices, so its size is the same as the palette size. */ +constexpr size_t LightTableSize = 256; + /** @brief Number of supported light levels */ constexpr size_t NumLightingLevels = LightsMax + 1; diff --git a/Source/engine/render/light_render.cpp b/Source/engine/render/light_render.cpp index 5be47c807..6bf7919b1 100644 --- a/Source/engine/render/light_render.cpp +++ b/Source/engine/render/light_render.cpp @@ -491,27 +491,26 @@ void BuildLightmap(Point tilePosition, Point targetBufferPosition, uint16_t view Lightmap::Lightmap(const uint8_t *outBuffer, uint16_t outPitch, std::span lightmapBuffer, uint16_t lightmapPitch, - const uint8_t *lightTables, size_t lightTableSize) + std::span, NumLightingLevels> lightTables) : outBuffer(outBuffer) , outPitch(outPitch) , lightmapBuffer(lightmapBuffer) , lightmapPitch(lightmapPitch) , lightTables(lightTables) - , lightTableSize(lightTableSize) { } Lightmap Lightmap::build(bool perPixelLighting, Point tilePosition, Point targetBufferPosition, int viewportWidth, int viewportHeight, int rows, int columns, const uint8_t *outBuffer, uint16_t outPitch, - const uint8_t *lightTables, size_t lightTableSize, + std::span, NumLightingLevels> lightTables, const uint8_t tileLights[MAXDUNX][MAXDUNY], uint_fast8_t microTileLen) { if (perPixelLighting) { BuildLightmap(tilePosition, targetBufferPosition, viewportWidth, viewportHeight, rows, columns, tileLights, microTileLen); } - return Lightmap(outBuffer, outPitch, LightmapBuffer, viewportWidth, lightTables, lightTableSize); + return Lightmap(outBuffer, outPitch, LightmapBuffer, viewportWidth, lightTables); } Lightmap Lightmap::bleedUp(bool perPixelLighting, const Lightmap &source, Point targetBufferPosition, std::span lightmapBuffer) @@ -566,7 +565,7 @@ Lightmap Lightmap::bleedUp(bool perPixelLighting, const Lightmap &source, Point return Lightmap(outBuffer, source.outPitch, lightmapBuffer, lightmapPitch, - source.lightTables, source.lightTableSize); + source.lightTables); } } // namespace devilution diff --git a/Source/engine/render/light_render.hpp b/Source/engine/render/light_render.hpp index aabc0b8da..45d064a49 100644 --- a/Source/engine/render/light_render.hpp +++ b/Source/engine/render/light_render.hpp @@ -1,9 +1,11 @@ #pragma once +#include #include #include #include +#include "engine/lighting_defs.hpp" #include "engine/point.hpp" #include "levels/gendung_defs.hpp" @@ -11,19 +13,18 @@ namespace devilution { class Lightmap { public: - explicit Lightmap(const uint8_t *outBuffer, std::span lightmapBuffer, uint16_t pitch, const uint8_t *lightTables, size_t lightTableSize) - : Lightmap(outBuffer, pitch, lightmapBuffer, pitch, lightTables, lightTableSize) + explicit Lightmap(const uint8_t *outBuffer, std::span lightmapBuffer, uint16_t pitch, std::span, NumLightingLevels> lightTables) + : Lightmap(outBuffer, pitch, lightmapBuffer, pitch, lightTables) { } explicit Lightmap(const uint8_t *outBuffer, uint16_t outPitch, std::span lightmapBuffer, uint16_t lightmapPitch, - const uint8_t *lightTables, size_t lightTableSize); + std::span, NumLightingLevels> lightTables); - uint8_t adjustColor(uint8_t color, uint8_t lightLevel) const + [[nodiscard]] uint8_t adjustColor(uint8_t color, uint8_t lightLevel) const { - size_t offset = lightLevel * lightTableSize + color; - return lightTables[offset]; + return lightTables[lightLevel][color]; } const uint8_t *getLightingAt(const uint8_t *outLoc) const @@ -45,7 +46,7 @@ public: static Lightmap build(bool perPixelLighting, Point tilePosition, Point targetBufferPosition, int viewportWidth, int viewportHeight, int rows, int columns, const uint8_t *outBuffer, uint16_t outPitch, - const uint8_t *lightTables, size_t lightTableSize, + std::span, NumLightingLevels> lightTables, const uint8_t tileLights[MAXDUNX][MAXDUNY], uint_fast8_t microTileLen); @@ -58,8 +59,7 @@ private: std::span lightmapBuffer; const uint16_t lightmapPitch; - const uint8_t *lightTables; - const size_t lightTableSize; + std::span, NumLightingLevels> lightTables; }; } // namespace devilution diff --git a/Source/engine/render/scrollrt.cpp b/Source/engine/render/scrollrt.cpp index 542187d5c..04d5870da 100644 --- a/Source/engine/render/scrollrt.cpp +++ b/Source/engine/render/scrollrt.cpp @@ -1133,7 +1133,7 @@ void DrawGame(const Surface &fullOut, Point position, Displacement offset) Lightmap lightmap = Lightmap::build(*GetOptions().Graphics.perPixelLighting, position, Point {} + offset, gnScreenWidth, gnViewportHeight, rows, columns, - out.at(0, 0), out.pitch(), LightTables[0].data(), LightTables[0].size(), + out.at(0, 0), out.pitch(), LightTables, dLight, MicroTileLen); DrawFloor(out, lightmap, position, Point {} + offset, rows, columns); diff --git a/Source/lighting.cpp b/Source/lighting.cpp index b1195fb2e..34a8e1ae4 100644 --- a/Source/lighting.cpp +++ b/Source/lighting.cpp @@ -15,6 +15,7 @@ #include "automap.h" #include "engine/displacement.hpp" +#include "engine/lighting_defs.hpp" #include "engine/load_file.hpp" #include "engine/point.hpp" #include "engine/points_in_rectangle_range.hpp" @@ -34,7 +35,7 @@ Light VisionList[MAXVISION]; Light Lights[MAXLIGHTS]; std::array ActiveLights; int ActiveLightCount; -std::array, NumLightingLevels> LightTables; +std::array, NumLightingLevels> LightTables; uint8_t *FullyLitLightTable = nullptr; uint8_t *FullyDarkLightTable = nullptr; std::array InfravisionTable; diff --git a/Source/lighting.h b/Source/lighting.h index d38d8d408..625d3537f 100644 --- a/Source/lighting.h +++ b/Source/lighting.h @@ -40,7 +40,7 @@ extern std::array VisionActive; extern Light Lights[MAXLIGHTS]; extern std::array ActiveLights; extern int ActiveLightCount; -extern DVL_API_FOR_TEST std::array, NumLightingLevels> LightTables; +extern DVL_API_FOR_TEST std::array, NumLightingLevels> LightTables; /** @brief Contains a pointer to a light table that is fully lit (no color mapping is required). Can be null in hell. */ extern DVL_API_FOR_TEST uint8_t *FullyLitLightTable; /** @brief Contains a pointer to a light table that is fully dark (every color result to 0/black). Can be null in hellfire levels. */ diff --git a/test/dun_render_benchmark.cpp b/test/dun_render_benchmark.cpp index 0d3249ae9..e2867ab6e 100644 --- a/test/dun_render_benchmark.cpp +++ b/test/dun_render_benchmark.cpp @@ -1,4 +1,6 @@ +#include #include +#include #include #include @@ -8,6 +10,7 @@ #include "engine/assets.hpp" #include "engine/clx_sprite.hpp" #include "engine/displacement.hpp" +#include "engine/lighting_defs.hpp" #include "engine/load_file.hpp" #include "engine/render/dun_render.hpp" #include "engine/surface.hpp" @@ -66,7 +69,8 @@ void InitOnce() void RunForTileMaskLight(benchmark::State &state, TileType tileType, MaskType maskType, const uint8_t *lightTable) { Surface out = Surface(SdlSurface.get()); - Lightmap lightmap(nullptr, {}, 1, nullptr, 0); + std::array, NumLightingLevels> lightTables; + Lightmap lightmap(/*outBuffer=*/nullptr, /*lightmapBuffer=*/ {}, /*pitch=*/1, lightTables); const std::span tiles = Tiles[tileType]; for (auto _ : state) { for (const LevelCelBlock &levelCelBlock : tiles) { diff --git a/test/light_render_benchmark.cpp b/test/light_render_benchmark.cpp index 4d0df0b9e..c7f669596 100644 --- a/test/light_render_benchmark.cpp +++ b/test/light_render_benchmark.cpp @@ -20,7 +20,7 @@ void BM_BuildLightmap(benchmark::State &state) const std::string benchmarkDataPath = paths::BasePath() + "test/fixtures/light_render_benchmark/dLight.dmp"; FILE *lightFile = std::fopen(benchmarkDataPath.c_str(), "rb"); uint8_t dLight[MAXDUNX][MAXDUNY]; - std::array, LightsMax> lightTables; + std::array, NumLightingLevels> lightTables; if (lightFile != nullptr) { if (std::fread(&dLight[0][0], sizeof(uint8_t) * MAXDUNX * MAXDUNY, 1, lightFile) != 1) { std::perror("Failed to read dLight.dmp"); @@ -50,7 +50,7 @@ void BM_BuildLightmap(benchmark::State &state) Lightmap lightmap = Lightmap::build(/*perPixelLighting=*/true, tilePosition, targetBufferPosition, viewportWidth, viewportHeight, rows, columns, - outBuffer, outPitch, lightTables[0].data(), lightTables[0].size(), + outBuffer, outPitch, lightTables, dLight, /*microTileLen=*/10); uint8_t lightLevel = *lightmap.getLightingAt(outBuffer + outPitch * 120 + 120);