diff --git a/src/common/PaletteHandler.cxx b/src/common/PaletteHandler.cxx index e6bce1494..f6fed70cf 100644 --- a/src/common/PaletteHandler.cxx +++ b/src/common/PaletteHandler.cxx @@ -294,6 +294,7 @@ PaletteArray PaletteHandler::adjustPalette(const PaletteArray& palette) constexpr int ADJUST_SIZE = 256; constexpr int RGB_UNIT = 1 << 8; constexpr float RGB_OFFSET = 0.5F; + const float hue = myHue; const float brightness = myBrightness * (0.5F * RGB_UNIT) + RGB_OFFSET; const float contrast = myContrast * (0.5F * RGB_UNIT) + RGB_UNIT; const float saturation = mySaturation + 1; @@ -313,10 +314,11 @@ PaletteArray PaletteHandler::adjustPalette(const PaletteArray& palette) int g = (pixel >> 8) & 0xff; int b = (pixel >> 0) & 0xff; - // TOOD: adjust hue (different for NTSC and PAL?) + // adjust hue (different for NTSC and PAL?) + adjustHue(r, g, b, hue); // adjust saturation - changeSaturation(r, g, b, saturation); + adustSaturation(r, g, b, saturation); // adjust contrast, brightness, gamma r = adjust[r]; @@ -496,7 +498,25 @@ void PaletteHandler::generateCustomPalette(ConsoleTiming timing) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PaletteHandler::changeSaturation(int& R, int& G, int& B, float change) +void PaletteHandler::adjustHue(int& R, int& G, int& B, float change) +{ + const float U = cos(-change * BSPF::PI_f); + const float W = sin(-change * BSPF::PI_f); + const float R_out = (.299 + .701 * U + .168 * W) * R + + (.587 - .587 * U + .330 * W) * G + + (.114 - .114 * U - .497 * W) * B; + const float G_out = (.299 - .299 * U - .328 * W) * R + + (.587 + .413 * U + .035 * W) * G + + (.114 - .114 * U + .292 * W) * B; + const float B_out = (.299 - .3 * U + 1.25 * W) * R + + (.587 - .588 * U - 1.05 * W) * G + + (.114 + .886 * U - .203 * W) * B; + + R = R_out; G = G_out; B = B_out; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void PaletteHandler::adustSaturation(int& R, int& G, int& B, float change) { // public-domain function by Darel Rex Finley // diff --git a/src/common/PaletteHandler.hxx b/src/common/PaletteHandler.hxx index 7c0f69dfc..ddb4bfaa1 100644 --- a/src/common/PaletteHandler.hxx +++ b/src/common/PaletteHandler.hxx @@ -110,7 +110,8 @@ class PaletteHandler PaletteArray adjustPalette(const PaletteArray& source); - void changeSaturation(int& R, int& G, int& B, float change); + void adjustHue(int& R, int& G, int& B, float change); + void adustSaturation(int& R, int& G, int& B, float change); /** Loads a user-defined palette file (from OSystem::paletteFile), filling the diff --git a/src/gui/VideoDialog.cxx b/src/gui/VideoDialog.cxx index 41460d9ba..a90657892 100644 --- a/src/gui/VideoDialog.cxx +++ b/src/gui/VideoDialog.cxx @@ -76,6 +76,16 @@ namespace { } } +#define CREATE_CUSTOM_SLIDERS(obj, desc, cmd) \ + myTV ## obj = \ + new SliderWidget(myTab, _font, xpos, ypos-1, swidth, lineHeight, \ + desc, lwidth, cmd, fontWidth*4, "%"); \ + myTV ## obj->setMinValue(0); myTV ## obj->setMaxValue(100); \ + myTV ## obj->setStepValue(2); \ + myTV ## obj->setTickmarkIntervals(2); \ + wid.push_back(myTV ## obj); \ + ypos += lineHeight + VGAP; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font, int max_w, int max_h) @@ -291,15 +301,6 @@ void VideoDialog::addPaletteTab() wid.push_back(myPhaseShiftPal); ypos += lineHeight + VGAP; -#define CREATE_CUSTOM_SLIDERS(obj, desc, cmd) \ - myTV ## obj = \ - new SliderWidget(myTab, _font, xpos, ypos-1, swidth, lineHeight, \ - desc, lwidth, cmd, fontWidth*4, "%"); \ - myTV ## obj->setMinValue(0); myTV ## obj->setMaxValue(100); \ - myTV ## obj->setTickmarkIntervals(2); \ - wid.push_back(myTV ## obj); \ - ypos += lineHeight + VGAP; - CREATE_CUSTOM_SLIDERS(Hue, "Hue ", kPaletteUpdated) CREATE_CUSTOM_SLIDERS(Satur, "Saturation ", kPaletteUpdated) CREATE_CUSTOM_SLIDERS(Contrast, "Contrast ", kPaletteUpdated) @@ -349,15 +350,6 @@ void VideoDialog::addTVEffectsTab() const int swidth = myTVMode->getWidth() - INDENT - lwidth; xpos += INDENT; -#define CREATE_CUSTOM_SLIDERS(obj, desc, cmd) \ - myTV ## obj = \ - new SliderWidget(myTab, _font, xpos, ypos-1, swidth, lineHeight, \ - desc, lwidth, cmd, fontWidth*4, "%"); \ - myTV ## obj->setMinValue(0); myTV ## obj->setMaxValue(100); \ - myTV ## obj->setTickmarkIntervals(2); \ - wid.push_back(myTV ## obj); \ - ypos += lineHeight + VGAP; - CREATE_CUSTOM_SLIDERS(Sharp, "Sharpness ", 0) CREATE_CUSTOM_SLIDERS(Res, "Resolution ", 0) CREATE_CUSTOM_SLIDERS(Artifacts, "Artifacts ", 0)