remove high score player parameter

refactor GameInfoDialog dialog accordingly
change high score format order
This commit is contained in:
thrust26 2020-02-20 15:55:28 +01:00
parent 0ada061ba7
commit d0ff7ba8eb
7 changed files with 213 additions and 314 deletions

View File

@ -17,24 +17,25 @@
/* /*
Formats (all optional): Formats (all optional):
4, ; score digits per player 4, ; score digits
0, ; trailing zeroes 0, ; trailing zeroes
B, ; score format (BCD, HEX) B, ; score format (BCD, HEX)
0, ; invert score order
B, ; variation format (BCD, HEX) B, ; variation format (BCD, HEX)
0, ; zero-based variation 0, ; zero-based variation
"", ; special label (5 chars) "", ; special label (5 chars)
B, ; special format (BCD, HEX) B, ; special format (BCD, HEX)
0, ; zero-based special 0, ; zero-based special
0, ; invert score order
Addresses (in hex): Addresses (in hex):
n*p-times xx, ; score info for each player, high to low n-times xx, ; score info, 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 ; special address (if defined) xx ; special address (if defined)
TODO: TODO:
- variation bits (Centipede) - variation bits (Centipede)
- player bits (Asteroids, Space Invaders)
- score swaps (Asteroids) - score swaps (Asteroids)
- special: one optional and named value extra per game (round, level...) - special: one optional and named value extra per game (round, level...)
*/ */
@ -111,14 +112,6 @@ bool HighScoresManager::enabled() const
return (!getPropIdx(properties(props), PropType::Cart_Addresses, 0).empty()); return (!getPropIdx(properties(props), PropType::Cart_Addresses, 0).empty());
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 HighScoresManager::numPlayers(const Properties& props) const
{
string numPlayers = getPropIdx(props, PropType::Cart_Players);
return min(uInt32(stringToInt(numPlayers, DEFAULT_PLAYER)), MAX_PLAYERS);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 HighScoresManager::numVariations(const Properties& props) const uInt32 HighScoresManager::numVariations(const Properties& props) const
{ {
@ -128,59 +121,45 @@ uInt32 HighScoresManager::numVariations(const Properties& props) const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool HighScoresManager::get(const Properties& props, uInt32& numPlayersR, uInt32& numVariationsR, bool HighScoresManager::get(const Properties& props, uInt32& numVariationsR,
ScoresInfo& info) const ScoresInfo& info) const
{ {
numPlayersR = numPlayers(props);
numVariationsR = numVariations(props); numVariationsR = numVariations(props);
//info.armRAM = armRAM(props);
info.numDigits = numDigits(props); info.numDigits = numDigits(props);
info.trailingZeroes = trailingZeroes(props); info.trailingZeroes = trailingZeroes(props);
info.scoreBCD = scoreBCD(props); info.scoreBCD = scoreBCD(props);
info.scoreInvert = scoreInvert(props);
info.varsBCD = varBCD(props); info.varsBCD = varBCD(props);
info.varsZeroBased = varZeroBased(props); info.varsZeroBased = varZeroBased(props);
info.special = specialLabel(props); info.special = specialLabel(props);
info.specialBCD = specialBCD(props); info.specialBCD = specialBCD(props);
info.specialZeroBased = specialZeroBased(props); info.specialZeroBased = specialZeroBased(props);
info.scoreInvert = scoreInvert(props);
info.playersAddr = playerAddress(props);
info.varsAddr = varAddress(props); info.varsAddr = varAddress(props);
info.specialAddr = specialAddress(props); info.specialAddr = specialAddress(props);
for (uInt32 p = 0; p < MAX_PLAYERS; ++p) for (uInt32 a = 0; a < numAddrBytes(props); ++a)
{ {
if (p < numPlayersR) string addr = getPropIdx(props, PropType::Cart_Addresses, a);
{
for (uInt32 a = 0; a < numAddrBytes(props); ++a)
{
uInt32 idx = p * numAddrBytes(props) + a;
string addr = getPropIdx(props, PropType::Cart_Addresses, idx);
info.scoresAddr[p][a] = stringToIntBase16(addr); info.scoreAddr[a] = stringToIntBase16(addr);
}
}
else
for (uInt32 a = 0; a < numAddrBytes(props); ++a)
info.scoresAddr[p][a] = -1;
} }
return (!getPropIdx(props, PropType::Cart_Addresses, 0).empty()); return (!getPropIdx(props, PropType::Cart_Addresses, 0).empty());
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void HighScoresManager::set(Properties& props, uInt32 numPlayers, uInt32 numVariations, void HighScoresManager::set(Properties& props, uInt32 numVariations,
const ScoresInfo& info) const const ScoresInfo& info) const
{ {
ostringstream buf; ostringstream buf;
string output; string output;
props.set(PropType::Cart_Players, to_string(numPlayers));
props.set(PropType::Cart_Variations, to_string(min(numVariations, MAX_VARIATIONS))); props.set(PropType::Cart_Variations, to_string(min(numVariations, MAX_VARIATIONS)));
// fill from the back to skip default values // fill from the back to skip default values
if (output.length() || info.scoreInvert != DEFAULT_SCORE_REVERSED)
output.insert(0, info.scoreInvert ? ",1" : ",0");
if (output.length() || info.specialZeroBased != DEFAULT_SPECIAL_ZERO_BASED) if (output.length() || info.specialZeroBased != DEFAULT_SPECIAL_ZERO_BASED)
output.insert(0, info.specialZeroBased ? ",1" : ",0"); output.insert(0, info.specialZeroBased ? ",1" : ",0");
if (output.length() || info.specialBCD != DEFAULT_SPECIAL_BCD) if (output.length() || info.specialBCD != DEFAULT_SPECIAL_BCD)
@ -192,27 +171,26 @@ void HighScoresManager::set(Properties& props, uInt32 numPlayers, uInt32 numVari
output.insert(0, info.varsZeroBased ? ",1" : ",0"); output.insert(0, info.varsZeroBased ? ",1" : ",0");
if (output.length() || info.varsBCD != DEFAULT_VARS_BCD) if (output.length() || info.varsBCD != DEFAULT_VARS_BCD)
output.insert(0, info.varsBCD ? ",B" : ",D"); output.insert(0, info.varsBCD ? ",B" : ",D");
if (output.length() || info.scoreInvert != DEFAULT_SCORE_REVERSED)
output.insert(0, info.scoreInvert ? ",1" : ",0");
if (output.length() || info.scoreBCD != DEFAULT_SCORE_BCD) if (output.length() || info.scoreBCD != DEFAULT_SCORE_BCD)
output.insert(0, info.scoreBCD ? ",B" : ",H"); output.insert(0, info.scoreBCD ? ",B" : ",H");
if (output.length() || info.trailingZeroes != DEFAULT_TRAILING) if (output.length() || info.trailingZeroes != DEFAULT_TRAILING)
output.insert(0, "," + to_string(info.trailingZeroes)); output.insert(0, "," + to_string(info.trailingZeroes));
if (output.length() || info.numDigits != DEFAULT_DIGITS) if (output.length() || info.numDigits != DEFAULT_DIGITS)
output.insert(0, to_string(info.numDigits)); output.insert(0, to_string(info.numDigits));
//if (output.length() || info.armRAM != DEFAULT_ARM_RAM)
// output.insert(0, info.armRAM ? "1" : "0"); // TODO add ',' to numDigits!
props.set(PropType::Cart_Formats, output); props.set(PropType::Cart_Formats, output);
for (uInt32 p = 0; p < numPlayers; ++p) for (uInt32 a = 0; a < numAddrBytes(info.numDigits, info.trailingZeroes); ++a)
{ buf << hex << info.scoreAddr[a] << ",";
for (uInt32 a = 0; a < numAddrBytes(info.numDigits, info.trailingZeroes); ++a)
buf << hex << info.scoresAddr[p][a] << ",";
}
// add optional addresses // add optional addresses
if (numVariations != DEFAULT_VARIATION || numPlayers != DEFAULT_PLAYER || !info.special.empty()) if (numVariations != DEFAULT_VARIATION || !info.special.empty())
buf << info.varsAddr << "," ; buf << info.varsAddr << "," ;
if (numPlayers != DEFAULT_PLAYER || !info.special.empty())
buf << info.playersAddr << "," ;
if (!info.special.empty()) if (!info.special.empty())
buf << info.specialAddr << "," ; buf << info.specialAddr << "," ;
@ -242,7 +220,14 @@ bool HighScoresManager::scoreBCD(const Properties& props) const
{ {
string bcd = getPropIdx(props, PropType::Cart_Formats, IDX_SCORE_BCD); string bcd = getPropIdx(props, PropType::Cart_Formats, IDX_SCORE_BCD);
return bcd == EmptyString ? DEFAULT_SCORE_BCD : bcd == "B"; return bcd.empty() ? DEFAULT_SCORE_BCD : bcd == "B";
}
bool HighScoresManager::scoreInvert(const Properties& props) const
{
string reversed = getPropIdx(props, PropType::Cart_Formats, IDX_SCORE_INVERT);
return reversed.empty() ? DEFAULT_SCORE_REVERSED : reversed != "0";
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -250,7 +235,7 @@ bool HighScoresManager::varBCD(const Properties& props) const
{ {
string bcd = getPropIdx(props, PropType::Cart_Formats, IDX_VAR_BCD); string bcd = getPropIdx(props, PropType::Cart_Formats, IDX_VAR_BCD);
return bcd == EmptyString ? DEFAULT_VARS_BCD : bcd == "B"; return bcd.empty() ? DEFAULT_VARS_BCD : bcd == "B";
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -258,7 +243,7 @@ bool HighScoresManager::varZeroBased(const Properties& props) const
{ {
string zeroBased = getPropIdx(props, PropType::Cart_Formats, IDX_VAR_ZERO_BASED); string zeroBased = getPropIdx(props, PropType::Cart_Formats, IDX_VAR_ZERO_BASED);
return zeroBased == EmptyString ? DEFAULT_VARS_ZERO_BASED : zeroBased != "0"; return zeroBased.empty() ? DEFAULT_VARS_ZERO_BASED : zeroBased != "0";
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -279,7 +264,7 @@ bool HighScoresManager::specialBCD(const Properties& props) const
{ {
string bcd = getPropIdx(props, PropType::Cart_Formats, IDX_SPECIAL_BCD); string bcd = getPropIdx(props, PropType::Cart_Formats, IDX_SPECIAL_BCD);
return bcd == EmptyString ? DEFAULT_SPECIAL_BCD : bcd == "B"; return bcd.empty() ? DEFAULT_SPECIAL_BCD : bcd == "B";
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -287,35 +272,22 @@ bool HighScoresManager::specialZeroBased(const Properties& props) const
{ {
string zeroBased = getPropIdx(props, PropType::Cart_Formats, IDX_SPECIAL_ZERO_BASED); string zeroBased = getPropIdx(props, PropType::Cart_Formats, IDX_SPECIAL_ZERO_BASED);
return zeroBased == EmptyString ? DEFAULT_SPECIAL_ZERO_BASED : zeroBased != "0"; return zeroBased.empty() ? DEFAULT_SPECIAL_ZERO_BASED : zeroBased != "0";
}
bool HighScoresManager::scoreInvert(const Properties& props) const
{
string reversed = getPropIdx(props, PropType::Cart_Formats, IDX_SCORE_INVERT);
return reversed == EmptyString ? DEFAULT_SCORE_REVERSED : reversed != "0";
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool HighScoresManager::playerZeroBased(const Properties& props) const /*bool HighScoresManager::armRAM(const Properties& props) const
{ {
return DEFAULT_PLAYERS_ZERO_BASED; //string armRAM = getPropIdx(props, PropType::Cart_Formats, IDX_ARM_RAM);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //return armRAM.empty() ? DEFAULT_ARM_RAM : armRAM != "0";
uInt16 HighScoresManager::playerAddress(const Properties& props) const return false;
{ }*/
uInt32 idx = numAddrBytes(props) * numPlayers(props) + IDX_PLAYERS_ADDRESS;
string addr = getPropIdx(props, PropType::Cart_Addresses, idx);
return stringToIntBase16(addr, DEFAULT_ADDRESS);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 HighScoresManager::varAddress(const Properties& props) const uInt16 HighScoresManager::varAddress(const Properties& props) const
{ {
uInt32 idx = numAddrBytes(props) * numPlayers(props) + IDX_VARS_ADDRESS; uInt32 idx = numAddrBytes(props) + IDX_VARS_ADDRESS;
string addr = getPropIdx(props, PropType::Cart_Addresses, idx); string addr = getPropIdx(props, PropType::Cart_Addresses, idx);
return stringToIntBase16(addr, DEFAULT_ADDRESS); return stringToIntBase16(addr, DEFAULT_ADDRESS);
@ -324,7 +296,7 @@ uInt16 HighScoresManager::varAddress(const Properties& props) const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 HighScoresManager::specialAddress(const Properties& props) const uInt16 HighScoresManager::specialAddress(const Properties& props) const
{ {
uInt32 idx = numAddrBytes(props) * numPlayers(props) + IDX_SPECIAL_ADDRESS; uInt32 idx = numAddrBytes(props) + IDX_SPECIAL_ADDRESS;
string addr = getPropIdx(props, PropType::Cart_Addresses, idx); string addr = getPropIdx(props, PropType::Cart_Addresses, idx);
return stringToIntBase16(addr, DEFAULT_ADDRESS); return stringToIntBase16(addr, DEFAULT_ADDRESS);
@ -343,22 +315,6 @@ uInt32 HighScoresManager::numAddrBytes(const Properties& props) const
return numAddrBytes(numDigits(props), trailingZeroes(props)); return numAddrBytes(numDigits(props), trailingZeroes(props));
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Int32 HighScoresManager::player(uInt16 addr, uInt32 numPlayers, bool zeroBased) const
{
if (!myOSystem.hasConsole())
return DEFAULT_PLAYER;
Int32 player = peek(addr);
Int32 bits = ceil(log(numPlayers + (!zeroBased ? 1 : 0))/log(2));
// limit to game's number of players
player %= 1 << bits;
player += zeroBased ? 1 : 0;
return player;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Int32 HighScoresManager::numVariations() const Int32 HighScoresManager::numVariations() const
{ {
@ -368,18 +324,6 @@ Int32 HighScoresManager::numVariations() const
return vars;; return vars;;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Int32 HighScoresManager::player() const
{
Properties props;
uInt16 addr = playerAddress(properties(props));
if (addr == DEFAULT_ADDRESS)
return DEFAULT_PLAYER;
return player(addr, numPlayers(props), playerZeroBased(props));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string HighScoresManager::specialLabel() const string HighScoresManager::specialLabel() const
{ {
@ -421,7 +365,7 @@ Int32 HighScoresManager::variation() const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Int32 HighScoresManager::score(uInt32 player, uInt32 numAddrBytes, uInt32 trailingZeroes, Int32 HighScoresManager::score(uInt32 numAddrBytes, uInt32 trailingZeroes,
bool isBCD, const ScoreAddresses& scoreAddr) const bool isBCD, const ScoreAddresses& scoreAddr) const
{ {
if (!myOSystem.hasConsole()) if (!myOSystem.hasConsole())
@ -459,20 +403,18 @@ Int32 HighScoresManager::score() const
{ {
Properties props; Properties props;
uInt32 numBytes = numAddrBytes(properties(props)); uInt32 numBytes = numAddrBytes(properties(props));
uInt32 currentPlayer = player() - (playerZeroBased(props) ? 1 : 0);
uInt32 idx = numBytes * currentPlayer;
ScoreAddresses scoreAddr; ScoreAddresses scoreAddr;
for (uInt32 b = 0; b < numBytes; ++b) for (uInt32 b = 0; b < numBytes; ++b)
{ {
string addr = getPropIdx(props, PropType::Cart_Addresses, idx + b); string addr = getPropIdx(props, PropType::Cart_Addresses, b);
if (addr == EmptyString) if (addr.empty())
return -1; return -1;
scoreAddr[b] = stringToIntBase16(addr); scoreAddr[b] = stringToIntBase16(addr);
} }
return score(currentPlayer, numBytes, trailingZeroes(props), scoreBCD(props), scoreAddr); return score(numBytes, trailingZeroes(props), scoreBCD(props), scoreAddr);
} }
bool HighScoresManager::scoreInvert() const bool HighScoresManager::scoreInvert() const

View File

@ -29,38 +29,34 @@ class OSystem;
*/ */
namespace HSM { namespace HSM {
static const uInt32 MAX_PLAYERS = 4;
static const uInt32 MAX_ADDR_CHARS = 4;
static const uInt32 MAX_SCORE_DIGITS = 8; static const uInt32 MAX_SCORE_DIGITS = 8;
static const uInt32 MAX_ADDR_CHARS = MAX_SCORE_DIGITS / 2;
static const uInt32 MAX_SCORE_ADDR = 4; static const uInt32 MAX_SCORE_ADDR = 4;
static const uInt32 MAX_SPECIAL_NAME = 5; static const uInt32 MAX_SPECIAL_NAME = 5;
static const uInt32 MAX_SPECIAL_DIGITS = 3; static const uInt32 MAX_SPECIAL_DIGITS = 3;
static const uInt32 DEFAULT_PLAYER = 1;
static const uInt32 DEFAULT_VARIATION = 1; static const uInt32 DEFAULT_VARIATION = 1;
static const uInt32 DEFAULT_ADDRESS = 0; 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>;
struct ScoresInfo { struct ScoresInfo {
// Formats // Formats
uInt32 numDigits; uInt32 numDigits;
uInt32 trailingZeroes; uInt32 trailingZeroes;
bool scoreBCD; bool scoreBCD;
bool scoreInvert;
bool varsBCD; bool varsBCD;
bool varsZeroBased; bool varsZeroBased;
string special; string special;
bool specialBCD; bool specialBCD;
bool specialZeroBased; bool specialZeroBased;
bool scoreInvert; //bool armRAM;
// Addresses // Addresses
ScoresAddresses scoresAddr; ScoreAddresses scoreAddr;
uInt16 varsAddr; uInt16 varsAddr;
uInt16 playersAddr;
uInt16 specialAddr; uInt16 specialAddr;
}; };
} // namespace HSM } // namespace HSM
using namespace HSM; using namespace HSM;
@ -88,12 +84,12 @@ class HighScoresManager
@return True if highscore data exists, else false @return True if highscore data exists, else false
*/ */
bool get(const Properties& props, uInt32& numPlayers, uInt32& numVariations, bool get(const Properties& props, uInt32& numVariations,
ScoresInfo& info) const; ScoresInfo& info) const;
/** /**
Set the highscore data of game's properties Set the highscore data of game's properties
*/ */
void set(Properties& props, uInt32 numPlayers, uInt32 numVariations, void set(Properties& props, uInt32 numVariations,
const ScoresInfo& info) const; const ScoresInfo& info) const;
/** /**
@ -104,21 +100,19 @@ class HighScoresManager
uInt32 numAddrBytes(Int32 digits, Int32 trailing) const; uInt32 numAddrBytes(Int32 digits, Int32 trailing) const;
// Retrieve current values from (using given parameters) // Retrieve current values from (using given parameters)
Int32 player(uInt16 addr, uInt32 numPlayers, bool zeroBased = true) const;
Int32 variation(uInt16 addr, bool varBCD, bool zeroBased, uInt32 numVariations) const; Int32 variation(uInt16 addr, bool varBCD, bool zeroBased, uInt32 numVariations) const;
/** /**
Calculate the score from given parameters Calculate the score from given parameters
@return The current score or -1 if no valid data exists @return The current score or -1 if no valid data exists
*/ */
Int32 score(uInt32 player, uInt32 numAddrBytes, uInt32 trailingZeroes, bool isBCD, Int32 score(uInt32 numAddrBytes, uInt32 trailingZeroes, bool isBCD,
const ScoreAddresses& scoreAddr) const; const ScoreAddresses& scoreAddr) const;
Int32 special(uInt16 addr, bool varBCD, bool zeroBased) const; Int32 special(uInt16 addr, bool varBCD, bool zeroBased) const;
// Retrieve current values (using game's properties) // Retrieve current values (using game's properties)
Int32 numVariations() const; Int32 numVariations() const;
Int32 player() const;
string specialLabel() const; string specialLabel() const;
Int32 variation() const; Int32 variation() const;
Int32 score() const; Int32 score() const;
@ -127,41 +121,39 @@ class HighScoresManager
private: private:
enum { enum {
//IDX_ARM_RAM = 0,
IDX_SCORE_DIGITS = 0, IDX_SCORE_DIGITS = 0,
IDX_TRAILING_ZEROES, IDX_TRAILING_ZEROES,
IDX_SCORE_BCD, IDX_SCORE_BCD,
IDX_SCORE_INVERT,
IDX_VAR_BCD, IDX_VAR_BCD,
IDX_VAR_ZERO_BASED, IDX_VAR_ZERO_BASED,
IDX_SPECIAL_LABEL, IDX_SPECIAL_LABEL,
IDX_SPECIAL_BCD, IDX_SPECIAL_BCD,
IDX_SPECIAL_ZERO_BASED, IDX_SPECIAL_ZERO_BASED,
IDX_SCORE_INVERT
}; };
enum { enum {
IDX_VARS_ADDRESS = 0, IDX_VARS_ADDRESS = 0,
IDX_PLAYERS_ADDRESS,
IDX_SPECIAL_ADDRESS IDX_SPECIAL_ADDRESS
}; };
static const uInt32 MAX_VARIATIONS = 256; static const uInt32 MAX_VARIATIONS = 256;
static const uInt32 MAX_TRAILING = 3; static const uInt32 MAX_TRAILING = 3;
static const bool DEFAULT_ARM_RAM = false;
static const uInt32 DEFAULT_DIGITS = 4; static const uInt32 DEFAULT_DIGITS = 4;
static const uInt32 DEFAULT_TRAILING = 0; static const uInt32 DEFAULT_TRAILING = 0;
static const bool DEFAULT_SCORE_BCD = true; static const bool DEFAULT_SCORE_BCD = true;
static const bool DEFAULT_SCORE_REVERSED = false; static const bool DEFAULT_SCORE_REVERSED = false;
static const bool DEFAULT_VARS_BCD = true; static const bool DEFAULT_VARS_BCD = true;
static const bool DEFAULT_VARS_ZERO_BASED = false; static const bool DEFAULT_VARS_ZERO_BASED = false;
static const bool DEFAULT_PLAYERS_ZERO_BASED = true;
static const bool DEFAULT_SPECIAL_BCD = true; static const bool DEFAULT_SPECIAL_BCD = true;
static const bool DEFAULT_SPECIAL_ZERO_BASED = false; static const bool DEFAULT_SPECIAL_ZERO_BASED = false;
private: private:
// Get individual highscore info from properties // Get individual highscore info from properties
uInt32 numVariations(const Properties& props) const; uInt32 numVariations(const Properties& props) const;
uInt32 numPlayers(const Properties& props) const;
uInt16 varAddress(const Properties& props) const; uInt16 varAddress(const Properties& props) const;
uInt16 playerAddress(const Properties& props) const;
uInt16 specialAddress(const Properties& props) const; uInt16 specialAddress(const Properties& props) const;
uInt32 numDigits(const Properties& props) const; uInt32 numDigits(const Properties& props) const;
uInt32 trailingZeroes(const Properties& props) const; uInt32 trailingZeroes(const Properties& props) const;
@ -172,7 +164,7 @@ class HighScoresManager
string specialLabel(const Properties& props) const; string specialLabel(const Properties& props) const;
bool specialBCD(const Properties& props) const; bool specialBCD(const Properties& props) const;
bool specialZeroBased(const Properties& props) const; bool specialZeroBased(const Properties& props) const;
bool playerZeroBased(const Properties& props) const; //bool armRAM(const Properties& props) const;
// Calculate the number of bytes for one player's score from property parameters // Calculate the number of bytes for one player's score from property parameters
uInt32 numAddrBytes(const Properties& props) const; uInt32 numAddrBytes(const Properties& props) const;

View File

@ -3,9 +3,8 @@
"Cart.ModelNo" "PB5300" "Cart.ModelNo" "PB5300"
"Cart.Name" "Frogger (1982) (Parker Bros)" "Cart.Name" "Frogger (1982) (Parker Bros)"
"Display.Phosphor" "YES" "Display.Phosphor" "YES"
"Cart.Players" "2"
"Cart.Variations" "6" "Cart.Variations" "6"
"Cart.Addresses" "CC,CE,CD,CF,DD,E6" "Cart.Addresses" "CC,CE,DD,E6"
"" ""
"Cart.MD5" "278f14887d601b5e5b620f1870bc09f6" "Cart.MD5" "278f14887d601b5e5b620f1870bc09f6"
@ -14,7 +13,7 @@
"Cart.Note" "Uses the Joystick (L) and Paddle (R) Controllers" "Cart.Note" "Uses the Joystick (L) and Paddle (R) Controllers"
"Cart.Rarity" "Homebrew" "Cart.Rarity" "Homebrew"
"Cart.Variations" "4" "Cart.Variations" "4"
"Cart.Formats" "6,0,B,B,1" "Cart.Formats" "6,0,B,0,B,1"
"Cart.Addresses" "FD,FE,FF,FC" "Cart.Addresses" "FD,FE,FF,FC"
"" ""
@ -23,7 +22,7 @@
"Cart.ModelNo" "CX2632 - 49-75153" "Cart.ModelNo" "CX2632 - 49-75153"
"Cart.Name" "Space Invaders (1980) (Atari)" "Cart.Name" "Space Invaders (1980) (Atari)"
"Cart.Variations" "112" "Cart.Variations" "112"
"Cart.Formats" "4,0,B,H,1" "Cart.Formats" "4,0,B,0,H,1"
"Cart.Addresses" "E6,E8,DC" "Cart.Addresses" "E6,E8,DC"
"" ""
@ -32,9 +31,8 @@
"Cart.ModelNo" "AG-001" "Cart.ModelNo" "AG-001"
"Cart.Name" "Dragster (1980) (Activision)" "Cart.Name" "Dragster (1980) (Activision)"
"Cart.Note" "AKA Drag Strip" "Cart.Note" "AKA Drag Strip"
"Cart.Players" "2" "Cart.Formats" "4,0,B,1,B,1"
"Cart.Formats" "4,0,B,B,1,-,D,0,1" "Cart.Addresses" "B3,B5,80,0"
"Cart.Addresses" "B3,B5,B4,B6,80,80,0"
"" ""
"Cart.MD5" "91c2098e88a6b13f977af8c003e0bca5" "Cart.MD5" "91c2098e88a6b13f977af8c003e0bca5"
@ -52,7 +50,7 @@
"Cart.Note" "AKA Lost City of Atlantis" "Cart.Note" "AKA Lost City of Atlantis"
"Cart.Rarity" "Uncommon" "Cart.Rarity" "Uncommon"
"Cart.Variations" "4" "Cart.Variations" "4"
"Cart.Formats" "6,2,B,B,1" "Cart.Formats" "6,2,B,0,B,1"
"Cart.Addresses" "A3,A2,8D" "Cart.Addresses" "A3,A2,8D"
"" ""
@ -69,10 +67,9 @@
"Cart.Manufacturer" "Activision, Bob Whitehead" "Cart.Manufacturer" "Activision, Bob Whitehead"
"Cart.ModelNo" "AX-015, AX-015-04" "Cart.ModelNo" "AX-015, AX-015-04"
"Cart.Name" "Chopper Command (1982) (Activision)" "Cart.Name" "Chopper Command (1982) (Activision)"
"Cart.Players" "2"
"Cart.Variations" "4" "Cart.Variations" "4"
"Cart.Formats" "6,0,B,B,1" "Cart.Formats" "6,0,B,0,B,1"
"Cart.Addresses" "EC,EE,F0,ED,EF,F1,E0,EB" "Cart.Addresses" "EC,EE,F0,E0"
"" ""
"Cart.MD5" "ccbd36746ed4525821a8083b0d6d2c2c" "Cart.MD5" "ccbd36746ed4525821a8083b0d6d2c2c"
@ -81,20 +78,18 @@
"Cart.Name" "Asteroids (1981) (Atari) [no copyright]" "Cart.Name" "Asteroids (1981) (Atari) [no copyright]"
"Cart.Rarity" "Common" "Cart.Rarity" "Common"
"Display.Phosphor" "YES" "Display.Phosphor" "YES"
"Cart.Players" "2"
"Cart.Variations" "66" "Cart.Variations" "66"
"Cart.Formats" "5,1,B,D,0" "Cart.Formats" "5,1,0,B,D,0"
"Cart.Addresses" "BD,BE,C0,C1,80,C7" "Cart.Addresses" "BD,BE,80,C7"
"" ""
"Cart.MD5" "dd7884b4f93cab423ac471aa1935e3df" "Cart.MD5" "dd7884b4f93cab423ac471aa1935e3df"
"Cart.Manufacturer" "Atari, Brad Stewart - Sears" "Cart.Manufacturer" "Atari, Brad Stewart - Sears"
"Cart.ModelNo" "CX2649, 49-75163" "Cart.ModelNo" "CX2649, 49-75163"
"Cart.Name" "Asteroids (1981) (Atari)" "Cart.Name" "Asteroids (1981) (Atari)"
"Cart.Players" "2"
"Cart.Variations" "66" "Cart.Variations" "66"
"Cart.Formats" "5,1,B,D,0" "Cart.Formats" "5,1,0,B,D,0"
"Cart.Addresses" "BD,BE,C0,C1,80,C7" "Cart.Addresses" "BD,BE,80,C7"
"" ""
"Cart.MD5" "f1489e27a4539a0c6c8529262f9f7e18" "Cart.MD5" "f1489e27a4539a0c6c8529262f9f7e18"
@ -106,8 +101,8 @@
"Display.Format" "PAL60" "Display.Format" "PAL60"
"Display.Phosphor" "YES" "Display.Phosphor" "YES"
"Cart.Variations" "3" "Cart.Variations" "3"
"Cart.Formats" "6,0,B,B,1,PART,D,1" "Cart.Formats" "6,0,B,0,B,1,PART,D,1"
"Cart.Addresses" "8E,8D,8C,8A,0,89" "Cart.Addresses" "8E,8D,8C,8A,89"
"" ""
"Cart.MD5" "fca4a5be1251927027f2c24774a02160" "Cart.MD5" "fca4a5be1251927027f2c24774a02160"
@ -115,7 +110,7 @@
"Cart.ModelNo" "AZ-036-04" "Cart.ModelNo" "AZ-036-04"
"Cart.Name" "H.E.R.O. (1984) (Activision)" "Cart.Name" "H.E.R.O. (1984) (Activision)"
"Cart.Variations" "5" "Cart.Variations" "5"
"Cart.Formats" "6,0,B,B,1,LEVEL,B,1" "Cart.Formats" "6,0,B,0,B,1,LEVEL,B,1"
"Cart.Addresses" "B7,B8,B9,B4,0,F5" "Cart.Addresses" "B7,B8,B9,B4,F5"
"" ""

View File

@ -258,7 +258,6 @@ void Properties::print() const
<< get(PropType::Display_VCenter) << "|" << get(PropType::Display_VCenter) << "|"
<< get(PropType::Display_Phosphor) << "|" << get(PropType::Display_Phosphor) << "|"
<< get(PropType::Display_PPBlend) << "|" << get(PropType::Display_PPBlend) << "|"
<< get(PropType::Cart_Players) << "|"
<< get(PropType::Cart_Variations) << "|" << get(PropType::Cart_Variations) << "|"
<< get(PropType::Cart_Formats) << "|" << get(PropType::Cart_Formats) << "|"
<< get(PropType::Cart_Addresses) << get(PropType::Cart_Addresses)
@ -315,7 +314,6 @@ void Properties::printHeader()
<< "Display_VCenter|" << "Display_VCenter|"
<< "Display_Phosphor|" << "Display_Phosphor|"
<< "Display_PPBlend|" << "Display_PPBlend|"
<< "Cart_Players|"
<< "Cart_Variations|" << "Cart_Variations|"
<< "Cart_Formats|" << "Cart_Formats|"
<< "Cart_Addresses" << "Cart_Addresses"
@ -346,7 +344,6 @@ std::array<string, Properties::NUM_PROPS> Properties::ourDefaultProperties =
"0", // Display.VCenter "0", // Display.VCenter
"NO", // Display.Phosphor "NO", // Display.Phosphor
"0", // Display.PPBlend "0", // Display.PPBlend
"1", // Cart.Players
"1", // Cart.Variations "1", // Cart.Variations
"", // Cart.Formats, "", // Cart.Formats,
"" // Cart.Addresses "" // Cart.Addresses
@ -376,7 +373,6 @@ std::array<string, Properties::NUM_PROPS> Properties::ourPropertyNames =
"Display.VCenter", "Display.VCenter",
"Display.Phosphor", "Display.Phosphor",
"Display.PPBlend", "Display.PPBlend",
"Cart.Players",
"Cart.Variations", "Cart.Variations",
"Cart.Formats", "Cart.Formats",
"Cart.Addresses" "Cart.Addresses"

View File

@ -42,7 +42,6 @@ enum class PropType : uInt8 {
Display_VCenter, Display_VCenter,
Display_Phosphor, Display_Phosphor,
Display_PPBlend, Display_PPBlend,
Cart_Players,
Cart_Variations, Cart_Variations,
Cart_Formats, Cart_Formats,
Cart_Addresses, Cart_Addresses,

View File

@ -451,83 +451,62 @@ void GameInfoDialog::addHighScoresTab()
xpos = HBORDER; ypos = VBORDER; xpos = HBORDER; ypos = VBORDER;
lwidth = _font.getStringWidth("Variations "); lwidth = _font.getStringWidth("Variations ");
myHighScores = new CheckboxWidget(myTab, _font, xpos, ypos + 1, "Enable High Scores", kHiScoresChanged); myHighScores = new CheckboxWidget(myTab, _font, xpos, ypos + 1, "Enable High Scores",
kHiScoresChanged);
xpos += 20; ypos += lineHeight + VGAP; xpos += 20; ypos += lineHeight + VGAP;
items.clear(); /*myARMGame = new CheckboxWidget(myTab, _font, xpos, ypos + 1, "read ARM cartridge RAM",
for (int i = 1; i <= HSM::MAX_PLAYERS; ++i) kHiScoresChanged);
VarList::push_back(items, std::to_string(i), std::to_string(i));
pwidth = _font.getStringWidth("4");
myPlayersLabel = new StaticTextWidget(myTab, _font, xpos, ypos + 1, lwidth, fontHeight, "Players"); ypos += lineHeight + VGAP;*/
myPlayers = new PopUpWidget(myTab, _font, xpos + lwidth, ypos, pwidth, lineHeight, items, "", 0, kHiScoresChanged);
wid.push_back(myPlayers); pwidth = _font.getStringWidth("4");
int awidth = _font.getMaxCharWidth() * HSM::MAX_ADDR_CHARS + 4; int awidth = _font.getMaxCharWidth() * HSM::MAX_ADDR_CHARS + 4;
int vwidth = _font.getStringWidth("123") + 4; int vwidth = _font.getStringWidth("123") + 4;
myPlayersAddressLabel = new StaticTextWidget(myTab, _font, myPlayers->getRight() + 16, ypos + 1, "Address ");
myPlayersAddress = new EditTextWidget(myTab, _font, myPlayersAddressLabel->getRight(), ypos - 1, awidth, lineHeight);
myPlayersAddress->setTextFilter(fAddr);
wid.push_back(myPlayersAddress);
myPlayersAddressVal = new EditTextWidget(myTab, _font, myPlayersAddress->getRight() + 2, ypos - 1, vwidth, lineHeight);
myPlayersAddressVal->setEditable(false);
ypos += lineHeight + VGAP;
fwidth = _font.getStringWidth("255") + 5; fwidth = _font.getStringWidth("255") + 5;
vwidth = _font.getStringWidth("123") + 4; vwidth = _font.getStringWidth("123") + 4;
int swidth = _font.getStringWidth("abcde") + 4; int swidth = _font.getStringWidth("abcde") + 4;
myVariationsLabel = new StaticTextWidget(myTab, _font, xpos, ypos + 1, lwidth, fontHeight, "Variations"); myVariationsLabel = new StaticTextWidget(myTab, _font, xpos, ypos + 1, lwidth, fontHeight,
"Variations");
myVariations = new EditTextWidget(myTab, _font, xpos + lwidth, ypos - 1, fwidth, lineHeight); myVariations = new EditTextWidget(myTab, _font, xpos + lwidth, ypos - 1, fwidth, lineHeight);
myVariations->setTextFilter(fVars); myVariations->setTextFilter(fVars);
wid.push_back(myVariations); wid.push_back(myVariations);
myVarAddressLabel = new StaticTextWidget(myTab, _font, myPlayersAddressLabel->getLeft(), ypos + 1, "Address "); myVarAddressLabel = new StaticTextWidget(myTab, _font, myVariations->getRight() + 16, ypos + 1,
myVarAddress = new EditTextWidget(myTab, _font, myVarAddressLabel->getRight(), ypos - 1, awidth, lineHeight); "Address ");
myVarAddress = new EditTextWidget(myTab, _font, myVarAddressLabel->getRight(), ypos - 1, awidth,
lineHeight);
myVarAddress->setTextFilter(fAddr); myVarAddress->setTextFilter(fAddr);
wid.push_back(myVarAddress); wid.push_back(myVarAddress);
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", kHiScoresChanged); 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", kHiScoresChanged); 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 * 4;
mySpecialLabel = new StaticTextWidget(myTab, _font, xpos, ypos + 1, "Special "); myScoreLabel = new StaticTextWidget(myTab, _font, xpos, ypos + 1, "Score");
mySpecialName = new EditTextWidget(myTab, _font, mySpecialLabel->getRight(), ypos - 1, swidth, lineHeight);
mySpecialName->setTextFilter(fSpecial);
wid.push_back(mySpecialName);
mySpecialAddressLabel = new StaticTextWidget(myTab, _font, myPlayersAddressLabel->getLeft(), ypos + 1, "Address "); xpos += 20; ypos += lineHeight + VGAP;
mySpecialAddress = new EditTextWidget(myTab, _font, mySpecialAddressLabel->getRight(), ypos - 1, awidth, lineHeight);
mySpecialAddress->setTextFilter(fAddr);
wid.push_back(mySpecialAddress);
mySpecialAddressVal = new EditTextWidget(myTab, _font, mySpecialAddress->getRight() + 2, ypos - 1, vwidth, lineHeight);
mySpecialAddressVal->setEditable(false);
mySpecialBCD = new CheckboxWidget(myTab, _font, mySpecialAddressVal->getRight() + 16, ypos + 1, "BCD", kHiScoresChanged);
wid.push_back(mySpecialBCD);
mySpecialZeroBased = new CheckboxWidget(myTab, _font, mySpecialBCD->getRight() + 16, ypos + 1, "0-based", kHiScoresChanged);
wid.push_back(mySpecialZeroBased);
//xpos += 20;
ypos += lineHeight + VGAP * 2;
vwidth = _font.getStringWidth("AB") + 4; vwidth = _font.getStringWidth("AB") + 4;
items.clear(); items.clear();
for (int i = 1; i <= HSM::MAX_SCORE_DIGITS; ++i) for (int i = 1; i <= HSM::MAX_SCORE_DIGITS; ++i)
VarList::push_back(items, std::to_string(i), std::to_string(i)); VarList::push_back(items, std::to_string(i), std::to_string(i));
myScoreDigitsLabel = new StaticTextWidget(myTab, _font, xpos, ypos + 1, "Score 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,
items, "", 0, kHiScoresChanged); lineHeight, items, "", 0, kHiScoresChanged);
wid.push_back(myScoreDigits); wid.push_back(myScoreDigits);
items.clear(); items.clear();
@ -535,39 +514,71 @@ void GameInfoDialog::addHighScoresTab()
VarList::push_back(items, std::to_string(i), std::to_string(i)); VarList::push_back(items, std::to_string(i), std::to_string(i));
pwidth = _font.getStringWidth("0"); pwidth = _font.getStringWidth("0");
myTrailingZeroesLabel = new StaticTextWidget(myTab, _font, myScoreDigits->getRight() + 30, ypos + 1, "0-digits "); myTrailingZeroesLabel = new StaticTextWidget(myTab, _font, myScoreDigits->getRight() + 30,
myTrailingZeroes = new PopUpWidget(myTab, _font, myTrailingZeroesLabel->getRight(), ypos, pwidth, lineHeight, ypos + 1, "0-digits ");
myTrailingZeroes = new PopUpWidget(myTab, _font, myTrailingZeroesLabel->getRight(), ypos,
pwidth, lineHeight,
items, "", 0, kHiScoresChanged); items, "", 0, kHiScoresChanged);
wid.push_back(myTrailingZeroes); wid.push_back(myTrailingZeroes);
myScoreBCD = new CheckboxWidget(myTab, _font, myVarsBCD->getLeft(), ypos + 1, "BCD", kHiScoresChanged); myScoreBCD = new CheckboxWidget(myTab, _font, myVarsBCD->getLeft(), ypos + 1, "BCD",
kHiScoresChanged);
wid.push_back(myScoreBCD); wid.push_back(myScoreBCD);
myScoreInvert = new CheckboxWidget(myTab, _font, myScoreBCD->getRight() + 16, ypos + 1, "Invert"); myScoreInvert = new CheckboxWidget(myTab, _font, myScoreBCD->getRight() + 16, ypos + 1,
"Invert");
wid.push_back(myScoreInvert); wid.push_back(myScoreInvert);
for (uInt32 p = 0; p < HSM::MAX_PLAYERS; ++p) uInt32 s_xpos = xpos;
ypos += lineHeight + VGAP;
myScoreAddressesLabel = new StaticTextWidget(myTab, _font, s_xpos, ypos + 1, "Addresses ");
s_xpos += myScoreAddressesLabel->getWidth();
for (uInt32 a = 0; a < HSM::MAX_SCORE_ADDR; ++a)
{ {
uInt32 s_xpos = xpos; myScoreAddress[a] = new EditTextWidget(myTab, _font, s_xpos, ypos - 1, awidth, lineHeight);
ypos += lineHeight + VGAP; myScoreAddress[a]->setTextFilter(fAddr);
wid.push_back(myScoreAddress[a]);
s_xpos += myScoreAddress[a]->getWidth() + 2;
myScoreAddressesLabel[p] = new StaticTextWidget(myTab, _font, s_xpos, ypos + 1, myScoreAddressVal[a] = new EditTextWidget(myTab, _font, myScoreAddress[a]->getRight() + 2,
"P" + to_string(p + 1) + " Addresses "); ypos - 1, vwidth, lineHeight);
s_xpos += myScoreAddressesLabel[p]->getWidth(); myScoreAddressVal[a]->setEditable(false);
for (uInt32 a = 0; a < HSM::MAX_SCORE_ADDR; ++a) s_xpos += myScoreAddressVal[a]->getWidth() + 16;
{
myScoreAddress[p][a] = new EditTextWidget(myTab, _font, s_xpos, ypos - 1, awidth, lineHeight);
myScoreAddress[p][a]->setTextFilter(fAddr);
wid.push_back(myScoreAddress[p][a]);
s_xpos += myScoreAddress[p][a]->getWidth() + 2;
myScoreAddressVal[p][a] = new EditTextWidget(myTab, _font, myScoreAddress[p][a]->getRight() + 2, ypos - 1, vwidth, lineHeight);
myScoreAddressVal[p][a]->setEditable(false);
s_xpos += myScoreAddressVal[p][a]->getWidth() + 16;
}
myCurrentScore[p] = new StaticTextWidget(myTab, _font, s_xpos, ypos + 1, "= 123456");
} }
//myCurrentScoreLabel = new StaticTextWidget(myTab, _font, myCurrentScore[0]->getLeft(), myScoreBCD->getTop(), "Current");
ypos += lineHeight + VGAP * 1;
myCurrentScoreLabel = new StaticTextWidget(myTab, _font, xpos, ypos + 1, "Current ");
myCurrentScore = new StaticTextWidget(myTab, _font, myCurrentScoreLabel->getRight(), ypos + 1,
"12345678");
xpos -= 20; ypos += lineHeight + VGAP * 4;
vwidth = _font.getStringWidth("123") + 4;
mySpecialLabel = new StaticTextWidget(myTab, _font, xpos, ypos + 1, "Special");
mySpecialName = new EditTextWidget(myTab, _font, mySpecialLabel->getRight() + 19, ypos - 1,
swidth, lineHeight);
mySpecialName->setTextFilter(fSpecial);
wid.push_back(mySpecialName);
mySpecialAddressLabel = new StaticTextWidget(myTab, _font, myVarAddressLabel->getLeft(),
ypos + 1, "Address ");
mySpecialAddress = new EditTextWidget(myTab, _font, mySpecialAddressLabel->getRight(),
ypos - 1, awidth, lineHeight);
mySpecialAddress->setTextFilter(fAddr);
wid.push_back(mySpecialAddress);
mySpecialAddressVal = new EditTextWidget(myTab, _font, mySpecialAddress->getRight() + 2,
ypos - 1, vwidth, lineHeight);
mySpecialAddressVal->setEditable(false);
mySpecialBCD = new CheckboxWidget(myTab, _font, myVarsBCD->getLeft(), ypos + 1, "BCD",
kHiScoresChanged);
wid.push_back(mySpecialBCD);
mySpecialZeroBased = new CheckboxWidget(myTab, _font, mySpecialBCD->getRight() + 16, ypos + 1,
"0-based", kHiScoresChanged);
wid.push_back(mySpecialZeroBased);
// Add items for tab 4 // Add items for tab 4
addToFocusList(wid, myTab, tabID); addToFocusList(wid, myTab, tabID);
@ -755,12 +766,11 @@ void GameInfoDialog::loadCartridgeProperties(const Properties& props)
void GameInfoDialog::loadHighScoresProperties(const Properties& props) void GameInfoDialog::loadHighScoresProperties(const Properties& props)
{ {
HSM::ScoresInfo info; HSM::ScoresInfo info;
uInt32 numPlayers, numVariations; uInt32 numVariations;
bool enable = instance().highScores().get(props, numPlayers, numVariations, info); bool enable = instance().highScores().get(props, numVariations, info);
myHighScores->setState(enable); myHighScores->setState(enable);
myPlayers->setSelected(numPlayers);
myVariations->setText(to_string(numVariations)); myVariations->setText(to_string(numVariations));
ostringstream ss; ostringstream ss;
@ -775,11 +785,6 @@ void GameInfoDialog::loadHighScoresProperties(const Properties& props)
mySpecialBCD->setState(info.specialBCD); mySpecialBCD->setState(info.specialBCD);
mySpecialZeroBased->setState(info.specialZeroBased); mySpecialZeroBased->setState(info.specialZeroBased);
ss.str("");
ss << hex << right //<< setw(HSM::MAX_ADDR_CHARS) << setfill(' ')
<< uppercase << info.playersAddr;
myPlayersAddress->setText(ss.str());
ss.str(""); ss.str("");
ss << hex << right //<< setw(HSM::MAX_ADDR_CHARS) << setfill(' ') ss << hex << right //<< setw(HSM::MAX_ADDR_CHARS) << setfill(' ')
<< uppercase << info.varsAddr; << uppercase << info.varsAddr;
@ -791,20 +796,12 @@ void GameInfoDialog::loadHighScoresProperties(const Properties& props)
mySpecialAddress->setText(ss.str()); mySpecialAddress->setText(ss.str());
for (uInt32 p = 0; p < HSM::MAX_PLAYERS; ++p) for (uInt32 a = 0; a < instance().highScores().numAddrBytes(info.numDigits, info.trailingZeroes); ++a)
{ {
for (uInt32 a = 0; a < instance().highScores().numAddrBytes(info.numDigits, info.trailingZeroes); ++a) ss.str("");
{ ss << hex << right //<< setw(HSM::MAX_ADDR_CHARS) << setfill(' ')
if (p < numPlayers) << uppercase << info.scoreAddr[a];
{ myScoreAddress[a]->setText(ss.str());
ss.str("");
ss << hex << right //<< setw(HSM::MAX_ADDR_CHARS) << setfill(' ')
<< uppercase << info.scoresAddr[p][a];
myScoreAddress[p][a]->setText(ss.str());
}
else
myScoreAddress[p][a]->setText("");
}
} }
updateHighScoresWidgets(); updateHighScoresWidgets();
} }
@ -913,30 +910,24 @@ void GameInfoDialog::saveHighScoresProperties()
// fill addresses // fill addresses
string strAddr; string strAddr;
strAddr = myPlayersAddress->getText();
info.playersAddr = stringToIntBase16(strAddr, HSM::DEFAULT_ADDRESS);
strAddr = myVarAddress->getText(); strAddr = myVarAddress->getText();
info.varsAddr = stringToIntBase16(strAddr, HSM::DEFAULT_ADDRESS); info.varsAddr = stringToIntBase16(strAddr, HSM::DEFAULT_ADDRESS);
strAddr = mySpecialAddress->getText(); strAddr = mySpecialAddress->getText();
info.specialAddr = stringToIntBase16(strAddr, HSM::DEFAULT_ADDRESS); info.specialAddr = stringToIntBase16(strAddr, HSM::DEFAULT_ADDRESS);
for (uInt32 p = 0; p < HSM::MAX_PLAYERS; ++p) for (uInt32 a = 0; a < HSM::MAX_SCORE_ADDR; ++a)
{ {
for (uInt32 a = 0; a < HSM::MAX_SCORE_ADDR; ++a) strAddr = myScoreAddress[a]->getText();
{ info.scoreAddr[a] = stringToIntBase16(strAddr, HSM::DEFAULT_ADDRESS);
strAddr = myScoreAddress[p][a]->getText();
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, stringToInt(strVars, HSM::DEFAULT_VARIATION),
stringToInt(strVars, HSM::DEFAULT_VARIATION), info); info);
} }
else else
{ {
myGameProperties.reset(PropType::Cart_Players);
myGameProperties.reset(PropType::Cart_Variations); myGameProperties.reset(PropType::Cart_Variations);
myGameProperties.reset(PropType::Cart_Formats); myGameProperties.reset(PropType::Cart_Formats);
myGameProperties.reset(PropType::Cart_Addresses); myGameProperties.reset(PropType::Cart_Addresses);
@ -1088,28 +1079,21 @@ void GameInfoDialog::eraseEEPROM()
void GameInfoDialog::updateHighScoresWidgets() void GameInfoDialog::updateHighScoresWidgets()
{ {
bool enable = myHighScores->getState(); bool enable = myHighScores->getState();
uInt32 players = myPlayers->getSelected() + 1;
bool enablePlayers = enable && players > 1;
bool enableVars = enable && myVariations->getText() > "1"; bool enableVars = enable && myVariations->getText() > "1";
bool enableSpecial = enable && !mySpecialName->getText().empty(); bool enableSpecial = enable && !mySpecialName->getText().empty();
bool enableConsole = instance().hasConsole();
uInt32 numAddr = instance().highScores().numAddrBytes(myScoreDigits->getSelected() + 1, uInt32 numAddr = instance().highScores().numAddrBytes(myScoreDigits->getSelected() + 1,
myTrailingZeroes->getSelected()); myTrailingZeroes->getSelected());
// enable widgets // enable widgets
myPlayersLabel->setEnabled(enable); //myARMGame->setEnabled(enable);
myPlayers->setEnabled(enable);
myPlayersAddressLabel->setEnabled(enablePlayers);
myPlayersAddress->setEnabled(enablePlayers);
myPlayersAddress->setEditable(enablePlayers);
myPlayersAddressVal->setEnabled(enablePlayers);
myVariationsLabel->setEnabled(enable); myVariationsLabel->setEnabled(enable);
myVariations->setEnabled(enable); myVariations->setEnabled(enable);
myVariations->setEditable(enable); myVariations->setEditable(enable);
myVarAddressLabel->setEnabled(enableVars); myVarAddressLabel->setEnabled(enableVars);
myVarAddress->setEnabled(enableVars); myVarAddress->setEnabled(enableVars);
myVarAddress->setEditable(enableVars); myVarAddress->setEditable(enableVars);
myVarAddressVal->setEnabled(enableVars); myVarAddressVal->setEnabled(enableVars && enableConsole);
myVarsBCD->setEnabled(enableVars && stringToInt(myVariations->getText(), 1) >= 10); myVarsBCD->setEnabled(enableVars && stringToInt(myVariations->getText(), 1) >= 10);
myVarsZeroBased->setEnabled(enableVars); myVarsZeroBased->setEnabled(enableVars);
@ -1119,79 +1103,70 @@ void GameInfoDialog::updateHighScoresWidgets()
mySpecialAddressLabel->setEnabled(enableSpecial); mySpecialAddressLabel->setEnabled(enableSpecial);
mySpecialAddress->setEnabled(enableSpecial); mySpecialAddress->setEnabled(enableSpecial);
mySpecialAddress->setEditable(enableSpecial); mySpecialAddress->setEditable(enableSpecial);
mySpecialAddressVal->setEnabled(enableSpecial); mySpecialAddressVal->setEnabled(enableSpecial && enableConsole);
mySpecialBCD->setEnabled(enableSpecial); mySpecialBCD->setEnabled(enableSpecial);
mySpecialZeroBased->setEnabled(enableSpecial); mySpecialZeroBased->setEnabled(enableSpecial);
myScoreLabel->setEnabled(enable);
myScoreDigitsLabel->setEnabled(enable); myScoreDigitsLabel->setEnabled(enable);
myScoreDigits->setEnabled(enable); myScoreDigits->setEnabled(enable);
myScoreBCD->setEnabled(enable); myScoreBCD->setEnabled(enable);
myTrailingZeroesLabel->setEnabled(enable); myTrailingZeroesLabel->setEnabled(enable);
myTrailingZeroes->setEnabled(enable); myTrailingZeroes->setEnabled(enable);
myScoreInvert->setEnabled(enable); myScoreInvert->setEnabled(enable);
//myCurrentScoreLabel->setEnabled(enable);
for (uInt32 p = 0; p < HSM::MAX_PLAYERS; ++p) myScoreAddressesLabel->setEnabled(enable);
for(uInt32 a = 0; a < HSM::MAX_SCORE_ADDR; ++a)
{ {
enable &= players > p; myScoreAddress[a]->setEnabled(enable && numAddr > a);
myScoreAddressesLabel[p]->setEnabled(enable); myScoreAddressVal[a]->setEnabled(enable && numAddr > a&& enableConsole);
for (uInt32 a = 0; a < HSM::MAX_SCORE_ADDR; ++a)
{
myScoreAddress[p][a]->setEnabled(enable && numAddr > a);
myScoreAddressVal[p][a]->setEnabled(enable && numAddr > a);
}
myCurrentScore[p]->setEnabled(enable);
} }
myCurrentScoreLabel->setEnabled(enable && enableConsole);
myCurrentScore->setEnabled(enable && enableConsole);
// verify and update widget data // verify and update widget data
// update players and variations RAM values // update variations RAM value
setAddressVal(myPlayersAddress, myPlayersAddressVal);
setAddressVal(myVarAddress, myVarAddressVal, myVarsBCD->getState(), setAddressVal(myVarAddress, myVarAddressVal, myVarsBCD->getState(),
myVarsZeroBased->getState() ? 1 : 0); myVarsZeroBased->getState() ? 1 : 0, stringToInt(myVariations->getText(), 1));
setAddressVal(mySpecialAddress, mySpecialAddressVal, mySpecialBCD->getState(), setAddressVal(mySpecialAddress, mySpecialAddressVal, mySpecialBCD->getState(),
mySpecialZeroBased->getState() ? 1 : 0); mySpecialZeroBased->getState() ? 1 : 0);
// update score RAM values and resulting scores // update score RAM values and resulting scores
for (uInt32 p = 0; p < HSM::MAX_PLAYERS; ++p) HSM::ScoreAddresses scoreAddr;
for(uInt32 a = 0; a < HSM::MAX_SCORE_ADDR; ++a)
{ {
if (p < players) if(a < numAddr)
{ {
HSM::ScoreAddresses scoreAddr; setAddressVal(myScoreAddress[a], myScoreAddressVal[a]);
string strAddr = myScoreAddress[a]->getText();
for (uInt32 a = 0; a < numAddr; ++a) scoreAddr[a] = stringToIntBase16(strAddr, HSM::DEFAULT_ADDRESS);
{
setAddressVal(myScoreAddress[p][a], myScoreAddressVal[p][a]);
string strAddr = myScoreAddress[p][a]->getText();
scoreAddr[a] = stringToIntBase16(strAddr, HSM::DEFAULT_ADDRESS);
}
Int32 score = instance().highScores().score(p, numAddr, myTrailingZeroes->getSelected(),
myScoreBCD->getState(), scoreAddr);
if (score >= 0)
{
ostringstream ss;
ss.str("");
ss << "= " << right << setw(myScoreDigits->getSelected() + 1) << setfill(' ') << score;
myCurrentScore[p]->setLabel(ss.str());
}
else
myCurrentScore[p]->setLabel("");
} }
else else
{ myScoreAddressVal[a]->setText("");
for (uInt32 a = 0; a < numAddr; ++a)
myScoreAddressVal[p][a]->setText("");
myCurrentScore[p]->setLabel("");
}
} }
Int32 score = instance().highScores().score(numAddr, myTrailingZeroes->getSelected(),
myScoreBCD->getState(), scoreAddr);
if(score >= 0)
{
ostringstream ss;
ss.str("");
ss << right << setw(myScoreDigits->getSelected() + 1) << setfill(' ') << score;
myCurrentScore->setLabel(ss.str());
}
else
myCurrentScore->setLabel("");
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GameInfoDialog::setAddressVal(EditTextWidget* addressWidget, EditTextWidget* valWidget, void GameInfoDialog::setAddressVal(EditTextWidget* addressWidget, EditTextWidget* valWidget,
bool isBCD, uInt8 incVal) bool isBCD, uInt8 incVal, uInt8 maxVal)
{ {
string strAddr; string strAddr;
@ -1205,10 +1180,13 @@ void GameInfoDialog::setAddressVal(EditTextWidget* addressWidget, EditTextWidget
uInt16 addr; uInt16 addr;
uInt8 val; uInt8 val;
ostringstream ss; ostringstream ss;
Int32 bits = ceil(log(maxVal + incVal)/log(2));
// convert to number and read from memory // convert to number and read from memory
addr = stringToIntBase16(strAddr, HSM::DEFAULT_ADDRESS); addr = stringToIntBase16(strAddr, HSM::DEFAULT_ADDRESS);
val = system.peek(addr) + incVal; val = system.peek(addr);
val %= 1 << bits;
val += incVal;
// format output and display in value widget // format output and display in value widget
if (isBCD) if (isBCD)
ss << hex; ss << hex;

View File

@ -73,7 +73,7 @@ class GameInfoDialog : public Dialog, public CommandSender
void updateHighScoresWidgets(); void updateHighScoresWidgets();
// set formatted memory value for given address field // set formatted memory value for given address field
void setAddressVal(EditTextWidget* address, EditTextWidget* val, void setAddressVal(EditTextWidget* address, EditTextWidget* val,
bool isBCD = true, uInt8 incVal = 0); bool isBCD = true, uInt8 incVal = 0, uInt8 maxVal = 255);
private: private:
TabWidget* myTab{nullptr}; TabWidget* myTab{nullptr};
@ -122,11 +122,7 @@ class GameInfoDialog : public Dialog, public CommandSender
// High Scores properties // High Scores properties
CheckboxWidget* myHighScores{nullptr}; CheckboxWidget* myHighScores{nullptr};
StaticTextWidget* myPlayersLabel{nullptr}; //CheckboxWidget* myARMGame{nullptr};
PopUpWidget* myPlayers{nullptr};
StaticTextWidget* myPlayersAddressLabel{nullptr};
EditTextWidget* myPlayersAddress{nullptr};
EditTextWidget* myPlayersAddressVal{nullptr};
StaticTextWidget* myVariationsLabel{nullptr}; StaticTextWidget* myVariationsLabel{nullptr};
EditTextWidget* myVariations{nullptr}; EditTextWidget* myVariations{nullptr};
@ -144,6 +140,7 @@ class GameInfoDialog : public Dialog, public CommandSender
CheckboxWidget* mySpecialBCD{nullptr}; CheckboxWidget* mySpecialBCD{nullptr};
CheckboxWidget* mySpecialZeroBased{nullptr}; CheckboxWidget* mySpecialZeroBased{nullptr};
StaticTextWidget* myScoreLabel{nullptr};
StaticTextWidget* myScoreDigitsLabel{nullptr}; StaticTextWidget* myScoreDigitsLabel{nullptr};
PopUpWidget* myScoreDigits{nullptr}; PopUpWidget* myScoreDigits{nullptr};
StaticTextWidget* myTrailingZeroesLabel{nullptr}; StaticTextWidget* myTrailingZeroesLabel{nullptr};
@ -151,11 +148,11 @@ class GameInfoDialog : public Dialog, public CommandSender
CheckboxWidget* myScoreBCD{nullptr}; CheckboxWidget* myScoreBCD{nullptr};
CheckboxWidget* myScoreInvert{nullptr}; CheckboxWidget* myScoreInvert{nullptr};
StaticTextWidget* myScoreAddressesLabel[HSM::MAX_PLAYERS]{nullptr}; StaticTextWidget* myScoreAddressesLabel{nullptr};
EditTextWidget* myScoreAddress[HSM::MAX_PLAYERS][HSM::MAX_SCORE_ADDR]{nullptr}; EditTextWidget* myScoreAddress[HSM::MAX_SCORE_ADDR]{nullptr};
EditTextWidget* myScoreAddressVal[HSM::MAX_PLAYERS][HSM::MAX_SCORE_ADDR]{nullptr}; EditTextWidget* myScoreAddressVal[HSM::MAX_SCORE_ADDR]{nullptr};
//StaticTextWidget* myCurrentScoreLabel{nullptr}; StaticTextWidget* myCurrentScoreLabel{nullptr};
StaticTextWidget* myCurrentScore[HSM::MAX_PLAYERS]{nullptr}; StaticTextWidget* myCurrentScore{nullptr};
enum { enum {
kVCenterChanged = 'Vcch', kVCenterChanged = 'Vcch',