From aa0dc0b9ff2564360572c8e44f617439b9ba9305 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 14 Feb 2020 13:49:48 +0100 Subject: [PATCH] get current data for HighScoresDialog define, load and store "special" value --- src/common/HighScoresManager.cxx | 104 ++++++++++++++++++++++-- src/common/HighScoresManager.hxx | 16 +++- src/common/stella.pro | 4 +- src/gui/GameInfoDialog.cxx | 73 ++++++++--------- src/gui/GameInfoDialog.hxx | 6 +- src/gui/HighScoresDialog.cxx | 132 ++++++++++++++++++++++++------- src/gui/HighScoresDialog.hxx | 30 +++++-- 7 files changed, 272 insertions(+), 93 deletions(-) diff --git a/src/common/HighScoresManager.cxx b/src/common/HighScoresManager.cxx index a16fe75ec..c07bebca5 100644 --- a/src/common/HighScoresManager.cxx +++ b/src/common/HighScoresManager.cxx @@ -130,12 +130,14 @@ bool HighScoresManager::get(const Properties& props, uInt32& numPlayersR, uInt32 info.scoreBCD = scoreBCD(props); info.varsBCD = varBCD(props); info.varsZeroBased = varZeroBased(props); - info.specialBCD = false; // TODO - info.specialZeroBased = true; // TODO + info.special = specialLabel(props); + info.specialBCD = specialBCD(props); + info.specialZeroBased = specialZeroBased(props); info.playersAddr = playerAddress(props); info.varsAddr = varAddress(props); - info.specialAddr = 0; // TODO + info.specialAddr = specialAddress(props); + for (uInt32 p = 0; p < MAX_PLAYERS; ++p) { if (p < numPlayersR) @@ -167,12 +169,20 @@ void HighScoresManager::set(Properties& props, uInt32 numPlayers, uInt32 numVari props.set(PropType::Cart_Variations, to_string(min(numVariations, MAX_VARIATIONS))); // fill from the back to skip default values - if (info.varsZeroBased != DEFAULT_VARS_ZERO_BASED) - output = info.varsZeroBased ? ",1" : ",0"; + if (output.length() || info.specialZeroBased != DEFAULT_SPECIAL_ZERO_BASED) + output = info.specialZeroBased ? ",1" : ",0"; + if (output.length() || info.specialBCD != DEFAULT_SPECIAL_BCD) + output.insert(0, info.specialBCD ? ",B" : ",D"); + if (output.length() || !info.special.empty()) + output.insert(0, "," + info.special); + + if (output.length() || info.varsZeroBased != DEFAULT_VARS_ZERO_BASED) + 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.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) @@ -187,10 +197,12 @@ void HighScoresManager::set(Properties& props, uInt32 numPlayers, uInt32 numVari } // add optional addresses - if (numVariations != DEFAULT_VARIATION || numPlayers != DEFAULT_PLAYER) + if (numVariations != DEFAULT_VARIATION || numPlayers != DEFAULT_PLAYER || !info.special.empty()) buf << info.varsAddr << "," ; - if (numPlayers != DEFAULT_PLAYER) + if (numPlayers != DEFAULT_PLAYER || !info.special.empty()) buf << info.playersAddr << "," ; + if (!info.special.empty()) + buf << info.specialAddr << "," ; output = buf.str(); output.pop_back(); @@ -202,7 +214,7 @@ uInt32 HighScoresManager::numDigits(const Properties& props) const { string digits = getPropIdx(props, PropType::Cart_Formats, 0); - return min(uInt32(stringToInt(digits, DEFAULT_DIGITS)), MAX_DIGITS); + return min(uInt32(stringToInt(digits, DEFAULT_DIGITS)), MAX_SCORE_DIGITS); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -237,6 +249,36 @@ bool HighScoresManager::varZeroBased(const Properties& props) const return zeroBased == EmptyString ? DEFAULT_VARS_ZERO_BASED : zeroBased != "0"; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string HighScoresManager::specialLabel(const Properties& props) const +{ + string orgLabel, label; + + // some ugly formatting + orgLabel = label = getPropIdx(props, PropType::Cart_Formats, 5); + label = BSPF::toLowerCase(label); + label[0] = orgLabel[0]; + + return label; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool HighScoresManager::specialBCD(const Properties& props) const +{ + string bcd = getPropIdx(props, PropType::Cart_Formats, 6); + + return bcd == EmptyString ? DEFAULT_SPECIAL_BCD : bcd == "B"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool HighScoresManager::specialZeroBased(const Properties& props) const +{ + string zeroBased = getPropIdx(props, PropType::Cart_Formats, 7); + + return zeroBased == EmptyString ? DEFAULT_SPECIAL_ZERO_BASED : zeroBased != "0"; +} + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool HighScoresManager::playerZeroBased(const Properties& props) const { @@ -262,6 +304,16 @@ uInt16 HighScoresManager::varAddress(const Properties& props) const return stringToIntBase16(addr, DEFAULT_ADDRESS); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt16 HighScoresManager::specialAddress(const Properties& props) const +{ + uInt32 idx = numAddrBytes(props) * numPlayers(props) + 2; + string addr = getPropIdx(props, PropType::Cart_Addresses, idx); + + return stringToIntBase16(addr, DEFAULT_ADDRESS); +} + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt32 HighScoresManager::numAddrBytes(Int32 digits, Int32 trailing) const { @@ -311,6 +363,14 @@ Int32 HighScoresManager::player() const return player(addr, numPlayers(props), playerZeroBased(props)); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string HighScoresManager::specialLabel() const +{ + Properties props; + + return specialLabel(properties(props)); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Int32 HighScoresManager::variation(uInt16 addr, bool varBCD, bool zeroBased, uInt32 numVariations) const @@ -398,6 +458,34 @@ Int32 HighScoresManager::score() const return score(currentPlayer, numBytes, trailingZeroes(props), scoreBCD(props), scoreAddr); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Int32 HighScoresManager::special() const +{ + Properties props; + uInt16 addr = specialAddress(properties(props)); + + if (addr == DEFAULT_ADDRESS) + return -1; + + return special(addr, specialBCD(props), specialZeroBased(props)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Int32 HighScoresManager::special(uInt16 addr, bool varBCD, bool zeroBased) const +{ + if (!myOSystem.hasConsole()) + return -1; + + Int32 var = peek(addr); + + if (varBCD) + var = fromBCD(var); + + var += zeroBased ? 1 : 0; + + return var; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Int32 HighScoresManager::fromBCD(uInt8 bcd) const { diff --git a/src/common/HighScoresManager.hxx b/src/common/HighScoresManager.hxx index 1a9e21e35..939ef3d94 100644 --- a/src/common/HighScoresManager.hxx +++ b/src/common/HighScoresManager.hxx @@ -22,8 +22,11 @@ class OSystem; namespace HSM { static const uInt32 MAX_PLAYERS = 4; + static const uInt32 MAX_ADDR_CHARS = 4; + static const uInt32 MAX_SCORE_DIGITS = 6; static const uInt32 MAX_SCORE_ADDR = 3; - static const uInt32 MAX_SPECIAL = 5; + 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; @@ -100,16 +103,19 @@ class HighScoresManager Int32 score(uInt32 player, 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; + Int32 special() const; private: static const uInt32 MAX_VARIATIONS = 256; - static const uInt32 MAX_DIGITS = 6; static const uInt32 MAX_TRAILING = 3; static const uInt32 DEFAULT_DIGITS = 4; static const uInt32 DEFAULT_TRAILING = 0; @@ -117,6 +123,8 @@ class HighScoresManager 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 @@ -124,11 +132,15 @@ class HighScoresManager 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; bool scoreBCD(const Properties& props) const; bool varBCD(const Properties& props) const; bool varZeroBased(const Properties& props) const; + string specialLabel(const Properties& props) const; + bool specialBCD(const Properties& props) const; + bool specialZeroBased(const Properties& props) const; bool playerZeroBased(const Properties& props) const; // Calculate the number of bytes for one player's score from property parameters diff --git a/src/common/stella.pro b/src/common/stella.pro index a6cb54616..c872eca64 100644 --- a/src/common/stella.pro +++ b/src/common/stella.pro @@ -95,7 +95,7 @@ "Cart.ModelNo" "AZ-036-04" "Cart.Name" "H.E.R.O. (1984) (Activision)" "Cart.Variations" "5" -"Cart.Formats" "6,0,B,B,1" -"Cart.Addresses" "B7,B8,B9,B4" +"Cart.Formats" "6,0,B,B,1,LEVEL,B,1" +"Cart.Addresses" "B7,B8,B9,B4,0,F5" "" diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx index 5e1061c72..2fabcbd2a 100644 --- a/src/gui/GameInfoDialog.cxx +++ b/src/gui/GameInfoDialog.cxx @@ -372,17 +372,15 @@ GameInfoDialog::GameInfoDialog( xpos += 20; ypos += lineHeight + VGAP; items.clear(); - VarList::push_back(items, "1", "1"); - VarList::push_back(items, "2", "2"); - VarList::push_back(items, "3", "3"); - VarList::push_back(items, "4", "4"); + 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"); 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); - int awidth = font.getStringWidth("FFFF") + 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 "); @@ -418,9 +416,9 @@ GameInfoDialog::GameInfoDialog( ypos += lineHeight + VGAP; mySpecialLabel = new StaticTextWidget(myTab, font, xpos, ypos + 1, "Special "); - mySpecial = new EditTextWidget(myTab, font, mySpecialLabel->getRight(), ypos - 1, swidth, lineHeight); - mySpecial->setTextFilter(fSpecial); - wid.push_back(mySpecial); + 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 "); mySpecialAddress = new EditTextWidget(myTab, font, mySpecialAddressLabel->getRight(), ypos - 1, awidth, lineHeight); @@ -440,12 +438,8 @@ GameInfoDialog::GameInfoDialog( vwidth = font.getStringWidth("AB") + 4; items.clear(); - VarList::push_back(items, "1", "1"); - VarList::push_back(items, "2", "2"); - VarList::push_back(items, "3", "3"); - VarList::push_back(items, "4", "4"); - VarList::push_back(items, "5", "5"); - VarList::push_back(items, "6", "6"); + 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, @@ -453,10 +447,8 @@ GameInfoDialog::GameInfoDialog( wid.push_back(myScoreDigits); items.clear(); - VarList::push_back(items, "0", "0"); - VarList::push_back(items, "1", "1"); - VarList::push_back(items, "2", "2"); - VarList::push_back(items, "3", "3"); + for (int i = 0; i <= HSM::MAX_SCORE_DIGITS - 3; ++i) + 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 "); @@ -699,22 +691,22 @@ void GameInfoDialog::loadHighScoresProperties(const Properties& props) myScoreBCD->setState(info.scoreBCD); myVarsBCD->setState(info.varsBCD); myVarsZeroBased->setState(info.varsZeroBased); - mySpecial->setText(info.special); + mySpecialName->setText(info.special); mySpecialBCD->setState(info.specialBCD); mySpecialZeroBased->setState(info.specialZeroBased); ss.str(""); - ss << hex << right << setw(4) << setfill(' ') + ss << hex << right //<< setw(HSM::MAX_ADDR_CHARS) << setfill(' ') << uppercase << info.playersAddr; myPlayersAddress->setText(ss.str()); ss.str(""); - ss << hex << right << setw(4) << setfill(' ') + ss << hex << right //<< setw(HSM::MAX_ADDR_CHARS) << setfill(' ') << uppercase << info.varsAddr; myVarAddress->setText(ss.str()); ss.str(""); - ss << hex << right << setw(4) << setfill(' ') + ss << hex << right //<< setw(HSM::MAX_ADDR_CHARS) << setfill(' ') << uppercase << info.specialAddr; mySpecialAddress->setText(ss.str()); @@ -726,7 +718,7 @@ void GameInfoDialog::loadHighScoresProperties(const Properties& props) if (p < numPlayers) { ss.str(""); - ss << hex << right << setw(4) << setfill('0') + ss << hex << right //<< setw(HSM::MAX_ADDR_CHARS) << setfill(' ') << uppercase << info.scoresAddr[p][a]; myScoreAddress[p][a]->setText(ss.str()); } @@ -814,11 +806,22 @@ void GameInfoDialog::saveHighScoresProperties() if (myHighScores->getState()) { + string strText; + + // limit variants and special size + strText = myVariations->getText(); + strText = strText.substr(0, 3); + myVariations->setText(strText); + + strText = mySpecialName->getText(); + strText = strText.substr(0, HSM::MAX_SPECIAL_NAME); + mySpecialName->setText(strText); + // fill format info.varsZeroBased = myVarsZeroBased->getState(); info.varsBCD = myVarsBCD->getState(); - info.special = mySpecial->getText(); + info.special = mySpecialName->getText(); info.specialZeroBased = mySpecialZeroBased->getState(); info.specialBCD = mySpecialBCD->getState(); @@ -1007,19 +1010,9 @@ void GameInfoDialog::updateHighScoresWidgets() uInt32 players = myPlayers->getSelected() + 1; bool enablePlayers = enable && players > 1; bool enableVars = enable && myVariations->getText() > "1"; - bool enableSpecial = enable && !mySpecial->getText().empty(); + bool enableSpecial = enable && !mySpecialName->getText().empty(); uInt32 numAddr = instance().highScores().numAddrBytes(myScoreDigits->getSelected() + 1, myTrailingZeroes->getSelected()); - string strText; - - // limit variants and special size - strText = myVariations->getText(); - strText = strText.substr(0, 3); - myVariations->setText(strText); - - strText = mySpecial->getText(); - strText = strText.substr(0, HSM::MAX_SPECIAL); - mySpecial->setText(strText); // enable widgets myPlayersLabel->setEnabled(enable); @@ -1040,8 +1033,8 @@ void GameInfoDialog::updateHighScoresWidgets() myVarsZeroBased->setEnabled(enableVars); mySpecialLabel->setEnabled(enable); - mySpecial->setEnabled(enable); - mySpecial->setEditable(enable); + mySpecialName->setEnabled(enable); + mySpecialName->setEditable(enable); mySpecialAddressLabel->setEnabled(enableSpecial); mySpecialAddress->setEnabled(enableSpecial); mySpecialAddress->setEditable(enableSpecial); @@ -1049,7 +1042,6 @@ void GameInfoDialog::updateHighScoresWidgets() mySpecialBCD->setEnabled(enableSpecial); mySpecialZeroBased->setEnabled(enableSpecial); - mySpecialLabel->setEnabled(enable); myScoreDigitsLabel->setEnabled(enable); myScoreDigits->setEnabled(enable); myScoreBCD->setEnabled(enable); @@ -1123,8 +1115,7 @@ void GameInfoDialog::setAddressVal(EditTextWidget* addressWidget, EditTextWidget // limit address size strAddr = addressWidget->getText(); - strAddr = strAddr.substr(0, 4); - addressWidget->setText(strAddr); + strAddr = strAddr.substr(0, HSM::MAX_ADDR_CHARS); if (instance().hasConsole() && valWidget->isEnabled()) { @@ -1139,7 +1130,7 @@ void GameInfoDialog::setAddressVal(EditTextWidget* addressWidget, EditTextWidget // format output and display in value widget if (isBCD) ss << hex; - ss << right << setw(2) << setfill(' ') + ss << right //<< setw(2) << setfill(' ') << uppercase << uInt16(val); valWidget->setText(ss.str()); } diff --git a/src/gui/GameInfoDialog.hxx b/src/gui/GameInfoDialog.hxx index ec969fa9d..d47b086af 100644 --- a/src/gui/GameInfoDialog.hxx +++ b/src/gui/GameInfoDialog.hxx @@ -131,7 +131,7 @@ class GameInfoDialog : public Dialog, public CommandSender CheckboxWidget* myVarsZeroBased{nullptr}; StaticTextWidget* mySpecialLabel{nullptr}; - EditTextWidget* mySpecial{nullptr}; + EditTextWidget* mySpecialName{nullptr}; StaticTextWidget* mySpecialAddressLabel{nullptr}; EditTextWidget* mySpecialAddress{nullptr}; EditTextWidget* mySpecialAddressVal{nullptr}; @@ -147,8 +147,8 @@ class GameInfoDialog : public Dialog, public CommandSender 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; - StaticTextWidget* myCurrentScore[HSM::MAX_PLAYERS]; + StaticTextWidget* myCurrentScoreLabel{nullptr}; + StaticTextWidget* myCurrentScore[HSM::MAX_PLAYERS]{nullptr}; enum { kVCenterChanged = 'Vcch', diff --git a/src/gui/HighScoresDialog.cxx b/src/gui/HighScoresDialog.cxx index 0545988cc..20014d8b2 100644 --- a/src/gui/HighScoresDialog.cxx +++ b/src/gui/HighScoresDialog.cxx @@ -55,7 +55,7 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent, //items.clear(); StaticTextWidget* s = new StaticTextWidget(this, font, xpos, ypos + 1, "Variation "); - myVariation = new PopUpWidget(this, font, s->getRight(), ypos, + myVariationWidget = new PopUpWidget(this, font, s->getRight(), ypos, font.getStringWidth("256") - 4, lineHeight, items, "", 0, 0); ypos += lineHeight + VGAP * 4; @@ -69,7 +69,7 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent, new StaticTextWidget(this, font, xposRank, ypos + 1, "Rank"); new StaticTextWidget(this, font, xposScore, ypos + 1, "Score"); - new StaticTextWidget(this, font, xposSpecial, ypos + 1, "Round"); + mySpecialLabelWidget = new StaticTextWidget(this, font, xposSpecial, ypos + 1, "Round"); new StaticTextWidget(this, font, xposName - 2, ypos + 1, "Name"); new StaticTextWidget(this, font, xposDate+16, ypos + 1, "Date Time"); @@ -77,25 +77,24 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent, for (uInt32 p = 0; p < NUM_POSITIONS; ++p) { - myPositions[p] = new StaticTextWidget(this, font, xposRank, ypos + 1, - (p < 9 ? " " : "") + std::to_string(p + 1) + ". "); - myScores[p] = new StaticTextWidget(this, font, xposScore, ypos + 1, "123456"); - mySpecials[p] = new StaticTextWidget(this, font, xposSpecial + 8, ypos + 1, "123"); - myEditNames[p] = new EditTextWidget(this, font, xposName, ypos - 1, nWidth, lineHeight, "JTZ"); - //myEditNames[p]->setEditable(false); - myEditNames[p]->setFlags(EditTextWidget::FLAG_INVISIBLE); - wid.push_back(myEditNames[p]); - myNames[p] = new StaticTextWidget(this, font, xposName + 2, ypos + 1, "JTZ"); + myPositionsWidget[p] = new StaticTextWidget(this, font, xposRank + 8, ypos + 1, + (p < 9 ? " " : "") + std::to_string(p + 1)); + myScoresWidget[p] = new StaticTextWidget(this, font, xposScore, ypos + 1, "123456"); + mySpecialsWidget[p] = new StaticTextWidget(this, font, xposSpecial + 8, ypos + 1, "123"); + myEditNamesWidget[p] = new EditTextWidget(this, font, xposName, ypos - 1, nWidth, lineHeight, "JTZ"); + myEditNamesWidget[p]->setFlags(EditTextWidget::FLAG_INVISIBLE); + wid.push_back(myEditNamesWidget[p]); + myNamesWidget[p] = new StaticTextWidget(this, font, xposName + 2, ypos + 1, "JTZ"); //new StaticTextWidget(this, font, xposDate, ypos + 1, "12.02.20 17:15"); //new StaticTextWidget(this, font, xposDate, ypos + 1, "02/12/20 12:30am"); - myDates[p] = new StaticTextWidget(this, font, xposDate, ypos + 1, "12-02-20 17:15"); + myDatesWidget[p] = new StaticTextWidget(this, font, xposDate, ypos + 1, "12-02-20 17:15"); ypos += lineHeight + VGAP; } ypos += VGAP * 2; - myMD5 = new StaticTextWidget(this, ifont, xpos, ypos + 1, "MD5: 9ad36e699ef6f45d9eb6c4cf90475c9f"); + myMD5Widget = new StaticTextWidget(this, ifont, xpos, ypos + 1, "MD5: 12345678901234567890123456789012"); wid.clear(); addOKCancelBGroup(wid, font); @@ -122,20 +121,27 @@ void HighScoresDialog::loadConfig() items.clear(); + myVariation = instance().highScores().variation(); + for (Int32 i = 1; i <= instance().highScores().numVariations(); ++i) { ostringstream buf; buf << std::setw(3) << std::setfill(' ') << i; VarList::push_back(items, buf.str(), i); } - myVariation->addItems(items); - myVariation->setSelected(instance().highScores().variation()); + myVariationWidget->addItems(items); + myScore = instance().highScores().score(); + mySpecial = instance().highScores().special(); + myVariationWidget->setSelected(myVariation); + + + ///////////////////////////////////////////////////////////////////////////////////////////////// // mock data - const string SCORES[NUM_POSITIONS] = {"999999", "250000", "100000", " 50000", " 20000", - " 5000", " 2000", " 700", " 200", " -"}; - const string SPECIALS[NUM_POSITIONS] = {"200", "150", " 90", " 70", " 45", - " 30", " 25", " 10", " 7", " -"}; + const Int32 SCORES[NUM_POSITIONS] = {999999, 250000, 100000, 50000, 20000, + 5000, 2000, 200, 20, 0}; + const Int32 SPECIALS[NUM_POSITIONS] = {200, 150, 90, 70, 45, + 30, 25, 10, 7, 0}; const string NAMES[NUM_POSITIONS] = {"RAM", "CDW", "AD ", "JTZ", "DOA", "ROM", "VCS", "N.S", "JWC", " -"}; const string DATES[NUM_POSITIONS] = {"19-12-24 21:00", "19-07-18 00:00", "20-01-01 12:00", @@ -145,18 +151,66 @@ void HighScoresDialog::loadConfig() for (Int32 p = 0; p < NUM_POSITIONS; ++p) { - myScores[p]->setLabel(SCORES[p]); - mySpecials[p]->setLabel(SPECIALS[p]); - myNames[p]->setLabel(NAMES[p]); - myEditNames[p]->setText(NAMES[p]); - myDates[p]->setLabel(DATES[p]); + myScores[p] = SCORES[p]; + mySpecials[p] = SPECIALS[p]; + myNames[p] = NAMES[p]; + myDates[p] = DATES[p]; + } + ///////////////////////////////////////////////////////////////////////////////////////////////// + + Int32 pos; + + mySpecialLabelWidget->setLabel(instance().highScores().specialLabel()); + + for (Int32 p = 0; p < NUM_POSITIONS; ++p) + myEditNamesWidget[p]->setFlags(EditTextWidget::FLAG_INVISIBLE); + + if (myScore > 0) + { + for (pos = 0; pos < NUM_POSITIONS; ++pos) + { + if (myScore > myScores[pos] || + (myScore == myScores[pos] && mySpecial > mySpecials[pos])) + break; + } + + if (pos < NUM_POSITIONS) + { + for (Int32 p = NUM_POSITIONS - 1; p > pos; --p) + { + myScores[p] = myScores[p - 1]; + mySpecials[p] = mySpecials[p - 1]; + myNames[p] = myNames[p - 1]; + myDates[p] = myDates[p - 1]; + } + myScores[pos] = myScore; + myNames[pos] = ""; + mySpecials[pos] = mySpecial; + myDates[pos] = now(); + + myEditNamesWidget[pos]->clearFlags(EditTextWidget::FLAG_INVISIBLE); + } } - //myEditNames[4]->setEditable(true); + for (Int32 p = 0; p < NUM_POSITIONS; ++p) + { + ostringstream buf; + + buf << std::setw(HSM::MAX_SCORE_DIGITS) << std::setfill(' ') << myScores[p]; + myScoresWidget[p]->setLabel(buf.str()); + buf.str(""); + buf << std::setw(HSM::MAX_SPECIAL_DIGITS) << std::setfill(' ') << mySpecials[p]; + mySpecialsWidget[p]->setLabel(buf.str()); + myNamesWidget[p]->setLabel(myNames[p]); + myEditNamesWidget[p]->setText(myNames[p]); + myDatesWidget[p]->setLabel(myDates[p]); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void HighScoresDialog::saveConfig() +{ - //myNames[3]->setHeight(1); - //myNames[3]->setWidth(0); - myEditNames[4]->clearFlags(EditTextWidget::FLAG_INVISIBLE); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -165,12 +219,32 @@ void HighScoresDialog::handleCommand(CommandSender* sender, int cmd, int data, i switch (cmd) { case kOKCmd: + saveConfig(); case kCloseCmd: instance().eventHandler().leaveMenuMode(); - instance().eventHandler().handleEvent(Event::ExitMode); +// instance().eventHandler().handleEvent(Event::ExitMode); + +// case GuiObject::kOKCmd: +// close(); break; default: Dialog::handleCommand(sender, cmd, data, 0); } } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string HighScoresDialog::now() const +{ + std::tm now = BSPF::localTime(); + ostringstream ss; + + ss << std::setfill('0') << std::right + << std::setw(2) << (now.tm_year - 100) << '-' + << std::setw(2) << (now.tm_mon + 1) << '-' + << std::setw(2) << now.tm_mday << " " + << std::setw(2) << now.tm_hour << ":" + << std::setw(2) << now.tm_min; + + return ss.str(); +} diff --git a/src/gui/HighScoresDialog.hxx b/src/gui/HighScoresDialog.hxx index ef701c646..4bb89bf5b 100644 --- a/src/gui/HighScoresDialog.hxx +++ b/src/gui/HighScoresDialog.hxx @@ -44,17 +44,31 @@ class HighScoresDialog : public Dialog protected: void loadConfig() override; + void saveConfig() override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; private: - PopUpWidget* myVariation; - StaticTextWidget* myPositions[NUM_POSITIONS]; - StaticTextWidget* myScores[NUM_POSITIONS]; - StaticTextWidget* mySpecials[NUM_POSITIONS]; - StaticTextWidget* myNames[NUM_POSITIONS]; - EditTextWidget* myEditNames[NUM_POSITIONS]; - StaticTextWidget* myDates[NUM_POSITIONS]; - StaticTextWidget* myMD5; + Int32 myVariation; + Int32 myScore; + Int32 mySpecial; + + Int32 myScores[NUM_POSITIONS]; + Int32 mySpecials[NUM_POSITIONS]; + string myNames[NUM_POSITIONS]; + string myDates[NUM_POSITIONS]; + string myMD5; + + PopUpWidget* myVariationWidget{nullptr}; + StaticTextWidget* mySpecialLabelWidget{nullptr}; + StaticTextWidget* myPositionsWidget[NUM_POSITIONS]{nullptr}; + StaticTextWidget* myScoresWidget[NUM_POSITIONS]{nullptr}; + StaticTextWidget* mySpecialsWidget[NUM_POSITIONS]{nullptr}; + StaticTextWidget* myNamesWidget[NUM_POSITIONS]{nullptr}; + EditTextWidget* myEditNamesWidget[NUM_POSITIONS]{nullptr}; + StaticTextWidget* myDatesWidget[NUM_POSITIONS]{nullptr}; + StaticTextWidget* myMD5Widget{nullptr}; + + string now() const; private: // Following constructors and assignment operators not supported