@@ -1504,7 +1504,7 @@ matches the address of the disassembly line where the mouse was clicked.
Disassemble @ current line: Disassemble from the disassembly line where the mouse was clicked.
This allows to fill gaps in the disassembly and is most useful for bankswitched ROMs.
-Show tentative code: Allow Distella to do a static analysis/disassembly.
+Show tentative code: Allow DiStella to do a static analysis/disassembly.
Show PC addresses: Show Program Counter addresses as labels (where there
isn't already a defined label).
@@ -1512,7 +1512,7 @@ isn't already a defined label).
Show GFX as binary: Switch between displaying/editing GFX and PGFX sections
in either binary or hexidecimal.
-Use address relocation: Corresponds to the Distella '-r' option
+Use address relocation: Corresponds to the DiStella '-r' option
(Relocate calls out of address range).
Note: The code will continue to run fine, but the ROM image will be altered.
@@ -1587,7 +1587,7 @@ the RAM in the DPC scheme is not viewable by the 6507, so its addresses start fr
-
+
As mentioned in ROM Disassembly, Stella supports the following directives:
CODE, GFX, PGFX, COL, PCOL, BCOL, AUD, DATA, ROW. While the debugger will try to automatically mark address
space with the appropriate directive, there are times when it will fail. There are
diff --git a/src/debugger/DebuggerParser.cxx b/src/debugger/DebuggerParser.cxx
index 73f09268f..97c302392 100644
--- a/src/debugger/DebuggerParser.cxx
+++ b/src/debugger/DebuggerParser.cxx
@@ -35,6 +35,7 @@
#include "PromptWidget.hxx"
#include "RomWidget.hxx"
#include "ProgressDialog.hxx"
+#include "BrowserDialog.hxx"
#include "TimerManager.hxx"
#include "Vec.hxx"
@@ -1828,14 +1829,20 @@ void DebuggerParser::executeS()
// "save"
void DebuggerParser::executeSave()
{
- commandResult << saveScriptFile(argStrings[0]);
+ if(argCount && argStrings[0] == "?")
+ debugger.myDialog->showBrowser(DebuggerDialog::svScript);
+ else
+ commandResult << saveScriptFile(argStrings[0]);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "saveaccess"
void DebuggerParser::executeSaveAccess()
{
- commandResult << debugger.cartDebug().saveAccessFile();
+ if(argCount && argStrings[0] == "?")
+ debugger.myDialog->showBrowser(DebuggerDialog::svAccess);
+ else
+ commandResult << debugger.cartDebug().saveAccessFile();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/src/debugger/gui/DebuggerDialog.cxx b/src/debugger/gui/DebuggerDialog.cxx
index be9ad7515..9c51f567b 100644
--- a/src/debugger/gui/DebuggerDialog.cxx
+++ b/src/debugger/gui/DebuggerDialog.cxx
@@ -37,19 +37,20 @@
#include "DataGridOpsWidget.hxx"
#include "EditTextWidget.hxx"
#include "MessageBox.hxx"
-#include "Debugger.hxx"
-#include "DebuggerParser.hxx"
+#include "debugger.hxx"
+#include "debuggerParser.hxx"
#include "ConsoleFont.hxx"
#include "ConsoleBFont.hxx"
#include "ConsoleMediumFont.hxx"
#include "ConsoleMediumBFont.hxx"
#include "StellaMediumFont.hxx"
#include "OptionsDialog.hxx"
+#include "BrowserDialog.hxx"
#include "StateManager.hxx"
#include "FrameManager.hxx"
#include "OSystem.hxx"
#include "Console.hxx"
-#include "DebuggerDialog.hxx"
+#include "debuggerDialog.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DebuggerDialog::DebuggerDialog(OSystem& osystem, DialogContainer& parent,
@@ -256,6 +257,43 @@ void DebuggerDialog::handleCommand(CommandSender* sender, int cmd,
loadConfig();
break;
+ case kSvScriptCmd:
+ execSave("save");
+ break;
+
+ case kSvSessionCmd:
+ execSave("saveses");
+ break;
+
+ case kSvConfigCmd:
+ execSave("saveconfig");
+ break;
+
+ case kSvDisCmd:
+ execSave("savedis");
+ break;
+
+ case kSvAccessCmd:
+ execSave("saveaccess");
+ break;
+
+ case kSvRomCmd:
+ execSave("saverom");
+ break;
+
+ case kSvStateCmd:
+ execSave("savestate");
+ break;
+
+
+ case kSvAllStatesCmd:
+ execSave("saveallstates");
+ break;
+
+ case kSvSnapCmd:
+ execSave("savesnap"); // TODO: param
+ break;
+
case RomWidget::kInvalidateListing:
// Only do a full redraw if the disassembly tab is actually showing
myRom->invalidate(myRomTab->getActiveTab() == 0);
@@ -408,6 +446,114 @@ void DebuggerDialog::createFont()
}
}
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void DebuggerDialog::showBrowser(BrowserType type)
+{
+ int cmd;
+ string title;
+ string key;
+ string defaultPath;
+
+ switch(type)
+ {
+ case BrowserType::svScript:
+ cmd = kSvScriptCmd;
+ title = "workbench";
+ key = "dbg.savepath";
+ defaultPath = instance().defaultSaveDir().getPath() + "commands.script";
+ break;
+
+ case BrowserType::svSession:
+ cmd = kSvSessionCmd;
+ title = "session";
+ key = "dbg.savesessionpath";
+ break;
+
+ case BrowserType::svConfig:
+ cmd = kSvConfigCmd;
+ title = "DiStella config";
+ key = "dbg.saveconfigpath";
+ break;
+
+ case BrowserType::svDis:
+ cmd = kSvDisCmd;
+ title = "disassembly";
+ key = "dbg.savedispath";
+ break;
+
+ case BrowserType::svAccess:
+ cmd = kSvAccessCmd;
+ title = "access counters";
+ key = "dbg.saveaccesspath";
+ break;
+
+ case BrowserType::svRom:
+ cmd = kSvRomCmd;
+ title = "ROM";
+ key = "dbg.saverompath";
+ break;
+
+ case BrowserType::svState:
+ cmd = kSvStateCmd;
+ title = "state";
+ key = "dbg.savestatepath";
+ break;
+
+ case BrowserType::svAllStates:
+ cmd = kSvAllStatesCmd;
+ title = "all states";
+ key = "dbg.savestatepath";
+ break;
+
+ case BrowserType::svSnap:
+ cmd = kSvSnapCmd;
+ title = "snapshot";
+ key = "snapsavedir";
+ break;
+
+ default:
+ cmd = 0;
+ break;
+ }
+
+ if(cmd)
+ {
+ //TODO: default path (path and filename)
+ string path = instance().settings().getString(key);
+
+ createBrowser("Save " + title + " as");
+
+ if(path.empty())
+ path = defaultPath;
+
+ //myBrowser->show(instance().defaultSaveDir().getPath(),
+ // BrowserDialog::FileSave, cmd);
+ myBrowser->show(path, BrowserDialog::FileSave, cmd);
+ }
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void DebuggerDialog::execSave(const string& command)
+{
+ FilesystemNode dir(myBrowser->getResult());
+
+ instance().debugger().parser().run(command + " " + dir.getShortPath());
+}
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void DebuggerDialog::createBrowser(const string& title)
+{
+ uInt32 w = 0, h = 0;
+ getDynamicBounds(w, h);
+
+ // Create file browser dialog
+ if(!myBrowser || uInt32(myBrowser->getWidth()) != w ||
+ uInt32(myBrowser->getHeight()) != h)
+ myBrowser = make_unique(this, instance().frameBuffer().font(), w, h, title);
+ else
+ myBrowser->setTitle(title);
+}
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DebuggerDialog::showFatalMessage(const string& msg)
{
diff --git a/src/debugger/gui/DebuggerDialog.hxx b/src/debugger/gui/DebuggerDialog.hxx
index 0affa5160..76fb869bb 100644
--- a/src/debugger/gui/DebuggerDialog.hxx
+++ b/src/debugger/gui/DebuggerDialog.hxx
@@ -34,6 +34,7 @@ class TiaZoomWidget;
class CartDebugWidget;
class CartRamWidget;
class OptionsDialog;
+class BrowserDialog;
namespace GUI {
class MessageBox;
@@ -54,6 +55,17 @@ class DebuggerDialog : public Dialog
kMediumFontMinW = 1160, kMediumFontMinH = 770,
kLargeFontMinW = 1160, kLargeFontMinH = 870
};
+ enum BrowserType {
+ svScript, // save
+ svSession, // saveses
+ svConfig, // saveconfig
+ svDis, // savedis
+ svAccess, // saveaccess
+ svRom, // saverom
+ svState, // savestate
+ svAllStates, // saveallstates
+ svSnap // savesnap
+ };
DebuggerDialog(OSystem& osystem, DialogContainer& parent,
int x, int y, int w, int h);
@@ -74,6 +86,7 @@ class DebuggerDialog : public Dialog
void showFatalMessage(const string& msg);
void saveConfig() override;
+ void showBrowser(BrowserType type);
private:
void center() override { positionAt(0); }
@@ -113,11 +126,23 @@ class DebuggerDialog : public Dialog
kDDSAdvCmd = 'DDsv',
kDDRewindCmd = 'DDrw',
kDDUnwindCmd = 'DDuw',
- kDDRunCmd = 'DDex',
+ kDDRunCmd = 'DDex',
kDDExitFatalCmd = 'DDer',
- kDDOptionsCmd = 'DDop'
+ kDDOptionsCmd = 'DDop',
+ kSvScriptCmd = 'SvSc',
+ kSvSessionCmd = 'SvSs',
+ kSvConfigCmd = 'SvCn',
+ kSvDisCmd = 'SvDs',
+ kSvAccessCmd = 'SvAc',
+ kSvRomCmd = 'SvRm',
+ kSvStateCmd = 'SvSt',
+ kSvAllStatesCmd = 'SvAs',
+ kSvSnapCmd = 'SvSn'
};
+ void execSave(const string& command);
+ void createBrowser(const string& title);
+
TabWidget *myTab{nullptr}, *myRomTab{nullptr};
PromptWidget* myPrompt{nullptr};
@@ -135,7 +160,8 @@ class DebuggerDialog : public Dialog
ButtonWidget* myUnwindButton{nullptr};
unique_ptr myFatalError;
- unique_ptr myOptions;
+ unique_ptr myOptions;
+ unique_ptr myBrowser;
unique_ptr myLFont; // used for labels
unique_ptr myNFont; // used for normal text
diff --git a/src/gui/BrowserDialog.cxx b/src/gui/BrowserDialog.cxx
index 544ff4518..49a311763 100644
--- a/src/gui/BrowserDialog.cxx
+++ b/src/gui/BrowserDialog.cxx
@@ -74,7 +74,7 @@ BrowserDialog::BrowserDialog(GuiObject* boss, const GUI::Font& font,
_type = new StaticTextWidget(this, font, xpos, ypos + 2, "Name ");
_selected = new EditTextWidget(this, font, xpos + _type->getWidth(), ypos,
_w - _type->getWidth() - 2 * xpos, lineHeight, "");
- _selected->setEditable(false);
+ addFocusWidget(_selected);
// Buttons
_goUpButton = new ButtonWidget(this, font, xpos, _h - buttonHeight - VBORDER,
@@ -112,45 +112,71 @@ void BrowserDialog::show(const string& startpath,
BrowserDialog::ListMode mode, int cmd,
const string& ext)
{
+#ifdef BSPF_WINDOWS
+ #define PATH_SEPARATOR '\\'
+#else
+ #define PATH_SEPARATOR '/'
+#endif
_cmd = cmd;
_mode = mode;
+ string fileName;
+
+ // Set start path
+ if(_mode != Directories)
+ {
+ // 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));
+ }
switch(_mode)
{
case FileLoad:
_fileList->setListMode(FilesystemNode::ListMode::All);
- _fileList->setNameFilter([&ext](const FilesystemNode& node) {
+ _fileList->setNameFilter([ext](const FilesystemNode& node) {
return BSPF::endsWithIgnoreCase(node.getName(), ext);
});
_selected->setEditable(false);
+ _selected->setEnabled(false);
_selected->clearFlags(Widget::FLAG_INVISIBLE);
_type->clearFlags(Widget::FLAG_INVISIBLE);
+ _okWidget->setLabel("Load");
+ updateUI(true);
break;
case FileSave:
_fileList->setListMode(FilesystemNode::ListMode::All);
- _fileList->setNameFilter([&ext](const FilesystemNode& node) {
+ _fileList->setNameFilter([ext](const FilesystemNode& node) {
return BSPF::endsWithIgnoreCase(node.getName(), ext);
});
- _selected->setEditable(false); // FIXME - disable user input for now
+ _selected->setEditable(true);
+ _selected->setEnabled(true);
_selected->clearFlags(Widget::FLAG_INVISIBLE);
_type->clearFlags(Widget::FLAG_INVISIBLE);
+ _okWidget->setLabel("Save");
+ _selected->setText(fileName);
+ updateUI(false);
break;
case Directories:
_fileList->setListMode(FilesystemNode::ListMode::DirectoriesOnly);
_fileList->setNameFilter([](const FilesystemNode&) { return true; });
_selected->setEditable(false);
+ _selected->setEnabled(false);
_selected->setFlags(Widget::FLAG_INVISIBLE);
_type->setFlags(Widget::FLAG_INVISIBLE);
+ _okWidget->setLabel("Choose");
+ updateUI(true);
break;
}
- // Set start path
- _fileList->setDirectory(FilesystemNode(startpath));
-
- updateUI();
-
// Finally, open the dialog after it has been fully updated
open();
}
@@ -159,13 +185,17 @@ void BrowserDialog::show(const string& startpath,
const FilesystemNode& BrowserDialog::getResult() const
{
if(_mode == FileLoad || _mode == FileSave)
- return _fileList->selected();
+ {
+ static FilesystemNode node(_fileList->currentDir().getShortPath() + _selected->getText());
+
+ return node;
+ }
else
return _fileList->currentDir();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-void BrowserDialog::updateUI()
+void BrowserDialog::updateUI(bool fileSelected)
{
// Only hilite the 'up' button if there's a parent directory
_goUpButton->setEnabled(_fileList->currentDir().hasParent());
@@ -174,13 +204,56 @@ void BrowserDialog::updateUI()
_currentPath->setText(_fileList->currentDir().getShortPath());
// Enable/disable OK button based on current mode
- bool enable = _mode == Directories || !_fileList->selected().isDirectory();
+ //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(!_fileList->selected().isDirectory())
- _selected->setText(_fileList->getSelectedString());
- else
- _selected->setText("");
+ if(fileSelected)
+ {
+ if(!_fileList->selected().isDirectory())
+ _selected->setText(_fileList->getSelectedString());
+ else
+ _selected->setText("");
+ }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -205,8 +278,13 @@ void BrowserDialog::handleCommand(CommandSender* sender, int cmd,
_fileList->setDirectory(FilesystemNode(instance().baseDir()));
break;
+ case EditableWidget::kChangedCmd:
+ Dialog::handleCommand(sender, cmd, data, 0);
+ updateUI(false);
+ break;
+
case FileListWidget::ItemChanged:
- updateUI();
+ updateUI(true);
break;
default:
diff --git a/src/gui/BrowserDialog.hxx b/src/gui/BrowserDialog.hxx
index 253e183b7..75a84c7c3 100644
--- a/src/gui/BrowserDialog.hxx
+++ b/src/gui/BrowserDialog.hxx
@@ -52,7 +52,7 @@ class BrowserDialog : public Dialog, public CommandSender
private:
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
- void updateUI();
+ void updateUI(bool fileSelected);
private:
enum {
diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx
index 85c95349f..7c1d7ecd5 100644
--- a/src/gui/Dialog.cxx
+++ b/src/gui/Dialog.cxx
@@ -684,7 +684,7 @@ bool Dialog::handleNavEvent(Event::Type e, bool repeated)
if(_okWidget && _okWidget->isEnabled() && !repeated)
{
// Receiving 'OK' is the same as getting the 'Select' event
- _okWidget->handleEvent(Event::UISelect);
+ //_okWidget->handleEvent(Event::UISelect);
return true;
}
break;
@@ -693,7 +693,7 @@ bool Dialog::handleNavEvent(Event::Type e, bool repeated)
if(_cancelWidget && _cancelWidget->isEnabled() && !repeated)
{
// Receiving 'Cancel' is the same as getting the 'Select' event
- _cancelWidget->handleEvent(Event::UISelect);
+ //_cancelWidget->handleEvent(Event::UISelect);
return true;
}
else if(_processCancel)
diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx
index 1f6bbec60..001dafcc0 100644
--- a/src/gui/Dialog.hxx
+++ b/src/gui/Dialog.hxx
@@ -73,9 +73,9 @@ class Dialog : public GuiObject
void addToFocusList(WidgetArray& list, TabWidget* w, int tabId);
void addBGroupToFocusList(WidgetArray& list) { _buttonGroup = list; }
void addTabWidget(TabWidget* w);
- void addDefaultWidget(Widget* w) { _defaultWidget = w; }
- void addOKWidget(Widget* w) { _okWidget = w; }
- void addCancelWidget(Widget* w) { _cancelWidget = w; }
+ void addDefaultWidget(ButtonWidget* w) { _defaultWidget = w; }
+ void addOKWidget(ButtonWidget* w) { _okWidget = w; }
+ void addCancelWidget(ButtonWidget* w) { _cancelWidget = w; }
void setFocus(Widget* w);
/** Returns the base surface associated with this dialog. */
@@ -192,9 +192,9 @@ class Dialog : public GuiObject
Widget* _mouseWidget{nullptr};
Widget* _focusedWidget{nullptr};
Widget* _dragWidget{nullptr};
- Widget* _defaultWidget{nullptr};
- Widget* _okWidget{nullptr};
- Widget* _cancelWidget{nullptr};
+ ButtonWidget* _defaultWidget{nullptr};
+ ButtonWidget* _okWidget{nullptr};
+ ButtonWidget* _cancelWidget{nullptr};
bool _visible{false};
bool _onTop{true};