|
|
|
|
@ -5,7 +5,10 @@
|
|
|
|
|
*/ |
|
|
|
|
#include "engine/palette.h" |
|
|
|
|
|
|
|
|
|
#include <algorithm> |
|
|
|
|
#include <array> |
|
|
|
|
#include <cstdint> |
|
|
|
|
#include <span> |
|
|
|
|
|
|
|
|
|
#include <fmt/core.h> |
|
|
|
|
|
|
|
|
|
@ -79,48 +82,50 @@ void CycleColorsReverse(int from, int to)
|
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
// When brightness==0, then a==0 (identity mapping)
|
|
|
|
|
// When brightness==100, then a==-MaxAdjustment (maximum brightening)
|
|
|
|
|
constexpr float CalculateToneMappingParameter(int brightness) |
|
|
|
|
{ |
|
|
|
|
// Maximum adjustment factor (tweak this constant to change the effect strength)
|
|
|
|
|
constexpr float MaxAdjustment = 2.0F; |
|
|
|
|
return -(brightness / 100.0f) * MaxAdjustment; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void palette_update(int first, int ncolor) |
|
|
|
|
constexpr uint8_t MapTone(float a, uint8_t color) |
|
|
|
|
{ |
|
|
|
|
if (HeadlessMode) |
|
|
|
|
return; |
|
|
|
|
const auto x = static_cast<float>(color / 255.0f); |
|
|
|
|
// Our quadratic tone mapping: f(x) = a*x^2 + (1-a)*x.
|
|
|
|
|
const float y = std::clamp(a * x * x + (1.0f - a) * x, 0.0f, 1.0f); |
|
|
|
|
return static_cast<uint8_t>(y * 255.0f + 0.5f); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
assert(Palette); |
|
|
|
|
if (SDLC_SetSurfaceAndPaletteColors(PalSurface, Palette.get(), system_palette.data(), first, ncolor) < 0) { |
|
|
|
|
ErrSdl(); |
|
|
|
|
} |
|
|
|
|
pal_surface_palette_version++; |
|
|
|
|
void ApplyToneMappingSingleColor(SDL_Color &dst, const SDL_Color &src) |
|
|
|
|
{ |
|
|
|
|
const float a = CalculateToneMappingParameter(*GetOptions().Graphics.brightness); |
|
|
|
|
dst.r = MapTone(a, src.r); |
|
|
|
|
dst.g = MapTone(a, src.g); |
|
|
|
|
dst.b = MapTone(a, src.b); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
// Applies a tone mapping curve based on the brightness slider value.
|
|
|
|
|
// The brightness value is in the range [0, 100] where 0 is neutral (no change)
|
|
|
|
|
// and 100 produces maximum brightening.
|
|
|
|
|
void ApplyToneMapping(std::array<SDL_Color, 256> &dst, |
|
|
|
|
const std::array<SDL_Color, 256> &src, |
|
|
|
|
int n) |
|
|
|
|
void ApplyToneMapping(std::array<SDL_Color, 256> &dst, std::span<const SDL_Color, 256> src) |
|
|
|
|
{ |
|
|
|
|
// Get the brightness slider value (0 = neutral, 100 = max brightening)
|
|
|
|
|
int brightnessSlider = *GetOptions().Graphics.brightness; // New brightness setting.
|
|
|
|
|
|
|
|
|
|
// Maximum adjustment factor (tweak this constant to change the effect strength)
|
|
|
|
|
const float maxAdjustment = 2.0f; |
|
|
|
|
// Compute the quadratic parameter:
|
|
|
|
|
// When brightnessSlider==0, then a==0 (identity mapping)
|
|
|
|
|
// When brightnessSlider==100, then a== -maxAdjustment (maximum brightening)
|
|
|
|
|
float a = -(brightnessSlider / 100.0f) * maxAdjustment; |
|
|
|
|
const int brightnessSlider = *GetOptions().Graphics.brightness; |
|
|
|
|
|
|
|
|
|
// Precompute a lookup table for speed.
|
|
|
|
|
const float a = CalculateToneMappingParameter(brightnessSlider); |
|
|
|
|
uint8_t toneMap[256]; |
|
|
|
|
for (int i = 0; i < 256; i++) { |
|
|
|
|
float x = i / 255.0f; |
|
|
|
|
// Our quadratic tone mapping: f(x) = a*x^2 + (1-a)*x.
|
|
|
|
|
const float y = std::clamp(a * x * x + (1.0f - a) * x, 0.0f, 1.0f); |
|
|
|
|
toneMap[i] = static_cast<uint8_t>(y * 255.0f + 0.5f); |
|
|
|
|
toneMap[i] = MapTone(a, i); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Apply the lookup table to each color channel in the palette.
|
|
|
|
|
for (int i = 0; i < n; i++) { |
|
|
|
|
for (int i = 0; i < 256; i++) { |
|
|
|
|
dst[i].r = toneMap[src[i].r]; |
|
|
|
|
dst[i].g = toneMap[src[i].g]; |
|
|
|
|
dst[i].b = toneMap[src[i].b]; |
|
|
|
|
@ -128,6 +133,18 @@ void ApplyToneMapping(std::array<SDL_Color, 256> &dst,
|
|
|
|
|
RedrawEverything(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void palette_update(int first, int ncolor) |
|
|
|
|
{ |
|
|
|
|
if (HeadlessMode) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
assert(Palette); |
|
|
|
|
if (SDLC_SetSurfaceAndPaletteColors(PalSurface, Palette.get(), system_palette.data(), first, ncolor) < 0) { |
|
|
|
|
ErrSdl(); |
|
|
|
|
} |
|
|
|
|
pal_surface_palette_version++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void palette_init() |
|
|
|
|
{ |
|
|
|
|
LoadBrightness(); |
|
|
|
|
@ -206,7 +223,7 @@ void IncreaseBrightness()
|
|
|
|
|
if (brightnessValue < 100) { |
|
|
|
|
int newBrightness = std::min(brightnessValue + 5, 100); |
|
|
|
|
GetOptions().Graphics.brightness.SetValue(newBrightness); |
|
|
|
|
ApplyToneMapping(system_palette, logical_palette, 256); |
|
|
|
|
ApplyToneMapping(system_palette, logical_palette); |
|
|
|
|
palette_update(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -217,7 +234,7 @@ void DecreaseBrightness()
|
|
|
|
|
if (brightnessValue > 0) { |
|
|
|
|
int newBrightness = std::max(brightnessValue - 5, 0); |
|
|
|
|
GetOptions().Graphics.brightness.SetValue(newBrightness); |
|
|
|
|
ApplyToneMapping(system_palette, logical_palette, 256); |
|
|
|
|
ApplyToneMapping(system_palette, logical_palette); |
|
|
|
|
palette_update(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -226,7 +243,7 @@ int UpdateBrightness(int brightness)
|
|
|
|
|
{ |
|
|
|
|
if (brightness >= 0) { |
|
|
|
|
GetOptions().Graphics.brightness.SetValue(brightness); |
|
|
|
|
ApplyToneMapping(system_palette, logical_palette, 256); |
|
|
|
|
ApplyToneMapping(system_palette, logical_palette); |
|
|
|
|
palette_update(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -267,7 +284,7 @@ void PaletteFadeIn(int fr, const std::array<SDL_Color, 256> &srcPalette)
|
|
|
|
|
if (demo::IsRunning()) |
|
|
|
|
fr = 0; |
|
|
|
|
|
|
|
|
|
ApplyToneMapping(logical_palette, srcPalette, 256); |
|
|
|
|
ApplyToneMapping(logical_palette, srcPalette); |
|
|
|
|
|
|
|
|
|
if (fr > 0) { |
|
|
|
|
const uint32_t tc = SDL_GetTicks(); |
|
|
|
|
@ -368,10 +385,11 @@ void palette_update_hive()
|
|
|
|
|
|
|
|
|
|
void palette_update_quest_palette(int n) |
|
|
|
|
{ |
|
|
|
|
int i = 32 - n; |
|
|
|
|
// n is in [1, 32], so `i` is in [0, 31].
|
|
|
|
|
const int i = 32 - n; |
|
|
|
|
logical_palette[i] = orig_palette[i]; |
|
|
|
|
ApplyToneMapping(system_palette, logical_palette, 32); |
|
|
|
|
palette_update(0, 31); |
|
|
|
|
ApplyToneMappingSingleColor(system_palette[i], logical_palette[i]); |
|
|
|
|
palette_update(i, 1); |
|
|
|
|
UpdateBlendedLookupTableSingleColor(i, logical_palette.data(), /*skipFrom=*/1, /*skipTo=*/31); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|