mirror of https://github.com/stella-emu/stella.git
add namespace for HighScoresManager
omit default property parameters
This commit is contained in:
parent
08b04f4695
commit
e849da3be1
|
@ -23,9 +23,9 @@
|
|||
B, ; variation format (BCD, HEX)
|
||||
0, ; zero-based variation
|
||||
Addresses (in hex):
|
||||
n*p-times xx, ; score addresses for each player, high to low
|
||||
n*p-times xx, ; score info for each player, high to low
|
||||
xx, ; variation address (if more than 1 variation)
|
||||
xx, ; player address (if more than 1 player)
|
||||
xx ; player address (if more than 1 player)
|
||||
|
||||
TODO:
|
||||
- variation bits (Centipede)
|
||||
|
@ -41,6 +41,10 @@
|
|||
|
||||
#include "HighScoresManager.hxx"
|
||||
|
||||
using namespace BSPF;
|
||||
using namespace std;
|
||||
using namespace HSM;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
HighScoresManager::HighScoresManager(OSystem& osystem)
|
||||
: myOSystem(osystem)
|
||||
|
@ -79,8 +83,8 @@ string HighScoresManager::getPropIdx(const Properties& props, PropType type, uIn
|
|||
{
|
||||
string property = props.get(type);
|
||||
|
||||
std::replace(property.begin(), property.end(), ',', ' ');
|
||||
std::replace(property.begin(), property.end(), '|', ' ');
|
||||
replace(property.begin(), property.end(), ',', ' ');
|
||||
replace(property.begin(), property.end(), '|', ' ');
|
||||
istringstream buf(property);
|
||||
string result;
|
||||
|
||||
|
@ -96,8 +100,7 @@ uInt32 HighScoresManager::numPlayers(const Properties& props) const
|
|||
{
|
||||
string numPlayers = getPropIdx(props, PropType::Cart_Players);
|
||||
|
||||
return numPlayers == EmptyString ?
|
||||
DEFAULT_PLAYER : std::min(uInt32(stoi(numPlayers)), MAX_PLAYERS);
|
||||
return min(uInt32(stringToInt(numPlayers, DEFAULT_PLAYER)), MAX_PLAYERS);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -105,25 +108,24 @@ uInt32 HighScoresManager::numVariations(const Properties& props) const
|
|||
{
|
||||
string numVariations = getPropIdx(props, PropType::Cart_Variations);
|
||||
|
||||
return numVariations == EmptyString ?
|
||||
DEFAULT_VARIATION : std::min(uInt32(stoi(numVariations)), MAX_VARIATIONS);
|
||||
return min(uInt32(stringToInt(numVariations, DEFAULT_VARIATION)), MAX_VARIATIONS);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool HighScoresManager::get(const Properties& props, uInt32& numPlayersR, uInt32& numVariationsR,
|
||||
Formats& formats, Addresses& addresses) const
|
||||
ScoresInfo& info) const
|
||||
{
|
||||
numPlayersR = numPlayers(props);
|
||||
numVariationsR = numVariations(props);
|
||||
|
||||
formats.numDigits = numDigits(props);
|
||||
formats.trailingZeroes = trailingZeroes(props);
|
||||
formats.scoreBCD = scoreBCD(props);
|
||||
formats.varsBCD = varBCD(props);
|
||||
formats.varsZeroBased = varZeroBased(props);
|
||||
info.numDigits = numDigits(props);
|
||||
info.trailingZeroes = trailingZeroes(props);
|
||||
info.scoreBCD = scoreBCD(props);
|
||||
info.varsBCD = varBCD(props);
|
||||
info.varsZeroBased = varZeroBased(props);
|
||||
|
||||
addresses.playersAddr = playerAddress(props);
|
||||
addresses.varsAddr = varAddress(props);
|
||||
info.playersAddr = playerAddress(props);
|
||||
info.varsAddr = varAddress(props);
|
||||
for (uInt32 p = 0; p < MAX_PLAYERS; ++p)
|
||||
{
|
||||
if (p < numPlayersR)
|
||||
|
@ -133,12 +135,12 @@ bool HighScoresManager::get(const Properties& props, uInt32& numPlayersR, uInt32
|
|||
uInt32 idx = p * numAddrBytes(props) + a;
|
||||
string addr = getPropIdx(props, PropType::Cart_Addresses, idx);
|
||||
|
||||
addresses.scoresAddr[p][a] = (addr == EmptyString ? 0 : stoi(addr, nullptr, 16));
|
||||
info.scoresAddr[p][a] = stringToIntBase16(addr);
|
||||
}
|
||||
}
|
||||
else
|
||||
for (uInt32 a = 0; a < numAddrBytes(props); ++a)
|
||||
addresses.scoresAddr[p][a] = -1;
|
||||
info.scoresAddr[p][a] = -1;
|
||||
}
|
||||
|
||||
return (EmptyString != getPropIdx(props, PropType::Cart_Addresses, 0));
|
||||
|
@ -146,31 +148,43 @@ bool HighScoresManager::get(const Properties& props, uInt32& numPlayersR, uInt32
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void HighScoresManager::set(Properties& props, uInt32 numPlayers, uInt32 numVariations,
|
||||
const Formats& formats, const Addresses& addresses) const
|
||||
const ScoresInfo& info) const
|
||||
{
|
||||
ostringstream buf;
|
||||
string output;
|
||||
|
||||
props.set(PropType::Cart_Players, std::to_string(numPlayers));
|
||||
props.set(PropType::Cart_Variations, std::to_string(std::min(numVariations, MAX_VARIATIONS)));
|
||||
props.set(PropType::Cart_Players, to_string(numPlayers));
|
||||
props.set(PropType::Cart_Variations, to_string(min(numVariations, MAX_VARIATIONS)));
|
||||
|
||||
// fill from the back to skip default values
|
||||
if (info.varsZeroBased != DEFAULT_VARS_ZERO_BASED)
|
||||
output = info.varsZeroBased ? ",1" : ",0";
|
||||
if (output.length() || info.varsBCD != DEFAULT_VARS_BCD)
|
||||
output.insert(0, info.varsBCD ? ",B" : ",D");
|
||||
if (output.length() || info.scoreBCD != DEFAULT_SCORE_BCD)
|
||||
output.insert(0, info.scoreBCD ? ",B" : ",H");
|
||||
if (output.length() || info.trailingZeroes != DEFAULT_TRAILING)
|
||||
output.insert(0, "," + to_string(info.trailingZeroes));
|
||||
if (output.length() || info.numDigits != DEFAULT_DIGITS)
|
||||
output.insert(0, to_string(info.numDigits));
|
||||
|
||||
props.set(PropType::Cart_Formats, output);
|
||||
|
||||
buf << formats.numDigits << ","
|
||||
<< formats.trailingZeroes << ","
|
||||
<< (formats.scoreBCD ? "B" : "H") << ","
|
||||
<< (formats.varsBCD ? "B" : "D") << ","
|
||||
<< formats.varsZeroBased;
|
||||
props.set(PropType::Cart_Formats, buf.str());
|
||||
|
||||
buf.str("");
|
||||
for (uInt32 p = 0; p < numPlayers; ++p)
|
||||
{
|
||||
for (uInt32 a = 0; a < numAddrBytes(formats.numDigits, formats.trailingZeroes); ++a)
|
||||
buf << std::hex << addresses.scoresAddr[p][a] << ",";
|
||||
for (uInt32 a = 0; a < numAddrBytes(info.numDigits, info.trailingZeroes); ++a)
|
||||
buf << hex << info.scoresAddr[p][a] << ",";
|
||||
}
|
||||
buf << addresses.varsAddr << ",";
|
||||
buf << addresses.playersAddr;
|
||||
props.set(PropType::Cart_Addresses, buf.str());
|
||||
|
||||
// add optional addresses
|
||||
if (numVariations > 1 || numPlayers > 1)
|
||||
buf << info.varsAddr << "," ;
|
||||
if (numPlayers > 1)
|
||||
buf << info.playersAddr << "," ;
|
||||
|
||||
output = buf.str();
|
||||
output.pop_back();
|
||||
props.set(PropType::Cart_Addresses, output);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -178,7 +192,7 @@ uInt32 HighScoresManager::numDigits(const Properties& props) const
|
|||
{
|
||||
string digits = getPropIdx(props, PropType::Cart_Formats, 0);
|
||||
|
||||
return digits == EmptyString ? DEFAULT_DIGITS : stoi(digits);
|
||||
return min(uInt32(stringToInt(digits, DEFAULT_DIGITS)), MAX_DIGITS);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -186,7 +200,8 @@ uInt32 HighScoresManager::trailingZeroes(const Properties& props) const
|
|||
{
|
||||
string trailing = getPropIdx(props, PropType::Cart_Formats, 1);
|
||||
|
||||
return trailing == EmptyString ? DEFAULT_TRAILING : stoi(trailing);}
|
||||
return min(uInt32(stringToInt(trailing, DEFAULT_TRAILING)), MAX_TRAILING);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool HighScoresManager::scoreBCD(const Properties& props) const
|
||||
|
@ -225,7 +240,7 @@ uInt16 HighScoresManager::playerAddress(const Properties& props) const
|
|||
uInt32 idx = numAddrBytes(props) * numPlayers(props) + 1;
|
||||
string addr = getPropIdx(props, PropType::Cart_Addresses, idx);
|
||||
|
||||
return addr == EmptyString ? DEFAULT_ADDRESS : stoi(addr, nullptr, 16);
|
||||
return stringToIntBase16(addr, DEFAULT_ADDRESS);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -234,7 +249,7 @@ uInt16 HighScoresManager::varAddress(const Properties& props) const
|
|||
uInt32 idx = numAddrBytes(props) * numPlayers(props);
|
||||
string addr = getPropIdx(props, PropType::Cart_Addresses, idx);
|
||||
|
||||
return addr == EmptyString ? DEFAULT_ADDRESS : stoi(addr, nullptr, 16);
|
||||
return stringToIntBase16(addr, DEFAULT_ADDRESS);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -250,8 +265,8 @@ uInt32 HighScoresManager::numAddrBytes(const Properties& props) const
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Int32 HighScoresManager::score(uInt32 player, uInt32 numAddrBytes, uInt32 trailingZeroes, bool isBCD,
|
||||
const ScoreAddresses& scoreAddr) const
|
||||
Int32 HighScoresManager::score(uInt32 player, uInt32 numAddrBytes, uInt32 trailingZeroes,
|
||||
bool isBCD, const ScoreAddresses& scoreAddr) const
|
||||
{
|
||||
if (!myOSystem.hasConsole())
|
||||
return -1;
|
||||
|
@ -322,7 +337,7 @@ Int32 HighScoresManager::score() const
|
|||
|
||||
if (addr == EmptyString)
|
||||
return -1;
|
||||
scoreAddr[b] = stoi(addr, nullptr, 16);
|
||||
scoreAddr[b] = stringToIntBase16(addr);
|
||||
}
|
||||
|
||||
return score(currentPlayer, numBytes, trailingZeroes(props), scoreBCD(props), scoreAddr);
|
||||
|
|
|
@ -20,91 +20,128 @@
|
|||
|
||||
class OSystem;
|
||||
|
||||
class HighScoresManager
|
||||
{
|
||||
|
||||
public:
|
||||
namespace HSM {
|
||||
static const uInt32 MAX_PLAYERS = 4;
|
||||
static const uInt32 MAX_SCORE_ADDR = 3;
|
||||
|
||||
static const uInt32 DEFAULT_PLAYER = 1;
|
||||
static const uInt32 DEFAULT_VARIATION = 1;
|
||||
static const uInt32 DEFAULT_ADDRESS = 0;
|
||||
|
||||
using ScoreAddresses = array<Int16, MAX_SCORE_ADDR>;
|
||||
using ScoresAddresses = array<ScoreAddresses, MAX_PLAYERS>;
|
||||
|
||||
struct Formats {
|
||||
struct ScoresInfo {
|
||||
// Formats
|
||||
uInt32 numDigits;
|
||||
uInt32 trailingZeroes;
|
||||
bool scoreBCD;
|
||||
bool varsBCD;
|
||||
bool varsZeroBased;
|
||||
};
|
||||
|
||||
struct Addresses {
|
||||
// Addresses
|
||||
ScoresAddresses scoresAddr;
|
||||
uInt16 varsAddr;
|
||||
uInt16 playersAddr;
|
||||
};
|
||||
|
||||
HighScoresManager(OSystem& osystem);
|
||||
virtual ~HighScoresManager() = default;
|
||||
} // namespace HSM
|
||||
|
||||
/*
|
||||
Methods for returning high scores related variables
|
||||
*/
|
||||
bool get(const Properties& props, uInt32& numPlayers, uInt32& numVariations,
|
||||
Formats& formats, Addresses& addresses) const;
|
||||
void set(Properties& props, uInt32 numPlayers, uInt32 numVariations,
|
||||
const Formats& formats, const Addresses& addresses) const;
|
||||
using namespace HSM;
|
||||
|
||||
uInt32 numAddrBytes(Int32 digits, Int32 trailing) const;
|
||||
|
||||
Int32 score(uInt32 player, uInt32 numAddrBytes, uInt32 trailingZeroes, bool isBCD,
|
||||
const ScoreAddresses& scoreAddr) const;
|
||||
/**
|
||||
This class provides an interface to define, load and save scores. It is meant
|
||||
for games which do not support saving highscores.
|
||||
|
||||
// retrieve current values
|
||||
Int32 player() const;
|
||||
Int32 variation() const;
|
||||
Int32 score() const;
|
||||
TODO: load and saves scores
|
||||
|
||||
private:
|
||||
static const uInt32 MAX_VARIATIONS = 256;
|
||||
static const uInt32 DEFAULT_PLAYER = 1;
|
||||
static const uInt32 DEFAULT_VARIATION = 1;
|
||||
static const uInt32 DEFAULT_DIGITS = 4;
|
||||
static const uInt32 DEFAULT_TRAILING = 0;
|
||||
static const bool DEFAULT_SCORE_BCD = true;
|
||||
static const bool DEFAULT_VARS_BCD = true;
|
||||
static const bool DEFAULT_VARS_ZERO_BASED = false;
|
||||
static const bool DEFAULT_PLAYERS_ZERO_BASED = true;
|
||||
static const uInt32 DEFAULT_ADDRESS = 0;
|
||||
@author Thomas Jentzsch
|
||||
*/
|
||||
|
||||
private:
|
||||
uInt32 numVariations(const Properties& props) const;
|
||||
uInt32 numPlayers(const Properties& props) const;
|
||||
uInt16 varAddress(const Properties& props) const;
|
||||
uInt16 playerAddress(const Properties& props) const;
|
||||
uInt32 numDigits(const Properties& props) const;
|
||||
uInt32 trailingZeroes(const Properties& props) const;
|
||||
bool scoreBCD(const Properties& props) const;
|
||||
bool varBCD(const Properties& props) const;
|
||||
bool varZeroBased(const Properties& props) const;
|
||||
bool playerZeroBased(const Properties& props) const;
|
||||
class HighScoresManager
|
||||
{
|
||||
public:
|
||||
HighScoresManager(OSystem& osystem);
|
||||
virtual ~HighScoresManager() = default;
|
||||
|
||||
uInt32 numAddrBytes(const Properties& props) const;
|
||||
/**
|
||||
Get the highscore data of game's properties
|
||||
|
||||
Properties& properties(Properties& props) const;
|
||||
string getPropIdx(const Properties& props, PropType type, uInt32 idx = 0) const;
|
||||
Int16 peek(uInt16 addr) const;
|
||||
@return True if highscore data exists, else false
|
||||
*/
|
||||
bool get(const Properties& props, uInt32& numPlayers, uInt32& numVariations,
|
||||
ScoresInfo& info) const;
|
||||
/**
|
||||
Set the highscore data of game's properties
|
||||
*/
|
||||
void set(Properties& props, uInt32 numPlayers, uInt32 numVariations,
|
||||
const ScoresInfo& info) const;
|
||||
|
||||
private:
|
||||
// Reference to the osystem object
|
||||
OSystem& myOSystem;
|
||||
/**
|
||||
Calculate the number of bytes for one player's score from given parameters
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
HighScoresManager() = delete;
|
||||
HighScoresManager(const HighScoresManager&) = delete;
|
||||
HighScoresManager(HighScoresManager&&) = delete;
|
||||
HighScoresManager& operator=(const HighScoresManager&) = delete;
|
||||
HighScoresManager& operator=(HighScoresManager&&) = delete;
|
||||
@return The number of score address bytes
|
||||
*/
|
||||
uInt32 numAddrBytes(Int32 digits, Int32 trailing) const;
|
||||
|
||||
/**
|
||||
Calculate the score from given parameters
|
||||
|
||||
@return The current score or -1 if no valid data exists
|
||||
*/
|
||||
Int32 score(uInt32 player, uInt32 numAddrBytes, uInt32 trailingZeroes, bool isBCD,
|
||||
const ScoreAddresses& scoreAddr) const;
|
||||
|
||||
// Retrieve current values (using game's properties)
|
||||
Int32 player() const;
|
||||
Int32 variation() const;
|
||||
Int32 score() const;
|
||||
|
||||
private:
|
||||
static const uInt32 MAX_VARIATIONS = 256;
|
||||
|
||||
static const uInt32 MAX_DIGITS = 6;
|
||||
static const uInt32 MAX_TRAILING = 3;
|
||||
static const uInt32 DEFAULT_DIGITS = 4;
|
||||
static const uInt32 DEFAULT_TRAILING = 0;
|
||||
static const bool DEFAULT_SCORE_BCD = true;
|
||||
static const bool DEFAULT_VARS_BCD = true;
|
||||
static const bool DEFAULT_VARS_ZERO_BASED = false;
|
||||
static const bool DEFAULT_PLAYERS_ZERO_BASED = true;
|
||||
|
||||
private:
|
||||
// Get individual highscore info from properties
|
||||
uInt32 numVariations(const Properties& props) const;
|
||||
uInt32 numPlayers(const Properties& props) const;
|
||||
uInt16 varAddress(const Properties& props) const;
|
||||
uInt16 playerAddress(const Properties& props) const;
|
||||
uInt32 numDigits(const Properties& props) const;
|
||||
uInt32 trailingZeroes(const Properties& props) const;
|
||||
bool scoreBCD(const Properties& props) const;
|
||||
bool varBCD(const Properties& props) const;
|
||||
bool varZeroBased(const Properties& props) const;
|
||||
bool playerZeroBased(const Properties& props) const;
|
||||
|
||||
// Calculate the number of bytes for one player's score from property parameters
|
||||
uInt32 numAddrBytes(const Properties& props) const;
|
||||
|
||||
// Get properties
|
||||
Properties& properties(Properties& props) const;
|
||||
// Get value from highscore propterties at given index
|
||||
string getPropIdx(const Properties& props, PropType type, uInt32 idx = 0) const;
|
||||
// Peek into memory
|
||||
Int16 peek(uInt16 addr) const;
|
||||
|
||||
private:
|
||||
// Reference to the osystem object
|
||||
OSystem& myOSystem;
|
||||
|
||||
private:
|
||||
// Following constructors and assignment operators not supported
|
||||
HighScoresManager() = delete;
|
||||
HighScoresManager(const HighScoresManager&) = delete;
|
||||
HighScoresManager(HighScoresManager&&) = delete;
|
||||
HighScoresManager& operator=(const HighScoresManager&) = delete;
|
||||
HighScoresManager& operator=(HighScoresManager&&) = delete;
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -152,6 +152,13 @@ namespace BSPF
|
|||
catch(...) { return defaultValue; }
|
||||
}
|
||||
|
||||
// Convert string with base 16 to integer, using default value on any error
|
||||
inline int stringToIntBase16(const string& s, const int defaultValue = 0)
|
||||
{
|
||||
try { return std::stoi(s, nullptr, 16); }
|
||||
catch(...) { return defaultValue; }
|
||||
}
|
||||
|
||||
// Compare two strings, ignoring case
|
||||
inline int compareIgnoreCase(const string& s1, const string& s2)
|
||||
{
|
||||
|
|
|
@ -42,6 +42,9 @@
|
|||
|
||||
#include "GameInfoDialog.hxx"
|
||||
|
||||
using namespace std;
|
||||
using namespace BSPF;
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
GameInfoDialog::GameInfoDialog(
|
||||
OSystem& osystem, DialogContainer& parent, const GUI::Font& font,
|
||||
|
@ -373,7 +376,7 @@ GameInfoDialog::GameInfoDialog(
|
|||
pwidth = font.getStringWidth("4");
|
||||
|
||||
myPlayersLabel = new StaticTextWidget(myTab, font, xpos, ypos + 1, lwidth, fontHeight, "Players");
|
||||
myPlayers = new PopUpWidget(myTab, font, xpos + lwidth, ypos, pwidth, lineHeight, items, "", 0, kPlayersChanged);
|
||||
myPlayers = new PopUpWidget(myTab, font, xpos + lwidth, ypos, pwidth, lineHeight, items, "", 0, kHiScoresChanged);
|
||||
wid.push_back(myPlayers);
|
||||
|
||||
int awidth = font.getStringWidth("FFFF") + 4;
|
||||
|
@ -402,10 +405,10 @@ GameInfoDialog::GameInfoDialog(
|
|||
myVarAddressVal = new EditTextWidget(myTab, font, myVarAddress->getRight() + 2, ypos - 1, vwidth, lineHeight);
|
||||
myVarAddressVal->setEditable(false);
|
||||
|
||||
myVarsBCD = new CheckboxWidget(myTab, font, myVarAddressVal->getRight() + 16, ypos + 1, "BCD", kVarBcdChanged);
|
||||
myVarsBCD = new CheckboxWidget(myTab, font, myVarAddressVal->getRight() + 16, ypos + 1, "BCD", kHiScoresChanged);
|
||||
wid.push_back(myVarsBCD);
|
||||
|
||||
myVarsZeroBased = new CheckboxWidget(myTab, font, myVarsBCD->getRight() + 16, ypos + 1, "0-based", kVarZeroBasedChanged);
|
||||
myVarsZeroBased = new CheckboxWidget(myTab, font, myVarsBCD->getRight() + 16, ypos + 1, "0-based", kHiScoresChanged);
|
||||
wid.push_back(myVarsZeroBased);
|
||||
|
||||
ypos += lineHeight + VGAP;
|
||||
|
@ -425,7 +428,7 @@ GameInfoDialog::GameInfoDialog(
|
|||
|
||||
myScoreDigitsLabel = new StaticTextWidget(myTab, font, xpos, ypos + 1, "Digits ");
|
||||
myScoreDigits = new PopUpWidget(myTab, font, myScoreDigitsLabel->getRight(), ypos, pwidth, lineHeight,
|
||||
items, "", 0, kScoreDigitsChanged);
|
||||
items, "", 0, kHiScoresChanged);
|
||||
wid.push_back(myScoreDigits);
|
||||
|
||||
items.clear();
|
||||
|
@ -437,22 +440,22 @@ GameInfoDialog::GameInfoDialog(
|
|||
|
||||
myTrailingZeroesLabel = new StaticTextWidget(myTab, font, myScoreDigits->getRight() + 20, ypos + 1, "0-Digits ");
|
||||
myTrailingZeroes = new PopUpWidget(myTab, font, myTrailingZeroesLabel->getRight(), ypos, pwidth, lineHeight,
|
||||
items, "", 0, kScoreZeroesChanged);
|
||||
items, "", 0, kHiScoresChanged);
|
||||
wid.push_back(myTrailingZeroes);
|
||||
|
||||
myScoreBCD = new CheckboxWidget(myTab, font, myVarsBCD->getLeft(), ypos + 1, "BCD", kScoreBcdChanged);
|
||||
myScoreBCD = new CheckboxWidget(myTab, font, myVarsBCD->getLeft(), ypos + 1, "BCD", kHiScoresChanged);
|
||||
wid.push_back(myScoreBCD);
|
||||
|
||||
|
||||
for (uInt32 p = 0; p < HighScoresManager::MAX_PLAYERS; ++p)
|
||||
for (uInt32 p = 0; p < HSM::MAX_PLAYERS; ++p)
|
||||
{
|
||||
uInt32 s_xpos = xpos;
|
||||
ypos += lineHeight + VGAP;
|
||||
|
||||
myScoreAddressesLabel[p] = new StaticTextWidget(myTab, font, s_xpos, ypos + 1,
|
||||
"P" + std::to_string(p + 1) + " Addresses ");
|
||||
"P" + to_string(p + 1) + " Addresses ");
|
||||
s_xpos += myScoreAddressesLabel[p]->getWidth();
|
||||
for (uInt32 a = 0; a < HighScoresManager::MAX_SCORE_ADDR; ++a)
|
||||
for (uInt32 a = 0; a < HSM::MAX_SCORE_ADDR; ++a)
|
||||
{
|
||||
myScoreAddress[p][a] = new EditTextWidget(myTab, font, s_xpos, ypos - 1, awidth, lineHeight);
|
||||
myScoreAddress[p][a]->setTextFilter(fAddr);
|
||||
|
@ -584,10 +587,10 @@ void GameInfoDialog::loadEmulationProperties(const Properties& props)
|
|||
myPPBlend->setEnabled(!alwaysPhosphor && usePhosphor);
|
||||
|
||||
const string& blend = props.get(PropType::Display_PPBlend);
|
||||
myPPBlend->setValue(BSPF::stringToInt(blend));
|
||||
myPPBlend->setValue(stringToInt(blend));
|
||||
|
||||
// set vertical center
|
||||
Int32 vcenter = BSPF::stringToInt(props.get(PropType::Display_VCenter));
|
||||
Int32 vcenter = stringToInt(props.get(PropType::Display_VCenter));
|
||||
myVCenter->setValueLabel(vcenter);
|
||||
myVCenter->setValue(vcenter);
|
||||
myVCenter->setValueUnit(vcenter ? "px" : "");
|
||||
|
@ -620,7 +623,7 @@ void GameInfoDialog::loadControllerProperties(const Properties& props)
|
|||
istringstream m_axis(props.get(PropType::Controller_MouseAxis));
|
||||
string m_control, m_range;
|
||||
m_axis >> m_control;
|
||||
bool autoAxis = BSPF::equalsIgnoreCase(m_control, "AUTO");
|
||||
bool autoAxis = equalsIgnoreCase(m_control, "AUTO");
|
||||
myMouseControl->setState(!autoAxis);
|
||||
if(autoAxis)
|
||||
{
|
||||
|
@ -636,7 +639,7 @@ void GameInfoDialog::loadControllerProperties(const Properties& props)
|
|||
myMouseY->setEnabled(!autoAxis);
|
||||
if(m_axis >> m_range)
|
||||
{
|
||||
myMouseRange->setValue(BSPF::stringToInt(m_range));
|
||||
myMouseRange->setValue(stringToInt(m_range));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -660,51 +663,49 @@ void GameInfoDialog::loadCartridgeProperties(const Properties& props)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void GameInfoDialog::loadHighScoresProperties(const Properties& props)
|
||||
{
|
||||
HighScoresManager::Formats formats;
|
||||
HighScoresManager::Addresses addresses;
|
||||
HSM::ScoresInfo info;
|
||||
uInt32 numPlayers, numVariations;
|
||||
bool enable = instance().highScores().get(props, numPlayers, numVariations,
|
||||
formats, addresses);
|
||||
bool enable = instance().highScores().get(props, numPlayers, numVariations, info);
|
||||
|
||||
myHighScores->setState(enable);
|
||||
|
||||
myPlayers->setSelected(numPlayers);
|
||||
myVariations->setText(std::to_string(numVariations));
|
||||
myVariations->setText(to_string(numVariations));
|
||||
|
||||
ostringstream ss;
|
||||
|
||||
myScoreDigits->setSelected(formats.numDigits);
|
||||
myTrailingZeroes->setSelected(formats.trailingZeroes);
|
||||
myScoreBCD->setState(formats.scoreBCD);
|
||||
myVarsBCD->setState(formats.varsBCD);
|
||||
myVarsZeroBased->setState(formats.varsZeroBased);
|
||||
myScoreDigits->setSelected(info.numDigits);
|
||||
myTrailingZeroes->setSelected(info.trailingZeroes);
|
||||
myScoreBCD->setState(info.scoreBCD);
|
||||
myVarsBCD->setState(info.varsBCD);
|
||||
myVarsZeroBased->setState(info.varsZeroBased);
|
||||
|
||||
ss.str("");
|
||||
ss << std::hex << std::right << std::setw(4) << std::setfill('0')
|
||||
<< std::uppercase << addresses.playersAddr;
|
||||
ss << hex << right << setw(4) << setfill('0')
|
||||
<< uppercase << info.playersAddr;
|
||||
myPlayersAddress->setText(ss.str());
|
||||
|
||||
ss.str("");
|
||||
ss << std::hex << std::right << std::setw(4) << std::setfill('0')
|
||||
<< std::uppercase << addresses.varsAddr;
|
||||
ss << hex << right << setw(4) << setfill('0')
|
||||
<< uppercase << info.varsAddr;
|
||||
myVarAddress->setText(ss.str());
|
||||
|
||||
for (uInt32 p = 0; p < HighScoresManager::MAX_PLAYERS; ++p)
|
||||
for (uInt32 p = 0; p < HSM::MAX_PLAYERS; ++p)
|
||||
{
|
||||
for (uInt32 a = 0; a < instance().highScores().numAddrBytes(formats.numDigits, formats.trailingZeroes); ++a)
|
||||
for (uInt32 a = 0; a < instance().highScores().numAddrBytes(info.numDigits, info.trailingZeroes); ++a)
|
||||
{
|
||||
if (p < numPlayers)
|
||||
{
|
||||
ss.str("");
|
||||
ss << std::hex << std::right << std::setw(4) << std::setfill('0')
|
||||
<< std::uppercase << addresses.scoresAddr[p][a];
|
||||
ss << hex << right << setw(4) << setfill('0')
|
||||
<< uppercase << info.scoresAddr[p][a];
|
||||
myScoreAddress[p][a]->setText(ss.str());
|
||||
}
|
||||
else
|
||||
myScoreAddress[p][a]->setText("");
|
||||
}
|
||||
}
|
||||
handleHighScoresWidgets();
|
||||
updateHighScoresWidgets();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -719,7 +720,7 @@ void GameInfoDialog::saveConfig()
|
|||
myPPBlend->getValueLabel());
|
||||
Int32 vcenter = myVCenter->getValue();
|
||||
|
||||
myGameProperties.set(PropType::Display_VCenter, std::to_string(vcenter));
|
||||
myGameProperties.set(PropType::Display_VCenter, to_string(vcenter));
|
||||
myGameProperties.set(PropType::Cart_Sound, mySound->getState() ? "STEREO" : "MONO");
|
||||
|
||||
// Console properties
|
||||
|
@ -780,40 +781,38 @@ void GameInfoDialog::saveConfig()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void GameInfoDialog::saveHighScoresProperties()
|
||||
{
|
||||
HighScoresManager::Formats formats;
|
||||
HighScoresManager::Addresses addresses;
|
||||
HSM::ScoresInfo info;
|
||||
|
||||
if (myHighScores->getState())
|
||||
{
|
||||
// fill formats
|
||||
formats.varsZeroBased = myVarsZeroBased->getState();
|
||||
formats.varsBCD = myVarsBCD->getState();
|
||||
formats.numDigits = myScoreDigits->getSelected() + 1;
|
||||
formats.trailingZeroes = myTrailingZeroes->getSelected();
|
||||
formats.scoreBCD = myScoreBCD->getState();
|
||||
// fill info
|
||||
info.varsZeroBased = myVarsZeroBased->getState();
|
||||
info.varsBCD = myVarsBCD->getState();
|
||||
info.numDigits = myScoreDigits->getSelected() + 1;
|
||||
info.trailingZeroes = myTrailingZeroes->getSelected();
|
||||
info.scoreBCD = myScoreBCD->getState();
|
||||
|
||||
// fill addresses
|
||||
// fill info
|
||||
string strAddr;
|
||||
|
||||
strAddr = myPlayersAddress->getText();
|
||||
addresses.playersAddr = strAddr == EmptyString ? 1 : stoi(strAddr, nullptr, 16);
|
||||
info.playersAddr = stringToIntBase16(strAddr, HSM::DEFAULT_ADDRESS);
|
||||
strAddr = myVarAddress->getText();
|
||||
addresses.varsAddr = strAddr == EmptyString ? 1 : stoi(strAddr, nullptr, 16);
|
||||
info.varsAddr = stringToIntBase16(strAddr, HSM::DEFAULT_ADDRESS);
|
||||
|
||||
for (uInt32 p = 0; p < HighScoresManager::MAX_PLAYERS; ++p)
|
||||
for (uInt32 p = 0; p < HSM::MAX_PLAYERS; ++p)
|
||||
{
|
||||
for (uInt32 a = 0; a < HighScoresManager::MAX_SCORE_ADDR; ++a)
|
||||
for (uInt32 a = 0; a < HSM::MAX_SCORE_ADDR; ++a)
|
||||
{
|
||||
strAddr = myScoreAddress[p][a]->getText();
|
||||
addresses.scoresAddr[p][a] = strAddr == EmptyString ? 0 : stoi(strAddr, nullptr, 16);
|
||||
info.scoresAddr[p][a] = stringToIntBase16(strAddr, HSM::DEFAULT_ADDRESS);
|
||||
}
|
||||
}
|
||||
|
||||
string strVars = myVariations->getText();
|
||||
|
||||
instance().highScores().set(myGameProperties, myPlayers->getSelected() + 1,
|
||||
strVars == EmptyString ? 1 : stoi(strVars),
|
||||
formats, addresses);
|
||||
stringToInt(strVars, HSM::DEFAULT_VARIATION), info);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -913,10 +912,10 @@ void GameInfoDialog::updateControllerStates()
|
|||
// Compumate bankswitching scheme doesn't allow to select controllers
|
||||
bool enableSelectControl = myBSType->getSelectedTag() != "CM";
|
||||
// Enable Swap Paddles checkbox only for paddle games
|
||||
bool enableSwapPaddles = BSPF::startsWithIgnoreCase(contrLeft, "PADDLES") ||
|
||||
BSPF::startsWithIgnoreCase(contrRight, "PADDLES") ||
|
||||
BSPF::startsWithIgnoreCase(myLeftPortDetected->getLabel(), "Paddles") ||
|
||||
BSPF::startsWithIgnoreCase(myRightPortDetected->getLabel(), "Paddles");
|
||||
bool enableSwapPaddles = startsWithIgnoreCase(contrLeft, "PADDLES") ||
|
||||
startsWithIgnoreCase(contrRight, "PADDLES") ||
|
||||
startsWithIgnoreCase(myLeftPortDetected->getLabel(), "Paddles") ||
|
||||
startsWithIgnoreCase(myRightPortDetected->getLabel(), "Paddles");
|
||||
|
||||
if(instance().hasConsole())
|
||||
{
|
||||
|
@ -966,7 +965,7 @@ void GameInfoDialog::eraseEEPROM()
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void GameInfoDialog::handleHighScoresWidgets()
|
||||
void GameInfoDialog::updateHighScoresWidgets()
|
||||
{
|
||||
bool enable = myHighScores->getState();
|
||||
uInt32 players = myPlayers->getSelected() + 1;
|
||||
|
@ -990,7 +989,7 @@ void GameInfoDialog::handleHighScoresWidgets()
|
|||
myVarAddress->setEnabled(enableVars);
|
||||
myVarAddress->setEditable(enableVars);
|
||||
myVarAddressVal->setEnabled(enableVars);
|
||||
myVarsBCD->setEnabled(enableVars);
|
||||
myVarsBCD->setEnabled(enableVars && stringToInt(myVariations->getText(), 1) >= 10);
|
||||
myVarsZeroBased->setEnabled(enableVars);
|
||||
|
||||
myScoresLabel->setEnabled(enable);
|
||||
|
@ -1001,12 +1000,12 @@ void GameInfoDialog::handleHighScoresWidgets()
|
|||
myTrailingZeroes->setEnabled(enable);
|
||||
myCurrentScoreLabel->setEnabled(enable);
|
||||
|
||||
for (uInt32 p = 0; p < HighScoresManager::MAX_PLAYERS; ++p)
|
||||
for (uInt32 p = 0; p < HSM::MAX_PLAYERS; ++p)
|
||||
{
|
||||
enable &= players > p;
|
||||
myScoreAddressesLabel[p]->setEnabled(enable);
|
||||
|
||||
for (uInt32 a = 0; a < HighScoresManager::MAX_SCORE_ADDR; ++a)
|
||||
for (uInt32 a = 0; a < HSM::MAX_SCORE_ADDR; ++a)
|
||||
{
|
||||
myScoreAddress[p][a]->setEnabled(enable && numAddr > a);
|
||||
myScoreAddressVal[p][a]->setEnabled(enable && numAddr > a);
|
||||
|
@ -1027,17 +1026,17 @@ void GameInfoDialog::handleHighScoresWidgets()
|
|||
setAddressVal(myVarAddress, myVarAddressVal, myVarsBCD->getState(), myVarsZeroBased->getState() ? 1 : 0);
|
||||
|
||||
// update score RAM values and resulting scores
|
||||
for (uInt32 p = 0; p < HighScoresManager::MAX_PLAYERS; ++p)
|
||||
for (uInt32 p = 0; p < HSM::MAX_PLAYERS; ++p)
|
||||
{
|
||||
if (p < players)
|
||||
{
|
||||
HighScoresManager::ScoreAddresses scoreAddr;
|
||||
HSM::ScoreAddresses scoreAddr;
|
||||
|
||||
for (uInt32 a = 0; a < numAddr; ++a)
|
||||
{
|
||||
setAddressVal(myScoreAddress[p][a], myScoreAddressVal[p][a]);
|
||||
string strAddr = myScoreAddress[p][a]->getText();
|
||||
scoreAddr[a] = strAddr == EmptyString ? 0 : stoi(strAddr, nullptr, 16);
|
||||
scoreAddr[a] = stringToIntBase16(strAddr, HSM::DEFAULT_ADDRESS);
|
||||
}
|
||||
|
||||
Int32 score = instance().highScores().score(p, numAddr, myTrailingZeroes->getSelected(),
|
||||
|
@ -1047,7 +1046,7 @@ void GameInfoDialog::handleHighScoresWidgets()
|
|||
ostringstream ss;
|
||||
|
||||
ss.str("");
|
||||
ss << std::right << std::setw(myScoreDigits->getSelected() + 1) << std::setfill(' ') << score;
|
||||
ss << right << setw(myScoreDigits->getSelected() + 1) << setfill(' ') << score;
|
||||
myCurrentScore[p]->setLabel(ss.str());
|
||||
}
|
||||
else
|
||||
|
@ -1081,13 +1080,13 @@ void GameInfoDialog::setAddressVal(EditTextWidget* addressWidget, EditTextWidget
|
|||
ostringstream ss;
|
||||
|
||||
// convert to number and read from memory
|
||||
addr = strAddr == EmptyString ? 0 : stoi(strAddr, nullptr, 16);
|
||||
addr = stringToIntBase16(strAddr, HSM::DEFAULT_ADDRESS);
|
||||
val = system.peek(addr) + incVal;
|
||||
// format output and display in value widget
|
||||
if (isBCD)
|
||||
ss << std::hex;
|
||||
ss << std::right << std::setw(2) << std::setfill('0')
|
||||
<< std::uppercase << uInt16(val);
|
||||
ss << hex;
|
||||
ss << right << setw(2) << setfill('0')
|
||||
<< uppercase << uInt16(val);
|
||||
valWidget->setText(ss.str());
|
||||
}
|
||||
else
|
||||
|
@ -1163,13 +1162,7 @@ void GameInfoDialog::handleCommand(CommandSender* sender, int cmd,
|
|||
|
||||
case EditTextWidget::kChangedCmd:
|
||||
case kHiScoresChanged:
|
||||
case kPlayersChanged:
|
||||
case kVarZeroBasedChanged:
|
||||
case kVarBcdChanged:
|
||||
case kScoreDigitsChanged:
|
||||
case kScoreZeroesChanged:
|
||||
case kScoreBcdChanged:
|
||||
handleHighScoresWidgets();
|
||||
updateHighScoresWidgets();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -59,10 +59,15 @@ class GameInfoDialog : public Dialog, public CommandSender
|
|||
// load the properties of the 'High Scores' tab
|
||||
void saveHighScoresProperties();
|
||||
|
||||
// update 'Controller' tab widgets
|
||||
void updateControllerStates();
|
||||
// erase SaveKey/AtariVox pages for current game
|
||||
void eraseEEPROM();
|
||||
void handleHighScoresWidgets();
|
||||
void setAddressVal(EditTextWidget* address, EditTextWidget* val, bool isBCD = true, uInt8 incVal = 0);
|
||||
// update 'High Scores' tab widgets
|
||||
void updateHighScoresWidgets();
|
||||
// set formatted memory value for given address field
|
||||
void setAddressVal(EditTextWidget* address, EditTextWidget* val,
|
||||
bool isBCD = true, uInt8 incVal = 0);
|
||||
|
||||
private:
|
||||
TabWidget* myTab{nullptr};
|
||||
|
@ -111,48 +116,42 @@ class GameInfoDialog : public Dialog, public CommandSender
|
|||
|
||||
// High Scores properties
|
||||
CheckboxWidget* myHighScores{nullptr};
|
||||
StaticTextWidget* myPlayersLabel{ nullptr };
|
||||
StaticTextWidget* myPlayersLabel{nullptr};
|
||||
PopUpWidget* myPlayers{nullptr};
|
||||
StaticTextWidget* myPlayersAddressLabel{ nullptr };
|
||||
EditTextWidget* myPlayersAddress{ nullptr };
|
||||
EditTextWidget* myPlayersAddressVal{ nullptr };
|
||||
StaticTextWidget* myPlayersAddressLabel{nullptr};
|
||||
EditTextWidget* myPlayersAddress{nullptr};
|
||||
EditTextWidget* myPlayersAddressVal{nullptr};
|
||||
|
||||
StaticTextWidget* myVariationsLabel{ nullptr };
|
||||
StaticTextWidget* myVariationsLabel{nullptr};
|
||||
EditTextWidget* myVariations{nullptr};
|
||||
StaticTextWidget* myVarAddressLabel{ nullptr };
|
||||
EditTextWidget* myVarAddress{ nullptr };
|
||||
EditTextWidget* myVarAddressVal{ nullptr };
|
||||
CheckboxWidget* myVarsBCD{ nullptr };
|
||||
CheckboxWidget* myVarsZeroBased{ nullptr };
|
||||
StaticTextWidget* myVarAddressLabel{nullptr};
|
||||
EditTextWidget* myVarAddress{nullptr};
|
||||
EditTextWidget* myVarAddressVal{nullptr};
|
||||
CheckboxWidget* myVarsBCD{nullptr};
|
||||
CheckboxWidget* myVarsZeroBased{nullptr};
|
||||
|
||||
StaticTextWidget* myScoresLabel{ nullptr };
|
||||
StaticTextWidget* myScoreDigitsLabel{ nullptr };
|
||||
StaticTextWidget* myScoresLabel{nullptr};
|
||||
StaticTextWidget* myScoreDigitsLabel{nullptr};
|
||||
PopUpWidget* myScoreDigits{nullptr};
|
||||
StaticTextWidget* myTrailingZeroesLabel{ nullptr };
|
||||
StaticTextWidget* myTrailingZeroesLabel{nullptr};
|
||||
PopUpWidget* myTrailingZeroes{nullptr};
|
||||
CheckboxWidget* myScoreBCD{nullptr};
|
||||
|
||||
StaticTextWidget* myScoreAddressesLabel[HighScoresManager::MAX_PLAYERS]{ nullptr };
|
||||
EditTextWidget* myScoreAddress[HighScoresManager::MAX_PLAYERS][HighScoresManager::MAX_SCORE_ADDR]{nullptr};
|
||||
EditTextWidget* myScoreAddressVal[HighScoresManager::MAX_PLAYERS][HighScoresManager::MAX_SCORE_ADDR]{nullptr};
|
||||
StaticTextWidget* myScoreAddressesLabel[HSM::MAX_PLAYERS]{nullptr};
|
||||
EditTextWidget* myScoreAddress[HSM::MAX_PLAYERS][HSM::MAX_SCORE_ADDR]{nullptr};
|
||||
EditTextWidget* myScoreAddressVal[HSM::MAX_PLAYERS][HSM::MAX_SCORE_ADDR]{nullptr};
|
||||
StaticTextWidget* myCurrentScoreLabel;
|
||||
StaticTextWidget* myCurrentScore[HighScoresManager::MAX_PLAYERS];
|
||||
StaticTextWidget* myCurrentScore[HSM::MAX_PLAYERS];
|
||||
|
||||
enum {
|
||||
kVCenterChanged = 'Vcch',
|
||||
kPhosphorChanged = 'PPch',
|
||||
kPPBlendChanged = 'PBch',
|
||||
kLeftCChanged = 'LCch',
|
||||
kRightCChanged = 'RCch',
|
||||
kMCtrlChanged = 'MCch',
|
||||
kEEButtonPressed = 'EEgb',
|
||||
kHiScoresChanged = 'HSch',
|
||||
kPlayersChanged = 'Plch',
|
||||
kVarZeroBasedChanged = 'VZch',
|
||||
kVarBcdChanged = 'VBch',
|
||||
kScoreDigitsChanged = 'SDch',
|
||||
kScoreZeroesChanged = 'SZch',
|
||||
kScoreBcdChanged = 'SBch',
|
||||
kVCenterChanged = 'Vcch',
|
||||
kPhosphorChanged = 'PPch',
|
||||
kPPBlendChanged = 'PBch',
|
||||
kLeftCChanged = 'LCch',
|
||||
kRightCChanged = 'RCch',
|
||||
kMCtrlChanged = 'MCch',
|
||||
kEEButtonPressed = 'EEgb',
|
||||
kHiScoresChanged = 'HSch',
|
||||
};
|
||||
|
||||
// Game properties for currently loaded ROM
|
||||
|
|
Loading…
Reference in New Issue