mirror of https://github.com/stella-emu/stella.git
fix PopUpWidget colors when disabled
display current scores and values address value formatting
This commit is contained in:
parent
7374b24ff8
commit
90b684335e
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -20,7 +20,6 @@
|
||||||
#include "Cart.hxx"
|
#include "Cart.hxx"
|
||||||
#include "MouseControl.hxx"
|
#include "MouseControl.hxx"
|
||||||
#include "SaveKey.hxx"
|
#include "SaveKey.hxx"
|
||||||
#include "Dialog.hxx"
|
|
||||||
#include "EditTextWidget.hxx"
|
#include "EditTextWidget.hxx"
|
||||||
#include "RadioButtonWidget.hxx"
|
#include "RadioButtonWidget.hxx"
|
||||||
#include "Launcher.hxx"
|
#include "Launcher.hxx"
|
||||||
|
@ -28,7 +27,6 @@
|
||||||
#include "CartDetector.hxx"
|
#include "CartDetector.hxx"
|
||||||
#include "ControllerDetector.hxx"
|
#include "ControllerDetector.hxx"
|
||||||
#include "PopUpWidget.hxx"
|
#include "PopUpWidget.hxx"
|
||||||
#include "Props.hxx"
|
|
||||||
#include "PropsSet.hxx"
|
#include "PropsSet.hxx"
|
||||||
#include "TabWidget.hxx"
|
#include "TabWidget.hxx"
|
||||||
#include "TIAConstants.hxx"
|
#include "TIAConstants.hxx"
|
||||||
|
@ -400,10 +398,10 @@ GameInfoDialog::GameInfoDialog(
|
||||||
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);
|
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);
|
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);
|
wid.push_back(myVarZeroBased);
|
||||||
|
|
||||||
ypos += lineHeight + VGAP;
|
ypos += lineHeight + VGAP;
|
||||||
|
@ -435,10 +433,10 @@ GameInfoDialog::GameInfoDialog(
|
||||||
|
|
||||||
myTrailingZeroesLabel = new StaticTextWidget(myTab, font, myScoreDigits->getRight() + 20, ypos + 1, "0-Digits ");
|
myTrailingZeroesLabel = new StaticTextWidget(myTab, font, myScoreDigits->getRight() + 20, ypos + 1, "0-Digits ");
|
||||||
myTrailingZeroes = new PopUpWidget(myTab, font, myTrailingZeroesLabel->getRight(), ypos, pwidth, lineHeight,
|
myTrailingZeroes = new PopUpWidget(myTab, font, myTrailingZeroesLabel->getRight(), ypos, pwidth, lineHeight,
|
||||||
items, "", 0, kScoreMultChanged);
|
items, "", 0, kScoreZeroesChanged);
|
||||||
wid.push_back(myTrailingZeroes);
|
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);
|
wid.push_back(myScoreBCD);
|
||||||
|
|
||||||
|
|
||||||
|
@ -461,7 +459,9 @@ GameInfoDialog::GameInfoDialog(
|
||||||
myScoreAddressVal[p][a]->setEditable(false);
|
myScoreAddressVal[p][a]->setEditable(false);
|
||||||
s_xpos += myScoreAddressVal[p][a]->getWidth() + 16;
|
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
|
// Add items for tab 4
|
||||||
addToFocusList(wid, myTab, tabID);
|
addToFocusList(wid, myTab, tabID);
|
||||||
|
@ -658,19 +658,19 @@ void GameInfoDialog::loadHighScoresProperties(const Properties& props)
|
||||||
{
|
{
|
||||||
HighScoresManager::Formats formats;
|
HighScoresManager::Formats formats;
|
||||||
HighScoresManager::Addresses addresses;
|
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);
|
myHighScores->setState(enable);
|
||||||
|
|
||||||
if (enable)
|
myPlayers->setSelected(instance().highScores().numPlayers());
|
||||||
|
myVariations->setText(std::to_string(instance().highScores().numVariations()));
|
||||||
|
|
||||||
|
if (true)
|
||||||
{
|
{
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
|
|
||||||
myPlayers->setSelected(instance().highScores().numPlayers());
|
|
||||||
myVariations->setText(std::to_string(instance().highScores().numVariations()));
|
|
||||||
|
|
||||||
myScoreDigits->setSelected(formats.numDigits);
|
myScoreDigits->setSelected(formats.numDigits);
|
||||||
myTrailingZeroes->setSelected(formats.trailingZeroes);
|
myTrailingZeroes->setSelected(formats.trailingZeroes);
|
||||||
myScoreBCD->setState(formats.scoreBCD);
|
myScoreBCD->setState(formats.scoreBCD);
|
||||||
|
@ -678,11 +678,13 @@ void GameInfoDialog::loadHighScoresProperties(const Properties& props)
|
||||||
myVarZeroBased->setState(formats.varZeroBased);
|
myVarZeroBased->setState(formats.varZeroBased);
|
||||||
|
|
||||||
ss.str("");
|
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());
|
myPlayersAddress->setText(ss.str());
|
||||||
|
|
||||||
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());
|
myVarAddress->setText(ss.str());
|
||||||
|
|
||||||
|
|
||||||
|
@ -691,7 +693,8 @@ void GameInfoDialog::loadHighScoresProperties(const Properties& props)
|
||||||
for (uInt32 a = 0; a < instance().highScores().numAddrBytes(); ++a)
|
for (uInt32 a = 0; a < instance().highScores().numAddrBytes(); ++a)
|
||||||
{
|
{
|
||||||
ss.str("");
|
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());
|
myScoreAddress[p][a]->setText(ss.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -941,6 +944,7 @@ void GameInfoDialog::handleHighScoresWidgets()
|
||||||
myScoreBCD->setEnabled(enable);
|
myScoreBCD->setEnabled(enable);
|
||||||
myTrailingZeroesLabel->setEnabled(enable);
|
myTrailingZeroesLabel->setEnabled(enable);
|
||||||
myTrailingZeroes->setEnabled(enable);
|
myTrailingZeroes->setEnabled(enable);
|
||||||
|
myCurrentScoreLabel->setEnabled(enable);
|
||||||
|
|
||||||
for (uInt32 p = 0; p < HighScoresManager::MAX_PLAYERS; ++p)
|
for (uInt32 p = 0; p < HighScoresManager::MAX_PLAYERS; ++p)
|
||||||
{
|
{
|
||||||
|
@ -952,18 +956,43 @@ void GameInfoDialog::handleHighScoresWidgets()
|
||||||
myScoreAddress[p][a]->setEnabled(enable && numAddr > a);
|
myScoreAddress[p][a]->setEnabled(enable && numAddr > a);
|
||||||
myScoreAddressVal[p][a]->setEnabled(enable && numAddr > a);
|
myScoreAddressVal[p][a]->setEnabled(enable && numAddr > a);
|
||||||
}
|
}
|
||||||
|
myCurrentScore[p]->setEnabled(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
setAddressVal(myPlayersAddress, myPlayersAddressVal);
|
setAddressVal(myPlayersAddress, myPlayersAddressVal);
|
||||||
setAddressVal(myVarAddress, myVarAddressVal, myVarBCD->getState(), myVarZeroBased->getState() ? 1 : 0);
|
setAddressVal(myVarAddress, myVarAddressVal, myVarBCD->getState(), myVarZeroBased->getState() ? 1 : 0);
|
||||||
|
|
||||||
for (uInt32 p = 0; p < players; ++p)
|
for (uInt32 p = 0; p < HighScoresManager::MAX_PLAYERS; ++p)
|
||||||
for (uInt32 a = 0; a < numAddr; ++a)
|
{
|
||||||
setAddressVal(myScoreAddress[p][a], myScoreAddressVal[p][a], myScoreBCD->getState());
|
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())
|
if (instance().hasConsole() && valWidget->isEnabled())
|
||||||
{
|
{
|
||||||
|
@ -978,10 +1007,9 @@ void GameInfoDialog::setAddressVal(const EditTextWidget* addressWidget, EditText
|
||||||
val = system.peek(addr) + incVal;
|
val = system.peek(addr) + incVal;
|
||||||
|
|
||||||
if (isBCD)
|
if (isBCD)
|
||||||
ss << std::hex << std::right << std::setw(2) << std::setfill('0');
|
ss << std::hex;
|
||||||
else
|
ss << std::right << std::setw(2) << std::setfill('0')
|
||||||
ss << std::dec;
|
<< std::uppercase << uInt16(val);
|
||||||
ss << uInt16(val);
|
|
||||||
valWidget->setText(ss.str());
|
valWidget->setText(ss.str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1055,10 +1083,14 @@ void GameInfoDialog::handleCommand(CommandSender* sender, int cmd,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case EditTextWidget::kChangedCmd:
|
||||||
case kHiScoresChanged:
|
case kHiScoresChanged:
|
||||||
case kPlayersChanged:
|
case kPlayersChanged:
|
||||||
|
case kVarZeroBasedChanged:
|
||||||
|
case kVarBcdChanged:
|
||||||
case kScoreDigitsChanged:
|
case kScoreDigitsChanged:
|
||||||
case kScoreMultChanged:
|
case kScoreZeroesChanged:
|
||||||
|
case kScoreBcdChanged:
|
||||||
handleHighScoresWidgets();
|
handleHighScoresWidgets();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ class GameInfoDialog : public Dialog, public CommandSender
|
||||||
void updateControllerStates();
|
void updateControllerStates();
|
||||||
void eraseEEPROM();
|
void eraseEEPROM();
|
||||||
void handleHighScoresWidgets();
|
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:
|
private:
|
||||||
TabWidget* myTab{nullptr};
|
TabWidget* myTab{nullptr};
|
||||||
|
@ -133,51 +133,24 @@ class GameInfoDialog : public Dialog, public CommandSender
|
||||||
StaticTextWidget* myScoreAddressesLabel[HighScoresManager::MAX_PLAYERS]{ nullptr };
|
StaticTextWidget* myScoreAddressesLabel[HighScoresManager::MAX_PLAYERS]{ nullptr };
|
||||||
EditTextWidget* myScoreAddress[HighScoresManager::MAX_PLAYERS][HighScoresManager::MAX_SCORE_ADDR]{nullptr};
|
EditTextWidget* myScoreAddress[HighScoresManager::MAX_PLAYERS][HighScoresManager::MAX_SCORE_ADDR]{nullptr};
|
||||||
EditTextWidget* myScoreAddressVal[HighScoresManager::MAX_PLAYERS][HighScoresManager::MAX_SCORE_ADDR]{nullptr};
|
EditTextWidget* myScoreAddressVal[HighScoresManager::MAX_PLAYERS][HighScoresManager::MAX_SCORE_ADDR]{nullptr};
|
||||||
|
StaticTextWidget* myCurrentScoreLabel;
|
||||||
/*StaticTextWidget* myP1AddressLabel{nullptr};
|
StaticTextWidget* myCurrentScore[HighScoresManager::MAX_PLAYERS];
|
||||||
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 };*/
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
kVCenterChanged = 'Vcch',
|
kVCenterChanged = 'Vcch',
|
||||||
kPhosphorChanged = 'PPch',
|
kPhosphorChanged = 'PPch',
|
||||||
kPPBlendChanged = 'PBch',
|
kPPBlendChanged = 'PBch',
|
||||||
kLeftCChanged = 'LCch',
|
kLeftCChanged = 'LCch',
|
||||||
kRightCChanged = 'RCch',
|
kRightCChanged = 'RCch',
|
||||||
kMCtrlChanged = 'MCch',
|
kMCtrlChanged = 'MCch',
|
||||||
kEEButtonPressed = 'EEgb',
|
kEEButtonPressed = 'EEgb',
|
||||||
kHiScoresChanged = 'HSch',
|
kHiScoresChanged = 'HSch',
|
||||||
kPlayersChanged = 'Plch',
|
kPlayersChanged = 'Plch',
|
||||||
kVar0BasedChanged = 'VZch',
|
kVarZeroBasedChanged = 'VZch',
|
||||||
kVarFormatChanged = 'VFch',
|
kVarBcdChanged = 'VBch',
|
||||||
kScoreDigitsChanged = 'SDch',
|
kScoreDigitsChanged = 'SDch',
|
||||||
kScoreMultChanged = 'SMch',
|
kScoreZeroesChanged = 'SZch',
|
||||||
kScoreFormatChanged = 'SFch'
|
kScoreBcdChanged = 'SBch',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Game properties for currently loaded ROM
|
// Game properties for currently loaded ROM
|
||||||
|
|
|
@ -208,8 +208,8 @@ void PopUpWidget::drawWidget(bool hilite)
|
||||||
s.frameRect(x + w - 16, _y + 1, 15, _h - 2, isEnabled() && hilite ? kWidColorHi : kBGColorLo);
|
s.frameRect(x + w - 16, _y + 1, 15, _h - 2, isEnabled() && hilite ? kWidColorHi : kBGColorLo);
|
||||||
|
|
||||||
// Fill the background
|
// Fill the background
|
||||||
s.fillRect(x + 1, _y + 1, w - 17, _h - 2, onTop ? _changed ? kDbgChangedColor : kWidColor : kDlgColor);
|
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 : kBGColorHi : 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
|
// 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,
|
s.drawBitmap(down_arrow.data(), x + w - 13, _y + myArrowsY + 1,
|
||||||
!(isEnabled() && onTop) ? kColor : kTextColor, 9U, 8U);
|
!(isEnabled() && onTop) ? kColor : kTextColor, 9U, 8U);
|
||||||
|
|
Loading…
Reference in New Issue