Merge remote-tracking branch 'origin/master' into feature/full-on-sqlite

This commit is contained in:
Christian Speckner 2020-12-30 21:02:05 +01:00
commit f496f8b74a
17 changed files with 227 additions and 162 deletions

View File

@ -41,7 +41,7 @@
* Fixed autofire bug for trackball controllers. * Fixed autofire bug for trackball controllers.
* Fixed bug in TV autodetection in filenames; a filename containing * Fixed bug in TV autodetection in filenames; a filename containing
'PAL' would sometimes misdetect as a PAL ROM. 'PAL' inside a word would sometimes misdetect as a PAL ROM.
* Fixed Stelladaptor/2600'daptor devices sometimes not being assigned * Fixed Stelladaptor/2600'daptor devices sometimes not being assigned
correct default mappings. correct default mappings.

View File

@ -947,7 +947,7 @@ clearsavestateifs - Clear all savestate points
deltrap - Delete trap <xx> deltrap - Delete trap <xx>
delwatch - Delete watch <xx> delwatch - Delete watch <xx>
disasm - Disassemble address xx [yy lines] (default=PC) disasm - Disassemble address xx [yy lines] (default=PC)
dump - Dump data at address <xx> [to yy] [1: memory; 2: CPU state; 4: input regs] dump - Dump data at address <xx> [to yy] [1: memory; 2: CPU state; 4: input regs] [?]
exec - Execute script file <xx> [prefix] exec - Execute script file <xx> [prefix]
exitrom - Exit emulator, return to ROM launcher exitrom - Exit emulator, return to ROM launcher
frame - Advance emulation by <xx> frames (default=1) frame - Advance emulation by <xx> frames (default=1)
@ -989,12 +989,12 @@ clearsavestateifs - Clear all savestate points
runto - Run until string xx in disassembly runto - Run until string xx in disassembly
runtopc - Run until PC is set to value xx runtopc - Run until PC is set to value xx
s - Set Stack Pointer to value xx s - Set Stack Pointer to value xx
save - Save breaks, watches, traps and functions to file xx (use ? for file dialog) save - Save breaks, watches, traps and functions to file <xx or ?>
saveaccess - Save access counters to CSV file (use ? for file dialog) saveaccess - Save access counters to CSV file [?]
saveconfig - Save DiStella config file (with default name) saveconfig - Save DiStella config file (with default name)
savedis - Save DiStella disassembly (use ? for file dialog) savedis - Save DiStella disassembly to file [?]
saverom - Save (possibly patched) ROM (use ? for file dialog) saverom - Save (possibly patched) ROM to file [?]
saveses - Save console session (use ? for file dialog) saveses - Save console session to file [?]
savesnap - Save current TIA image to PNG file savesnap - Save current TIA image to PNG file
saveallstates - Save all emulator states saveallstates - Save all emulator states
savestate - Save emulator state xx (valid args 0-9) savestate - Save emulator state xx (valid args 0-9)

View File

@ -3239,19 +3239,21 @@
<tr> <tr>
<td><pre>-dis.resolve &lt;1|0&gt;</pre></td> <td><pre>-dis.resolve &lt;1|0&gt;</pre></td>
<td>Try to differentiate between code vs. data sections in the <td>Try to differentiate between tentative code vs. data sections in the
disassembler. See the <b>Debugger - <a href="debugger.html#DisassemblySettings">ROM Disassembly Settings</b></a> for more information.</td> disassembler via static code analysis. See the <b>Debugger -
<a href="debugger.html#DisassemblySettings">ROM Disassembly Settings</b></a> for more information.</td>
</tr> </tr>
<tr> <tr>
<td><pre>-dis.gfxformat &lt;2|16&gt;</pre></td> <td><pre>-dis.gfxformat &lt;2|16&gt;</pre></td>
<td>Set the base to use for displaying GFX sections in the disassembler. <td>Switch between displaying/editing GFX and PGFX sections in either
binary or hexidecimal in the disassembler.
</td> </td>
</tr> </tr>
<tr> <tr>
<td><pre>-dis.showaddr &lt;1|0&gt;</pre></td> <td><pre>-dis.showaddr &lt;1|0&gt;</pre></td>
<td>Show/hide opcode addresses in the disassembler.</td> <td>Show/hide program counter addresses as labels in the disassembler.</td>
</tr> </tr>
<tr> <tr>

