add HighScoresDialog to LauncherDialog

remove high scores debug events
add Dragster data to stella.pro
This commit is contained in:
thrust26 2020-02-16 21:37:22 +01:00
parent 23ec31110b
commit bac7b0552e
11 changed files with 152 additions and 128 deletions

View File

@ -347,7 +347,7 @@ uInt32 HighScoresManager::numAddrBytes(const Properties& props) const
Int32 HighScoresManager::player(uInt16 addr, uInt32 numPlayers, bool zeroBased) const
{
if (!myOSystem.hasConsole())
return -1;
return DEFAULT_PLAYER;
Int32 player = peek(addr);
Int32 bits = ceil(log(numPlayers + (!zeroBased ? 1 : 0))/log(2));
@ -393,7 +393,7 @@ Int32 HighScoresManager::variation(uInt16 addr, bool varBCD, bool zeroBased,
uInt32 numVariations) const
{
if (!myOSystem.hasConsole())
return -1;
return DEFAULT_VARIATION;
Int32 var = peek(addr);
Int32 bits = ceil(log(numVariations + (!zeroBased ? 1 : 0))/log(2));

View File

@ -20,6 +20,8 @@
class OSystem;
#include "Props.hxx"
namespace HSM {
static const uInt32 MAX_PLAYERS = 4;
static const uInt32 MAX_ADDR_CHARS = 4;
@ -62,8 +64,6 @@ using namespace HSM;
This class provides an interface to define, load and save scores. It is meant
for games which do not support saving highscores.
TODO: load and saves scores
@author Thomas Jentzsch
*/

View File

@ -505,8 +505,6 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultCommo
{Event::Unwind1Menu, KBDK_RIGHT, MOD3},
{Event::Unwind10Menu, KBDK_RIGHT, KBDM_SHIFT | MOD3},
{Event::UnwindAllMenu, KBDK_UP, MOD3},
{Event::ShowScore, KBDK_S, KBDM_SHIFT | KBDM_CTRL},
{Event::ShowVariation, KBDK_V, KBDM_SHIFT | KBDM_CTRL},
{Event::HighScoresMenuMode, KBDK_INSERT},
#if defined(RETRON77)

View File

@ -27,6 +27,16 @@
"Cart.Addresses" "E6,E8,DC"
""
"Cart.MD5" "77057d9d14b99e465ea9e29783af0ae3"
"Cart.Manufacturer" "Activision, David Crane"
"Cart.ModelNo" "AG-001"
"Cart.Name" "Dragster (1980) (Activision)"
"Cart.Note" "AKA Drag Strip"
"Cart.Players" "2"
"Cart.Formats" "4,0,B,B,1,-,D,0,1"
"Cart.Addresses" "B3,B5,B4,B6,80,80,0"
""
"Cart.MD5" "91c2098e88a6b13f977af8c003e0bca5"
"Cart.Manufacturer" "Atari - GCC"
"Cart.ModelNo" "CX2676"

View File

@ -120,7 +120,7 @@ class Event
ToggleFrameStats, ToggleSAPortOrder, ExitGame,
// add new events from here to avoid that user remapped events get overwritten
ShowScore, ShowVariation, HighScoresMenuMode,
HighScoresMenuMode,
LastType
};

View File

@ -721,27 +721,6 @@ void EventHandler::handleEvent(Event::Type event, Int32 value, bool repeated)
if(pressed && !repeated) myOSystem.frameBuffer().tiaSurface().saveSnapShot();
return;
#ifdef GUI_SUPPORT
// Debug only, TODO: remove!
case Event::ShowScore:
if (pressed)
{
ostringstream msg;
msg << "Score: " << myOSystem.highScores().score();
myOSystem.frameBuffer().showMessage(msg.str());
}
return;
case Event::ShowVariation:
if (pressed)
{
ostringstream msg;
msg << "Variation: " << myOSystem.highScores().variation();
myOSystem.frameBuffer().showMessage(msg.str());
}
return;
#endif
case Event::ExitMode:
// Special handling for Escape key
// Basically, exit whichever mode we're currently in
@ -1857,6 +1836,7 @@ EventHandler::EmulActionList EventHandler::ourEmulActionList = { {
{ Event::ExitMode, "Exit current Stella menu/mode", "" },
{ Event::OptionsMenuMode, "Enter Options menu UI", "" },
{ Event::CmdMenuMode, "Toggle Commands menu UI", "" },
{ Event::HighScoresMenuMode, "Toggle High Scores UI", "" },
{ Event::TogglePauseMode, "Toggle Pause mode", "" },
{ Event::StartPauseMode, "Start Pause mode", "" },
{ Event::Fry, "Fry cartridge", "" },
@ -2035,9 +2015,6 @@ EventHandler::EmulActionList EventHandler::ourEmulActionList = { {
{ Event::Combo14, "Combo 14", "" },
{ Event::Combo15, "Combo 15", "" },
{ Event::Combo16, "Combo 16", "" },
{ Event::ShowScore, "Display current score", "" },
{ Event::ShowVariation, "Display current variation", "" },
{ Event::HighScoresMenuMode, "Toggle High Scores UI", "" },
} };
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -2076,7 +2053,7 @@ const Event::EventSet EventHandler::MiscEvents = {
// Event::MouseButtonLeftValue, Event::MouseButtonRightValue,
Event::HandleMouseControl, Event::ToggleGrabMouse,
Event::ToggleSAPortOrder,
Event::ShowScore, Event::ShowVariation,
Event::HighScoresMenuMode
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -17,6 +17,7 @@
#include "OSystem.hxx"
#include "Console.hxx"
#include "Launcher.hxx"
#include "EventHandler.hxx"
#include "Font.hxx"
#include "FBSurface.hxx"
@ -30,16 +31,18 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent,
const GUI::Font& font, int max_w, int max_h)
: Dialog(osystem, parent, font, "High Scores"),
_max_w(max_w),
_max_h(max_h),
myInitials(""),
myDirty(false)
int max_w, int max_h,
Menu::AppMode mode)
: Dialog(osystem, parent, osystem.frameBuffer().font(), "High Scores"),
myMode(mode),
_max_w(max_w),
_max_h(max_h),
myInitials(""),
myDirty(false)
{
const GUI::Font& ifont = instance().frameBuffer().infoFont();
const int lineHeight = font.getLineHeight(),
fontWidth = font.getMaxCharWidth();
const int lineHeight = _font.getLineHeight(),
fontWidth = _font.getMaxCharWidth();
const int VBORDER = 8;
const int HBORDER = 10;
const int VGAP = 4;
@ -56,43 +59,43 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent,
//items.clear();
StaticTextWidget* s = new StaticTextWidget(this, font, xpos, ypos + 1, "Variation ");
myVariationWidget = new PopUpWidget(this, font, s->getRight(), ypos,
font.getStringWidth("256") - 4, lineHeight, items, "", 0,
StaticTextWidget* s = new StaticTextWidget(this, _font, xpos, ypos + 1, "Variation ");
myVariationWidget = new PopUpWidget(this, _font, s->getRight(), ypos,
_font.getStringWidth("256") - 4, lineHeight, items, "", 0,
kVariationChanged);
wid.push_back(myVariationWidget);
ypos += lineHeight + VGAP * 4;
int xposRank = HBORDER;
int xposScore = xposRank + font.getStringWidth("Rank") + 16;
int xposSpecial = xposScore + font.getStringWidth("Score") + 24;
int xposName = xposSpecial + font.getStringWidth("Round") + 16;
int xposDate = xposName + font.getStringWidth("Name") + 16;
int xposDelete = xposDate + font.getStringWidth("YY-MM-DD HH:MM") + 16;
int nWidth = font.getStringWidth("ABC") + 4;
int xposScore = xposRank + _font.getStringWidth("Rank") + 16;
int xposSpecial = xposScore + _font.getStringWidth("Score") + 24;
int xposName = xposSpecial + _font.getStringWidth("Round") + 16;
int xposDate = xposName + _font.getStringWidth("Name") + 16;
int xposDelete = xposDate + _font.getStringWidth("YY-MM-DD HH:MM") + 16;
int nWidth = _font.getStringWidth("ABC") + 4;
new StaticTextWidget(this, font, xposRank, ypos + 1, "Rank");
new StaticTextWidget(this, font, xposScore, ypos + 1, " Score");
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");
new StaticTextWidget(this, _font, xposRank, ypos + 1, "Rank");
new StaticTextWidget(this, _font, xposScore, ypos + 1, " Score");
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");
ypos += lineHeight + VGAP;
for (uInt32 p = 0; p < NUM_POSITIONS; ++p)
{
myPositionsWidget[p] = new StaticTextWidget(this, font, xposRank + 8, ypos + 1,
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");
myNamesWidget[p] = new StaticTextWidget(this, font, xposName + 2, ypos + 1, " ");
myEditNamesWidget[p] = new EditTextWidget(this, font, xposName, ypos - 1, nWidth, lineHeight);
myScoresWidget[p] = new StaticTextWidget(this, _font, xposScore, ypos + 1, "123456");
mySpecialsWidget[p] = new StaticTextWidget(this, _font, xposSpecial + 8, ypos + 1, "123");
myNamesWidget[p] = new StaticTextWidget(this, _font, xposName + 2, ypos + 1, " ");
myEditNamesWidget[p] = new EditTextWidget(this, _font, xposName, ypos - 1, nWidth, lineHeight);
myEditNamesWidget[p]->setFlags(EditTextWidget::FLAG_INVISIBLE);
myEditNamesWidget[p]->setEnabled(false);
wid.push_back(myEditNamesWidget[p]);
myDatesWidget[p] = new StaticTextWidget(this, font, xposDate, ypos + 1, "12-02-20 17:15");
myDeleteButtons[p] = new ButtonWidget(this, font, xposDelete, ypos + 1, 18, 18, "X",
myDatesWidget[p] = new StaticTextWidget(this, _font, xposDate, ypos + 1, "12-02-20 17:15");
myDeleteButtons[p] = new ButtonWidget(this, _font, xposDelete, ypos + 1, 18, 18, "X",
kDeleteSingle);
myDeleteButtons[p]->setID(p);
wid.push_back(myDeleteButtons[p]);
@ -103,9 +106,8 @@ HighScoresDialog::HighScoresDialog(OSystem& osystem, DialogContainer& parent,
myMD5Widget = new StaticTextWidget(this, ifont, xpos, ypos + 1, "MD5: 12345678901234567890123456789012");
addDefaultsOKCancelBGroup(wid, font, "Save", "Cancel", " Reset ");
addToFocusList(wid);
}
addDefaultsOKCancelBGroup(wid, _font, "Save", "Cancel", " Reset ");
addToFocusList(wid); }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
HighScoresDialog::~HighScoresDialog()
@ -142,7 +144,11 @@ void HighScoresDialog::loadConfig()
label = label.substr(label.length() - 5);
mySpecialLabelWidget->setLabel(label);
myMD5 = instance().console().properties().get(PropType::Cart_MD5);
if (instance().hasConsole())
myMD5 = instance().console().properties().get(PropType::Cart_MD5);
else
myMD5 = instance().launcher().selectedRomMD5();
myMD5Widget->setLabel("MD5: " + myMD5);
myEditPos = myHighScorePos = -1;
@ -173,7 +179,10 @@ void HighScoresDialog::handleCommand(CommandSender* sender, int cmd, int data, i
saveConfig();
[[fallthrough]];
case kCloseCmd:
instance().eventHandler().leaveMenuMode();
if(myMode != Menu::AppMode::emulator)
close();
else
instance().eventHandler().leaveMenuMode();
break;
case kVariationChanged:
@ -269,7 +278,6 @@ void HighScoresDialog::updateWidgets(bool init)
myEditNamesWidget[p]->setEditable(false);
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -363,33 +371,39 @@ bool HighScoresDialog::handleDirty()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void HighScoresDialog::saveHighScores(Int32 variation) const
string HighScoresDialog::cartName() const
{
if(instance().hasConsole())
return instance().console().properties().get(PropType::Cart_Name);
else
return instance().launcher().currentNode().getNameWithExt("");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void HighScoresDialog::saveHighScores(Int32 variation) const
{
ostringstream buf;
buf << instance().stateDir() << cartName() << ".hs" << variation;
// Make sure the file can be opened for writing
Serializer out(buf.str());
if(!out)
{
ostringstream buf;
buf << instance().stateDir()
<< instance().console().properties().get(PropType::Cart_Name)
<< ".hs" << variation;
// Make sure the file can be opened for writing
Serializer out(buf.str());
if(!out)
{
buf.str("");
buf << "Can't open/save to high scores file for variation " << variation;
instance().frameBuffer().showMessage(buf.str());
}
// Do a complete high scores save
if (!save(out, variation))
{
buf.str("");
buf << "Error saving high scores for variation" << variation;
instance().frameBuffer().showMessage(buf.str());
}
buf.str("");
buf << "Can't open/save to high scores file for variation " << variation;
instance().frameBuffer().showMessage(buf.str());
}
// Do a complete high scores save
if(!save(out, variation))
{
buf.str("");
buf << "Error saving high scores for variation" << variation;
instance().frameBuffer().showMessage(buf.str());
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -403,41 +417,37 @@ void HighScoresDialog::loadHighScores(Int32 variation)
myDates[p] = "";
}
if(instance().hasConsole())
ostringstream buf;
buf << instance().stateDir() << cartName() << ".hs" << variation;
// Make sure the file can be opened in read-only mode
Serializer in(buf.str(), Serializer::Mode::ReadOnly);
if(!in)
return;
// First test if we have a valid header
// If so, do a complete high scores load
buf.str("");
try
{
ostringstream buf;
buf << instance().stateDir()
<< instance().console().properties().get(PropType::Cart_Name)
<< ".hs" << variation;
// Make sure the file can be opened in read-only mode
Serializer in(buf.str(), Serializer::Mode::ReadOnly);
if(!in)
return;
// First test if we have a valid header
// If so, do a complete high scores load
buf.str("");
try
if (in.getString() != HIGHSCORE_HEADER)
buf << "Incompatible high scores for variation " << variation << " file";
else
{
if (in.getString() != HIGHSCORE_HEADER)
buf << "Incompatible high scores for variation " << variation << " file";
if (load(in, variation))
return;
else
{
if (load(in, variation))
return;
else
buf << "Invalid data in high scores for variation " << variation << " file";
}
buf << "Invalid data in high scores for variation " << variation << " file";
}
catch(...)
{
buf << "Invalid data in high scores for variation " << variation << " file";
}
instance().frameBuffer().showMessage(buf.str());
}
catch(...)
{
buf << "Invalid data in high scores for variation " << variation << " file";
}
instance().frameBuffer().showMessage(buf.str());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -31,6 +31,7 @@ namespace GUI {
}
class Serializer;
#include "Menu.hxx"
#include "Dialog.hxx"
/**
@ -45,7 +46,7 @@ class HighScoresDialog : public Dialog
static const uInt32 NUM_POSITIONS = 10;
HighScoresDialog(OSystem& osystem, DialogContainer& parent,
const GUI::Font& font, int max_w, int max_h);
int max_w, int max_h, Menu::AppMode mode);
virtual ~HighScoresDialog();
protected:
@ -60,6 +61,7 @@ class HighScoresDialog : public Dialog
void deletePos(int pos);
bool handleDirty();
string cartName() const;
void saveHighScores(Int32 variation) const;
void loadHighScores(Int32 variation);
@ -119,6 +121,8 @@ class HighScoresDialog : public Dialog
StaticTextWidget* myMD5Widget{nullptr};
Menu::AppMode myMode{Menu::AppMode::emulator};
private:
// Following constructors and assignment operators not supported
HighScoresDialog() = delete;

View File

@ -36,8 +36,9 @@ HighScoresMenu::~HighScoresMenu()
Dialog* HighScoresMenu::baseDialog()
{
if (myHighScoresDialog == nullptr)
myHighScoresDialog = new HighScoresDialog(myOSystem, *this, myOSystem.frameBuffer().font(),
FBMinimum::Width, FBMinimum::Height);
myHighScoresDialog = new HighScoresDialog(myOSystem, *this,
FBMinimum::Width, FBMinimum::Height,
Menu::AppMode::emulator);
return myHighScoresDialog;
}

View File

@ -26,6 +26,8 @@
#include "FSNode.hxx"
#include "MD5.hxx"
#include "OptionsDialog.hxx"
#include "HighScoresDialog.hxx"
#include "HighScoresManager.hxx"
#include "GlobalPropsDialog.hxx"
#include "StellaSettingsDialog.hxx"
#include "MessageBox.hxx"
@ -204,11 +206,8 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
addToFocusList(wid);
// Create context menu for ROM list options
VariantList l;
VarList::push_back(l, "Power-on options" + ELLIPSIS, "override");
VarList::push_back(l, "Reload listing", "reload");
myMenu = make_unique<ContextMenu>(this, osystem.frameBuffer().font(), l);
// Create (empty) context menu for ROM list options
myMenu = make_unique<ContextMenu>(this, osystem.frameBuffer().font(), EmptyVarList);
// Create global props dialog, which is used to temporarily overrride
// ROM properties
@ -353,6 +352,8 @@ void LauncherDialog::handleContextMenu()
myGlobalProps->open();
else if(cmd == "reload")
reload();
else if(cmd == "highscores")
openHighScores();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -460,6 +461,15 @@ void LauncherDialog::handleMouseDown(int x, int y, MouseButton b, int clickCount
// Grab right mouse button for context menu, send left to base class
if(b == MouseButton::RIGHT)
{
// Dynamically create context menu for ROM list options
VariantList items;
VarList::push_back(items, "Power-on options" + ELLIPSIS, "override");
if(instance().highScores().enabled())
VarList::push_back(items, "High scores" + ELLIPSIS, "highscores");
VarList::push_back(items, "Reload listing", "reload");
myMenu->addItems(items);
// Add menu at current x,y mouse location
myMenu->show(x + getAbsX(), y + getAbsY(), surface().dstRect());
}
@ -565,3 +575,14 @@ void LauncherDialog::openSettings()
myOptionsDialog->open();
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherDialog::openHighScores()
{
// Create an options dialog, similar to the in-game one
if(myHighScoresDialog == nullptr)
myHighScoresDialog = make_unique<HighScoresDialog>(instance(), parent(), _w, _h,
Menu::AppMode::launcher);
myHighScoresDialog->open();
}

View File

@ -24,6 +24,7 @@ class ContextMenu;
class DialogContainer;
class BrowserDialog;
class OptionsDialog;
class HighScoresDialog;
class GlobalPropsDialog;
class StellaSettingsDialog;
class OSystem;
@ -103,9 +104,11 @@ class LauncherDialog : public Dialog
void handleContextMenu();
void showOnlyROMs(bool state);
void openSettings();
void openHighScores();
private:
unique_ptr<OptionsDialog> myOptionsDialog;
unique_ptr<HighScoresDialog> myHighScoresDialog;
unique_ptr<StellaSettingsDialog> myStellaSettingsDialog;
unique_ptr<ContextMenu> myMenu;
unique_ptr<GlobalPropsDialog> myGlobalProps;