Merge branch 'feature-palette'

This commit is contained in:
thrust26 2020-05-11 21:19:52 +02:00
commit 71d5cb723a
60 changed files with 2896 additions and 2161 deletions

View File

@ -22,6 +22,8 @@
a game. This allows the user to save high scores for these games. For each
game and variation, the top 10 scores can be saved. (TODO: Doc)
* Added interactive palette to Video & Audio settings
* Added 'Custom' palette, generated from user controlled phase shifts.
* Added 'Turbo' mode, runs the game as fast as the computer allows.

View File

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

View File

@ -17,13 +17,7 @@
#include "OSystem.hxx"
#include "Console.hxx"
#include "Settings.hxx"
#include "EventHandler.hxx"
#include "Sound.hxx"
#include "StateManager.hxx"
#include "StellaKeys.hxx"
#include "TIASurface.hxx"
#include "PNGLibrary.hxx"
#include "PKeyboardHandler.hxx"
#ifdef DEBUGGER_SUPPORT
@ -475,25 +469,30 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultCommo
{Event::ToggleFullScreen, KBDK_RETURN, MOD3},
{Event::OverscanDecrease, KBDK_PAGEDOWN, KBDM_SHIFT},
{Event::OverscanIncrease, KBDK_PAGEUP, KBDM_SHIFT},
{Event::VidmodeStd, KBDK_1, MOD3},
{Event::VidmodeRGB, KBDK_2, MOD3},
{Event::VidmodeSVideo, KBDK_3, MOD3},
{Event::VidModeComposite, KBDK_4, MOD3},
{Event::VidModeBad, KBDK_5, MOD3},
{Event::VidModeCustom, KBDK_6, MOD3},
{Event::PreviousAttribute, KBDK_7, KBDM_SHIFT | MOD3},
{Event::NextAttribute, KBDK_7, MOD3},
{Event::DecreaseAttribute, KBDK_8, KBDM_SHIFT | MOD3},
{Event::IncreaseAttribute, KBDK_8, MOD3},
//{Event::VidmodeStd, KBDK_1, MOD3},
//{Event::VidmodeRGB, KBDK_2, MOD3},
//{Event::VidmodeSVideo, KBDK_3, MOD3},
//{Event::VidModeComposite, KBDK_4, MOD3},
//{Event::VidModeBad, KBDK_5, MOD3},
//{Event::VidModeCustom, KBDK_6, MOD3},
{Event::PreviousVideoMode, KBDK_1, KBDM_SHIFT | MOD3},
{Event::NextVideoMode, KBDK_1, MOD3},
{Event::PreviousAttribute, KBDK_2, KBDM_SHIFT | 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::PhosphorIncrease, KBDK_9, MOD3},
{Event::TogglePhosphor, KBDK_P, MOD3},
{Event::ScanlinesDecrease, KBDK_0, KBDM_SHIFT | MOD3},
{Event::ScanlinesIncrease, KBDK_0, MOD3},
{Event::ToggleColorLoss, KBDK_L, KBDM_CTRL},
{Event::TogglePalette, KBDK_P, KBDM_CTRL},
{Event::ColorShiftDecrease, KBDK_9, KBDM_SHIFT | KBDM_CTRL},
{Event::ColorShiftIncrease, KBDK_9, KBDM_CTRL},
{Event::PaletteDecrease, KBDK_P, KBDM_SHIFT | KBDM_CTRL},
{Event::PaletteIncrease, KBDK_P, KBDM_CTRL},
{Event::ToggleInter, KBDK_I, KBDM_CTRL},
{Event::ToggleTurbo, KBDK_T, KBDM_CTRL},
{Event::ToggleJitter, KBDK_J, MOD3},

View File

