Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Gamma Adjustment with Brightness Adjustment #7704

Merged
merged 8 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Source/DiabloUI/diabloui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ Sint16 GetCenterOffset(Sint16 w, Sint16 bw)
void UiLoadDefaultPalette()
{
LoadPalette(gbIsHellfire ? "ui_art\\hellfire.pal" : "ui_art\\diablo.pal", /*blend=*/false);
ApplyGamma(logical_palette, orig_palette, 256);
ApplyToneMapping(logical_palette, orig_palette, 256);
}

bool UiLoadBlackBackground()
Expand All @@ -673,7 +673,7 @@ void LoadBackgroundArt(const char *pszFile, int frames)
return;

LoadPalInMem(pPal);
ApplyGamma(logical_palette, orig_palette, 256);
ApplyToneMapping(logical_palette, orig_palette, 256);
UiOnBackgroundChange();
}

Expand Down
28 changes: 14 additions & 14 deletions Source/diablo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1909,19 +1909,19 @@ void InitKeymapActions()
SDLK_PAUSE,
diablo_pause_game);
options.Keymapper.AddAction(
"DecreaseGamma",
N_("Decrease Gamma"),
"DecreaseBrightness",
N_("Decrease Brightness"),
N_("Reduce screen brightness."),
'G',
DecreaseGamma,
'F',
DecreaseBrightness,
nullptr,
CanPlayerTakeAction);
options.Keymapper.AddAction(
"IncreaseGamma",
N_("Increase Gamma"),
"IncreaseBrightness",
N_("Increase Brightness"),
N_("Increase screen brightness."),
'F',
IncreaseGamma,
'G',
IncreaseBrightness,
nullptr,
CanPlayerTakeAction);
options.Keymapper.AddAction(
Expand Down Expand Up @@ -2395,19 +2395,19 @@ void InitPadmapActions()
ControllerButton_NONE,
diablo_pause_game);
options.Padmapper.AddAction(
"DecreaseGamma",
N_("Decrease Gamma"),
"DecreaseBrightness",
N_("Decrease Brightness"),
N_("Reduce screen brightness."),
ControllerButton_NONE,
DecreaseGamma,
DecreaseBrightness,
nullptr,
CanPlayerTakeAction);
options.Padmapper.AddAction(
"IncreaseGamma",
N_("Increase Gamma"),
"IncreaseBrightness",
N_("Increase Brightness"),
N_("Increase screen brightness."),
ControllerButton_NONE,
IncreaseGamma,
IncreaseBrightness,
nullptr,
CanPlayerTakeAction);
options.Padmapper.AddAction(
Expand Down
82 changes: 55 additions & 27 deletions Source/engine/palette.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ namespace {
/** Specifies whether the palette has max brightness. */
bool sgbFadedIn = true;

void LoadGamma()
void LoadBrightness()
{
int gammaValue = *GetOptions().Graphics.gammaCorrection;
gammaValue = std::clamp(gammaValue, 30, 100);
GetOptions().Graphics.gammaCorrection.SetValue(gammaValue - gammaValue % 5);
int brightnessValue = *GetOptions().Graphics.brightness;
brightnessValue = std::clamp(brightnessValue, 0, 100);
GetOptions().Graphics.brightness.SetValue(brightnessValue - brightnessValue % 5);
}

Uint8 FindBestMatchForColor(std::array<SDL_Color, 256> &palette, SDL_Color color, int skipFrom, int skipTo)
Expand Down Expand Up @@ -183,21 +183,46 @@ void palette_update(int first, int ncolor)
pal_surface_palette_version++;
}

void ApplyGamma(std::array<SDL_Color, 256> &dst, const std::array<SDL_Color, 256> &src, int n)
// 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)
{
float g = *GetOptions().Graphics.gammaCorrection / 100.0F;
// 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;

// Precompute a lookup table for speed.
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.
float y = a * x * x + (1.0f - a) * x;
if (y < 0.0f) y = 0.0f;
if (y > 1.0f) y = 1.0f;
kphoenix137 marked this conversation as resolved.
Show resolved Hide resolved
toneMap[i] = static_cast<Uint8>(y * 255.0f + 0.5f);
kphoenix137 marked this conversation as resolved.
Show resolved Hide resolved
}

// Apply the lookup table to each color channel in the palette.
for (int i = 0; i < n; i++) {
dst[i].r = static_cast<Uint8>(pow(src[i].r / 256.0F, g) * 256.0F);
dst[i].g = static_cast<Uint8>(pow(src[i].g / 256.0F, g) * 256.0F);
dst[i].b = static_cast<Uint8>(pow(src[i].b / 256.0F, g) * 256.0F);
dst[i].r = toneMap[src[i].r];
dst[i].g = toneMap[src[i].g];
dst[i].b = toneMap[src[i].b];
}
RedrawEverything();
}

