stella/src/common/PaletteHandler.hxx

261 lines
7.5 KiB
C++

//============================================================================
//
// 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"
#include "EventHandlerConstants.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;
enum Adjustables {
PHASE_SHIFT,
HUE,
SATURATION,
CONTRAST,
BRIGHTNESS,
GAMMA
};
// 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);
/**
Cycle through available palettes.
@param direction +1 indicates increase, -1 indicates decrease.
*/
void cyclePalette(int direction = +1);
/*
Cycle through each palette adjustable.
@param direction +1 indicates increase, -1 indicates decrease.
*/
void cycleAdjustable(int direction = +1);
/*
Increase or decrease given palette adjustable.
@param adjustable The adjustable to change
@param direction +1 indicates increase, -1 indicates decrease.
*/
void changeAdjustable(int adjustable, int direction);
/*
Increase or decrease current palette adjustable.
@param direction +1 indicates increase, -1 indicates decrease.
*/
void changeCurrentAdjustable(int direction = +1);
// 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
*/
static constexpr float scaleFrom100(float x) { return (x / 50.F) - 1.F; }
static constexpr uInt32 scaleTo100(float x) { return uInt32(50.0001F * (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;
/**
Display current adjustable with gauge bar message
*/
void showAdjustableMessage();
/**
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 = +1);
/**
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