@ -0,0 +1,738 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#include <cmath>
#include "Console.hxx"
#include "FrameBuffer.hxx"
#include "PaletteHandler.hxx"
PaletteHandler::PaletteHandler(OSystem& system)
: myOSystem(system)
{
// Load user-defined palette for this ROM
loadUserPalette();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteHandler::PaletteType PaletteHandler::toPaletteType(const string& name) const
{
if(name == SETTING_Z26)
return PaletteType::Z26;
if(name == SETTING_USER && myUserPaletteDefined)
return PaletteType::User;
if(name == SETTING_CUSTOM)
return PaletteType::Custom;
return PaletteType::Standard;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string PaletteHandler::toPaletteName(PaletteType type) const
{
const string SETTING_NAMES[int(PaletteType::NumTypes)] = {
SETTING_STANDARD, SETTING_Z26, SETTING_USER, SETTING_CUSTOM
};
return SETTING_NAMES[type];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::cyclePalette(bool next)
{
const string MESSAGES[PaletteType::NumTypes] = {
"Standard Stella", "Z26", "User-defined", "Custom"
};
int type = toPaletteType(myOSystem.settings().getString("palette"));
if(next)
{
if(type == PaletteType::MaxType)
type = PaletteType::Standard;
else
type++;
// If we have no user-defined palette, we will skip it
if(type == PaletteType::User && !myUserPaletteDefined)
type++;
}
else
{
if(type == PaletteType::MinType)
type = PaletteType::MaxType;
else
type--;
// If we have no user-defined palette, we will skip it
if(type == PaletteType::User && !myUserPaletteDefined)
type--;
}
const string palette = toPaletteName(PaletteType(type));
const string message = MESSAGES[type] + " palette";
myOSystem.frameBuffer().showMessage(message);
setPalette(palette);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::cycleAdjustable(bool next)
{
const bool isCustomPalette = SETTING_CUSTOM == myOSystem.settings().getString("palette");
bool isPhaseShift;
do {
if(next)
{
myCurrentAdjustable++;
myCurrentAdjustable %= NUM_ADJUSTABLES;
}
else
{
if(myCurrentAdjustable == 0)
myCurrentAdjustable = NUM_ADJUSTABLES - 1;
else
myCurrentAdjustable--;
}
isPhaseShift = myAdjustables[myCurrentAdjustable].value == nullptr;
// skip phase shift when 'Custom' palette is not selected
} while(isPhaseShift && !isCustomPalette);
ostringstream buf;
buf << "Palette adjustable '" << myAdjustables[myCurrentAdjustable].name
<< "' selected (";
if(isPhaseShift)
buf << (myOSystem.console().timing() == ConsoleTiming::pal ? myPhasePAL : myPhaseNTSC)
<< DEGREE << ")";
else
buf << scaleTo100(*myAdjustables[myCurrentAdjustable].value) << "%)";
myOSystem.frameBuffer().showMessage(buf.str());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::changeAdjustable(bool increase)
{
if(myAdjustables[myCurrentAdjustable].value == nullptr)
changeColorPhaseShift(increase);
else
{
int newVal = scaleTo100(*myAdjustables[myCurrentAdjustable].value);
if(increase)
newVal += 2; // += 2%
else
newVal -= 2; // -= 2%
newVal = BSPF::clamp(newVal, 0, 100);
*myAdjustables[myCurrentAdjustable].value = scaleFrom100(newVal);
ostringstream buf;
buf << "Custom '" << myAdjustables[myCurrentAdjustable].name
<< "' set to " << newVal << "%";
myOSystem.frameBuffer().showMessage(buf.str());
setPalette();
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::changeColorPhaseShift(bool increase)
{
const ConsoleTiming timing = myOSystem.console().timing();
// SECAM is not supported
if(timing != ConsoleTiming::secam)
{
const bool isNTSC = timing == ConsoleTiming::ntsc;
const float shift = isNTSC ? DEF_NTSC_SHIFT : DEF_PAL_SHIFT;
float newPhase = isNTSC ? myPhaseNTSC : myPhasePAL;
if(increase) // increase color phase shift
newPhase += 0.3F;
else // decrease color phase shift
newPhase -= 0.3F;
newPhase = BSPF::clamp(newPhase, shift - MAX_SHIFT, shift + MAX_SHIFT);
if(isNTSC)
myPhaseNTSC = newPhase;
else
myPhasePAL = newPhase;
generateCustomPalette(timing);
setPalette(SETTING_CUSTOM);
ostringstream ss;
ss << "Color phase shift at "
<< std::fixed << std::setprecision(1) << newPhase << DEGREE;
myOSystem.frameBuffer().showMessage(ss.str());
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::loadConfig(const Settings& settings)
{
// 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);
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.phase_ntsc", myPhaseNTSC);
settings.setValue("tv.phase_pal", myPhasePAL);
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(const Adjustable& adjustable)
{
myPhaseNTSC = adjustable.phaseNtsc / 10.F;
myPhasePAL = adjustable.phasePal / 10.F;
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.phaseNtsc = myPhaseNTSC * 10.F;
adjustable.phasePal = myPhasePAL * 10.F;
adjustable.hue = scaleTo100(myHue);
adjustable.saturation = scaleTo100(mySaturation);
adjustable.contrast = scaleTo100(myContrast);
adjustable.brightness = scaleTo100(myBrightness);
adjustable.gamma = scaleTo100(myGamma);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::setPalette(const string& name)
{
myOSystem.settings().setValue("palette", name);
setPalette();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::setPalette()
{
if(myOSystem.hasConsole())
{
const string& name = myOSystem.settings().getString("palette");
// Look at all the palettes, since we don't know which one is
// currently active
static constexpr BSPF::array2D<const PaletteArray*, PaletteType::NumTypes, int(ConsoleTiming::numTimings)> palettes = {{
{ &ourNTSCPalette, &ourPALPalette, &ourSECAMPalette },
{ &ourNTSCPaletteZ26, &ourPALPaletteZ26, &ourSECAMPaletteZ26 },
{ &ourUserNTSCPalette, &ourUserPALPalette, &ourUserSECAMPalette },
{ &ourCustomNTSCPalette, &ourCustomPALPalette, &ourSECAMPalette }
}};
// See which format we should be using
const ConsoleTiming timing = myOSystem.console().timing();
const PaletteType paletteType = toPaletteType(name);
// Now consider the current display format
const PaletteArray* palette = palettes[paletteType][int(timing)];
if(paletteType == PaletteType::Custom)
generateCustomPalette(timing);
myOSystem.frameBuffer().setTIAPalette(adjustedPalette(*palette));
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteArray PaletteHandler::adjustedPalette(const PaletteArray& palette)
{
PaletteArray destPalette;
// Constants for saturation and gray scale calculation
constexpr float PR = .2989F;
constexpr float PG = .5870F;
constexpr float PB = .1140F;
// Generate adjust table
constexpr int ADJUST_SIZE = 256;
constexpr int RGB_UNIT = 1 << 8;
constexpr float RGB_OFFSET = 0.5F;
const float hue = myHue;
const float brightness = myBrightness * (0.5F * RGB_UNIT) + RGB_OFFSET;
const float contrast = myContrast * (0.5F * RGB_UNIT) + RGB_UNIT;
const float saturation = mySaturation + 1;
const float gamma = 1.1333F - myGamma * 0.5F;
/* match common PC's 2.2 gamma to TV's 2.65 gamma */
constexpr float toFloat = 1.F / (ADJUST_SIZE - 1);
std::array<float, ADJUST_SIZE> adjust;
for(int i = 0; i < ADJUST_SIZE; i++)
adjust[i] = powf(i * toFloat, gamma) * contrast + brightness;
// Transform original palette into destination palette
for(size_t i = 0; i < destPalette.size(); i += 2)
{
const uInt32 pixel = palette[i];
int r = (pixel >> 16) & 0xff;
int g = (pixel >> 8) & 0xff;
int b = (pixel >> 0) & 0xff;
// adjust hue (different for NTSC and PAL?) and saturation
adjustHueSaturation(r, g, b, hue, saturation);
// adjust contrast, brightness, gamma
r = adjust[r];
g = adjust[g];
b = adjust[b];
r = BSPF::clamp(r, 0, 255);
g = BSPF::clamp(g, 0, 255);
b = BSPF::clamp(b, 0, 255);
destPalette[i] = (r << 16) + (g << 8) + b;
// Fill the odd numbered palette entries with gray values (calculated
// 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));
destPalette[i + 1] = (lum << 16) + (lum << 8) + lum;
}
return destPalette;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::loadUserPalette()
{
if (!myOSystem.checkUserPalette(true))
return;
const string& palette = myOSystem.paletteFile();
ifstream in(palette, std::ios::binary);
// Now that we have valid data, create the user-defined palettes
std::array<uInt8, 3> pixbuf; // Temporary buffer for one 24-bit pixel
for(int i = 0; i < 128; i++) // NTSC palette
{
in.read(reinterpret_cast<char*>(pixbuf.data()), 3);
const uInt32 pixel = (int(pixbuf[0]) << 16) + (int(pixbuf[1]) << 8) + int(pixbuf[2]);
ourUserNTSCPalette[(i<<1)] = pixel;
}
for(int i = 0; i < 128; i++) // PAL palette
{
in.read(reinterpret_cast<char*>(pixbuf.data()), 3);
const uInt32 pixel = (int(pixbuf[0]) << 16) + (int(pixbuf[1]) << 8) + int(pixbuf[2]);
ourUserPALPalette[(i<<1)] = pixel;
}
std::array<uInt32, 16> secam; // All 8 24-bit pixels, plus 8 colorloss pixels
for(int i = 0; i < 8; i++) // SECAM palette
{
in.read(reinterpret_cast<char*>(pixbuf.data()), 3);
const uInt32 pixel = (int(pixbuf[0]) << 16) + (int(pixbuf[1]) << 8) + int(pixbuf[2]);
secam[(i<<1)] = pixel;
secam[(i<<1)+1] = 0;
}
uInt32* ptr = ourUserSECAMPalette.data();
for(int i = 0; i < 16; ++i)
{
const uInt32* s = secam.data();
for(int j = 0; j < 16; ++j)
*ptr++ = *s++;
}
myUserPaletteDefined = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::generateCustomPalette(ConsoleTiming timing)
{
constexpr int NUM_CHROMA = 16;
constexpr int NUM_LUMA = 8;
constexpr float SATURATION = 0.25F; // default saturation
float color[NUM_CHROMA][2] = {{0.0F}};
if(timing == ConsoleTiming::ntsc)
{
// YIQ is YUV shifted by 33°
constexpr float offset = 33 * BSPF::PI_f / 180;
const float shift = myPhaseNTSC * BSPF::PI_f / 180;
// color 0 is grayscale
for(int chroma = 1; chroma < NUM_CHROMA; chroma++)
{
color[chroma][0] = SATURATION * sinf(offset + shift * (chroma - 1));
color[chroma][1] = SATURATION * sinf(offset + shift * (chroma - 1 - BSPF::PI_f));
}
for(int chroma = 0; chroma < NUM_CHROMA; chroma++)
{
const float I = color[chroma][0];
const float Q = color[chroma][1];
for(int luma = 0; luma < NUM_LUMA; luma++)
{
const float Y = 0.05F + luma / 8.24F; // 0.05..~0.90
float R = Y + 0.956F * I + 0.621F * Q;
float G = Y - 0.272F * I - 0.647F * Q;
float B = Y - 1.106F * I + 1.703F * Q;
if(R < 0) R = 0;
if(G < 0) G = 0;
if(B < 0) B = 0;
R = powf(R, 0.9F);
G = powf(G, 0.9F);
B = powf(B, 0.9F);
int r = BSPF::clamp(R * 255.F, 0.F, 255.F);
int g = BSPF::clamp(G * 255.F, 0.F, 255.F);
int b = BSPF::clamp(B * 255.F, 0.F, 255.F);
ourCustomNTSCPalette[(chroma * NUM_LUMA + luma) << 1] = (r << 16) + (g << 8) + b;
}
}
}
else if(timing == ConsoleTiming::pal)
{
constexpr float offset = BSPF::PI_f;
const float shift = myPhasePAL * BSPF::PI_f / 180;
constexpr float fixedShift = 22.5F * BSPF::PI_f / 180;
// colors 0, 1, 14 and 15 are grayscale
for(int chroma = 2; chroma < NUM_CHROMA - 2; chroma++)
{
int idx = NUM_CHROMA - 1 - chroma;
color[idx][0] = SATURATION * sinf(offset - fixedShift * chroma);
if ((idx & 1) == 0)
color[idx][1] = SATURATION * sinf(offset - shift * (chroma - 3.5F) / 2.F);
else
color[idx][1] = SATURATION * -sinf(offset - shift * chroma / 2.F);
}
for(int chroma = 0; chroma < NUM_CHROMA; chroma++)
{
const float U = color[chroma][0];
const float V = color[chroma][1];
for(int luma = 0; luma < NUM_LUMA; luma++)
{
const float Y = 0.05F + luma / 8.24F; // 0.05..~0.90
// Most sources
float R = Y + 1.403F * V;
float G = Y - 0.344F * U - 0.714F * V;
float B = Y + 1.770F * U;
// German Wikipedia, huh???
//float B = Y + 1 / 0.493 * U;
//float R = Y + 1 / 0.877 * V;
//float G = 1.704 * Y - 0.590 * R - 0.194 * B;
if(R < 0) R = 0.0;
if(G < 0) G = 0.0;
if(B < 0) B = 0.0;
R = powf(R, 1.2F);
G = powf(G, 1.2F);
B = powf(B, 1.2F);
int r = BSPF::clamp(R * 255.F, 0.F, 255.F);
int g = BSPF::clamp(G * 255.F, 0.F, 255.F);
int b = BSPF::clamp(B * 255.F, 0.F, 255.F);
ourCustomPALPalette[(chroma * NUM_LUMA + luma) << 1] = (r << 16) + (g << 8) + b;
}
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PaletteHandler::adjustHueSaturation(int& R, int& G, int& B, float H, float S)
{
// Adapted from http://beesbuzz.biz/code/16-hsv-color-transforms
// (C) J. “Fluffy” Shagam
// License: CC BY-SA 4.0
const float su = S * cosf(-H * BSPF::PI_f);
const float sw = S * sinf(-H * BSPF::PI_f);
const float r = (.299F + .701F * su + .168F * sw) * R
+ (.587F - .587F * su + .330F * sw) * G
+ (.114F - .114F * su - .497F * sw) * B;
const float g = (.299F - .299F * su - .328F * sw) * R
+ (.587F + .413F * su + .035F * sw) * G
+ (.114F - .114F * su + .292F * sw) * B;
const float b = (.299F - .300F * su + 1.25F * sw) * R
+ (.587F - .588F * su - 1.05F * sw) * G
+ (.114F + .886F * su - .203F * sw) * B;
R = BSPF::clamp(r, 0.F, 255.F);
G = BSPF::clamp(g, 0.F, 255.F);
B = BSPF::clamp(b, 0.F, 255.F);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const PaletteArray PaletteHandler::ourNTSCPalette = {
0x000000, 0, 0x4a4a4a, 0, 0x6f6f6f, 0, 0x8e8e8e, 0,
0xaaaaaa, 0, 0xc0c0c0, 0, 0xd6d6d6, 0, 0xececec, 0,
0x484800, 0, 0x69690f, 0, 0x86861d, 0, 0xa2a22a, 0,
0xbbbb35, 0, 0xd2d240, 0, 0xe8e84a, 0, 0xfcfc54, 0,
0x7c2c00, 0, 0x904811, 0, 0xa26221, 0, 0xb47a30, 0,
0xc3903d, 0, 0xd2a44a, 0, 0xdfb755, 0, 0xecc860, 0,
0x901c00, 0, 0xa33915, 0, 0xb55328, 0, 0xc66c3a, 0,
0xd5824a, 0, 0xe39759, 0, 0xf0aa67, 0, 0xfcbc74, 0,
0x940000, 0, 0xa71a1a, 0, 0xb83232, 0, 0xc84848, 0,
0xd65c5c, 0, 0xe46f6f, 0, 0xf08080, 0, 0xfc9090, 0,
0x840064, 0, 0x97197a, 0, 0xa8308f, 0, 0xb846a2, 0,
0xc659b3, 0, 0xd46cc3, 0, 0xe07cd2, 0, 0xec8ce0, 0,
0x500084, 0, 0x68199a, 0, 0x7d30ad, 0, 0x9246c0, 0,
0xa459d0, 0, 0xb56ce0, 0, 0xc57cee, 0, 0xd48cfc, 0,
0x140090, 0, 0x331aa3, 0, 0x4e32b5, 0, 0x6848c6, 0,
0x7f5cd5, 0, 0x956fe3, 0, 0xa980f0, 0, 0xbc90fc, 0,
0x000094, 0, 0x181aa7, 0, 0x2d32b8, 0, 0x4248c8, 0,
0x545cd6, 0, 0x656fe4, 0, 0x7580f0, 0, 0x8490fc, 0,
0x001c88, 0, 0x183b9d, 0, 0x2d57b0, 0, 0x4272c2, 0,
0x548ad2, 0, 0x65a0e1, 0, 0x75b5ef, 0, 0x84c8fc, 0,
0x003064, 0, 0x185080, 0, 0x2d6d98, 0, 0x4288b0, 0,
0x54a0c5, 0, 0x65b7d9, 0, 0x75cceb, 0, 0x84e0fc, 0,
0x004030, 0, 0x18624e, 0, 0x2d8169, 0, 0x429e82, 0,
0x54b899, 0, 0x65d1ae, 0, 0x75e7c2, 0, 0x84fcd4, 0,
0x004400, 0, 0x1a661a, 0, 0x328432, 0, 0x48a048, 0,
0x5cba5c, 0, 0x6fd26f, 0, 0x80e880, 0, 0x90fc90, 0,
0x143c00, 0, 0x355f18, 0, 0x527e2d, 0, 0x6e9c42, 0,
0x87b754, 0, 0x9ed065, 0, 0xb4e775, 0, 0xc8fc84, 0,
0x303800, 0, 0x505916, 0, 0x6d762b, 0, 0x88923e, 0,
0xa0ab4f, 0, 0xb7c25f, 0, 0xccd86e, 0, 0xe0ec7c, 0,
0x482c00, 0, 0x694d14, 0, 0x866a26, 0, 0xa28638, 0,
0xbb9f47, 0, 0xd2b656, 0, 0xe8cc63, 0, 0xfce070, 0
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const PaletteArray PaletteHandler::ourPALPalette = {
0x000000, 0, 0x121212, 0, 0x242424, 0, 0x484848, 0, // 180 0
0x6c6c6c, 0, 0x909090, 0, 0xb4b4b4, 0, 0xd8d8d8, 0, // was 0x111111..0xcccccc
0x000000, 0, 0x121212, 0, 0x242424, 0, 0x484848, 0, // 198 1
0x6c6c6c, 0, 0x909090, 0, 0xb4b4b4, 0, 0xd8d8d8, 0,
0x1d0f00, 0, 0x3f2700, 0, 0x614900, 0, 0x836b01, 0, // 1b0 2
0xa58d23, 0, 0xc7af45, 0, 0xe9d167, 0, 0xffe789, 0, // was ..0xfff389
0x002400, 0, 0x004600, 0, 0x216800, 0, 0x438a07, 0, // 1c8 3
0x65ac29, 0, 0x87ce4b, 0, 0xa9f06d, 0, 0xcbff8f, 0,
0x340000, 0, 0x561400, 0, 0x783602, 0, 0x9a5824, 0, // 1e0 4
0xbc7a46, 0, 0xde9c68, 0, 0xffbe8a, 0, 0xffd0ad, 0, // was ..0xffe0ac
0x002700, 0, 0x004900, 0, 0x0c6b0c, 0, 0x2e8d2e, 0, // 1f8 5
0x50af50, 0, 0x72d172, 0, 0x94f394, 0, 0xb6ffb6, 0,
0x3d0008, 0, 0x610511, 0, 0x832733, 0, 0xa54955, 0, // 210 6
0xc76b77, 0, 0xe98d99, 0, 0xffafbb, 0, 0xffd1d7, 0, // was 0x3f0000..0xffd1dd
0x001e12, 0, 0x004228, 0, 0x046540, 0, 0x268762, 0, // 228 7
0x48a984, 0, 0x6acba6, 0, 0x8cedc8, 0, 0xafffe0, 0, // was 0x002100, 0x00431e..0xaeffff
0x300025, 0, 0x5f0047, 0, 0x811e69, 0, 0xa3408b, 0, // 240 8
0xc562ad, 0, 0xe784cf, 0, 0xffa8ea, 0, 0xffc9f2, 0, // was ..0xffa6f1, 0xffc8ff
0x001431, 0, 0x003653, 0, 0x0a5875, 0, 0x2c7a97, 0, // 258 9
0x4e9cb9, 0, 0x70bedb, 0, 0x92e0fd, 0, 0xb4ffff, 0,
0x2c0052, 0, 0x4e0074, 0, 0x701d96, 0, 0x923fb8, 0, // 270 a
0xb461da, 0, 0xd683fc, 0, 0xe2a5ff, 0, 0xeec9ff, 0, // was ..0xf8a5ff, 0xffc7ff
0x001759, 0, 0x00247c, 0, 0x1d469e, 0, 0x3f68c0, 0, // 288 b
0x618ae2, 0, 0x83acff, 0, 0xa5ceff, 0, 0xc7f0ff, 0,
0x12006d, 0, 0x34038f, 0, 0x5625b1, 0, 0x7847d3, 0, // 2a0 c
0x9a69f5, 0, 0xb48cff, 0, 0xc9adff, 0, 0xe1d1ff, 0, // was ..0xbc8bff, 0xdeadff, 0xffcfff,
0x000070, 0, 0x161292, 0, 0x3834b4, 0, 0x5a56d6, 0, // 2b8 d
0x7c78f8, 0, 0x9e9aff, 0, 0xc0bcff, 0, 0xe2deff, 0,
0x000000, 0, 0x121212, 0, 0x242424, 0, 0x484848, 0, // 2d0 e
0x6c6c6c, 0, 0x909090, 0, 0xb4b4b4, 0, 0xd8d8d8, 0,
0x000000, 0, 0x121212, 0, 0x242424, 0, 0x484848, 0, // 2e8 f
0x6c6c6c, 0, 0x909090, 0, 0xb4b4b4, 0, 0xd8d8d8, 0,
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const PaletteArray PaletteHandler::ourSECAMPalette = {
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const PaletteArray PaletteHandler::ourNTSCPaletteZ26 = {
0x000000, 0, 0x505050, 0, 0x646464, 0, 0x787878, 0,
0x8c8c8c, 0, 0xa0a0a0, 0, 0xb4b4b4, 0, 0xc8c8c8, 0,
0x445400, 0, 0x586800, 0, 0x6c7c00, 0, 0x809000, 0,
0x94a414, 0, 0xa8b828, 0, 0xbccc3c, 0, 0xd0e050, 0,
0x673900, 0, 0x7b4d00, 0, 0x8f6100, 0, 0xa37513, 0,
0xb78927, 0, 0xcb9d3b, 0, 0xdfb14f, 0, 0xf3c563, 0,
0x7b2504, 0, 0x8f3918, 0, 0xa34d2c, 0, 0xb76140, 0,
0xcb7554, 0, 0xdf8968, 0, 0xf39d7c, 0, 0xffb190, 0,
0x7d122c, 0, 0x912640, 0, 0xa53a54, 0, 0xb94e68, 0,
0xcd627c, 0, 0xe17690, 0, 0xf58aa4, 0, 0xff9eb8, 0,
0x730871, 0, 0x871c85, 0, 0x9b3099, 0, 0xaf44ad, 0,
0xc358c1, 0, 0xd76cd5, 0, 0xeb80e9, 0, 0xff94fd, 0,
0x5d0b92, 0, 0x711fa6, 0, 0x8533ba, 0, 0x9947ce, 0,
0xad5be2, 0, 0xc16ff6, 0, 0xd583ff, 0, 0xe997ff, 0,
0x401599, 0, 0x5429ad, 0, 0x683dc1, 0, 0x7c51d5, 0,
0x9065e9, 0, 0xa479fd, 0, 0xb88dff, 0, 0xcca1ff, 0,
0x252593, 0, 0x3939a7, 0, 0x4d4dbb, 0, 0x6161cf, 0,
0x7575e3, 0, 0x8989f7, 0, 0x9d9dff, 0, 0xb1b1ff, 0,
0x0f3480, 0, 0x234894, 0, 0x375ca8, 0, 0x4b70bc, 0,
0x5f84d0, 0, 0x7398e4, 0, 0x87acf8, 0, 0x9bc0ff, 0,
0x04425a, 0, 0x18566e, 0, 0x2c6a82, 0, 0x407e96, 0,
0x5492aa, 0, 0x68a6be, 0, 0x7cbad2, 0, 0x90cee6, 0,
0x044f30, 0, 0x186344, 0, 0x2c7758, 0, 0x408b6c, 0,
0x549f80, 0, 0x68b394, 0, 0x7cc7a8, 0, 0x90dbbc, 0,
0x0f550a, 0, 0x23691e, 0, 0x377d32, 0, 0x4b9146, 0,
0x5fa55a, 0, 0x73b96e, 0, 0x87cd82, 0, 0x9be196, 0,
0x1f5100, 0, 0x336505, 0, 0x477919, 0, 0x5b8d2d, 0,
0x6fa141, 0, 0x83b555, 0, 0x97c969, 0, 0xabdd7d, 0,
0x344600, 0, 0x485a00, 0, 0x5c6e14, 0, 0x708228, 0,
0x84963c, 0, 0x98aa50, 0, 0xacbe64, 0, 0xc0d278, 0,
0x463e00, 0, 0x5a5205, 0, 0x6e6619, 0, 0x827a2d, 0,
0x968e41, 0, 0xaaa255, 0, 0xbeb669, 0, 0xd2ca7d, 0
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const PaletteArray PaletteHandler::ourPALPaletteZ26 = {
0x000000, 0, 0x4c4c4c, 0, 0x606060, 0, 0x747474, 0,
0x888888, 0, 0x9c9c9c, 0, 0xb0b0b0, 0, 0xc4c4c4, 0,
0x000000, 0, 0x4c4c4c, 0, 0x606060, 0, 0x747474, 0,
0x888888, 0, 0x9c9c9c, 0, 0xb0b0b0, 0, 0xc4c4c4, 0,
0x533a00, 0, 0x674e00, 0, 0x7b6203, 0, 0x8f7617, 0,
0xa38a2b, 0, 0xb79e3f, 0, 0xcbb253, 0, 0xdfc667, 0,
0x1b5800, 0, 0x2f6c00, 0, 0x438001, 0, 0x579415, 0,
0x6ba829, 0, 0x7fbc3d, 0, 0x93d051, 0, 0xa7e465, 0,
0x6a2900, 0, 0x7e3d12, 0, 0x925126, 0, 0xa6653a, 0,
0xba794e, 0, 0xce8d62, 0, 0xe2a176, 0, 0xf6b58a, 0,
0x075b00, 0, 0x1b6f11, 0, 0x2f8325, 0, 0x439739, 0,
0x57ab4d, 0, 0x6bbf61, 0, 0x7fd375, 0, 0x93e789, 0,
0x741b2f, 0, 0x882f43, 0, 0x9c4357, 0, 0xb0576b, 0,
0xc46b7f, 0, 0xd87f93, 0, 0xec93a7, 0, 0xffa7bb, 0,
0x00572e, 0, 0x106b42, 0, 0x247f56, 0, 0x38936a, 0,
0x4ca77e, 0, 0x60bb92, 0, 0x74cfa6, 0, 0x88e3ba, 0,
0x6d165f, 0, 0x812a73, 0, 0x953e87, 0, 0xa9529b, 0,
0xbd66af, 0, 0xd17ac3, 0, 0xe58ed7, 0, 0xf9a2eb, 0,
0x014c5e, 0, 0x156072, 0, 0x297486, 0, 0x3d889a, 0,
0x519cae, 0, 0x65b0c2, 0, 0x79c4d6, 0, 0x8dd8ea, 0,
0x5f1588, 0, 0x73299c, 0, 0x873db0, 0, 0x9b51c4, 0,
0xaf65d8, 0, 0xc379ec, 0, 0xd78dff, 0, 0xeba1ff, 0,
0x123b87, 0, 0x264f9b, 0, 0x3a63af, 0, 0x4e77c3, 0,
0x628bd7, 0, 0x769feb, 0, 0x8ab3ff, 0, 0x9ec7ff, 0,
0x451e9d, 0, 0x5932b1, 0, 0x6d46c5, 0, 0x815ad9, 0,
0x956eed, 0, 0xa982ff, 0, 0xbd96ff, 0, 0xd1aaff, 0,
0x2a2b9e, 0, 0x3e3fb2, 0, 0x5253c6, 0, 0x6667da, 0,
0x7a7bee, 0, 0x8e8fff, 0, 0xa2a3ff, 0, 0xb6b7ff, 0,
0x000000, 0, 0x4c4c4c, 0, 0x606060, 0, 0x747474, 0,
0x888888, 0, 0x9c9c9c, 0, 0xb0b0b0, 0, 0xc4c4c4, 0,
0x000000, 0, 0x4c4c4c, 0, 0x606060, 0, 0x747474, 0,
0x888888, 0, 0x9c9c9c, 0, 0xb0b0b0, 0, 0xc4c4c4, 0
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const PaletteArray PaletteHandler::ourSECAMPaletteZ26 = {
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteArray PaletteHandler::ourUserNTSCPalette = { 0 }; // filled from external file
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteArray PaletteHandler::ourUserPALPalette = { 0 }; // filled from external file
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteArray PaletteHandler::ourUserSECAMPalette = { 0 }; // filled from external file
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteArray PaletteHandler::ourCustomNTSCPalette = { 0 }; // filled by function
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteArray PaletteHandler::ourCustomPALPalette = { 0 }; // filled by function

View File

@ -0,0 +1,238 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#ifndef PALETTE_HANDLER_HXX
#define PALETTE_HANDLER_HXX
#include "bspf.hxx"
#include "OSystem.hxx"
#include "ConsoleTiming.hxx"
class PaletteHandler
{
public:
// Setting names of palette types
static constexpr const char* SETTING_STANDARD = "standard";
static constexpr const char* SETTING_Z26 = "z26";
static constexpr const char* SETTING_USER = "user";
static constexpr const char* SETTING_CUSTOM = "custom";
// Phase shift default and limits
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;
// Externally used adjustment parameters
struct Adjustable {
float phaseNtsc{0.F}, phasePal{0.F};
uInt32 hue{0}, saturation{0}, contrast{0}, brightness{0}, gamma{0};
};
public:
PaletteHandler(OSystem& system);
virtual ~PaletteHandler() = default;
/**
Cycle through available palettes.
@param next Select next palette, else previous one
*/
void cyclePalette(bool next = true);
/*
Cycle through each palette adjustable.
@param next Select next adjustable, else previous one
*/
void cycleAdjustable(bool next = true);
/*
Increase or decrease current palette adjustable.
@param increase Increase adjustable if true, else decrease
*/
void changeAdjustable(bool increase = true);
// Load adjustables from settings
void loadConfig(const Settings& settings);
// Save adjustables to settings
void saveConfig(Settings& settings) const;
// Set adjustables
void setAdjustables(const Adjustable& adjustable);
// Retrieve current adjustables
void getAdjustables(Adjustable& adjustable) const;
/**
Sets the palette according to the given palette name.
@param name The palette to switch to
*/
void setPalette(const string& name);
/**
Sets the palette from current settings.
*/
void setPalette();
private:
static constexpr char DEGREE = 0x1c;
enum PaletteType {
Standard,
Z26,
User,
Custom,
NumTypes,
MinType = Standard,
MaxType = Custom
};
/**
Convert adjustables from/to 100% scale
*/
constexpr float scaleFrom100(float x) const { return (x / 50.F) - 1.F; }
constexpr uInt32 scaleTo100(float x) const { return uInt32(50 * (x + 1.F)); }
/**
Convert palette settings name to enumeration.
@param name The given palette's settings name
@return The palette type
*/
PaletteType toPaletteType(const string& name) const;
/**
Convert enumeration to palette settings name.
@param type The given palette type
@return The palette's settings name
*/
string toPaletteName(PaletteType type) const;
/**
Change the "phase shift" variable.
Note that there are two of these (NTSC and PAL). The currently
active mode will determine which one is used.
@param increase Increase if true, else decrease
*/
void changeColorPhaseShift(bool increase = true);
/**
Generates a custom palette, based on user defined phase shifts.
@param timing Use NTSC or PAL phase shift and generate according palette
*/
void generateCustomPalette(ConsoleTiming timing);
/**
Create new palette by applying palette adjustments on given palette.
@param source The palette which should be adjusted
@return An adjusted palette
*/
PaletteArray adjustedPalette(const PaletteArray& source);
/**
Adjust hue and saturation for given RGB values.
@param R The red value to adjust
@param G The green value to adjust
@param B The blue value to adjust
@param H The hue adjustment value
@param S The saturation
*/
void adjustHueSaturation(int& R, int& G, int& B, float H, float S);
/**
Loads a user-defined palette file (from OSystem::paletteFile), filling the
appropriate user-defined palette arrays.
*/
void loadUserPalette();
private:
static constexpr int NUM_ADJUSTABLES = 6;
OSystem& myOSystem;
// The currently selected adjustable
uInt32 myCurrentAdjustable{0};
struct AdjustableTag {
const char* const name{nullptr};
float* value{nullptr};
};
const std::array<AdjustableTag, NUM_ADJUSTABLES> myAdjustables =
{ {
{ "phase shift", nullptr },
{ "hue", &myHue },
{ "saturation", &mySaturation },
{ "contrast", &myContrast },
{ "brightness", &myBrightness },
{ "gamma", &myGamma },
} };
// NTSC and PAL color phase shifts
float myPhaseNTSC{DEF_NTSC_SHIFT};
float myPhasePAL{DEF_PAL_SHIFT};
// range -1.0 to +1.0 (as in AtariNTSC)
// Basic parameters
float myHue{0.0F}; // -1 = -180 degrees +1 = +180 degrees
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)
// Advanced parameters
float myGamma{0.0F}; // -1 = dark (1.5) +1 = light (0.5)
// Indicates whether an external palette was found and
// successfully loaded
bool myUserPaletteDefined{false};
// Table of RGB values for NTSC, PAL and SECAM
static const PaletteArray ourNTSCPalette;
static const PaletteArray ourPALPalette;
static const PaletteArray ourSECAMPalette;
// Table of RGB values for NTSC, PAL and SECAM - Z26 version
static const PaletteArray ourNTSCPaletteZ26;
static const PaletteArray ourPALPaletteZ26;
static const PaletteArray ourSECAMPaletteZ26;
// Table of RGB values for NTSC, PAL and SECAM - user-defined
static PaletteArray ourUserNTSCPalette;
static PaletteArray ourUserPALPalette;
static PaletteArray ourUserSECAMPalette;
// Table of RGB values for NTSC, PAL - custom-defined and generated
static PaletteArray ourCustomNTSCPalette;
static PaletteArray ourCustomPALPalette;
private:
PaletteHandler() = delete;
PaletteHandler(const PaletteHandler&) = delete;
PaletteHandler(PaletteHandler&&) = delete;
PaletteHandler& operator=(const PaletteHandler&) = delete;
PaletteHandler& operator=(const PaletteHandler&&) = delete;
};
#endif // PALETTE_HANDLER_HXX

View File

@ -11,6 +11,7 @@ MODULE_OBJS := \
src/common/Logger.o \
src/common/main.o \
src/common/MouseControl.o \
src/common/PaletteHandler.o \
src/common/PhosphorHandler.o \
src/common/PhysicalJoystick.o \
src/common/PJoystickHandler.o \

View File

@ -57,9 +57,15 @@ void AtariNTSC::generateKernels()
const uInt8* ptr = myRGBPalette.data();
for(size_t entry = 0; entry < myRGBPalette.size() / 3; ++entry)
{
#ifdef BLARGG_PALETTE
float r = myImpl.to_float[*ptr++],
g = 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 );
// 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)
{
#ifdef BLARGG_PALETTE
impl.brightness = setup.brightness * (0.5F * rgb_unit) + rgb_offset;
impl.contrast = setup.contrast * (0.5F * rgb_unit) + rgb_unit;
#endif
impl.artifacts = setup.artifacts;
if ( impl.artifacts > 0 )
@ -334,6 +342,7 @@ void AtariNTSC::init(init_t& impl, const Setup& setup)
initFilters(impl, setup);
#ifdef BLARGG_PALETTE
/* generate gamma table */
if (true) /* was (gamma_size > 1) */
{
@ -345,15 +354,18 @@ void AtariNTSC::init(init_t& impl, const Setup& setup)
impl.to_float[i] =
powf(i * to_float, gamma) * impl.contrast + impl.brightness;
}
#endif
/* setup decoder matricies */
{
#ifdef BLARGG_PALETTE
float hue = setup.hue * BSPF::PI_f + BSPF::PI_f / 180 * ext_decoder_hue;
float sat = setup.saturation + 1;
hue += BSPF::PI_f / 180 * (std_decoder_hue - ext_decoder_hue);
float s = sinf(hue)*sat;
float c = cosf(hue)*sat;
#endif
float* out = impl.to_rgb.data();
int n;
@ -366,8 +378,13 @@ void AtariNTSC::init(init_t& impl, const Setup& setup)
{
float i = *in++;
float q = *in++;
#ifdef BLARGG_PALETTE
*out++ = i * c - q * s;
*out++ = i * s + q * c;
#else
*out++ = i ;
*out++ = q;
#endif
}
while ( --n2 );
#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 = {
#ifdef BLARGG_PALETTE
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 = {
#ifdef BLARGG_PALETTE
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 = {
#ifdef BLARGG_PALETTE
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 = {
#ifdef BLARGG_PALETTE
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 "bspf.hxx"
//#define BLARGG_PALETTE // also modify contrast, brightness, saturation, gamma and hue when defined
class AtariNTSC
{
public:
@ -57,14 +59,18 @@ class AtariNTSC
struct Setup
{
// Basic parameters
#ifdef BLARGG_PALETTE
float hue{0.F}; // -1 = -180 degrees +1 = +180 degrees
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 brightness{0.F}; // -1 = dark (0.5) +1 = light (1.5)
#endif
float sharpness{0.F}; // edge contrast enhancement/blurring
// Advanced parameters
#ifdef BLARGG_PALETTE
float gamma{0.F}; // -1 = dark (1.5) +1 = light (0.5)
#endif
float resolution{0.F}; // image resolution
float artifacts{0.F}; // artifacts caused by color changes
float fringing{0.F}; // color artifacts caused by brightness changes
@ -127,7 +133,9 @@ class AtariNTSC
burst_size = entry_size / burst_count,
kernel_half = 16,
kernel_size = kernel_half * 2 + 1,
#ifdef BLARGG_PALETTE
gamma_size = 256,
#endif
rgb_builder = ((1 << 21) | (1 << 11) | (1 << 1)),
rgb_kernel_size = burst_size / alignment_count,
@ -162,16 +170,20 @@ class AtariNTSC
struct init_t
{
std::array<float, burst_count * 6> to_rgb{0.F};
#ifdef BLARGG_PALETTE
std::array<float, gamma_size> to_float{0.F};
float contrast{0.F};
float brightness{0.F};
#endif
float artifacts{0.F};
float fringing{0.F};
std::array<float, rescale_out * kernel_size * 2> kernel{0.F};
init_t() {
to_rgb.fill(0.0);
#ifdef BLARGG_PALETTE
to_float.fill(0.0);
#endif
kernel.fill(0.0);
}
};

View File

@ -74,13 +74,19 @@ string NTSCFilter::getPreset() const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string NTSCFilter::setNextAdjustable()
{
if(myPreset != Preset::CUSTOM)
return "'Custom' TV mode not selected";
//if(myPreset != Preset::CUSTOM)
// return "'Custom' TV mode not selected";
#ifdef BLARGG_PALETTE
myCurrentAdjustable = (myCurrentAdjustable + 1) % 10;
#else
myCurrentAdjustable = (myCurrentAdjustable + 1) % 5;
#endif
ostringstream buf;
buf << "Custom adjustable '" << ourCustomAdjustables[myCurrentAdjustable].type
<< "' selected";
<< "' selected ("
<< scaleTo100(*ourCustomAdjustables[myCurrentAdjustable].value) << "%)";
return buf.str();
}
@ -88,14 +94,19 @@ string NTSCFilter::setNextAdjustable()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string NTSCFilter::setPreviousAdjustable()
{
if(myPreset != Preset::CUSTOM)
return "'Custom' TV mode not selected";
//if(myPreset != Preset::CUSTOM)
// return "'Custom' TV mode not selected";
#ifdef BLARGG_PALETTE
if(myCurrentAdjustable == 0) myCurrentAdjustable = 9;
#else
if(myCurrentAdjustable == 0) myCurrentAdjustable = 4;
#endif
else --myCurrentAdjustable;
ostringstream buf;
buf << "Custom adjustable '" << ourCustomAdjustables[myCurrentAdjustable].type
<< "' selected";
<< "' selected ("
<< scaleTo100(*ourCustomAdjustables[myCurrentAdjustable].value) << "%)";
return buf.str();
}
@ -103,8 +114,8 @@ string NTSCFilter::setPreviousAdjustable()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string NTSCFilter::increaseAdjustable()
{
if(myPreset != Preset::CUSTOM)
return "'Custom' TV mode not selected";
//if(myPreset != Preset::CUSTOM)
// return "'Custom' TV mode not selected";
uInt32 newval = scaleTo100(*ourCustomAdjustables[myCurrentAdjustable].value);
newval += 2; if(newval > 100) newval = 100;
@ -112,7 +123,7 @@ string NTSCFilter::increaseAdjustable()
ostringstream buf;
buf << "Custom '" << ourCustomAdjustables[myCurrentAdjustable].type
<< "' set to " << newval;
<< "' set to " << newval << "%";
setPreset(myPreset);
return buf.str();
@ -121,8 +132,8 @@ string NTSCFilter::increaseAdjustable()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string NTSCFilter::decreaseAdjustable()
{
if(myPreset != Preset::CUSTOM)
return "'Custom' TV mode not selected";
//if(myPreset != Preset::CUSTOM)
// return "'Custom' TV mode not selected";
uInt32 newval = scaleTo100(*ourCustomAdjustables[myCurrentAdjustable].value);
if(newval < 2) newval = 0;
@ -131,7 +142,7 @@ string NTSCFilter::decreaseAdjustable()
ostringstream buf;
buf << "Custom '" << ourCustomAdjustables[myCurrentAdjustable].type
<< "' set to " << newval;
<< "' set to " << newval << "%";
setPreset(myPreset);
return buf.str();
@ -140,13 +151,16 @@ string NTSCFilter::decreaseAdjustable()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void NTSCFilter::loadConfig(const Settings& settings)
{
// Load adjustables for custom mode
#ifdef BLARGG_PALETTE
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.contrast = BSPF::clamp(settings.getFloat("tv.contrast"), -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);
#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.artifacts = BSPF::clamp(settings.getFloat("tv.artifacts"), -1.0F, 1.0F);
myCustomSetup.fringing = BSPF::clamp(settings.getFloat("tv.fringing"), -1.0F, 1.0F);
@ -157,12 +171,14 @@ void NTSCFilter::loadConfig(const Settings& settings)
void NTSCFilter::saveConfig(Settings& settings) const
{
// Save adjustables for custom mode
settings.setValue("tv.hue", myCustomSetup.hue);
settings.setValue("tv.saturation", myCustomSetup.saturation);
settings.setValue("tv.contrast", myCustomSetup.contrast);
settings.setValue("tv.brightness", myCustomSetup.brightness);
#ifdef BLARGG_PALETTE
//settings.setValue("tv.hue", myCustomSetup.hue);
//settings.setValue("tv.saturation", myCustomSetup.saturation);
//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.gamma", myCustomSetup.gamma);
settings.setValue("tv.resolution", myCustomSetup.resolution);
settings.setValue("tv.artifacts", myCustomSetup.artifacts);
settings.setValue("tv.fringing", myCustomSetup.fringing);
@ -192,12 +208,14 @@ void NTSCFilter::getAdjustables(Adjustable& adjustable, Preset preset) const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void NTSCFilter::setCustomAdjustables(Adjustable& adjustable)
{
myCustomSetup.hue = scaleFrom100(adjustable.hue);
myCustomSetup.saturation = scaleFrom100(adjustable.saturation);
myCustomSetup.contrast = scaleFrom100(adjustable.contrast);
myCustomSetup.brightness = scaleFrom100(adjustable.brightness);
#ifdef BLARGG_PALETTE
//myCustomSetup.hue = scaleFrom100(adjustable.hue);
//myCustomSetup.saturation = scaleFrom100(adjustable.saturation);
//myCustomSetup.contrast = scaleFrom100(adjustable.contrast);
//myCustomSetup.brightness = scaleFrom100(adjustable.brightness);
//myCustomSetup.gamma = scaleFrom100(adjustable.gamma);
#endif
myCustomSetup.sharpness = scaleFrom100(adjustable.sharpness);
myCustomSetup.gamma = scaleFrom100(adjustable.gamma);
myCustomSetup.resolution = scaleFrom100(adjustable.resolution);
myCustomSetup.artifacts = scaleFrom100(adjustable.artifacts);
myCustomSetup.fringing = scaleFrom100(adjustable.fringing);
@ -208,12 +226,14 @@ void NTSCFilter::setCustomAdjustables(Adjustable& adjustable)
void NTSCFilter::convertToAdjustable(Adjustable& adjustable,
const AtariNTSC::Setup& setup) const
{
adjustable.hue = scaleTo100(setup.hue);
adjustable.saturation = scaleTo100(setup.saturation);
adjustable.contrast = scaleTo100(setup.contrast);
adjustable.brightness = scaleTo100(setup.brightness);
#ifdef BLARGG_PALETTE
//adjustable.hue = scaleTo100(setup.hue);
//adjustable.saturation = scaleTo100(setup.saturation);
//adjustable.contrast = scaleTo100(setup.contrast);
//adjustable.brightness = scaleTo100(setup.brightness);
//adjustable.gamma = scaleTo100(setup.gamma);
#endif
adjustable.sharpness = scaleTo100(setup.sharpness);
adjustable.gamma = scaleTo100(setup.gamma);
adjustable.resolution = scaleTo100(setup.resolution);
adjustable.artifacts = scaleTo100(setup.artifacts);
adjustable.fringing = scaleTo100(setup.fringing);
@ -224,12 +244,16 @@ void NTSCFilter::convertToAdjustable(Adjustable& adjustable,
AtariNTSC::Setup NTSCFilter::myCustomSetup = AtariNTSC::TV_Composite;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#ifdef BLARGG_PALETTE
const std::array<NTSCFilter::AdjustableTag, 10> NTSCFilter::ourCustomAdjustables = { {
{ "contrast", &myCustomSetup.contrast },
{ "brightness", &myCustomSetup.brightness },
{ "hue", &myCustomSetup.hue },
{ "saturation", &myCustomSetup.saturation },
{ "gamma", &myCustomSetup.gamma },
#else
const std::array<NTSCFilter::AdjustableTag, 5> NTSCFilter::ourCustomAdjustables = { {
#endif
{ "sharpness", &myCustomSetup.sharpness },
{ "resolution", &myCustomSetup.resolution },
{ "artifacts", &myCustomSetup.artifacts },

View File

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

View File

@ -1179,7 +1179,7 @@ void DiStella::outputColors()
color = SECAM_COLOR[(byte >> 1) & 0x7];
myDisasmBuf << "$" << Base::HEX1 << (byte >> 4) << "|" << color;
}
myDisasmBuf << std::setw(16 - color.length()) << std::setfill(' ');
myDisasmBuf << std::setw(int(16 - color.length())) << std::setfill(' ');
// output address
myDisasmBuf << "; $" << Base::HEX4 << myPC + myOffset << " "

View File

@ -16,6 +16,8 @@
//============================================================================
#include "CartAR.hxx"
#include "Debugger.hxx"
#include "CartDebug.hxx"
#include "PopUpWidget.hxx"
#include "CartARWidget.hxx"

View File

@ -19,7 +19,6 @@
#define CART_DEBUG_WIDGET_HXX
class GuiObject;
class ButtonWidget;
class StringListWidget;
namespace GUI {
@ -29,8 +28,6 @@ namespace GUI {
#include "Base.hxx" // not needed here, but all child classes need it
#include "Command.hxx"
#include "Widget.hxx"
#include "Debugger.hxx"
#include "CartDebug.hxx"
class CartDebugWidget : public Widget, public CommandSender
{

View File

@ -49,7 +49,7 @@ string CartridgeE0Widget::romDescription()
info << "Segment #" << seg << " accessible @ $"
<< Common::Base::HEX4 << (ADDR_BASE | segmentOffset)
<< " - $" << (ADDR_BASE | segmentOffset + /*myCart.myBankSize - 1*/ 0x3FF) << ",\n";
<< " - $" << (ADDR_BASE | (segmentOffset + /*myCart.myBankSize - 1*/ 0x3FF)) << ",\n";
if (seg < 3)
info << " Hotspots " << hotspotStr(0, seg, true) << " - " << hotspotStr(7, seg, true) << "\n";
else

View File

@ -17,6 +17,8 @@
#include "PopUpWidget.hxx"
#include "Debugger.hxx"
#include "CartDebug.hxx"
#include "CartEnhanced.hxx"
#include "CartEnhancedWidget.hxx"

View File

@ -68,6 +68,11 @@ DebuggerDialog::DebuggerDialog(OSystem& osystem, DialogContainer& parent,
Menu::AppMode::debugger);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DebuggerDialog::~DebuggerDialog()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DebuggerDialog::loadConfig()
{

View File

@ -33,14 +33,16 @@ class TiaOutputWidget;
class TiaZoomWidget;
class CartDebugWidget;
class CartRamWidget;
class OptionsDialog;
namespace GUI {
class MessageBox;
}
namespace Common {
struct Rect;
}
#include "Dialog.hxx"
#include "MessageBox.hxx"
#include "OptionsDialog.hxx"
class DebuggerDialog : public Dialog
{
@ -55,7 +57,7 @@ class DebuggerDialog : public Dialog
DebuggerDialog(OSystem& osystem, DialogContainer& parent,
int x, int y, int w, int h);
virtual ~DebuggerDialog() = default;
virtual ~DebuggerDialog();
const GUI::Font& lfont() const { return *myLFont; }
const GUI::Font& nfont() const { return *myNFont; }

View File

@ -81,13 +81,6 @@ Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
myCart(std::move(cart)),
myAudioSettings(audioSettings)
{
// Load user-defined palette for this ROM
loadUserPalette();
// Generate custom palette
generateCustomPalette(0);
generateCustomPalette(1);
// Create subsystems for the console
my6502 = make_unique<M6502>(myOSystem.settings());
myRiot = make_unique<M6532>(*this, myOSystem.settings());
@ -441,7 +434,6 @@ void Console::setFormat(uInt32 format)
myConsoleInfo.DisplayFormat = myDisplayFormat + autodetected;
setPalette(myOSystem.settings().getString("palette"));
setTIAProperties();
initializeVideo(); // takes care of refreshing the screen
initializeAudio(); // ensure that audio synthesis is set up to match emulation speed
@ -477,96 +469,6 @@ void Console::enableColorLoss(bool state)
myTIA->enableColorLoss(state);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Console::getPaletteNum(const string& name) const
{
if(name == "z26")
return PaletteType::Z26;
if(name == "user" && myUserPaletteDefined)
return PaletteType::User;
if(name == "custom")
return PaletteType::Custom;
return PaletteType::Standard;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::togglePalette()
{
string palette, message;
palette = myOSystem.settings().getString("palette");
if(palette == "standard") // switch to z26
{
palette = "z26";
message = "Z26 palette";
}
else if(palette == "z26") // switch to user or standard
{
// If we have a user-defined palette, it will come next in
// the sequence; otherwise loop back to the standard one
if(myUserPaletteDefined)
{
palette = "user";
message = "User-defined palette";
}
else
{
palette = "custom";
message = "Custom palette";
}
}
else if(palette == "user") // switch to custom
{
palette = "custom";
message = "Custom palette";
}
else // switch to standard mode if we get this far
{
palette = "standard";
message = "Standard Stella palette";
}
myOSystem.settings().setValue("palette", palette);
myOSystem.frameBuffer().showMessage(message);
setPalette(palette);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::setPalette(const string& type)
{
// Look at all the palettes, since we don't know which one is
// currently active
static constexpr BSPF::array2D<PaletteArray*, PaletteType::NumTypes, 3> palettes = {{
{ &ourNTSCPalette, &ourPALPalette, &ourSECAMPalette },
{ &ourNTSCPaletteZ26, &ourPALPaletteZ26, &ourSECAMPaletteZ26 },
{ &ourUserNTSCPalette, &ourUserPALPalette, &ourUserSECAMPalette },
{ &ourCustomNTSCPalette, &ourCustomPALPalette, &ourSECAMPalette }
}};
// See which format we should be using
int paletteNum = getPaletteNum(type);
if(paletteNum == PaletteType::Custom)
{
}
// Now consider the current display format
const PaletteArray* palette =
(myDisplayFormat.compare(0, 3, "PAL") == 0) ? palettes[paletteNum][1] :
(myDisplayFormat.compare(0, 5, "SECAM") == 0) ? palettes[paletteNum][2] :
palettes[paletteNum][0];
myOSystem.frameBuffer().setTIAPalette(*palette);
if(myTIA->usingFixedColors())
myTIA->enableFixedColors(true);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::toggleInter()
{
@ -677,12 +579,7 @@ FBInitStatus Console::initializeVideo(bool full)
myOSystem.frameBuffer().showFrameStats(
myOSystem.settings().getBool(devSettings ? "dev.stats" : "plr.stats"));
generateCustomPalette(0);
generateCustomPalette(1);
generateColorLossPalette();
}
setPalette(myOSystem.settings().getString("palette"));
return fbstatus;
}
@ -826,46 +723,6 @@ void Console::changeScanlineAdjust(int direction)
myOSystem.frameBuffer().showMessage(ss.str());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::changeColorPhaseShift(int direction)
{
const char DEGREE = 0x1c;
const float NTSC_SHIFT = 26.2F;
const float PAL_SHIFT = 31.3F; // 360 / 11.5
const bool isNTSC = myDisplayFormat == "NTSC" || myDisplayFormat == "NTSC50";
const bool isPAL = myDisplayFormat == "PAL" || myDisplayFormat == "PAL60";
// SECAM is not supported
if(isNTSC || isPAL)
{
const string key = isNTSC ? "phase_ntsc" : "phase_pal";
const float shift = isNTSC ? NTSC_SHIFT : PAL_SHIFT;
float phase = myOSystem.settings().getFloat(key);
if(direction == +1) // increase color phase shift
{
phase += 0.3F;
phase = std::min(phase, shift + 4.5F);
}
else if(direction == -1) // decrease color phase shift
{
phase -= 0.3F;
phase = std::max(phase, shift - 4.5F);
}
myOSystem.settings().setValue(key, phase);
generateCustomPalette(isNTSC ? 0 : 1);
myOSystem.settings().setValue("palette", "custom");
setPalette("custom");
ostringstream ss;
ss << "Color phase shift at "
<< std::fixed << std::setprecision(1) << phase << DEGREE;
myOSystem.frameBuffer().showMessage(ss.str());
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::setTIAProperties()
{
@ -1073,202 +930,6 @@ unique_ptr<Controller> Console::getControllerPort(const Controller::Type type,
return controller;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::loadUserPalette()
{
if (!myOSystem.checkUserPalette(true))
return;
const string& palette = myOSystem.paletteFile();
ifstream in(palette, std::ios::binary);
// Now that we have valid data, create the user-defined palettes
std::array<uInt8, 3> pixbuf; // Temporary buffer for one 24-bit pixel
for(int i = 0; i < 128; i++) // NTSC palette
{
in.read(reinterpret_cast<char*>(pixbuf.data()), 3);
uInt32 pixel = (int(pixbuf[0]) << 16) + (int(pixbuf[1]) << 8) + int(pixbuf[2]);
ourUserNTSCPalette[(i<<1)] = pixel;
}
for(int i = 0; i < 128; i++) // PAL palette
{
in.read(reinterpret_cast<char*>(pixbuf.data()), 3);
uInt32 pixel = (int(pixbuf[0]) << 16) + (int(pixbuf[1]) << 8) + int(pixbuf[2]);
ourUserPALPalette[(i<<1)] = pixel;
}
std::array<uInt32, 16> secam; // All 8 24-bit pixels, plus 8 colorloss pixels
for(int i = 0; i < 8; i++) // SECAM palette
{
in.read(reinterpret_cast<char*>(pixbuf.data()), 3);
uInt32 pixel = (int(pixbuf[0]) << 16) + (int(pixbuf[1]) << 8) + int(pixbuf[2]);
secam[(i<<1)] = pixel;
secam[(i<<1)+1] = 0;
}
uInt32* ptr = ourUserSECAMPalette.data();
for(int i = 0; i < 16; ++i)
{
const uInt32* s = secam.data();
for(int j = 0; j < 16; ++j)
*ptr++ = *s++;
}
myUserPaletteDefined = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::generateCustomPalette(int type)
{
constexpr int NUM_CHROMA = 16;
constexpr int NUM_LUMA = 8;
constexpr float SATURATION = 0.25F;
float color[NUM_CHROMA][2] = {{0.0F}};
if(type == 0)
{
// YIQ is YUV shifted by 33°
constexpr float offset = 33 * (2 * BSPF::PI_f / 360);
const float shift = myOSystem.settings().getFloat("phase_ntsc") *
(2 * BSPF::PI_f / 360);
// color 0 is grayscale
for(int chroma = 1; chroma < NUM_CHROMA; chroma++)
{
color[chroma][0] = SATURATION * sin(offset + shift * (chroma - 1));
color[chroma][1] = SATURATION * sin(offset + shift * (chroma - 1 - BSPF::PI_f));
}
for(int chroma = 0; chroma < NUM_CHROMA; chroma++)
{
const float I = color[chroma][0];
const float Q = color[chroma][1];
for(int luma = 0; luma < NUM_LUMA; luma++)
{
const float Y = 0.05F + luma / 8.24F; // 0.05..~0.90
float R = Y + 0.956F * I + 0.621F * Q;
float G = Y - 0.272F * I - 0.647F * Q;
float B = Y - 1.106F * I + 1.703F * Q;
if(R < 0) R = 0;
if(G < 0) G = 0;
if(B < 0) B = 0;
R = powf(R, 0.9F);
G = powf(G, 0.9F);
B = powf(B, 0.9F);
if(R > 1) R = 1;
if(G > 1) G = 1;
if(B > 1) B = 1;
int r = R * 255.F;
int g = G * 255.F;
int b = B * 255.F;
ourCustomNTSCPalette[(chroma * NUM_LUMA + luma) << 1] = (r << 16) + (g << 8) + b;
}
}
}
else
{
constexpr float offset = 180 * (2 * BSPF::PI_f / 360);
float shift = myOSystem.settings().getFloat("phase_pal") *
(2 * BSPF::PI_f / 360);
constexpr float fixedShift = 22.5F * (2 * BSPF::PI_f / 360);
// colors 0, 1, 14 and 15 are grayscale
for(int chroma = 2; chroma < NUM_CHROMA - 2; chroma++)
{
int idx = NUM_CHROMA - 1 - chroma;
color[idx][0] = SATURATION * sinf(offset - fixedShift * chroma);
if ((idx & 1) == 0)
color[idx][1] = SATURATION * sinf(offset - shift * (chroma - 3.5F) / 2.F);
else
color[idx][1] = SATURATION * -sinf(offset - shift * chroma / 2.F);
}
for(int chroma = 0; chroma < NUM_CHROMA; chroma++)
{
const float U = color[chroma][0];
const float V = color[chroma][1];
for(int luma = 0; luma < NUM_LUMA; luma++)
{
const float Y = 0.05F + luma / 8.24F; // 0.05..~0.90
// Most sources
float R = Y + 1.403F * V;
float G = Y - 0.344F * U - 0.714F * V;
float B = Y + 1.770F * U;
// German Wikipedia, huh???
//float B = Y + 1 / 0.493 * U;
//float R = Y + 1 / 0.877 * V;
//float G = 1.704 * Y - 0.590 * R - 0.194 * B;
if(R < 0) R = 0.0;
if(G < 0) G = 0.0;
if(B < 0) B = 0.0;
R = powf(R, 1.2);
G = powf(G, 1.2);
B = powf(B, 1.2);
if(R > 1) R = 1;
if(G > 1) G = 1;
if(B > 1) B = 1;
int r = R * 255.F;
int g = G * 255.F;
int b = B * 255.F;
ourCustomPALPalette[(chroma * NUM_LUMA + luma) << 1] = (r << 16) + (g << 8) + b;
}
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::generateColorLossPalette()
{
// Look at all the palettes, since we don't know which one is
// currently active
std::array<uInt32*, 3 * 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)
{
palette[6] = ourUserNTSCPalette.data();
palette[7] = ourUserPALPalette.data();
palette[8] = ourUserSECAMPalette.data();
}
for(int i = 0; i < 3 * 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;
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
float Console::getFramerate() const
{
@ -1340,234 +1001,3 @@ void Console::stateChanged(EventHandlerState state)
{
// only the CompuMate used to care about state changes
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteArray Console::ourNTSCPalette = {
0x000000, 0, 0x4a4a4a, 0, 0x6f6f6f, 0, 0x8e8e8e, 0,
0xaaaaaa, 0, 0xc0c0c0, 0, 0xd6d6d6, 0, 0xececec, 0,
0x484800, 0, 0x69690f, 0, 0x86861d, 0, 0xa2a22a, 0,
0xbbbb35, 0, 0xd2d240, 0, 0xe8e84a, 0, 0xfcfc54, 0,
0x7c2c00, 0, 0x904811, 0, 0xa26221, 0, 0xb47a30, 0,
0xc3903d, 0, 0xd2a44a, 0, 0xdfb755, 0, 0xecc860, 0,
0x901c00, 0, 0xa33915, 0, 0xb55328, 0, 0xc66c3a, 0,
0xd5824a, 0, 0xe39759, 0, 0xf0aa67, 0, 0xfcbc74, 0,
0x940000, 0, 0xa71a1a, 0, 0xb83232, 0, 0xc84848, 0,
0xd65c5c, 0, 0xe46f6f, 0, 0xf08080, 0, 0xfc9090, 0,
0x840064, 0, 0x97197a, 0, 0xa8308f, 0, 0xb846a2, 0,
0xc659b3, 0, 0xd46cc3, 0, 0xe07cd2, 0, 0xec8ce0, 0,
0x500084, 0, 0x68199a, 0, 0x7d30ad, 0, 0x9246c0, 0,
0xa459d0, 0, 0xb56ce0, 0, 0xc57cee, 0, 0xd48cfc, 0,
0x140090, 0, 0x331aa3, 0, 0x4e32b5, 0, 0x6848c6, 0,
0x7f5cd5, 0, 0x956fe3, 0, 0xa980f0, 0, 0xbc90fc, 0,
0x000094, 0, 0x181aa7, 0, 0x2d32b8, 0, 0x4248c8, 0,
0x545cd6, 0, 0x656fe4, 0, 0x7580f0, 0, 0x8490fc, 0,
0x001c88, 0, 0x183b9d, 0, 0x2d57b0, 0, 0x4272c2, 0,
0x548ad2, 0, 0x65a0e1, 0, 0x75b5ef, 0, 0x84c8fc, 0,
0x003064, 0, 0x185080, 0, 0x2d6d98, 0, 0x4288b0, 0,
0x54a0c5, 0, 0x65b7d9, 0, 0x75cceb, 0, 0x84e0fc, 0,
0x004030, 0, 0x18624e, 0, 0x2d8169, 0, 0x429e82, 0,
0x54b899, 0, 0x65d1ae, 0, 0x75e7c2, 0, 0x84fcd4, 0,
0x004400, 0, 0x1a661a, 0, 0x328432, 0, 0x48a048, 0,
0x5cba5c, 0, 0x6fd26f, 0, 0x80e880, 0, 0x90fc90, 0,
0x143c00, 0, 0x355f18, 0, 0x527e2d, 0, 0x6e9c42, 0,
0x87b754, 0, 0x9ed065, 0, 0xb4e775, 0, 0xc8fc84, 0,
0x303800, 0, 0x505916, 0, 0x6d762b, 0, 0x88923e, 0,
0xa0ab4f, 0, 0xb7c25f, 0, 0xccd86e, 0, 0xe0ec7c, 0,
0x482c00, 0, 0x694d14, 0, 0x866a26, 0, 0xa28638, 0,
0xbb9f47, 0, 0xd2b656, 0, 0xe8cc63, 0, 0xfce070, 0
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteArray Console::ourPALPalette = {
0x000000, 0, 0x121212, 0, 0x242424, 0, 0x484848, 0, // 180 0
0x6c6c6c, 0, 0x909090, 0, 0xb4b4b4, 0, 0xd8d8d8, 0, // was 0x111111..0xcccccc
0x000000, 0, 0x121212, 0, 0x242424, 0, 0x484848, 0, // 198 1
0x6c6c6c, 0, 0x909090, 0, 0xb4b4b4, 0, 0xd8d8d8, 0,
0x1d0f00, 0, 0x3f2700, 0, 0x614900, 0, 0x836b01, 0, // 1b0 2
0xa58d23, 0, 0xc7af45, 0, 0xe9d167, 0, 0xffe789, 0, // was ..0xfff389
0x002400, 0, 0x004600, 0, 0x216800, 0, 0x438a07, 0, // 1c8 3
0x65ac29, 0, 0x87ce4b, 0, 0xa9f06d, 0, 0xcbff8f, 0,
0x340000, 0, 0x561400, 0, 0x783602, 0, 0x9a5824, 0, // 1e0 4
0xbc7a46, 0, 0xde9c68, 0, 0xffbe8a, 0, 0xffd0ad, 0, // was ..0xffe0ac
0x002700, 0, 0x004900, 0, 0x0c6b0c, 0, 0x2e8d2e, 0, // 1f8 5
0x50af50, 0, 0x72d172, 0, 0x94f394, 0, 0xb6ffb6, 0,
0x3d0008, 0, 0x610511, 0, 0x832733, 0, 0xa54955, 0, // 210 6
0xc76b77, 0, 0xe98d99, 0, 0xffafbb, 0, 0xffd1d7, 0, // was 0x3f0000..0xffd1dd
0x001e12, 0, 0x004228, 0, 0x046540, 0, 0x268762, 0, // 228 7
0x48a984, 0, 0x6acba6, 0, 0x8cedc8, 0, 0xafffe0, 0, // was 0x002100, 0x00431e..0xaeffff
0x300025, 0, 0x5f0047, 0, 0x811e69, 0, 0xa3408b, 0, // 240 8
0xc562ad, 0, 0xe784cf, 0, 0xffa8ea, 0, 0xffc9f2, 0, // was ..0xffa6f1, 0xffc8ff
0x001431, 0, 0x003653, 0, 0x0a5875, 0, 0x2c7a97, 0, // 258 9
0x4e9cb9, 0, 0x70bedb, 0, 0x92e0fd, 0, 0xb4ffff, 0,
0x2c0052, 0, 0x4e0074, 0, 0x701d96, 0, 0x923fb8, 0, // 270 a
0xb461da, 0, 0xd683fc, 0, 0xe2a5ff, 0, 0xeec9ff, 0, // was ..0xf8a5ff, 0xffc7ff
0x001759, 0, 0x00247c, 0, 0x1d469e, 0, 0x3f68c0, 0, // 288 b
0x618ae2, 0, 0x83acff, 0, 0xa5ceff, 0, 0xc7f0ff, 0,
0x12006d, 0, 0x34038f, 0, 0x5625b1, 0, 0x7847d3, 0, // 2a0 c
0x9a69f5, 0, 0xb48cff, 0, 0xc9adff, 0, 0xe1d1ff, 0, // was ..0xbc8bff, 0xdeadff, 0xffcfff,
0x000070, 0, 0x161292, 0, 0x3834b4, 0, 0x5a56d6, 0, // 2b8 d
0x7c78f8, 0, 0x9e9aff, 0, 0xc0bcff, 0, 0xe2deff, 0,
0x000000, 0, 0x121212, 0, 0x242424, 0, 0x484848, 0, // 2d0 e
0x6c6c6c, 0, 0x909090, 0, 0xb4b4b4, 0, 0xd8d8d8, 0,
0x000000, 0, 0x121212, 0, 0x242424, 0, 0x484848, 0, // 2e8 f
0x6c6c6c, 0, 0x909090, 0, 0xb4b4b4, 0, 0xd8d8d8, 0,
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteArray Console::ourSECAMPalette = {
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff50ff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteArray Console::ourNTSCPaletteZ26 = {
0x000000, 0, 0x505050, 0, 0x646464, 0, 0x787878, 0,
0x8c8c8c, 0, 0xa0a0a0, 0, 0xb4b4b4, 0, 0xc8c8c8, 0,
0x445400, 0, 0x586800, 0, 0x6c7c00, 0, 0x809000, 0,
0x94a414, 0, 0xa8b828, 0, 0xbccc3c, 0, 0xd0e050, 0,
0x673900, 0, 0x7b4d00, 0, 0x8f6100, 0, 0xa37513, 0,
0xb78927, 0, 0xcb9d3b, 0, 0xdfb14f, 0, 0xf3c563, 0,
0x7b2504, 0, 0x8f3918, 0, 0xa34d2c, 0, 0xb76140, 0,
0xcb7554, 0, 0xdf8968, 0, 0xf39d7c, 0, 0xffb190, 0,
0x7d122c, 0, 0x912640, 0, 0xa53a54, 0, 0xb94e68, 0,
0xcd627c, 0, 0xe17690, 0, 0xf58aa4, 0, 0xff9eb8, 0,
0x730871, 0, 0x871c85, 0, 0x9b3099, 0, 0xaf44ad, 0,
0xc358c1, 0, 0xd76cd5, 0, 0xeb80e9, 0, 0xff94fd, 0,
0x5d0b92, 0, 0x711fa6, 0, 0x8533ba, 0, 0x9947ce, 0,
0xad5be2, 0, 0xc16ff6, 0, 0xd583ff, 0, 0xe997ff, 0,
0x401599, 0, 0x5429ad, 0, 0x683dc1, 0, 0x7c51d5, 0,
0x9065e9, 0, 0xa479fd, 0, 0xb88dff, 0, 0xcca1ff, 0,
0x252593, 0, 0x3939a7, 0, 0x4d4dbb, 0, 0x6161cf, 0,
0x7575e3, 0, 0x8989f7, 0, 0x9d9dff, 0, 0xb1b1ff, 0,
0x0f3480, 0, 0x234894, 0, 0x375ca8, 0, 0x4b70bc, 0,
0x5f84d0, 0, 0x7398e4, 0, 0x87acf8, 0, 0x9bc0ff, 0,
0x04425a, 0, 0x18566e, 0, 0x2c6a82, 0, 0x407e96, 0,
0x5492aa, 0, 0x68a6be, 0, 0x7cbad2, 0, 0x90cee6, 0,
0x044f30, 0, 0x186344, 0, 0x2c7758, 0, 0x408b6c, 0,
0x549f80, 0, 0x68b394, 0, 0x7cc7a8, 0, 0x90dbbc, 0,
0x0f550a, 0, 0x23691e, 0, 0x377d32, 0, 0x4b9146, 0,
0x5fa55a, 0, 0x73b96e, 0, 0x87cd82, 0, 0x9be196, 0,
0x1f5100, 0, 0x336505, 0, 0x477919, 0, 0x5b8d2d, 0,
0x6fa141, 0, 0x83b555, 0, 0x97c969, 0, 0xabdd7d, 0,
0x344600, 0, 0x485a00, 0, 0x5c6e14, 0, 0x708228, 0,
0x84963c, 0, 0x98aa50, 0, 0xacbe64, 0, 0xc0d278, 0,
0x463e00, 0, 0x5a5205, 0, 0x6e6619, 0, 0x827a2d, 0,
0x968e41, 0, 0xaaa255, 0, 0xbeb669, 0, 0xd2ca7d, 0
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteArray Console::ourPALPaletteZ26 = {
0x000000, 0, 0x4c4c4c, 0, 0x606060, 0, 0x747474, 0,
0x888888, 0, 0x9c9c9c, 0, 0xb0b0b0, 0, 0xc4c4c4, 0,
0x000000, 0, 0x4c4c4c, 0, 0x606060, 0, 0x747474, 0,
0x888888, 0, 0x9c9c9c, 0, 0xb0b0b0, 0, 0xc4c4c4, 0,
0x533a00, 0, 0x674e00, 0, 0x7b6203, 0, 0x8f7617, 0,
0xa38a2b, 0, 0xb79e3f, 0, 0xcbb253, 0, 0xdfc667, 0,
0x1b5800, 0, 0x2f6c00, 0, 0x438001, 0, 0x579415, 0,
0x6ba829, 0, 0x7fbc3d, 0, 0x93d051, 0, 0xa7e465, 0,
0x6a2900, 0, 0x7e3d12, 0, 0x925126, 0, 0xa6653a, 0,
0xba794e, 0, 0xce8d62, 0, 0xe2a176, 0, 0xf6b58a, 0,
0x075b00, 0, 0x1b6f11, 0, 0x2f8325, 0, 0x439739, 0,
0x57ab4d, 0, 0x6bbf61, 0, 0x7fd375, 0, 0x93e789, 0,
0x741b2f, 0, 0x882f43, 0, 0x9c4357, 0, 0xb0576b, 0,
0xc46b7f, 0, 0xd87f93, 0, 0xec93a7, 0, 0xffa7bb, 0,
0x00572e, 0, 0x106b42, 0, 0x247f56, 0, 0x38936a, 0,
0x4ca77e, 0, 0x60bb92, 0, 0x74cfa6, 0, 0x88e3ba, 0,
0x6d165f, 0, 0x812a73, 0, 0x953e87, 0, 0xa9529b, 0,
0xbd66af, 0, 0xd17ac3, 0, 0xe58ed7, 0, 0xf9a2eb, 0,
0x014c5e, 0, 0x156072, 0, 0x297486, 0, 0x3d889a, 0,
0x519cae, 0, 0x65b0c2, 0, 0x79c4d6, 0, 0x8dd8ea, 0,
0x5f1588, 0, 0x73299c, 0, 0x873db0, 0, 0x9b51c4, 0,
0xaf65d8, 0, 0xc379ec, 0, 0xd78dff, 0, 0xeba1ff, 0,
0x123b87, 0, 0x264f9b, 0, 0x3a63af, 0, 0x4e77c3, 0,
0x628bd7, 0, 0x769feb, 0, 0x8ab3ff, 0, 0x9ec7ff, 0,
0x451e9d, 0, 0x5932b1, 0, 0x6d46c5, 0, 0x815ad9, 0,
0x956eed, 0, 0xa982ff, 0, 0xbd96ff, 0, 0xd1aaff, 0,
0x2a2b9e, 0, 0x3e3fb2, 0, 0x5253c6, 0, 0x6667da, 0,
0x7a7bee, 0, 0x8e8fff, 0, 0xa2a3ff, 0, 0xb6b7ff, 0,
0x000000, 0, 0x4c4c4c, 0, 0x606060, 0, 0x747474, 0,
0x888888, 0, 0x9c9c9c, 0, 0xb0b0b0, 0, 0xc4c4c4, 0,
0x000000, 0, 0x4c4c4c, 0, 0x606060, 0, 0x747474, 0,
0x888888, 0, 0x9c9c9c, 0, 0xb0b0b0, 0, 0xc4c4c4, 0
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteArray Console::ourSECAMPaletteZ26 = {
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0,
0x000000, 0, 0x2121ff, 0, 0xf03c79, 0, 0xff3cff, 0,
0x7fff00, 0, 0x7fffff, 0, 0xffff3f, 0, 0xffffff, 0
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteArray Console::ourUserNTSCPalette = { 0 }; // filled from external file
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteArray Console::ourUserPALPalette = { 0 }; // filled from external file
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteArray Console::ourUserSECAMPalette = { 0 }; // filled from external file
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteArray Console::ourCustomNTSCPalette = { 0 }; // filled by function
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PaletteArray Console::ourCustomPALPalette = { 0 }; // filled by function

View File

@ -39,7 +39,6 @@ class AudioSettings;
#include "FrameBufferConstants.hxx"
#include "Serializable.hxx"
#include "EventHandlerConstants.hxx"
#include "NTSCFilter.hxx"
#include "EmulationTiming.hxx"
#include "ConsoleTiming.hxx"
#include "frame-manager/AbstractFrameManager.hxx"
@ -204,23 +203,6 @@ class Console : public Serializable, public ConsoleIO
*/
string getFormatString() const { return myDisplayFormat; }
/**
Toggle between the available palettes.
*/
void togglePalette();
/**
Generates a custom palette, based on user defined phase shifts.
*/
void generateCustomPalette(int type);
/**
Sets the palette according to the given palette name.
@param palette The palette to switch to.
*/
void setPalette(const string& palette);
/**
Toggle interpolation on/off
*/
@ -288,16 +270,6 @@ class Console : public Serializable, public ConsoleIO
*/
void changeScanlineAdjust(int direction);
/**
Change the "phase shift" variable.
Note that there are two of these (NTSC and PAL). The currently
active mode will determine which one is used.
@param direction +1 indicates increase, -1 indicates decrease.
*/
void changeColorPhaseShift(int direction);
/**
Returns the current framerate.
*/
@ -379,35 +351,10 @@ class Console : public Serializable, public ConsoleIO
unique_ptr<Controller> getControllerPort(const Controller::Type type,
const Controller::Jack port, const string& romMd5);
/**
Loads a user-defined palette file (from OSystem::paletteFile), filling the
appropriate user-defined palette arrays.
*/
void loadUserPalette();
/**
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();
int getPaletteNum(const string& name) const;
void toggleTIABit(TIABit bit, const string& bitname, bool show = true) const;
void toggleTIACollision(TIABit bit, const string& bitname, bool show = true) const;
private:
enum PaletteType {
Standard,
Z26,
User,
Custom,
NumTypes
};
// Reference to the osystem object
OSystem& myOSystem;
@ -457,10 +404,6 @@ class Console : public Serializable, public ConsoleIO
// Is the TV format autodetected?
bool myFormatAutodetected{false};
// Indicates whether an external palette was found and
// successfully loaded
bool myUserPaletteDefined{false};
// Contains detailed info about this console
ConsoleInfo myConsoleInfo;
@ -474,25 +417,6 @@ class Console : public Serializable, public ConsoleIO
// The audio settings
AudioSettings& myAudioSettings;
// Table of RGB values for NTSC, PAL and SECAM
static PaletteArray ourNTSCPalette;
static PaletteArray ourPALPalette;
static PaletteArray ourSECAMPalette;
// Table of RGB values for NTSC, PAL and SECAM - Z26 version
static PaletteArray ourNTSCPaletteZ26;
static PaletteArray ourPALPaletteZ26;
static PaletteArray ourSECAMPaletteZ26;
// Table of RGB values for NTSC, PAL and SECAM - user-defined
static PaletteArray ourUserNTSCPalette;
static PaletteArray ourUserPALPalette;
static PaletteArray ourUserSECAMPalette;
// Table of RGB values for NTSC, PAL - custom-defined
static PaletteArray ourCustomNTSCPalette;
static PaletteArray ourCustomPALPalette;
private:
// Following constructors and assignment operators not supported
Console() = delete;

View File

@ -25,7 +25,8 @@ enum class ConsoleTiming
{
ntsc, // console with CPU running at 1.193182 MHz, NTSC colours
pal, // console with CPU running at 1.182298 MHz, PAL colours
secam // console with CPU running at 1.187500 MHz, SECAM colours
secam, // console with CPU running at 1.187500 MHz, SECAM colours
numTimings
};
#endif // CONSOLE_TIMING_HXX

View File

@ -22,7 +22,6 @@
#include <set>
#include "bspf.hxx"
#include "StellaKeys.hxx"
/**
@author Stephen Anthony, Christian Speckner, Thomas Jentzsch
@ -92,6 +91,7 @@ class Event
TogglePauseMode, StartPauseMode,
OptionsMenuMode, CmdMenuMode, DebuggerMode, ExitMode,
TakeSnapshot, ToggleContSnapshots, ToggleContSnapshotsFrame,
ToggleTurbo,
NextState, PreviousState, LoadState, SaveState,
SaveAllStates, LoadAllStates,
@ -100,12 +100,15 @@ class Event
Unwind1Menu, Unwind10Menu, UnwindAllMenu,
RewindPause, UnwindPause,
FormatDecrease, FormatIncrease, TogglePalette, ToggleColorLoss,
FormatDecrease, FormatIncrease, PaletteDecrease, PaletteIncrease, ToggleColorLoss,
PreviousPaletteAttribute, NextPaletteAttribute,
PaletteAttributeDecrease, PaletteAttributeIncrease,
ToggleFullScreen, VidmodeDecrease, VidmodeIncrease,
VCenterDecrease, VCenterIncrease, ScanlineAdjustDecrease, ScanlineAdjustIncrease,
OverscanDecrease, OverscanIncrease,
VidmodeStd, VidmodeRGB, VidmodeSVideo, VidModeComposite, VidModeBad, VidModeCustom,
PreviousVideoMode, NextVideoMode,
PreviousAttribute, NextAttribute, DecreaseAttribute, IncreaseAttribute,
ScanlinesDecrease, ScanlinesIncrease,
PhosphorDecrease, PhosphorIncrease, TogglePhosphor, ToggleInter, ToggleJitter,
@ -118,10 +121,7 @@ class Event
ToggleCollisions, ToggleBits, ToggleFixedColors,
ToggleFrameStats, ToggleSAPortOrder, ExitGame,
// add new events from here to avoid that user remapped events get overwritten
ToggleTurbo,
ColorShiftDecrease, ColorShiftIncrease,
LastType
};
@ -136,7 +136,7 @@ class Event
};
// 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>;

View File

@ -22,6 +22,7 @@
#include "Base.hxx"
#include "Console.hxx"
#include "PaletteHandler.hxx"
#include "FrameBuffer.hxx"
#include "FSNode.hxx"
#include "OSystem.hxx"
@ -435,12 +436,20 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
if (pressed) myOSystem.console().changeScanlineAdjust(+1);
return;
case Event::ColorShiftDecrease:
if (pressed) myOSystem.console().changeColorPhaseShift(-1);
case Event::PreviousPaletteAttribute:
if (pressed) myOSystem.frameBuffer().tiaSurface().paletteHandler().cycleAdjustable(false);
return;
case Event::ColorShiftIncrease:
if (pressed) myOSystem.console().changeColorPhaseShift(+1);
case Event::NextPaletteAttribute:
if (pressed) myOSystem.frameBuffer().tiaSurface().paletteHandler().cycleAdjustable(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::ToggleFullScreen:
@ -455,6 +464,14 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
if (pressed) myOSystem.frameBuffer().changeOverscan(1);
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:
if (pressed && !repeated) myOSystem.frameBuffer().tiaSurface().setNTSC(NTSCFilter::Preset::OFF);
return;
@ -539,8 +556,12 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
if (pressed && !repeated) myOSystem.console().toggleColorLoss();
return;
case Event::TogglePalette:
if (pressed && !repeated) myOSystem.console().togglePalette();
case Event::PaletteDecrease:
if (pressed && !repeated) myOSystem.frameBuffer().tiaSurface().paletteHandler().cyclePalette(false);
return;
case Event::PaletteIncrease:
if (pressed && !repeated) myOSystem.frameBuffer().tiaSurface().paletteHandler().cyclePalette(true);
return;
case Event::ToggleInter:
@ -1929,21 +1950,28 @@ EventHandler::EmulActionList EventHandler::ourEmulActionList = { {
{ Event::VCenterIncrease, "Move display down", "" },
{ Event::FormatDecrease, "Decrease display format", "" },
{ Event::FormatIncrease, "Increase display format", "" },
{ Event::TogglePalette, "Switch palette (Std./Z26/User/Cust.)", "" },
{ Event::ColorShiftDecrease, "Decrease custom palette phase shift", "" },
{ Event::ColorShiftIncrease, "Increase custom palette phase shift", "" },
// Palette settings
{ Event::PaletteDecrease, "Switch to previous 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::ToggleInter, "Toggle display interpolation", "" },
// TV effects:
// Blargg TV effects:
{ Event::VidmodeStd, "Disable TV effects", "" },
{ Event::VidmodeRGB, "Select 'RGB' preset", "" },
{ Event::VidmodeSVideo, "Select 'S-Video' preset", "" },
{ Event::VidModeComposite, "Select 'Composite' preset", "" },
{ Event::VidModeBad, "Select 'Badly adjusted' 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::NextAttribute, "Select next 'Custom' attribute", "" },
{ Event::DecreaseAttribute, "Decrease selected 'Custom' attribute", "" },
{ Event::IncreaseAttribute, "Increase selected 'Custom' attribute", "" },
// Other TV effects
{ Event::TogglePhosphor, "Toggle 'phosphor' effect", "" },
{ Event::PhosphorDecrease, "Decrease 'phosphor' blend", "" },
{ Event::PhosphorIncrease, "Increase 'phosphor' blend", "" },
@ -2058,7 +2086,10 @@ const Event::EventSet EventHandler::AudioVideoEvents = {
Event::VCenterDecrease, Event::VCenterIncrease,
Event::ScanlineAdjustDecrease, Event::ScanlineAdjustIncrease,
Event::OverscanDecrease, Event::OverscanIncrease,
Event::TogglePalette, Event::ColorShiftDecrease, Event::ColorShiftIncrease,
Event::PaletteDecrease, Event::PaletteIncrease,
Event::PreviousVideoMode, Event::NextVideoMode,
Event::PreviousPaletteAttribute, Event::NextPaletteAttribute,
Event::PaletteAttributeDecrease, Event::PaletteAttributeIncrease,
Event::ToggleInter
};

View File

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

View File

@ -171,10 +171,9 @@ void FrameBuffer::setupFonts()
// However, we have to make sure all Dialogs are sized using the fontsize.
int zoom_h = (fd.height * 4 * 2) / GUI::stellaMediumDesc.height;
int zoom_w = (fd.maxwidth * 4 * 2) / GUI::stellaMediumDesc.maxwidth;
myTIAMinZoom = std::max(zoom_w, zoom_h) / 4.F; // round to 25% steps
myTIAMinZoom = std::max(std::max(zoom_w, zoom_h) / 4.F, 2.F); // round to 25% steps, >= 200%
}
// The font used by the ROM launcher
const string& lf = myOSystem.settings().getString("launcherfont");
@ -310,7 +309,7 @@ FBInitStatus FrameBuffer::createDisplay(const string& title, BufferType type,
}
if(!myMsg.surface)
myMsg.surface = allocateSurface(FBMinimum::Width, font().getFontHeight() * 1.5);
myMsg.surface = allocateSurface(font().getMaxCharWidth() * 56, font().getFontHeight() * 1.5);
#endif
// Print initial usage message, but only print it later if the status has changed

View File

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

View File

@ -41,7 +41,7 @@ class AudioSettings;
class Menu;
class MessageMenu;
class TimeMachine;
class VideoDialog;
class VideoAudioDialog;
#endif
#ifdef PNG_SUPPORT
class PNGLibrary;

View File

@ -15,6 +15,8 @@
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#include <cmath>
#include "Control.hxx"
#include "Event.hxx"
#include "System.hxx"

View File

@ -21,6 +21,7 @@
#include "Version.hxx"
#include "Logger.hxx"
#include "AudioSettings.hxx"
#include "PaletteHandler.hxx"
#include "Paddles.hxx"
#ifdef DEBUGGER_SUPPORT
@ -45,9 +46,7 @@ Settings::Settings()
setPermanent("center", "true");
setPermanent("windowedpos", Common::Point(50, 50));
setPermanent("display", 0);
setPermanent("palette", "standard");
setPermanent("phase_ntsc", "26.2");
setPermanent("phase_pal", "31.3");
setPermanent("palette", PaletteHandler::SETTING_STANDARD);
setPermanent("uimessages", "true");
// TIA specific options
@ -64,12 +63,14 @@ Settings::Settings()
setPermanent("tv.phosphor", "byrom");
setPermanent("tv.phosblend", "50");
setPermanent("tv.scanlines", "25");
// TV options when using 'custom' mode
setPermanent("tv.phase_ntsc", "26.2");
setPermanent("tv.phase_pal", "31.3");
setPermanent("tv.contrast", "0.0");
setPermanent("tv.brightness", "0.0");
setPermanent("tv.hue", "0.0");
setPermanent("tv.saturation", "0.0");
setPermanent("tv.gamma", "0.0");
// TV options when using 'custom' mode
setPermanent("tv.sharpness", "0.0");
setPermanent("tv.resolution", "0.0");
setPermanent("tv.artifacts", "0.0");
@ -358,8 +359,11 @@ void Settings::validate()
else if(i > 10) setValue("ssinterval", "10");
s = getString("palette");
if(s != "standard" && s != "z26" && s != "user" && s != "custom")
setValue("palette", "standard");
if(s != PaletteHandler::SETTING_STANDARD
&& s != PaletteHandler::SETTING_Z26
&& s != PaletteHandler::SETTING_USER
&& s != PaletteHandler::SETTING_CUSTOM)
setValue("palette", PaletteHandler::SETTING_STANDARD);
s = getString("launcherfont");
if(s != "small" && s != "low_medium" && s != "medium" && s != "large"

View File

@ -23,6 +23,7 @@
#include "Console.hxx"
#include "TIA.hxx"
#include "PNGLibrary.hxx"
#include "PaletteHandler.hxx"
#include "TIASurface.hxx"
namespace {
@ -76,6 +77,14 @@ TIASurface::TIASurface(OSystem& system)
// Enable/disable threading in the NTSC TV effects renderer
myNTSCFilter.enableThreading(myOSystem.settings().getBool("threads"));
myPaletteHandler = make_unique<PaletteHandler>(myOSystem);
myPaletteHandler->loadConfig(myOSystem.settings());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TIASurface::~TIASurface()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -89,6 +98,8 @@ void TIASurface::initialize(const Console& console,
mySLineSurface->setDstPos(mode.image.x(), mode.image.y());
mySLineSurface->setDstSize(mode.image.w(), mode.image.h());
myPaletteHandler->setPalette();
// Phosphor mode can be enabled either globally or per-ROM
int p_blend = 0;
bool enable = false;
@ -188,6 +199,32 @@ void TIASurface::setNTSC(NTSCFilter::Preset preset, bool show)
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)
{

View File

@ -22,6 +22,7 @@ class TIA;
class Console;
class OSystem;
class FBSurface;
class PaletteHandler;
#include <thread>
@ -48,6 +49,7 @@ class TIASurface
Creates a new TIASurface object
*/
explicit TIASurface(OSystem& system);
virtual ~TIASurface();
/**
Set the TIA object, which is needed for actually rendering the TIA image.
@ -87,6 +89,16 @@ class TIASurface
*/
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.
*/
@ -100,7 +112,6 @@ class TIASurface
@return New current intensity
*/
uInt32 enableScanlines(int relative, int absolute = 50);
void enableScanlineInterpolation(bool enable);
/**
Enable/disable/query phosphor effect.
@ -183,6 +194,9 @@ class TIASurface
// Flag for saving a snapshot
bool mySaveSnapFlag{false};
// The palette handler
unique_ptr<PaletteHandler>myPaletteHandler;
private:
// Following constructors and assignment operators not supported
TIASurface() = delete;

View File

@ -108,6 +108,7 @@ void Thumbulator::setConsoleTiming(ConsoleTiming timing)
case ConsoleTiming::ntsc: timing_factor = NTSC; break;
case ConsoleTiming::secam: timing_factor = SECAM; break;
case ConsoleTiming::pal: timing_factor = PAL; break;
default: break; // satisfy compiler
}
}

View File

@ -1,353 +0,0 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#include <sstream>
#include "bspf.hxx"
#include "Console.hxx"
#include "Cart.hxx"
#include "CartDPC.hxx"
#include "Control.hxx"
#include "Dialog.hxx"
#include "Font.hxx"
#include "Menu.hxx"
#include "OSystem.hxx"
#include "PopUpWidget.hxx"
#include "Settings.hxx"
#include "Sound.hxx"
#include "Widget.hxx"
#include "AudioSettings.hxx"
#include "AudioDialog.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AudioDialog::AudioDialog(OSystem& osystem, DialogContainer& parent,
const GUI::Font& font)
: Dialog(osystem, parent, font, "Audio settings")
{
const int lineHeight = font.getLineHeight(),
fontHeight = font.getFontHeight(),
fontWidth = font.getMaxCharWidth();
const int VBORDER = fontHeight / 2;
const int HBORDER = fontWidth * 1.25;
const int INDENT = fontWidth * 2;
const int VGAP = fontHeight / 4;
int xpos, ypos;
int lwidth = font.getStringWidth("Volume "),
pwidth;
WidgetArray wid;
VariantList items;
// Set real dimensions
_w = 48 * fontWidth + HBORDER * 2;
_h = 12 * (lineHeight + VGAP) + VBORDER + _th;
xpos = HBORDER; ypos = VBORDER + _th;
// Enable sound
mySoundEnableCheckbox = new CheckboxWidget(this, font, xpos, ypos,
"Enable sound", kSoundEnableChanged);
wid.push_back(mySoundEnableCheckbox);
ypos += lineHeight + VGAP;
xpos += CheckboxWidget::prefixSize(font);
// Volume
myVolumeSlider = new SliderWidget(this, font, xpos, ypos,
"Volume", lwidth, 0, 4 * fontWidth, "%");
myVolumeSlider->setMinValue(1); myVolumeSlider->setMaxValue(100);
myVolumeSlider->setTickmarkIntervals(4);
wid.push_back(myVolumeSlider);
ypos += lineHeight + VGAP;
// Mode
items.clear();
VarList::push_back(items, "Low quality, medium lag", static_cast<int>(AudioSettings::Preset::lowQualityMediumLag));
VarList::push_back(items, "High quality, medium lag", static_cast<int>(AudioSettings::Preset::highQualityMediumLag));
VarList::push_back(items, "High quality, low lag", static_cast<int>(AudioSettings::Preset::highQualityLowLag));
VarList::push_back(items, "Ultra quality, minimal lag", static_cast<int>(AudioSettings::Preset::ultraQualityMinimalLag));
VarList::push_back(items, "Custom", static_cast<int>(AudioSettings::Preset::custom));
myModePopup = new PopUpWidget(this, font, xpos, ypos,
font.getStringWidth("Ultry quality, minimal lag"), lineHeight,
items, "Mode", lwidth, kModeChanged);
wid.push_back(myModePopup);
ypos += lineHeight + VGAP;
xpos += INDENT;
// Fragment size
pwidth = font.getStringWidth("512 samples") + 7;
lwidth = font.getStringWidth("Resampling quality ");
items.clear();
VarList::push_back(items, "128 samples", 128);
VarList::push_back(items, "256 samples", 256);
VarList::push_back(items, "512 samples", 512);
VarList::push_back(items, "1k samples", 1024);
VarList::push_back(items, "2k samples", 2048);
VarList::push_back(items, "4K samples", 4096);
myFragsizePopup = new PopUpWidget(this, font, xpos, ypos,
pwidth, lineHeight,
items, "Fragment size", lwidth);
wid.push_back(myFragsizePopup);
ypos += lineHeight + VGAP;
// Output frequency
items.clear();
VarList::push_back(items, "44100 Hz", 44100);
VarList::push_back(items, "48000 Hz", 48000);
VarList::push_back(items, "96000 Hz", 96000);
myFreqPopup = new PopUpWidget(this, font, xpos, ypos,
pwidth, lineHeight,
items, "Sample rate", lwidth);
wid.push_back(myFreqPopup);
ypos += lineHeight + VGAP;
// Resampling quality
items.clear();
VarList::push_back(items, "Low", static_cast<int>(AudioSettings::ResamplingQuality::nearestNeightbour));
VarList::push_back(items, "High", static_cast<int>(AudioSettings::ResamplingQuality::lanczos_2));
VarList::push_back(items, "Ultra", static_cast<int>(AudioSettings::ResamplingQuality::lanczos_3));
myResamplingPopup = new PopUpWidget(this, font, xpos, ypos,
pwidth, lineHeight,
items, "Resampling quality ", lwidth);
wid.push_back(myResamplingPopup);
ypos += lineHeight + VGAP;
// Param 1
int swidth = pwidth+23;
myHeadroomSlider = new SliderWidget(this, font, xpos, ypos, swidth, lineHeight,
"Headroom ", 0, kHeadroomChanged, 10 * fontWidth);
myHeadroomSlider->setMinValue(0); myHeadroomSlider->setMaxValue(AudioSettings::MAX_HEADROOM);
myHeadroomSlider->setTickmarkIntervals(5);
wid.push_back(myHeadroomSlider);
ypos += lineHeight + VGAP;
// Param 2
myBufferSizeSlider = new SliderWidget(this, font, xpos, ypos, swidth, lineHeight,
"Buffer size ", 0, kBufferSizeChanged, 10 * fontWidth);
myBufferSizeSlider->setMinValue(0); myBufferSizeSlider->setMaxValue(AudioSettings::MAX_BUFFER_SIZE);
myBufferSizeSlider->setTickmarkIntervals(5);
wid.push_back(myBufferSizeSlider);
ypos += lineHeight + VGAP;
// Stereo sound
xpos -= INDENT;
myStereoSoundCheckbox = new CheckboxWidget(this, font, xpos, ypos,
"Stereo for all ROMs");
wid.push_back(myStereoSoundCheckbox);
ypos += lineHeight + VGAP;
myDpcPitch = new SliderWidget(this, font, xpos, ypos, swidth - 16, lineHeight,
"Pitfall II music pitch ", 0, 0, 5 * fontWidth);
myDpcPitch->setMinValue(10000); myDpcPitch->setMaxValue(30000);
myDpcPitch->setStepValue(100);
myDpcPitch->setTickmarkIntervals(2);
wid.push_back(myDpcPitch);
// Add Defaults, OK and Cancel buttons
addDefaultsOKCancelBGroup(wid, font);
addToFocusList(wid);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void AudioDialog::loadConfig()
{
AudioSettings& audioSettings = instance().audioSettings();
// Enable sound
mySoundEnableCheckbox->setState(audioSettings.enabled());
// Volume
myVolumeSlider->setValue(audioSettings.volume());
// Stereo
myStereoSoundCheckbox->setState(audioSettings.stereo());
// DPC Pitch
myDpcPitch->setValue(audioSettings.dpcPitch());
// Preset / mode
myModePopup->setSelected(static_cast<int>(audioSettings.preset()));
updateSettingsWithPreset(instance().audioSettings());
updateEnabledState();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void AudioDialog::updateSettingsWithPreset(AudioSettings& audioSettings)
{
// Fragsize
myFragsizePopup->setSelected(audioSettings.fragmentSize());
// Output frequency
myFreqPopup->setSelected(audioSettings.sampleRate());
// Headroom
myHeadroomSlider->setValue(audioSettings.headroom());
// Buffer size
myBufferSizeSlider->setValue(audioSettings.bufferSize());
// Resampling quality
myResamplingPopup->setSelected(static_cast<int>(audioSettings.resamplingQuality()));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void AudioDialog::saveConfig()
{
AudioSettings& audioSettings = instance().audioSettings();
// Enabled
audioSettings.setEnabled(mySoundEnableCheckbox->getState());
instance().sound().setEnabled(mySoundEnableCheckbox->getState());
// Volume
audioSettings.setVolume(myVolumeSlider->getValue());
instance().sound().setVolume(myVolumeSlider->getValue());
// Stereo
audioSettings.setStereo(myStereoSoundCheckbox->getState());
// DPC Pitch
audioSettings.setDpcPitch(myDpcPitch->getValue());
// update if current cart is Pitfall II
if (instance().hasConsole() && instance().console().cartridge().name() == "CartridgeDPC")
{
CartridgeDPC& cart = static_cast<CartridgeDPC&>(instance().console().cartridge());
cart.setDpcPitch(myDpcPitch->getValue());
}
AudioSettings::Preset preset = static_cast<AudioSettings::Preset>(myModePopup->getSelectedTag().toInt());
audioSettings.setPreset(preset);
if (preset == AudioSettings::Preset::custom) {
// Fragsize
audioSettings.setFragmentSize(myFragsizePopup->getSelectedTag().toInt());
audioSettings.setSampleRate(myFreqPopup->getSelectedTag().toInt());
audioSettings.setHeadroom(myHeadroomSlider->getValue());
audioSettings.setBufferSize(myBufferSizeSlider->getValue());
audioSettings.setResamplingQuality(static_cast<AudioSettings::ResamplingQuality>(myResamplingPopup->getSelectedTag().toInt()));
}
// Only force a re-initialization when necessary, since it can
// be a time-consuming operation
if(instance().hasConsole())
instance().console().initializeAudio();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void AudioDialog::setDefaults()
{
mySoundEnableCheckbox->setState(AudioSettings::DEFAULT_ENABLED);
myVolumeSlider->setValue(AudioSettings::DEFAULT_VOLUME);
myStereoSoundCheckbox->setState(AudioSettings::DEFAULT_STEREO);
myDpcPitch->setValue(AudioSettings::DEFAULT_DPC_PITCH);
myModePopup->setSelected(static_cast<int>(AudioSettings::DEFAULT_PRESET));
if (AudioSettings::DEFAULT_PRESET == AudioSettings::Preset::custom) {
myResamplingPopup->setSelected(static_cast<int>(AudioSettings::DEFAULT_RESAMPLING_QUALITY));
myFragsizePopup->setSelected(AudioSettings::DEFAULT_FRAGMENT_SIZE);
myFreqPopup->setSelected(AudioSettings::DEFAULT_SAMPLE_RATE);
myHeadroomSlider->setValue(AudioSettings::DEFAULT_HEADROOM);
myBufferSizeSlider->setValue(AudioSettings::DEFAULT_BUFFER_SIZE);
}
else updatePreset();
updateEnabledState();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void AudioDialog::updateEnabledState()
{
bool active = mySoundEnableCheckbox->getState();
AudioSettings::Preset preset = static_cast<AudioSettings::Preset>(myModePopup->getSelectedTag().toInt());
bool userMode = preset == AudioSettings::Preset::custom;
myVolumeSlider->setEnabled(active);
myStereoSoundCheckbox->setEnabled(active);
myModePopup->setEnabled(active);
// enable only for Pitfall II cart
myDpcPitch->setEnabled(active && instance().hasConsole() && instance().console().cartridge().name() == "CartridgeDPC");
myFragsizePopup->setEnabled(active && userMode);
myFreqPopup->setEnabled(active && userMode);
myResamplingPopup->setEnabled(active && userMode);
myHeadroomSlider->setEnabled(active && userMode);
myBufferSizeSlider->setEnabled(active && userMode);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void AudioDialog::updatePreset()
{
AudioSettings::Preset preset = static_cast<AudioSettings::Preset>(myModePopup->getSelectedTag().toInt());
// Make a copy that does not affect the actual settings...
AudioSettings audioSettings = instance().audioSettings();
audioSettings.setPersistent(false);
// ... and set the requested preset
audioSettings.setPreset(preset);
updateSettingsWithPreset(audioSettings);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void AudioDialog::handleCommand(CommandSender* sender, int cmd,
int data, int id)
{
switch(cmd)
{
case GuiObject::kOKCmd:
saveConfig();
close();
break;
case GuiObject::kDefaultsCmd:
setDefaults();
break;
case kSoundEnableChanged:
updateEnabledState();
break;
case kModeChanged:
updatePreset();
updateEnabledState();
break;
case kHeadroomChanged:
{
std::ostringstream ss;
ss << std::fixed << std::setprecision(1) << (0.5 * myHeadroomSlider->getValue()) << " frames";
myHeadroomSlider->setValueLabel(ss.str());
break;
}
case kBufferSizeChanged:
{
std::ostringstream ss;
ss << std::fixed << std::setprecision(1) << (0.5 * myBufferSizeSlider->getValue()) << " frames";
myBufferSizeSlider->setValueLabel(ss.str());
break;
}
default:
Dialog::handleCommand(sender, cmd, data, 0);
break;
}
}

View File

@ -1,77 +0,0 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#ifndef AUDIO_DIALOG_HXX
#define AUDIO_DIALOG_HXX
class CommandSender;
class Dialog;
class DialogContainer;
class PopUpWidget;
class SliderWidget;
class StaticTextWidget;
class CheckboxWidget;
class OSystem;
class AudioSettings;
#include "bspf.hxx"
class AudioDialog : public Dialog
{
public:
AudioDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font);
virtual ~AudioDialog() = default;
private:
void loadConfig() override;
void saveConfig() override;
void setDefaults() override;
void updatePreset();
void updateEnabledState();
void updateSettingsWithPreset(AudioSettings&);
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
private:
enum {
kSoundEnableChanged = 'ADse',
kModeChanged = 'ADmc',
kHeadroomChanged = 'ADhc',
kBufferSizeChanged = 'ADbc'
};
CheckboxWidget* mySoundEnableCheckbox{nullptr};
SliderWidget* myVolumeSlider{nullptr};
CheckboxWidget* myStereoSoundCheckbox{nullptr};
PopUpWidget* myModePopup{nullptr};
PopUpWidget* myFragsizePopup{nullptr};
PopUpWidget* myFreqPopup{nullptr};
PopUpWidget* myResamplingPopup{nullptr};
SliderWidget* myHeadroomSlider{nullptr};
SliderWidget* myBufferSizeSlider{nullptr};
SliderWidget* myDpcPitch{nullptr};
private:
// Following constructors and assignment operators not supported
AudioDialog() = delete;
AudioDialog(const AudioDialog&) = delete;
AudioDialog(AudioDialog&&) = delete;
AudioDialog& operator=(const AudioDialog&) = delete;
AudioDialog& operator=(AudioDialog&&) = delete;
};
#endif

View File

@ -25,9 +25,10 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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),
CommandSender(boss),
_framed(framed),
_cmd(cmd)
{
_flags = Widget::FLAG_ENABLED | Widget::FLAG_CLEARBG | Widget::FLAG_RETAIN_FOCUS;
@ -46,11 +47,18 @@ void ColorWidget::drawWidget(bool hilite)
FBSurface& s = dialog().surface();
bool onTop = _boss->dialog().isOnTop();
if(_framed)
{
// Draw a thin frame around us.
s.frameRect(_x, _y, _w, _h + 1, kColor);
// Show the currently selected color
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?
if(_crossGrid)

View File

@ -36,7 +36,7 @@ class ColorWidget : public Widget, public CommandSender
public:
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;
void setColor(ColorId color);
@ -49,6 +49,7 @@ class ColorWidget : public Widget, public CommandSender
protected:
ColorId _color{kNone};
bool _framed{true};
int _cmd{0};
bool _crossGrid{false};

View File

@ -16,6 +16,7 @@
//============================================================================
#include "Console.hxx"
#include "PaletteHandler.hxx"
#include "TIA.hxx"
#include "Switches.hxx"
#include "Dialog.hxx"
@ -203,7 +204,7 @@ void CommandDialog::handleCommand(CommandSender* sender, int cmd,
break;
case kPaletteCmd:
instance().console().togglePalette();
instance().frameBuffer().tiaSurface().paletteHandler().cyclePalette();
updatePalette();
break;
@ -269,11 +270,11 @@ void CommandDialog::updatePalette()
string palette, label;
palette = instance().settings().getString("palette");
if(BSPF::equalsIgnoreCase(palette, "standard"))
if(BSPF::equalsIgnoreCase(palette, PaletteHandler::SETTING_STANDARD))
label = "Stella Palette";
else if(BSPF::equalsIgnoreCase(palette, "z26"))
else if(BSPF::equalsIgnoreCase(palette, PaletteHandler::SETTING_Z26))
label = "Z26 Palette";
else if(BSPF::equalsIgnoreCase(palette, "user"))
else if(BSPF::equalsIgnoreCase(palette, PaletteHandler::SETTING_USER))
label = "User Palette";
else
label = "Custom Palette";

View File

@ -499,31 +499,6 @@ void DeveloperDialog::addTimeMachineTab(const GUI::Font& font)
lineHeight, items, "Horizon ~ ", 0, kHorizonChanged);
wid.push_back(myStateHorizonWidget);
xpos = HBORDER + INDENT;
ypos += lineHeight + VGAP * 2;
new StaticTextWidget(myTab, font, HBORDER, ypos + 1,
"When entering/exiting emulation:");
ypos += lineHeight + VGAP;
mySaveOnExitGroup = new RadioButtonGroup();
r = new RadioButtonWidget(myTab, font, xpos, ypos + 1,
"Do nothing", mySaveOnExitGroup);
wid.push_back(r);
ypos += lineHeight + VGAP;
r = new RadioButtonWidget(myTab, font, xpos, ypos + 1,
"Save current state in current slot", mySaveOnExitGroup);
wid.push_back(r);
ypos += lineHeight + VGAP;
r = new RadioButtonWidget(myTab, font, xpos, ypos + 1,
"Load/save all Time Machine states", mySaveOnExitGroup);
wid.push_back(r);
ypos += lineHeight + VGAP;
xpos = HBORDER;
myAutoSlotWidget = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Automatically change save state slots");
wid.push_back(myAutoSlotWidget);
ypos += lineHeight + VGAP;
// Add message concerning usage
const GUI::Font& infofont = instance().frameBuffer().infoFont();
ypos = myTab->getHeight() - fontHeight - infofont.getFontHeight() - VGAP - VBORDER;
@ -678,8 +653,6 @@ void DeveloperDialog::loadSettings(SettingsSet set)
myUncompressed[set] = instance().settings().getInt(prefix + "tm.uncompressed");
myStateInterval[set] = instance().settings().getString(prefix + "tm.interval");
myStateHorizon[set] = instance().settings().getString(prefix + "tm.horizon");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -871,12 +844,6 @@ void DeveloperDialog::loadConfig()
// Debug colours
handleDebugColours(instance().settings().getString("tia.dbgcolors"));
// Save on exit
string saveOnExit = instance().settings().getString("saveonexit");
mySaveOnExitGroup->setSelected(saveOnExit == "all" ? 2 : saveOnExit == "current" ? 1 : 0);
// Automatically change save state slots
myAutoSlotWidget->setState(instance().settings().getBool("autoslot"));
#ifdef DEBUGGER_SUPPORT
uInt32 w, h;
@ -953,13 +920,6 @@ void DeveloperDialog::saveConfig()
instance().state().setRewindMode(myTimeMachineWidget->getState() ?
StateManager::Mode::TimeMachine : StateManager::Mode::Off);
// Save on exit
int saveOnExit = mySaveOnExitGroup->getSelected();
instance().settings().setValue("saveonexit",
saveOnExit == 0 ? "none" : saveOnExit == 1 ? "current" : "all");
// Automatically change save state slots
instance().settings().setValue("autoslot", myAutoSlotWidget->getState());
#ifdef DEBUGGER_SUPPORT
// Debugger font style
instance().settings().setValue("dbg.fontstyle",
@ -1050,8 +1010,6 @@ void DeveloperDialog::setDefaults()
myStateHorizon[set] = devSettings ? "30s" : "10m";
setWidgetStates(set);
mySaveOnExitGroup->setSelected(0);
myAutoSlotWidget->setState(false);
break;
case 4: // Debugger options

View File

@ -135,8 +135,6 @@ class DeveloperDialog : public Dialog
SliderWidget* myUncompressedWidget{nullptr};
PopUpWidget* myStateIntervalWidget{nullptr};
PopUpWidget* myStateHorizonWidget{nullptr};
RadioButtonGroup* mySaveOnExitGroup{nullptr};
CheckboxWidget* myAutoSlotWidget{nullptr};
#ifdef DEBUGGER_SUPPORT
// Debugger UI widgets

View File

@ -384,4 +384,3 @@ void DialogContainer::reset()
uInt64 DialogContainer::_DOUBLE_CLICK_DELAY = 500;
uInt64 DialogContainer::_REPEAT_INITIAL_DELAY = 400;
uInt64 DialogContainer::_REPEAT_SUSTAIN_DELAY = 50;

283
src/gui/EmulationDialog.cxx Normal file
View File

@ -0,0 +1,283 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#include "Console.hxx"
#include "FrameBuffer.hxx"
#include "RadioButtonWidget.hxx"
#include "TIASurface.hxx"
#include "EmulationDialog.hxx"
namespace {
// Emulation speed is a positive float that multiplies the framerate. However, the UI controls
// adjust speed in terms of a speedup factor (1/10, 1/9 .. 1/2, 1, 2, 3, .., 10). The following
// mapping and formatting functions implement this conversion. The speedup factor is represented
// by an integer value between -900 and 900 (0 means no speedup).
constexpr int MAX_SPEED = 900;
constexpr int MIN_SPEED = -900;
constexpr int SPEED_STEP = 10;
int mapSpeed(float speed)
{
speed = std::abs(speed);
return BSPF::clamp(
static_cast<int>(round(100 * (speed >= 1 ? speed - 1 : -1 / speed + 1))),
MIN_SPEED, MAX_SPEED
);
}
float unmapSpeed(int speed)
{
float f_speed = static_cast<float>(speed) / 100;
return speed < 0 ? -1 / (f_speed - 1) : 1 + f_speed;
}
string formatSpeed(int speed) {
stringstream ss;
ss
<< std::setw(3) << std::fixed << std::setprecision(0)
<< (unmapSpeed(speed) * 100);
return ss.str();
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EmulationDialog::EmulationDialog(OSystem& osystem, DialogContainer& parent,
const GUI::Font& font, int max_w, int max_h)
: Dialog(osystem, parent, font, "Emulation settings")
{
const int lineHeight = font.getLineHeight(),
fontHeight = font.getFontHeight(),
fontWidth = font.getMaxCharWidth(),
buttonHeight = font.getLineHeight() * 1.25;
const int VBORDER = fontHeight / 2;
const int HBORDER = fontWidth * 1.25;
const int INDENT = fontWidth * 2;
const int VGAP = fontHeight / 4;
int xpos, ypos;
int lwidth = font.getStringWidth("Emulation speed ");
WidgetArray wid;
VariantList items;
const int swidth = fontWidth * 10;
// Set real dimensions
_w = 37 * fontWidth + HBORDER * 2 + CheckboxWidget::prefixSize(_font);
_h = 12 * (lineHeight + VGAP) + VGAP * 7 + VBORDER * 3 + _th + buttonHeight;
xpos = HBORDER; ypos = VBORDER + _th;
// Speed
mySpeed =
new SliderWidget(this, _font, xpos, ypos-1, swidth, lineHeight,
"Emulation speed ", lwidth, kSpeedupChanged, fontWidth * 5, "%");
mySpeed->setMinValue(MIN_SPEED); mySpeed->setMaxValue(MAX_SPEED);
mySpeed->setStepValue(SPEED_STEP);
mySpeed->setTickmarkIntervals(2);
wid.push_back(mySpeed);
ypos += lineHeight + VGAP;
// Use sync to vblank
myUseVSync = new CheckboxWidget(this, _font, xpos, ypos + 1, "VSync");
wid.push_back(myUseVSync);
ypos += lineHeight + VGAP;
myTurbo = new CheckboxWidget(this, _font, xpos, ypos + 1, "Turbo mode");
wid.push_back(myTurbo);
ypos += lineHeight + VGAP * 3;
// Use multi-threading
myUseThreads = new CheckboxWidget(this, _font, xpos, ypos + 1, "Multi-threading");
wid.push_back(myUseThreads);
ypos += lineHeight + VGAP;
// Skip progress load bars for SuperCharger ROMs
// Doesn't really belong here, but I couldn't find a better place for it
myFastSCBios = new CheckboxWidget(this, _font, xpos, ypos + 1, "Fast SuperCharger load");
wid.push_back(myFastSCBios);
ypos += lineHeight + VGAP;
// Show UI messages onscreen
myUIMessages = new CheckboxWidget(this, _font, xpos, ypos + 1, "Show UI messages");
wid.push_back(myUIMessages);
ypos += lineHeight + VGAP;
// Confirm dialog when exiting emulation
xpos = HBORDER; ypos += VGAP * 3;
myConfirmExitWidget = new CheckboxWidget(this, _font, xpos, ypos, "Confirm exiting emulation");
wid.push_back(myConfirmExitWidget);
xpos = HBORDER + INDENT;
ypos += lineHeight + VGAP * 3;
new StaticTextWidget(this, font, HBORDER, ypos + 1,
"When entering/exiting emulation:");
ypos += lineHeight + VGAP;
mySaveOnExitGroup = new RadioButtonGroup();
RadioButtonWidget* r;
r = new RadioButtonWidget(this, font, xpos, ypos + 1,
"Do nothing", mySaveOnExitGroup);
wid.push_back(r);
ypos += lineHeight + VGAP;
r = new RadioButtonWidget(this, font, xpos, ypos + 1,
"Save current state in current slot", mySaveOnExitGroup);
wid.push_back(r);
ypos += lineHeight + VGAP;
r = new RadioButtonWidget(this, font, xpos, ypos + 1,
"Load/save all Time Machine states", mySaveOnExitGroup);
wid.push_back(r);
ypos += lineHeight + VGAP;
xpos = HBORDER;
myAutoSlotWidget = new CheckboxWidget(this, font, xpos, ypos + 1, "Automatically change save state slots");
wid.push_back(myAutoSlotWidget);
ypos += lineHeight + VGAP;
// Add Defaults, OK and Cancel buttons
addDefaultsOKCancelBGroup(wid, font);
addToFocusList(wid);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EmulationDialog::loadConfig()
{
Settings& settings = instance().settings();
// Emulation speed
int speed = mapSpeed(settings.getFloat("speed"));
mySpeed->setValue(speed);
mySpeed->setValueLabel(formatSpeed(speed));
// Use sync to vertical blank
myUseVSync->setState(settings.getBool("vsync"));
// Enable 'Turbo' mode
myTurbo->setState(settings.getBool("turbo"));
// Show UI messages
myUIMessages->setState(settings.getBool("uimessages"));
// Fast loading of Supercharger BIOS
myFastSCBios->setState(settings.getBool("fastscbios"));
// Multi-threaded rendering
myUseThreads->setState(settings.getBool("threads"));
// Confirm dialog when exiting emulation
myConfirmExitWidget->setState(settings.getBool("confirmexit"));
// Save on exit
string saveOnExit = settings.getString("saveonexit");
mySaveOnExitGroup->setSelected(saveOnExit == "all" ? 2 : saveOnExit == "current" ? 1 : 0);
// Automatically change save state slots
myAutoSlotWidget->setState(settings.getBool("autoslot"));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EmulationDialog::saveConfig()
{
Settings& settings = instance().settings();
// Speed
const int speedup = mySpeed->getValue();
settings.setValue("speed", unmapSpeed(speedup));
if(instance().hasConsole())
instance().console().initializeAudio();
// Use sync to vertical blank
settings.setValue("vsync", myUseVSync->getState());
// Enable 'Turbo' mode
settings.setValue("turbo", myTurbo->getState());
// Show UI messages
settings.setValue("uimessages", myUIMessages->getState());
// Fast loading of Supercharger BIOS
settings.setValue("fastscbios", myFastSCBios->getState());
// Multi-threaded rendering
settings.setValue("threads", myUseThreads->getState());
// Confirm dialog when exiting emulation
settings.setValue("confirmexit", myConfirmExitWidget->getState());
// Save on exit
int saveOnExit = mySaveOnExitGroup->getSelected();
settings.setValue("saveonexit",
saveOnExit == 0 ? "none" : saveOnExit == 1 ? "current" : "all");
// Automatically change save state slots
settings.setValue("autoslot", myAutoSlotWidget->getState());
if(instance().hasConsole())
{
// update speed
instance().console().initializeAudio();
// update VSync
instance().console().initializeVideo();
instance().frameBuffer().tiaSurface().ntsc().enableThreading(myUseThreads->getState());
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EmulationDialog::setDefaults()
{
// speed
mySpeed->setValue(0);
myUseVSync->setState(true);
// misc
myUIMessages->setState(true);
myFastSCBios->setState(true);
myUseThreads->setState(false);
myConfirmExitWidget->setState(false);
mySaveOnExitGroup->setSelected(0);
myAutoSlotWidget->setState(false);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EmulationDialog::handleCommand(CommandSender* sender, int cmd,
int data, int id)
{
switch(cmd)
{
case GuiObject::kOKCmd:
saveConfig();
close();
break;
case GuiObject::kDefaultsCmd:
setDefaults();
break;
case kSpeedupChanged:
mySpeed->setValueLabel(formatSpeed(mySpeed->getValue()));
break;
default:
Dialog::handleCommand(sender, cmd, data, 0);
break;
}
}

View File

@ -0,0 +1,63 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#ifndef EMULATION_DIALOG_HXX
#define EMULATION_DIALOG_HXX
class RadioButtonGroup;
#include "Dialog.hxx"
class EmulationDialog : public Dialog
{
public:
EmulationDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font,
int max_w, int max_h);
virtual ~EmulationDialog() = default;
private:
void loadConfig() override;
void saveConfig() override;
void setDefaults() override;
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
private:
SliderWidget* mySpeed{nullptr};
CheckboxWidget* myUseVSync{nullptr};
CheckboxWidget* myTurbo{nullptr};
CheckboxWidget* myUIMessages{nullptr};
CheckboxWidget* myFastSCBios{nullptr};
CheckboxWidget* myUseThreads{nullptr};
CheckboxWidget* myConfirmExitWidget{nullptr};
RadioButtonGroup* mySaveOnExitGroup{nullptr};
CheckboxWidget* myAutoSlotWidget{nullptr};
enum {
kSpeedupChanged = 'EDSp',
};
private:
// Following constructors and assignment operators not supported
EmulationDialog() = delete;
EmulationDialog(const EmulationDialog&) = delete;
EmulationDialog(EmulationDialog&&) = delete;
EmulationDialog& operator=(const EmulationDialog&) = delete;
EmulationDialog& operator=(EmulationDialog&&) = delete;
};
#endif

View File

@ -121,7 +121,7 @@ void HelpDialog::updateStrings(uInt8 page, uInt8 lines, string& title)
case 2:
title = "Special commands";
ADD_EVENT(Event::FormatIncrease, "Switch between NTSC/PAL/SECAM");
ADD_EVENT(Event::TogglePalette, "Switch palette");
ADD_EVENT(Event::PaletteIncrease, "Switch to next palette");
ADD_EVENT(Event::TogglePhosphor, "Toggle 'phosphor' effect");
ADD_LINE();
ADD_EVENT(Event::ToggleGrabMouse, "Grab mouse (keep in window)");

View File

@ -53,7 +53,7 @@ InputDialog::InputDialog(OSystem& osystem, DialogContainer& parent,
int xpos, ypos, tabID;
// Set real dimensions
setSize(50 * fontWidth + HBORDER * 2,
setSize(48 * fontWidth + PopUpWidget::dropDownWidth(_font) + HBORDER * 2,
_th + VGAP * 3 + lineHeight + 13 * (lineHeight + VGAP) + VGAP * 8 + buttonHeight + VBORDER * 3,
max_w, max_h);

View File

@ -23,8 +23,8 @@
#include "Widget.hxx"
#include "Font.hxx"
#include "Control.hxx"
#include "VideoDialog.hxx"
#include "AudioDialog.hxx"
#include "EmulationDialog.hxx"
#include "VideoAudioDialog.hxx"
#include "InputDialog.hxx"
#include "UIDialog.hxx"
#include "SnapshotDialog.hxx"
@ -89,13 +89,10 @@ OptionsDialog::OptionsDialog(OSystem& osystem, DialogContainer& parent,
return bw;
};
b = ADD_OD_BUTTON("Video" + ELLIPSIS, kVidCmd);
b = ADD_OD_BUTTON("Video & Audio" + ELLIPSIS, kVidCmd);
wid.push_back(b);
b = ADD_OD_BUTTON("Audio" + ELLIPSIS, kAudCmd);
#ifndef SOUND_SUPPORT
b->clearFlags(Widget::FLAG_ENABLED);
#endif
b = ADD_OD_BUTTON("Emulation" + ELLIPSIS, kEmuCmd);
wid.push_back(b);
b = ADD_OD_BUTTON("Input" + ELLIPSIS, kInptCmd);
@ -143,8 +140,8 @@ OptionsDialog::OptionsDialog(OSystem& osystem, DialogContainer& parent,
addCancelWidget(b);
// Now create all the dialogs attached to each menu button
myVideoDialog = make_unique<VideoDialog>(osystem, parent, _font, max_w, max_h);
myAudioDialog = make_unique<AudioDialog>(osystem, parent, _font);
myVideoDialog = make_unique<VideoAudioDialog>(osystem, parent, _font, max_w, max_h);
myEmulationDialog= make_unique<EmulationDialog>(osystem, parent, _font, max_w, max_h);
myInputDialog = make_unique<InputDialog>(osystem, parent, _font, max_w, max_h);
myUIDialog = make_unique<UIDialog>(osystem, parent, _font, boss, max_w, max_h);
mySnapshotDialog = make_unique<SnapshotDialog>(osystem, parent, _font, max_w, max_h);
@ -212,6 +209,10 @@ void OptionsDialog::handleCommand(CommandSender* sender, int cmd,
instance().eventHandler().leaveMenuMode();
break;
case kEmuCmd:
myEmulationDialog->open();
break;
case kVidCmd:
{
// This dialog is resizable under certain conditions, so we need
@ -220,17 +221,12 @@ void OptionsDialog::handleCommand(CommandSender* sender, int cmd,
if(myVideoDialog == nullptr || myVideoDialog->shouldResize(w, h))
{
myVideoDialog = make_unique<VideoDialog>(instance(), parent(),
myVideoDialog = make_unique<VideoAudioDialog>(instance(), parent(),
instance().frameBuffer().font(), w, h);
}
myVideoDialog->open();
break;
}
case kAudCmd:
myAudioDialog->open();
break;
case kInptCmd:
{
// This dialog is resizable under certain conditions, so we need

View File

@ -22,8 +22,8 @@ class CommandSender;
class DialogContainer;
class GuiObject;
class OSystem;
class VideoDialog;
class AudioDialog;
class EmulationDialog;
class VideoAudioDialog;
class InputDialog;
class UIDialog;
class SnapshotDialog;
@ -52,8 +52,8 @@ class OptionsDialog : public Dialog
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
private:
unique_ptr<VideoDialog> myVideoDialog;
unique_ptr<AudioDialog> myAudioDialog;
unique_ptr<VideoAudioDialog> myVideoDialog;
unique_ptr<EmulationDialog> myEmulationDialog;
unique_ptr<InputDialog> myInputDialog;
unique_ptr<UIDialog> myUIDialog;
unique_ptr<SnapshotDialog> mySnapshotDialog;
@ -78,7 +78,7 @@ class OptionsDialog : public Dialog
enum {
kBasSetCmd = 'BAST',
kVidCmd = 'VIDO',
kAudCmd = 'AUDO',
kEmuCmd = 'EMUO',
kInptCmd = 'INPT',
kUsrIfaceCmd = 'URIF',
kSnapCmd = 'SNAP',

View File

@ -105,12 +105,13 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent,
wid.push_back(myDialogFontPopup);
// Enable HiDPI mode
myHidpiWidget = new CheckboxWidget(myTab, font, myDialogFontPopup->getRight() + fontWidth * 5,
xpos = myDialogFontPopup->getRight() + fontWidth * 5;
myHidpiWidget = new CheckboxWidget(myTab, font, xpos,
ypos + 1, "HiDPI mode (*)");
wid.push_back(myHidpiWidget);
ypos += lineHeight + VGAP;
// Dialog position
xpos = HBORDER; ypos += lineHeight + VGAP;
items.clear();
VarList::push_back(items, "Centered", 0);
VarList::push_back(items, "Left top", 1);
@ -120,14 +121,14 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent,
myPositionPopup = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight,
items, "Dialogs position", lwidth);
wid.push_back(myPositionPopup);
ypos += lineHeight + VGAP * 2;
// Confirm dialog when exiting emulation
myConfirmExitWidget = new CheckboxWidget(myTab, font, xpos, ypos, "Confirm exiting emulation");
wid.push_back(myConfirmExitWidget);
ypos += lineHeight + VGAP * 3;
// Center window (in windowed mode)
xpos = myHidpiWidget->getLeft();
myCenter = new CheckboxWidget(myTab, _font, xpos, ypos + 1, "Center windows");
wid.push_back(myCenter);
// Delay between quick-selecting characters in ListWidget
xpos = HBORDER; ypos += lineHeight + VGAP * 4;
int swidth = myPalettePopup->getWidth() - lwidth;
myListDelaySlider = new SliderWidget(myTab, font, xpos, ypos, swidth, lineHeight,
"List input delay ", 0, kListDelay,
@ -303,6 +304,10 @@ UIDialog::UIDialog(OSystem& osystem, DialogContainer& parent,
wid.clear();
addDefaultsOKCancelBGroup(wid, font);
addBGroupToFocusList(wid);
#ifndef WINDOWED_SUPPORT
myCenter->clearFlags(Widget::FLAG_ENABLED);
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -353,6 +358,10 @@ void UIDialog::loadConfig()
const string& pal = settings.getString("uipalette");
myPalettePopup->setSelected(pal, "standard");
// Dialog font
const string& dialogFont = settings.getString("dialogfont");
myDialogFontPopup->setSelected(dialogFont, "medium");
// Enable HiDPI mode
if (!instance().frameBuffer().hidpiAllowed())
{
@ -364,16 +373,12 @@ void UIDialog::loadConfig()
myHidpiWidget->setState(settings.getBool("hidpi"));
}
// Confirm dialog when exiting emulation
myConfirmExitWidget->setState(settings.getBool("confirmexit"));
// Dialog font
const string& dialogFont = settings.getString("dialogfont");
myDialogFontPopup->setSelected(dialogFont, "medium");
// Dialog position
myPositionPopup->setSelected(settings.getString("dialogpos"), "0");
// Center window
myCenter->setState(settings.getBool("center"));
// Listwidget quick delay
int delay = settings.getInt("listdelay");
myListDelaySlider->setValue(delay);
@ -436,18 +441,18 @@ void UIDialog::saveConfig()
myPalettePopup->getSelectedTag().toString());
instance().frameBuffer().setUIPalette();
// Enable HiDPI mode
settings.setValue("hidpi", myHidpiWidget->getState());
// Dialog font
settings.setValue("dialogfont",
myDialogFontPopup->getSelectedTag().toString());
// Enable HiDPI mode
settings.setValue("hidpi", myHidpiWidget->getState());
// Dialog position
settings.setValue("dialogpos", myPositionPopup->getSelectedTag().toString());
// Confirm dialog when exiting emulation
settings.setValue("confirmexit", myConfirmExitWidget->getState());
// Center window
settings.setValue("center", myCenter->getState());
// Listwidget quick delay
settings.setValue("listdelay", myListDelaySlider->getValue());
@ -481,10 +486,10 @@ void UIDialog::setDefaults()
{
case 0: // Misc. options
myPalettePopup->setSelected("standard");
myHidpiWidget->setState(false);
myDialogFontPopup->setSelected("medium", "");
myHidpiWidget->setState(false);
myPositionPopup->setSelected("0");
myConfirmExitWidget->setState(false);
myCenter->setState(false);
myListDelaySlider->setValue(300);
myWheelLinesSlider->setValue(4);
myDoubleClickSlider->setValue(500);

View File

@ -66,10 +66,10 @@ class UIDialog : public Dialog, public CommandSender
// Misc options
PopUpWidget* myPalettePopup{nullptr};
CheckboxWidget* myHidpiWidget{nullptr};
PopUpWidget* myDialogFontPopup{nullptr};
CheckboxWidget* myHidpiWidget{nullptr};
PopUpWidget* myPositionPopup{nullptr};
CheckboxWidget* myConfirmExitWidget{nullptr};
CheckboxWidget* myCenter{nullptr};
SliderWidget* myListDelaySlider{nullptr};
SliderWidget* myWheelLinesSlider{nullptr};
SliderWidget* myControllerRateSlider{nullptr};

1084
src/gui/VideoAudioDialog.cxx Normal file

File diff suppressed because it is too large Load Diff

View File

@ -15,77 +15,75 @@
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#ifndef VIDEO_DIALOG_HXX
#define VIDEO_DIALOG_HXX
#ifndef VIDEOAUDIO_DIALOG_HXX
#define VIDEOAUDIO_DIALOG_HXX
class CommandSender;
class CheckboxWidget;
class ColorWidget;
class DialogContainer;
class PopUpWidget;
class RadioButtonGroup;
class SliderWidget;
class StaticTextWidget;
class TabWidget;
class OSystem;
#include "Dialog.hxx"
#include "PaletteHandler.hxx"
#include "NTSCFilter.hxx"
#include "bspf.hxx"
class VideoDialog : public Dialog
class VideoAudioDialog : public Dialog
{
public:
VideoDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font,
VideoAudioDialog(OSystem& osystem, DialogContainer& parent, const GUI::Font& font,
int max_w, int max_h);
virtual ~VideoDialog() = default;
virtual ~VideoAudioDialog() = default;
private:
void loadConfig() override;
void saveConfig() override;
void setDefaults() override;
void addDisplayTab();
void addPaletteTab();
void addTVEffectsTab();
void addAudioTab();
void handleTVModeChange(NTSCFilter::Preset);
void loadTVAdjustables(NTSCFilter::Preset preset);
void handlePaletteChange();
void handlePaletteUpdate();
void handleFullScreenChange();
void handleOverscanChange();
void handlePhosphorChange();
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
void addPalette(int x, int y, int h, int w);
void colorPalette();
void updatePreset();
void updateEnabledState();
void updateSettingsWithPreset(AudioSettings&);
private:
TabWidget* myTab;
// General options
PopUpWidget* myRenderer{nullptr};
SliderWidget* myTIAZoom{nullptr};
PopUpWidget* myTIAPalette{nullptr};
SliderWidget* myPhaseShiftNtsc{nullptr};
SliderWidget* myPhaseShiftPal{nullptr};
CheckboxWidget* myTIAInterpolate{nullptr};
SliderWidget* myVSizeAdjust{nullptr};
SliderWidget* mySpeed{nullptr};
CheckboxWidget* myFullscreen{nullptr};
//PopUpWidget* myFullScreenMode;
CheckboxWidget* myUseStretch{nullptr};
SliderWidget* myTVOverscan{nullptr};
CheckboxWidget* myUseVSync{nullptr};
CheckboxWidget* myUIMessages{nullptr};
CheckboxWidget* myCenter{nullptr};
CheckboxWidget* myFastSCBios{nullptr};
CheckboxWidget* myUseThreads{nullptr};
SliderWidget* myTIAZoom{nullptr};
SliderWidget* myVSizeAdjust{nullptr};
// TV effects adjustables (custom mode)
PopUpWidget* myTVMode{nullptr};
SliderWidget* myTVSharp{nullptr};
SliderWidget* myTVHue{nullptr};
SliderWidget* myTVRes{nullptr};
SliderWidget* myTVArtifacts{nullptr};
SliderWidget* myTVFringe{nullptr};
SliderWidget* myTVBleed{nullptr};
SliderWidget* myTVBright{nullptr};
SliderWidget* myTVContrast{nullptr};
SliderWidget* myTVSatur{nullptr};
SliderWidget* myTVGamma{nullptr};
// TV phosphor effect
CheckboxWidget* myTVPhosphor{nullptr};
@ -102,15 +100,44 @@ class VideoDialog : public Dialog
ButtonWidget* myCloneBad{nullptr};
ButtonWidget* myCloneCustom{nullptr};
// Palettes
PopUpWidget* myTIAPalette{nullptr};
SliderWidget* myPhaseShiftNtsc{nullptr};
SliderWidget* myPhaseShiftPal{nullptr};
SliderWidget* myTVHue{nullptr};
SliderWidget* myTVSatur{nullptr};
SliderWidget* myTVBright{nullptr};
SliderWidget* myTVContrast{nullptr};
SliderWidget* myTVGamma{nullptr};
std::array<StaticTextWidget*, 16> myColorLbl{nullptr};
ColorWidget* myColor[16][8]{{nullptr}};
// Audio
CheckboxWidget* mySoundEnableCheckbox{nullptr};
SliderWidget* myVolumeSlider{nullptr};
CheckboxWidget* myStereoSoundCheckbox{nullptr};
PopUpWidget* myModePopup{nullptr};
PopUpWidget* myFragsizePopup{nullptr};
PopUpWidget* myFreqPopup{nullptr};
PopUpWidget* myResamplingPopup{nullptr};
SliderWidget* myHeadroomSlider{nullptr};
SliderWidget* myBufferSizeSlider{nullptr};
SliderWidget* myDpcPitch{nullptr};
string myPalette;
PaletteHandler::Adjustable myPaletteAdj;
enum {
kPaletteChanged = 'VDpl',
kNtscShiftChanged = 'VDns',
kPalShiftChanged = 'VDps',
kSpeedupChanged = 'VDSp',
kZoomChanged = 'VDZo',
kVSizeChanged = 'VDVs',
kFullScreenChanged = 'VDFs',
kOverscanChanged = 'VDOv',
kPaletteChanged = 'VDpl',
kNtscShiftChanged = 'VDns',
kPalShiftChanged = 'VDps',
kPaletteUpdated = 'VDpu',
kTVModeChanged = 'VDtv',
kCloneCompositeCmd = 'CLcp',
kCloneSvideoCmd = 'CLsv',
@ -119,16 +146,21 @@ class VideoDialog : public Dialog
kCloneCustomCmd = 'CLcu',
kPhosphorChanged = 'VDph',
kPhosBlendChanged = 'VDbl',
kScanlinesChanged = 'VDsc'
kScanlinesChanged = 'VDsc',
kSoundEnableChanged = 'ADse',
kModeChanged = 'ADmc',
kHeadroomChanged = 'ADhc',
kBufferSizeChanged = 'ADbc'
};
private:
// Following constructors and assignment operators not supported
VideoDialog() = delete;
VideoDialog(const VideoDialog&) = delete;
VideoDialog(VideoDialog&&) = delete;
VideoDialog& operator=(const VideoDialog&) = delete;
VideoDialog& operator=(VideoDialog&&) = delete;
VideoAudioDialog() = delete;
VideoAudioDialog(const VideoAudioDialog&) = delete;
VideoAudioDialog(VideoAudioDialog&&) = delete;
VideoAudioDialog& operator=(const VideoAudioDialog&) = delete;
VideoAudioDialog& operator=(VideoAudioDialog&&) = delete;
};
#endif

View File

@ -1,772 +0,0 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#include <cmath>
#include "bspf.hxx"
#include "Control.hxx"
#include "Dialog.hxx"
#include "Menu.hxx"
#include "OSystem.hxx"
#include "EditTextWidget.hxx"
#include "PopUpWidget.hxx"
#include "Console.hxx"
#include "TIA.hxx"
#include "Settings.hxx"
#include "Widget.hxx"
#include "Font.hxx"
#include "TabWidget.hxx"
#include "NTSCFilter.hxx"
#include "TIASurface.hxx"
#include "VideoDialog.hxx"
namespace {
// Emulation speed is a positive float that multiplies the framerate. However, the UI controls
// adjust speed in terms of a speedup factor (1/10, 1/9 .. 1/2, 1, 2, 3, .., 10). The following
// mapping and formatting functions implement this conversion. The speedup factor is represented
// by an integer value between -900 and 900 (0 means no speedup).
constexpr int MAX_SPEED = 900;
constexpr int MIN_SPEED = -900;
constexpr int SPEED_STEP = 10;
int mapSpeed(float speed)
{
speed = std::abs(speed);
return BSPF::clamp(
static_cast<int>(round(100 * (speed >= 1 ? speed - 1 : -1 / speed + 1))),
MIN_SPEED, MAX_SPEED
);
}
float unmapSpeed(int speed)
{
float f_speed = static_cast<float>(speed) / 100;
return speed < 0 ? -1 / (f_speed - 1) : 1 + f_speed;
}
string formatSpeed(int speed) {
stringstream ss;
ss
<< std::setw(3) << std::fixed << std::setprecision(0)
<< (unmapSpeed(speed) * 100);
return ss.str();
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
VideoDialog::VideoDialog(OSystem& osystem, DialogContainer& parent,
const GUI::Font& font, int max_w, int max_h)
: Dialog(osystem, parent, font, "Video settings")
{
const int lineHeight = font.getLineHeight(),
fontHeight = font.getFontHeight(),
fontWidth = font.getMaxCharWidth(),
buttonHeight = font.getLineHeight() * 1.25;
const int VGAP = fontHeight / 4;
const int VBORDER = fontHeight / 2;
const int HBORDER = fontWidth * 1.25;
const int INDENT = fontWidth * 2;
int xpos, ypos, tabID;
int lwidth = font.getStringWidth("V-Size adjust "),
pwidth = font.getStringWidth("XXXXxXXXX");
WidgetArray wid;
VariantList items;
// Set real dimensions
setSize(57 * fontWidth + HBORDER * 2 + PopUpWidget::dropDownWidth(font) * 2,
_th + VGAP * 3 + lineHeight + 11 * (lineHeight + VGAP) + buttonHeight + VBORDER * 3,
max_w, max_h);
// The tab widget
xpos = 2; ypos = VGAP;
myTab = new TabWidget(this, font, xpos, ypos + _th,
_w - 2*xpos,
_h - _th - VGAP - buttonHeight - VBORDER * 2);
addTabWidget(myTab);
xpos = HBORDER; ypos = VBORDER;
//////////////////////////////////////////////////////////
// 1) General options
tabID = myTab->addTab(" General ");
// Video renderer
myRenderer = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight,
instance().frameBuffer().supportedRenderers(),
"Renderer ", lwidth);
wid.push_back(myRenderer);
ypos += lineHeight + VGAP;
// TIA Palette
items.clear();
VarList::push_back(items, "Standard", "standard");
VarList::push_back(items, "z26", "z26");
if (instance().checkUserPalette())
VarList::push_back(items, "User", "user");
VarList::push_back(items, "Custom", "custom");
myTIAPalette = new PopUpWidget(myTab, font, xpos, ypos, pwidth,
lineHeight, items, "Palette ", lwidth, kPaletteChanged);
wid.push_back(myTIAPalette);
ypos += lineHeight + VGAP;
int swidth = myTIAPalette->getWidth() - lwidth;
int plWidth = font.getStringWidth("NTSC phase ");
int pswidth = swidth - INDENT + lwidth - plWidth;
myPhaseShiftNtsc =
new SliderWidget(myTab, font, xpos + INDENT, ypos-1, pswidth, lineHeight,
"NTSC phase", plWidth, kNtscShiftChanged, fontWidth * 5);
myPhaseShiftNtsc->setMinValue(262 - 45); myPhaseShiftNtsc->setMaxValue(262 + 45);
myPhaseShiftNtsc->setTickmarkIntervals(4);
wid.push_back(myPhaseShiftNtsc);
ypos += lineHeight + VGAP;
myPhaseShiftPal =
new SliderWidget(myTab, font, xpos + INDENT, ypos-1, pswidth, lineHeight,
"PAL phase", plWidth, kPalShiftChanged, fontWidth * 5);
myPhaseShiftPal->setMinValue(313 - 45); myPhaseShiftPal->setMaxValue(313 + 45);
myPhaseShiftPal->setTickmarkIntervals(4);
wid.push_back(myPhaseShiftPal);
ypos += lineHeight + VGAP * 4;
// TIA interpolation
myTIAInterpolate = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Interpolation ");
wid.push_back(myTIAInterpolate); ypos += lineHeight + VGAP;
// TIA zoom levels (will be dynamically filled later)
myTIAZoom = new SliderWidget(myTab, font, xpos, ypos - 1, swidth, lineHeight,
"Zoom ", lwidth, 0, fontWidth * 4, "%");
myTIAZoom->setMinValue(200); myTIAZoom->setStepValue(FrameBuffer::ZOOM_STEPS * 100);
wid.push_back(myTIAZoom);
ypos += lineHeight + VGAP;
// Aspect ratio (NTSC mode)
myVSizeAdjust =
new SliderWidget(myTab, font, xpos, ypos-1, swidth, lineHeight,
"V-Size adjust", lwidth, kVSizeChanged, fontWidth * 7, "%", 0, true);
myVSizeAdjust->setMinValue(-5); myVSizeAdjust->setMaxValue(5);
myVSizeAdjust->setTickmarkIntervals(2);
wid.push_back(myVSizeAdjust);
ypos += lineHeight + VGAP;
// Speed
mySpeed =
new SliderWidget(myTab, font, xpos, ypos-1, swidth, lineHeight,
"Emul. speed ", lwidth, kSpeedupChanged, fontWidth * 5, "%");
mySpeed->setMinValue(MIN_SPEED); mySpeed->setMaxValue(MAX_SPEED);
mySpeed->setStepValue(SPEED_STEP);
mySpeed->setTickmarkIntervals(2);
wid.push_back(mySpeed);
ypos += lineHeight + VGAP;
// Use sync to vblank
myUseVSync = new CheckboxWidget(myTab, font, xpos, ypos + 1, "VSync");
wid.push_back(myUseVSync);
// Move over to the next column
xpos = myVSizeAdjust->getRight() + fontWidth * 3;
ypos = VBORDER;
// Fullscreen
myFullscreen = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Fullscreen", kFullScreenChanged);
wid.push_back(myFullscreen);
ypos += lineHeight + VGAP;
/*pwidth = font.getStringWidth("0: 3840x2860@120Hz");
myFullScreenMode = new PopUpWidget(myTab, font, xpos + INDENT + 2, ypos, pwidth, lineHeight,
instance().frameBuffer().supportedScreenModes(), "Mode ");
wid.push_back(myFullScreenMode);
ypos += lineHeight + VGAP;*/
// FS stretch
myUseStretch = new CheckboxWidget(myTab, font, xpos + INDENT, ypos + 1, "Stretch");
wid.push_back(myUseStretch);
ypos += lineHeight + VGAP;
// FS overscan
myTVOverscan = new SliderWidget(myTab, font, xpos + INDENT, ypos - 1, swidth, lineHeight,
"Overscan", font.getStringWidth("Overscan "), kOverscanChanged, fontWidth * 3, "%");
myTVOverscan->setMinValue(0); myTVOverscan->setMaxValue(10);
myTVOverscan->setTickmarkIntervals(2);
wid.push_back(myTVOverscan);
ypos += (lineHeight + VGAP) * 2;
// Skip progress load bars for SuperCharger ROMs
// Doesn't really belong here, but I couldn't find a better place for it
myFastSCBios = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Fast SuperCharger load");
wid.push_back(myFastSCBios);
ypos += lineHeight + VGAP;
// Show UI messages onscreen
myUIMessages = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Show UI messages");
wid.push_back(myUIMessages);
ypos += lineHeight + VGAP;
// Center window (in windowed mode)
myCenter = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Center window");
wid.push_back(myCenter);
ypos += (lineHeight + VGAP) * 2;
// Use multi-threading
myUseThreads = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Multi-threading");
wid.push_back(myUseThreads);
// Add items for tab 0
addToFocusList(wid, myTab, tabID);
//////////////////////////////////////////////////////////
// 2) TV effects options
wid.clear();
tabID = myTab->addTab(" TV Effects ");
xpos = HBORDER;
ypos = VBORDER;
swidth = fontWidth * 8 - fontWidth / 2;
// TV Mode
items.clear();
VarList::push_back(items, "Disabled", static_cast<uInt32>(NTSCFilter::Preset::OFF));
VarList::push_back(items, "RGB", static_cast<uInt32>(NTSCFilter::Preset::RGB));
VarList::push_back(items, "S-Video", static_cast<uInt32>(NTSCFilter::Preset::SVIDEO));
VarList::push_back(items, "Composite", static_cast<uInt32>(NTSCFilter::Preset::COMPOSITE));
VarList::push_back(items, "Bad adjust", static_cast<uInt32>(NTSCFilter::Preset::BAD));
VarList::push_back(items, "Custom", static_cast<uInt32>(NTSCFilter::Preset::CUSTOM));
lwidth = font.getStringWidth("TV Mode ");
pwidth = font.getStringWidth("Bad adjust");
myTVMode =
new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight,
items, "TV mode ", lwidth, kTVModeChanged);
wid.push_back(myTVMode);
ypos += lineHeight + VGAP;
// Custom adjustables (using macro voodoo)
xpos += INDENT - 2; ypos += 0;
lwidth = font.getStringWidth("Saturation ");
#define CREATE_CUSTOM_SLIDERS(obj, desc, cmd) \
myTV ## obj = \
new SliderWidget(myTab, font, xpos, ypos-1, swidth, lineHeight, \
desc, lwidth, cmd, fontWidth*4, "%"); \
myTV ## obj->setMinValue(0); myTV ## obj->setMaxValue(100); \
myTV ## obj->setTickmarkIntervals(2); \
wid.push_back(myTV ## obj); \
ypos += lineHeight + VGAP;
CREATE_CUSTOM_SLIDERS(Contrast, "Contrast ", 0)
CREATE_CUSTOM_SLIDERS(Bright, "Brightness ", 0)
CREATE_CUSTOM_SLIDERS(Hue, "Hue ", 0)
CREATE_CUSTOM_SLIDERS(Satur, "Saturation ", 0)
CREATE_CUSTOM_SLIDERS(Gamma, "Gamma ", 0)
CREATE_CUSTOM_SLIDERS(Sharp, "Sharpness ", 0)
CREATE_CUSTOM_SLIDERS(Res, "Resolution ", 0)
CREATE_CUSTOM_SLIDERS(Artifacts, "Artifacts ", 0)
CREATE_CUSTOM_SLIDERS(Fringe, "Fringing ", 0)
CREATE_CUSTOM_SLIDERS(Bleed, "Bleeding ", 0)
xpos += myTVContrast->getWidth() + fontWidth * 6;
ypos = VBORDER;
lwidth = font.getStringWidth("Intensity ");
// TV Phosphor effect
myTVPhosphor = new CheckboxWidget(myTab, font, xpos, ypos + 1, "Phosphor for all ROMs", kPhosphorChanged);
wid.push_back(myTVPhosphor);
ypos += lineHeight + VGAP / 2;
// TV Phosphor blend level
xpos += INDENT;
swidth = font.getMaxCharWidth() * 10;
CREATE_CUSTOM_SLIDERS(PhosLevel, "Blend ", kPhosBlendChanged)
ypos += VGAP * 2;
// Scanline intensity and interpolation
xpos -= INDENT;
myTVScanLabel = new StaticTextWidget(myTab, font, xpos, ypos, "Scanlines:");
ypos += lineHeight + VGAP / 2;
xpos += INDENT;
CREATE_CUSTOM_SLIDERS(ScanIntense, "Intensity ", kScanlinesChanged)
ypos += VGAP * 3;
// Adjustable presets
xpos -= INDENT;
int cloneWidth = font.getStringWidth("Clone Bad Adjust") + 20;
#define CREATE_CLONE_BUTTON(obj, desc) \
myClone ## obj = \
new ButtonWidget(myTab, font, xpos, ypos, cloneWidth, buttonHeight,\
desc, kClone ## obj ##Cmd); \
wid.push_back(myClone ## obj); \
ypos += buttonHeight + VGAP;
ypos += VGAP;
CREATE_CLONE_BUTTON(RGB, "Clone RGB")
CREATE_CLONE_BUTTON(Svideo, "Clone S-Video")
CREATE_CLONE_BUTTON(Composite, "Clone Composite")
CREATE_CLONE_BUTTON(Bad, "Clone Bad adjust")
CREATE_CLONE_BUTTON(Custom, "Revert")
// Add items for tab 2
addToFocusList(wid, myTab, tabID);
// Activate the first tab
myTab->setActiveTab(0);
// Add Defaults, OK and Cancel buttons
wid.clear();
addDefaultsOKCancelBGroup(wid, font);
addBGroupToFocusList(wid);
// Disable certain functions when we know they aren't present
#ifndef WINDOWED_SUPPORT
myFullscreen->clearFlags(Widget::FLAG_ENABLED);
myCenter->clearFlags(Widget::FLAG_ENABLED);
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoDialog::loadConfig()
{
// Renderer settings
myRenderer->setSelected(instance().settings().getString("video"), "default");
// TIA zoom levels
// These are dynamically loaded, since they depend on the size of
// the desktop and which renderer we're using
float minZoom = instance().frameBuffer().supportedTIAMinZoom(); // or 2 if we allow lower values
float maxZoom = instance().frameBuffer().supportedTIAMaxZoom();
myTIAZoom->setMinValue(minZoom * 100);
myTIAZoom->setMaxValue(maxZoom * 100);
myTIAZoom->setTickmarkIntervals((maxZoom - minZoom) * 2); // every ~50%
myTIAZoom->setValue(instance().settings().getFloat("tia.zoom") * 100);
// TIA Palette
myTIAPalette->setSelected(
instance().settings().getString("palette"), "standard");
// Custom Palette
myPhaseShiftNtsc->setValue(instance().settings().getFloat("phase_ntsc") * 10);
myPhaseShiftPal->setValue(instance().settings().getFloat("phase_pal") * 10);
handlePaletteChange();
// TIA interpolation
myTIAInterpolate->setState(instance().settings().getBool("tia.inter"));
// Aspect ratio setting (NTSC and PAL)
myVSizeAdjust->setValue(instance().settings().getInt("tia.vsizeadjust"));
// Emulation speed
int speed = mapSpeed(instance().settings().getFloat("speed"));
mySpeed->setValue(speed);
mySpeed->setValueLabel(formatSpeed(speed));
// Fullscreen
myFullscreen->setState(instance().settings().getBool("fullscreen"));
/*string mode = instance().settings().getString("fullscreenmode");
myFullScreenMode->setSelected(mode);*/
// Fullscreen stretch setting
myUseStretch->setState(instance().settings().getBool("tia.fs_stretch"));
// Fullscreen overscan setting
myTVOverscan->setValue(instance().settings().getInt("tia.fs_overscan"));
handleFullScreenChange();
// Use sync to vertical blank
myUseVSync->setState(instance().settings().getBool("vsync"));
// Show UI messages
myUIMessages->setState(instance().settings().getBool("uimessages"));
// Center window
myCenter->setState(instance().settings().getBool("center"));
// Fast loading of Supercharger BIOS
myFastSCBios->setState(instance().settings().getBool("fastscbios"));
// Multi-threaded rendering
myUseThreads->setState(instance().settings().getBool("threads"));
// TV Mode
myTVMode->setSelected(
instance().settings().getString("tv.filter"), "0");
int preset = instance().settings().getInt("tv.filter");
handleTVModeChange(NTSCFilter::Preset(preset));
// TV Custom adjustables
loadTVAdjustables(NTSCFilter::Preset::CUSTOM);
// TV phosphor mode
myTVPhosphor->setState(instance().settings().getString("tv.phosphor") == "always");
// TV phosphor blend
myTVPhosLevel->setValue(instance().settings().getInt("tv.phosblend"));
handlePhosphorChange();
// TV scanline intensity and interpolation
myTVScanIntense->setValue(instance().settings().getInt("tv.scanlines"));
myTab->loadConfig();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoDialog::saveConfig()
{
// Renderer setting
instance().settings().setValue("video",
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("phase_ntsc", myPhaseShiftNtsc->getValue() / 10.0);
instance().settings().setValue("phase_pal", myPhaseShiftPal->getValue() / 10.0);
// TIA interpolation
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);
// Speed
int speedup = mySpeed->getValue();
instance().settings().setValue("speed", unmapSpeed(speedup));
if (instance().hasConsole()) instance().console().initializeAudio();
// Fullscreen
instance().settings().setValue("fullscreen", myFullscreen->getState());
// Fullscreen stretch setting
instance().settings().setValue("tia.fs_stretch", myUseStretch->getState());
// Fullscreen overscan
instance().settings().setValue("tia.fs_overscan", myTVOverscan->getValueLabel());
// Use sync to vertical blank
instance().settings().setValue("vsync", myUseVSync->getState());
// Show UI messages
instance().settings().setValue("uimessages", myUIMessages->getState());
// Center window
instance().settings().setValue("center", myCenter->getState());
// Fast loading of Supercharger BIOS
instance().settings().setValue("fastscbios", myFastSCBios->getState());
// Multi-threaded rendering
instance().settings().setValue("threads", myUseThreads->getState());
if (instance().hasConsole())
instance().frameBuffer().tiaSurface().ntsc().enableThreading(myUseThreads->getState());
// TV Mode
instance().settings().setValue("tv.filter",
myTVMode->getSelectedTag().toString());
// TV Custom adjustables
NTSCFilter::Adjustable adj;
adj.hue = myTVHue->getValue();
adj.saturation = myTVSatur->getValue();
adj.contrast = myTVContrast->getValue();
adj.brightness = myTVBright->getValue();
adj.sharpness = myTVSharp->getValue();
adj.gamma = myTVGamma->getValue();
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
instance().settings().setValue("tv.phosphor",
myTVPhosphor->getState() ? "always" : "byrom");
// TV phosphor blend
instance().settings().setValue("tv.phosblend", myTVPhosLevel->getValueLabel() == "Off"
? "0" : myTVPhosLevel->getValueLabel());
// TV scanline intensity
instance().settings().setValue("tv.scanlines", myTVScanIntense->getValueLabel());
if(instance().hasConsole())
{
instance().console().setTIAProperties();
if(instance().settings().getString("palette") == "custom")
{
instance().console().generateCustomPalette(0);
instance().console().generateCustomPalette(1);
}
if(vsizeChanged)
{
instance().console().tia().clearFrameBuffer();
instance().console().initializeVideo();
}
}
// Finally, issue a complete framebuffer re-initialization...
instance().createFrameBuffer();
// ... and apply potential setting changes to the TIA surface
instance().frameBuffer().tiaSurface().updateSurfaceSettings();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoDialog::setDefaults()
{
switch(myTab->getActiveTab())
{
case 0: // General
{
myRenderer->setSelectedIndex(0);
myTIAZoom->setValue(300);
myTIAPalette->setSelected("standard", "");
myPhaseShiftNtsc->setValue(262);
myPhaseShiftPal->setValue(313);
myTIAInterpolate->setState(false);
myVSizeAdjust->setValue(0);
mySpeed->setValue(0);
myFullscreen->setState(false);
//myFullScreenMode->setSelectedIndex(0);
myUseStretch->setState(false);
myUseVSync->setState(true);
myUIMessages->setState(true);
myCenter->setState(false);
myFastSCBios->setState(true);
myUseThreads->setState(false);
handlePaletteChange();
break;
}
case 1: // TV effects
{
myTVMode->setSelected("0", "0");
// TV phosphor mode
myTVPhosphor->setState(false);
// TV phosphor blend
myTVPhosLevel->setValue(50);
// TV scanline intensity and interpolation
myTVScanIntense->setValue(25);
// Make sure that mutually-exclusive items are not enabled at the same time
handleTVModeChange(NTSCFilter::Preset::OFF);
handlePhosphorChange();
loadTVAdjustables(NTSCFilter::Preset::CUSTOM);
break;
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoDialog::handleTVModeChange(NTSCFilter::Preset preset)
{
bool enable = preset == NTSCFilter::Preset::CUSTOM;
myTVSharp->setEnabled(enable);
myTVHue->setEnabled(enable);
myTVRes->setEnabled(enable);
myTVArtifacts->setEnabled(enable);
myTVFringe->setEnabled(enable);
myTVBleed->setEnabled(enable);
myTVBright->setEnabled(enable);
myTVContrast->setEnabled(enable);
myTVSatur->setEnabled(enable);
myTVGamma->setEnabled(enable);
myCloneComposite->setEnabled(enable);
myCloneSvideo->setEnabled(enable);
myCloneRGB->setEnabled(enable);
myCloneBad->setEnabled(enable);
myCloneCustom->setEnabled(enable);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoDialog::loadTVAdjustables(NTSCFilter::Preset preset)
{
NTSCFilter::Adjustable adj;
instance().frameBuffer().tiaSurface().ntsc().getAdjustables(
adj, NTSCFilter::Preset(preset));
myTVSharp->setValue(adj.sharpness);
myTVHue->setValue(adj.hue);
myTVRes->setValue(adj.resolution);
myTVArtifacts->setValue(adj.artifacts);
myTVFringe->setValue(adj.fringing);
myTVBleed->setValue(adj.bleed);
myTVBright->setValue(adj.brightness);
myTVContrast->setValue(adj.contrast);
myTVSatur->setValue(adj.saturation);
myTVGamma->setValue(adj.gamma);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoDialog::handlePaletteChange()
{
bool enable = myTIAPalette->getSelectedTag().toString() == "custom";
myPhaseShiftNtsc->setEnabled(enable);
myPhaseShiftPal->setEnabled(enable);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoDialog::handleFullScreenChange()
{
bool enable = myFullscreen->getState();
myUseStretch->setEnabled(enable);
myTVOverscan->setEnabled(enable);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoDialog::handleOverscanChange()
{
if (myTVOverscan->getValue() == 0)
{
myTVOverscan->setValueLabel("Off");
myTVOverscan->setValueUnit("");
}
else
myTVOverscan->setValueUnit("%");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoDialog::handlePhosphorChange()
{
myTVPhosLevel->setEnabled(myTVPhosphor->getState());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoDialog::handleCommand(CommandSender* sender, int cmd,
int data, int id)
{
switch (cmd)
{
case GuiObject::kOKCmd:
saveConfig();
close();
break;
case GuiObject::kDefaultsCmd:
setDefaults();
break;
case kPaletteChanged:
handlePaletteChange();
break;
case kNtscShiftChanged:
{
std::ostringstream ss;
ss << std::setw(4) << std::fixed << std::setprecision(1)
<< (0.1 * abs(myPhaseShiftNtsc->getValue())) << DEGREE;
myPhaseShiftNtsc->setValueLabel(ss.str());
break;
}
case kPalShiftChanged:
{
std::ostringstream ss;
ss << std::setw(4) << std::fixed << std::setprecision(1)
<< (0.1 * abs(myPhaseShiftPal->getValue())) << DEGREE;
myPhaseShiftPal->setValueLabel(ss.str());
break;
}
case kVSizeChanged:
{
int adjust = myVSizeAdjust->getValue();
if (!adjust)
{
myVSizeAdjust->setValueLabel("Default");
myVSizeAdjust->setValueUnit("");
}
else
myVSizeAdjust->setValueUnit("%");
break;
}
case kSpeedupChanged:
mySpeed->setValueLabel(formatSpeed(mySpeed->getValue()));
break;
case kFullScreenChanged:
handleFullScreenChange();
break;
case kOverscanChanged:
handleOverscanChange();
break;
case kTVModeChanged:
handleTVModeChange(NTSCFilter::Preset(myTVMode->getSelectedTag().toInt()));
break;
case kCloneCompositeCmd: loadTVAdjustables(NTSCFilter::Preset::COMPOSITE);
break;
case kCloneSvideoCmd: loadTVAdjustables(NTSCFilter::Preset::SVIDEO);
break;
case kCloneRGBCmd: loadTVAdjustables(NTSCFilter::Preset::RGB);
break;
case kCloneBadCmd: loadTVAdjustables(NTSCFilter::Preset::BAD);
break;
case kCloneCustomCmd: loadTVAdjustables(NTSCFilter::Preset::CUSTOM);
break;
case kScanlinesChanged:
if (myTVScanIntense->getValue() == 0)
{
myTVScanIntense->setValueLabel("Off");
myTVScanIntense->setValueUnit("");
}
else
myTVScanIntense->setValueUnit("%");
break;
case kPhosphorChanged:
handlePhosphorChange();
break;
case kPhosBlendChanged:
if (myTVPhosLevel->getValue() == 0)
{
myTVPhosLevel->setValueLabel("Off");
myTVPhosLevel->setValueUnit("");
}
else
myTVPhosLevel->setValueUnit("%");
break;
default:
Dialog::handleCommand(sender, cmd, data, 0);
break;
}
}

View File

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

View File

@ -2,7 +2,6 @@ MODULE := src/gui
MODULE_OBJS := \
src/gui/AboutDialog.o \
src/gui/AudioDialog.o \
src/gui/BrowserDialog.o \
src/gui/CheckListWidget.o \
src/gui/ColorWidget.o \
@ -15,6 +14,7 @@ MODULE_OBJS := \
src/gui/Dialog.o \
src/gui/EditableWidget.o \
src/gui/EditTextWidget.o \
src/gui/EmulationDialog.o \
src/gui/EventMappingWidget.o \
src/gui/FileListWidget.o \
src/gui/Font.o \
@ -49,7 +49,7 @@ MODULE_OBJS := \
src/gui/TimeMachineDialog.o \
src/gui/TimeMachine.o \
src/gui/UIDialog.o \
src/gui/VideoDialog.o \
src/gui/VideoAudioDialog.o \
src/gui/Widget.o
MODULE_DIRS += \

View File

@ -230,7 +230,7 @@
* the type.
*/
# ifndef PNG_EXPORT_TYPE
# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
# define PNG_EXPORT_TYPE(name) name PNG_IMPEXP
# endif
# define PNG_DLL_EXPORT __export
# else /* newer compiler */
@ -450,7 +450,7 @@
# define PNG_FP_EXPORT(ordinal, type, name, args)\
PNG_EXPORT(ordinal, type, name, args);
# else /* No floating point APIs */
# define PNG_FP_EXPORT(ordinal, type, name, args)
# define PNG_FP_EXPORT(ordinal, name, name, args)
# endif
#endif
#ifndef PNG_FIXED_EXPORT /* A fixed point API. */
@ -458,7 +458,7 @@
# define PNG_FIXED_EXPORT(ordinal, type, name, args)\
PNG_EXPORT(ordinal, type, name, args);
# else /* No fixed point APIs */
# define PNG_FIXED_EXPORT(ordinal, type, name, args)
# define PNG_FIXED_EXPORT(ordinal, name, name, args)
# endif
#endif

View File

@ -23,6 +23,7 @@ SOURCES_CXX := \
$(CORE_DIR)/common/KeyMap.cxx \
$(CORE_DIR)/common/Logger.cxx \
$(CORE_DIR)/common/MouseControl.cxx \
$(CORE_DIR)/common/PaletteHandler.cxx \
$(CORE_DIR)/common/PhosphorHandler.cxx \
$(CORE_DIR)/common/PhysicalJoystick.cxx \
$(CORE_DIR)/common/PJoystickHandler.cxx \

View File

@ -40,7 +40,7 @@ StellaLIBRETRO::StellaLIBRETRO()
video_aspect_ntsc = 0;
video_aspect_pal = 0;
video_palette = "standard";
video_palette = PaletteHandler::SETTING_STANDARD;
video_filter = NTSCFilter::Preset::OFF;
video_ready = false;
@ -374,19 +374,12 @@ void StellaLIBRETRO::setVideoFilter(NTSCFilter::Preset mode)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void StellaLIBRETRO::setVideoPalette(uInt32 mode)
void StellaLIBRETRO::setVideoPalette(const string& mode)
{
switch (mode)
{
case 0: video_palette = "standard"; break;
case 1: video_palette = "z26"; break;
case 2: video_palette = "user"; break;
}
if (system_ready)
{
myOSystem->settings().setValue("palette", video_palette);
myOSystem->console().setPalette(video_palette);
myOSystem->frameBuffer().tiaSurface().paletteHandler().setPalette(video_palette);
}
}

View File

@ -104,7 +104,7 @@ class StellaLIBRETRO
void setVideoAspectPAL(uInt32 value) { video_aspect_pal = value; };
void setVideoFilter(NTSCFilter::Preset mode);
void setVideoPalette(uInt32 mode);
void setVideoPalette(const string& mode);
void setVideoPhosphor(uInt32 mode, uInt32 blend);
void setAudioStereo(int mode);

View File

@ -15,6 +15,7 @@
#include "StellaLIBRETRO.hxx"
#include "Event.hxx"
#include "NTSCFilter.hxx"
#include "PaletteHandler.hxx"
#include "Version.hxx"
@ -30,11 +31,12 @@ static retro_audio_sample_batch_t audio_batch_cb;
// libretro UI settings
static int setting_ntsc, setting_pal;
static int setting_stereo, setting_palette;
static int setting_stereo;
static int setting_phosphor, setting_console, setting_phosphor_blend;
static int stella_paddle_joypad_sensitivity;
static int setting_crop_hoverscan, crop_left;
static NTSCFilter::Preset setting_filter;
static const char* setting_palette;
static bool system_reset;
@ -275,17 +277,11 @@ static void update_variables(bool init = false)
RETRO_GET("stella_palette")
{
int value = 0;
if(!strcmp(var.value, "standard")) value = 0;
else if(!strcmp(var.value, "z26")) value = 1;
else if(!strcmp(var.value, "user")) value = 2;
if(setting_palette != value)
if(setting_palette != var.value)
{
stella.setVideoPalette(value);
stella.setVideoPalette(var.value);
setting_palette = value;
setting_palette = var.value;
}
}
@ -494,7 +490,7 @@ void retro_set_environment(retro_environment_t cb)
static struct retro_variable variables[] = {
// Adding more variables and rearranging them is safe.
{ "stella_console", "Console display; auto|ntsc|pal|secam|ntsc50|pal60|secam60" },
{ "stella_palette", "Palette colors; standard|z26|user" },
{ "stella_palette", "Palette colors; standard|z26|user|custom" },
{ "stella_filter", "TV effects; disabled|composite|s-video|rgb|badly adjusted" },
{ "stella_ntsc_aspect", "NTSC aspect %; par|100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|50|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99" },
{ "stella_pal_aspect", "PAL aspect %; par|100|101|102|103|104|105|106|107|108|109|110|111|112|113|114|115|116|117|118|119|120|121|122|123|124|125|50|75|76|77|78|79|80|81|82|83|84|85|86|87|88|89|90|91|92|93|94|95|96|97|98|99" },

View File

@ -44,7 +44,6 @@
2D9173FA09BA90380026E9FF /* FrameBuffer.hxx in Headers */ = {isa = PBXBuildFile; fileRef = 2D733D71062895B2006265D9 /* FrameBuffer.hxx */; };
2D9173FB09BA90380026E9FF /* Settings.hxx in Headers */ = {isa = PBXBuildFile; fileRef = 2D733D77062895F1006265D9 /* Settings.hxx */; };
2D91740009BA90380026E9FF /* AboutDialog.hxx in Headers */ = {isa = PBXBuildFile; fileRef = 2DDBEAA4084578BF00812C11 /* AboutDialog.hxx */; };
2D91740109BA90380026E9FF /* AudioDialog.hxx in Headers */ = {isa = PBXBuildFile; fileRef = 2DDBEAA7084578BF00812C11 /* AudioDialog.hxx */; };
2D91740209BA90380026E9FF /* BrowserDialog.hxx in Headers */ = {isa = PBXBuildFile; fileRef = 2DDBEAA9084578BF00812C11 /* BrowserDialog.hxx */; };
2D91740309BA90380026E9FF /* Command.hxx in Headers */ = {isa = PBXBuildFile; fileRef = 2DDBEAAA084578BF00812C11 /* Command.hxx */; };
2D91740409BA90380026E9FF /* Dialog.hxx in Headers */ = {isa = PBXBuildFile; fileRef = 2DDBEAAC084578BF00812C11 /* Dialog.hxx */; };
@ -61,7 +60,6 @@
2D91741209BA90380026E9FF /* ProgressDialog.hxx in Headers */ = {isa = PBXBuildFile; fileRef = 2DDBEAC9084578BF00812C11 /* ProgressDialog.hxx */; };
2D91741309BA90380026E9FF /* ScrollBarWidget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = 2DDBEACB084578BF00812C11 /* ScrollBarWidget.hxx */; };
2D91741609BA90380026E9FF /* TabWidget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = 2DDBEAD1084578BF00812C11 /* TabWidget.hxx */; };
2D91741709BA90380026E9FF /* VideoDialog.hxx in Headers */ = {isa = PBXBuildFile; fileRef = 2DDBEAD3084578BF00812C11 /* VideoDialog.hxx */; };
2D91741809BA90380026E9FF /* Widget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = 2DDBEAD5084578BF00812C11 /* Widget.hxx */; };
2D91741909BA90380026E9FF /* CartUA.hxx in Headers */ = {isa = PBXBuildFile; fileRef = 2DDBEB7108457B7D00812C11 /* CartUA.hxx */; };
2D91741A09BA90380026E9FF /* FSNode.hxx in Headers */ = {isa = PBXBuildFile; fileRef = 2DDBEB7308457B7D00812C11 /* FSNode.hxx */; };
@ -142,7 +140,6 @@
2D9174A309BA90380026E9FF /* Settings.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2D944848062904E800DD9879 /* Settings.cxx */; };
2D9174A809BA90380026E9FF /* FSNodePOSIX.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2DDBEA0C0845708800812C11 /* FSNodePOSIX.cxx */; };
2D9174AA09BA90380026E9FF /* AboutDialog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2DDBEAA3084578BF00812C11 /* AboutDialog.cxx */; };
2D9174AB09BA90380026E9FF /* AudioDialog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2DDBEAA6084578BF00812C11 /* AudioDialog.cxx */; };
2D9174AC09BA90380026E9FF /* BrowserDialog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2DDBEAA8084578BF00812C11 /* BrowserDialog.cxx */; };
2D9174AD09BA90380026E9FF /* Dialog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2DDBEAAB084578BF00812C11 /* Dialog.cxx */; };
2D9174AE09BA90380026E9FF /* DialogContainer.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2DDBEAAD084578BF00812C11 /* DialogContainer.cxx */; };
@ -157,7 +154,6 @@
2D9174B909BA90380026E9FF /* ProgressDialog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2DDBEAC8084578BF00812C11 /* ProgressDialog.cxx */; };
2D9174BA09BA90380026E9FF /* ScrollBarWidget.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2DDBEACA084578BF00812C11 /* ScrollBarWidget.cxx */; };
2D9174BB09BA90380026E9FF /* TabWidget.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2DDBEAD0084578BF00812C11 /* TabWidget.cxx */; };
2D9174BC09BA90380026E9FF /* VideoDialog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2DDBEAD2084578BF00812C11 /* VideoDialog.cxx */; };
2D9174BD09BA90380026E9FF /* Widget.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2DDBEAD4084578BF00812C11 /* Widget.cxx */; };
2D9174BE09BA90380026E9FF /* CartUA.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2DDBEB7008457B7D00812C11 /* CartUA.cxx */; };
2D9174BF09BA90380026E9FF /* FSNode.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 2DDBEB7208457B7D00812C11 /* FSNode.cxx */; };
@ -233,8 +229,6 @@
DC2410E32274BDA8007A4CBF /* MinUICommandDialog.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC2410E12274BDA7007A4CBF /* MinUICommandDialog.hxx */; };
DC2410E42274BDA8007A4CBF /* MinUICommandDialog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC2410E22274BDA8007A4CBF /* MinUICommandDialog.cxx */; };
DC2874071F8F2278004BF21A /* TrapArray.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC2874061F8F2278004BF21A /* TrapArray.hxx */; };
DC2AADAE194F389C0026C7A4 /* CartDASH.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC2AADAA194F389C0026C7A4 /* CartDASH.cxx */; };
DC2AADAF194F389C0026C7A4 /* CartDASH.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC2AADAB194F389C0026C7A4 /* CartDASH.hxx */; };
DC2AADB0194F389C0026C7A4 /* TIASurface.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC2AADAC194F389C0026C7A4 /* TIASurface.cxx */; };
DC2AADB1194F389C0026C7A4 /* TIASurface.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC2AADAD194F389C0026C7A4 /* TIASurface.hxx */; };
DC2AADB4194F390F0026C7A4 /* CartRamWidget.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC2AADB2194F390F0026C7A4 /* CartRamWidget.cxx */; };
@ -250,6 +244,18 @@
DC368F5918A2FB710084199C /* SoundSDL2.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC368F5318A2FB710084199C /* SoundSDL2.hxx */; };
DC36D2C814CAFAB0007DC821 /* CartFA2.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC36D2C614CAFAB0007DC821 /* CartFA2.cxx */; };
DC36D2C914CAFAB0007DC821 /* CartFA2.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC36D2C714CAFAB0007DC821 /* CartFA2.hxx */; };
DC3C9BC52469C8F700CF2D47 /* PaletteHandler.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC3C9BC32469C8F700CF2D47 /* PaletteHandler.cxx */; };
DC3C9BC62469C8F700CF2D47 /* PaletteHandler.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC3C9BC42469C8F700CF2D47 /* PaletteHandler.hxx */; };
DC3C9BCB2469C93D00CF2D47 /* VideoAudioDialog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC3C9BC72469C93D00CF2D47 /* VideoAudioDialog.cxx */; };
DC3C9BCC2469C93D00CF2D47 /* EmulationDialog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC3C9BC82469C93D00CF2D47 /* EmulationDialog.cxx */; };
DC3C9BCD2469C93D00CF2D47 /* VideoAudioDialog.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC3C9BC92469C93D00CF2D47 /* VideoAudioDialog.hxx */; };
DC3C9BCE2469C93D00CF2D47 /* EmulationDialog.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC3C9BCA2469C93D00CF2D47 /* EmulationDialog.hxx */; };
DC3C9BD32469C9A200CF2D47 /* CartEnhanced.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC3C9BCF2469C9A200CF2D47 /* CartEnhanced.cxx */; };
DC3C9BD42469C9A200CF2D47 /* Cart3EX.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC3C9BD02469C9A200CF2D47 /* Cart3EX.hxx */; };
DC3C9BD52469C9A200CF2D47 /* CartEnhanced.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC3C9BD12469C9A200CF2D47 /* CartEnhanced.hxx */; };
DC3C9BD62469C9A200CF2D47 /* Cart3EX.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC3C9BD22469C9A200CF2D47 /* Cart3EX.cxx */; };
DC3C9BD92469C9C700CF2D47 /* CartEnhancedWidget.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC3C9BD72469C9C700CF2D47 /* CartEnhancedWidget.cxx */; };
DC3C9BDA2469C9C700CF2D47 /* CartEnhancedWidget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC3C9BD82469C9C700CF2D47 /* CartEnhancedWidget.hxx */; };
DC3DAFAC1F2E233B00A64410 /* PointingDevice.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC3DAFAB1F2E233B00A64410 /* PointingDevice.hxx */; };
DC3EE8561E2C0E6D00905161 /* adler32.c in Sources */ = {isa = PBXBuildFile; fileRef = DC3EE83C1E2C0E6D00905161 /* adler32.c */; settings = {COMPILER_FLAGS = "-w"; }; };
DC3EE8571E2C0E6D00905161 /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = DC3EE83D1E2C0E6D00905161 /* compress.c */; settings = {COMPILER_FLAGS = "-w"; }; };
@ -393,8 +399,6 @@
DC73BD891915E5E3003FAFAD /* FBSurface.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC73BD871915E5E3003FAFAD /* FBSurface.cxx */; };
DC73BD8A1915E5E3003FAFAD /* FBSurface.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC73BD881915E5E3003FAFAD /* FBSurface.hxx */; };
DC74D6A2138D4D7E00F05C5C /* StringParser.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC74D6A0138D4D7E00F05C5C /* StringParser.hxx */; };
DC74E5C6198AF12700F37E36 /* CartDASHWidget.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC74E5C4198AF12700F37E36 /* CartDASHWidget.cxx */; };
DC74E5C7198AF12700F37E36 /* CartDASHWidget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC74E5C5198AF12700F37E36 /* CartDASHWidget.hxx */; };
DC79F81217A88D9E00288B91 /* Base.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DC79F81017A88D9E00288B91 /* Base.cxx */; };
DC79F81317A88D9E00288B91 /* Base.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC79F81117A88D9E00288B91 /* Base.hxx */; };
DC7A24D5173B1CF600B20FE9 /* Variant.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DC7A24D4173B1CF600B20FE9 /* Variant.hxx */; };
@ -494,10 +498,6 @@
DCAAE5F11715887B0080BB82 /* CartFAWidget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCAAE5D01715887B0080BB82 /* CartFAWidget.hxx */; };
DCAAE5F21715887B0080BB82 /* CartUAWidget.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCAAE5D11715887B0080BB82 /* CartUAWidget.cxx */; };
DCAAE5F31715887B0080BB82 /* CartUAWidget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCAAE5D21715887B0080BB82 /* CartUAWidget.hxx */; };
DCACBAD01C54296300703A9B /* CartCVPlusWidget.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCACBACE1C54296300703A9B /* CartCVPlusWidget.cxx */; };
DCACBAD11C54296300703A9B /* CartCVPlusWidget.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCACBACF1C54296300703A9B /* CartCVPlusWidget.hxx */; };
DCACBAD41C54298300703A9B /* CartCVPlus.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCACBAD21C54298300703A9B /* CartCVPlus.cxx */; };
DCACBAD51C54298300703A9B /* CartCVPlus.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCACBAD31C54298300703A9B /* CartCVPlus.hxx */; };
DCAD60A81152F8BD00BC4184 /* CartDPCPlus.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCAD60A61152F8BD00BC4184 /* CartDPCPlus.cxx */; };
DCAD60A91152F8BD00BC4184 /* CartDPCPlus.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCAD60A71152F8BD00BC4184 /* CartDPCPlus.hxx */; };
DCB20EC71A0C506C0048F595 /* main.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCB20EC61A0C506C0048F595 /* main.cxx */; };
@ -828,8 +828,6 @@
2DDBEA0C0845708800812C11 /* FSNodePOSIX.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FSNodePOSIX.cxx; sourceTree = "<group>"; };
2DDBEAA3084578BF00812C11 /* AboutDialog.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AboutDialog.cxx; sourceTree = "<group>"; };
2DDBEAA4084578BF00812C11 /* AboutDialog.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = AboutDialog.hxx; sourceTree = "<group>"; };
2DDBEAA6084578BF00812C11 /* AudioDialog.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AudioDialog.cxx; sourceTree = "<group>"; };
2DDBEAA7084578BF00812C11 /* AudioDialog.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = AudioDialog.hxx; sourceTree = "<group>"; };
2DDBEAA8084578BF00812C11 /* BrowserDialog.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BrowserDialog.cxx; sourceTree = "<group>"; };
2DDBEAA9084578BF00812C11 /* BrowserDialog.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = BrowserDialog.hxx; sourceTree = "<group>"; };
2DDBEAAA084578BF00812C11 /* Command.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = Command.hxx; sourceTree = "<group>"; };
@ -860,8 +858,6 @@
2DDBEACB084578BF00812C11 /* ScrollBarWidget.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = ScrollBarWidget.hxx; sourceTree = "<group>"; };
2DDBEAD0084578BF00812C11 /* TabWidget.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TabWidget.cxx; sourceTree = "<group>"; };
2DDBEAD1084578BF00812C11 /* TabWidget.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = TabWidget.hxx; sourceTree = "<group>"; };
2DDBEAD2084578BF00812C11 /* VideoDialog.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = VideoDialog.cxx; sourceTree = "<group>"; };
2DDBEAD3084578BF00812C11 /* VideoDialog.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = VideoDialog.hxx; sourceTree = "<group>"; };
2DDBEAD4084578BF00812C11 /* Widget.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Widget.cxx; sourceTree = "<group>"; };
2DDBEAD5084578BF00812C11 /* Widget.hxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = Widget.hxx; sourceTree = "<group>"; };
2DDBEB7008457B7D00812C11 /* CartUA.cxx */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CartUA.cxx; sourceTree = "<group>"; };
@ -972,8 +968,6 @@
DC2410E12274BDA7007A4CBF /* MinUICommandDialog.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MinUICommandDialog.hxx; sourceTree = "<group>"; };
DC2410E22274BDA8007A4CBF /* MinUICommandDialog.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MinUICommandDialog.cxx; sourceTree = "<group>"; };
DC2874061F8F2278004BF21A /* TrapArray.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TrapArray.hxx; sourceTree = "<group>"; };
DC2AADAA194F389C0026C7A4 /* CartDASH.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartDASH.cxx; sourceTree = "<group>"; };
DC2AADAB194F389C0026C7A4 /* CartDASH.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartDASH.hxx; sourceTree = "<group>"; };
DC2AADAC194F389C0026C7A4 /* TIASurface.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TIASurface.cxx; sourceTree = "<group>"; };
DC2AADAD194F389C0026C7A4 /* TIASurface.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TIASurface.hxx; sourceTree = "<group>"; };
DC2AADB2194F390F0026C7A4 /* CartRamWidget.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartRamWidget.cxx; sourceTree = "<group>"; };
@ -989,6 +983,18 @@
DC368F5318A2FB710084199C /* SoundSDL2.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SoundSDL2.hxx; sourceTree = "<group>"; };
DC36D2C614CAFAB0007DC821 /* CartFA2.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartFA2.cxx; sourceTree = "<group>"; };
DC36D2C714CAFAB0007DC821 /* CartFA2.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartFA2.hxx; sourceTree = "<group>"; };
DC3C9BC32469C8F700CF2D47 /* PaletteHandler.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PaletteHandler.cxx; sourceTree = "<group>"; };
DC3C9BC42469C8F700CF2D47 /* PaletteHandler.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = PaletteHandler.hxx; sourceTree = "<group>"; };
DC3C9BC72469C93D00CF2D47 /* VideoAudioDialog.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VideoAudioDialog.cxx; sourceTree = "<group>"; };
DC3C9BC82469C93D00CF2D47 /* EmulationDialog.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EmulationDialog.cxx; sourceTree = "<group>"; };
DC3C9BC92469C93D00CF2D47 /* VideoAudioDialog.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = VideoAudioDialog.hxx; sourceTree = "<group>"; };
DC3C9BCA2469C93D00CF2D47 /* EmulationDialog.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = EmulationDialog.hxx; sourceTree = "<group>"; };
DC3C9BCF2469C9A200CF2D47 /* CartEnhanced.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartEnhanced.cxx; sourceTree = "<group>"; };
DC3C9BD02469C9A200CF2D47 /* Cart3EX.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Cart3EX.hxx; sourceTree = "<group>"; };
DC3C9BD12469C9A200CF2D47 /* CartEnhanced.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartEnhanced.hxx; sourceTree = "<group>"; };
DC3C9BD22469C9A200CF2D47 /* Cart3EX.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cart3EX.cxx; sourceTree = "<group>"; };
DC3C9BD72469C9C700CF2D47 /* CartEnhancedWidget.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartEnhancedWidget.cxx; sourceTree = "<group>"; };
DC3C9BD82469C9C700CF2D47 /* CartEnhancedWidget.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartEnhancedWidget.hxx; sourceTree = "<group>"; };
DC3DAFAB1F2E233B00A64410 /* PointingDevice.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = PointingDevice.hxx; sourceTree = "<group>"; };
DC3EE83C1E2C0E6D00905161 /* adler32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = adler32.c; sourceTree = "<group>"; };
DC3EE83D1E2C0E6D00905161 /* compress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = compress.c; sourceTree = "<group>"; };
@ -1132,8 +1138,6 @@
DC73BD871915E5E3003FAFAD /* FBSurface.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FBSurface.cxx; sourceTree = "<group>"; };
DC73BD881915E5E3003FAFAD /* FBSurface.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FBSurface.hxx; sourceTree = "<group>"; };
DC74D6A0138D4D7E00F05C5C /* StringParser.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = StringParser.hxx; sourceTree = "<group>"; };
DC74E5C4198AF12700F37E36 /* CartDASHWidget.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartDASHWidget.cxx; sourceTree = "<group>"; };
DC74E5C5198AF12700F37E36 /* CartDASHWidget.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartDASHWidget.hxx; sourceTree = "<group>"; };
DC79F81017A88D9E00288B91 /* Base.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Base.cxx; sourceTree = "<group>"; };
DC79F81117A88D9E00288B91 /* Base.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Base.hxx; sourceTree = "<group>"; };
DC7A24D4173B1CF600B20FE9 /* Variant.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Variant.hxx; sourceTree = "<group>"; };
@ -1234,10 +1238,6 @@
DCAAE5D01715887B0080BB82 /* CartFAWidget.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartFAWidget.hxx; sourceTree = "<group>"; };
DCAAE5D11715887B0080BB82 /* CartUAWidget.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartUAWidget.cxx; sourceTree = "<group>"; };
DCAAE5D21715887B0080BB82 /* CartUAWidget.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartUAWidget.hxx; sourceTree = "<group>"; };
DCACBACE1C54296300703A9B /* CartCVPlusWidget.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartCVPlusWidget.cxx; sourceTree = "<group>"; };
DCACBACF1C54296300703A9B /* CartCVPlusWidget.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartCVPlusWidget.hxx; sourceTree = "<group>"; };
DCACBAD21C54298300703A9B /* CartCVPlus.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartCVPlus.cxx; sourceTree = "<group>"; };
DCACBAD31C54298300703A9B /* CartCVPlus.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartCVPlus.hxx; sourceTree = "<group>"; };
DCAD60A61152F8BD00BC4184 /* CartDPCPlus.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CartDPCPlus.cxx; sourceTree = "<group>"; };
DCAD60A71152F8BD00BC4184 /* CartDPCPlus.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CartDPCPlus.hxx; sourceTree = "<group>"; };
DCB20EC61A0C506C0048F595 /* main.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cxx; sourceTree = "<group>"; };
@ -1589,12 +1589,8 @@
DC676A2C1729A0B000E4E73D /* CartCMWidget.hxx */,
DC676A2D1729A0B000E4E73D /* CartCTYWidget.cxx */,
DC676A2E1729A0B000E4E73D /* CartCTYWidget.hxx */,
DCACBACE1C54296300703A9B /* CartCVPlusWidget.cxx */,
DCACBACF1C54296300703A9B /* CartCVPlusWidget.hxx */,
DCAAE5BA1715887B0080BB82 /* CartCVWidget.cxx */,
DCAAE5BB1715887B0080BB82 /* CartCVWidget.hxx */,
DC74E5C4198AF12700F37E36 /* CartDASHWidget.cxx */,
DC74E5C5198AF12700F37E36 /* CartDASHWidget.hxx */,
DC5ACB5D1FBFCEB800A213FD /* CartDebugWidget.cxx */,
DCAAE5BC1715887B0080BB82 /* CartDebugWidget.hxx */,
DCAACB0A188D636F00A4D282 /* CartDFSCWidget.cxx */,
@ -1615,6 +1611,8 @@
DCAAE5BE1715887B0080BB82 /* CartEFSCWidget.hxx */,
DCAAE5BF1715887B0080BB82 /* CartEFWidget.cxx */,
DCAAE5C01715887B0080BB82 /* CartEFWidget.hxx */,
DC3C9BD72469C9C700CF2D47 /* CartEnhancedWidget.cxx */,
DC3C9BD82469C9C700CF2D47 /* CartEnhancedWidget.hxx */,
DCAAE5C11715887B0080BB82 /* CartF0Widget.cxx */,
DCAAE5C21715887B0080BB82 /* CartF0Widget.hxx */,
DCAAE5C31715887B0080BB82 /* CartF4SCWidget.cxx */,
@ -1744,6 +1742,8 @@
DCB87E571A104C1E00BF2A3B /* MediaFactory.hxx */,
DC56FCDC14CCCC4900A31CC3 /* MouseControl.cxx */,
DC56FCDD14CCCC4900A31CC3 /* MouseControl.hxx */,
DC3C9BC32469C8F700CF2D47 /* PaletteHandler.cxx */,
DC3C9BC42469C8F700CF2D47 /* PaletteHandler.hxx */,
DCA233AE23B583FE0032ABF3 /* PhosphorHandler.cxx */,
DCA233AF23B583FE0032ABF3 /* PhosphorHandler.hxx */,
DC6DC91A205DB879004A5FC3 /* PhysicalJoystick.cxx */,
@ -1824,6 +1824,8 @@
2D9555DA0880E78000466554 /* Cart3E.hxx */,
DCBDDE9C1D6A5F2F009DF1E9 /* Cart3EPlus.cxx */,
DCBDDE9D1D6A5F2F009DF1E9 /* Cart3EPlus.hxx */,
DC3C9BD22469C9A200CF2D47 /* Cart3EX.cxx */,
DC3C9BD02469C9A200CF2D47 /* Cart3EX.hxx */,
2DE2DF160627AE07006BEC99 /* Cart3F.cxx */,
2DE2DF170627AE07006BEC99 /* Cart3F.hxx */,
DCD56D360B247D920092F9F8 /* Cart4A50.cxx */,
@ -1850,10 +1852,6 @@
DC6727091556F4860023653B /* CartCTY.hxx */,
2DE2DF1C0627AE07006BEC99 /* CartCV.cxx */,
2DE2DF1D0627AE07006BEC99 /* CartCV.hxx */,
DCACBAD21C54298300703A9B /* CartCVPlus.cxx */,
DCACBAD31C54298300703A9B /* CartCVPlus.hxx */,
DC2AADAA194F389C0026C7A4 /* CartDASH.cxx */,
DC2AADAB194F389C0026C7A4 /* CartDASH.hxx */,
DCB2ECAC1F0AECA3009738A6 /* CartDetector.cxx */,
DCB2ECAD1F0AECA3009738A6 /* CartDetector.hxx */,
DCAACAF2188D631500A4D282 /* CartDF.cxx */,
@ -1874,6 +1872,8 @@
DCF467BF0F939A1400B25D7A /* CartEF.hxx */,
DCF467C00F939A1400B25D7A /* CartEFSC.cxx */,
DCF467C10F939A1400B25D7A /* CartEFSC.hxx */,
DC3C9BCF2469C9A200CF2D47 /* CartEnhanced.cxx */,
DC3C9BD12469C9A200CF2D47 /* CartEnhanced.hxx */,
DCF7B0D910A762FC007A2870 /* CartF0.cxx */,
DCF7B0DA10A762FC007A2870 /* CartF0.hxx */,
2DE2DF240627AE07006BEC99 /* CartF4.cxx */,
@ -2003,8 +2003,6 @@
children = (
2DDBEAA3084578BF00812C11 /* AboutDialog.cxx */,
2DDBEAA4084578BF00812C11 /* AboutDialog.hxx */,
2DDBEAA6084578BF00812C11 /* AudioDialog.cxx */,
2DDBEAA7084578BF00812C11 /* AudioDialog.hxx */,
2DDBEAA8084578BF00812C11 /* BrowserDialog.cxx */,
2DDBEAA9084578BF00812C11 /* BrowserDialog.hxx */,
2DEF21F808BC033500B246B4 /* CheckListWidget.cxx */,
@ -2034,6 +2032,8 @@
2D403BA1086116D1001E31A1 /* EditableWidget.hxx */,
2D403BA4086116D1001E31A1 /* EditTextWidget.cxx */,
2D403BA5086116D1001E31A1 /* EditTextWidget.hxx */,
DC3C9BC82469C93D00CF2D47 /* EmulationDialog.cxx */,
DC3C9BCA2469C93D00CF2D47 /* EmulationDialog.hxx */,
2D05FF5E096E269100A518FE /* EventMappingWidget.cxx */,
2D05FF5F096E269100A518FE /* EventMappingWidget.hxx */,
DC7A24DD173B1DBC00B20FE9 /* FileListWidget.cxx */,
@ -2107,8 +2107,8 @@
DCA82C701FEB4E780059340F /* TimeMachineDialog.hxx */,
DC8078E60B4BD697005E9305 /* UIDialog.cxx */,
DC8078E70B4BD697005E9305 /* UIDialog.hxx */,
2DDBEAD2084578BF00812C11 /* VideoDialog.cxx */,
2DDBEAD3084578BF00812C11 /* VideoDialog.hxx */,
DC3C9BC72469C93D00CF2D47 /* VideoAudioDialog.cxx */,
DC3C9BC92469C93D00CF2D47 /* VideoAudioDialog.hxx */,
2DDBEAD4084578BF00812C11 /* Widget.cxx */,
2DDBEAD5084578BF00812C11 /* Widget.hxx */,
);
@ -2391,10 +2391,9 @@
DC5AAC2D1FCB24DF00C420A6 /* RadioButtonWidget.hxx in Headers */,
2D9173E309BA90380026E9FF /* Driving.hxx in Headers */,
2D9173E409BA90380026E9FF /* Event.hxx in Headers */,
DC3C9BCD2469C93D00CF2D47 /* VideoAudioDialog.hxx in Headers */,
2D9173E509BA90380026E9FF /* Joystick.hxx in Headers */,
2D9173E609BA90380026E9FF /* Keyboard.hxx in Headers */,
DCACBAD51C54298300703A9B /* CartCVPlus.hxx in Headers */,
DCACBAD11C54296300703A9B /* CartCVPlusWidget.hxx in Headers */,
DC1B2EC81E50036100F62837 /* TrakBall.hxx in Headers */,
2D9173E709BA90380026E9FF /* M6532.hxx in Headers */,
E0893AF3211B9842008B170D /* HighPass.hxx in Headers */,
@ -2417,7 +2416,7 @@
DCF3A6EE1DFC75E3008A8AF3 /* DelayQueueMember.hxx in Headers */,
DC96162F1F817830008A2206 /* AtariMouseWidget.hxx in Headers */,
DCF4907A1A0ECE5B00A67AA9 /* Vec.hxx in Headers */,
2D91740109BA90380026E9FF /* AudioDialog.hxx in Headers */,
DC3C9BCE2469C93D00CF2D47 /* EmulationDialog.hxx in Headers */,
DC71EA9E1FDA06D2008827CB /* CartE78K.hxx in Headers */,
2D91740209BA90380026E9FF /* BrowserDialog.hxx in Headers */,
2D91740309BA90380026E9FF /* Command.hxx in Headers */,
@ -2446,7 +2445,6 @@
2D91741309BA90380026E9FF /* ScrollBarWidget.hxx in Headers */,
2D91741609BA90380026E9FF /* TabWidget.hxx in Headers */,
DCB2ECB01F0AECA3009738A6 /* CartDetector.hxx in Headers */,
2D91741709BA90380026E9FF /* VideoDialog.hxx in Headers */,
2D91741809BA90380026E9FF /* Widget.hxx in Headers */,
2D91741909BA90380026E9FF /* CartUA.hxx in Headers */,
DCE8B1871E7E03B300189864 /* FrameLayout.hxx in Headers */,
@ -2476,6 +2474,7 @@
DC3EE86C1E2C0E6D00905161 /* zconf.h in Headers */,
2D91743609BA90380026E9FF /* DebuggerSystem.hxx in Headers */,
2D91743A09BA90380026E9FF /* Expression.hxx in Headers */,
DC3C9BDA2469C9C700CF2D47 /* CartEnhancedWidget.hxx in Headers */,
2D91744F09BA90380026E9FF /* InputTextDialog.hxx in Headers */,
DC1B2EC61E50036100F62837 /* AtariMouse.hxx in Headers */,
DC9616331F817830008A2206 /* PointingDeviceWidget.hxx in Headers */,
@ -2502,7 +2501,7 @@
DCA078351F8C1B04008EFEE5 /* SDL_lib.hxx in Headers */,
DCDA03B11A2009BB00711920 /* CartWD.hxx in Headers */,
2D91745909BA90380026E9FF /* PromptWidget.hxx in Headers */,
DC2AADAF194F389C0026C7A4 /* CartDASH.hxx in Headers */,
DC3C9BC62469C8F700CF2D47 /* PaletteHandler.hxx in Headers */,
2D91745A09BA90380026E9FF /* RamWidget.hxx in Headers */,
2D91745B09BA90380026E9FF /* RomListWidget.hxx in Headers */,
2D91745C09BA90380026E9FF /* RomWidget.hxx in Headers */,
@ -2513,6 +2512,7 @@
2D91746109BA90380026E9FF /* TogglePixelWidget.hxx in Headers */,
2D91746209BA90380026E9FF /* ToggleWidget.hxx in Headers */,
2D91746409BA90380026E9FF /* TiaZoomWidget.hxx in Headers */,
DC3C9BD52469C9A200CF2D47 /* CartEnhanced.hxx in Headers */,
DC1BC6672066B4390076F74A /* PKeyboardHandler.hxx in Headers */,
2D91746609BA90380026E9FF /* AudioWidget.hxx in Headers */,
DC70065E241EC97900A459AB /* Stella14x28tFont.hxx in Headers */,
@ -2593,7 +2593,6 @@
DCD6FC7111C281ED005DA767 /* png.h in Headers */,
DCD6FC7211C281ED005DA767 /* pngconf.h in Headers */,
DCF3A6F41DFC75E3008A8AF3 /* LatchedInput.hxx in Headers */,
DC74E5C7198AF12700F37E36 /* CartDASHWidget.hxx in Headers */,
DCD6FC7711C281ED005DA767 /* pngpriv.h in Headers */,
CFE3F60C1E84A9A200A8204E /* CartBUSWidget.hxx in Headers */,
DCD6FC9411C28C6F005DA767 /* PNGLibrary.hxx in Headers */,
@ -2637,6 +2636,7 @@
DCE395EF16CB0B5F008DB1E5 /* FSNodeFactory.hxx in Headers */,
DCE395F116CB0B5F008DB1E5 /* FSNodeZIP.hxx in Headers */,
DCE395F316CB0B5F008DB1E5 /* ZipHandler.hxx in Headers */,
DC3C9BD42469C9A200CF2D47 /* Cart3EX.hxx in Headers */,
DCAAE5D41715887B0080BB82 /* Cart2KWidget.hxx in Headers */,
DCF7F129223D796000701A47 /* ProfilingRunner.hxx in Headers */,
DCAAE5D61715887B0080BB82 /* Cart3FWidget.hxx in Headers */,
@ -2816,7 +2816,9 @@
E0A755792244294600101889 /* CartCDFInfoWidget.cxx in Sources */,
E0406FB81F81A85400A82AE0 /* FrameManager.cxx in Sources */,
2D91747409BA90380026E9FF /* SDLMain.m in Sources */,
DC3C9BC52469C8F700CF2D47 /* PaletteHandler.cxx in Sources */,
2D91747509BA90380026E9FF /* Booster.cxx in Sources */,
DC3C9BD62469C9A200CF2D47 /* Cart3EX.cxx in Sources */,
DC3EE8671E2C0E6D00905161 /* inftrees.c in Sources */,
2D91747609BA90380026E9FF /* Cart.cxx in Sources */,
2D91747709BA90380026E9FF /* Cart2K.cxx in Sources */,
@ -2844,6 +2846,7 @@
DCF3A6FA1DFC75E3008A8AF3 /* Player.cxx in Sources */,
2D91748609BA90380026E9FF /* CartFE.cxx in Sources */,
2D91748909BA90380026E9FF /* Console.cxx in Sources */,
DC3C9BD32469C9A200CF2D47 /* CartEnhanced.cxx in Sources */,
DC6DC91E205DB879004A5FC3 /* PhysicalJoystick.cxx in Sources */,
E08FCD5323A037EB0051F59B /* QisBlitter.cxx in Sources */,
DCCE0355225104BF008C246F /* StellaSettingsDialog.cxx in Sources */,
@ -2867,7 +2870,6 @@
2D9174A309BA90380026E9FF /* Settings.cxx in Sources */,
2D9174A809BA90380026E9FF /* FSNodePOSIX.cxx in Sources */,
2D9174AA09BA90380026E9FF /* AboutDialog.cxx in Sources */,
2D9174AB09BA90380026E9FF /* AudioDialog.cxx in Sources */,
2D9174AC09BA90380026E9FF /* BrowserDialog.cxx in Sources */,
2D9174AD09BA90380026E9FF /* Dialog.cxx in Sources */,
2D9174AE09BA90380026E9FF /* DialogContainer.cxx in Sources */,
@ -2877,6 +2879,7 @@
2D9174B309BA90380026E9FF /* LauncherDialog.cxx in Sources */,
2D9174B509BA90380026E9FF /* ListWidget.cxx in Sources */,
2D9174B609BA90380026E9FF /* Menu.cxx in Sources */,
DC3C9BD92469C9C700CF2D47 /* CartEnhancedWidget.cxx in Sources */,
CFE3F60D1E84A9A200A8204E /* CartCDFWidget.cxx in Sources */,
2D9174B709BA90380026E9FF /* OptionsDialog.cxx in Sources */,
2D9174B809BA90380026E9FF /* PopUpWidget.cxx in Sources */,
@ -2886,7 +2889,6 @@
2D9174B909BA90380026E9FF /* ProgressDialog.cxx in Sources */,
2D9174BA09BA90380026E9FF /* ScrollBarWidget.cxx in Sources */,
2D9174BB09BA90380026E9FF /* TabWidget.cxx in Sources */,
2D9174BC09BA90380026E9FF /* VideoDialog.cxx in Sources */,
DC6A18FC19B3E67A00DEB242 /* CartMDM.cxx in Sources */,
2D9174BD09BA90380026E9FF /* Widget.cxx in Sources */,
2D9174BE09BA90380026E9FF /* CartUA.cxx in Sources */,
@ -2914,7 +2916,6 @@
2D9174F109BA90380026E9FF /* InputTextDialog.cxx in Sources */,
DC6DC920205DB879004A5FC3 /* PJoystickHandler.cxx in Sources */,
DC2410E42274BDA8007A4CBF /* MinUICommandDialog.cxx in Sources */,
DC74E5C6198AF12700F37E36 /* CartDASHWidget.cxx in Sources */,
2D9174F209BA90380026E9FF /* CheckListWidget.cxx in Sources */,
2D9174F309BA90380026E9FF /* StringListWidget.cxx in Sources */,
2D9174F409BA90380026E9FF /* CommandDialog.cxx in Sources */,
@ -2931,7 +2932,6 @@
DC5963132139FA14002736F2 /* Bankswitch.cxx in Sources */,
DCDFF08120B781B0001227C0 /* DispatchResult.cxx in Sources */,
2D9174FC09BA90380026E9FF /* RamWidget.cxx in Sources */,
DC2AADAE194F389C0026C7A4 /* CartDASH.cxx in Sources */,
DC21E5C121CA903E007D0E1A /* SerialPortMACOS.cxx in Sources */,
E007231F210FBF5E002CF343 /* FpsMeter.cxx in Sources */,
2D9174FD09BA90380026E9FF /* RomListWidget.cxx in Sources */,
@ -2960,7 +2960,6 @@
DC47455A09C34BFA00EDDA3A /* CheatManager.cxx in Sources */,
DC47455C09C34BFA00EDDA3A /* CheetahCheat.cxx in Sources */,
DC62E6471960E87B007AEF05 /* AtariVoxWidget.cxx in Sources */,
DCACBAD41C54298300703A9B /* CartCVPlus.cxx in Sources */,
DC47455E09C34BFA00EDDA3A /* RamCheat.cxx in Sources */,
E0FABEEC20E9948200EB8E28 /* AudioSettings.cxx in Sources */,
DCD56D380B247D920092F9F8 /* Cart4A50.cxx in Sources */,
@ -3003,6 +3002,7 @@
DC6B2BA411037FF200F199A7 /* CartDebug.cxx in Sources */,
DCB20EC71A0C506C0048F595 /* main.cxx in Sources */,
DC6B2BA611037FF200F199A7 /* DiStella.cxx in Sources */,
DC3C9BCB2469C93D00CF2D47 /* VideoAudioDialog.cxx in Sources */,
CFE3F6151E84A9CE00A8204E /* CartCDF.cxx in Sources */,
E08D2F3E23089B9B000BD709 /* JoyMap.cxx in Sources */,
DCA82C711FEB4E780059340F /* TimeMachine.cxx in Sources */,
@ -3103,6 +3103,7 @@
DC676A531729A0B000E4E73D /* CartFA2Widget.cxx in Sources */,
DC676A551729A0B000E4E73D /* CartFEWidget.cxx in Sources */,
DC676A591729A0B000E4E73D /* CartSBWidget.cxx in Sources */,
DC3C9BCC2469C93D00CF2D47 /* EmulationDialog.cxx in Sources */,
DC676A5B1729A0B000E4E73D /* CartX07Widget.cxx in Sources */,
DC7A24DF173B1DBC00B20FE9 /* FileListWidget.cxx in Sources */,
DC13B53F176FF2F500B8B4BB /* RomListSettings.cxx in Sources */,
@ -3116,7 +3117,6 @@
DCAACAFC188D631500A4D282 /* CartDF.cxx in Sources */,
DCAACAFE188D631500A4D282 /* CartDFSC.cxx in Sources */,
DCAACB0E188D636F00A4D282 /* Cart4KSCWidget.cxx in Sources */,
DCACBAD01C54296300703A9B /* CartCVPlusWidget.cxx in Sources */,
DCAACB10188D636F00A4D282 /* CartBFSCWidget.cxx in Sources */,
DCAACB12188D636F00A4D282 /* CartBFWidget.cxx in Sources */,
DCAACB14188D636F00A4D282 /* CartDFSCWidget.cxx in Sources */,

View File

@ -503,6 +503,7 @@
<ClCompile Include="..\common\Logger.cxx" />
<ClCompile Include="..\common\main.cxx" />
<ClCompile Include="..\common\MouseControl.cxx" />
<ClCompile Include="..\common\PaletteHandler.cxx" />
<ClCompile Include="..\common\PhosphorHandler.cxx" />
<ClCompile Include="..\common\PhysicalJoystick.cxx" />
<ClCompile Include="..\common\PJoystickHandler.cxx" />
@ -757,6 +758,7 @@
<ClCompile Include="..\emucore\tia\TIA.cxx" />
<ClCompile Include="..\gui\ColorWidget.cxx" />
<ClCompile Include="..\gui\DeveloperDialog.cxx" />
<ClCompile Include="..\gui\EmulationDialog.cxx" />
<ClCompile Include="..\gui\FileListWidget.cxx" />
<ClCompile Include="..\gui\JoystickDialog.cxx" />
<ClCompile Include="..\gui\LoggerDialog.cxx" />
@ -906,7 +908,6 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-NoDebugger|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\gui\AboutDialog.cxx" />
<ClCompile Include="..\gui\AudioDialog.cxx" />
<ClCompile Include="..\gui\BrowserDialog.cxx" />
<ClCompile Include="..\gui\CheckListWidget.cxx" />
<ClCompile Include="..\gui\ComboDialog.cxx" />
@ -938,7 +939,7 @@
<ClCompile Include="..\gui\StringListWidget.cxx" />
<ClCompile Include="..\gui\TabWidget.cxx" />
<ClCompile Include="..\gui\UIDialog.cxx" />
<ClCompile Include="..\gui\VideoDialog.cxx" />
<ClCompile Include="..\gui\VideoAudioDialog.cxx" />
<ClCompile Include="..\gui\Widget.cxx" />
<ClCompile Include="..\zlib\adler32.c">
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsC</CompileAs>
@ -1503,6 +1504,7 @@
<ClInclude Include="..\common\Logger.hxx" />
<ClInclude Include="..\common\MediaFactory.hxx" />
<ClInclude Include="..\common\MouseControl.hxx" />
<ClInclude Include="..\common\PaletteHandler.hxx" />
<ClInclude Include="..\common\PhosphorHandler.hxx" />
<ClInclude Include="..\common\PhysicalJoystick.hxx" />
<ClInclude Include="..\common\PJoystickHandler.hxx" />
@ -1789,6 +1791,7 @@
<ClInclude Include="..\gui\ConsoleMediumBFont.hxx" />
<ClInclude Include="..\gui\ConsoleMediumFont.hxx" />
<ClInclude Include="..\gui\DeveloperDialog.hxx" />
<ClInclude Include="..\gui\EmulationDialog.hxx" />
<ClInclude Include="..\gui\FileListWidget.hxx" />
<ClInclude Include="..\gui\JoystickDialog.hxx" />
<ClInclude Include="..\gui\LoggerDialog.hxx" />
@ -1965,7 +1968,6 @@
<ClInclude Include="..\cheat\CheetahCheat.hxx" />
<ClInclude Include="..\cheat\RamCheat.hxx" />
<ClInclude Include="..\gui\AboutDialog.hxx" />
<ClInclude Include="..\gui\AudioDialog.hxx" />
<ClInclude Include="..\gui\BrowserDialog.hxx" />
<ClInclude Include="..\gui\CheckListWidget.hxx" />
<ClInclude Include="..\gui\ComboDialog.hxx" />
@ -2001,7 +2003,7 @@
<ClInclude Include="..\gui\StringListWidget.hxx" />
<ClInclude Include="..\gui\TabWidget.hxx" />
<ClInclude Include="..\gui\UIDialog.hxx" />
<ClInclude Include="..\gui\VideoDialog.hxx" />
<ClInclude Include="..\gui\VideoAudioDialog.hxx" />
<ClInclude Include="..\gui\Widget.hxx" />
<ClInclude Include="..\zlib\crc32.h" />
<ClInclude Include="..\zlib\deflate.h" />

View File

@ -342,9 +342,6 @@
<ClCompile Include="..\gui\AboutDialog.cxx">
<Filter>Source Files\gui</Filter>
</ClCompile>
<ClCompile Include="..\gui\AudioDialog.cxx">
<Filter>Source Files\gui</Filter>
</ClCompile>
<ClCompile Include="..\gui\BrowserDialog.cxx">
<Filter>Source Files\gui</Filter>
</ClCompile>
@ -438,9 +435,6 @@
<ClCompile Include="..\gui\UIDialog.cxx">
<Filter>Source Files\gui</Filter>
</ClCompile>
<ClCompile Include="..\gui\VideoDialog.cxx">
<Filter>Source Files\gui</Filter>
</ClCompile>
<ClCompile Include="..\gui\Widget.cxx">
<Filter>Source Files\gui</Filter>
</ClCompile>
@ -1002,6 +996,15 @@
<ClCompile Include="..\emucore\Cart3EX.cxx">
<Filter>Source Files\emucore</Filter>
</ClCompile>
<ClCompile Include="..\common\PaletteHandler.cxx">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\gui\EmulationDialog.cxx">
<Filter>Source Files\gui</Filter>
</ClCompile>
<ClCompile Include="..\gui\VideoAudioDialog.cxx">
<Filter>Source Files\gui</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\common\bspf.hxx">
@ -1313,9 +1316,6 @@
<ClInclude Include="..\gui\AboutDialog.hxx">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\gui\AudioDialog.hxx">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\gui\BrowserDialog.hxx">
<Filter>Header Files\gui</Filter>
</ClInclude>
@ -1421,9 +1421,6 @@
<ClInclude Include="..\gui\UIDialog.hxx">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\gui\VideoDialog.hxx">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\gui\Widget.hxx">
<Filter>Header Files\gui</Filter>
</ClInclude>
@ -2057,6 +2054,15 @@
<ClInclude Include="..\emucore\Cart3EX.hxx">
<Filter>Header Files\emucore</Filter>
</ClInclude>
<ClInclude Include="..\common\PaletteHandler.hxx">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\gui\EmulationDialog.hxx">
<Filter>Header Files\gui</Filter>
</ClInclude>
<ClInclude Include="..\gui\VideoAudioDialog.hxx">
<Filter>Header Files\gui</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="stella.ico">