mirror of https://github.com/stella-emu/stella.git
added interactive palette display to VideoDialog
This commit is contained in:
parent
8fc7413d8f
commit
441aa6c867
|
@ -46,7 +46,7 @@ PaletteHandler::PaletteType PaletteHandler::toPaletteType(const string& name) co
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
string PaletteHandler::toPaletteName(PaletteType type) const
|
string PaletteHandler::toPaletteName(PaletteType type) const
|
||||||
{
|
{
|
||||||
string SETTING_NAMES[int(PaletteType::NumTypes)] = {
|
const string SETTING_NAMES[int(PaletteType::NumTypes)] = {
|
||||||
SETTING_STANDARD, SETTING_Z26, SETTING_USER, SETTING_CUSTOM
|
SETTING_STANDARD, SETTING_Z26, SETTING_USER, SETTING_CUSTOM
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ string PaletteHandler::toPaletteName(PaletteType type) const
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void PaletteHandler::changePalette(bool increase)
|
void PaletteHandler::changePalette(bool increase)
|
||||||
{
|
{
|
||||||
string MESSAGES[PaletteType::NumTypes] = {
|
const string MESSAGES[PaletteType::NumTypes] = {
|
||||||
"Standard Stella", "Z26", "User-defined", "Custom"
|
"Standard Stella", "Z26", "User-defined", "Custom"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ void PaletteHandler::changePalette(bool increase)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void PaletteHandler::selectAdjustable(bool next)
|
void PaletteHandler::selectAdjustable(bool next)
|
||||||
{
|
{
|
||||||
bool isCustomPalette = "custom" == myOSystem.settings().getString("palette");
|
const bool isCustomPalette = "custom" == myOSystem.settings().getString("palette");
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if(next)
|
if(next)
|
||||||
|
@ -154,10 +154,54 @@ void PaletteHandler::changeAdjustable(bool increase)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void PaletteHandler::changeColorPhaseShift(bool increase)
|
||||||
|
{
|
||||||
|
const ConsoleTiming timing = myOSystem.console().timing();
|
||||||
|
|
||||||
|
// SECAM is not supported
|
||||||
|
if(timing != ConsoleTiming::secam)
|
||||||
|
{
|
||||||
|
constexpr char DEGREE = 0x1c;
|
||||||
|
const bool isNTSC = timing == ConsoleTiming::ntsc;
|
||||||
|
const float shift = isNTSC ? DEF_NTSC_SHIFT : DEF_PAL_SHIFT;
|
||||||
|
float phase = isNTSC ? myPhaseNTSC : myPhasePAL;
|
||||||
|
|
||||||
|
if(increase) // increase color phase shift
|
||||||
|
{
|
||||||
|
phase += 0.3F;
|
||||||
|
phase = std::min(phase, shift + MAX_SHIFT);
|
||||||
|
}
|
||||||
|
else // decrease color phase shift
|
||||||
|
{
|
||||||
|
phase -= 0.3F;
|
||||||
|
phase = std::max(phase, shift - MAX_SHIFT);
|
||||||
|
}
|
||||||
|
if(isNTSC)
|
||||||
|
myPhaseNTSC = phase;
|
||||||
|
else
|
||||||
|
myPhasePAL = phase;
|
||||||
|
|
||||||
|
generateCustomPalette(timing);
|
||||||
|
setPalette("custom");
|
||||||
|
|
||||||
|
ostringstream ss;
|
||||||
|
ss << "Color phase shift at "
|
||||||
|
<< std::fixed << std::setprecision(1) << phase << DEGREE;
|
||||||
|
|
||||||
|
myOSystem.frameBuffer().showMessage(ss.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void PaletteHandler::loadConfig(const Settings& settings)
|
void PaletteHandler::loadConfig(const Settings& settings)
|
||||||
{
|
{
|
||||||
// Load adjustables
|
// Load adjustables
|
||||||
|
myPhaseNTSC = BSPF::clamp(settings.getFloat("tv.phase_ntsc"),
|
||||||
|
DEF_NTSC_SHIFT - MAX_SHIFT, DEF_NTSC_SHIFT + MAX_SHIFT);
|
||||||
|
myPhasePAL = BSPF::clamp(settings.getFloat("tv.phase_pal"),
|
||||||
|
DEF_PAL_SHIFT - MAX_SHIFT, DEF_PAL_SHIFT + MAX_SHIFT);
|
||||||
|
|
||||||
myHue = BSPF::clamp(settings.getFloat("tv.hue"), -1.0F, 1.0F);
|
myHue = BSPF::clamp(settings.getFloat("tv.hue"), -1.0F, 1.0F);
|
||||||
mySaturation = BSPF::clamp(settings.getFloat("tv.saturation"), -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);
|
myContrast = BSPF::clamp(settings.getFloat("tv.contrast"), -1.0F, 1.0F);
|
||||||
|
@ -169,6 +213,9 @@ void PaletteHandler::loadConfig(const Settings& settings)
|
||||||
void PaletteHandler::saveConfig(Settings& settings) const
|
void PaletteHandler::saveConfig(Settings& settings) const
|
||||||
{
|
{
|
||||||
// Save adjustables
|
// Save adjustables
|
||||||
|
settings.setValue("tv.phase_ntsc", myPhaseNTSC);
|
||||||
|
settings.setValue("tv.phase_pal", myPhasePAL);
|
||||||
|
|
||||||
settings.setValue("tv.hue", myHue);
|
settings.setValue("tv.hue", myHue);
|
||||||
settings.setValue("tv.saturation", mySaturation);
|
settings.setValue("tv.saturation", mySaturation);
|
||||||
settings.setValue("tv.contrast", myContrast);
|
settings.setValue("tv.contrast", myContrast);
|
||||||
|
@ -177,8 +224,11 @@ void PaletteHandler::saveConfig(Settings& settings) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void PaletteHandler::setAdjustables(Adjustable& adjustable)
|
void PaletteHandler::setAdjustables(const Adjustable& adjustable)
|
||||||
{
|
{
|
||||||
|
myPhaseNTSC = adjustable.phaseNtsc / 10.F;
|
||||||
|
myPhasePAL = adjustable.phasePal / 10.F;
|
||||||
|
|
||||||
myHue = scaleFrom100(adjustable.hue);
|
myHue = scaleFrom100(adjustable.hue);
|
||||||
mySaturation = scaleFrom100(adjustable.saturation);
|
mySaturation = scaleFrom100(adjustable.saturation);
|
||||||
myContrast = scaleFrom100(adjustable.contrast);
|
myContrast = scaleFrom100(adjustable.contrast);
|
||||||
|
@ -189,6 +239,9 @@ void PaletteHandler::setAdjustables(Adjustable& adjustable)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void PaletteHandler::getAdjustables(Adjustable& adjustable) const
|
void PaletteHandler::getAdjustables(Adjustable& adjustable) const
|
||||||
{
|
{
|
||||||
|
adjustable.phaseNtsc = myPhaseNTSC * 10.F;
|
||||||
|
adjustable.phasePal = myPhasePAL * 10.F;
|
||||||
|
|
||||||
adjustable.hue = scaleTo100(myHue);
|
adjustable.hue = scaleTo100(myHue);
|
||||||
adjustable.saturation = scaleTo100(mySaturation);
|
adjustable.saturation = scaleTo100(mySaturation);
|
||||||
adjustable.contrast = scaleTo100(myContrast);
|
adjustable.contrast = scaleTo100(myContrast);
|
||||||
|
@ -196,46 +249,6 @@ void PaletteHandler::getAdjustables(Adjustable& adjustable) const
|
||||||
adjustable.gamma = scaleTo100(myGamma);
|
adjustable.gamma = scaleTo100(myGamma);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void PaletteHandler::changeColorPhaseShift(bool increase)
|
|
||||||
{
|
|
||||||
const ConsoleTiming timing = myOSystem.console().timing();
|
|
||||||
|
|
||||||
// SECAM is not supported
|
|
||||||
if(timing != ConsoleTiming::secam)
|
|
||||||
{
|
|
||||||
const char DEGREE = 0x1c;
|
|
||||||
const float NTSC_SHIFT = 26.2F;
|
|
||||||
const float PAL_SHIFT = 31.3F; // 360 / 11.5
|
|
||||||
const bool isNTSC = timing == ConsoleTiming::ntsc;
|
|
||||||
const string key = isNTSC ? "tv.phase_ntsc" : "tv.phase_pal";
|
|
||||||
const float shift = isNTSC ? NTSC_SHIFT : PAL_SHIFT;
|
|
||||||
float phase = myOSystem.settings().getFloat(key);
|
|
||||||
|
|
||||||
if(increase) // increase color phase shift
|
|
||||||
{
|
|
||||||
phase += 0.3F;
|
|
||||||
phase = std::min(phase, shift + 4.5F);
|
|
||||||
}
|
|
||||||
else // decrease color phase shift
|
|
||||||
{
|
|
||||||
phase -= 0.3F;
|
|
||||||
phase = std::max(phase, shift - 4.5F);
|
|
||||||
}
|
|
||||||
myOSystem.settings().setValue(key, phase);
|
|
||||||
generateCustomPalette(timing);
|
|
||||||
|
|
||||||
setPalette("custom");
|
|
||||||
|
|
||||||
ostringstream ss;
|
|
||||||
ss << "Color phase shift at "
|
|
||||||
<< std::fixed << std::setprecision(1) << phase << DEGREE;
|
|
||||||
|
|
||||||
myOSystem.frameBuffer().showMessage(ss.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void PaletteHandler::setPalette(const string& name)
|
void PaletteHandler::setPalette(const string& name)
|
||||||
{
|
{
|
||||||
|
@ -251,7 +264,7 @@ void PaletteHandler::setPalette()
|
||||||
|
|
||||||
// Look at all the palettes, since we don't know which one is
|
// Look at all the palettes, since we don't know which one is
|
||||||
// currently active
|
// currently active
|
||||||
static constexpr BSPF::array2D<PaletteArray*, PaletteType::NumTypes, int(ConsoleTiming::numTimings)> palettes = {{
|
static constexpr BSPF::array2D<const PaletteArray*, PaletteType::NumTypes, int(ConsoleTiming::numTimings)> palettes = {{
|
||||||
{ &ourNTSCPalette, &ourPALPalette, &ourSECAMPalette },
|
{ &ourNTSCPalette, &ourPALPalette, &ourSECAMPalette },
|
||||||
{ &ourNTSCPaletteZ26, &ourPALPaletteZ26, &ourSECAMPaletteZ26 },
|
{ &ourNTSCPaletteZ26, &ourPALPaletteZ26, &ourSECAMPaletteZ26 },
|
||||||
{ &ourUserNTSCPalette, &ourUserPALPalette, &ourUserSECAMPalette },
|
{ &ourUserNTSCPalette, &ourUserPALPalette, &ourUserSECAMPalette },
|
||||||
|
@ -274,19 +287,19 @@ PaletteArray PaletteHandler::adjustPalette(const PaletteArray& palette)
|
||||||
{
|
{
|
||||||
PaletteArray destPalette;
|
PaletteArray destPalette;
|
||||||
// Constants for saturation and gray scale calculation
|
// Constants for saturation and gray scale calculation
|
||||||
const float PR = .2989F;
|
constexpr float PR = .2989F;
|
||||||
const float PG = .5870F;
|
constexpr float PG = .5870F;
|
||||||
const float PB = .1140F;
|
constexpr float PB = .1140F;
|
||||||
// Generate adjust table
|
// Generate adjust table
|
||||||
const int ADJUST_SIZE = 256;
|
constexpr int ADJUST_SIZE = 256;
|
||||||
const int RGB_UNIT = 1 << 8;
|
constexpr int RGB_UNIT = 1 << 8;
|
||||||
const float RGB_OFFSET = 0.5F;
|
constexpr float RGB_OFFSET = 0.5F;
|
||||||
const float brightness = myBrightness * (0.5F * RGB_UNIT) + RGB_OFFSET;
|
const float brightness = myBrightness * (0.5F * RGB_UNIT) + RGB_OFFSET;
|
||||||
const float contrast = myContrast * (0.5F * RGB_UNIT) + RGB_UNIT;
|
const float contrast = myContrast * (0.5F * RGB_UNIT) + RGB_UNIT;
|
||||||
const float saturation = mySaturation + 1;
|
const float saturation = mySaturation + 1;
|
||||||
const float gamma = 1.1333F - myGamma * 0.5F;
|
const float gamma = 1.1333F - myGamma * 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 */
|
||||||
const float toFloat = 1.F / (ADJUST_SIZE - 1);
|
constexpr float toFloat = 1.F / (ADJUST_SIZE - 1);
|
||||||
std::array<float, ADJUST_SIZE> adjust;
|
std::array<float, ADJUST_SIZE> adjust;
|
||||||
|
|
||||||
for(int i = 0; i < ADJUST_SIZE; i++)
|
for(int i = 0; i < ADJUST_SIZE; i++)
|
||||||
|
@ -341,13 +354,13 @@ void PaletteHandler::loadUserPalette()
|
||||||
for(int i = 0; i < 128; i++) // NTSC palette
|
for(int i = 0; i < 128; i++) // NTSC palette
|
||||||
{
|
{
|
||||||
in.read(reinterpret_cast<char*>(pixbuf.data()), 3);
|
in.read(reinterpret_cast<char*>(pixbuf.data()), 3);
|
||||||
uInt32 pixel = (int(pixbuf[0]) << 16) + (int(pixbuf[1]) << 8) + int(pixbuf[2]);
|
const uInt32 pixel = (int(pixbuf[0]) << 16) + (int(pixbuf[1]) << 8) + int(pixbuf[2]);
|
||||||
ourUserNTSCPalette[(i<<1)] = pixel;
|
ourUserNTSCPalette[(i<<1)] = pixel;
|
||||||
}
|
}
|
||||||
for(int i = 0; i < 128; i++) // PAL palette
|
for(int i = 0; i < 128; i++) // PAL palette
|
||||||
{
|
{
|
||||||
in.read(reinterpret_cast<char*>(pixbuf.data()), 3);
|
in.read(reinterpret_cast<char*>(pixbuf.data()), 3);
|
||||||
uInt32 pixel = (int(pixbuf[0]) << 16) + (int(pixbuf[1]) << 8) + int(pixbuf[2]);
|
const uInt32 pixel = (int(pixbuf[0]) << 16) + (int(pixbuf[1]) << 8) + int(pixbuf[2]);
|
||||||
ourUserPALPalette[(i<<1)] = pixel;
|
ourUserPALPalette[(i<<1)] = pixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,7 +368,7 @@ void PaletteHandler::loadUserPalette()
|
||||||
for(int i = 0; i < 8; i++) // SECAM palette
|
for(int i = 0; i < 8; i++) // SECAM palette
|
||||||
{
|
{
|
||||||
in.read(reinterpret_cast<char*>(pixbuf.data()), 3);
|
in.read(reinterpret_cast<char*>(pixbuf.data()), 3);
|
||||||
uInt32 pixel = (int(pixbuf[0]) << 16) + (int(pixbuf[1]) << 8) + int(pixbuf[2]);
|
const uInt32 pixel = (int(pixbuf[0]) << 16) + (int(pixbuf[1]) << 8) + int(pixbuf[2]);
|
||||||
secam[(i<<1)] = pixel;
|
secam[(i<<1)] = pixel;
|
||||||
secam[(i<<1)+1] = 0;
|
secam[(i<<1)+1] = 0;
|
||||||
}
|
}
|
||||||
|
@ -383,8 +396,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("tv.phase_ntsc") *
|
const float shift = myPhaseNTSC * (2 * BSPF::PI_f / 360);
|
||||||
(2 * BSPF::PI_f / 360);
|
|
||||||
|
|
||||||
// color 0 is grayscale
|
// color 0 is grayscale
|
||||||
for(int chroma = 1; chroma < NUM_CHROMA; chroma++)
|
for(int chroma = 1; chroma < NUM_CHROMA; chroma++)
|
||||||
|
@ -429,8 +441,7 @@ void PaletteHandler::generateCustomPalette(ConsoleTiming timing)
|
||||||
else if(timing == ConsoleTiming::pal)
|
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("tv.phase_pal") *
|
const float shift = myPhasePAL * (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);
|
||||||
|
|
||||||
// colors 0, 1, 14 and 15 are grayscale
|
// colors 0, 1, 14 and 15 are grayscale
|
||||||
|
@ -453,11 +464,10 @@ void PaletteHandler::generateCustomPalette(ConsoleTiming timing)
|
||||||
{
|
{
|
||||||
const float Y = 0.05F + luma / 8.24F; // 0.05..~0.90
|
const float Y = 0.05F + luma / 8.24F; // 0.05..~0.90
|
||||||
|
|
||||||
// Most sources
|
// Most sources
|
||||||
float R = Y + 1.403F * V;
|
float R = Y + 1.403F * V;
|
||||||
float G = Y - 0.344F * U - 0.714F * V;
|
float G = Y - 0.344F * U - 0.714F * V;
|
||||||
float B = Y + 1.770F * U;
|
float B = Y + 1.770F * U;
|
||||||
|
|
||||||
// German Wikipedia, huh???
|
// German Wikipedia, huh???
|
||||||
//float B = Y + 1 / 0.493 * U;
|
//float B = Y + 1 / 0.493 * U;
|
||||||
//float R = Y + 1 / 0.877 * V;
|
//float R = Y + 1 / 0.877 * V;
|
||||||
|
@ -504,8 +514,7 @@ void PaletteHandler::changeSaturation(int& R, int& G, int& B, float change)
|
||||||
constexpr float PR = .2989F;
|
constexpr float PR = .2989F;
|
||||||
constexpr float PG = .5870F;
|
constexpr float PG = .5870F;
|
||||||
constexpr float PB = .1140F;
|
constexpr float PB = .1140F;
|
||||||
|
const float P = sqrt(R * R * PR + G * G * PG + B * B * PB) ;
|
||||||
float P = sqrt(R * R * PR + G * G * PG + B * B * PB) ;
|
|
||||||
|
|
||||||
R = P + (R - P) * change;
|
R = P + (R - P) * change;
|
||||||
G = P + (G - P) * change;
|
G = P + (G - P) * change;
|
||||||
|
@ -517,7 +526,7 @@ void PaletteHandler::changeSaturation(int& R, int& G, int& B, float change)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
PaletteArray PaletteHandler::ourNTSCPalette = {
|
const PaletteArray PaletteHandler::ourNTSCPalette = {
|
||||||
0x000000, 0, 0x4a4a4a, 0, 0x6f6f6f, 0, 0x8e8e8e, 0,
|
0x000000, 0, 0x4a4a4a, 0, 0x6f6f6f, 0, 0x8e8e8e, 0,
|
||||||
0xaaaaaa, 0, 0xc0c0c0, 0, 0xd6d6d6, 0, 0xececec, 0,
|
0xaaaaaa, 0, 0xc0c0c0, 0, 0xd6d6d6, 0, 0xececec, 0,
|
||||||
0x484800, 0, 0x69690f, 0, 0x86861d, 0, 0xa2a22a, 0,
|
0x484800, 0, 0x69690f, 0, 0x86861d, 0, 0xa2a22a, 0,
|
||||||
|
@ -553,7 +562,7 @@ PaletteArray PaletteHandler::ourNTSCPalette = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
PaletteArray PaletteHandler::ourPALPalette = {
|
const PaletteArray PaletteHandler::ourPALPalette = {
|
||||||
0x000000, 0, 0x121212, 0, 0x242424, 0, 0x484848, 0, // 180 0
|
0x000000, 0, 0x121212, 0, 0x242424, 0, 0x484848, 0, // 180 0
|
||||||
0x6c6c6c, 0, 0x909090, 0, 0xb4b4b4, 0, 0xd8d8d8, 0, // was 0x111111..0xcccccc
|
0x6c6c6c, 0, 0x909090, 0, 0xb4b4b4, 0, 0xd8d8d8, 0, // was 0x111111..0xcccccc
|
||||||
0x000000, 0, 0x121212, 0, 0x242424, 0, 0x484848, 0, // 198 1
|
0x000000, 0, 0x121212, 0, 0x242424, 0, 0x484848, 0, // 198 1
|
||||||
|
@ -589,7 +598,7 @@ PaletteArray PaletteHandler::ourPALPalette = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
PaletteArray PaletteHandler::ourSECAMPalette = {
|
const PaletteArray PaletteHandler::ourSECAMPalette = {
|
||||||
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
|
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
|
||||||
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
|
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
|
||||||
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
|
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
|
||||||
|
@ -625,7 +634,7 @@ PaletteArray PaletteHandler::ourSECAMPalette = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
PaletteArray PaletteHandler::ourNTSCPaletteZ26 = {
|
const PaletteArray PaletteHandler::ourNTSCPaletteZ26 = {
|
||||||
0x000000, 0, 0x505050, 0, 0x646464, 0, 0x787878, 0,
|
0x000000, 0, 0x505050, 0, 0x646464, 0, 0x787878, 0,
|
||||||
0x8c8c8c, 0, 0xa0a0a0, 0, 0xb4b4b4, 0, 0xc8c8c8, 0,
|
0x8c8c8c, 0, 0xa0a0a0, 0, 0xb4b4b4, 0, 0xc8c8c8, 0,
|
||||||
0x445400, 0, 0x586800, 0, 0x6c7c00, 0, 0x809000, 0,
|
0x445400, 0, 0x586800, 0, 0x6c7c00, 0, 0x809000, 0,
|
||||||
|
@ -661,7 +670,7 @@ PaletteArray PaletteHandler::ourNTSCPaletteZ26 = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
PaletteArray PaletteHandler::ourPALPaletteZ26 = {
|
const PaletteArray PaletteHandler::ourPALPaletteZ26 = {
|
||||||
0x000000, 0, 0x4c4c4c, 0, 0x606060, 0, 0x747474, 0,
|
0x000000, 0, 0x4c4c4c, 0, 0x606060, 0, 0x747474, 0,
|
||||||
0x888888, 0, 0x9c9c9c, 0, 0xb0b0b0, 0, 0xc4c4c4, 0,
|
0x888888, 0, 0x9c9c9c, 0, 0xb0b0b0, 0, 0xc4c4c4, 0,
|
||||||
0x000000, 0, 0x4c4c4c, 0, 0x606060, 0, 0x747474, 0,
|
0x000000, 0, 0x4c4c4c, 0, 0x606060, 0, 0x747474, 0,
|
||||||
|
@ -697,7 +706,7 @@ PaletteArray PaletteHandler::ourPALPaletteZ26 = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
PaletteArray PaletteHandler::ourSECAMPaletteZ26 = {
|
const PaletteArray PaletteHandler::ourSECAMPaletteZ26 = {
|
||||||
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
|
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
|
||||||
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
|
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
|
||||||
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
|
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
#include "OSystem.hxx"
|
#include "OSystem.hxx"
|
||||||
|
#include "ConsoleTiming.hxx"
|
||||||
|
|
||||||
class PaletteHandler
|
class PaletteHandler
|
||||||
{
|
{
|
||||||
|
@ -29,6 +30,10 @@ class PaletteHandler
|
||||||
static constexpr const char* SETTING_USER = "user";
|
static constexpr const char* SETTING_USER = "user";
|
||||||
static constexpr const char* SETTING_CUSTOM = "custom";
|
static constexpr const char* SETTING_CUSTOM = "custom";
|
||||||
|
|
||||||
|
static constexpr float DEF_NTSC_SHIFT = 26.2F;
|
||||||
|
static constexpr float DEF_PAL_SHIFT = 31.3F; // 360 / 11.5
|
||||||
|
static constexpr float MAX_SHIFT = 4.5F;
|
||||||
|
|
||||||
enum DisplayType {
|
enum DisplayType {
|
||||||
NTSC,
|
NTSC,
|
||||||
PAL,
|
PAL,
|
||||||
|
@ -37,6 +42,7 @@ class PaletteHandler
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Adjustable {
|
struct Adjustable {
|
||||||
|
float phaseNtsc, phasePal;
|
||||||
uInt32 hue, saturation, contrast, brightness, gamma;
|
uInt32 hue, saturation, contrast, brightness, gamma;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,7 +61,7 @@ class PaletteHandler
|
||||||
|
|
||||||
void loadConfig(const Settings& settings);
|
void loadConfig(const Settings& settings);
|
||||||
void saveConfig(Settings& settings) const;
|
void saveConfig(Settings& settings) const;
|
||||||
void setAdjustables(Adjustable& adjustable);
|
void setAdjustables(const Adjustable& adjustable);
|
||||||
void getAdjustables(Adjustable& adjustable) const;
|
void getAdjustables(Adjustable& adjustable) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -114,7 +120,7 @@ class PaletteHandler
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int NUM_ADJUSTABLES = 6;
|
static constexpr int NUM_ADJUSTABLES = 6;
|
||||||
|
|
||||||
OSystem& myOSystem;
|
OSystem& myOSystem;
|
||||||
|
|
||||||
|
@ -133,11 +139,13 @@ class PaletteHandler
|
||||||
{ "gamma", &myGamma },
|
{ "gamma", &myGamma },
|
||||||
} };
|
} };
|
||||||
|
|
||||||
|
float myPhaseNTSC{0.0F};
|
||||||
|
float myPhasePAL{0.0F};
|
||||||
// range -1.0 to +1.0 (as in AtariNTSC)
|
// range -1.0 to +1.0 (as in AtariNTSC)
|
||||||
// Basic parameters
|
// Basic parameters
|
||||||
float myContrast{0.0F}; // -1 = dark (0.5) +1 = light (1.5)
|
|
||||||
float myHue{0.0F}; // -1 = -180 degrees +1 = +180 degrees
|
float myHue{0.0F}; // -1 = -180 degrees +1 = +180 degrees
|
||||||
float mySaturation{0.0F}; // -1 = grayscale (0.0) +1 = oversaturated colors (2.0)
|
float mySaturation{0.0F}; // -1 = grayscale (0.0) +1 = oversaturated colors (2.0)
|
||||||
|
float myContrast{0.0F}; // -1 = dark (0.5) +1 = light (1.5)
|
||||||
float myBrightness{0.0F}; // -1 = dark (0.5) +1 = light (1.5)
|
float myBrightness{0.0F}; // -1 = dark (0.5) +1 = light (1.5)
|
||||||
// Advanced parameters
|
// Advanced parameters
|
||||||
float myGamma{0.0F}; // -1 = dark (1.5) +1 = light (0.5)
|
float myGamma{0.0F}; // -1 = dark (1.5) +1 = light (0.5)
|
||||||
|
@ -147,14 +155,14 @@ class PaletteHandler
|
||||||
bool myUserPaletteDefined{false};
|
bool myUserPaletteDefined{false};
|
||||||
|
|
||||||
// Table of RGB values for NTSC, PAL and SECAM
|
// Table of RGB values for NTSC, PAL and SECAM
|
||||||
static PaletteArray ourNTSCPalette;
|
static const PaletteArray ourNTSCPalette;
|
||||||
static PaletteArray ourPALPalette;
|
static const PaletteArray ourPALPalette;
|
||||||
static PaletteArray ourSECAMPalette;
|
static const PaletteArray ourSECAMPalette;
|
||||||
|
|
||||||
// Table of RGB values for NTSC, PAL and SECAM - Z26 version
|
// Table of RGB values for NTSC, PAL and SECAM - Z26 version
|
||||||
static PaletteArray ourNTSCPaletteZ26;
|
static const PaletteArray ourNTSCPaletteZ26;
|
||||||
static PaletteArray ourPALPaletteZ26;
|
static const PaletteArray ourPALPaletteZ26;
|
||||||
static PaletteArray ourSECAMPaletteZ26;
|
static const PaletteArray ourSECAMPaletteZ26;
|
||||||
|
|
||||||
// Table of RGB values for NTSC, PAL and SECAM - user-defined
|
// Table of RGB values for NTSC, PAL and SECAM - user-defined
|
||||||
static PaletteArray ourUserNTSCPalette;
|
static PaletteArray ourUserNTSCPalette;
|
||||||
|
|
|
@ -25,10 +25,11 @@
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
ColorWidget::ColorWidget(GuiObject* boss, const GUI::Font& font,
|
ColorWidget::ColorWidget(GuiObject* boss, const GUI::Font& font,
|
||||||
int x, int y, int w, int h, int cmd)
|
int x, int y, int w, int h, int cmd, bool framed)
|
||||||
: Widget(boss, font, x, y, w, h),
|
: Widget(boss, font, x, y, w, h),
|
||||||
CommandSender(boss),
|
CommandSender(boss),
|
||||||
_cmd(cmd)
|
_cmd(cmd),
|
||||||
|
_framed(framed)
|
||||||
{
|
{
|
||||||
_flags = Widget::FLAG_ENABLED | Widget::FLAG_CLEARBG | Widget::FLAG_RETAIN_FOCUS;
|
_flags = Widget::FLAG_ENABLED | Widget::FLAG_CLEARBG | Widget::FLAG_RETAIN_FOCUS;
|
||||||
}
|
}
|
||||||
|
@ -46,11 +47,18 @@ void ColorWidget::drawWidget(bool hilite)
|
||||||
FBSurface& s = dialog().surface();
|
FBSurface& s = dialog().surface();
|
||||||
bool onTop = _boss->dialog().isOnTop();
|
bool onTop = _boss->dialog().isOnTop();
|
||||||
|
|
||||||
|
if(_framed)
|
||||||
|
{
|
||||||
// Draw a thin frame around us.
|
// Draw a thin frame around us.
|
||||||
s.frameRect(_x, _y, _w, _h + 1, kColor);
|
s.frameRect(_x, _y, _w, _h + 1, kColor);
|
||||||
|
|
||||||
// Show the currently selected color
|
// Show the currently selected color
|
||||||
s.fillRect(_x+1, _y+1, _w-2, _h-1, onTop ? isEnabled() ? _color : kWidColor : kBGColorLo);
|
s.fillRect(_x + 1, _y + 1, _w - 2, _h - 1, onTop ? isEnabled() ? _color : kWidColor : kBGColorLo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s.fillRect(_x, _y, _w, _h, onTop ? isEnabled() ? _color : kWidColor : kBGColorLo);
|
||||||
|
}
|
||||||
|
|
||||||
// Cross out the grid?
|
// Cross out the grid?
|
||||||
if(_crossGrid)
|
if(_crossGrid)
|
||||||
|
|
|
@ -36,7 +36,7 @@ class ColorWidget : public Widget, public CommandSender
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ColorWidget(GuiObject* boss, const GUI::Font& font,
|
ColorWidget(GuiObject* boss, const GUI::Font& font,
|
||||||
int x, int y, int w, int h, int cmd = 0);
|
int x, int y, int w, int h, int cmd = 0, bool framed = true);
|
||||||
virtual ~ColorWidget() = default;
|
virtual ~ColorWidget() = default;
|
||||||
|
|
||||||
void setColor(ColorId color);
|
void setColor(ColorId color);
|
||||||
|
@ -49,6 +49,7 @@ class ColorWidget : public Widget, public CommandSender
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ColorId _color{kNone};
|
ColorId _color{kNone};
|
||||||
|
bool _framed{true};
|
||||||
int _cmd{0};
|
int _cmd{0};
|
||||||
|
|
||||||
bool _crossGrid{false};
|
bool _crossGrid{false};
|
||||||
|
|
|
@ -18,12 +18,14 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
|
#include "Base.hxx"
|
||||||
#include "Control.hxx"
|
#include "Control.hxx"
|
||||||
#include "Dialog.hxx"
|
#include "Dialog.hxx"
|
||||||
#include "Menu.hxx"
|
#include "Menu.hxx"
|
||||||
#include "OSystem.hxx"
|
#include "OSystem.hxx"
|
||||||
#include "EditTextWidget.hxx"
|
#include "EditTextWidget.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
#include "PopUpWidget.hxx"
|
||||||
|
#include "ColorWidget.hxx"
|
||||||
#include "Console.hxx"
|
#include "Console.hxx"
|
||||||
#include "PaletteHandler.hxx"
|
#include "PaletteHandler.hxx"
|
||||||
#include "TIA.hxx"
|
#include "TIA.hxx"
|
||||||
|
@ -104,6 +106,14 @@ VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
addPaletteTab();
|
addPaletteTab();
|
||||||
addTVEffectsTab();
|
addTVEffectsTab();
|
||||||
|
|
||||||
|
//const int req_w = std::max(myFastSCBios->getRight(), myCloneBad->getRight()) + HBORDER + 1;
|
||||||
|
//const int req_h = _th + VGAP * 3
|
||||||
|
// + std::max(myUseVSync->getBottom(), myTVScanIntense->getBottom())
|
||||||
|
// + buttonHeight + VBORDER * 2;
|
||||||
|
//// Set real dimensions
|
||||||
|
//setSize(req_w, req_h, max_w, max_h);
|
||||||
|
|
||||||
|
|
||||||
// Add Defaults, OK and Cancel buttons
|
// Add Defaults, OK and Cancel buttons
|
||||||
WidgetArray wid;
|
WidgetArray wid;
|
||||||
addDefaultsOKCancelBGroup(wid, _font);
|
addDefaultsOKCancelBGroup(wid, _font);
|
||||||
|
@ -266,7 +276,8 @@ void VideoDialog::addPaletteTab()
|
||||||
myPhaseShiftNtsc =
|
myPhaseShiftNtsc =
|
||||||
new SliderWidget(myTab, _font, xpos + INDENT, ypos-1, pswidth, lineHeight,
|
new SliderWidget(myTab, _font, xpos + INDENT, ypos-1, pswidth, lineHeight,
|
||||||
"NTSC phase", plWidth, kNtscShiftChanged, fontWidth * 5);
|
"NTSC phase", plWidth, kNtscShiftChanged, fontWidth * 5);
|
||||||
myPhaseShiftNtsc->setMinValue(262 - 45); myPhaseShiftNtsc->setMaxValue(262 + 45);
|
myPhaseShiftNtsc->setMinValue((PaletteHandler::DEF_NTSC_SHIFT - PaletteHandler::MAX_SHIFT) * 10);
|
||||||
|
myPhaseShiftNtsc->setMaxValue((PaletteHandler::DEF_NTSC_SHIFT + PaletteHandler::MAX_SHIFT) * 10);
|
||||||
myPhaseShiftNtsc->setTickmarkIntervals(4);
|
myPhaseShiftNtsc->setTickmarkIntervals(4);
|
||||||
wid.push_back(myPhaseShiftNtsc);
|
wid.push_back(myPhaseShiftNtsc);
|
||||||
ypos += lineHeight + VGAP;
|
ypos += lineHeight + VGAP;
|
||||||
|
@ -274,7 +285,8 @@ void VideoDialog::addPaletteTab()
|
||||||
myPhaseShiftPal =
|
myPhaseShiftPal =
|
||||||
new SliderWidget(myTab, _font, xpos + INDENT, ypos-1, pswidth, lineHeight,
|
new SliderWidget(myTab, _font, xpos + INDENT, ypos-1, pswidth, lineHeight,
|
||||||
"PAL phase", plWidth, kPalShiftChanged, fontWidth * 5);
|
"PAL phase", plWidth, kPalShiftChanged, fontWidth * 5);
|
||||||
myPhaseShiftPal->setMinValue(313 - 45); myPhaseShiftPal->setMaxValue(313 + 45);
|
myPhaseShiftPal->setMinValue((PaletteHandler::DEF_PAL_SHIFT - PaletteHandler::MAX_SHIFT) * 10);
|
||||||
|
myPhaseShiftPal->setMaxValue((PaletteHandler::DEF_PAL_SHIFT + PaletteHandler::MAX_SHIFT) * 10);
|
||||||
myPhaseShiftPal->setTickmarkIntervals(4);
|
myPhaseShiftPal->setTickmarkIntervals(4);
|
||||||
wid.push_back(myPhaseShiftPal);
|
wid.push_back(myPhaseShiftPal);
|
||||||
ypos += lineHeight + VGAP;
|
ypos += lineHeight + VGAP;
|
||||||
|
@ -288,11 +300,15 @@ void VideoDialog::addPaletteTab()
|
||||||
wid.push_back(myTV ## obj); \
|
wid.push_back(myTV ## obj); \
|
||||||
ypos += lineHeight + VGAP;
|
ypos += lineHeight + VGAP;
|
||||||
|
|
||||||
CREATE_CUSTOM_SLIDERS(Hue, "Hue ", 0)
|
CREATE_CUSTOM_SLIDERS(Hue, "Hue ", kPaletteUpdated)
|
||||||
CREATE_CUSTOM_SLIDERS(Satur, "Saturation ", 0)
|
CREATE_CUSTOM_SLIDERS(Satur, "Saturation ", kPaletteUpdated)
|
||||||
CREATE_CUSTOM_SLIDERS(Contrast, "Contrast ", 0)
|
CREATE_CUSTOM_SLIDERS(Contrast, "Contrast ", kPaletteUpdated)
|
||||||
CREATE_CUSTOM_SLIDERS(Bright, "Brightness ", 0)
|
CREATE_CUSTOM_SLIDERS(Bright, "Brightness ", kPaletteUpdated)
|
||||||
CREATE_CUSTOM_SLIDERS(Gamma, "Gamma ", 0)
|
CREATE_CUSTOM_SLIDERS(Gamma, "Gamma ", kPaletteUpdated)
|
||||||
|
|
||||||
|
// The resulting palette
|
||||||
|
addPalette(myPhaseShiftNtsc->getRight() + fontWidth * 2, VBORDER,
|
||||||
|
fontWidth * 2 * 8, myTVGamma->getBottom() - myTIAPalette->getTop());
|
||||||
|
|
||||||
// Add items for tab 2
|
// Add items for tab 2
|
||||||
addToFocusList(wid, myTab, tabID);
|
addToFocusList(wid, myTab, tabID);
|
||||||
|
@ -412,13 +428,20 @@ void VideoDialog::loadConfig()
|
||||||
myTIAZoom->setValue(instance().settings().getFloat("tia.zoom") * 100);
|
myTIAZoom->setValue(instance().settings().getFloat("tia.zoom") * 100);
|
||||||
|
|
||||||
// TIA Palette
|
// TIA Palette
|
||||||
myTIAPalette->setSelected(
|
myPalette = instance().settings().getString("palette");
|
||||||
instance().settings().getString("palette"), "standard");
|
myTIAPalette->setSelected(myPalette, "standard");
|
||||||
|
|
||||||
// Custom Palette
|
// Palette adjustables
|
||||||
myPhaseShiftNtsc->setValue(instance().settings().getFloat("tv.phase_ntsc") * 10);
|
instance().frameBuffer().tiaSurface().paletteHandler().getAdjustables(myPaletteAdj);
|
||||||
myPhaseShiftPal->setValue(instance().settings().getFloat("tv.phase_pal") * 10);
|
myPhaseShiftNtsc->setValue(myPaletteAdj.phaseNtsc);
|
||||||
|
myPhaseShiftPal->setValue(myPaletteAdj.phasePal);
|
||||||
|
myTVHue->setValue(myPaletteAdj.hue);
|
||||||
|
myTVBright->setValue(myPaletteAdj.brightness);
|
||||||
|
myTVContrast->setValue(myPaletteAdj.contrast);
|
||||||
|
myTVSatur->setValue(myPaletteAdj.saturation);
|
||||||
|
myTVGamma->setValue(myPaletteAdj.gamma);
|
||||||
handlePaletteChange();
|
handlePaletteChange();
|
||||||
|
colorPalette();
|
||||||
|
|
||||||
// TIA interpolation
|
// TIA interpolation
|
||||||
myTIAInterpolate->setState(instance().settings().getBool("tia.inter"));
|
myTIAInterpolate->setState(instance().settings().getBool("tia.inter"));
|
||||||
|
@ -459,15 +482,6 @@ 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);
|
||||||
|
|
||||||
|
@ -491,31 +505,12 @@ void VideoDialog::saveConfig()
|
||||||
instance().settings().setValue("video",
|
instance().settings().setValue("video",
|
||||||
myRenderer->getSelectedTag().toString());
|
myRenderer->getSelectedTag().toString());
|
||||||
|
|
||||||
// TIA zoom levels
|
|
||||||
instance().settings().setValue("tia.zoom", myTIAZoom->getValue() / 100.0);
|
|
||||||
|
|
||||||
// TIA Palette
|
|
||||||
instance().settings().setValue("palette",
|
|
||||||
myTIAPalette->getSelectedTag().toString());
|
|
||||||
|
|
||||||
// Custom Palette
|
|
||||||
instance().settings().setValue("tv.phase_ntsc", myPhaseShiftNtsc->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());
|
||||||
|
|
||||||
// Aspect ratio setting (NTSC and PAL)
|
|
||||||
int oldAdjust = instance().settings().getInt("tia.vsizeadjust");
|
|
||||||
int newAdjust = myVSizeAdjust->getValue();
|
|
||||||
bool vsizeChanged = oldAdjust != newAdjust;
|
|
||||||
|
|
||||||
instance().settings().setValue("tia.vsizeadjust", newAdjust);
|
// Note: Palette values are saved directly when changed!
|
||||||
|
|
||||||
// Speed
|
|
||||||
int speedup = mySpeed->getValue();
|
|
||||||
instance().settings().setValue("speed", unmapSpeed(speedup));
|
|
||||||
if (instance().hasConsole()) instance().console().initializeAudio();
|
|
||||||
|
|
||||||
// Fullscreen
|
// Fullscreen
|
||||||
instance().settings().setValue("fullscreen", myFullscreen->getState());
|
instance().settings().setValue("fullscreen", myFullscreen->getState());
|
||||||
|
@ -524,6 +519,22 @@ void VideoDialog::saveConfig()
|
||||||
// Fullscreen overscan
|
// Fullscreen overscan
|
||||||
instance().settings().setValue("tia.fs_overscan", myTVOverscan->getValueLabel());
|
instance().settings().setValue("tia.fs_overscan", myTVOverscan->getValueLabel());
|
||||||
|
|
||||||
|
// TIA zoom levels
|
||||||
|
instance().settings().setValue("tia.zoom", myTIAZoom->getValue() / 100.0);
|
||||||
|
|
||||||
|
// Aspect ratio setting (NTSC and PAL)
|
||||||
|
const int oldAdjust = instance().settings().getInt("tia.vsizeadjust");
|
||||||
|
const int newAdjust = myVSizeAdjust->getValue();
|
||||||
|
const bool vsizeChanged = oldAdjust != newAdjust;
|
||||||
|
|
||||||
|
instance().settings().setValue("tia.vsizeadjust", newAdjust);
|
||||||
|
|
||||||
|
// Speed
|
||||||
|
const int speedup = mySpeed->getValue();
|
||||||
|
instance().settings().setValue("speed", unmapSpeed(speedup));
|
||||||
|
if (instance().hasConsole())
|
||||||
|
instance().console().initializeAudio();
|
||||||
|
|
||||||
// Use sync to vertical blank
|
// Use sync to vertical blank
|
||||||
instance().settings().setValue("vsync", myUseVSync->getState());
|
instance().settings().setValue("vsync", myUseVSync->getState());
|
||||||
|
|
||||||
|
@ -541,16 +552,6 @@ void VideoDialog::saveConfig()
|
||||||
// TV Mode
|
// TV Mode
|
||||||
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 ntscAdj;
|
NTSCFilter::Adjustable ntscAdj;
|
||||||
ntscAdj.sharpness = myTVSharp->getValue();
|
ntscAdj.sharpness = myTVSharp->getValue();
|
||||||
|
@ -596,32 +597,36 @@ void VideoDialog::setDefaults()
|
||||||
case 0: // General
|
case 0: // General
|
||||||
{
|
{
|
||||||
myRenderer->setSelectedIndex(0);
|
myRenderer->setSelectedIndex(0);
|
||||||
myTIAZoom->setValue(300);
|
|
||||||
myTIAInterpolate->setState(false);
|
myTIAInterpolate->setState(false);
|
||||||
myVSizeAdjust->setValue(0);
|
// screen size
|
||||||
mySpeed->setValue(0);
|
|
||||||
|
|
||||||
myFullscreen->setState(false);
|
myFullscreen->setState(false);
|
||||||
//myFullScreenMode->setSelectedIndex(0);
|
//myFullScreenMode->setSelectedIndex(0);
|
||||||
myUseStretch->setState(false);
|
myUseStretch->setState(false);
|
||||||
|
myTVOverscan->setValue(0);
|
||||||
|
myTIAZoom->setValue(300);
|
||||||
|
myVSizeAdjust->setValue(0);
|
||||||
|
// speed
|
||||||
|
mySpeed->setValue(0);
|
||||||
myUseVSync->setState(true);
|
myUseVSync->setState(true);
|
||||||
|
// misc
|
||||||
myUIMessages->setState(true);
|
myUIMessages->setState(true);
|
||||||
myFastSCBios->setState(true);
|
myFastSCBios->setState(true);
|
||||||
myUseThreads->setState(false);
|
myUseThreads->setState(false);
|
||||||
|
|
||||||
handlePaletteChange();
|
handleFullScreenChange();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 1: // Palettes
|
case 1: // Palettes
|
||||||
myTIAPalette->setSelected("standard", "");
|
myTIAPalette->setSelected("standard", "");
|
||||||
myPhaseShiftNtsc->setValue(262);
|
myPhaseShiftNtsc->setValue(PaletteHandler::DEF_NTSC_SHIFT * 10);
|
||||||
myPhaseShiftPal->setValue(313);
|
myPhaseShiftPal->setValue(PaletteHandler::DEF_PAL_SHIFT * 10);
|
||||||
myTVHue->setValue(50);
|
myTVHue->setValue(50);
|
||||||
myTVSatur->setValue(50);
|
myTVSatur->setValue(50);
|
||||||
myTVContrast->setValue(50);
|
myTVContrast->setValue(50);
|
||||||
myTVBright->setValue(50);
|
myTVBright->setValue(50);
|
||||||
myTVGamma->setValue(50);
|
myTVGamma->setValue(50);
|
||||||
|
handlePaletteChange();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: // TV effects
|
case 2: // TV effects
|
||||||
|
@ -685,6 +690,27 @@ void VideoDialog::handlePaletteChange()
|
||||||
myPhaseShiftPal->setEnabled(enable);
|
myPhaseShiftPal->setEnabled(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void VideoDialog::handlePaletteUpdate()
|
||||||
|
{
|
||||||
|
// TIA Palette
|
||||||
|
instance().settings().setValue("palette",
|
||||||
|
myTIAPalette->getSelectedTag().toString());
|
||||||
|
// Palette adjustables
|
||||||
|
PaletteHandler::Adjustable paletteAdj;
|
||||||
|
paletteAdj.phaseNtsc = myPhaseShiftNtsc->getValue();
|
||||||
|
paletteAdj.phasePal = myPhaseShiftPal->getValue();
|
||||||
|
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);
|
||||||
|
|
||||||
|
if(instance().hasConsole())
|
||||||
|
instance().frameBuffer().tiaSurface().paletteHandler().setPalette();
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void VideoDialog::handleFullScreenChange()
|
void VideoDialog::handleFullScreenChange()
|
||||||
{
|
{
|
||||||
|
@ -722,12 +748,24 @@ void VideoDialog::handleCommand(CommandSender* sender, int cmd,
|
||||||
close();
|
close();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GuiObject::kCloseCmd:
|
||||||
|
// restore palette settings
|
||||||
|
instance().frameBuffer().tiaSurface().paletteHandler().setAdjustables(myPaletteAdj);
|
||||||
|
instance().frameBuffer().tiaSurface().paletteHandler().setPalette(myPalette);
|
||||||
|
Dialog::handleCommand(sender, cmd, data, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
case GuiObject::kDefaultsCmd:
|
case GuiObject::kDefaultsCmd:
|
||||||
setDefaults();
|
setDefaults();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kPaletteChanged:
|
case kPaletteChanged:
|
||||||
handlePaletteChange();
|
handlePaletteChange();
|
||||||
|
handlePaletteUpdate();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kPaletteUpdated:
|
||||||
|
handlePaletteUpdate();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kNtscShiftChanged:
|
case kNtscShiftChanged:
|
||||||
|
@ -737,6 +775,7 @@ void VideoDialog::handleCommand(CommandSender* sender, int cmd,
|
||||||
ss << std::setw(4) << std::fixed << std::setprecision(1)
|
ss << std::setw(4) << std::fixed << std::setprecision(1)
|
||||||
<< (0.1 * abs(myPhaseShiftNtsc->getValue())) << DEGREE;
|
<< (0.1 * abs(myPhaseShiftNtsc->getValue())) << DEGREE;
|
||||||
myPhaseShiftNtsc->setValueLabel(ss.str());
|
myPhaseShiftNtsc->setValueLabel(ss.str());
|
||||||
|
handlePaletteUpdate();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kPalShiftChanged:
|
case kPalShiftChanged:
|
||||||
|
@ -746,6 +785,7 @@ void VideoDialog::handleCommand(CommandSender* sender, int cmd,
|
||||||
ss << std::setw(4) << std::fixed << std::setprecision(1)
|
ss << std::setw(4) << std::fixed << std::setprecision(1)
|
||||||
<< (0.1 * abs(myPhaseShiftPal->getValue())) << DEGREE;
|
<< (0.1 * abs(myPhaseShiftPal->getValue())) << DEGREE;
|
||||||
myPhaseShiftPal->setValueLabel(ss.str());
|
myPhaseShiftPal->setValueLabel(ss.str());
|
||||||
|
handlePaletteUpdate();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kVSizeChanged:
|
case kVSizeChanged:
|
||||||
|
@ -818,3 +858,57 @@ void VideoDialog::handleCommand(CommandSender* sender, int cmd,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void VideoDialog::addPalette(int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
if(instance().hasConsole())
|
||||||
|
{
|
||||||
|
constexpr int NUM_LUMA = 8;
|
||||||
|
constexpr int NUM_CHROMA = 16;
|
||||||
|
const GUI::Font& ifont = instance().frameBuffer().infoFont();
|
||||||
|
const int lwidth = ifont.getMaxCharWidth() * 1.5;
|
||||||
|
const float COLW = float(w - lwidth) / NUM_LUMA;
|
||||||
|
const float COLH = float(h) / NUM_CHROMA;
|
||||||
|
const int yofs = (COLH - ifont.getFontHeight() + 1) / 2;
|
||||||
|
|
||||||
|
for(int idx = 0; idx < NUM_CHROMA; ++idx)
|
||||||
|
{
|
||||||
|
myColorLbl[idx] = new StaticTextWidget(myTab, ifont, x, y + yofs + idx * COLH, " ");
|
||||||
|
for(int lum = 0; lum < NUM_LUMA; ++lum)
|
||||||
|
{
|
||||||
|
myColor[idx][lum] = new ColorWidget(myTab, _font, x + lwidth + lum * COLW, y + idx * COLH,
|
||||||
|
COLW + 1, COLH + 1, 0, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void VideoDialog::colorPalette()
|
||||||
|
{
|
||||||
|
if(instance().hasConsole())
|
||||||
|
{
|
||||||
|
constexpr int NUM_LUMA = 8;
|
||||||
|
constexpr int NUM_CHROMA = 16;
|
||||||
|
const int order[2][NUM_CHROMA] =
|
||||||
|
{
|
||||||
|
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
||||||
|
{0, 1, 2, 4, 6, 8, 10, 12, 13, 11, 9, 7, 5, 3, 14, 15}
|
||||||
|
};
|
||||||
|
const int type = instance().console().timing() == ConsoleTiming::pal ? 1 : 0;
|
||||||
|
|
||||||
|
for(int idx = 0; idx < NUM_CHROMA; ++idx)
|
||||||
|
{
|
||||||
|
ostringstream ss;
|
||||||
|
const int color = order[type][idx];
|
||||||
|
|
||||||
|
ss << Common::Base::HEX1 << std::uppercase << color;
|
||||||
|
myColorLbl[idx]->setLabel(ss.str());
|
||||||
|
for(int lum = 0; lum < NUM_LUMA; ++lum)
|
||||||
|
{
|
||||||
|
myColor[idx][lum]->setColor(color * NUM_CHROMA + lum * 2); // skip grayscale colors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
class CommandSender;
|
class CommandSender;
|
||||||
class CheckboxWidget;
|
class CheckboxWidget;
|
||||||
|
class ColorWidget;
|
||||||
class DialogContainer;
|
class DialogContainer;
|
||||||
class PopUpWidget;
|
class PopUpWidget;
|
||||||
class RadioButtonGroup;
|
class RadioButtonGroup;
|
||||||
|
@ -29,6 +30,7 @@ class TabWidget;
|
||||||
class OSystem;
|
class OSystem;
|
||||||
|
|
||||||
#include "Dialog.hxx"
|
#include "Dialog.hxx"
|
||||||
|
#include "PaletteHandler.hxx"
|
||||||
#include "NTSCFilter.hxx"
|
#include "NTSCFilter.hxx"
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
|
|
||||||
|
@ -50,10 +52,13 @@ class VideoDialog : public Dialog
|
||||||
void handleTVModeChange(NTSCFilter::Preset);
|
void handleTVModeChange(NTSCFilter::Preset);
|
||||||
void loadTVAdjustables(NTSCFilter::Preset preset);
|
void loadTVAdjustables(NTSCFilter::Preset preset);
|
||||||
void handlePaletteChange();
|
void handlePaletteChange();
|
||||||
|
void handlePaletteUpdate();
|
||||||
void handleFullScreenChange();
|
void handleFullScreenChange();
|
||||||
void handleOverscanChange();
|
void handleOverscanChange();
|
||||||
void handlePhosphorChange();
|
void handlePhosphorChange();
|
||||||
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
|
||||||
|
void addPalette(int x, int y, int h, int w);
|
||||||
|
void colorPalette();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TabWidget* myTab;
|
TabWidget* myTab;
|
||||||
|
@ -77,6 +82,9 @@ class VideoDialog : public Dialog
|
||||||
CheckboxWidget* myUIMessages{nullptr};
|
CheckboxWidget* myUIMessages{nullptr};
|
||||||
CheckboxWidget* myFastSCBios{nullptr};
|
CheckboxWidget* myFastSCBios{nullptr};
|
||||||
CheckboxWidget* myUseThreads{nullptr};
|
CheckboxWidget* myUseThreads{nullptr};
|
||||||
|
std::array<StaticTextWidget*, 16> myColorLbl{nullptr};
|
||||||
|
//std::array<ColorWidget*, 16> myColor{nullptr};
|
||||||
|
ColorWidget* myColor[16][8]{nullptr};
|
||||||
|
|
||||||
// TV effects adjustables (custom mode)
|
// TV effects adjustables (custom mode)
|
||||||
PopUpWidget* myTVMode{nullptr};
|
PopUpWidget* myTVMode{nullptr};
|
||||||
|
@ -106,10 +114,14 @@ class VideoDialog : public Dialog
|
||||||
ButtonWidget* myCloneBad{nullptr};
|
ButtonWidget* myCloneBad{nullptr};
|
||||||
ButtonWidget* myCloneCustom{nullptr};
|
ButtonWidget* myCloneCustom{nullptr};
|
||||||
|
|
||||||
|
string myPalette;
|
||||||
|
PaletteHandler::Adjustable myPaletteAdj{0.0F};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
kPaletteChanged = 'VDpl',
|
kPaletteChanged = 'VDpl',
|
||||||
kNtscShiftChanged = 'VDns',
|
kNtscShiftChanged = 'VDns',
|
||||||
kPalShiftChanged = 'VDps',
|
kPalShiftChanged = 'VDps',
|
||||||
|
kPaletteUpdated = 'VDpu',
|
||||||
kSpeedupChanged = 'VDSp',
|
kSpeedupChanged = 'VDSp',
|
||||||
kVSizeChanged = 'VDVs',
|
kVSizeChanged = 'VDVs',
|
||||||
kFullScreenChanged = 'VDFs',
|
kFullScreenChanged = 'VDFs',
|
||||||
|
|
Loading…
Reference in New Issue