remove palette functionality from NTSCFilter

load and save config values in PaletteHandler
This commit is contained in:
thrust26 2020-05-09 21:36:22 +02:00
parent 825c0e516a
commit 123d2ec9f6
20 changed files with 389 additions and 203 deletions

View File

@ -21,6 +21,7 @@
#include <unordered_map> #include <unordered_map>
#include "Event.hxx" #include "Event.hxx"
#include "EventHandlerConstants.hxx" #include "EventHandlerConstants.hxx"
#include "StellaKeys.hxx"
/** /**
This class handles keyboard mappings in Stella. This class handles keyboard mappings in Stella.

View File

@ -15,15 +15,7 @@
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================ //============================================================================
#include "OSystem.hxx"
#include "Console.hxx"
#include "Settings.hxx"
#include "EventHandler.hxx" #include "EventHandler.hxx"
#include "Sound.hxx"
#include "StateManager.hxx"
#include "StellaKeys.hxx"
#include "TIASurface.hxx"
#include "PNGLibrary.hxx"
#include "PKeyboardHandler.hxx" #include "PKeyboardHandler.hxx"
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
@ -475,16 +467,22 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultCommo
{Event::ToggleFullScreen, KBDK_RETURN, MOD3}, {Event::ToggleFullScreen, KBDK_RETURN, MOD3},
{Event::OverscanDecrease, KBDK_PAGEDOWN, KBDM_SHIFT}, {Event::OverscanDecrease, KBDK_PAGEDOWN, KBDM_SHIFT},
{Event::OverscanIncrease, KBDK_PAGEUP, KBDM_SHIFT}, {Event::OverscanIncrease, KBDK_PAGEUP, KBDM_SHIFT},
{Event::VidmodeStd, KBDK_1, MOD3}, //{Event::VidmodeStd, KBDK_1, MOD3},
{Event::VidmodeRGB, KBDK_2, MOD3}, //{Event::VidmodeRGB, KBDK_2, MOD3},
{Event::VidmodeSVideo, KBDK_3, MOD3}, //{Event::VidmodeSVideo, KBDK_3, MOD3},
{Event::VidModeComposite, KBDK_4, MOD3}, //{Event::VidModeComposite, KBDK_4, MOD3},
{Event::VidModeBad, KBDK_5, MOD3}, //{Event::VidModeBad, KBDK_5, MOD3},
{Event::VidModeCustom, KBDK_6, MOD3}, //{Event::VidModeCustom, KBDK_6, MOD3},
{Event::PreviousAttribute, KBDK_7, KBDM_SHIFT | MOD3}, {Event::PreviousVideoMode, KBDK_1, KBDM_SHIFT | MOD3},
{Event::NextAttribute, KBDK_7, MOD3}, {Event::NextVideoMode, KBDK_1, MOD3},
{Event::DecreaseAttribute, KBDK_8, KBDM_SHIFT | MOD3}, {Event::PreviousAttribute, KBDK_2, KBDM_SHIFT | MOD3},
{Event::IncreaseAttribute, KBDK_8, MOD3}, {Event::NextAttribute, KBDK_2, MOD3},
{Event::DecreaseAttribute, KBDK_3, KBDM_SHIFT | MOD3},
{Event::IncreaseAttribute, KBDK_3, MOD3},
{Event::PreviousPaletteAttribute, KBDK_4, KBDM_SHIFT | MOD3},
{Event::NextPaletteAttribute, KBDK_4, MOD3},
{Event::PaletteAttributeDecrease, KBDK_5, KBDM_SHIFT | MOD3},
{Event::PaletteAttributeIncrease, KBDK_5, MOD3},
{Event::PhosphorDecrease, KBDK_9, KBDM_SHIFT | MOD3}, {Event::PhosphorDecrease, KBDK_9, KBDM_SHIFT | MOD3},
{Event::PhosphorIncrease, KBDK_9, MOD3}, {Event::PhosphorIncrease, KBDK_9, MOD3},
{Event::TogglePhosphor, KBDK_P, MOD3}, {Event::TogglePhosphor, KBDK_P, MOD3},

View File

@ -26,10 +26,6 @@ PaletteHandler::PaletteHandler(OSystem& system)
{ {
// Load user-defined palette for this ROM // Load user-defined palette for this ROM
loadUserPalette(); loadUserPalette();
//// Generate custom palette
//generateCustomPalette(ConsoleTiming::ntsc);
//generateCustomPalette(ConsoleTiming::pal);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -100,27 +96,118 @@ void PaletteHandler::changePalette(bool increase)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::generatePalettes() void PaletteHandler::selectAdjustable(bool next)
{ {
generateCustomPalette(ConsoleTiming::ntsc); if(next)
generateCustomPalette(ConsoleTiming::pal); {
generateColorLossPalette(); if(myCurrentAdjustable == NUM_ADJUSTABLES - 1)
myCurrentAdjustable = 0;
else
myCurrentAdjustable++;
}
else
{
if(myCurrentAdjustable == 0)
myCurrentAdjustable = NUM_ADJUSTABLES - 1;
else
myCurrentAdjustable--;
}
ostringstream buf;
buf << "Palette adjustable '" << myAdjustables[myCurrentAdjustable].type
<< "' selected";
myOSystem.frameBuffer().showMessage(buf.str());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::changeAdjustable(bool increase)
{
if(myCurrentAdjustable == NUM_ADJUSTABLES - 1)
changeColorPhaseShift(increase);
else
{
float newVal = (*myAdjustables[myCurrentAdjustable].value);
if(increase)
{
newVal += 0.05F;
if(newVal > 1.0F)
newVal = 1.0F;
}
else
{
newVal -= 0.05F;
if(newVal < -1.0F)
newVal = -1.0F;
}
*myAdjustables[myCurrentAdjustable].value = newVal;
ostringstream buf;
buf << "Custom '" << myAdjustables[myCurrentAdjustable].type
<< "' set to " << int((newVal + 1.0F) * 100.0F + 0.5F) << "%";
myOSystem.frameBuffer().showMessage(buf.str());
setPalette();
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::loadConfig(const Settings& settings)
{
// Load adjustables
myHue = BSPF::clamp(settings.getFloat("tv.hue"), -1.0F, 1.0F);
mySaturation = BSPF::clamp(settings.getFloat("tv.saturation"), -1.0F, 1.0F);
myContrast = BSPF::clamp(settings.getFloat("tv.contrast"), -1.0F, 1.0F);
myBrightness = BSPF::clamp(settings.getFloat("tv.brightness"), -1.0F, 1.0F);
myGamma = BSPF::clamp(settings.getFloat("tv.gamma"), -1.0F, 1.0F);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::saveConfig(Settings& settings) const
{
// Save adjustables
settings.setValue("tv.hue", myHue);
settings.setValue("tv.saturation", mySaturation);
settings.setValue("tv.contrast", myContrast);
settings.setValue("tv.brightness", myBrightness);
settings.setValue("tv.gamma", myGamma);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::setAdjustables(Adjustable& adjustable)
{
myHue = scaleFrom100(adjustable.hue);
mySaturation = scaleFrom100(adjustable.saturation);
myContrast = scaleFrom100(adjustable.contrast);
myBrightness = scaleFrom100(adjustable.brightness);
myGamma = scaleFrom100(adjustable.gamma);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::getAdjustables(Adjustable& adjustable) const
{
adjustable.hue = scaleTo100(myHue);
adjustable.saturation = scaleTo100(mySaturation);
adjustable.contrast = scaleTo100(myContrast);
adjustable.brightness = scaleTo100(myBrightness);
adjustable.gamma = scaleTo100(myGamma);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::changeColorPhaseShift(bool increase) void PaletteHandler::changeColorPhaseShift(bool increase)
{ {
const ConsoleTiming timing = myOSystem.console().timing();
// SECAM is not supported
if(timing != ConsoleTiming::secam)
{
const char DEGREE = 0x1c; const char DEGREE = 0x1c;
const float NTSC_SHIFT = 26.2F; const float NTSC_SHIFT = 26.2F;
const float PAL_SHIFT = 31.3F; // 360 / 11.5 const float PAL_SHIFT = 31.3F; // 360 / 11.5
const ConsoleTiming timing = myOSystem.console().timing();
const bool isNTSC = timing == ConsoleTiming::ntsc; const bool isNTSC = timing == ConsoleTiming::ntsc;
const bool isPAL = timing == ConsoleTiming::pal; const string key = isNTSC ? "tv.phase_ntsc" : "tv.phase_pal";
// SECAM is not supported
if(isNTSC || isPAL)
{
const string key = isNTSC ? "phase_ntsc" : "phase_pal";
const float shift = isNTSC ? NTSC_SHIFT : PAL_SHIFT; const float shift = isNTSC ? NTSC_SHIFT : PAL_SHIFT;
float phase = myOSystem.settings().getFloat(key); float phase = myOSystem.settings().getFloat(key);
@ -175,6 +262,9 @@ void PaletteHandler::setPalette()
// Now consider the current display format // Now consider the current display format
const PaletteArray* palette = palettes[paletteType][int(timing)]; const PaletteArray* palette = palettes[paletteType][int(timing)];
if(paletteType == PaletteType::Custom)
generateCustomPalette(timing);
myOSystem.frameBuffer().setTIAPalette(adjustPalette(*palette)); myOSystem.frameBuffer().setTIAPalette(adjustPalette(*palette));
} }
@ -212,15 +302,7 @@ PaletteArray PaletteHandler::adjustPalette(const PaletteArray& palette)
// TOOD: adjust hue (different for NTSC and PAL?) // TOOD: adjust hue (different for NTSC and PAL?)
// adjust saturation // adjust saturation
float P = sqrt(r * r * PR + g * g * PG + b * b * PB) ; changeSaturation(r, g, b, saturation);
r = P + (r - P) * saturation;
g = P + (g - P) * saturation;
b = P + (b - P) * saturation;
r = BSPF::clamp(r, 0, 255);
g = BSPF::clamp(g, 0, 255);
b = BSPF::clamp(b, 0, 255);
// adjust contrast, brightness, gamma // adjust contrast, brightness, gamma
r = adjust[r]; r = adjust[r];
@ -235,6 +317,7 @@ PaletteArray PaletteHandler::adjustPalette(const PaletteArray& palette)
// Fill the odd numbered palette entries with gray values (calculated // Fill the odd numbered palette entries with gray values (calculated
// using the standard RGB -> grayscale conversion formula) // using the standard RGB -> grayscale conversion formula)
// Used for PAL color-loss data and 'greying out' the frame in the debugger.
const uInt8 lum = static_cast<uInt8>((r * PR) + (g * PG) + (b * PB)); const uInt8 lum = static_cast<uInt8>((r * PR) + (g * PG) + (b * PB));
destPalette[i + 1] = (lum << 16) + (lum << 8) + lum; destPalette[i + 1] = (lum << 16) + (lum << 8) + lum;
@ -299,7 +382,7 @@ void PaletteHandler::generateCustomPalette(ConsoleTiming timing)
{ {
// YIQ is YUV shifted by 33° // YIQ is YUV shifted by 33°
constexpr float offset = 33 * (2 * BSPF::PI_f / 360); constexpr float offset = 33 * (2 * BSPF::PI_f / 360);
const float shift = myOSystem.settings().getFloat("phase_ntsc") * const float shift = myOSystem.settings().getFloat("tv.phase_ntsc") *
(2 * BSPF::PI_f / 360); (2 * BSPF::PI_f / 360);
// color 0 is grayscale // color 0 is grayscale
@ -342,10 +425,10 @@ void PaletteHandler::generateCustomPalette(ConsoleTiming timing)
} }
} }
} }
else else if(timing == ConsoleTiming::pal)
{ {
constexpr float offset = 180 * (2 * BSPF::PI_f / 360); constexpr float offset = 180 * (2 * BSPF::PI_f / 360);
float shift = myOSystem.settings().getFloat("phase_pal") * float shift = myOSystem.settings().getFloat("tv.phase_pal") *
(2 * BSPF::PI_f / 360); (2 * BSPF::PI_f / 360);
constexpr float fixedShift = 22.5F * (2 * BSPF::PI_f / 360); constexpr float fixedShift = 22.5F * (2 * BSPF::PI_f / 360);
@ -432,63 +515,6 @@ void PaletteHandler::changeSaturation(int& R, int& G, int& B, float change)
B = BSPF::clamp(B, 0, 255); B = BSPF::clamp(B, 0, 255);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::changeSaturation(float& R, float& G, float& B, float change)
{
constexpr float PR = .2989F;
constexpr float PG = .5870F;
constexpr float PB = .1140F;
float P = sqrt(R * R * PR + G * G * PG + B * B * PB) ;
R = P + (R - P) * change;
G = P + (G - P) * change;
B = P + (B - P) * change;
if(R < 0) R = 0;
if(G < 0) G = 0;
if(B < 0) B = 0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::generateColorLossPalette()
{
// Look at all the palettes, since we don't know which one is
// currently active
std::array<uInt32*, int(ConsoleTiming::numTimings) * PaletteType::NumTypes> palette = {
ourNTSCPalette.data(), ourPALPalette.data(), ourSECAMPalette.data(),
ourNTSCPaletteZ26.data(), ourPALPaletteZ26.data(), ourSECAMPaletteZ26.data(),
nullptr, nullptr, nullptr,
ourCustomNTSCPalette.data(), ourCustomPALPalette.data(), ourSECAMPalette.data(),
};
if(myUserPaletteDefined)
{
int idx = PaletteType::User * int(ConsoleTiming::numTimings);
palette[idx + int(ConsoleTiming::ntsc)] = ourUserNTSCPalette.data();
palette[idx + int(ConsoleTiming::pal)] = ourUserPALPalette.data();
palette[idx + int(ConsoleTiming::secam)] = ourUserSECAMPalette.data();
}
for(int i = 0; i < int(ConsoleTiming::numTimings) * PaletteType::NumTypes; ++i)
{
if(palette[i] == nullptr)
continue;
// Fill the odd numbered palette entries with gray values (calculated
// using the standard RGB -> grayscale conversion formula)
for(int j = 0; j < 128; ++j)
{
const uInt32 pixel = palette[i][(j<<1)];
const uInt8 r = (pixel >> 16) & 0xff;
const uInt8 g = (pixel >> 8) & 0xff;
const uInt8 b = (pixel >> 0) & 0xff;
const uInt8 sum = static_cast<uInt8>((r * 0.2989) + (g * 0.5870) + (b * 0.1140));
palette[i][(j<<1)+1] = (sum << 16) + (sum << 8) + sum;
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteArray PaletteHandler::ourNTSCPalette = { PaletteArray PaletteHandler::ourNTSCPalette = {
0x000000, 0, 0x4a4a4a, 0, 0x6f6f6f, 0, 0x8e8e8e, 0, 0x000000, 0, 0x4a4a4a, 0, 0x6f6f6f, 0, 0x8e8e8e, 0,

View File

@ -36,6 +36,9 @@ class PaletteHandler
NumDisplayTypes NumDisplayTypes
}; };
struct Adjustable {
uInt32 hue, saturation, contrast, brightness, gamma;
};
public: public:
PaletteHandler(OSystem& system); PaletteHandler(OSystem& system);
@ -46,6 +49,14 @@ class PaletteHandler
*/ */
void changePalette(bool increase = true); void changePalette(bool increase = true);
void selectAdjustable(bool next = true);
void changeAdjustable(bool increase = true);
void loadConfig(const Settings& settings);
void saveConfig(Settings& settings) const;
void setAdjustables(Adjustable& adjustable);
void getAdjustables(Adjustable& adjustable) const;
/** /**
Change the "phase shift" variable. Change the "phase shift" variable.
@ -56,9 +67,6 @@ class PaletteHandler
*/ */
void changeColorPhaseShift(bool increase = true); void changeColorPhaseShift(bool increase = true);
void changeSaturation(int& R, int& G, int& B, float change);
void changeSaturation(float& R, float& G, float& B, float change);
/** /**
Sets the palette according to the given palette name. Sets the palette according to the given palette name.
@ -72,17 +80,6 @@ class PaletteHandler
*/ */
void setPalette(); void setPalette();
void generatePalettes();
/**
Loads all defined palettes with PAL color-loss data, even those that
normally can't have it enabled (NTSC), since it's also used for
'greying out' the frame in the debugger.
*/
void generateColorLossPalette();
/** /**
Generates a custom palette, based on user defined phase shifts. Generates a custom palette, based on user defined phase shifts.
*/ */
@ -99,11 +96,16 @@ class PaletteHandler
MaxType = Custom MaxType = Custom
}; };
float scaleFrom100(float x) const { return (x / 100.F) - 1.F; }
uInt32 scaleTo100(float x) const { return uInt32(100 * (x + 1.F)); }
PaletteType toPaletteType(const string& name) const; PaletteType toPaletteType(const string& name) const;
string toPaletteName(PaletteType type) const; string toPaletteName(PaletteType type) const;
PaletteArray adjustPalette(const PaletteArray& source); PaletteArray adjustPalette(const PaletteArray& source);
void changeSaturation(int& R, int& G, int& B, float change);
/** /**
Loads a user-defined palette file (from OSystem::paletteFile), filling the Loads a user-defined palette file (from OSystem::paletteFile), filling the
appropriate user-defined palette arrays. appropriate user-defined palette arrays.
@ -112,14 +114,33 @@ class PaletteHandler
private: private:
static const int NUM_ADJUSTABLES = 6;
OSystem& myOSystem; OSystem& myOSystem;
uInt32 myCurrentAdjustable{0};
struct AdjustableTag {
const char* const type{nullptr};
float* value{nullptr};
};
const std::array<AdjustableTag, NUM_ADJUSTABLES> myAdjustables =
{ {
{ "contrast", &myContrast },
{ "brightness", &myBrightness },
{ "hue", &myHue },
{ "saturation", &mySaturation },
{ "gamma", &myGamma },
{ "phase shift", nullptr },
} };
// range -1.0 to +1.0 (as in AtariNTSC) // range -1.0 to +1.0 (as in AtariNTSC)
float myContrast{0.0F}; // Basic parameters
float myBrightness{0.0F}; float myContrast{0.0F}; // -1 = dark (0.5) +1 = light (1.5)
float myHue{0.0F}; float myHue{0.0F}; // -1 = -180 degrees +1 = +180 degrees
float mySaturation{0.0F}; float mySaturation{0.0F}; // -1 = grayscale (0.0) +1 = oversaturated colors (2.0)
float myGamma{0.0F}; float myBrightness{0.0F}; // -1 = dark (0.5) +1 = light (1.5)
// Advanced parameters
float myGamma{0.0F}; // -1 = dark (1.5) +1 = light (0.5)
// Indicates whether an external palette was found and // Indicates whether an external palette was found and
// successfully loaded // successfully loaded

View File

@ -57,9 +57,15 @@ void AtariNTSC::generateKernels()
const uInt8* ptr = myRGBPalette.data(); const uInt8* ptr = myRGBPalette.data();
for(size_t entry = 0; entry < myRGBPalette.size() / 3; ++entry) for(size_t entry = 0; entry < myRGBPalette.size() / 3; ++entry)
{ {
#ifdef BLARGG_PALETTE
float r = myImpl.to_float[*ptr++], float r = myImpl.to_float[*ptr++],
g = myImpl.to_float[*ptr++], g = myImpl.to_float[*ptr++],
b = myImpl.to_float[*ptr++]; b = myImpl.to_float[*ptr++];
#else
float r = (*ptr++) / 255.F * rgb_unit + rgb_offset,
g = (*ptr++) / 255.F * rgb_unit + rgb_offset,
b = (*ptr++) / 255.F * rgb_unit + rgb_offset;
#endif
float y, i, q; RGB_TO_YIQ( r, g, b, y, i, q ); float y, i, q; RGB_TO_YIQ( r, g, b, y, i, q );
// Generate kernel // Generate kernel
@ -319,8 +325,10 @@ void AtariNTSC::renderWithPhosphorThread(const uInt8* atari_in, const uInt32 in_
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void AtariNTSC::init(init_t& impl, const Setup& setup) void AtariNTSC::init(init_t& impl, const Setup& setup)
{ {
#ifdef BLARGG_PALETTE
impl.brightness = setup.brightness * (0.5F * rgb_unit) + rgb_offset; impl.brightness = setup.brightness * (0.5F * rgb_unit) + rgb_offset;
impl.contrast = setup.contrast * (0.5F * rgb_unit) + rgb_unit; impl.contrast = setup.contrast * (0.5F * rgb_unit) + rgb_unit;
#endif
impl.artifacts = setup.artifacts; impl.artifacts = setup.artifacts;
if ( impl.artifacts > 0 ) if ( impl.artifacts > 0 )
@ -334,6 +342,7 @@ void AtariNTSC::init(init_t& impl, const Setup& setup)
initFilters(impl, setup); initFilters(impl, setup);
#ifdef BLARGG_PALETTE
/* generate gamma table */ /* generate gamma table */
if (true) /* was (gamma_size > 1) */ if (true) /* was (gamma_size > 1) */
{ {
@ -341,19 +350,22 @@ void AtariNTSC::init(init_t& impl, const Setup& setup)
float const gamma = 1.1333F - setup.gamma * 0.5F; float const gamma = 1.1333F - setup.gamma * 0.5F;
/* match common PC's 2.2 gamma to TV's 2.65 gamma */ /* match common PC's 2.2 gamma to TV's 2.65 gamma */
int i; int i;
for ( i = 0; i < gamma_size; i++ ) for(i = 0; i < gamma_size; i++)
impl.to_float [i] = impl.to_float[i] =
powf( i * to_float, gamma ) * impl.contrast + impl.brightness; powf(i * to_float, gamma) * impl.contrast + impl.brightness;
} }
#endif
/* setup decoder matricies */ /* setup decoder matricies */
{ {
#ifdef BLARGG_PALETTE
float hue = setup.hue * BSPF::PI_f + BSPF::PI_f / 180 * ext_decoder_hue; float hue = setup.hue * BSPF::PI_f + BSPF::PI_f / 180 * ext_decoder_hue;
float sat = setup.saturation + 1; float sat = setup.saturation + 1;
hue += BSPF::PI_f / 180 * (std_decoder_hue - ext_decoder_hue); hue += BSPF::PI_f / 180 * (std_decoder_hue - ext_decoder_hue);
float s = sinf( hue ) * sat; float s = sinf(hue)*sat;
float c = cosf( hue ) * sat; float c = cosf(hue)*sat;
#endif
float* out = impl.to_rgb.data(); float* out = impl.to_rgb.data();
int n; int n;
@ -366,8 +378,13 @@ void AtariNTSC::init(init_t& impl, const Setup& setup)
{ {
float i = *in++; float i = *in++;
float q = *in++; float q = *in++;
#ifdef BLARGG_PALETTE
*out++ = i * c - q * s; *out++ = i * c - q * s;
*out++ = i * s + q * c; *out++ = i * s + q * c;
#else
*out++ = i ;
*out++ = q;
#endif
} }
while ( --n2 ); while ( --n2 );
#if 0 // burst_count is always 0 #if 0 // burst_count is always 0
@ -544,16 +561,32 @@ void AtariNTSC::genKernel(init_t& impl, float y, float i, float q, uInt32* out)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const AtariNTSC::Setup AtariNTSC::TV_Composite = { const AtariNTSC::Setup AtariNTSC::TV_Composite = {
#ifdef BLARGG_PALETTE
0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.15F, 0.0F, 0.0F, 0.0F 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.15F, 0.0F, 0.0F, 0.0F
#else
0.0F, 0.15F, 0.0F, 0.0F, 0.0F
#endif
}; };
const AtariNTSC::Setup AtariNTSC::TV_SVideo = { const AtariNTSC::Setup AtariNTSC::TV_SVideo = {
#ifdef BLARGG_PALETTE
0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.45F, -1.0F, -1.0F, 0.0F 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.45F, -1.0F, -1.0F, 0.0F
#else
0.0F, 0.45F, -1.0F, -1.0F, 0.0F
#endif
}; };
const AtariNTSC::Setup AtariNTSC::TV_RGB = { const AtariNTSC::Setup AtariNTSC::TV_RGB = {
#ifdef BLARGG_PALETTE
0.0F, 0.0F, 0.0F, 0.0F, 0.2F, 0.0F, 0.70F, -1.0F, -1.0F, -1.0F 0.0F, 0.0F, 0.0F, 0.0F, 0.2F, 0.0F, 0.70F, -1.0F, -1.0F, -1.0F
#else
0.2F, 0.70F, -1.0F, -1.0F, -1.0F
#endif
}; };
const AtariNTSC::Setup AtariNTSC::TV_Bad = { const AtariNTSC::Setup AtariNTSC::TV_Bad = {
#ifdef BLARGG_PALETTE
0.1F, -0.3F, 0.3F, 0.25F, 0.2F, 0.0F, 0.1F, 0.5F, 0.5F, 0.5F 0.1F, -0.3F, 0.3F, 0.25F, 0.2F, 0.0F, 0.1F, 0.5F, 0.5F, 0.5F
#else
0.2F, 0.1F, 0.5F, 0.5F, 0.5F
#endif
}; };
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -46,6 +46,8 @@
#include "FrameBufferConstants.hxx" #include "FrameBufferConstants.hxx"
#include "bspf.hxx" #include "bspf.hxx"
//#define BLARGG_PALETTE // also modify contrast, brightness, saturation, gamma and hue when defined
class AtariNTSC class AtariNTSC
{ {
public: public:
@ -57,14 +59,18 @@ class AtariNTSC
struct Setup struct Setup
{ {
// Basic parameters // Basic parameters
#ifdef BLARGG_PALETTE
float hue{0.F}; // -1 = -180 degrees +1 = +180 degrees float hue{0.F}; // -1 = -180 degrees +1 = +180 degrees
float saturation{0.F}; // -1 = grayscale (0.0) +1 = oversaturated colors (2.0) float saturation{0.F}; // -1 = grayscale (0.0) +1 = oversaturated colors (2.0)
float contrast{0.F}; // -1 = dark (0.5) +1 = light (1.5) float contrast{0.F}; // -1 = dark (0.5) +1 = light (1.5)
float brightness{0.F}; // -1 = dark (0.5) +1 = light (1.5) float brightness{0.F}; // -1 = dark (0.5) +1 = light (1.5)
#endif
float sharpness{0.F}; // edge contrast enhancement/blurring float sharpness{0.F}; // edge contrast enhancement/blurring
// Advanced parameters // Advanced parameters
#ifdef BLARGG_PALETTE
float gamma{0.F}; // -1 = dark (1.5) +1 = light (0.5) float gamma{0.F}; // -1 = dark (1.5) +1 = light (0.5)
#endif
float resolution{0.F}; // image resolution float resolution{0.F}; // image resolution
float artifacts{0.F}; // artifacts caused by color changes float artifacts{0.F}; // artifacts caused by color changes
float fringing{0.F}; // color artifacts caused by brightness changes float fringing{0.F}; // color artifacts caused by brightness changes
@ -127,7 +133,9 @@ class AtariNTSC
burst_size = entry_size / burst_count, burst_size = entry_size / burst_count,
kernel_half = 16, kernel_half = 16,
kernel_size = kernel_half * 2 + 1, kernel_size = kernel_half * 2 + 1,
#ifdef BLARGG_PALETTE
gamma_size = 256, gamma_size = 256,
#endif
rgb_builder = ((1 << 21) | (1 << 11) | (1 << 1)), rgb_builder = ((1 << 21) | (1 << 11) | (1 << 1)),
rgb_kernel_size = burst_size / alignment_count, rgb_kernel_size = burst_size / alignment_count,
@ -162,16 +170,20 @@ class AtariNTSC
struct init_t struct init_t
{ {
std::array<float, burst_count * 6> to_rgb{0.F}; std::array<float, burst_count * 6> to_rgb{0.F};
#ifdef BLARGG_PALETTE
std::array<float, gamma_size> to_float{0.F}; std::array<float, gamma_size> to_float{0.F};
float contrast{0.F}; float contrast{0.F};
float brightness{0.F}; float brightness{0.F};
#endif
float artifacts{0.F}; float artifacts{0.F};
float fringing{0.F}; float fringing{0.F};
std::array<float, rescale_out * kernel_size * 2> kernel{0.F}; std::array<float, rescale_out * kernel_size * 2> kernel{0.F};
init_t() { init_t() {
to_rgb.fill(0.0); to_rgb.fill(0.0);
#ifdef BLARGG_PALETTE
to_float.fill(0.0); to_float.fill(0.0);
#endif
kernel.fill(0.0); kernel.fill(0.0);
} }
}; };

View File

@ -140,13 +140,16 @@ string NTSCFilter::decreaseAdjustable()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void NTSCFilter::loadConfig(const Settings& settings) void NTSCFilter::loadConfig(const Settings& settings)
{ {
// Load adjustables for custom mode // Load adjustables for custom mode
#ifdef BLARGG_PALETTE
myCustomSetup.hue = BSPF::clamp(settings.getFloat("tv.hue"), -1.0F, 1.0F); myCustomSetup.hue = BSPF::clamp(settings.getFloat("tv.hue"), -1.0F, 1.0F);
myCustomSetup.saturation = BSPF::clamp(settings.getFloat("tv.saturation"), -1.0F, 1.0F); myCustomSetup.saturation = BSPF::clamp(settings.getFloat("tv.saturation"), -1.0F, 1.0F);
myCustomSetup.contrast = BSPF::clamp(settings.getFloat("tv.contrast"), -1.0F, 1.0F); myCustomSetup.contrast = BSPF::clamp(settings.getFloat("tv.contrast"), -1.0F, 1.0F);
myCustomSetup.brightness = BSPF::clamp(settings.getFloat("tv.brightness"), -1.0F, 1.0F); myCustomSetup.brightness = BSPF::clamp(settings.getFloat("tv.brightness"), -1.0F, 1.0F);
myCustomSetup.sharpness = BSPF::clamp(settings.getFloat("tv.sharpness"), -1.0F, 1.0F);
myCustomSetup.gamma = BSPF::clamp(settings.getFloat("tv.gamma"), -1.0F, 1.0F); myCustomSetup.gamma = BSPF::clamp(settings.getFloat("tv.gamma"), -1.0F, 1.0F);
#endif
myCustomSetup.sharpness = BSPF::clamp(settings.getFloat("tv.sharpness"), -1.0F, 1.0F);
myCustomSetup.resolution = BSPF::clamp(settings.getFloat("tv.resolution"), -1.0F, 1.0F); myCustomSetup.resolution = BSPF::clamp(settings.getFloat("tv.resolution"), -1.0F, 1.0F);
myCustomSetup.artifacts = BSPF::clamp(settings.getFloat("tv.artifacts"), -1.0F, 1.0F); myCustomSetup.artifacts = BSPF::clamp(settings.getFloat("tv.artifacts"), -1.0F, 1.0F);
myCustomSetup.fringing = BSPF::clamp(settings.getFloat("tv.fringing"), -1.0F, 1.0F); myCustomSetup.fringing = BSPF::clamp(settings.getFloat("tv.fringing"), -1.0F, 1.0F);
@ -157,12 +160,14 @@ void NTSCFilter::loadConfig(const Settings& settings)
void NTSCFilter::saveConfig(Settings& settings) const void NTSCFilter::saveConfig(Settings& settings) const
{ {
// Save adjustables for custom mode // Save adjustables for custom mode
settings.setValue("tv.hue", myCustomSetup.hue); #ifdef BLARGG_PALETTE
settings.setValue("tv.saturation", myCustomSetup.saturation); //settings.setValue("tv.hue", myCustomSetup.hue);
settings.setValue("tv.contrast", myCustomSetup.contrast); //settings.setValue("tv.saturation", myCustomSetup.saturation);
settings.setValue("tv.brightness", myCustomSetup.brightness); //settings.setValue("tv.contrast", myCustomSetup.contrast);
//settings.setValue("tv.brightness", myCustomSetup.brightness);
//settings.setValue("tv.gamma", myCustomSetup.gamma);
#endif
settings.setValue("tv.sharpness", myCustomSetup.sharpness); settings.setValue("tv.sharpness", myCustomSetup.sharpness);
settings.setValue("tv.gamma", myCustomSetup.gamma);
settings.setValue("tv.resolution", myCustomSetup.resolution); settings.setValue("tv.resolution", myCustomSetup.resolution);
settings.setValue("tv.artifacts", myCustomSetup.artifacts); settings.setValue("tv.artifacts", myCustomSetup.artifacts);
settings.setValue("tv.fringing", myCustomSetup.fringing); settings.setValue("tv.fringing", myCustomSetup.fringing);
@ -192,12 +197,14 @@ void NTSCFilter::getAdjustables(Adjustable& adjustable, Preset preset) const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void NTSCFilter::setCustomAdjustables(Adjustable& adjustable) void NTSCFilter::setCustomAdjustables(Adjustable& adjustable)
{ {
myCustomSetup.hue = scaleFrom100(adjustable.hue); #ifdef BLARGG_PALETTE
myCustomSetup.saturation = scaleFrom100(adjustable.saturation); //myCustomSetup.hue = scaleFrom100(adjustable.hue);
myCustomSetup.contrast = scaleFrom100(adjustable.contrast); //myCustomSetup.saturation = scaleFrom100(adjustable.saturation);
myCustomSetup.brightness = scaleFrom100(adjustable.brightness); //myCustomSetup.contrast = scaleFrom100(adjustable.contrast);
//myCustomSetup.brightness = scaleFrom100(adjustable.brightness);
//myCustomSetup.gamma = scaleFrom100(adjustable.gamma);
#endif
myCustomSetup.sharpness = scaleFrom100(adjustable.sharpness); myCustomSetup.sharpness = scaleFrom100(adjustable.sharpness);
myCustomSetup.gamma = scaleFrom100(adjustable.gamma);
myCustomSetup.resolution = scaleFrom100(adjustable.resolution); myCustomSetup.resolution = scaleFrom100(adjustable.resolution);
myCustomSetup.artifacts = scaleFrom100(adjustable.artifacts); myCustomSetup.artifacts = scaleFrom100(adjustable.artifacts);
myCustomSetup.fringing = scaleFrom100(adjustable.fringing); myCustomSetup.fringing = scaleFrom100(adjustable.fringing);
@ -208,12 +215,14 @@ void NTSCFilter::setCustomAdjustables(Adjustable& adjustable)
void NTSCFilter::convertToAdjustable(Adjustable& adjustable, void NTSCFilter::convertToAdjustable(Adjustable& adjustable,
const AtariNTSC::Setup& setup) const const AtariNTSC::Setup& setup) const
{ {
adjustable.hue = scaleTo100(setup.hue); #ifdef BLARGG_PALETTE
adjustable.saturation = scaleTo100(setup.saturation); //adjustable.hue = scaleTo100(setup.hue);
adjustable.contrast = scaleTo100(setup.contrast); //adjustable.saturation = scaleTo100(setup.saturation);
adjustable.brightness = scaleTo100(setup.brightness); //adjustable.contrast = scaleTo100(setup.contrast);
//adjustable.brightness = scaleTo100(setup.brightness);
//adjustable.gamma = scaleTo100(setup.gamma);
#endif
adjustable.sharpness = scaleTo100(setup.sharpness); adjustable.sharpness = scaleTo100(setup.sharpness);
adjustable.gamma = scaleTo100(setup.gamma);
adjustable.resolution = scaleTo100(setup.resolution); adjustable.resolution = scaleTo100(setup.resolution);
adjustable.artifacts = scaleTo100(setup.artifacts); adjustable.artifacts = scaleTo100(setup.artifacts);
adjustable.fringing = scaleTo100(setup.fringing); adjustable.fringing = scaleTo100(setup.fringing);
@ -224,12 +233,16 @@ void NTSCFilter::convertToAdjustable(Adjustable& adjustable,
AtariNTSC::Setup NTSCFilter::myCustomSetup = AtariNTSC::TV_Composite; AtariNTSC::Setup NTSCFilter::myCustomSetup = AtariNTSC::TV_Composite;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#ifdef BLARGG_PALETTE
const std::array<NTSCFilter::AdjustableTag, 10> NTSCFilter::ourCustomAdjustables = { { const std::array<NTSCFilter::AdjustableTag, 10> NTSCFilter::ourCustomAdjustables = { {
{ "contrast", &myCustomSetup.contrast }, { "contrast", &myCustomSetup.contrast },
{ "brightness", &myCustomSetup.brightness }, { "brightness", &myCustomSetup.brightness },
{ "hue", &myCustomSetup.hue }, { "hue", &myCustomSetup.hue },
{ "saturation", &myCustomSetup.saturation }, { "saturation", &myCustomSetup.saturation },
{ "gamma", &myCustomSetup.gamma }, { "gamma", &myCustomSetup.gamma },
#else
const std::array<NTSCFilter::AdjustableTag, 5> NTSCFilter::ourCustomAdjustables = { {
#endif
{ "sharpness", &myCustomSetup.sharpness }, { "sharpness", &myCustomSetup.sharpness },
{ "resolution", &myCustomSetup.resolution }, { "resolution", &myCustomSetup.resolution },
{ "artifacts", &myCustomSetup.artifacts }, { "artifacts", &myCustomSetup.artifacts },

View File

@ -51,8 +51,12 @@ class NTSCFilter
/* Normally used in conjunction with custom mode, contains all /* Normally used in conjunction with custom mode, contains all
aspects currently adjustable in NTSC TV emulation. */ aspects currently adjustable in NTSC TV emulation. */
struct Adjustable { struct Adjustable {
#ifdef BLARGG_PALETTE
uInt32 hue, saturation, contrast, brightness, gamma, uInt32 hue, saturation, contrast, brightness, gamma,
sharpness, resolution, artifacts, fringing, bleed; sharpness, resolution, artifacts, fringing, bleed;
#else
uInt32 sharpness, resolution, artifacts, fringing, bleed;
#endif
}; };
public: public:
@ -139,7 +143,11 @@ class NTSCFilter
float* value{nullptr}; float* value{nullptr};
}; };
uInt32 myCurrentAdjustable{0}; uInt32 myCurrentAdjustable{0};
#ifdef BLARGG_PALETTE
static const std::array<AdjustableTag, 10> ourCustomAdjustables; static const std::array<AdjustableTag, 10> ourCustomAdjustables;
#else
static const std::array<AdjustableTag, 5> ourCustomAdjustables;
#endif
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported

View File

@ -62,7 +62,6 @@
#include "AudioSettings.hxx" #include "AudioSettings.hxx"
#include "frame-manager/FrameManager.hxx" #include "frame-manager/FrameManager.hxx"
#include "frame-manager/FrameLayoutDetector.hxx" #include "frame-manager/FrameLayoutDetector.hxx"
#include "PaletteHandler.hxx"
#ifdef CHEATCODE_SUPPORT #ifdef CHEATCODE_SUPPORT
#include "CheatManager.hxx" #include "CheatManager.hxx"
@ -88,7 +87,6 @@ Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
myTIA = make_unique<TIA>(*this, [this]() { return timing(); }, myOSystem.settings()); myTIA = make_unique<TIA>(*this, [this]() { return timing(); }, myOSystem.settings());
myFrameManager = make_unique<FrameManager>(); myFrameManager = make_unique<FrameManager>();
mySwitches = make_unique<Switches>(myEvent, myProperties, myOSystem.settings()); mySwitches = make_unique<Switches>(myEvent, myProperties, myOSystem.settings());
myPaletteHandler = make_unique<PaletteHandler>(myOSystem);
myTIA->setFrameManager(myFrameManager.get()); myTIA->setFrameManager(myFrameManager.get());
@ -436,7 +434,6 @@ void Console::setFormat(uInt32 format)
myConsoleInfo.DisplayFormat = myDisplayFormat + autodetected; myConsoleInfo.DisplayFormat = myDisplayFormat + autodetected;
myPaletteHandler->setPalette();
setTIAProperties(); setTIAProperties();
initializeVideo(); // takes care of refreshing the screen initializeVideo(); // takes care of refreshing the screen
initializeAudio(); // ensure that audio synthesis is set up to match emulation speed initializeAudio(); // ensure that audio synthesis is set up to match emulation speed
@ -582,10 +579,7 @@ FBInitStatus Console::initializeVideo(bool full)
myOSystem.frameBuffer().showFrameStats( myOSystem.frameBuffer().showFrameStats(
myOSystem.settings().getBool(devSettings ? "dev.stats" : "plr.stats")); myOSystem.settings().getBool(devSettings ? "dev.stats" : "plr.stats"));
myPaletteHandler->generatePalettes();
} }
myPaletteHandler->setPalette();
return fbstatus; return fbstatus;
} }

View File

@ -29,7 +29,6 @@ class CompuMate;
class Debugger; class Debugger;
class AudioQueue; class AudioQueue;
class AudioSettings; class AudioSettings;
class PaletteHandler;
#include "bspf.hxx" #include "bspf.hxx"
#include "ConsoleIO.hxx" #include "ConsoleIO.hxx"
@ -40,7 +39,6 @@ class PaletteHandler;
#include "FrameBufferConstants.hxx" #include "FrameBufferConstants.hxx"
#include "Serializable.hxx" #include "Serializable.hxx"
#include "EventHandlerConstants.hxx" #include "EventHandlerConstants.hxx"
#include "NTSCFilter.hxx"
#include "EmulationTiming.hxx" #include "EmulationTiming.hxx"
#include "ConsoleTiming.hxx" #include "ConsoleTiming.hxx"
#include "frame-manager/AbstractFrameManager.hxx" #include "frame-manager/AbstractFrameManager.hxx"
@ -187,11 +185,6 @@ class Console : public Serializable, public ConsoleIO
*/ */
EmulationTiming& emulationTiming() { return myEmulationTiming; } EmulationTiming& emulationTiming() { return myEmulationTiming; }
/**
Retrieve palette handler.
*/
PaletteHandler& paletteHandler() const { return *myPaletteHandler; }
public: public:
/** /**
Toggle between NTSC/PAL/SECAM (and variants) display format. Toggle between NTSC/PAL/SECAM (and variants) display format.
@ -424,9 +417,6 @@ class Console : public Serializable, public ConsoleIO
// The audio settings // The audio settings
AudioSettings& myAudioSettings; AudioSettings& myAudioSettings;
// The palette handling
unique_ptr<PaletteHandler>myPaletteHandler;
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported
Console() = delete; Console() = delete;

View File

@ -22,7 +22,6 @@
#include <set> #include <set>
#include "bspf.hxx" #include "bspf.hxx"
#include "StellaKeys.hxx"
/** /**
@author Stephen Anthony, Christian Speckner, Thomas Jentzsch @author Stephen Anthony, Christian Speckner, Thomas Jentzsch
@ -92,6 +91,7 @@ class Event
TogglePauseMode, StartPauseMode, TogglePauseMode, StartPauseMode,
OptionsMenuMode, CmdMenuMode, DebuggerMode, ExitMode, OptionsMenuMode, CmdMenuMode, DebuggerMode, ExitMode,
TakeSnapshot, ToggleContSnapshots, ToggleContSnapshotsFrame, TakeSnapshot, ToggleContSnapshots, ToggleContSnapshotsFrame,
ToggleTurbo,
NextState, PreviousState, LoadState, SaveState, NextState, PreviousState, LoadState, SaveState,
SaveAllStates, LoadAllStates, SaveAllStates, LoadAllStates,
@ -100,12 +100,16 @@ class Event
Unwind1Menu, Unwind10Menu, UnwindAllMenu, Unwind1Menu, Unwind10Menu, UnwindAllMenu,
RewindPause, UnwindPause, RewindPause, UnwindPause,
FormatDecrease, FormatIncrease, PaletteIncrease, ToggleColorLoss, FormatDecrease, FormatIncrease, PaletteDecrease, PaletteIncrease, ToggleColorLoss,
ColorShiftDecrease, ColorShiftIncrease,
PreviousPaletteAttribute, NextPaletteAttribute,
PaletteAttributeDecrease, PaletteAttributeIncrease,
ToggleFullScreen, VidmodeDecrease, VidmodeIncrease, ToggleFullScreen, VidmodeDecrease, VidmodeIncrease,
VCenterDecrease, VCenterIncrease, ScanlineAdjustDecrease, ScanlineAdjustIncrease, VCenterDecrease, VCenterIncrease, ScanlineAdjustDecrease, ScanlineAdjustIncrease,
OverscanDecrease, OverscanIncrease, OverscanDecrease, OverscanIncrease,
VidmodeStd, VidmodeRGB, VidmodeSVideo, VidModeComposite, VidModeBad, VidModeCustom, VidmodeStd, VidmodeRGB, VidmodeSVideo, VidModeComposite, VidModeBad, VidModeCustom,
PreviousVideoMode, NextVideoMode,
PreviousAttribute, NextAttribute, DecreaseAttribute, IncreaseAttribute, PreviousAttribute, NextAttribute, DecreaseAttribute, IncreaseAttribute,
ScanlinesDecrease, ScanlinesIncrease, ScanlinesDecrease, ScanlinesIncrease,
PhosphorDecrease, PhosphorIncrease, TogglePhosphor, ToggleInter, ToggleJitter, PhosphorDecrease, PhosphorIncrease, TogglePhosphor, ToggleInter, ToggleJitter,
@ -118,10 +122,7 @@ class Event
ToggleCollisions, ToggleBits, ToggleFixedColors, ToggleCollisions, ToggleBits, ToggleFixedColors,
ToggleFrameStats, ToggleSAPortOrder, ExitGame, ToggleFrameStats, ToggleSAPortOrder, ExitGame,
// add new events from here to avoid that user remapped events get overwritten // add new events from here to avoid that user remapped events get overwritten
ToggleTurbo, PaletteDecrease,
ColorShiftDecrease, ColorShiftIncrease,
LastType LastType
}; };
@ -136,7 +137,7 @@ class Event
}; };
// Event list version, update only if the id of existing(!) event types changed // Event list version, update only if the id of existing(!) event types changed
static constexpr Int32 VERSION = 3; static constexpr Int32 VERSION = 4;
using EventSet = std::set<Event::Type>; using EventSet = std::set<Event::Type>;

View File

@ -436,12 +436,28 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
if (pressed) myOSystem.console().changeScanlineAdjust(+1); if (pressed) myOSystem.console().changeScanlineAdjust(+1);
return; return;
case Event::PreviousPaletteAttribute:
if (pressed) myOSystem.frameBuffer().tiaSurface().paletteHandler().selectAdjustable(false);
return;
case Event::NextPaletteAttribute:
if (pressed) myOSystem.frameBuffer().tiaSurface().paletteHandler().selectAdjustable(true);
return;
case Event::PaletteAttributeDecrease:
if (pressed) myOSystem.frameBuffer().tiaSurface().paletteHandler().changeAdjustable(false);
return;
case Event::PaletteAttributeIncrease:
if (pressed) myOSystem.frameBuffer().tiaSurface().paletteHandler().changeAdjustable(true);
return;
case Event::ColorShiftDecrease: case Event::ColorShiftDecrease:
if (pressed) myOSystem.console().paletteHandler().changeColorPhaseShift(false); if (pressed) myOSystem.frameBuffer().tiaSurface().paletteHandler().changeColorPhaseShift(false);
return; return;
case Event::ColorShiftIncrease: case Event::ColorShiftIncrease:
if (pressed) myOSystem.console().paletteHandler().changeColorPhaseShift(); if (pressed) myOSystem.frameBuffer().tiaSurface().paletteHandler().changeColorPhaseShift(true);
return; return;
case Event::ToggleFullScreen: case Event::ToggleFullScreen:
@ -456,6 +472,14 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
if (pressed) myOSystem.frameBuffer().changeOverscan(1); if (pressed) myOSystem.frameBuffer().changeOverscan(1);
return; return;
case Event::PreviousVideoMode:
if (pressed && !repeated) myOSystem.frameBuffer().tiaSurface().changeNTSC(false);
return;
case Event::NextVideoMode:
if (pressed && !repeated) myOSystem.frameBuffer().tiaSurface().changeNTSC(true);
return;
case Event::VidmodeStd: case Event::VidmodeStd:
if (pressed && !repeated) myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::Preset::OFF); if (pressed && !repeated) myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::Preset::OFF);
return; return;
@ -541,11 +565,11 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
return; return;
case Event::PaletteDecrease: case Event::PaletteDecrease:
if (pressed && !repeated) myOSystem.console().paletteHandler().changePalette(false); if (pressed && !repeated) myOSystem.frameBuffer().tiaSurface().paletteHandler().changePalette(false);
return; return;
case Event::PaletteIncrease: case Event::PaletteIncrease:
if (pressed && !repeated) myOSystem.console().paletteHandler().changePalette(); if (pressed && !repeated) myOSystem.frameBuffer().tiaSurface().paletteHandler().changePalette(true);
return; return;
case Event::ToggleInter: case Event::ToggleInter:
@ -1934,22 +1958,30 @@ EventHandler::EmulActionList EventHandler::ourEmulActionList = { {
{ Event::VCenterIncrease, "Move display down", "" }, { Event::VCenterIncrease, "Move display down", "" },
{ Event::FormatDecrease, "Decrease display format", "" }, { Event::FormatDecrease, "Decrease display format", "" },
{ Event::FormatIncrease, "Increase display format", "" }, { Event::FormatIncrease, "Increase display format", "" },
// Palette settings
{ Event::PaletteDecrease, "Switch to previous palette", "" }, { Event::PaletteDecrease, "Switch to previous palette", "" },
{ Event::PaletteIncrease, "Switch to next palette", "" }, { Event::PaletteIncrease, "Switch to next palette", "" },
{ Event::PreviousPaletteAttribute,"Select previous palette attribute", "" },
{ Event::NextPaletteAttribute, "Select next palette attribute", "" },
{ Event::PaletteAttributeDecrease,"Decrease selected palette attribute", "" },
{ Event::PaletteAttributeIncrease,"Increase selected palette attribute", "" },
{ Event::ColorShiftDecrease, "Decrease custom palette phase shift", "" }, { Event::ColorShiftDecrease, "Decrease custom palette phase shift", "" },
{ Event::ColorShiftIncrease, "Increase custom palette phase shift", "" }, { Event::ColorShiftIncrease, "Increase custom palette phase shift", "" },
{ Event::ToggleInter, "Toggle display interpolation", "" }, { Event::ToggleInter, "Toggle display interpolation", "" },
// TV effects: // Blargg TV effects:
{ Event::VidmodeStd, "Disable TV effects", "" }, { Event::VidmodeStd, "Disable TV effects", "" },
{ Event::VidmodeRGB, "Select 'RGB' preset", "" }, { Event::VidmodeRGB, "Select 'RGB' preset", "" },
{ Event::VidmodeSVideo, "Select 'S-Video' preset", "" }, { Event::VidmodeSVideo, "Select 'S-Video' preset", "" },
{ Event::VidModeComposite, "Select 'Composite' preset", "" }, { Event::VidModeComposite, "Select 'Composite' preset", "" },
{ Event::VidModeBad, "Select 'Badly adjusted' preset", "" }, { Event::VidModeBad, "Select 'Badly adjusted' preset", "" },
{ Event::VidModeCustom, "Select 'Custom' preset", "" }, { Event::VidModeCustom, "Select 'Custom' preset", "" },
{ Event::PreviousVideoMode, "Select previous TV effect mode preset", "" },
{ Event::NextVideoMode, "Select next TV effect mode preset", "" },
{ Event::PreviousAttribute, "Select previous 'Custom' attribute", "" }, { Event::PreviousAttribute, "Select previous 'Custom' attribute", "" },
{ Event::NextAttribute, "Select next 'Custom' attribute", "" }, { Event::NextAttribute, "Select next 'Custom' attribute", "" },
{ Event::DecreaseAttribute, "Decrease selected 'Custom' attribute", "" }, { Event::DecreaseAttribute, "Decrease selected 'Custom' attribute", "" },
{ Event::IncreaseAttribute, "Increase selected 'Custom' attribute", "" }, { Event::IncreaseAttribute, "Increase selected 'Custom' attribute", "" },
// Other TV effects
{ Event::TogglePhosphor, "Toggle 'phosphor' effect", "" }, { Event::TogglePhosphor, "Toggle 'phosphor' effect", "" },
{ Event::PhosphorDecrease, "Decrease 'phosphor' blend", "" }, { Event::PhosphorDecrease, "Decrease 'phosphor' blend", "" },
{ Event::PhosphorIncrease, "Increase 'phosphor' blend", "" }, { Event::PhosphorIncrease, "Increase 'phosphor' blend", "" },
@ -2066,6 +2098,9 @@ const Event::EventSet EventHandler::AudioVideoEvents = {
Event::OverscanDecrease, Event::OverscanIncrease, Event::OverscanDecrease, Event::OverscanIncrease,
Event::PaletteDecrease, Event::PaletteIncrease, Event::PaletteDecrease, Event::PaletteIncrease,
Event::ColorShiftDecrease, Event::ColorShiftIncrease, Event::ColorShiftDecrease, Event::ColorShiftIncrease,
Event::PreviousVideoMode, Event::NextVideoMode,
Event::PreviousPaletteAttribute, Event::NextPaletteAttribute,
Event::PaletteAttributeDecrease, Event::PaletteAttributeIncrease,
Event::ToggleInter Event::ToggleInter
}; };

View File

@ -25,6 +25,7 @@ class OSystem;
class MouseControl; class MouseControl;
class DialogContainer; class DialogContainer;
class PhysicalJoystick; class PhysicalJoystick;
class Variant;
namespace GUI { namespace GUI {
class Font; class Font;
@ -36,7 +37,6 @@ namespace GUI {
#include "StellaKeys.hxx" #include "StellaKeys.hxx"
#include "PKeyboardHandler.hxx" #include "PKeyboardHandler.hxx"
#include "PJoystickHandler.hxx" #include "PJoystickHandler.hxx"
#include "Variant.hxx"
#include "bspf.hxx" #include "bspf.hxx"
/** /**
@ -468,7 +468,7 @@ class EventHandler
#else #else
PNG_SIZE = 0, PNG_SIZE = 0,
#endif #endif
EMUL_ACTIONLIST_SIZE = 150 + PNG_SIZE + COMBO_SIZE, EMUL_ACTIONLIST_SIZE = 154 + PNG_SIZE + COMBO_SIZE,
MENU_ACTIONLIST_SIZE = 18 MENU_ACTIONLIST_SIZE = 18
; ;

View File

@ -49,6 +49,7 @@
#include "CartDetector.hxx" #include "CartDetector.hxx"
#include "FrameBuffer.hxx" #include "FrameBuffer.hxx"
#include "TIASurface.hxx" #include "TIASurface.hxx"
#include "PaletteHandler.hxx"
#include "TIAConstants.hxx" #include "TIAConstants.hxx"
#include "Settings.hxx" #include "Settings.hxx"
#include "PropsSet.hxx" #include "PropsSet.hxx"
@ -243,6 +244,8 @@ void OSystem::saveConfig()
Logger::debug("Saving TV effects options ..."); Logger::debug("Saving TV effects options ...");
myFrameBuffer->tiaSurface().ntsc().saveConfig(settings()); myFrameBuffer->tiaSurface().ntsc().saveConfig(settings());
Logger::debug("Saving palette settings...");
myFrameBuffer->tiaSurface().paletteHandler().saveConfig(settings());
} }
Logger::debug("Saving config options ..."); Logger::debug("Saving config options ...");

View File

@ -46,8 +46,6 @@ Settings::Settings()
setPermanent("windowedpos", Common::Point(50, 50)); setPermanent("windowedpos", Common::Point(50, 50));
setPermanent("display", 0); setPermanent("display", 0);
setPermanent("palette", "standard"); setPermanent("palette", "standard");
setPermanent("phase_ntsc", "26.2");
setPermanent("phase_pal", "31.3");
setPermanent("uimessages", "true"); setPermanent("uimessages", "true");
// TIA specific options // TIA specific options
@ -64,6 +62,8 @@ Settings::Settings()
setPermanent("tv.phosphor", "byrom"); setPermanent("tv.phosphor", "byrom");
setPermanent("tv.phosblend", "50"); setPermanent("tv.phosblend", "50");
setPermanent("tv.scanlines", "25"); setPermanent("tv.scanlines", "25");
setPermanent("tv.phase_ntsc", "26.2");
setPermanent("tv.phase_pal", "31.3");
setPermanent("tv.contrast", "0.0"); setPermanent("tv.contrast", "0.0");
setPermanent("tv.brightness", "0.0"); setPermanent("tv.brightness", "0.0");
setPermanent("tv.hue", "0.0"); setPermanent("tv.hue", "0.0");

View File

@ -23,6 +23,7 @@
#include "Console.hxx" #include "Console.hxx"
#include "TIA.hxx" #include "TIA.hxx"
#include "PNGLibrary.hxx" #include "PNGLibrary.hxx"
#include "PaletteHandler.hxx"
#include "TIASurface.hxx" #include "TIASurface.hxx"
namespace { namespace {
@ -76,6 +77,9 @@ TIASurface::TIASurface(OSystem& system)
// Enable/disable threading in the NTSC TV effects renderer // Enable/disable threading in the NTSC TV effects renderer
myNTSCFilter.enableThreading(myOSystem.settings().getBool("threads")); myNTSCFilter.enableThreading(myOSystem.settings().getBool("threads"));
myPaletteHandler = make_unique<PaletteHandler>(myOSystem);
myPaletteHandler->loadConfig(myOSystem.settings());
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -89,6 +93,8 @@ void TIASurface::initialize(const Console& console,
mySLineSurface->setDstPos(mode.image.x(), mode.image.y()); mySLineSurface->setDstPos(mode.image.x(), mode.image.y());
mySLineSurface->setDstSize(mode.image.w(), mode.image.h()); mySLineSurface->setDstSize(mode.image.w(), mode.image.h());
myPaletteHandler->setPalette();
// Phosphor mode can be enabled either globally or per-ROM // Phosphor mode can be enabled either globally or per-ROM
int p_blend = 0; int p_blend = 0;
bool enable = false; bool enable = false;
@ -188,6 +194,32 @@ void TIASurface::setNTSC(NTSCFilter::Preset preset, bool show)
if(show) myFB.showMessage(buf.str()); if(show) myFB.showMessage(buf.str());
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIASurface::changeNTSC(bool next, bool show)
{
constexpr NTSCFilter::Preset PRESETS[] = {
NTSCFilter::Preset::OFF, NTSCFilter::Preset::RGB, NTSCFilter::Preset::SVIDEO,
NTSCFilter::Preset::COMPOSITE, NTSCFilter::Preset::BAD, NTSCFilter::Preset::CUSTOM
};
int preset = myOSystem.settings().getInt("tv.filter");
if(next)
{
if(preset == int(NTSCFilter::Preset::CUSTOM))
preset = int(NTSCFilter::Preset::OFF);
else
preset++;
}
else
{
if(preset == int(NTSCFilter::Preset::OFF))
preset = int(NTSCFilter::Preset::CUSTOM);
else
preset--;
}
setNTSC(PRESETS[preset], show);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIASurface::setScanlineIntensity(int amount) void TIASurface::setScanlineIntensity(int amount)
{ {

View File

@ -22,6 +22,7 @@ class TIA;
class Console; class Console;
class OSystem; class OSystem;
class FBSurface; class FBSurface;
class PaletteHandler;
#include <thread> #include <thread>
@ -49,6 +50,8 @@ class TIASurface
*/ */
explicit TIASurface(OSystem& system); explicit TIASurface(OSystem& system);
virtual ~TIASurface() = default;
/** /**
Set the TIA object, which is needed for actually rendering the TIA image. Set the TIA object, which is needed for actually rendering the TIA image.
*/ */
@ -87,6 +90,16 @@ class TIASurface
*/ */
void setNTSC(NTSCFilter::Preset preset, bool show = true); void setNTSC(NTSCFilter::Preset preset, bool show = true);
/**
Switch to next/previous NTSC filtering effect.
*/
void changeNTSC(bool next, bool show = true);
/**
Retrieve palette handler.
*/
PaletteHandler& paletteHandler() const { return *myPaletteHandler; }
/** /**
Increase/decrease current scanline intensity by given relative amount. Increase/decrease current scanline intensity by given relative amount.
*/ */
@ -100,7 +113,6 @@ class TIASurface
@return New current intensity @return New current intensity
*/ */
uInt32 enableScanlines(int relative, int absolute = 50); uInt32 enableScanlines(int relative, int absolute = 50);
void enableScanlineInterpolation(bool enable);
/** /**
Enable/disable/query phosphor effect. Enable/disable/query phosphor effect.
@ -183,6 +195,9 @@ class TIASurface
// Flag for saving a snapshot // Flag for saving a snapshot
bool mySaveSnapFlag{false}; bool mySaveSnapFlag{false};
// The palette handler
unique_ptr<PaletteHandler>myPaletteHandler;
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported
TIASurface() = delete; TIASurface() = delete;

View File

@ -204,7 +204,7 @@ void CommandDialog::handleCommand(CommandSender* sender, int cmd,
break; break;
case kPaletteCmd: case kPaletteCmd:
instance().console().paletteHandler().changePalette(); instance().frameBuffer().tiaSurface().paletteHandler().changePalette();
updatePalette(); updatePalette();
break; break;

View File

@ -367,8 +367,8 @@ void VideoDialog::loadConfig()
instance().settings().getString("palette"), "standard"); instance().settings().getString("palette"), "standard");
// Custom Palette // Custom Palette
myPhaseShiftNtsc->setValue(instance().settings().getFloat("phase_ntsc") * 10); myPhaseShiftNtsc->setValue(instance().settings().getFloat("tv.phase_ntsc") * 10);
myPhaseShiftPal->setValue(instance().settings().getFloat("phase_pal") * 10); myPhaseShiftPal->setValue(instance().settings().getFloat("tv.phase_pal") * 10);
handlePaletteChange(); handlePaletteChange();
// TIA interpolation // TIA interpolation
@ -413,6 +413,15 @@ void VideoDialog::loadConfig()
int preset = instance().settings().getInt("tv.filter"); int preset = instance().settings().getInt("tv.filter");
handleTVModeChange(NTSCFilter::Preset(preset)); handleTVModeChange(NTSCFilter::Preset(preset));
// Palette adjustables
PaletteHandler::Adjustable paletteAdj;
instance().frameBuffer().tiaSurface().paletteHandler().getAdjustables(paletteAdj);
myTVHue->setValue(paletteAdj.hue);
myTVBright->setValue(paletteAdj.brightness);
myTVContrast->setValue(paletteAdj.contrast);
myTVSatur->setValue(paletteAdj.saturation);
myTVGamma->setValue(paletteAdj.gamma);
// TV Custom adjustables // TV Custom adjustables
loadTVAdjustables(NTSCFilter::Preset::CUSTOM); loadTVAdjustables(NTSCFilter::Preset::CUSTOM);
@ -444,8 +453,8 @@ void VideoDialog::saveConfig()
myTIAPalette->getSelectedTag().toString()); myTIAPalette->getSelectedTag().toString());
// Custom Palette // Custom Palette
instance().settings().setValue("phase_ntsc", myPhaseShiftNtsc->getValue() / 10.0); instance().settings().setValue("tv.phase_ntsc", myPhaseShiftNtsc->getValue() / 10.0);
instance().settings().setValue("phase_pal", myPhaseShiftPal->getValue() / 10.0); instance().settings().setValue("tv.phase_pal", myPhaseShiftPal->getValue() / 10.0);
// TIA interpolation // TIA interpolation
instance().settings().setValue("tia.inter", myTIAInterpolate->getState()); instance().settings().setValue("tia.inter", myTIAInterpolate->getState());
@ -490,19 +499,23 @@ void VideoDialog::saveConfig()
instance().settings().setValue("tv.filter", instance().settings().setValue("tv.filter",
myTVMode->getSelectedTag().toString()); myTVMode->getSelectedTag().toString());
// Palette adjustables
PaletteHandler::Adjustable paletteAdj;
paletteAdj.hue = myTVHue->getValue();
paletteAdj.saturation = myTVSatur->getValue();
paletteAdj.contrast = myTVContrast->getValue();
paletteAdj.brightness = myTVBright->getValue();
paletteAdj.gamma = myTVGamma->getValue();
instance().frameBuffer().tiaSurface().paletteHandler().setAdjustables(paletteAdj);
// TV Custom adjustables // TV Custom adjustables
NTSCFilter::Adjustable adj; NTSCFilter::Adjustable ntscAdj;
adj.hue = myTVHue->getValue(); ntscAdj.sharpness = myTVSharp->getValue();
adj.saturation = myTVSatur->getValue(); ntscAdj.resolution = myTVRes->getValue();
adj.contrast = myTVContrast->getValue(); ntscAdj.artifacts = myTVArtifacts->getValue();
adj.brightness = myTVBright->getValue(); ntscAdj.fringing = myTVFringe->getValue();
adj.sharpness = myTVSharp->getValue(); ntscAdj.bleed = myTVBleed->getValue();
adj.gamma = myTVGamma->getValue(); instance().frameBuffer().tiaSurface().ntsc().setCustomAdjustables(ntscAdj);
adj.resolution = myTVRes->getValue();
adj.artifacts = myTVArtifacts->getValue();
adj.fringing = myTVFringe->getValue();
adj.bleed = myTVBleed->getValue();
instance().frameBuffer().tiaSurface().ntsc().setCustomAdjustables(adj);
// TV phosphor mode // TV phosphor mode
instance().settings().setValue("tv.phosphor", instance().settings().setValue("tv.phosphor",
@ -520,8 +533,8 @@ void VideoDialog::saveConfig()
if(instance().settings().getString("palette") == "custom") if(instance().settings().getString("palette") == "custom")
{ {
instance().console().paletteHandler().generateCustomPalette(ConsoleTiming::ntsc); instance().frameBuffer().tiaSurface().paletteHandler().generateCustomPalette(ConsoleTiming::ntsc);
instance().console().paletteHandler().generateCustomPalette(ConsoleTiming::pal); instance().frameBuffer().tiaSurface().paletteHandler().generateCustomPalette(ConsoleTiming::pal);
} }
if(vsizeChanged) if(vsizeChanged)
@ -595,15 +608,10 @@ void VideoDialog::handleTVModeChange(NTSCFilter::Preset preset)
bool enable = preset == NTSCFilter::Preset::CUSTOM; bool enable = preset == NTSCFilter::Preset::CUSTOM;
myTVSharp->setEnabled(enable); myTVSharp->setEnabled(enable);
myTVHue->setEnabled(enable);
myTVRes->setEnabled(enable); myTVRes->setEnabled(enable);
myTVArtifacts->setEnabled(enable); myTVArtifacts->setEnabled(enable);
myTVFringe->setEnabled(enable); myTVFringe->setEnabled(enable);
myTVBleed->setEnabled(enable); myTVBleed->setEnabled(enable);
myTVBright->setEnabled(enable);
myTVContrast->setEnabled(enable);
myTVSatur->setEnabled(enable);
myTVGamma->setEnabled(enable);
myCloneComposite->setEnabled(enable); myCloneComposite->setEnabled(enable);
myCloneSvideo->setEnabled(enable); myCloneSvideo->setEnabled(enable);
myCloneRGB->setEnabled(enable); myCloneRGB->setEnabled(enable);
@ -618,15 +626,10 @@ void VideoDialog::loadTVAdjustables(NTSCFilter::Preset preset)
instance().frameBuffer().tiaSurface().ntsc().getAdjustables( instance().frameBuffer().tiaSurface().ntsc().getAdjustables(
adj, NTSCFilter::Preset(preset)); adj, NTSCFilter::Preset(preset));
myTVSharp->setValue(adj.sharpness); myTVSharp->setValue(adj.sharpness);
myTVHue->setValue(adj.hue);
myTVRes->setValue(adj.resolution); myTVRes->setValue(adj.resolution);
myTVArtifacts->setValue(adj.artifacts); myTVArtifacts->setValue(adj.artifacts);
myTVFringe->setValue(adj.fringing); myTVFringe->setValue(adj.fringing);
myTVBleed->setValue(adj.bleed); myTVBleed->setValue(adj.bleed);
myTVBright->setValue(adj.brightness);
myTVContrast->setValue(adj.contrast);
myTVSatur->setValue(adj.saturation);
myTVGamma->setValue(adj.gamma);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -31,6 +31,7 @@ namespace GUI {
#include "bspf.hxx" #include "bspf.hxx"
#include "Event.hxx" #include "Event.hxx"
#include "StellaKeys.hxx"
#include "GuiObject.hxx" #include "GuiObject.hxx"
#include "Font.hxx" #include "Font.hxx"