mirror of https://github.com/stella-emu/stella.git
Merge branch 'feature-highscores' of https://github.com/stella-emu/stella into feature-highscores
This commit is contained in:
commit
d43d8c6730
|
@ -120,8 +120,9 @@ bool HighScoresManager::enabled() const
|
||||||
uInt32 HighScoresManager::numVariations(const Properties& props) const
|
uInt32 HighScoresManager::numVariations(const Properties& props) const
|
||||||
{
|
{
|
||||||
string numVariations = getPropIdx(props, PropType::Cart_Variations);
|
string numVariations = getPropIdx(props, PropType::Cart_Variations);
|
||||||
|
uInt32 maxVariations = MAX_VARIATIONS;
|
||||||
|
|
||||||
return min(uInt32(stringToInt(numVariations, DEFAULT_VARIATION)), MAX_VARIATIONS);
|
return min(uInt32(stringToInt(numVariations, DEFAULT_VARIATION)), maxVariations);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -161,8 +162,9 @@ void HighScoresManager::set(Properties& props, uInt32 numVariations,
|
||||||
{
|
{
|
||||||
ostringstream buf;
|
ostringstream buf;
|
||||||
string output;
|
string output;
|
||||||
|
uInt32 maxVariations = MAX_VARIATIONS;
|
||||||
|
|
||||||
props.set(PropType::Cart_Variations, to_string(min(numVariations, MAX_VARIATIONS)));
|
props.set(PropType::Cart_Variations, to_string(min(numVariations, maxVariations)));
|
||||||
|
|
||||||
// fill from the back to skip default values
|
// fill from the back to skip default values
|
||||||
if (output.length() || !info.notes.empty())
|
if (output.length() || !info.notes.empty())
|
||||||
|
@ -211,16 +213,18 @@ void HighScoresManager::set(Properties& props, uInt32 numVariations,
|
||||||
uInt32 HighScoresManager::numDigits(const Properties& props) const
|
uInt32 HighScoresManager::numDigits(const Properties& props) const
|
||||||
{
|
{
|
||||||
string digits = getPropIdx(props, PropType::Cart_Formats, IDX_SCORE_DIGITS);
|
string digits = getPropIdx(props, PropType::Cart_Formats, IDX_SCORE_DIGITS);
|
||||||
|
uInt32 maxScoreDigits = MAX_SCORE_DIGITS;
|
||||||
|
|
||||||
return min(uInt32(stringToInt(digits, DEFAULT_DIGITS)), MAX_SCORE_DIGITS);
|
return min(uInt32(stringToInt(digits, DEFAULT_DIGITS)), maxScoreDigits);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 HighScoresManager::trailingZeroes(const Properties& props) const
|
uInt32 HighScoresManager::trailingZeroes(const Properties& props) const
|
||||||
{
|
{
|
||||||
string trailing = getPropIdx(props, PropType::Cart_Formats, IDX_TRAILING_ZEROES);
|
string trailing = getPropIdx(props, PropType::Cart_Formats, IDX_TRAILING_ZEROES);
|
||||||
|
const uInt32 maxTrailing = MAX_TRAILING;
|
||||||
|
|
||||||
return min(uInt32(stringToInt(trailing, DEFAULT_TRAILING)), MAX_TRAILING);
|
return min(uInt32(stringToInt(trailing, DEFAULT_TRAILING)), maxTrailing);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -357,11 +361,12 @@ Int32 HighScoresManager::variation() const
|
||||||
Properties props;
|
Properties props;
|
||||||
uInt16 addr = varAddress(properties(props));
|
uInt16 addr = varAddress(properties(props));
|
||||||
|
|
||||||
if(addr == DEFAULT_ADDRESS)
|
if(addr == DEFAULT_ADDRESS) {
|
||||||
if(numVariations() == 1)
|
if(numVariations() == 1)
|
||||||
return DEFAULT_VARIATION;
|
return DEFAULT_VARIATION;
|
||||||
else
|
else
|
||||||
return NO_VALUE;
|
return NO_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
return variation(addr, varBCD(props), varZeroBased(props), numVariations(props));
|
return variation(addr, varBCD(props), varZeroBased(props), numVariations(props));
|
||||||
}
|
}
|
||||||
|
@ -378,7 +383,7 @@ Int32 HighScoresManager::score(uInt32 numAddrBytes, uInt32 trailingZeroes,
|
||||||
for (uInt32 b = 0; b < numAddrBytes; ++b)
|
for (uInt32 b = 0; b < numAddrBytes; ++b)
|
||||||
{
|
{
|
||||||
uInt16 addr = scoreAddr[b];
|
uInt16 addr = scoreAddr[b];
|
||||||
uInt32 score;
|
Int32 score;
|
||||||
|
|
||||||
totalScore *= isBCD ? 100 : 256;
|
totalScore *= isBCD ? 100 : 256;
|
||||||
score = peek(addr);
|
score = peek(addr);
|
||||||
|
@ -486,7 +491,7 @@ string HighScoresManager::notes() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Int32 HighScoresManager::convert(uInt32 val, uInt32 maxVal, bool isBCD, bool zeroBased) const
|
Int32 HighScoresManager::convert(Int32 val, uInt32 maxVal, bool isBCD, bool zeroBased) const
|
||||||
{
|
{
|
||||||
maxVal += zeroBased ? 0 : 1;
|
maxVal += zeroBased ? 0 : 1;
|
||||||
Int32 bits = isBCD
|
Int32 bits = isBCD
|
||||||
|
|
|
@ -29,16 +29,16 @@ class OSystem;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace HSM {
|
namespace HSM {
|
||||||
static const uInt32 MAX_SCORE_DIGITS = 8;
|
static constexpr uInt32 MAX_SCORE_DIGITS = 8;
|
||||||
static const uInt32 MAX_ADDR_CHARS = MAX_SCORE_DIGITS / 2;
|
static constexpr uInt32 MAX_ADDR_CHARS = MAX_SCORE_DIGITS / 2;
|
||||||
static const uInt32 MAX_SCORE_ADDR = 4;
|
static constexpr uInt32 MAX_SCORE_ADDR = 4;
|
||||||
static const uInt32 MAX_SPECIAL_NAME = 5;
|
static constexpr uInt32 MAX_SPECIAL_NAME = 5;
|
||||||
static const uInt32 MAX_SPECIAL_DIGITS = 3;
|
static constexpr uInt32 MAX_SPECIAL_DIGITS = 3;
|
||||||
|
|
||||||
static const uInt32 DEFAULT_VARIATION = 1;
|
static constexpr uInt32 DEFAULT_VARIATION = 1;
|
||||||
static const uInt32 DEFAULT_ADDRESS = 0;
|
static constexpr uInt32 DEFAULT_ADDRESS = 0;
|
||||||
|
|
||||||
static const Int32 NO_VALUE = -1;
|
static constexpr Int32 NO_VALUE = -1;
|
||||||
|
|
||||||
using ScoreAddresses = array<Int16, MAX_SCORE_ADDR>;
|
using ScoreAddresses = array<Int16, MAX_SCORE_ADDR>;
|
||||||
|
|
||||||
|
@ -62,9 +62,6 @@ namespace HSM {
|
||||||
};
|
};
|
||||||
} // namespace HSM
|
} // namespace HSM
|
||||||
|
|
||||||
using namespace HSM;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This class provides an interface to define, load and save scores. It is meant
|
This class provides an interface to define, load and save scores. It is meant
|
||||||
for games which do not support saving highscores.
|
for games which do not support saving highscores.
|
||||||
|
@ -88,12 +85,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& numVariations,
|
bool get(const Properties& props, uInt32& numVariations,
|
||||||
ScoresInfo& info) const;
|
HSM::ScoresInfo& info) const;
|
||||||
/**
|
/**
|
||||||
Set the highscore data of game's properties
|
Set the highscore data of game's properties
|
||||||
*/
|
*/
|
||||||
void set(Properties& props, uInt32 numVariations,
|
void set(Properties& props, uInt32 numVariations,
|
||||||
const ScoresInfo& info) const;
|
const HSM::ScoresInfo& info) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Calculate the number of bytes for one player's score from given parameters
|
Calculate the number of bytes for one player's score from given parameters
|
||||||
|
@ -110,7 +107,7 @@ class HighScoresManager
|
||||||
@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 numAddrBytes, uInt32 trailingZeroes, bool isBCD,
|
Int32 score(uInt32 numAddrBytes, uInt32 trailingZeroes, bool isBCD,
|
||||||
const ScoreAddresses& scoreAddr) const;
|
const HSM::ScoreAddresses& scoreAddr) const;
|
||||||
|
|
||||||
Int32 special(uInt16 addr, bool varBCD, bool zeroBased) const;
|
Int32 special(uInt16 addr, bool varBCD, bool zeroBased) const;
|
||||||
|
|
||||||
|
@ -126,7 +123,7 @@ class HighScoresManager
|
||||||
|
|
||||||
// converts the given value, using only the maximum bits required by maxVal
|
// converts the given value, using only the maximum bits required by maxVal
|
||||||
// and adjusted for BCD and zero based data
|
// and adjusted for BCD and zero based data
|
||||||
Int32 convert(uInt32 val, uInt32 maxVal, bool isBCD, bool zeroBased) const;
|
Int32 convert(Int32 val, uInt32 maxVal, bool isBCD, bool zeroBased) const;
|
||||||
|
|
||||||
// Peek into memory
|
// Peek into memory
|
||||||
Int16 peek(uInt16 addr) const;
|
Int16 peek(uInt16 addr) const;
|
||||||
|
@ -150,18 +147,18 @@ class HighScoresManager
|
||||||
IDX_SPECIAL_ADDRESS
|
IDX_SPECIAL_ADDRESS
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uInt32 MAX_VARIATIONS = 256;
|
static constexpr uInt32 MAX_VARIATIONS = 256;
|
||||||
|
|
||||||
static const uInt32 MAX_TRAILING = 3;
|
static constexpr uInt32 MAX_TRAILING = 3;
|
||||||
static const bool DEFAULT_ARM_RAM = false;
|
static constexpr bool DEFAULT_ARM_RAM = false;
|
||||||
static const uInt32 DEFAULT_DIGITS = 4;
|
static constexpr uInt32 DEFAULT_DIGITS = 4;
|
||||||
static const uInt32 DEFAULT_TRAILING = 0;
|
static constexpr uInt32 DEFAULT_TRAILING = 0;
|
||||||
static const bool DEFAULT_SCORE_BCD = true;
|
static constexpr bool DEFAULT_SCORE_BCD = true;
|
||||||
static const bool DEFAULT_SCORE_REVERSED = false;
|
static constexpr bool DEFAULT_SCORE_REVERSED = false;
|
||||||
static const bool DEFAULT_VARS_BCD = true;
|
static constexpr bool DEFAULT_VARS_BCD = true;
|
||||||
static const bool DEFAULT_VARS_ZERO_BASED = false;
|
static constexpr bool DEFAULT_VARS_ZERO_BASED = false;
|
||||||
static const bool DEFAULT_SPECIAL_BCD = true;
|
static constexpr bool DEFAULT_SPECIAL_BCD = true;
|
||||||
static const bool DEFAULT_SPECIAL_ZERO_BASED = false;
|
static constexpr bool DEFAULT_SPECIAL_ZERO_BASED = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Get individual highscore info from properties
|
// Get individual highscore info from properties
|
||||||
|
|
|
@ -37,11 +37,12 @@ CommandMenu::~CommandMenu()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Dialog* CommandMenu::baseDialog()
|
Dialog* CommandMenu::baseDialog()
|
||||||
{
|
{
|
||||||
if (myBaseDialog == nullptr)
|
if (myBaseDialog == nullptr) {
|
||||||
if (myOSystem.settings().getBool("minimal_ui"))
|
if (myOSystem.settings().getBool("minimal_ui"))
|
||||||
myBaseDialog = new MinUICommandDialog(myOSystem, *this);
|
myBaseDialog = new MinUICommandDialog(myOSystem, *this);
|
||||||
else
|
else
|
||||||
myBaseDialog = new CommandDialog(myOSystem, *this);
|
myBaseDialog = new CommandDialog(myOSystem, *this);
|
||||||
|
}
|
||||||
|
|
||||||
return myBaseDialog;
|
return myBaseDialog;
|
||||||
}
|
}
|
||||||
|
|
|
@ -536,7 +536,7 @@ void GameInfoDialog::addHighScoresTab()
|
||||||
|
|
||||||
vwidth = _font.getStringWidth("AB") + 3;
|
vwidth = _font.getStringWidth("AB") + 3;
|
||||||
items.clear();
|
items.clear();
|
||||||
for (int i = 1; i <= HSM::MAX_SCORE_DIGITS; ++i)
|
for (uInt32 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, "Digits ");
|
myScoreDigitsLabel = new StaticTextWidget(myTab, _font, xpos, ypos + 1, "Digits ");
|
||||||
|
@ -545,7 +545,7 @@ void GameInfoDialog::addHighScoresTab()
|
||||||
wid.push_back(myScoreDigits);
|
wid.push_back(myScoreDigits);
|
||||||
|
|
||||||
items.clear();
|
items.clear();
|
||||||
for (int i = 0; i <= HSM::MAX_SCORE_DIGITS - 3; ++i)
|
for (uInt32 i = 0; i <= HSM::MAX_SCORE_DIGITS - 3; ++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));
|
||||||
pwidth = _font.getStringWidth("0");
|
pwidth = _font.getStringWidth("0");
|
||||||
|
|
||||||
|
|
|
@ -62,13 +62,13 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent,
|
||||||
int max_w, int max_h,
|
int max_w, int max_h,
|
||||||
Menu::AppMode mode)
|
Menu::AppMode mode)
|
||||||
: Dialog(osystem, parent, osystem.frameBuffer().font(), "High Scores"),
|
: Dialog(osystem, parent, osystem.frameBuffer().font(), "High Scores"),
|
||||||
myMode(mode),
|
myDirty(false),
|
||||||
|
myHighScoreSaved(false),
|
||||||
_max_w(max_w),
|
_max_w(max_w),
|
||||||
_max_h(max_h),
|
_max_h(max_h),
|
||||||
myVariation(HSM::DEFAULT_VARIATION),
|
myVariation(HSM::DEFAULT_VARIATION),
|
||||||
myInitials(""),
|
myInitials(""),
|
||||||
myDirty(false),
|
myMode(mode)
|
||||||
myHighScoreSaved(false)
|
|
||||||
{
|
{
|
||||||
const GUI::Font& ifont = instance().frameBuffer().infoFont();
|
const GUI::Font& ifont = instance().frameBuffer().infoFont();
|
||||||
const int lineHeight = _font.getLineHeight(),
|
const int lineHeight = _font.getLineHeight(),
|
||||||
|
@ -328,7 +328,7 @@ void HighScoresDialog::updateWidgets(bool init)
|
||||||
myPrevVarButton->setEnabled(myVariation > 1);
|
myPrevVarButton->setEnabled(myVariation > 1);
|
||||||
myNextVarButton->setEnabled(myVariation < instance().highScores().numVariations());
|
myNextVarButton->setEnabled(myVariation < instance().highScores().numVariations());
|
||||||
|
|
||||||
for (Int32 r = 0; r < NUM_RANKS; ++r)
|
for (uInt32 r = 0; r < NUM_RANKS; ++r)
|
||||||
{
|
{
|
||||||
ostringstream buf;
|
ostringstream buf;
|
||||||
|
|
||||||
|
@ -354,7 +354,7 @@ void HighScoresDialog::updateWidgets(bool init)
|
||||||
myNameWidgets[r]->setLabel(myNames[r]);
|
myNameWidgets[r]->setLabel(myNames[r]);
|
||||||
myDateWidgets[r]->setLabel(myDates[r]);
|
myDateWidgets[r]->setLabel(myDates[r]);
|
||||||
|
|
||||||
if (r == myEditRank)
|
if (static_cast<Int32>(r) == myEditRank)
|
||||||
{
|
{
|
||||||
myNameWidgets[r]->setFlags(EditTextWidget::FLAG_INVISIBLE);
|
myNameWidgets[r]->setFlags(EditTextWidget::FLAG_INVISIBLE);
|
||||||
myEditNameWidgets[r]->clearFlags(EditTextWidget::FLAG_INVISIBLE);
|
myEditNameWidgets[r]->clearFlags(EditTextWidget::FLAG_INVISIBLE);
|
||||||
|
@ -384,7 +384,7 @@ void HighScoresDialog::handlePlayedVariation()
|
||||||
Int32 newSpecial = instance().highScores().special();
|
Int32 newSpecial = instance().highScores().special();
|
||||||
bool scoreInvert = instance().highScores().scoreInvert();
|
bool scoreInvert = instance().highScores().scoreInvert();
|
||||||
|
|
||||||
for (myHighScoreRank = 0; myHighScoreRank < NUM_RANKS; ++myHighScoreRank)
|
for (myHighScoreRank = 0; myHighScoreRank < static_cast<Int32>(NUM_RANKS); ++myHighScoreRank)
|
||||||
{
|
{
|
||||||
if ((!scoreInvert && newScore > myHighScores[myHighScoreRank]) ||
|
if ((!scoreInvert && newScore > myHighScores[myHighScoreRank]) ||
|
||||||
((scoreInvert && newScore < myHighScores[myHighScoreRank]) || myHighScores[myHighScoreRank] == 0))
|
((scoreInvert && newScore < myHighScores[myHighScoreRank]) || myHighScores[myHighScoreRank] == 0))
|
||||||
|
@ -393,10 +393,10 @@ void HighScoresDialog::handlePlayedVariation()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myHighScoreRank < NUM_RANKS)
|
if (myHighScoreRank < static_cast<Int32>(NUM_RANKS))
|
||||||
{
|
{
|
||||||
myEditRank = myHighScoreRank;
|
myEditRank = myHighScoreRank;
|
||||||
for (Int32 r = NUM_RANKS - 1; r > myHighScoreRank; --r)
|
for (uInt32 r = NUM_RANKS - 1; static_cast<Int32>(r) > myHighScoreRank; --r)
|
||||||
{
|
{
|
||||||
myHighScores[r] = myHighScores[r - 1];
|
myHighScores[r] = myHighScores[r - 1];
|
||||||
mySpecials[r] = mySpecials[r - 1];
|
mySpecials[r] = mySpecials[r - 1];
|
||||||
|
@ -416,7 +416,7 @@ void HighScoresDialog::handlePlayedVariation()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void HighScoresDialog::deleteRank(int rank)
|
void HighScoresDialog::deleteRank(int rank)
|
||||||
{
|
{
|
||||||
for (Int32 r = rank; r < NUM_RANKS - 1; ++r)
|
for (uInt32 r = rank; r < NUM_RANKS - 1; ++r)
|
||||||
{
|
{
|
||||||
myHighScores[r] = myHighScores[r + 1];
|
myHighScores[r] = myHighScores[r + 1];
|
||||||
mySpecials[r] = mySpecials[r + 1];
|
mySpecials[r] = mySpecials[r + 1];
|
||||||
|
@ -510,7 +510,7 @@ void HighScoresDialog::saveHighScores(Int32 variation) const
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void HighScoresDialog::loadHighScores(Int32 variation)
|
void HighScoresDialog::loadHighScores(Int32 variation)
|
||||||
{
|
{
|
||||||
for (Int32 r = 0; r < NUM_RANKS; ++r)
|
for (uInt32 r = 0; r < NUM_RANKS; ++r)
|
||||||
{
|
{
|
||||||
myHighScores[r] = 0;
|
myHighScores[r] = 0;
|
||||||
mySpecials[r] = 0;
|
mySpecials[r] = 0;
|
||||||
|
@ -562,7 +562,7 @@ bool HighScoresDialog::save(Serializer& out, Int32 variation) const
|
||||||
|
|
||||||
out.putString(myMD5);
|
out.putString(myMD5);
|
||||||
out.putInt(variation);
|
out.putInt(variation);
|
||||||
for (Int32 r = 0; r < NUM_RANKS; ++r)
|
for (uInt32 r = 0; r < NUM_RANKS; ++r)
|
||||||
{
|
{
|
||||||
out.putInt(myHighScores[r]);
|
out.putInt(myHighScores[r]);
|
||||||
out.putInt(mySpecials[r]);
|
out.putInt(mySpecials[r]);
|
||||||
|
@ -588,7 +588,7 @@ bool HighScoresDialog::load(Serializer& in, Int32 variation)
|
||||||
if (Int32(in.getInt()) != variation)
|
if (Int32(in.getInt()) != variation)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (Int32 r = 0; r < NUM_RANKS; ++r)
|
for (uInt32 r = 0; r < NUM_RANKS; ++r)
|
||||||
{
|
{
|
||||||
myHighScores[r] = in.getInt();
|
myHighScores[r] = in.getInt();
|
||||||
mySpecials[r] = in.getInt();
|
mySpecials[r] = in.getInt();
|
||||||
|
|
Loading…
Reference in New Issue