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