View File

@ -26,10 +26,9 @@ class Cheat
{ {
public: public:
Cheat(OSystem& osystem, const string& name, const string& code) Cheat(OSystem& osystem, const string& name, const string& code)
: myOSystem(osystem), : myOSystem{osystem},
myName(name == "" ? code : name), myName{name == "" ? code : name},
myCode(code) myCode{code} { }
{ }
virtual ~Cheat() = default; virtual ~Cheat() = default;
bool enabled() const { return myEnabled; } bool enabled() const { return myEnabled; }

View File

@ -32,7 +32,6 @@ namespace Common {
*/ */
struct Point struct Point
{ {
// FIXME : make this uInt32
Int32 x{0}; //!< The horizontal part of the point Int32 x{0}; //!< The horizontal part of the point
Int32 y{0}; //!< The vertical part of the point Int32 y{0}; //!< The vertical part of the point

View File

@ -170,10 +170,10 @@ namespace BSPF
return (val < lower) ? upper : (val > upper) ? lower : val; return (val < lower) ? upper : (val > upper) ? lower : val;
} }
// Test whether the vector contains the given value // Test whether a container contains the given value
template<typename T> template<typename Container>
bool contains(const std::vector<T>& v, const T& elem) { bool contains(const Container& c, typename Container::const_reference elem) {
return !(v.empty() || std::find(v.begin(), v.end(), elem) == v.end()); return std::find(c.cbegin(), c.cend(), elem) != c.end();
} }
// Convert string to given case // Convert string to given case

View File

@ -236,13 +236,13 @@ class CartDebug : public DebuggerSystem
/** /**
Save disassembly and ROM file Save disassembly and ROM file
*/ */
string saveDisassembly(string path); string saveDisassembly(string path = EmptyString);
string saveRom(string path); string saveRom(string path = EmptyString);
/** /**
Save access counters file Save access counters file
*/ */
string saveAccessFile(string path); string saveAccessFile(string path = EmptyString);
/** /**
Show Distella directives (both set by the user and determined by Distella) Show Distella directives (both set by the user and determined by Distella)

View File

@ -36,6 +36,7 @@
#include "RomWidget.hxx" #include "RomWidget.hxx"
#include "ProgressDialog.hxx" #include "ProgressDialog.hxx"
#include "BrowserDialog.hxx" #include "BrowserDialog.hxx"
#include "FrameBuffer.hxx"
#include "TimerManager.hxx" #include "TimerManager.hxx"
#include "Vec.hxx" #include "Vec.hxx"
@ -699,6 +700,21 @@ string DebuggerParser::saveScriptFile(string file)
return "saved " + node.getShortPath() + " OK"; return "saved " + node.getShortPath() + " OK";
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DebuggerParser::saveDump(const FilesystemNode& node, const stringstream& out,
ostringstream& result)
{
try
{
node.write(out);
result << " to file " << node.getShortPath();
}
catch(...)
{
result.str(red("Unable to append dump to file " + node.getShortPath()));
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DebuggerParser::executeDirective(Device::AccessType type) void DebuggerParser::executeDirective(Device::AccessType type)
{ {
@ -1126,7 +1142,7 @@ void DebuggerParser::executeDump()
}; };
// Error checking // Error checking
if( argCount == 0 || argCount > 3) if(argCount == 0 || argCount > 4)
{ {
outputCommandError("wrong number of arguments", myCommand); outputCommandError("wrong number of arguments", myCommand);
return; return;
@ -1143,32 +1159,33 @@ void DebuggerParser::executeDump()
dump(commandResult, args[0], args[1]); dump(commandResult, args[0], args[1]);
else else
{ {
ostringstream file; if((args[2] & 0x07) == 0)
file << debugger.myOSystem.userDir() << cartName() << "_dbg_";
if(execDepth > 0)
{ {
file << execPrefix; commandResult << red("dump flags must be 1..7");
}
else
{
file << std::hex << std::setw(8) << std::setfill('0')
<< uInt32(TimerManager::getTicks() / 1000);
}
file << ".dump";
FilesystemNode node(file.str());
// cout << "dump " << args[0] << "-" << args[1] << " to " << file.str() << endl;
std::ofstream ofs(node.getPath(), std::ofstream::out | std::ofstream::app);
if(!ofs.is_open())
{
outputCommandError("Unable to append dump to file " + node.getShortPath(), myCommand);
return; return;
} }
if((args[2] & 0x07) != 0) if(argCount == 4 && argStrings[3] != "?")
commandResult << "dumped "; {
commandResult << red("browser dialog parameter must be '?'");
return;
}
ostringstream path;
path << debugger.myOSystem.userDir() << cartName() << "_dbg_";
if(execDepth > 0)
path << execPrefix;
else
path << std::hex << std::setw(8) << std::setfill('0')
<< uInt32(TimerManager::getTicks() / 1000);
path << ".dump";
commandResult << "dumped ";
stringstream out;
if((args[2] & 0x01) != 0) if((args[2] & 0x01) != 0)
{ {
// dump memory // dump memory
dump(ofs, args[0], args[1]); dump(out, args[0], args[1]);
commandResult << "bytes from $" << hex << args[0] << " to $" << hex << args[1]; commandResult << "bytes from $" << hex << args[0] << " to $" << hex << args[1];
if((args[2] & 0x06) != 0) if((args[2] & 0x06) != 0)
commandResult << ", "; commandResult << ", ";
@ -1177,8 +1194,8 @@ void DebuggerParser::executeDump()
{ {
// dump CPU state // dump CPU state
CpuDebug& cpu = debugger.cpuDebug(); CpuDebug& cpu = debugger.cpuDebug();
ofs << " <PC>PC SP A X Y - - N V B D I Z C -\n"; out << " <PC>PC SP A X Y - - N V B D I Z C -\n";
ofs << "XC: " out << "XC: "
<< Base::toString(cpu.pc() & 0xff) << " " // PC lsb << Base::toString(cpu.pc() & 0xff) << " " // PC lsb
<< Base::toString(cpu.pc() >> 8) << " " // PC msb << Base::toString(cpu.pc() >> 8) << " " // PC msb
<< Base::toString(cpu.sp()) << " " // SP << Base::toString(cpu.sp()) << " " // SP
@ -1203,8 +1220,8 @@ void DebuggerParser::executeDump()
if((args[2] & 0x04) != 0) if((args[2] & 0x04) != 0)
{ {
// dump SWCHx/INPTx state // dump SWCHx/INPTx state
ofs << " SWA - SWB - IT - - - I0 I1 I2 I3 I4 I5 - -\n"; out << " SWA - SWB - IT - - - I0 I1 I2 I3 I4 I5 - -\n";
ofs << "XS: " out << "XS: "
<< Base::toString(debugger.peek(0x280)) << " " // SWCHA << Base::toString(debugger.peek(0x280)) << " " // SWCHA
<< Base::toString(0) << " " // unused << Base::toString(0) << " " // unused
<< Base::toString(debugger.peek(0x282)) << " " // SWCHB << Base::toString(debugger.peek(0x282)) << " " // SWCHB
@ -1224,8 +1241,37 @@ void DebuggerParser::executeDump()
<< endl; << endl;
commandResult << "switches and fire buttons"; commandResult << "switches and fire buttons";
} }
if((args[2] & 0x07) != 0)
commandResult << " to file " << node.getShortPath(); if(argCount == 4)
{
// FIXME: C++ doesn't currently allow capture of stringstreams
// So we pass a copy of its contents, then re-create the
// stream inside the lambda
// Maybe this will change in a future version
const string outStr = out.str();
const string resultStr = commandResult.str();
DebuggerDialog* dlg = debugger.myDialog;
BrowserDialog::show(dlg, "Save Dump as", path.str(),
BrowserDialog::Mode::FileSave,
[this, dlg, outStr, resultStr]
(bool OK, const FilesystemNode& node)
{
if(OK)
{
stringstream localOut(outStr);
ostringstream localResult(resultStr, std::ios_base::app);
saveDump(node, localOut, localResult);
dlg->prompt().print(localResult.str() + '\n');
}
dlg->prompt().printPrompt();
});
// avoid printing a new prompt
commandResult.str("_NO_PROMPT");
}
else
saveDump(FilesystemNode(path.str()), out, commandResult);
} }
} }
@ -1846,9 +1892,19 @@ void DebuggerParser::executeSave()
{ {
if(argCount && argStrings[0] == "?") if(argCount && argStrings[0] == "?")
{ {
debugger.myDialog->showBrowser(DebuggerDialog::svScript, cartName() + ".script"); DebuggerDialog* dlg = debugger.myDialog;
BrowserDialog::show(dlg, "Save Workbench as",
dlg->instance().userDir().getPath() + cartName() + ".script",
BrowserDialog::Mode::FileSave,
[this, dlg](bool OK, const FilesystemNode& node)
{
if(OK)
dlg->prompt().print(saveScriptFile(node.getPath()) + '\n');
dlg->prompt().printPrompt();
});
// avoid printing a new prompt // avoid printing a new prompt
commandResult << "_EXIT_DEBUGGER"; commandResult.str("_NO_PROMPT");
} }
else else
commandResult << saveScriptFile(argStrings[0]); commandResult << saveScriptFile(argStrings[0]);
@ -1860,12 +1916,22 @@ void DebuggerParser::executeSaveAccess()
{ {
if(argCount && argStrings[0] == "?") if(argCount && argStrings[0] == "?")
{ {
debugger.myDialog->showBrowser(DebuggerDialog::svAccess, cartName() + ".csv"); DebuggerDialog* dlg = debugger.myDialog;
BrowserDialog::show(dlg, "Save Access Counters as",
dlg->instance().userDir().getPath() + cartName() + ".csv",
BrowserDialog::Mode::FileSave,
[this, dlg](bool OK, const FilesystemNode& node)
{
if(OK)
dlg->prompt().print(debugger.cartDebug().saveAccessFile(node.getPath()) + '\n');
dlg->prompt().printPrompt();
});
// avoid printing a new prompt // avoid printing a new prompt
commandResult << "_EXIT_DEBUGGER"; commandResult.str("_NO_PROMPT");
} }
else else
commandResult << debugger.cartDebug().saveAccessFile(argCount ? argStrings[0] : EmptyString); commandResult << debugger.cartDebug().saveAccessFile();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1881,12 +1947,22 @@ void DebuggerParser::executeSavedisassembly()
{ {
if(argCount && argStrings[0] == "?") if(argCount && argStrings[0] == "?")
{ {
debugger.myDialog->showBrowser(DebuggerDialog::svDis, cartName() + ".asm"); DebuggerDialog* dlg = debugger.myDialog;
BrowserDialog::show(dlg, "Save Disassembly as",
dlg->instance().userDir().getPath() + cartName() + ".asm",
BrowserDialog::Mode::FileSave,
[this, dlg](bool OK, const FilesystemNode& node)
{
if(OK)
dlg->prompt().print(debugger.cartDebug().saveDisassembly(node.getPath()) + '\n');
dlg->prompt().printPrompt();
});
// avoid printing a new prompt // avoid printing a new prompt
commandResult << "_EXIT_DEBUGGER"; commandResult.str("_NO_PROMPT");
} }
else else
commandResult << debugger.cartDebug().saveDisassembly(argCount ? argStrings[0] : EmptyString); commandResult << debugger.cartDebug().saveDisassembly();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1895,12 +1971,22 @@ void DebuggerParser::executeSaverom()
{ {
if(argCount && argStrings[0] == "?") if(argCount && argStrings[0] == "?")
{ {
debugger.myDialog->showBrowser(DebuggerDialog::svRom, cartName() + ".a26"); DebuggerDialog* dlg = debugger.myDialog;
BrowserDialog::show(dlg, "Save ROM as",
dlg->instance().userDir().getPath() + cartName() + ".a26",
BrowserDialog::Mode::FileSave,
[this, dlg](bool OK, const FilesystemNode& node)
{
if(OK)
dlg->prompt().print(debugger.cartDebug().saveRom(node.getPath()) + '\n');
dlg->prompt().printPrompt();
});
// avoid printing a new prompt // avoid printing a new prompt
commandResult << "_EXIT_DEBUGGER"; commandResult.str("_NO_PROMPT");
} }
else else
commandResult << debugger.cartDebug().saveRom(argCount ? argStrings[0] : EmptyString); commandResult << debugger.cartDebug().saveRom();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1913,22 +1999,30 @@ void DebuggerParser::executeSaveses()
if(argCount && argStrings[0] == "?") if(argCount && argStrings[0] == "?")
{ {
debugger.myDialog->showBrowser(DebuggerDialog::svSession, filename.str()); DebuggerDialog* dlg = debugger.myDialog;
commandResult << "_EXIT_DEBUGGER";
BrowserDialog::show(dlg, "Save Session as",
dlg->instance().userDir().getPath() + filename.str(),
BrowserDialog::Mode::FileSave,
[this, dlg](bool OK, const FilesystemNode& node)
{
if(OK)
dlg->prompt().print(debugger.prompt().saveBuffer(node) + '\n');
dlg->prompt().printPrompt();
});
// avoid printing a new prompt
commandResult.str("_NO_PROMPT");
} }
else else
{ {
ostringstream path; ostringstream path;
if(argCount) if(argCount)
path << argStrings[0]; path << argStrings[0];
else else
path << debugger.myOSystem.userDir() << filename.str(); path << debugger.myOSystem.userDir() << filename.str();
FilesystemNode file(path.str());
if(debugger.prompt().saveBuffer(file)) commandResult << debugger.prompt().saveBuffer(FilesystemNode(path.str()));
commandResult << "saved " + file.getShortPath() + " OK";
else
commandResult << "unable to save session";
} }
} }
@ -2667,15 +2761,16 @@ std::array<DebuggerParser::Command, 100> DebuggerParser::commands = { {
{ {
"dump", "dump",
"Dump data at address <xx> [to yy] [1: memory; 2: CPU state; 4: input regs]", "Dump data at address <xx> [to yy] [1: memory; 2: CPU state; 4: input regs] [?]",
"Example:\n" "Example:\n"
" dump f000 - dumps 128 bytes from f000\n" " dump f000 - dumps 128 bytes from f000\n"
" dump f000 f0ff - dumps all bytes from f000 to f0ff\n" " dump f000 f0ff - dumps all bytes from f000 to f0ff\n"
" dump f000 f0ff 7 - dumps all bytes from f000 to f0ff,\n" " dump f000 f0ff 7 - dumps all bytes from f000 to f0ff,\n"
" CPU state and input registers into a file in user dir", " CPU state and input registers into a file in user dir,\n"
" dump f000 f0ff 7 ? - same, but with a browser dialog\n",
true, true,
false, false,
{ Parameters::ARG_WORD, Parameters::ARG_MULTI_BYTE }, { Parameters::ARG_WORD, Parameters::ARG_WORD, Parameters::ARG_BYTE, Parameters::ARG_LABEL },
std::mem_fn(&DebuggerParser::executeDump) std::mem_fn(&DebuggerParser::executeDump)
}, },
@ -3095,7 +3190,7 @@ std::array<DebuggerParser::Command, 100> DebuggerParser::commands = { {
{ {
"save", "save",
"Save breaks, watches, traps and functions to file xx", "Save breaks, watches, traps and functions to file <xx or ?>",
"Example: save commands.script, save ?\n" "Example: save commands.script, save ?\n"
"NOTE: saves to user dir by default", "NOTE: saves to user dir by default",
true, true,
@ -3106,12 +3201,12 @@ std::array<DebuggerParser::Command, 100> DebuggerParser::commands = { {
{ {
"saveaccess", "saveaccess",
"Save the access counters to CSV file", "Save the access counters to CSV file [?]",
"Example: saveaccess, saveaccess ?\n" "Example: saveaccess, saveaccess ?\n"
"NOTE: saves to user dir by default", "NOTE: saves to user dir by default",
false, false,
false, false,
{ Parameters::ARG_FILE, Parameters::ARG_END_ARGS }, { Parameters::ARG_LABEL, Parameters::ARG_END_ARGS },
std::mem_fn(&DebuggerParser::executeSaveAccess) std::mem_fn(&DebuggerParser::executeSaveAccess)
}, },
@ -3127,34 +3222,34 @@ std::array<DebuggerParser::Command, 100> DebuggerParser::commands = { {
{ {
"savedis", "savedis",
"Save Distella disassembly", "Save Distella disassembly to file [?]",
"Example: savedis, savedis ?\n" "Example: savedis, savedis ?\n"
"NOTE: saves to user dir by default", "NOTE: saves to user dir by default",
false, false,
false, false,
{ Parameters::ARG_FILE, Parameters::ARG_END_ARGS }, { Parameters::ARG_LABEL, Parameters::ARG_END_ARGS },
std::mem_fn(&DebuggerParser::executeSavedisassembly) std::mem_fn(&DebuggerParser::executeSavedisassembly)
}, },
{ {
"saverom", "saverom",
"Save (possibly patched) ROM", "Save (possibly patched) ROM to file [?]",
"Example: saverom, saverom ?\n" "Example: saverom, saverom ?\n"
"NOTE: saves to user dir by default", "NOTE: saves to user dir by default",
false, false,
false, false,
{ Parameters::ARG_FILE, Parameters::ARG_END_ARGS }, { Parameters::ARG_LABEL, Parameters::ARG_END_ARGS },
std::mem_fn(&DebuggerParser::executeSaverom) std::mem_fn(&DebuggerParser::executeSaverom)
}, },
{ {
"saveses", "saveses",
"Save console session", "Save console session to file [?]",
"Example: saveses, saveses ?\n" "Example: saveses, saveses ?\n"
"NOTE: saves to user dir by default", "NOTE: saves to user dir by default",
false, false,
false, false,
{ Parameters::ARG_FILE, Parameters::ARG_END_ARGS }, { Parameters::ARG_LABEL, Parameters::ARG_END_ARGS },
std::mem_fn(&DebuggerParser::executeSaveses) std::mem_fn(&DebuggerParser::executeSaveses)
}, },

View File

@ -65,6 +65,8 @@ class DebuggerParser
bool validateArgs(int cmd); bool validateArgs(int cmd);
string eval(); string eval();
string saveScriptFile(string file); string saveScriptFile(string file);
void saveDump(const FilesystemNode& node, const stringstream& out,
ostringstream& result);
const string& cartName() const; const string& cartName() const;
private: private:

View File

@ -400,66 +400,6 @@ void DebuggerDialog::createFont()
tooltip().setFont(*myNFont); tooltip().setFont(*myNFont);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DebuggerDialog::showBrowser(BrowserType type, const string& defaultName)
{
string title, command;
switch(type)
{
case BrowserType::svAccess:
title = "Access Counters";
command = "saveaccess";
break;
case BrowserType::svDis:
title = "Disassembly";
command = "savedis";
break;
case BrowserType::svRom:
title = "ROM";
command = "saverom";
break;
case BrowserType::svScript:
title = "Workbench";
command = "save";
break;
case BrowserType::svSession:
title = "Session";
command = "saveses";
break;
default:
break;
}
if(command != EmptyString)
{
BrowserDialog::show(this, instance().frameBuffer().font(), "Save " + title + " as",
instance().userDir().getPath() + defaultName,
BrowserDialog::Mode::FileSave,
[this, command](bool OK, const FilesystemNode& node) {
if(OK) runCommand(node, command);
else runCommand(node);
});
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DebuggerDialog::runCommand(const FilesystemNode& node, const string& command)
{
if(command != EmptyString)
{
string result = instance().debugger().parser().run(command + " {" +
node.getPath() + "}");
prompt().print(result + '\n');
}
prompt().printPrompt();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void DebuggerDialog::showFatalMessage(const string& msg) void DebuggerDialog::showFatalMessage(const string& msg)
{ {

View File

@ -55,13 +55,6 @@ class DebuggerDialog : public Dialog
kMediumFontMinW = 1160, kMediumFontMinH = 770, kMediumFontMinW = 1160, kMediumFontMinH = 770,
kLargeFontMinW = 1160, kLargeFontMinH = 870 kLargeFontMinW = 1160, kLargeFontMinH = 870
}; };
enum BrowserType {
svAccess, // saveaccess
svDis, // savedis
svRom, // saverom
svScript, // save
svSession // saveses
};
DebuggerDialog(OSystem& osystem, DialogContainer& parent, DebuggerDialog(OSystem& osystem, DialogContainer& parent,
int x, int y, int w, int h); int x, int y, int w, int h);
@ -82,7 +75,6 @@ class DebuggerDialog : public Dialog
void showFatalMessage(const string& msg); void showFatalMessage(const string& msg);
void saveConfig() override; void saveConfig() override;
void showBrowser(BrowserType type, const string& defaultName);
private: private:
void setPosition() override { positionAt(0); } void setPosition() override { positionAt(0); }
@ -127,9 +119,6 @@ class DebuggerDialog : public Dialog
kDDOptionsCmd = 'DDop' kDDOptionsCmd = 'DDop'
}; };
void runCommand(const FilesystemNode& node,
const string& command = EmptyString);
TabWidget *myTab{nullptr}, *myRomTab{nullptr}; TabWidget *myTab{nullptr}, *myRomTab{nullptr};
PromptWidget* myPrompt{nullptr}; PromptWidget* myPrompt{nullptr};

View File

@ -191,6 +191,8 @@ bool PromptWidget::handleKeyDown(StellaKey key, StellaMod mod)
_exitedEarly = true; _exitedEarly = true;
return true; return true;
} }
else if(result == "_NO_PROMPT")
return true;
else if(result != "") else if(result != "")
print(result + "\n"); print(result + "\n");
} }
@ -968,7 +970,7 @@ void PromptWidget::scrollToCurrent()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool PromptWidget::saveBuffer(const FilesystemNode& file) string PromptWidget::saveBuffer(const FilesystemNode& file)
{ {
stringstream out; stringstream out;
for(int start = 0; start < _promptStartPos; start += _lineWidth) for(int start = 0; start < _promptStartPos; start += _lineWidth)
@ -988,8 +990,13 @@ bool PromptWidget::saveBuffer(const FilesystemNode& file)
out << endl; out << endl;
} }
try { return file.write(out) > 0; } try {
catch(...) { return false; } if(file.write(out) > 0)
return "saved " + file.getShortPath() + " OK";
}
catch(...) { }
return "unable to save session";
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -46,7 +46,7 @@ class PromptWidget : public Widget, public CommandSender
ATTRIBUTE_FMT_PRINTF int vprintf(const char* format, va_list argptr); ATTRIBUTE_FMT_PRINTF int vprintf(const char* format, va_list argptr);
void print(const string& str); void print(const string& str);
void printPrompt(); void printPrompt();
bool saveBuffer(const FilesystemNode& file); string saveBuffer(const FilesystemNode& file);
// Clear screen and erase all history // Clear screen and erase all history
void clearScreen(); void clearScreen();

View File

@ -58,19 +58,24 @@ RomListSettings::RomListSettings(GuiObject* boss, const GUI::Font& font)
// Settings for Distella // Settings for Distella
xpos += 4; ypos += buttonHeight + 8; xpos += 4; ypos += buttonHeight + 8;
myShowTentative = new CheckboxWidget(this, font, xpos, ypos, myShowTentative = new CheckboxWidget(this, font, xpos, ypos,
"Show tentative code", RomListWidget::kTentativeCodeCmd); "Show tentative code", RomListWidget::kTentativeCodeCmd);
myShowTentative->setToolTip("Check to differentiate between tentative code\n"
"vs. data sections via static code analysis.");
wid.push_back(myShowTentative); wid.push_back(myShowTentative);
ypos += buttonHeight + 4; ypos += buttonHeight + 4;
myShowAddresses = new CheckboxWidget(this, font, xpos, ypos, myShowAddresses = new CheckboxWidget(this, font, xpos, ypos,
"Show PC addresses", RomListWidget::kPCAddressesCmd); "Show PC addresses", RomListWidget::kPCAddressesCmd);
myShowAddresses->setToolTip("Check to show program counter addresses as labels.");
wid.push_back(myShowAddresses); wid.push_back(myShowAddresses);
ypos += buttonHeight + 4; ypos += buttonHeight + 4;
myShowGFXBinary = new CheckboxWidget(this, font, xpos, ypos, myShowGFXBinary = new CheckboxWidget(this, font, xpos, ypos,
"Show GFX as binary", RomListWidget::kGfxAsBinaryCmd); "Show GFX as binary", RomListWidget::kGfxAsBinaryCmd);
myShowGFXBinary->setToolTip("Check to allow editing GFX sections in binary format.");
wid.push_back(myShowGFXBinary); wid.push_back(myShowGFXBinary);
ypos += buttonHeight + 4; ypos += buttonHeight + 4;
myUseRelocation = new CheckboxWidget(this, font, xpos, ypos, myUseRelocation = new CheckboxWidget(this, font, xpos, ypos,
"Use address relocation", RomListWidget::kAddrRelocationCmd); "Use address relocation", RomListWidget::kAddrRelocationCmd);
myUseRelocation->setToolTip("Check to relocate calls out of address range.");
wid.push_back(myUseRelocation); wid.push_back(myUseRelocation);
// Set real dimensions // Set real dimensions

View File

@ -20,6 +20,7 @@
#include "FSNode.hxx" #include "FSNode.hxx"
#include "GuiObject.hxx" #include "GuiObject.hxx"
#include "OSystem.hxx" #include "OSystem.hxx"
#include "FrameBuffer.hxx"
#include "EditTextWidget.hxx" #include "EditTextWidget.hxx"
#include "FileListWidget.hxx" #include "FileListWidget.hxx"
#include "Widget.hxx" #include "Widget.hxx"
@ -131,6 +132,17 @@ void BrowserDialog::show(GuiObject* parent, const GUI::Font& font,
ourBrowser->show(startpath, mode, command, namefilter); ourBrowser->show(startpath, mode, command, namefilter);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void BrowserDialog::show(GuiObject* parent,
const string& title, const string& startpath,
BrowserDialog::Mode mode,
const Command& command,
const FilesystemNode::NameFilter& namefilter)
{
show(parent, parent->instance().frameBuffer().font(), title, startpath,
mode, command, namefilter);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void BrowserDialog::show(const string& startpath, void BrowserDialog::show(const string& startpath,
BrowserDialog::Mode mode, BrowserDialog::Mode mode,
@ -247,7 +259,6 @@ void BrowserDialog::handleCommand(CommandSender* sender, int cmd,
// Send a signal to the calling class that a selection has been made // Send a signal to the calling class that a selection has been made
if(_mode != Mode::Directories) if(_mode != Mode::Directories)
{ {
// TODO: check if affected by '-baseDir'and 'basedirinapp' params
bool savePath = _savePathBox->getState(); bool savePath = _savePathBox->getState();
instance().settings().setValue("saveuserdir", savePath); instance().settings().setValue("saveuserdir", savePath);

View File

@ -69,6 +69,23 @@ class BrowserDialog : public Dialog
const FilesystemNode::NameFilter& namefilter = { const FilesystemNode::NameFilter& namefilter = {
[](const FilesystemNode&) { return true; }}); [](const FilesystemNode&) { return true; }});
/**
Place the browser window onscreen, using the given attributes.
@param parent The parent object of the browser (cannot be nullptr)
@param title The title of the browser window
@param startpath The initial path to select in the browser
@param mode The functionality to use (load/save/display)
@param command The command to run when 'OK' or 'Cancel' is clicked
@param namefilter Filter files/directories in browser display
*/
static void show(GuiObject* parent,
const string& title, const string& startpath,
BrowserDialog::Mode mode,
const Command& command,
const FilesystemNode::NameFilter& namefilter = {
[](const FilesystemNode&) { return true; } });
private: private:
/** Place the browser window onscreen, using the given attributes */ /** Place the browser window onscreen, using the given attributes */
void show(const string& startpath, void show(const string& startpath,

View File

@ -316,8 +316,7 @@ bool Widget::isWidgetInChain(Widget* w, Widget* find)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Widget::isWidgetInChain(const WidgetArray& list, Widget* find) bool Widget::isWidgetInChain(const WidgetArray& list, Widget* find)
{ {
return std::any_of(list.cbegin(), list.cend(), return BSPF::contains(list, find);
[&](Widget* w) { return w == find; });
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -