mirror of https://github.com/stella-emu/stella.git
577 lines
17 KiB
C++
577 lines
17 KiB
C++
//============================================================================
|
|
//
|
|
// SSSS tt lll lll
|
|
// SS SS tt ll ll
|
|
// SS tttttt eeee ll ll aaaa
|
|
// SSSS tt ee ee ll ll aa
|
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
// SS SS tt ee ll ll aa aa
|
|
// SSSS ttt eeeee llll llll aaaaa
|
|
//
|
|
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
|
|
// and the Stella Team
|
|
//
|
|
// See the file "License.txt" for information on usage and redistribution of
|
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
//============================================================================
|
|
|
|
/*
|
|
Formats (all optional):
|
|
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
|
|
Addresses (in hex):
|
|
n-times xx, ; score info, high to low
|
|
xx, ; variation address (if more than 1 variation)
|
|
xx ; special address (if defined)
|
|
|
|
TODO:
|
|
- variation bits (Centipede)
|
|
- score swaps (Asteroids)
|
|
- special: one optional and named value extra per game (round, level...)
|
|
*/
|
|
|
|
#include <cmath>
|
|
|
|
#include "OSystem.hxx"
|
|
#include "PropsSet.hxx"
|
|
#include "System.hxx"
|
|
#include "Cart.hxx"
|
|
#include "Console.hxx"
|
|
#include "Launcher.hxx"
|
|
#include "Base.hxx"
|
|
|
|
#include "HighScoresManager.hxx"
|
|
|
|
using namespace BSPF;
|
|
using namespace std;
|
|
using namespace HSM;
|
|
using Common::Base;
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
HighScoresManager::HighScoresManager(OSystem& osystem)
|
|
: myOSystem(osystem)
|
|
{
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Int16 HighScoresManager::peek(uInt16 addr) const
|
|
{
|
|
if (myOSystem.hasConsole())
|
|
{
|
|
if(addr < 0x100u || myOSystem.console().cartridge().internalRamSize() == 0)
|
|
return myOSystem.console().system().peek(addr);
|
|
else
|
|
return myOSystem.console().cartridge().internalRamGetValue(addr);
|
|
}
|
|
return NO_VALUE;
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
const json HighScoresManager::properties(const Properties& props) const
|
|
{
|
|
const string& property = props.get(PropType::Cart_Highscore);
|
|
|
|
if(property.empty())
|
|
return json::array();
|
|
|
|
return json::parse(property);
|
|
}
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
json HighScoresManager::properties(json& jprops) const
|
|
{
|
|
Properties props;
|
|
|
|
if(myOSystem.hasConsole())
|
|
{
|
|
props = myOSystem.console().properties();
|
|
}
|
|
else
|
|
{
|
|
const string& md5 = myOSystem.launcher().selectedRomMD5();
|
|
myOSystem.propSet().getMD5(md5, props);
|
|
}
|
|
|
|
return jprops = properties(props);
|
|
}
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
bool HighScoresManager::enabled() const
|
|
{
|
|
json hsProp;
|
|
|
|
return properties(hsProp).contains(SCORE_ADDRESSES);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
uInt32 HighScoresManager::numVariations(const json& jprops) const
|
|
{
|
|
return min(getPropInt(jprops, VARIATIONS_COUNT, DEFAULT_VARIATION), MAX_VARIATIONS);
|
|
}
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
bool HighScoresManager::get(const Properties& props, uInt32& numVariationsR,
|
|
ScoresInfo& info) const
|
|
{
|
|
json jprops = properties(props);
|
|
|
|
numVariationsR = numVariations(jprops);
|
|
|
|
//info.armRAM = armRAM(jprops);
|
|
info.numDigits = numDigits(jprops);
|
|
info.trailingZeroes = trailingZeroes(jprops);
|
|
info.scoreBCD = scoreBCD(jprops);
|
|
info.scoreInvert = scoreInvert(jprops);
|
|
info.varsBCD = varBCD(jprops);
|
|
info.varsZeroBased = varZeroBased(jprops);
|
|
info.special = specialLabel(jprops);
|
|
info.specialBCD = specialBCD(jprops);
|
|
info.specialZeroBased = specialZeroBased(jprops);
|
|
info.notes = notes(jprops);
|
|
|
|
info.varsAddr = varAddress(jprops);
|
|
info.specialAddr = specialAddress(jprops);
|
|
|
|
info.scoreAddr = getPropScoreAddr(jprops);
|
|
|
|
return enabled();
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
void HighScoresManager::set(Properties& props, uInt32 numVariations,
|
|
const ScoresInfo& info) const
|
|
{
|
|
json jprops = json::object();
|
|
|
|
// handle variations
|
|
jprops[VARIATIONS_COUNT] = min(numVariations, MAX_VARIATIONS);
|
|
if(numVariations != DEFAULT_VARIATION)
|
|
jprops[VARIATIONS_ADDRESS] = "0x" + Base::toString(info.varsAddr, Base::Fmt::_16);
|
|
if(info.varsBCD != DEFAULT_VARS_BCD)
|
|
jprops[VARIATIONS_BCD] = info.varsBCD;
|
|
if(info.varsZeroBased != DEFAULT_VARS_ZERO_BASED)
|
|
jprops[VARIATIONS_ZERO_BASED] = info.varsZeroBased;
|
|
|
|
// handle score
|
|
if(info.numDigits != DEFAULT_DIGITS)
|
|
jprops[SCORE_DIGITS] = info.numDigits;
|
|
if(info.trailingZeroes != DEFAULT_TRAILING)
|
|
jprops[SCORE_TRAILING_ZEROES] = info.trailingZeroes;
|
|
if(info.scoreBCD != DEFAULT_SCORE_BCD)
|
|
jprops[SCORE_BCD] = info.scoreBCD;
|
|
if(info.scoreInvert != DEFAULT_SCORE_REVERSED)
|
|
jprops[SCORE_INVERTED] = info.scoreInvert;
|
|
|
|
uInt32 addrBytes = numAddrBytes(info.numDigits, info.trailingZeroes);
|
|
json addresses = json::array();
|
|
|
|
for(uInt32 a = 0; a < addrBytes; ++a)
|
|
addresses.push_back("0x" + Base::toString(info.scoreAddr[a], Base::Fmt::_16));
|
|
jprops[SCORE_ADDRESSES] = addresses;
|
|
|
|
// handle special
|
|
if(!info.special.empty())
|
|
jprops[SPECIAL_LABEL] = info.special;
|
|
if(!info.special.empty())
|
|
jprops[SPECIAL_ADDRESS] = "0x" + Base::toString(info.specialAddr, Base::Fmt::_16);
|
|
if(info.specialBCD != DEFAULT_SPECIAL_BCD)
|
|
jprops[SPECIAL_BCD] = info.specialBCD;
|
|
if(info.specialZeroBased != DEFAULT_SPECIAL_ZERO_BASED)
|
|
jprops[SPECIAL_ZERO_BASED] = info.specialZeroBased;
|
|
|
|
// handle notes
|
|
if(!info.notes.empty())
|
|
jprops[NOTES] = info.notes;
|
|
|
|
//if(info.armRAM != DEFAULT_ARM_RAM)
|
|
// jprops[""] = info.armRAM;
|
|
|
|
props.set(PropType::Cart_Highscore, jprops.dump());
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
uInt32 HighScoresManager::numDigits(const json& jprops) const
|
|
{
|
|
return min(getPropInt(jprops, SCORE_DIGITS, DEFAULT_DIGITS), MAX_SCORE_DIGITS);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
uInt32 HighScoresManager::trailingZeroes(const json& jprops) const
|
|
{
|
|
return min(getPropInt(jprops, SCORE_TRAILING_ZEROES, DEFAULT_TRAILING), MAX_TRAILING);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
bool HighScoresManager::scoreBCD(const json& jprops) const
|
|
{
|
|
return getPropBool(jprops, SCORE_BCD, DEFAULT_SCORE_BCD);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
bool HighScoresManager::scoreInvert(const json& jprops) const
|
|
{
|
|
return getPropBool(jprops, SCORE_INVERTED, DEFAULT_SCORE_REVERSED);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
bool HighScoresManager::varBCD(const json& jprops) const
|
|
{
|
|
return getPropBool(jprops, VARIATIONS_BCD, DEFAULT_VARS_BCD);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
bool HighScoresManager::varZeroBased(const json& jprops) const
|
|
{
|
|
return getPropBool(jprops, VARIATIONS_ZERO_BASED, DEFAULT_VARS_ZERO_BASED);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
const string HighScoresManager::specialLabel(const json& jprops) const
|
|
{
|
|
return getPropStr(jprops, SPECIAL_LABEL);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
bool HighScoresManager::specialBCD(const json& jprops) const
|
|
{
|
|
return getPropBool(jprops, SPECIAL_BCD, DEFAULT_SPECIAL_BCD);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
bool HighScoresManager::specialZeroBased(const json& jprops) const
|
|
{
|
|
return getPropBool(jprops, SPECIAL_ZERO_BASED, DEFAULT_SPECIAL_ZERO_BASED);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
const string HighScoresManager::notes(const json& jprops) const
|
|
{
|
|
return getPropStr(jprops, NOTES);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
/*bool HighScoresManager::armRAM(const json& jprops) const
|
|
{
|
|
return getPropStr(jprops, ARM_RAM);
|
|
}*/
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
uInt16 HighScoresManager::varAddress(const json& jprops) const
|
|
{
|
|
return getPropAddr(jprops, VARIATIONS_ADDRESS, DEFAULT_ADDRESS);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
uInt16 HighScoresManager::specialAddress(const json& jprops) const
|
|
{
|
|
return getPropAddr(jprops, SPECIAL_ADDRESS, DEFAULT_ADDRESS);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
uInt32 HighScoresManager::numAddrBytes(Int32 digits, Int32 trailing) const
|
|
{
|
|
return (digits - trailing + 1) / 2;
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
uInt32 HighScoresManager::numAddrBytes(const json& jprops) const
|
|
{
|
|
return numAddrBytes(numDigits(jprops), trailingZeroes(jprops));
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Int32 HighScoresManager::numVariations() const
|
|
{
|
|
json jprops;
|
|
|
|
return numVariations(properties(jprops));
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
const string HighScoresManager::specialLabel() const
|
|
{
|
|
json jprops;
|
|
|
|
return specialLabel(properties(jprops));
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Int32 HighScoresManager::variation(uInt16 addr, bool varBCD, bool zeroBased,
|
|
uInt32 numVariations) const
|
|
{
|
|
if (!myOSystem.hasConsole())
|
|
return DEFAULT_VARIATION;
|
|
|
|
Int32 var = peek(addr);
|
|
|
|
return convert(var, numVariations, varBCD, zeroBased);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Int32 HighScoresManager::variation() const
|
|
{
|
|
json jprops;
|
|
uInt16 addr = varAddress(properties(jprops));
|
|
|
|
if(addr == DEFAULT_ADDRESS) {
|
|
if(numVariations() == 1)
|
|
return DEFAULT_VARIATION;
|
|
else
|
|
return NO_VALUE;
|
|
}
|
|
|
|
return variation(addr, varBCD(jprops), varZeroBased(jprops), numVariations(jprops));
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Int32 HighScoresManager::score(uInt32 numAddrBytes, uInt32 trailingZeroes,
|
|
bool isBCD, const ScoreAddresses& scoreAddr) const
|
|
{
|
|
if (!myOSystem.hasConsole())
|
|
return NO_VALUE;
|
|
|
|
Int32 totalScore = 0;
|
|
|
|
for (uInt32 b = 0; b < numAddrBytes; ++b)
|
|
{
|
|
uInt16 addr = scoreAddr[b];
|
|
Int32 score;
|
|
|
|
totalScore *= isBCD ? 100 : 256;
|
|
score = peek(addr);
|
|
if (isBCD)
|
|
{
|
|
score = fromBCD(score);
|
|
// verify if score is legit
|
|
if (score == NO_VALUE)
|
|
return NO_VALUE;
|
|
}
|
|
totalScore += score;
|
|
}
|
|
|
|
if (totalScore != NO_VALUE)
|
|
for (uInt32 i = 0; i < trailingZeroes; ++i)
|
|
totalScore *= 10;
|
|
|
|
return totalScore;
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Int32 HighScoresManager::score() const
|
|
{
|
|
json jprops;
|
|
uInt32 numBytes = numAddrBytes(properties(jprops));
|
|
const ScoreAddresses scoreAddr = getPropScoreAddr(jprops);
|
|
|
|
if(uInt32(scoreAddr.size()) < numBytes)
|
|
return NO_VALUE;
|
|
return score(numBytes, trailingZeroes(jprops), scoreBCD(jprops), scoreAddr);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
const string HighScoresManager::formattedScore(Int32 score, Int32 width) const
|
|
{
|
|
if(score <= 0)
|
|
return "";
|
|
|
|
ostringstream buf;
|
|
json jprops;
|
|
Int32 digits = numDigits(properties(jprops));
|
|
|
|
if(scoreBCD(jprops))
|
|
{
|
|
if(width > digits)
|
|
digits = width;
|
|
buf << std::setw(digits) << std::setfill(' ') << score;
|
|
}
|
|
else {
|
|
if(width > digits)
|
|
buf << std::setw(width - digits) << std::setfill(' ') << "";
|
|
buf << std::hex << std::setw(digits) << std::setfill('0') << score;
|
|
}
|
|
|
|
return buf.str();
|
|
}
|
|
|
|
bool HighScoresManager::scoreInvert() const
|
|
{
|
|
json jprops;
|
|
return scoreInvert(properties(jprops));
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Int32 HighScoresManager::special() const
|
|
{
|
|
json jprops;
|
|
uInt16 addr = specialAddress(properties(jprops));
|
|
|
|
if (addr == DEFAULT_ADDRESS)
|
|
return NO_VALUE;
|
|
|
|
return special(addr, specialBCD(jprops), specialZeroBased(jprops));
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Int32 HighScoresManager::special(uInt16 addr, bool varBCD, bool zeroBased) const
|
|
{
|
|
if (!myOSystem.hasConsole())
|
|
return NO_VALUE;
|
|
|
|
Int32 var = peek(addr);
|
|
|
|
if (varBCD)
|
|
var = fromBCD(var);
|
|
|
|
var += zeroBased ? 1 : 0;
|
|
|
|
return var;
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
const string HighScoresManager::notes() const
|
|
{
|
|
json jprops;
|
|
|
|
return notes(properties(jprops));
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Int32 HighScoresManager::convert(Int32 val, uInt32 maxVal, bool isBCD, bool zeroBased) const
|
|
{
|
|
maxVal += zeroBased ? 0 : 1;
|
|
Int32 bits = isBCD
|
|
? ceil(log(maxVal) / log(10) * 4)
|
|
: ceil(log(maxVal) / log(2));
|
|
|
|
// limit to maxVal's bits
|
|
val %= 1 << bits;
|
|
|
|
if (isBCD)
|
|
val = fromBCD(val);
|
|
|
|
if(val == NO_VALUE)
|
|
return 0;
|
|
|
|
val += zeroBased ? 1 : 0;
|
|
|
|
return val;
|
|
}
|
|
|
|
void replaceAll(std::string& str, const std::string& from, const std::string& to) {
|
|
if(from.empty())
|
|
return;
|
|
size_t start_pos = 0;
|
|
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
|
|
str.replace(start_pos, from.length(), to);
|
|
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
|
|
}
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
bool HighScoresManager::getPropBool(const json& jprops, const string& key,
|
|
bool defVal) const
|
|
{
|
|
return jprops.contains(key) ? jprops.at(key).get<bool>() : defVal;
|
|
}
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
uInt32 HighScoresManager::getPropInt(const json& jprops, const string& key,
|
|
uInt32 defVal) const
|
|
{
|
|
return jprops.contains(key) ? jprops.at(key).get<uInt32>() : defVal;
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
const string HighScoresManager::getPropStr(const json& jprops, const string& key,
|
|
const string& defVal) const
|
|
{
|
|
return jprops.contains(key) ? jprops.at(key).get<string>() : defVal;
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
uInt16 HighScoresManager::getPropAddr(const json& jprops, const string& key,
|
|
uInt16 defVal) const
|
|
{
|
|
const string str = getPropStr(jprops, key);
|
|
|
|
return str.empty() ? defVal : fromHexStr(str);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
const HSM::ScoreAddresses HighScoresManager::getPropScoreAddr(const json& jprops) const
|
|
{
|
|
ScoreAddresses scoreAddr{};
|
|
|
|
if(jprops.contains(SCORE_ADDRESSES))
|
|
{
|
|
const json addrProps = jprops.at(SCORE_ADDRESSES);
|
|
|
|
if(!addrProps.empty() && addrProps.is_array())
|
|
{
|
|
int a = 0;
|
|
|
|
for(const json& addresses : addrProps)
|
|
{
|
|
const string address = addresses.get<string>();
|
|
|
|
if(address.empty())
|
|
scoreAddr[a++] = DEFAULT_ADDRESS;
|
|
else
|
|
scoreAddr[a++] = fromHexStr(address);
|
|
}
|
|
}
|
|
}
|
|
return scoreAddr;
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
uInt16 HighScoresManager::fromHexStr(const string& addr) const
|
|
{
|
|
string naked = addr;
|
|
|
|
if(int pos = naked.find("0x") != std::string::npos)
|
|
naked = naked.substr(pos + 1);
|
|
|
|
return stringToIntBase16(naked);
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
Int32 HighScoresManager::fromBCD(uInt8 bcd) const
|
|
{
|
|
// verify if score is legit
|
|
if ((bcd & 0xF0) >= 0xA0 || (bcd & 0xF) >= 0xA)
|
|
return NO_VALUE;
|
|
|
|
return (bcd >> 4) * 10 + bcd % 16;
|
|
}
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
const string HighScoresManager::VARIATIONS_COUNT = "variations_count";
|
|
const string HighScoresManager::VARIATIONS_ADDRESS = "variations_address";
|
|
const string HighScoresManager::VARIATIONS_BCD = "variations_bcd";
|
|
const string HighScoresManager::VARIATIONS_ZERO_BASED = "variations_zero_based";
|
|
const string HighScoresManager::SCORE_DIGITS = "score_digits";
|
|
const string HighScoresManager::SCORE_TRAILING_ZEROES = "score_trailing_zeroes";
|
|
const string HighScoresManager::SCORE_BCD = "score_bcd";
|
|
const string HighScoresManager::SCORE_INVERTED = "score_inverted";
|
|
const string HighScoresManager::SCORE_ADDRESSES = "score_addresses";
|
|
const string HighScoresManager::SPECIAL_LABEL = "special_label";
|
|
const string HighScoresManager::SPECIAL_ADDRESS = "special_address";
|
|
const string HighScoresManager::SPECIAL_BCD = "special_bcd";
|
|
const string HighScoresManager::SPECIAL_ZERO_BASED = "special_zero_based";
|
|
const string HighScoresManager::NOTES = "notes";
|