mirror of https://github.com/stella-emu/stella.git
Improved the new Snapshot Settings dialog with more informative text.
Added option to save snapshots using either internal database name (the default) or actual ROM filename. Extended FSNode API for parsing filenames and adding/removing extensions, which was previously being done in different ways throughout the codebase. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2753 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
41cb93c437
commit
f3d412fce7
|
@ -51,6 +51,12 @@
|
|||
created with newer versions of the ZIP program. Related to this, added
|
||||
better error messages for invalid/missing/unreadable ROM files.
|
||||
|
||||
* Added 'snapname' commandline argument and associated UI item, for
|
||||
specifying whether snapshots should be saved using either the internal
|
||||
ROM database name or the actual ROM filename. This feature was
|
||||
present in older releases of Stella, and due to popular demand it's
|
||||
now back again.
|
||||
|
||||
* Fixed bug in Linux/OSX versions when starting Stella for the first
|
||||
time; it was previously creating mislabeled directories to store
|
||||
settings, snapshots, etc.
|
||||
|
|
|
@ -721,8 +721,7 @@ string CartDebug::loadSymbolFile()
|
|||
const string& propsname =
|
||||
myConsole.properties().get(Cartridge_Name) + ".sym";
|
||||
|
||||
FilesystemNode case1(FilesystemNode(myOSystem.romFile()).getParent().getPath() +
|
||||
propsname);
|
||||
FilesystemNode case1(myOSystem.romFile().getParent().getPath() + propsname);
|
||||
if(case1.isFile() && case1.isReadable())
|
||||
mySymbolFile = case1.getPath();
|
||||
else
|
||||
|
@ -772,8 +771,7 @@ string CartDebug::loadConfigFile()
|
|||
const string& propsname =
|
||||
myConsole.properties().get(Cartridge_Name) + ".cfg";
|
||||
|
||||
FilesystemNode case1(FilesystemNode(myOSystem.romFile()).getParent().getPath() +
|
||||
propsname);
|
||||
FilesystemNode case1(myOSystem.romFile().getParent().getPath() + propsname);
|
||||
FilesystemNode case2(myOSystem.cfgDir() + propsname);
|
||||
|
||||
if(case1.isFile() && case1.isReadable())
|
||||
|
@ -928,8 +926,7 @@ string CartDebug::saveDisassembly()
|
|||
const string& propsname =
|
||||
myConsole.properties().get(Cartridge_Name) + ".asm";
|
||||
|
||||
FilesystemNode case0(
|
||||
FilesystemNode(myOSystem.romFile()).getParent().getPath() + propsname);
|
||||
FilesystemNode case0(myOSystem.romFile().getParent().getPath() + propsname);
|
||||
if(case0.getParent().isWritable())
|
||||
myDisasmFile = case0.getPath();
|
||||
else
|
||||
|
@ -1037,7 +1034,7 @@ string CartDebug::saveDisassembly()
|
|||
// Some boilerplate, similar to what DiStella adds
|
||||
time_t currtime;
|
||||
time(&currtime);
|
||||
out << "; Disassembly of " << FilesystemNode(myOSystem.romFile()).getShortPath() << "\n"
|
||||
out << "; Disassembly of " << myOSystem.romFile().getShortPath() << "\n"
|
||||
<< "; Disassembled " << ctime(&currtime)
|
||||
<< "; Using Stella " << STELLA_VERSION << "\n;\n"
|
||||
<< "; ROM properties name : " << myConsole.properties().get(Cartridge_Name) << "\n"
|
||||
|
|
|
@ -244,14 +244,7 @@ string Debugger::autoExec()
|
|||
<< myParser->exec(autoexec) << endl;
|
||||
|
||||
// Also, "romname.stella" if present
|
||||
string file = myOSystem->romFile();
|
||||
string::size_type pos;
|
||||
if( (pos = file.find_last_of('.')) != string::npos )
|
||||
file.replace(pos, file.size(), ".stella");
|
||||
else
|
||||
file += ".stella";
|
||||
|
||||
FilesystemNode romname(file);
|
||||
FilesystemNode romname(myOSystem->romFile().getPathWithExt(".stella"));
|
||||
buf << myParser->exec(romname) << endl;
|
||||
|
||||
// Init builtins
|
||||
|
|
|
@ -1949,7 +1949,9 @@ void EventHandler::takeSnapshot(uInt32 number)
|
|||
string filename;
|
||||
bool showmessage = number == 0;
|
||||
string sspath = myOSystem->snapshotSaveDir() +
|
||||
myOSystem->console().properties().get(Cartridge_Name);
|
||||
(myOSystem->settings().getString("snapname") != "int" ?
|
||||
myOSystem->romFile().getNameWithExt("")
|
||||
: myOSystem->console().properties().get(Cartridge_Name));
|
||||
|
||||
// Check whether we want multiple snapshots created
|
||||
if(number > 0)
|
||||
|
|
|
@ -79,10 +79,50 @@ bool FilesystemNode::getChildren(FSList& fslist, ListMode mode, bool hidden) con
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const string& FilesystemNode::getName() const
|
||||
{
|
||||
assert(_realNode);
|
||||
return _realNode->getName();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const string& FilesystemNode::getPath() const
|
||||
{
|
||||
return _realNode->getPath();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string FilesystemNode::getShortPath() const
|
||||
{
|
||||
return _realNode->getShortPath();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string FilesystemNode::getNameWithExt(const string& ext) const
|
||||
{
|
||||
size_t pos = _realNode->getName().find_last_of("/\\");
|
||||
string s = pos == string::npos ? _realNode->getName() :
|
||||
_realNode->getName().substr(pos+1);
|
||||
|
||||
pos = s.find_last_of(".");
|
||||
return (pos != string::npos) ? s.replace(pos, string::npos, ext) : s + ext;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string FilesystemNode::getPathWithExt(const string& ext) const
|
||||
{
|
||||
string s = _realNode->getPath();
|
||||
|
||||
size_t pos = s.find_last_of(".");
|
||||
return (pos != string::npos) ? s.replace(pos, string::npos, ext) : s + ext;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string FilesystemNode::getShortPathWithExt(const string& ext) const
|
||||
{
|
||||
string s = _realNode->getShortPath();
|
||||
|
||||
size_t pos = s.find_last_of(".");
|
||||
return (pos != string::npos) ? s.replace(pos, string::npos, ext) : s + ext;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FilesystemNode::hasParent() const
|
||||
{
|
||||
|
@ -99,18 +139,6 @@ FilesystemNode FilesystemNode::getParent() const
|
|||
return (node == 0) ? *this : FilesystemNode(node);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const string& FilesystemNode::getPath() const
|
||||
{
|
||||
return _realNode->getPath();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
string FilesystemNode::getShortPath() const
|
||||
{
|
||||
return _realNode->getShortPath();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FilesystemNode::isDirectory() const
|
||||
{
|
||||
|
|
|
@ -239,6 +239,16 @@ class FilesystemNode
|
|||
*/
|
||||
virtual uInt32 read(uInt8*& buffer) const;
|
||||
|
||||
/**
|
||||
* The following methods are almost exactly the same as the various
|
||||
* getXXXX() methods above. Internally, they call the respective methods
|
||||
* and replace the extension (if present) with the given one. If no
|
||||
* extension is present, the given one is appended instead.
|
||||
*/
|
||||
string getNameWithExt(const string& ext) const;
|
||||
string getPathWithExt(const string& ext) const;
|
||||
string getShortPathWithExt(const string& ext) const;
|
||||
|
||||
private:
|
||||
Common::SharedPtr<AbstractFSNode> _realNode;
|
||||
FilesystemNode(AbstractFSNode* realNode);
|
||||
|
|
|
@ -365,9 +365,9 @@ class OSystem
|
|||
This method should be called to get the full path of the currently
|
||||
loaded ROM.
|
||||
|
||||
@return String representing the full path of the ROM file.
|
||||
@return FSNode object representing the ROM file.
|
||||
*/
|
||||
const string& romFile() const { return myRomFile.getPath(); }
|
||||
const FilesystemNode& romFile() const { return myRomFile; }
|
||||
|
||||
/**
|
||||
Creates a new game console from the specified romfile, and correctly
|
||||
|
|
|
@ -154,20 +154,8 @@ void PropertiesSet::getMD5WithInsert(const FilesystemNode& rom,
|
|||
if(!getMD5(md5, properties))
|
||||
{
|
||||
properties.set(Cartridge_MD5, md5);
|
||||
|
||||
// Create a name suitable for using in properties
|
||||
size_t pos = rom.getName().find_last_of("/\\");
|
||||
const string& filename = pos == string::npos ? rom.getName() :
|
||||
rom.getName().substr(pos+1);
|
||||
if(BSPF_endsWithIgnoreCase(filename, ".a26") ||
|
||||
BSPF_endsWithIgnoreCase(filename, ".bin") ||
|
||||
BSPF_endsWithIgnoreCase(filename, ".rom"))
|
||||
{
|
||||
const string& name = filename.substr(0, filename.size() - 4);
|
||||
properties.set(Cartridge_Name, name);
|
||||
}
|
||||
else
|
||||
properties.set(Cartridge_Name, filename);
|
||||
properties.set(Cartridge_Name, rom.getNameWithExt(""));
|
||||
|
||||
insert(properties, false);
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ Settings::Settings(OSystem* osystem)
|
|||
// Snapshot options
|
||||
setInternal("snapsavedir", "");
|
||||
setInternal("snaploaddir", "");
|
||||
setInternal("snapname", "int");
|
||||
setInternal("sssingle", "false");
|
||||
setInternal("ss1x", "false");
|
||||
setInternal("ssinterval", "2");
|
||||
|
@ -401,6 +402,7 @@ void Settings::usage()
|
|||
<< " -fastscbios <1|0> Disable Supercharger BIOS progress loading bars\n"
|
||||
<< " -snapsavedir <path> The directory to save snapshot files to\n"
|
||||
<< " -snaploaddir <path> The directory to load snapshot files from\n"
|
||||
<< " -snapname <int|rom> Name snapshots according to internal database or ROM\n"
|
||||
<< " -sssingle <1|0> Generate single snapshot instead of many\n"
|
||||
<< " -ss1x <1|0> Generate TIA snapshot in 1x mode (ignore scaling/effects)\n"
|
||||
<< " -ssinterval <number Number of seconds between snapshots in continuous snapshot mode\n"
|
||||
|
|
|
@ -38,22 +38,22 @@ SnapshotDialog::SnapshotDialog(
|
|||
{
|
||||
const int lineHeight = font.getLineHeight(),
|
||||
fontWidth = font.getMaxCharWidth(),
|
||||
buttonWidth = font.getStringWidth("Snapshot load path:") + 20,
|
||||
buttonWidth = font.getStringWidth("Save path:") + 20,
|
||||
buttonHeight = font.getLineHeight() + 4;
|
||||
const int vBorder = 8;
|
||||
int xpos, ypos;
|
||||
const int vBorder = 10;
|
||||
int xpos, ypos, lwidth, fwidth;
|
||||
WidgetArray wid;
|
||||
ButtonWidget* b;
|
||||
|
||||
// Set real dimensions
|
||||
_w = 56 * fontWidth + 8;
|
||||
_h = 13 * (lineHeight + 4) + 10;
|
||||
_w = 53 * fontWidth + 8;
|
||||
_h = 10 * (lineHeight + 4) + 10;
|
||||
|
||||
xpos = vBorder; ypos = vBorder;
|
||||
|
||||
// Snapshot path (save files)
|
||||
b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
|
||||
"Snapshot save path:", kChooseSnapSaveDirCmd);
|
||||
"Save path:", kChooseSnapSaveDirCmd);
|
||||
wid.push_back(b);
|
||||
xpos += buttonWidth + 10;
|
||||
mySnapSavePath = new EditTextWidget(this, font, xpos, ypos + 2,
|
||||
|
@ -63,27 +63,26 @@ SnapshotDialog::SnapshotDialog(
|
|||
// Snapshot path (load files)
|
||||
xpos = vBorder; ypos += buttonHeight + 3;
|
||||
b = new ButtonWidget(this, font, xpos, ypos, buttonWidth, buttonHeight,
|
||||
"Snapshot load path:", kChooseSnapLoadDirCmd);
|
||||
"Load path:", kChooseSnapLoadDirCmd);
|
||||
wid.push_back(b);
|
||||
xpos += buttonWidth + 10;
|
||||
mySnapLoadPath = new EditTextWidget(this, font, xpos, ypos + 2,
|
||||
_w - xpos - 10, lineHeight, "");
|
||||
wid.push_back(mySnapLoadPath);
|
||||
|
||||
// Snapshot single or multiple saves
|
||||
xpos = 30; ypos += b->getHeight() + 5;
|
||||
mySnapSingle = new CheckboxWidget(this, font, xpos, ypos,
|
||||
"Overwrite snapshots");
|
||||
wid.push_back(mySnapSingle);
|
||||
|
||||
// Snapshot in 1x mode (ignore scaling)
|
||||
xpos += mySnapSingle->getWidth() + 20;
|
||||
mySnap1x = new CheckboxWidget(this, font, xpos, ypos,
|
||||
"Snapshot in 1x mode");
|
||||
wid.push_back(mySnap1x);
|
||||
// Snapshot naming
|
||||
lwidth = font.getStringWidth("Continuous snapshot interval: ");
|
||||
fwidth = font.getStringWidth("internal database");
|
||||
VariantList items;
|
||||
items.push_back("actual ROM name", "rom");
|
||||
items.push_back("internal database", "int");
|
||||
xpos = vBorder+10; ypos += buttonHeight + 8;
|
||||
mySnapName =
|
||||
new PopUpWidget(this, font, xpos, ypos, fwidth, lineHeight, items,
|
||||
"Save snapshots according to: ", lwidth);
|
||||
wid.push_back(mySnapName);
|
||||
|
||||
// Snapshot interval (continuous mode)
|
||||
VariantList items;
|
||||
items.clear();
|
||||
items.push_back("1 second", "1");
|
||||
items.push_back("2 seconds", "2");
|
||||
|
@ -95,12 +94,30 @@ SnapshotDialog::SnapshotDialog(
|
|||
items.push_back("8 seconds", "8");
|
||||
items.push_back("9 seconds", "9");
|
||||
items.push_back("10 seconds", "10");
|
||||
xpos = 30; ypos += b->getHeight();
|
||||
mySnapInterval = new PopUpWidget(this, font, xpos, ypos,
|
||||
font.getStringWidth("10 seconds"), lineHeight,
|
||||
items, "Continuous snapshot interval: ");
|
||||
ypos += buttonHeight;
|
||||
mySnapInterval =
|
||||
new PopUpWidget(this, font, xpos, ypos, fwidth, lineHeight, items,
|
||||
"Continuous snapshot interval: ", lwidth);
|
||||
wid.push_back(mySnapInterval);
|
||||
|
||||
// Booleans for saving snapshots
|
||||
fwidth = font.getStringWidth("When saving snapshots:");
|
||||
xpos = vBorder; ypos += buttonHeight + 5;
|
||||
new StaticTextWidget(this, font, xpos, ypos, fwidth, lineHeight,
|
||||
"When saving snapshots:", kTextAlignLeft);
|
||||
|
||||
// Snapshot single or multiple saves
|
||||
xpos += 30; ypos += lineHeight + 3;
|
||||
mySnapSingle = new CheckboxWidget(this, font, xpos, ypos,
|
||||
"Overwrite existing files");
|
||||
wid.push_back(mySnapSingle);
|
||||
|
||||
// Snapshot in 1x mode (ignore scaling)
|
||||
ypos += mySnapSingle->getHeight() + 4;
|
||||
mySnap1x = new CheckboxWidget(this, font, xpos, ypos,
|
||||
"Disable image filtering (1x mode)");
|
||||
wid.push_back(mySnap1x);
|
||||
|
||||
// Add Defaults, OK and Cancel buttons
|
||||
b = new ButtonWidget(this, font, 10, _h - buttonHeight - 10,
|
||||
font.getStringWidth("Defaults") + 20, buttonHeight,
|
||||
|
@ -126,9 +143,10 @@ void SnapshotDialog::loadConfig()
|
|||
const Settings& settings = instance().settings();
|
||||
mySnapSavePath->setText(settings.getString("snapsavedir"));
|
||||
mySnapLoadPath->setText(settings.getString("snaploaddir"));
|
||||
mySnapName->setSelected(instance().settings().getString("snapname"), "int");
|
||||
mySnapInterval->setSelected(instance().settings().getString("ssinterval"), "2");
|
||||
mySnapSingle->setState(settings.getBool("sssingle"));
|
||||
mySnap1x->setState(settings.getBool("ss1x"));
|
||||
mySnapInterval->setSelected(instance().settings().getString("ssinterval"), "2");
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -136,6 +154,8 @@ void SnapshotDialog::saveConfig()
|
|||
{
|
||||
instance().settings().setValue("snapsavedir", mySnapSavePath->getText());
|
||||
instance().settings().setValue("snaploaddir", mySnapLoadPath->getText());
|
||||
instance().settings().setValue("snapname",
|
||||
mySnapName->getSelectedTag().toString());
|
||||
instance().settings().setValue("sssingle", mySnapSingle->getState());
|
||||
instance().settings().setValue("ss1x", mySnap1x->getState());
|
||||
instance().settings().setValue("ssinterval",
|
||||
|
|
|
@ -62,10 +62,11 @@ class SnapshotDialog : public Dialog
|
|||
EditTextWidget* mySnapSavePath;
|
||||
EditTextWidget* mySnapLoadPath;
|
||||
|
||||
// Other snapshot settings
|
||||
PopUpWidget* mySnapName;
|
||||
PopUpWidget* mySnapInterval;
|
||||
|
||||
CheckboxWidget* mySnapSingle;
|
||||
CheckboxWidget* mySnap1x;
|
||||
PopUpWidget* mySnapInterval;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue