mirror of https://github.com/stella-emu/stella.git
parent
eb0c1d0964
commit
542c22fbfd
|
@ -22,16 +22,20 @@
|
|||
B, ; score format (BCD, HEX)
|
||||
B, ; variation format (BCD, HEX)
|
||||
0, ; zero-based variation
|
||||
"", ; special label (5 chars)
|
||||
B, ; special format (BCD, HEX)
|
||||
0, ; zero-based special
|
||||
Addresses (in hex):
|
||||
n*p-times xx, ; score info for each player, high to low
|
||||
xx, ; variation address (if more than 1 variation)
|
||||
xx ; player address (if more than 1 player)
|
||||
xx ; special address (if defined)
|
||||
|
||||
TODO:
|
||||
- variation bits (Centipede)
|
||||
- player bits (Asteroids, Space Invaders)
|
||||
- score swaps (Asteroids)
|
||||
- one optional and named value extra per game (round, level...)
|
||||
- special: one optional and named value extra per game (round, level...)
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
|
@ -126,9 +130,12 @@ 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.playersAddr = playerAddress(props);
|
||||
info.varsAddr = varAddress(props);
|
||||
info.specialAddr = 0; // TODO
|
||||
for (uInt32 p = 0; p < MAX_PLAYERS; ++p)
|
||||
{
|
||||
if (p < numPlayersR)
|
||||
|
@ -146,7 +153,7 @@ bool HighScoresManager::get(const Properties& props, uInt32& numPlayersR, uInt32
|
|||
info.scoresAddr[p][a] = -1;
|
||||
}
|
||||
|
||||
return (EmptyString != getPropIdx(props, PropType::Cart_Addresses, 0));
|
||||
return (!getPropIdx(props, PropType::Cart_Addresses, 0).empty());
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -23,6 +23,7 @@ class OSystem;
|
|||
namespace HSM {
|
||||
static const uInt32 MAX_PLAYERS = 4;
|
||||
static const uInt32 MAX_SCORE_ADDR = 3;
|
||||
static const uInt32 MAX_SPECIAL = 5;
|
||||
|
||||
static const uInt32 DEFAULT_PLAYER = 1;
|
||||
static const uInt32 DEFAULT_VARIATION = 1;
|
||||
|
@ -38,10 +39,14 @@ namespace HSM {
|
|||
bool scoreBCD;
|
||||
bool varsBCD;
|
||||
bool varsZeroBased;
|
||||
string special;
|
||||
bool specialBCD;
|
||||
bool specialZeroBased;
|
||||
// Addresses
|
||||
ScoresAddresses scoresAddr;
|
||||
uInt16 varsAddr;
|
||||
uInt16 playersAddr;
|
||||
uInt16 specialAddr;
|
||||
};
|
||||
|
||||
} // namespace HSM
|
||||
|
|
|
@ -360,6 +360,10 @@ GameInfoDialog::GameInfoDialog(
|
|||
EditableWidget::TextFilter fVars = [](char c) {
|
||||
return (c >= '0' && c <= '9');
|
||||
};
|
||||
EditableWidget::TextFilter fSpecial = [](char c) {
|
||||
return (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.'|| c == '-,';
|
||||
};
|
||||
|
||||
xpos = HBORDER; ypos = VBORDER;
|
||||
lwidth = font.getStringWidth("Variations ");
|
||||
|
||||
|
@ -415,7 +419,7 @@ GameInfoDialog::GameInfoDialog(
|
|||
|
||||
mySpecialLabel = new StaticTextWidget(myTab, font, xpos, ypos + 1, "Special ");
|
||||
mySpecial = new EditTextWidget(myTab, font, mySpecialLabel->getRight(), ypos - 1, swidth, lineHeight);
|
||||
//mySpecial->setTextFilter(...);
|
||||
mySpecial->setTextFilter(fSpecial);
|
||||
wid.push_back(mySpecial);
|
||||
|
||||
mySpecialAddressLabel = new StaticTextWidget(myTab, font, myPlayersAddressLabel->getLeft(), ypos + 1, "Address ");
|
||||
|
@ -695,17 +699,26 @@ void GameInfoDialog::loadHighScoresProperties(const Properties& props)
|
|||
myScoreBCD->setState(info.scoreBCD);
|
||||
myVarsBCD->setState(info.varsBCD);
|
||||
myVarsZeroBased->setState(info.varsZeroBased);
|
||||
mySpecial->setText(info.special);
|
||||
mySpecialBCD->setState(info.specialBCD);
|
||||
mySpecialZeroBased->setState(info.specialZeroBased);
|
||||
|
||||
ss.str("");
|
||||
ss << hex << right << setw(4) << setfill('0')
|
||||
ss << hex << right << setw(4) << setfill(' ')
|
||||
<< uppercase << info.playersAddr;
|
||||
myPlayersAddress->setText(ss.str());
|
||||
|
||||
ss.str("");
|
||||
ss << hex << right << setw(4) << setfill('0')
|
||||
ss << hex << right << setw(4) << setfill(' ')
|
||||
<< uppercase << info.varsAddr;
|
||||
myVarAddress->setText(ss.str());
|
||||
|
||||
ss.str("");
|
||||
ss << hex << right << setw(4) << setfill(' ')
|
||||
<< uppercase << info.specialAddr;
|
||||
mySpecialAddress->setText(ss.str());
|
||||
|
||||
|
||||
for (uInt32 p = 0; p < HSM::MAX_PLAYERS; ++p)
|
||||
{
|
||||
for (uInt32 a = 0; a < instance().highScores().numAddrBytes(info.numDigits, info.trailingZeroes); ++a)
|
||||
|
@ -801,20 +814,27 @@ void GameInfoDialog::saveHighScoresProperties()
|
|||
|
||||
if (myHighScores->getState())
|
||||
{
|
||||
// fill info
|
||||
// fill format
|
||||
info.varsZeroBased = myVarsZeroBased->getState();
|
||||
info.varsBCD = myVarsBCD->getState();
|
||||
|
||||
info.special = mySpecial->getText();
|
||||
info.specialZeroBased = mySpecialZeroBased->getState();
|
||||
info.specialBCD = mySpecialBCD->getState();
|
||||
|
||||
info.numDigits = myScoreDigits->getSelected() + 1;
|
||||
info.trailingZeroes = myTrailingZeroes->getSelected();
|
||||
info.scoreBCD = myScoreBCD->getState();
|
||||
|
||||
// fill info
|
||||
// fill addresses
|
||||
string strAddr;
|
||||
|
||||
strAddr = myPlayersAddress->getText();
|
||||
info.playersAddr = stringToIntBase16(strAddr, HSM::DEFAULT_ADDRESS);
|
||||
strAddr = myVarAddress->getText();
|
||||
info.varsAddr = stringToIntBase16(strAddr, HSM::DEFAULT_ADDRESS);
|
||||
strAddr = mySpecialAddress->getText();
|
||||
info.specialAddr = stringToIntBase16(strAddr, HSM::DEFAULT_ADDRESS);
|
||||
|
||||
for (uInt32 p = 0; p < HSM::MAX_PLAYERS; ++p)
|
||||
{
|
||||
|
@ -987,8 +1007,19 @@ 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();
|
||||
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);
|
||||
|
@ -1008,6 +1039,16 @@ void GameInfoDialog::updateHighScoresWidgets()
|
|||
myVarsBCD->setEnabled(enableVars && stringToInt(myVariations->getText(), 1) >= 10);
|
||||
myVarsZeroBased->setEnabled(enableVars);
|
||||
|
||||
mySpecialLabel->setEnabled(enable);
|
||||
mySpecial->setEnabled(enable);
|
||||
mySpecial->setEditable(enable);
|
||||
mySpecialAddressLabel->setEnabled(enableSpecial);
|
||||
mySpecialAddress->setEnabled(enableSpecial);
|
||||
mySpecialAddress->setEditable(enableSpecial);
|
||||
mySpecialAddressVal->setEnabled(enableSpecial);
|
||||
mySpecialBCD->setEnabled(enableSpecial);
|
||||
mySpecialZeroBased->setEnabled(enableSpecial);
|
||||
|
||||
mySpecialLabel->setEnabled(enable);
|
||||
myScoreDigitsLabel->setEnabled(enable);
|
||||
myScoreDigits->setEnabled(enable);
|
||||
|
@ -1030,16 +1071,13 @@ void GameInfoDialog::updateHighScoresWidgets()
|
|||
}
|
||||
|
||||
// verify and update widget data
|
||||
string strVars;
|
||||
|
||||
// limit variants size
|
||||
strVars = myVariations->getText();
|
||||
strVars = strVars.substr(0, 3);
|
||||
myVariations->setText(strVars);
|
||||
|
||||
// update players and variations RAM values
|
||||
setAddressVal(myPlayersAddress, myPlayersAddressVal);
|
||||
setAddressVal(myVarAddress, myVarAddressVal, myVarsBCD->getState(), myVarsZeroBased->getState() ? 1 : 0);
|
||||
setAddressVal(myVarAddress, myVarAddressVal, myVarsBCD->getState(),
|
||||
myVarsZeroBased->getState() ? 1 : 0);
|
||||
setAddressVal(mySpecialAddress, mySpecialAddressVal, mySpecialBCD->getState(),
|
||||
mySpecialZeroBased->getState() ? 1 : 0);
|
||||
|
||||
// update score RAM values and resulting scores
|
||||
for (uInt32 p = 0; p < HSM::MAX_PLAYERS; ++p)
|
||||
|
@ -1101,7 +1139,7 @@ void GameInfoDialog::setAddressVal(EditTextWidget* addressWidget, EditTextWidget
|
|||
// format output and display in value widget
|
||||
if (isBCD)
|
||||
ss << hex;
|
||||
ss << right << setw(2) << setfill('0')
|
||||
ss << right << setw(2) << setfill(' ')
|
||||
<< uppercase << uInt16(val);
|
||||
valWidget->setText(ss.str());
|
||||
}
|
||||
|
|
|
@ -33,8 +33,8 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent,
|
|||
: Dialog(osystem, parent, font, "High Scores")
|
||||
{
|
||||
const GUI::Font& ifont = instance().frameBuffer().infoFont();
|
||||
const int lineHeight = font.getLineHeight();
|
||||
//fontWidth = font.getMaxCharWidth(),
|
||||
const int lineHeight = font.getLineHeight(),
|
||||
fontWidth = font.getMaxCharWidth();
|
||||
//fontHeight = font.getFontHeight(),
|
||||
//buttonHeight = font.getLineHeight() + 4;
|
||||
//infoLineHeight = ifont.getLineHeight();
|
||||
|
@ -46,7 +46,7 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent,
|
|||
WidgetArray wid;
|
||||
VariantList items;
|
||||
|
||||
_w = 400; // max_w - 20;
|
||||
_w = 40 * fontWidth + HBORDER * 2; // max_w - 20;
|
||||
_h = 400; // max_h - 20;
|
||||
|
||||
ypos = VBORDER + _th; xpos = HBORDER;
|
||||
|
@ -58,19 +58,19 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent,
|
|||
myVariation = new PopUpWidget(this, font, s->getRight(), ypos,
|
||||
font.getStringWidth("256") - 4, lineHeight, items, "", 0, 0);
|
||||
|
||||
ypos += lineHeight + VGAP * 2;
|
||||
ypos += lineHeight + VGAP * 4;
|
||||
|
||||
int xposRank = HBORDER;
|
||||
int xposScore = xposRank + font.getStringWidth("Rank") + 16;
|
||||
int xposName = xposScore + font.getStringWidth("123456") + 24;
|
||||
int xposExtra = xposName + font.getStringWidth("Date") + 16;
|
||||
int xposDate = xposExtra + font.getStringWidth("Round") + 16;
|
||||
int xposSpecial = xposScore + font.getStringWidth("Score") + 24;
|
||||
int xposName = xposSpecial + font.getStringWidth("Round") + 16;
|
||||
int xposDate = xposName + font.getStringWidth("Name") + 16;
|
||||
int nWidth = font.getStringWidth("ABC") + 4;
|
||||
|
||||
new StaticTextWidget(this, font, xposRank, ypos + 1, "Rank");
|
||||
new StaticTextWidget(this, font, xposScore, ypos + 1, "Score");
|
||||
new StaticTextWidget(this, font, xposSpecial, ypos + 1, "Round");
|
||||
new StaticTextWidget(this, font, xposName - 2, ypos + 1, "Name");
|
||||
new StaticTextWidget(this, font, xposExtra, ypos + 1, "Round");
|
||||
new StaticTextWidget(this, font, xposDate+16, ypos + 1, "Date Time");
|
||||
|
||||
ypos += lineHeight + VGAP;
|
||||
|
@ -79,22 +79,27 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent,
|
|||
{
|
||||
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");
|
||||
myNames[p] = new EditTextWidget(this, font, xposName, ypos + 1, nWidth, lineHeight, "JTZ");
|
||||
myNames[p]->setEditable(false);
|
||||
wid.push_back(myNames[p]);
|
||||
|
||||
new StaticTextWidget(this, font, xposExtra, ypos + 1, " 123");
|
||||
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");
|
||||
|
||||
//new StaticTextWidget(this, font, xposDate, ypos + 1, "12.02.20 17:15");
|
||||
//new StaticTextWidget(this, font, xposDate, ypos + 1, "02/12/20 12:30am");
|
||||
new StaticTextWidget(this, font, xposDate, ypos + 1, "12-02-20 17:15");
|
||||
myDates[p] = new StaticTextWidget(this, font, xposDate, ypos + 1, "12-02-20 17:15");
|
||||
|
||||
ypos += lineHeight + VGAP;
|
||||
}
|
||||
ypos += VGAP;
|
||||
ypos += VGAP * 2;
|
||||
|
||||
myMD5 = new StaticTextWidget(this, ifont, xpos, ypos + 1, "MD5: 9ad36e699ef6f45d9eb6c4cf90475c9f");
|
||||
|
||||
wid.clear();
|
||||
addOKCancelBGroup(wid, font);
|
||||
addBGroupToFocusList(wid);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -125,6 +130,33 @@ void HighScoresDialog::loadConfig()
|
|||
}
|
||||
myVariation->addItems(items);
|
||||
myVariation->setSelected(instance().highScores().variation());
|
||||
|
||||
// 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 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",
|
||||
"20-02-12 21:50", "20-02-11 14:16", "20-02-11 13:11",
|
||||
"20-02-10 19:45", "10-02-10 20:04", "05-02-09 22:32",
|
||||
" - -"};
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
//myEditNames[4]->setEditable(true);
|
||||
|
||||
//myNames[3]->setHeight(1);
|
||||
//myNames[3]->setWidth(0);
|
||||
myEditNames[4]->clearFlags(EditTextWidget::FLAG_INVISIBLE);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -134,6 +166,7 @@ void HighScoresDialog::handleCommand(CommandSender* sender, int cmd, int data, i
|
|||
{
|
||||
case kOKCmd:
|
||||
case kCloseCmd:
|
||||
instance().eventHandler().leaveMenuMode();
|
||||
instance().eventHandler().handleEvent(Event::ExitMode);
|
||||
break;
|
||||
|
||||
|
|
|
@ -50,7 +50,10 @@ class HighScoresDialog : public Dialog
|
|||
PopUpWidget* myVariation;
|
||||
StaticTextWidget* myPositions[NUM_POSITIONS];
|
||||
StaticTextWidget* myScores[NUM_POSITIONS];
|
||||
EditTextWidget* myNames[NUM_POSITIONS];
|
||||
StaticTextWidget* mySpecials[NUM_POSITIONS];
|
||||
StaticTextWidget* myNames[NUM_POSITIONS];
|
||||
EditTextWidget* myEditNames[NUM_POSITIONS];
|
||||
StaticTextWidget* myDates[NUM_POSITIONS];
|
||||
StaticTextWidget* myMD5;
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue