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):
4, ; score digits per player
4, ; score digits
0, ; trailing zeroes
B, ; score format (BCD, HEX)
0, ; invert score order
B, ; variation format (BCD, HEX)
0, ; zero-based variation
"", ; special label (5 chars)
B, ; special format (BCD, HEX)
0, ; zero-based special
0, ; invert score order
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 ; player address (if more than 1 player)
xx ; special address (if defined)
TODO:
- variation bits (Centipede)
- player bits (Asteroids, Space Invaders)
- score swaps (Asteroids)
- 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());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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
{
@ -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
{
numPlayersR = numPlayers(props);
numVariationsR = numVariations(props);
//info.armRAM = armRAM(props);
info.numDigits = numDigits(props);
info.trailingZeroes = trailingZeroes(props);
info.scoreBCD = scoreBCD(props);
info.scoreInvert = scoreInvert(props);
info.varsBCD = varBCD(props);
info.varsZeroBased = varZeroBased(props);
info.special = specialLabel(props);
info.specialBCD = specialBCD(props);
info.specialZeroBased = specialZeroBased(props);
info.scoreInvert = scoreInvert(props);
info.playersAddr = playerAddress(props);
info.varsAddr = varAddress(props);
info.specialAddr = specialAddress(props);
for (uInt32 p = 0; p < MAX_PLAYERS; ++p)
for (uInt32 a = 0; a < numAddrBytes(props); ++a)
{
if (p < numPlayersR)
{
for (uInt32 a = 0; a < numAddrBytes(props); ++a)
{
uInt32 idx = p * numAddrBytes(props) + a;
string addr = getPropIdx(props, PropType::Cart_Addresses, idx);
string addr = getPropIdx(props, PropType::Cart_Addresses, a);
info.scoresAddr[p][a] = stringToIntBase16(addr);
}
}
else
for (uInt32 a = 0; a < numAddrBytes(props); ++a)
info.scoresAddr[p][a] = -1;
info.scoreAddr[a] = stringToIntBase16(addr);
}
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
{
ostringstream buf;
string output;
props.set(PropType::Cart_Players, to_string(numPlayers));
props.set(PropType::Cart_Variations, to_string(min(numVariations, MAX_VARIATIONS)));
// fill from the back to skip default values
if (output.length() || info.scoreInvert != DEFAULT_SCORE_REVERSED)
output.insert(0, info.scoreInvert ? ",1" : ",0");
if (output.length() || info.specialZeroBased != DEFAULT_SPECIAL_ZERO_BASED)
output.insert(0, info.specialZeroBased ? ",1" : ",0");
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");
if (output.length() || info.varsBCD != DEFAULT_VARS_BCD)
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)
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));
//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);
for (uInt32 p = 0; p < numPlayers; ++p)
{
for (uInt32 a = 0; a < numAddrBytes(info.numDigits, info.trailingZeroes); ++a)
buf << hex << info.scoresAddr[p][a] << ",";
}
for (uInt32 a = 0; a < numAddrBytes(info.numDigits, info.trailingZeroes); ++a)
buf << hex << info.scoreAddr[a] << ",";
// add optional addresses
if (numVariations != DEFAULT_VARIATION || numPlayers != DEFAULT_PLAYER || !info.special.empty())
if (numVariations != DEFAULT_VARIATION || !info.special.empty())
buf << info.varsAddr << "," ;
if (numPlayers != DEFAULT_PLAYER || !info.special.empty())
buf << info.playersAddr << "," ;
if (!info.special.empty())
buf << info.specialAddr << "," ;
@ -242,7 +220,14 @@ bool HighScoresManager::scoreBCD(const Properties& props) const
{
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);
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);
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);
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);
return zeroBased == EmptyString ? 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";
return zeroBased.empty() ? DEFAULT_SPECIAL_ZERO_BASED : zeroBased != "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);
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 HighScoresManager::playerAddress(const Properties& props) const
{
uInt32 idx = numAddrBytes(props) * numPlayers(props) + IDX_PLAYERS_ADDRESS;
string addr = getPropIdx(props, PropType::Cart_Addresses, idx);
return stringToIntBase16(addr, DEFAULT_ADDRESS);
}
//return armRAM.empty() ? DEFAULT_ARM_RAM : armRAM != "0";
return false;
}*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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);
return stringToIntBase16(addr, DEFAULT_ADDRESS);
@ -324,7 +296,7 @@ uInt16 HighScoresManager::varAddress(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);
return stringToIntBase16(addr, DEFAULT_ADDRESS);
@ -343,22 +315,6 @@ uInt32 HighScoresManager::numAddrBytes(const Properties& props) const
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
{
@ -368,18 +324,6 @@ Int32 HighScoresManager::numVariations() const
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
{
@ -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
{
if (!myOSystem.hasConsole())
@ -459,20 +403,18 @@ Int32 HighScoresManager::score() const
{
Properties props;
uInt32 numBytes = numAddrBytes(properties(props));
uInt32 currentPlayer = player() - (playerZeroBased(props) ? 1 : 0);
uInt32 idx = numBytes * currentPlayer;
ScoreAddresses scoreAddr;
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;
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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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