diff --git a/src/common/HighScoresManager.cxx b/src/common/HighScoresManager.cxx new file mode 100644 index 000000000..32e1fd474 --- /dev/null +++ b/src/common/HighScoresManager.cxx @@ -0,0 +1,375 @@ +//============================================================================ +// +// 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 per player + 0, ; trailing zeroes + B, ; score format (BCD, HEX) + B, ; variation format (BCD, HEX) + 0, ; zero-based variation + Addresses (in hex): + n*p-times xx, ; score addresses for each player, high to low + xx, ; variation address (if more than 1 variation) + xx, ; player address (if more than 1 player) + + TODO: + - variation bits (Centipede) + - player bits (Asteroids, Space Invaders) + - score swaps (Asteroids) +*/ + +#include "OSystem.hxx" +//#include "Props.hxx" +#include "PropsSet.hxx" +#include "Console.hxx" +#include "Launcher.hxx" +#include "System.hxx" + +#include "HighScoresManager.hxx" + + + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +HighScoresManager::HighScoresManager(OSystem& osystem) + : myOSystem(osystem) +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Int16 HighScoresManager::peek(uInt16 addr) +{ + if (myOSystem.hasConsole()) + { + System& system = myOSystem.console().system(); + return system.peek(addr); + } + return -1; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Properties& HighScoresManager::properties(Properties& props) const +{ + + if (myOSystem.hasConsole()) + { + props = myOSystem.console().properties(); + } + else + { + const string& md5 = myOSystem.launcher().selectedRomMD5(); + myOSystem.propSet().getMD5(md5, props); + } + return props; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string HighScoresManager::getPropIdx(PropType type, uInt32 idx) const +{ + Properties props; + string property = properties(props).get(type); + std::replace(property.begin(), property.end(), ',', ' '); + std::replace(property.begin(), property.end(), '|', ' '); + istringstream buf(property); + string result; + + for (uInt32 i = 0; i <= idx; ++i) + if(!(buf >> result)) + return ""; + + return result; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt32 HighScoresManager::numPlayers() const +{ + string numPlayers = getPropIdx(PropType::Cart_Players); + + return numPlayers == EmptyString ? 1 : std::min(uInt32(stoi(numPlayers)), MAX_PLAYERS); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt32 HighScoresManager::numVariations() const +{ + string numVariations = getPropIdx(PropType::Cart_Variations); + + return numVariations == EmptyString ? 1 : std::min(stoi(numVariations), 256); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool HighScoresManager::getFormats(Formats& formats) const +{ + formats.numDigits = numDigits(); + formats.trailingZeroes = trailingZeroes(); + formats.scoreBCD = scoreBCD(); + formats.varBCD = varBCD(); + formats.varZeroBased = varZeroBased(); + + return true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt32 HighScoresManager::numDigits() const +{ + string digits = getPropIdx(PropType::Cart_Formats, 0); + + return digits == EmptyString ? 4 : stoi(digits); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt32 HighScoresManager::trailingZeroes() const +{ + string trailing = getPropIdx(PropType::Cart_Formats, 1); + + return trailing == EmptyString ? 0 : stoi(trailing);} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool HighScoresManager::scoreBCD() const +{ + string bcd = getPropIdx(PropType::Cart_Formats, 2); + + return bcd == EmptyString ? true : bcd == "B"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool HighScoresManager::varBCD() const +{ + string bcd = getPropIdx(PropType::Cart_Formats, 3); + + return bcd == EmptyString ? true : bcd == "B"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool HighScoresManager::varZeroBased() const +{ + string zeroBased = getPropIdx(PropType::Cart_Formats, 4); + + return zeroBased == EmptyString ? false : zeroBased != "0"; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool HighScoresManager::getAddresses(Addresses& addresses) const +{ + addresses.playerAddr = playerAddress(); + addresses.varAddr = varAddress(); + for (uInt32 p = 0; p < MAX_PLAYERS; ++p) + { + if (p < numPlayers()) + { + for (uInt32 a = 0; a < numAddrBytes(); ++a) + { + uInt32 idx = p * numAddrBytes() + a; + string addr = getPropIdx(PropType::Cart_Addresses, idx); + + addresses.scoreAddr[p][a] = (addr == EmptyString ? 0 : stoi(addr, nullptr, 16)); + } + } + else + for (uInt32 a = 0; a < numAddrBytes(); ++a) + addresses.scoreAddr[p][a] = -1; + } + + return (EmptyString != getPropIdx(PropType::Cart_Addresses, 0)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt16 HighScoresManager::playerAddress() const +{ + uInt32 idx = numAddrBytes() * numPlayers() + 1; + string addr = getPropIdx(PropType::Cart_Addresses, idx); + + return addr == EmptyString ? 0 : stoi(addr, nullptr, 16); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt16 HighScoresManager::varAddress() const +{ + uInt32 idx = numAddrBytes() * numPlayers(); + string addr = getPropIdx(PropType::Cart_Addresses, idx); + + return addr == EmptyString ? 0 : stoi(addr, nullptr, 16); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +uInt32 HighScoresManager::numAddrBytes(Int32 digits, Int32 trailing) const +{ + return ((digits < 0 ? numDigits() : digits) - (trailing < 0 ? trailingZeroes() : trailing) + 1) / 2; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Int32 HighScoresManager::score(uInt32 player, uInt32 numAddrBytes, bool isBCD) const +{ + if (!myOSystem.hasConsole()) + return -1; + + System& system = myOSystem.console().system(); + Int32 totalScore = 0; + + for (uInt32 b = 0; b < numAddrBytes; ++b) + { + uInt32 idx = player * numAddrBytes + b; + string strAddr = getPropIdx(PropType::Cart_Addresses, idx); + uInt16 addr = (strAddr == EmptyString ? 0 : stoi(strAddr, nullptr, 16)); + uInt32 score; + + totalScore *= isBCD ? 100 : 256; + score = system.peek(addr); + if (isBCD) + { + // verify if score is legit + if (score >= 160) + { + totalScore = -1; + break; + } + score = (score >> 4) * 10 + score % 16; + } + totalScore += score; + } + + if (totalScore != -1) + for (uInt32 i = 0; i < trailingZeroes(); ++i) + totalScore *= 10; + + return totalScore; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Int32 HighScoresManager::score(uInt32 player) const +{ + return score(player, numAddrBytes(), scoreBCD()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool HighScoresManager::parseAddresses(uInt32& variation, uInt32& player, uInt32 scores[]) +{ + variation = 1; player = 0; scores[0] = 0; + + if (!myOSystem.hasConsole()) + return false; + + System& system = myOSystem.console().system(); + + + Properties props; + string formats = properties(props).get(PropType::Cart_Formats); + string addresses = properties(props).get(PropType::Cart_Addresses); + char scoreFormat; + char varFormat; + Int16 addr; + Int32 varAdd, numScoreAddr, scoreMult; + + // Since istringstream swallows whitespace, we have to make the + // delimiters be spaces + std::replace(formats.begin(), formats.end(), ',', ' '); + std::replace(formats.begin(), formats.end(), '|', ' '); + std::replace(addresses.begin(), addresses.end(), ',', ' '); + std::replace(addresses.begin(), addresses.end(), '|', ' '); + istringstream addrBuf(addresses); + istringstream formatBuf(formats); + + // 1. retrieve formats + if (!(formatBuf >> numScoreAddr)) + numScoreAddr = 2; + if (!(formatBuf >> scoreMult)) + scoreMult = 1; + if (!(formatBuf >> scoreFormat)) + scoreFormat = 'B'; + if (!(formatBuf >> varFormat)) + varFormat = 'B'; + if (!(formatBuf >> varAdd)) + varAdd = 0; + + // 2. retrieve current scores for all players + for (uInt32 i = 0; i < numPlayers(); ++i) + { + Int32 totalScore = 0; + + for (int j = 0; j < numScoreAddr; ++j) + { + Int32 score; + + if (!(addrBuf >> std::hex >> addr)) + return false; + + totalScore *= (scoreFormat == 'B') ? 100 : 256; + + score = system.peek(addr); + if (scoreFormat == 'B') + score = (score >> 4) * 10 + score % 16; + totalScore += score; + } + scores[i] = totalScore * scoreMult; + } + + // 3. retrieve current variation (0..255) + if (numVariations() == 1) + return true; + + if (!(addrBuf >> std::hex >> addr)) + return false; + variation = system.peek(addr); + if (varFormat == 'B') + variation = (variation >> 4) * 10 + variation % 16; + variation += varAdd; + variation = std::min(variation, numVariations()); + + // 4. retrieve current player (0..3) + if (numPlayers() == 1) + return true; + + if (!(addrBuf >> std::hex >> addr)) + return false; + + player = system.peek(addr); + player = std::min(player, numPlayers() - 1); + + return true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Int32 HighScoresManager::variation() +{ + uInt32 variation, player, scores[4]; + + if (parseAddresses(variation, player, scores)) + return variation; + + return -1; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Int32 HighScoresManager::player() +{ + uInt32 variation, player, scores[4]; + + if (parseAddresses(variation, player, scores)) + return player; + + return -1; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Int32 HighScoresManager::score() +{ + uInt32 variation, player, scores[4]; + + if (parseAddresses(variation, player, scores)) + return scores[std::min(player, uInt32(MAX_PLAYERS))]; + + return -1; +} \ No newline at end of file diff --git a/src/common/HighScoresManager.hxx b/src/common/HighScoresManager.hxx new file mode 100644 index 000000000..b98892642 --- /dev/null +++ b/src/common/HighScoresManager.hxx @@ -0,0 +1,97 @@ +//============================================================================ +// +// 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. +//============================================================================ + +#ifndef HIGHSCORES_MANAGER_HXX +#define HIGHSCORES_MANAGER_HXX + +//#include "bspf.hxx" + +class OSystem; + +class HighScoresManager +{ + +public: + + static const uInt32 MAX_PLAYERS = 4; + static const uInt32 MAX_SCORE_ADDR = 3; + + struct Formats { + uInt32 numDigits; + uInt32 trailingZeroes; + bool scoreBCD; + bool varBCD; + bool varZeroBased; + }; + + + struct Addresses { + Int16 scoreAddr[HighScoresManager::MAX_PLAYERS][HighScoresManager::MAX_SCORE_ADDR]; + uInt16 varAddr; + uInt16 playerAddr; + }; + + HighScoresManager(OSystem& osystem); + virtual ~HighScoresManager() = default; + + /* + Methods for returning high scores related variables + */ + uInt32 numVariations() const; + uInt32 numPlayers() const; + + bool getFormats(Formats& formats) const; + bool getAddresses(Addresses& addresses) const; + + uInt32 numDigits() const; + uInt32 trailingZeroes() const; + bool scoreBCD() const; + bool varBCD() const; + bool varZeroBased() const; + + uInt16 varAddress() const; + uInt16 playerAddress() const; + + uInt32 numAddrBytes(Int32 digits = -1, Int32 trailing = -1) const; + + // current values + Int32 player(); + Int32 variation(); + Int32 score(); + + Int32 score(uInt32 player) const; + Int32 score(uInt32 player, uInt32 numAddrBytes, bool isBCD) const; + +private: + Properties& properties(Properties& props) const; + string getPropIdx(PropType type, uInt32 idx = 0) const; + Int16 peek(uInt16 addr); + bool parseAddresses(uInt32& variation, uInt32& player, uInt32 scores[]); + +private: + // Reference to the osystem object + OSystem& myOSystem; + +private: + // Following constructors and assignment operators not supported + HighScoresManager() = delete; + HighScoresManager(const HighScoresManager&) = delete; + HighScoresManager(HighScoresManager&&) = delete; + HighScoresManager& operator=(const HighScoresManager&) = delete; + HighScoresManager& operator=(HighScoresManager&&) = delete; +}; +#endif diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx index 05f4cb2ce..3229717bd 100644 --- a/src/gui/GameInfoDialog.cxx +++ b/src/gui/GameInfoDialog.cxx @@ -20,7 +20,6 @@ #include "Cart.hxx" #include "MouseControl.hxx" #include "SaveKey.hxx" -#include "Dialog.hxx" #include "EditTextWidget.hxx" #include "RadioButtonWidget.hxx" #include "Launcher.hxx" @@ -28,7 +27,6 @@ #include "CartDetector.hxx" #include "ControllerDetector.hxx" #include "PopUpWidget.hxx" -#include "Props.hxx" #include "PropsSet.hxx" #include "TabWidget.hxx" #include "TIAConstants.hxx" @@ -400,10 +398,10 @@ GameInfoDialog::GameInfoDialog( myVarAddressVal = new EditTextWidget(myTab, font, myVarAddress->getRight() + 2, ypos - 1, vwidth, lineHeight); myVarAddressVal->setEditable(false); - myVarBCD = new CheckboxWidget(myTab, font, myVarAddressVal->getRight() + 16, ypos + 1, "BCD", kVarFormatChanged); + myVarBCD = new CheckboxWidget(myTab, font, myVarAddressVal->getRight() + 16, ypos + 1, "BCD", kVarBcdChanged); wid.push_back(myVarBCD); - myVarZeroBased = new CheckboxWidget(myTab, font, myVarBCD->getRight() + 16, ypos + 1, "0-based", kVar0BasedChanged); + myVarZeroBased = new CheckboxWidget(myTab, font, myVarBCD->getRight() + 16, ypos + 1, "0-based", kVarZeroBasedChanged); wid.push_back(myVarZeroBased); ypos += lineHeight + VGAP; @@ -435,10 +433,10 @@ GameInfoDialog::GameInfoDialog( myTrailingZeroesLabel = new StaticTextWidget(myTab, font, myScoreDigits->getRight() + 20, ypos + 1, "0-Digits "); myTrailingZeroes = new PopUpWidget(myTab, font, myTrailingZeroesLabel->getRight(), ypos, pwidth, lineHeight, - items, "", 0, kScoreMultChanged); + items, "", 0, kScoreZeroesChanged); wid.push_back(myTrailingZeroes); - myScoreBCD = new CheckboxWidget(myTab, font, myVarBCD->getLeft(), ypos + 1, "BCD", kScoreFormatChanged); + myScoreBCD = new CheckboxWidget(myTab, font, myVarBCD->getLeft(), ypos + 1, "BCD", kScoreBcdChanged); wid.push_back(myScoreBCD); @@ -461,7 +459,9 @@ GameInfoDialog::GameInfoDialog( myScoreAddressVal[p][a]->setEditable(false); s_xpos += myScoreAddressVal[p][a]->getWidth() + 16; } + myCurrentScore[p] = new StaticTextWidget(myTab, font, s_xpos + 8, ypos + 1, "123456"); } + myCurrentScoreLabel = new StaticTextWidget(myTab, font, myCurrentScore[0]->getLeft(), myScoreBCD->getTop(), "Current"); // Add items for tab 4 addToFocusList(wid, myTab, tabID); @@ -658,19 +658,19 @@ void GameInfoDialog::loadHighScoresProperties(const Properties& props) { HighScoresManager::Formats formats; HighScoresManager::Addresses addresses; - bool enable = instance().highScores().getFormats(formats); + bool enable = instance().highScores().getAddresses(addresses); - enable &= instance().highScores().getAddresses(addresses); // make compiler happy + instance().highScores().getFormats(formats); myHighScores->setState(enable); - if (enable) + myPlayers->setSelected(instance().highScores().numPlayers()); + myVariations->setText(std::to_string(instance().highScores().numVariations())); + + if (true) { ostringstream ss; - myPlayers->setSelected(instance().highScores().numPlayers()); - myVariations->setText(std::to_string(instance().highScores().numVariations())); - myScoreDigits->setSelected(formats.numDigits); myTrailingZeroes->setSelected(formats.trailingZeroes); myScoreBCD->setState(formats.scoreBCD); @@ -678,11 +678,13 @@ void GameInfoDialog::loadHighScoresProperties(const Properties& props) myVarZeroBased->setState(formats.varZeroBased); ss.str(""); - ss << std::hex << std::right << std::setw(4) << std::setfill('0') << addresses.playerAddr; + ss << std::hex << std::right << std::setw(4) << std::setfill('0') + << std::uppercase << addresses.playerAddr; myPlayersAddress->setText(ss.str()); ss.str(""); - ss << std::hex << std::right << std::setw(4) << std::setfill('0') << addresses.varAddr; + ss << std::hex << std::right << std::setw(4) << std::setfill('0') + << std::uppercase << addresses.varAddr; myVarAddress->setText(ss.str()); @@ -691,7 +693,8 @@ void GameInfoDialog::loadHighScoresProperties(const Properties& props) for (uInt32 a = 0; a < instance().highScores().numAddrBytes(); ++a) { ss.str(""); - ss << std::hex << std::right << std::setw(4) << std::setfill('0') << addresses.scoreAddr[p][a]; + ss << std::hex << std::right << std::setw(4) << std::setfill('0') + << std::uppercase << addresses.scoreAddr[p][a]; myScoreAddress[p][a]->setText(ss.str()); } } @@ -941,6 +944,7 @@ void GameInfoDialog::handleHighScoresWidgets() myScoreBCD->setEnabled(enable); myTrailingZeroesLabel->setEnabled(enable); myTrailingZeroes->setEnabled(enable); + myCurrentScoreLabel->setEnabled(enable); for (uInt32 p = 0; p < HighScoresManager::MAX_PLAYERS; ++p) { @@ -952,18 +956,43 @@ void GameInfoDialog::handleHighScoresWidgets() myScoreAddress[p][a]->setEnabled(enable && numAddr > a); myScoreAddressVal[p][a]->setEnabled(enable && numAddr > a); } + myCurrentScore[p]->setEnabled(enable); } setAddressVal(myPlayersAddress, myPlayersAddressVal); setAddressVal(myVarAddress, myVarAddressVal, myVarBCD->getState(), myVarZeroBased->getState() ? 1 : 0); - for (uInt32 p = 0; p < players; ++p) - for (uInt32 a = 0; a < numAddr; ++a) - setAddressVal(myScoreAddress[p][a], myScoreAddressVal[p][a], myScoreBCD->getState()); + for (uInt32 p = 0; p < HighScoresManager::MAX_PLAYERS; ++p) + { + if (p < players) + { + for (uInt32 a = 0; a < numAddr; ++a) + setAddressVal(myScoreAddress[p][a], myScoreAddressVal[p][a]); + + Int32 score = instance().highScores().score(p, numAddr, myScoreBCD->getState()); + if (score >= 0) + { + ostringstream ss; + + ss.str(""); + ss << std::right << std::setw(myScoreDigits->getSelected() + 1) << std::setfill(' ') << score; + myCurrentScore[p]->setLabel(ss.str()); + } + else + myCurrentScore[p]->setLabel(""); + } + else + { + for (uInt32 a = 0; a < numAddr; ++a) + myScoreAddressVal[p][a]->setText(""); + myCurrentScore[p]->setLabel(""); + } + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void GameInfoDialog::setAddressVal(const EditTextWidget* addressWidget, EditTextWidget* valWidget, bool isBCD, uInt8 incVal) +void GameInfoDialog::setAddressVal(const EditTextWidget* addressWidget, EditTextWidget* valWidget, + bool isBCD, uInt8 incVal) { if (instance().hasConsole() && valWidget->isEnabled()) { @@ -978,10 +1007,9 @@ void GameInfoDialog::setAddressVal(const EditTextWidget* addressWidget, EditText val = system.peek(addr) + incVal; if (isBCD) - ss << std::hex << std::right << std::setw(2) << std::setfill('0'); - else - ss << std::dec; - ss << uInt16(val); + ss << std::hex; + ss << std::right << std::setw(2) << std::setfill('0') + << std::uppercase << uInt16(val); valWidget->setText(ss.str()); } else @@ -1055,10 +1083,14 @@ void GameInfoDialog::handleCommand(CommandSender* sender, int cmd, break; } + case EditTextWidget::kChangedCmd: case kHiScoresChanged: case kPlayersChanged: + case kVarZeroBasedChanged: + case kVarBcdChanged: case kScoreDigitsChanged: - case kScoreMultChanged: + case kScoreZeroesChanged: + case kScoreBcdChanged: handleHighScoresWidgets(); break; diff --git a/src/gui/GameInfoDialog.hxx b/src/gui/GameInfoDialog.hxx index 7c4200d11..25a25689e 100644 --- a/src/gui/GameInfoDialog.hxx +++ b/src/gui/GameInfoDialog.hxx @@ -60,7 +60,7 @@ class GameInfoDialog : public Dialog, public CommandSender void updateControllerStates(); void eraseEEPROM(); void handleHighScoresWidgets(); - void setAddressVal(const EditTextWidget* address, EditTextWidget* val, bool isBCD = false, uInt8 incVal = 0); + void setAddressVal(const EditTextWidget* address, EditTextWidget* val, bool isBCD = true, uInt8 incVal = 0); private: TabWidget* myTab{nullptr}; @@ -133,51 +133,24 @@ class GameInfoDialog : public Dialog, public CommandSender StaticTextWidget* myScoreAddressesLabel[HighScoresManager::MAX_PLAYERS]{ nullptr }; EditTextWidget* myScoreAddress[HighScoresManager::MAX_PLAYERS][HighScoresManager::MAX_SCORE_ADDR]{nullptr}; EditTextWidget* myScoreAddressVal[HighScoresManager::MAX_PLAYERS][HighScoresManager::MAX_SCORE_ADDR]{nullptr}; - - /*StaticTextWidget* myP1AddressLabel{nullptr}; - EditTextWidget* myP1Address0{nullptr}; - EditTextWidget* myP1Address0Val{ nullptr }; - EditTextWidget* myP1Address1{nullptr}; - EditTextWidget* myP1Address1Val{ nullptr }; - EditTextWidget* myP1Address2{nullptr}; - EditTextWidget* myP1Address2Val{ nullptr }; - StaticTextWidget* myP2AddressLabel{nullptr}; - EditTextWidget* myP2Address0{nullptr}; - EditTextWidget* myP2Address0Val{ nullptr }; - EditTextWidget* myP2Address1{nullptr}; - EditTextWidget* myP2Address1Val{ nullptr }; - EditTextWidget* myP2Address2{nullptr}; - EditTextWidget* myP2Address2Val{ nullptr }; - StaticTextWidget* myP3AddressLabel{nullptr}; - EditTextWidget* myP3Address0{nullptr}; - EditTextWidget* myP3Address0Val{ nullptr }; - EditTextWidget* myP3Address1{nullptr}; - EditTextWidget* myP3Address1Val{ nullptr }; - EditTextWidget* myP3Address2{nullptr}; - EditTextWidget* myP3Address2Val{ nullptr }; - StaticTextWidget* myP4AddressLabel{nullptr}; - EditTextWidget* myP4Address0{nullptr}; - EditTextWidget* myP4Address0Val{ nullptr }; - EditTextWidget* myP4Address1{nullptr}; - EditTextWidget* myP4Address1Val{ nullptr }; - EditTextWidget* myP4Address2{nullptr}; - EditTextWidget* myP4Address2Val{ nullptr };*/ + StaticTextWidget* myCurrentScoreLabel; + StaticTextWidget* myCurrentScore[HighScoresManager::MAX_PLAYERS]; enum { - kVCenterChanged = 'Vcch', - kPhosphorChanged = 'PPch', - kPPBlendChanged = 'PBch', - kLeftCChanged = 'LCch', - kRightCChanged = 'RCch', - kMCtrlChanged = 'MCch', - kEEButtonPressed = 'EEgb', - kHiScoresChanged = 'HSch', - kPlayersChanged = 'Plch', - kVar0BasedChanged = 'VZch', - kVarFormatChanged = 'VFch', - kScoreDigitsChanged = 'SDch', - kScoreMultChanged = 'SMch', - kScoreFormatChanged = 'SFch' + kVCenterChanged = 'Vcch', + kPhosphorChanged = 'PPch', + kPPBlendChanged = 'PBch', + kLeftCChanged = 'LCch', + kRightCChanged = 'RCch', + kMCtrlChanged = 'MCch', + kEEButtonPressed = 'EEgb', + kHiScoresChanged = 'HSch', + kPlayersChanged = 'Plch', + kVarZeroBasedChanged = 'VZch', + kVarBcdChanged = 'VBch', + kScoreDigitsChanged = 'SDch', + kScoreZeroesChanged = 'SZch', + kScoreBcdChanged = 'SBch', }; // Game properties for currently loaded ROM diff --git a/src/gui/PopUpWidget.cxx b/src/gui/PopUpWidget.cxx index 6b530f6d1..0c1124066 100644 --- a/src/gui/PopUpWidget.cxx +++ b/src/gui/PopUpWidget.cxx @@ -208,8 +208,8 @@ void PopUpWidget::drawWidget(bool hilite) s.frameRect(x + w - 16, _y + 1, 15, _h - 2, isEnabled() && hilite ? kWidColorHi : kBGColorLo); // Fill the background - s.fillRect(x + 1, _y + 1, w - 17, _h - 2, onTop ? _changed ? kDbgChangedColor : kWidColor : kDlgColor); - s.fillRect(x + w - 15, _y + 2, 13, _h - 4, onTop ? isEnabled() && hilite ? kWidColor : kBGColorHi : kBGColorLo); + s.fillRect(x + 1, _y + 1, w - 17, _h - 2, onTop ? _changed ? kDbgChangedColor : isEnabled() ? kWidColor : kDlgColor : kBGColorLo); + s.fillRect(x + w - 15, _y + 2, 13, _h - 4, onTop ? isEnabled() && hilite ? kWidColor : kDlgColor : kBGColorLo); // Draw an arrow pointing down at the right end to signal this is a dropdown/popup s.drawBitmap(down_arrow.data(), x + w - 13, _y + myArrowsY + 1, !(isEnabled() && onTop) ? kColor : kTextColor, 9U, 8U);