void palette_init()
{
LoadGamma();
LoadBrightness();
system_palette = orig_palette;
InitPalette();
}
Expand Down Expand Up @@ -267,34 +292,37 @@ void LoadRndLvlPal(dungeon_type l)
LoadPalette(szFileName);
}

void IncreaseGamma()
void IncreaseBrightness()
{
int gammaValue = *GetOptions().Graphics.gammaCorrection;
if (gammaValue < 100) {
GetOptions().Graphics.gammaCorrection.SetValue(std::min(gammaValue + 5, 100));
ApplyGamma(system_palette, logical_palette, 256);
int brightnessValue = *GetOptions().Graphics.brightness;
if (brightnessValue < 100) {
int newBrightness = std::min(brightnessValue + 5, 100);
GetOptions().Graphics.brightness.SetValue(newBrightness);
ApplyToneMapping(system_palette, logical_palette, 256);
palette_update();
}
}

void DecreaseGamma()
void DecreaseBrightness()
{
int gammaValue = *GetOptions().Graphics.gammaCorrection;
if (gammaValue > 30) {
GetOptions().Graphics.gammaCorrection.SetValue(std::max(gammaValue - 5, 30));
ApplyGamma(system_palette, logical_palette, 256);
int brightnessValue = *GetOptions().Graphics.brightness;
if (brightnessValue > 0) {
int newBrightness = std::max(brightnessValue - 5, 0);
GetOptions().Graphics.brightness.SetValue(newBrightness);
ApplyToneMapping(system_palette, logical_palette, 256);
palette_update();
}
}

int UpdateGamma(int gamma)
int UpdateBrightness(int brightness)
{
if (gamma > 0) {
GetOptions().Graphics.gammaCorrection.SetValue(130 - gamma);
ApplyGamma(system_palette, logical_palette, 256);
if (brightness >= 0) {
GetOptions().Graphics.brightness.SetValue(brightness);
ApplyToneMapping(system_palette, logical_palette, 256);
palette_update();
}
return 130 - *GetOptions().Graphics.gammaCorrection;

return *GetOptions().Graphics.brightness;
}

void SetFadeLevel(int fadeval, bool updateHardwareCursor, const std::array<SDL_Color, 256> &srcPalette)
Expand Down Expand Up @@ -331,7 +359,7 @@ void PaletteFadeIn(int fr, const std::array<SDL_Color, 256> &srcPalette)
if (demo::IsRunning())
fr = 0;

ApplyGamma(logical_palette, srcPalette, 256);
ApplyToneMapping(logical_palette, srcPalette, 256);

if (fr > 0) {
const uint32_t tc = SDL_GetTicks();
Expand Down Expand Up @@ -434,7 +462,7 @@ void palette_update_quest_palette(int n)
{
int i = 32 - n;
logical_palette[i] = orig_palette[i];
ApplyGamma(system_palette, logical_palette, 32);
ApplyToneMapping(system_palette, logical_palette, 32);
palette_update(0, 31);
// Update blended transparency, but only for the color that was updated
for (int j = 0; j < 256; j++) {
Expand Down
8 changes: 4 additions & 4 deletions Source/engine/palette.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ void palette_update(int first = 0, int ncolor = 256);
void palette_init();
void LoadPalette(const char *pszFileName, bool blend = true);
void LoadRndLvlPal(dungeon_type l);
void IncreaseGamma();
void ApplyGamma(std::array<SDL_Color, 256> &dst, const std::array<SDL_Color, 256> &src, int n);
void DecreaseGamma();
int UpdateGamma(int gamma);
void IncreaseBrightness();
void ApplyToneMapping(std::array<SDL_Color, 256> &dst, const std::array<SDL_Color, 256> &src, int n);
void DecreaseBrightness();
int UpdateBrightness(int sliderValue);
void BlackPalette();
void SetFadeLevel(int fadeval, bool updateHardwareCursor = true, const std::array<SDL_Color, 256> &srcPalette = logical_palette);
/**
Expand Down
33 changes: 15 additions & 18 deletions Source/gamemenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void GamemenuRestartTown(bool bActivate);
void GamemenuOptions(bool bActivate);
void GamemenuMusicVolume(bool bActivate);
void GamemenuSoundVolume(bool bActivate);
void GamemenuGamma(bool bActivate);
void GamemenuBrightness(bool bActivate);
void GamemenuSpeed(bool bActivate);

/** Contains the game menu items of the single player menu. */
Expand Down Expand Up @@ -69,7 +69,7 @@ TMenuItem sgOptionsMenu[] = {
// dwFlags, pszStr, fnMenu
{ GMENU_ENABLED | GMENU_SLIDER, nullptr, &GamemenuMusicVolume },
{ GMENU_ENABLED | GMENU_SLIDER, nullptr, &GamemenuSoundVolume },
{ GMENU_ENABLED | GMENU_SLIDER, N_("Gamma"), &GamemenuGamma },
{ GMENU_ENABLED | GMENU_SLIDER, N_("Gamma"), &GamemenuBrightness },
{ GMENU_ENABLED | GMENU_SLIDER, N_("Speed"), &GamemenuSpeed },
{ GMENU_ENABLED , N_("Previous Menu"), &GamemenuPrevious },
{ GMENU_ENABLED , nullptr, nullptr },
Expand Down Expand Up @@ -156,10 +156,10 @@ void GamemenuGetSound()
GamemenuSoundMusicToggle(SoundToggleNames, &sgOptionsMenu[1], sound_get_or_set_sound_volume(1));
}

void GamemenuGetGamma()
void GamemenuGetBrightness()
{
gmenu_slider_steps(&sgOptionsMenu[2], 15);
gmenu_slider_set(&sgOptionsMenu[2], 30, 100, UpdateGamma(0));
gmenu_slider_steps(&sgOptionsMenu[2], 21);
gmenu_slider_set(&sgOptionsMenu[2], 0, 100, UpdateBrightness(-1));
}

void GamemenuGetSpeed()
Expand All @@ -184,16 +184,16 @@ void GamemenuGetSpeed()
gmenu_slider_set(&sgOptionsMenu[3], 20, 50, sgGameInitInfo.nTickRate);
}

int GamemenuSliderGamma()
int GamemenuSliderBrightness()
{
return gmenu_slider_get(&sgOptionsMenu[2], 30, 100);
return gmenu_slider_get(&sgOptionsMenu[2], 0, 100);
}

void GamemenuOptions(bool /*bActivate*/)
{
GamemenuGetMusic();
GamemenuGetSound();
GamemenuGetGamma();
GamemenuGetBrightness();
GamemenuGetSpeed();
gmenu_set_items(sgOptionsMenu, nullptr);
}
Expand Down Expand Up @@ -254,21 +254,18 @@ void GamemenuSoundVolume(bool bActivate)
GamemenuGetSound();
}

void GamemenuGamma(bool bActivate)
void GamemenuBrightness(bool bActivate)
{
int gamma;
int brightness;
if (bActivate) {
gamma = UpdateGamma(0);
if (gamma == 30)
gamma = 100;
else
gamma = 30;
brightness = UpdateBrightness(-1);
brightness = (brightness == 0) ? 100 : 0;
} else {
gamma = GamemenuSliderGamma();
brightness = GamemenuSliderBrightness();
}

UpdateGamma(gamma);
GamemenuGetGamma();
UpdateBrightness(brightness);
GamemenuGetBrightness();
}

void GamemenuSpeed(bool bActivate)
Expand Down
2 changes: 1 addition & 1 deletion Source/interfac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ void ProgressEventHandler(const SDL_Event &event, uint16_t modState)
if (RenderDirectlyToOutputSurface && PalSurface != nullptr) {
// The loading thread sets `orig_palette`, so we make sure to use
// our own palette for drawing the foreground.
ApplyGamma(logical_palette, ProgressEventHandlerState.palette, 256);
ApplyToneMapping(logical_palette, ProgressEventHandlerState.palette, 256);

// Ensure that all back buffers have the full progress bar.
const void *initialPixels = PalSurface->pixels;
Expand Down
4 changes: 2 additions & 2 deletions Source/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,7 @@ GraphicsOptions::GraphicsOptions()
#endif
{ FrameRateControl::CPUSleep, N_("Limit FPS") },
})
, gammaCorrection("Gamma Correction", OptionEntryFlags::Invisible, "Gamma Correction", "Gamma correction level.", 100)
, brightness("Brightness Correction", OptionEntryFlags::Invisible, "Brightness Correction", "Brightness correction level.", 100)
, zoom("Zoom", OptionEntryFlags::None, N_("Zoom"), N_("Zoom on when enabled."), false)
, colorCycling("Color Cycling", OptionEntryFlags::None, N_("Color Cycling"), N_("Color cycling effect used for water, lava, and acid animation."), true)
, alternateNestArt("Alternate nest art", OptionEntryFlags::OnlyHellfire | OptionEntryFlags::CantChangeInGame, N_("Alternate nest art"), N_("The game will use an alternative palette for Hellfire’s nest tileset."), false)
Expand Down Expand Up @@ -701,7 +701,7 @@ std::vector<OptionEntryBase *> GraphicsOptions::GetEntries()
&integerScaling,
#endif
&frameRateControl,
&gammaCorrection,
&brightness,
&zoom,
&showFPS,
&colorCycling,
Expand Down
4 changes: 2 additions & 2 deletions Source/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -526,8 +526,8 @@ struct GraphicsOptions : OptionCategoryBase {
#endif
/** @brief Limit frame rate either for vsync or CPU load. */
OptionEntryEnum<FrameRateControl> frameRateControl;
/** @brief Gamma correction level. */
OptionEntryInt<int> gammaCorrection;
/** @brief Brightness level. */
OptionEntryInt<int> brightness;
/** @brief Zoom on start. */
OptionEntryBoolean zoom;
/** @brief Enable color cycling animations. */
Expand Down
Loading