diff --git a/docs/graphics/options_gameinfo_cartridge.png b/docs/graphics/options_gameinfo_cartridge.png
index da6f4fdc4..772f1334b 100644
Binary files a/docs/graphics/options_gameinfo_cartridge.png and b/docs/graphics/options_gameinfo_cartridge.png differ
diff --git a/docs/graphics/options_gameinfo_console.png b/docs/graphics/options_gameinfo_console.png
index 83d4b04b1..f7233672b 100644
Binary files a/docs/graphics/options_gameinfo_console.png and b/docs/graphics/options_gameinfo_console.png differ
diff --git a/docs/graphics/options_gameinfo_controller.png b/docs/graphics/options_gameinfo_controller.png
index 6b8740424..63b5548a3 100644
Binary files a/docs/graphics/options_gameinfo_controller.png and b/docs/graphics/options_gameinfo_controller.png differ
diff --git a/docs/graphics/options_gameinfo_emulation.png b/docs/graphics/options_gameinfo_emulation.png
index 8da3b8c42..b67ca95f7 100644
Binary files a/docs/graphics/options_gameinfo_emulation.png and b/docs/graphics/options_gameinfo_emulation.png differ
diff --git a/docs/graphics/options_gameinfo_highscores.png b/docs/graphics/options_gameinfo_highscores.png
index 9a6e7f1d2..572aa252b 100644
Binary files a/docs/graphics/options_gameinfo_highscores.png and b/docs/graphics/options_gameinfo_highscores.png differ
diff --git a/docs/index.html b/docs/index.html
index d6cfdb001..359a8bfed 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -3930,7 +3930,7 @@
Allow all 4 directions ... | Allow all 4 joystick directions to be pressed simultaneously | -joyallow4 |
Use modifier key combos | Enable using modifier keys in keyboard actions | -modcombo |
Swap Stelladaptor ports | Swap the order of the detected Stelladaptors/2600-daptors (see Advanced Configuration - Stelladaptor/2600-daptor Support) | -saport |
- Joystick database | Show all joysticks that Stella knows about, with the option to remove them | |
+ Joystick Database | Show all joysticks that Stella knows about, with the option to remove them | |
Erase EEPROM | Erase the whole AtariVox/SaveKey flash memory | |
AtariVox serial port | Described in further detail in Advanced Configuration - AtariVox/SaveKey Support | -avoxport |
diff --git a/src/debugger/gui/DataGridOpsWidget.cxx b/src/debugger/gui/DataGridOpsWidget.cxx
index 2a62ec60c..e4bf5d247 100644
--- a/src/debugger/gui/DataGridOpsWidget.cxx
+++ b/src/debugger/gui/DataGridOpsWidget.cxx
@@ -34,7 +34,7 @@ DataGridOpsWidget::DataGridOpsWidget(GuiObject* boss, const GUI::Font& font,
_zeroButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight,
"0", kDGZeroCmd);
_zeroButton->setToolTip("Zero currently selected value");
-
+
ypos += bheight + space;
_invButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight,
"Inv", kDGInvertCmd);
diff --git a/src/debugger/gui/DebuggerDialog.cxx b/src/debugger/gui/DebuggerDialog.cxx
index 87481234c..8abf382d4 100644
--- a/src/debugger/gui/DebuggerDialog.cxx
+++ b/src/debugger/gui/DebuggerDialog.cxx
@@ -489,6 +489,8 @@ void DebuggerDialog::createBrowser(const string& title)
{
uInt32 w = 0, h = 0;
getDynamicBounds(w, h);
+ if(w > uInt32(_font.getMaxCharWidth() * 80))
+ w = _font.getMaxCharWidth() * 80;
// Create file browser dialog
if(!myBrowser || uInt32(myBrowser->getWidth()) != w ||
diff --git a/src/emucore/FSNode.cxx b/src/emucore/FSNode.cxx
index d9de7e0a5..212828379 100644
--- a/src/emucore/FSNode.cxx
+++ b/src/emucore/FSNode.cxx
@@ -59,7 +59,6 @@ FilesystemNode& FilesystemNode::operator/=(const string& path)
}
return *this;
-#undef PATH_SEPARATOR
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/gui/BrowserDialog.cxx b/src/gui/BrowserDialog.cxx
index 25b35aee1..3b1ee48a7 100644
--- a/src/gui/BrowserDialog.cxx
+++ b/src/gui/BrowserDialog.cxx
@@ -81,14 +81,19 @@ BrowserDialog::BrowserDialog(GuiObject* boss, const GUI::Font& font,
buttonWidth, buttonHeight, "Go up", kGoUpCmd);
addFocusWidget(_goUpButton);
- _basedirButton =
- new ButtonWidget(this, font, _goUpButton->getRight() + BUTTON_GAP, _h - buttonHeight - VBORDER,
- buttonWidth, buttonHeight, "Base Dir", kBaseDirCmd);
- addFocusWidget(_basedirButton);
+ b = new ButtonWidget(this, font, _goUpButton->getRight() + BUTTON_GAP, _h - buttonHeight - VBORDER,
+ buttonWidth, buttonHeight, "Base Dir", kBaseDirCmd);
+ b->setToolTip("Go to Stella's base directory.");
+ addFocusWidget(b);
+
+ b = new ButtonWidget(this, font, b->getRight() + BUTTON_GAP, _h - buttonHeight - VBORDER,
+ buttonWidth, buttonHeight, "Home Dir", kHomeDirCmd);
+ b->setToolTip("Go to user's home directory.");
+ addFocusWidget(b);
#ifndef BSPF_MACOS
b = new ButtonWidget(this, font, _w - (2 * buttonWidth + BUTTON_GAP + HBORDER), _h - buttonHeight - VBORDER,
- buttonWidth, buttonHeight, "Choose", kChooseCmd);
+ buttonWidth, buttonHeight, "OK", kChooseCmd);
addFocusWidget(b);
addOKWidget(b);
b = new ButtonWidget(this, font, _w - (buttonWidth + HBORDER), _h - buttonHeight - VBORDER,
@@ -101,7 +106,7 @@ BrowserDialog::BrowserDialog(GuiObject* boss, const GUI::Font& font,
addFocusWidget(b);
addCancelWidget(b);
b = new ButtonWidget(this, font, _w - (buttonWidth + HBORDER), _h - buttonHeight - VBORDER,
- buttonWidth, buttonHeight, "Choose", kChooseCmd);
+ buttonWidth, buttonHeight, "OK", kChooseCmd);
addFocusWidget(b);
addOKWidget(b);
#endif
@@ -115,7 +120,9 @@ void BrowserDialog::show(const string& startpath,
_mode = mode;
_cmd = cmd;
_cancelCmd = cancelCmd;
- string fileName;
+ string directory;// = EmptyString;
+ string fileName;// = EmptyString;
+ bool fileSelected = true;
// Set start path
if(_mode != Directories)
@@ -123,13 +130,7 @@ void BrowserDialog::show(const string& startpath,
// split startpath into path and filename
FilesystemNode fs = FilesystemNode(startpath);
fileName = fs.getName();
- string directory = fs.isDirectory() ? "" : fs.getParent().getPath();
-
- _fileList->setDirectory(FilesystemNode(directory), fileName);
- }
- else
- {
- _fileList->setDirectory(FilesystemNode(startpath));
+ directory = fs.isDirectory() ? "" : fs.getParent().getPath();
}
switch(_mode)
@@ -144,7 +145,6 @@ void BrowserDialog::show(const string& startpath,
_selected->clearFlags(Widget::FLAG_INVISIBLE);
_type->clearFlags(Widget::FLAG_INVISIBLE);
_okWidget->setLabel("Load");
- updateUI(true);
break;
case FileSave:
@@ -158,7 +158,7 @@ void BrowserDialog::show(const string& startpath,
_type->clearFlags(Widget::FLAG_INVISIBLE);
_okWidget->setLabel("Save");
_selected->setText(fileName);
- updateUI(false);
+ fileSelected = false;
break;
case Directories:
@@ -168,11 +168,17 @@ void BrowserDialog::show(const string& startpath,
_selected->setEnabled(false);
_selected->setFlags(Widget::FLAG_INVISIBLE);
_type->setFlags(Widget::FLAG_INVISIBLE);
- _okWidget->setLabel("Choose");
- updateUI(true);
+ _okWidget->setLabel("OK");
break;
}
+ // Set start path
+ if(_mode != Directories)
+ _fileList->setDirectory(FilesystemNode(directory), fileName);
+ else
+ _fileList->setDirectory(FilesystemNode(startpath));
+ updateUI(fileSelected);
+
// Finally, open the dialog after it has been fully updated
open();
}
@@ -182,76 +188,15 @@ const FilesystemNode& BrowserDialog::getResult() const
{
if(_mode == FileLoad || _mode == FileSave)
{
- static FilesystemNode node(_fileList->currentDir().getShortPath() + _selected->getText());
+ static FilesystemNode node;
- return node;
+ return node
+ = FilesystemNode(_fileList->currentDir().getShortPath() + _selected->getText());
}
else
return _fileList->currentDir();
}
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void BrowserDialog::updateUI(bool fileSelected)
-{
- // Only hilite the 'up' button if there's a parent directory
- _goUpButton->setEnabled(_fileList->currentDir().hasParent());
-
- // Update the path display
- _currentPath->setText(_fileList->currentDir().getShortPath());
-
- // Enable/disable OK button based on current mode
- //bool enable = true;
- //switch(_mode)
- //{
- // case Directories:
- // enable = true;
- // break;
-
- // case FileLoad:
- // if(_fileList->selected().isDirectory())
- // {
- // enable = false;
- // _selected->setText("");
- // }
- // else
- // {
- // enable = fileSelected && !_selected->getText().empty();
- // _selected->setText(_fileList->getSelectedString());
- // }
- // break;
-
- // case FileSave:
- // if(_fileList->selected().isDirectory())
- // {
- // enable = false;
- // _selected->setText("");
- // }
- // else
- // {
- // enable = fileSelected && !_selected->getText().empty(); // TODO
- // _selected->setText(_fileList->getSelectedString());
- // }
- // break;
-
- // default:
- // break;
- //}
- //_okWidget->setEnabled(enable);
-
- bool enable = _mode == Directories
- || (!_fileList->selected().isDirectory() && fileSelected)
- || (!_selected->getText().empty() && !fileSelected);
- _okWidget->setEnabled(enable);
-
- if(fileSelected)
- {
- if(!_fileList->selected().isDirectory())
- _selected->setText(_fileList->getSelectedString());
- else
- _selected->setText("");
- }
-}
-
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void BrowserDialog::handleCommand(CommandSender* sender, int cmd,
int data, int id)
@@ -281,6 +226,10 @@ void BrowserDialog::handleCommand(CommandSender* sender, int cmd,
_fileList->setDirectory(FilesystemNode(instance().baseDir()));
break;
+ case kHomeDirCmd:
+ _fileList->setDirectory(FilesystemNode(instance().defaultSaveDir()));
+ break;
+
case EditableWidget::kChangedCmd:
Dialog::handleCommand(sender, cmd, data, 0);
updateUI(false);
@@ -295,3 +244,23 @@ void BrowserDialog::handleCommand(CommandSender* sender, int cmd,
break;
}
}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void BrowserDialog::updateUI(bool fileSelected)
+{
+ // Only hilite the 'up' button if there's a parent directory
+ _goUpButton->setEnabled(_fileList->currentDir().hasParent());
+
+ // Update the path display
+ _currentPath->setText(_fileList->currentDir().getShortPath());
+
+ // Enable/disable OK button based on current mode and status
+ bool enable = true;
+
+ if(_mode != Directories)
+ enable = !_selected->getText().empty();
+ _okWidget->setEnabled(enable);
+
+ if(fileSelected && !_fileList->selected().isDirectory())
+ _selected->setText(_fileList->getSelectedString());
+}
diff --git a/src/gui/BrowserDialog.hxx b/src/gui/BrowserDialog.hxx
index 9ee401ad6..1038398c0 100644
--- a/src/gui/BrowserDialog.hxx
+++ b/src/gui/BrowserDialog.hxx
@@ -58,7 +58,8 @@ class BrowserDialog : public Dialog, public CommandSender
enum {
kChooseCmd = 'CHOS',
kGoUpCmd = 'GOUP',
- kBaseDirCmd = 'BADR'
+ kBaseDirCmd = 'BADR',
+ kHomeDirCmd = 'HODR'
};
int _cmd{0};
@@ -69,7 +70,6 @@ class BrowserDialog : public Dialog, public CommandSender
StaticTextWidget* _type{nullptr};
EditTextWidget* _selected{nullptr};
ButtonWidget* _goUpButton{nullptr};
- ButtonWidget* _basedirButton{nullptr};
BrowserDialog::ListMode _mode{Directories};
diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx
index 3700caf5f..fc2c08c47 100644
--- a/src/gui/GameInfoDialog.cxx
+++ b/src/gui/GameInfoDialog.cxx
@@ -29,6 +29,7 @@
#include "Paddles.hxx"
#include "PopUpWidget.hxx"
#include "PropsSet.hxx"
+#include "BrowserDialog.hxx"
#include "QuadTariDialog.hxx"
#include "TabWidget.hxx"
#include "TIAConstants.hxx"
@@ -92,7 +93,7 @@ GameInfoDialog::GameInfoDialog(
myTab->setActiveTab(0);
// Add Defaults, OK and Cancel buttons
- addDefaultsExtraOKCancelBGroup(wid, font, "Export", kExportPressed);
+ addDefaultsExtraOKCancelBGroup(wid, font, "Export" + ELLIPSIS, kExportPressed);
_extraWidget->setToolTip("Export the current ROM's properties\n"
"into the default directory.");
addBGroupToFocusList(wid);
@@ -660,12 +661,27 @@ void GameInfoDialog::addHighScoresTab()
addToFocusList(wid, myTab, tabID);
}
-
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
GameInfoDialog::~GameInfoDialog()
{
}
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void GameInfoDialog::createBrowser(const string& title)
+{
+ uInt32 w = 0, h = 0;
+ getDynamicBounds(w, h);
+ if(w > uInt32(_font.getMaxCharWidth() * 80))
+ w = _font.getMaxCharWidth() * 80;
+
+ // Create file browser dialog
+ if(!myBrowser || uInt32(myBrowser->getWidth()) != w ||
+ uInt32(myBrowser->getHeight()) != h)
+ myBrowser = make_unique(this, _font, w, h, title);
+ else
+ myBrowser->setTitle(title);
+}
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GameInfoDialog::loadConfig()
{
@@ -1350,16 +1366,14 @@ void GameInfoDialog::exportCurrentPropertiesToDisk()
try
{
- FilesystemNode propfile = instance().defaultSaveDir();
- propfile /= myGameFile.getNameWithExt(".pro");
+ FilesystemNode propfile(myBrowser->getResult().getShortPath());
propfile.write(out);
- instance().frameBuffer().showTextMessage("Properties exported to " +
- propfile.getShortPath());
+ instance().frameBuffer().showTextMessage("ROM properties exported");
}
catch(...)
{
- instance().frameBuffer().showTextMessage("Error exporting properties");
+ instance().frameBuffer().showTextMessage("Error exporting ROM properties");
}
}
@@ -1379,6 +1393,15 @@ void GameInfoDialog::handleCommand(CommandSender* sender, int cmd,
break;
case kExportPressed:
+ // This dialog is resizable under certain conditions, so we need
+ // to re-create it as necessary
+ createBrowser("Export properties as");
+
+ myBrowser->show(instance().defaultSaveDir().getPath() + myGameFile.getNameWithExt(".pro"),
+ BrowserDialog::FileSave, kExportChosen);
+ break;
+
+ case kExportChosen:
exportCurrentPropertiesToDisk();
break;
diff --git a/src/gui/GameInfoDialog.hxx b/src/gui/GameInfoDialog.hxx
index c217bd689..d3af6775e 100644
--- a/src/gui/GameInfoDialog.hxx
+++ b/src/gui/GameInfoDialog.hxx
@@ -27,6 +27,7 @@ class RadioButtonGroup;
class TabWidget;
class SliderWidget;
class QuadTariDialog;
+class BrowserDialog;
#include "Dialog.hxx"
#include "Command.hxx"
@@ -78,6 +79,7 @@ class GameInfoDialog : public Dialog, public CommandSender
void setAddressVal(EditTextWidget* address, EditTextWidget* val,
bool isBCD = true, bool zeroBased = false, uInt8 maxVal = 255);
void exportCurrentPropertiesToDisk();
+ void createBrowser(const string& title);
private:
TabWidget* myTab{nullptr};
@@ -168,6 +170,8 @@ class GameInfoDialog : public Dialog, public CommandSender
StaticTextWidget* myHighScoreNotesLabel{nullptr};
EditTextWidget* myHighScoreNotes{nullptr};
+ unique_ptr myBrowser;
+
enum {
kVCenterChanged = 'Vcch',
kPhosphorChanged = 'PPch',
@@ -180,7 +184,8 @@ class GameInfoDialog : public Dialog, public CommandSender
kHiScoresChanged = 'HSch',
kPXCenterChanged = 'Pxch',
kPYCenterChanged = 'Pych',
- kExportPressed = 'GIsp'
+ kExportPressed = 'Expr',
+ kExportChosen = 'Exch'
};
// Game properties for currently loaded ROM
diff --git a/src/gui/RomAuditDialog.cxx b/src/gui/RomAuditDialog.cxx
index 65b4d0c33..60b627f8d 100644
--- a/src/gui/RomAuditDialog.cxx
+++ b/src/gui/RomAuditDialog.cxx
@@ -223,6 +223,8 @@ void RomAuditDialog::createBrowser(const string& title)
{
uInt32 w = 0, h = 0;
getDynamicBounds(w, h);
+ if(w > uInt32(_font.getMaxCharWidth() * 80))
+ w = _font.getMaxCharWidth() * 80;
// Create file browser dialog
if(!myBrowser || uInt32(myBrowser->getWidth()) != w ||
diff --git a/src/gui/SnapshotDialog.cxx b/src/gui/SnapshotDialog.cxx
index 80af8ec1d..c983c1d5b 100644
--- a/src/gui/SnapshotDialog.cxx
+++ b/src/gui/SnapshotDialog.cxx
@@ -183,6 +183,8 @@ void SnapshotDialog::createBrowser(const string& title)
{
uInt32 w = 0, h = 0;
getDynamicBounds(w, h);
+ if(w > uInt32(_font.getMaxCharWidth() * 80))
+ w = _font.getMaxCharWidth() * 80;
// Create file browser dialog
if(!myBrowser || uInt32(myBrowser->getWidth()) != w ||
diff --git a/src/gui/UIDialog.cxx b/src/gui/UIDialog.cxx
index beb6f576d..6ba10d9f8 100644
--- a/src/gui/UIDialog.cxx
+++ b/src/gui/UIDialog.cxx
@@ -706,6 +706,8 @@ void UIDialog::createBrowser(const string& title)
{
uInt32 w = 0, h = 0;
getDynamicBounds(w, h);
+ if(w > uInt32(_font.getMaxCharWidth() * 80))
+ w = _font.getMaxCharWidth() * 80;
// Create file browser dialog
if(!myBrowser || uInt32(myBrowser->getWidth()) != w ||