Cleaned up handling of various file paths throughtout the codebase.

Basically, directories are now guaranteed to always end in the path
separator.  Ensuring this makes certain sections of code work faster,
and guaranteeing it allows higher layers of code to not worry about it.

Added 'cfgdir' commandline argument, to specify the default directory
for Distella-like Stella-compatible config files.

Implemented 'loadconfig' debugger prompt command.  It's currently
working great with several test config files provided by Omega of
AtariAge.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2125 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2010-09-06 00:17:51 +00:00
parent 871d851e4d
commit 2d08d4e459
17 changed files with 198 additions and 74 deletions

View File

@ -1648,7 +1648,7 @@ GLuint FBSurfaceGL::genShader(ShaderType type)
// These shader files are stored in 'BASEDIR/shaders/' // These shader files are stored in 'BASEDIR/shaders/'
char* buffer = NULL; char* buffer = NULL;
const string& filename = const string& filename =
myFB.myOSystem->baseDir() + BSPF_PATH_SEPARATOR + "shaders" + myFB.myOSystem->baseDir() + "shaders" +
BSPF_PATH_SEPARATOR + fFile; BSPF_PATH_SEPARATOR + fFile;
ifstream in(filename.c_str()); ifstream in(filename.c_str());
if(in && in.is_open()) if(in && in.is_open())

View File

@ -26,9 +26,9 @@
#include "CartDebug.hxx" #include "CartDebug.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CartDebug::CartDebug(Debugger& dbg, Console& console, const RamAreaList& areas, CartDebug::CartDebug(Debugger& dbg, Console& console, const OSystem& osystem)
const Settings& settings)
: DebuggerSystem(dbg, console), : DebuggerSystem(dbg, console),
myOSystem(osystem),
myRWPortAddress(0), myRWPortAddress(0),
myLabelLength(5) // longest pre-defined label myLabelLength(5) // longest pre-defined label
{ {
@ -36,6 +36,7 @@ CartDebug::CartDebug(Debugger& dbg, Console& console, const RamAreaList& areas,
addRamArea(0x80, 128, 0, 0); addRamArea(0x80, 128, 0, 0);
// Add extended RAM // Add extended RAM
const RamAreaList& areas = console.cartridge().ramAreas();
for(RamAreaList::const_iterator i = areas.begin(); i != areas.end(); ++i) for(RamAreaList::const_iterator i = areas.begin(); i != areas.end(); ++i)
addRamArea(i->start, i->size, i->roffset, i->woffset); addRamArea(i->start, i->size, i->roffset, i->woffset);
@ -65,7 +66,7 @@ CartDebug::CartDebug(Debugger& dbg, Console& console, const RamAreaList& areas,
// Add settings for Distella // Add settings for Distella
DiStella::settings.gfx_format = DiStella::settings.gfx_format =
settings.getInt("gfxformat") == 16 ? kBASE_16 : kBASE_2; myOSystem.settings().getInt("gfxformat") == 16 ? kBASE_16 : kBASE_2;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -346,7 +347,8 @@ string CartDebug::disassemble(uInt16 start, uInt16 lines) const
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartDebug::addDirective(CartDebug::DisasmType type, uInt16 start, uInt16 end) bool CartDebug::addDirective(CartDebug::DisasmType type,
uInt16 start, uInt16 end, int bank)
{ {
#define PRINT_TAG(d) \ #define PRINT_TAG(d) \
cerr << (d.type == CartDebug::CODE ? "CODE" : \ cerr << (d.type == CartDebug::CODE ? "CODE" : \
@ -360,10 +362,13 @@ bool CartDebug::addDirective(CartDebug::DisasmType type, uInt16 start, uInt16 en
PRINT_TAG((*d)); \ PRINT_TAG((*d)); \
cerr << endl; cerr << endl;
BankInfo& info = (myDebugger.cpuDebug().pc() & 0x1000) ? if(bank < 0) // Do we want the current bank or ZP RAM?
myBankInfo[getBank()] : myBankInfo[myBankInfo.size()-1]; bank = (myDebugger.cpuDebug().pc() & 0x1000) ? getBank() : myBankInfo.size()-1;
bank = BSPF_min(bank, bankCount() - 1);
BankInfo& info = myBankInfo[bank];
DirectiveList& list = info.directiveList; DirectiveList& list = info.directiveList;
DirectiveTag tag; DirectiveTag tag;
tag.type = type; tag.type = type;
tag.start = start; tag.start = start;
@ -642,13 +647,118 @@ string CartDebug::loadSymbolFile(const string& f)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string CartDebug::loadConfigFile(const string& f) string CartDebug::loadConfigFile(string file)
{ {
return "NOT YET IMPLEMENTED"; FilesystemNode node(file);
if(file == "") // Use config file based on ROM name
{
file = myOSystem.romFile();
string::size_type spos;
if((spos = file.find_last_of('.')) != string::npos )
file.replace(spos, file.size(), ".cfg");
else
file += ".cfg";
FilesystemNode usercfg(file);
if(usercfg.exists())
{
node = usercfg;
}
else // Use global config file based on properties cart name
{
const string& globalfile = myOSystem.cfgDir() +
myConsole.properties().get(Cartridge_Name) + ".cfg";
FilesystemNode globalcfg(globalfile);
if(globalcfg.exists())
node = globalcfg;
}
}
if(node.exists() && !node.isDirectory())
{
ifstream in(node.getPath().c_str());
if(!in.is_open())
return "Unable to read directives from " + node.getPath();
int currentbank = 0;
while(!in.eof())
{
// Skip leading space
int c = in.peek();
while(c == ' ' && c == '\t')
{
in.get();
c = in.peek();
}
string line;
c = in.peek();
if(c == '/') // Comment, swallow line and continue
{
getline(in, line);
continue;
}
else if(c == '[')
{
in.get();
getline(in, line, ']');
stringstream buf(line);
buf >> currentbank;
}
else // Should be commands from this point on
{
getline(in, line);
stringstream buf;
buf << line;
string directive;
uInt16 start = 0, end = 0;
buf >> directive;
if(BSPF_startsWithIgnoreCase(directive, "ORG"))
{
buf >> hex >> start;
// TODO - figure out what to do with this
cerr << "ignoring directive: "
<< directive << " " << HEX4 << start << endl;
}
else if(BSPF_startsWithIgnoreCase(directive, "BLOCK"))
{
buf >> hex >> start;
buf >> hex >> end;
// TODO - add directive for this
cerr << "ignoring directive: " << directive << " "
<< HEX4 << start << " " << HEX4 << end << endl;
}
else if(BSPF_startsWithIgnoreCase(directive, "CODE"))
{
buf >> hex >> start;
buf >> hex >> end;
addDirective(CartDebug::CODE, start, end, currentbank);
}
else if(BSPF_startsWithIgnoreCase(directive, "DATA"))
{
buf >> hex >> start;
buf >> hex >> end;
addDirective(CartDebug::DATA, start, end, currentbank);
}
else if(BSPF_startsWithIgnoreCase(directive, "GFX"))
{
buf >> hex >> start;
buf >> hex >> end;
addDirective(CartDebug::GFX, start, end, currentbank);
}
}
}
in.close();
return "loaded " + node.getRelativePath() + " OK";
}
else
return DebuggerParser::red("config file not found");
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string CartDebug::saveConfigFile(const string& f) string CartDebug::saveConfigFile(string file)
{ {
return "NOT YET IMPLEMENTED"; return "NOT YET IMPLEMENTED";
} }
@ -676,7 +786,7 @@ string CartDebug::listConfig(int bank)
<< (i->type == CartDebug::CODE ? "CODE" : << (i->type == CartDebug::CODE ? "CODE" :
i->type == CartDebug::DATA ? "DATA" : i->type == CartDebug::DATA ? "DATA" :
"GFX") "GFX")
<< " " << hex << i->start << " " << hex << i->end << endl; << " " << HEX4 << i->start << " " << HEX4 << i->end << endl;
} }
getBankDirectives(buf, info); getBankDirectives(buf, info);
} }

View File

@ -74,8 +74,7 @@ class CartDebug : public DebuggerSystem
} Disassembly; } Disassembly;
public: public:
CartDebug(Debugger& dbg, Console& console, const RamAreaList& areas, CartDebug(Debugger& dbg, Console& console, const OSystem& osystem);
const Settings& settings);
virtual ~CartDebug(); virtual ~CartDebug();
const DebuggerState& getState(); const DebuggerState& getState();
@ -161,10 +160,12 @@ class CartDebug : public DebuggerSystem
@param type Currently, CODE/DATA/GFX are supported @param type Currently, CODE/DATA/GFX are supported
@param start The start address (inclusive) to mark with the given type @param start The start address (inclusive) to mark with the given type
@param end The end address (inclusive) to mark with the given type @param end The end address (inclusive) to mark with the given type
@param bank Bank to which these directive apply (0 indicated current bank)
@return True if directive was added, else false if it was removed @return True if directive was added, else false if it was removed
*/ */
bool addDirective(CartDebug::DisasmType type, uInt16 start, uInt16 end); bool addDirective(CartDebug::DisasmType type, uInt16 start, uInt16 end,
int bank = -1);
// The following are convenience methods that query the cartridge object // The following are convenience methods that query the cartridge object
// for the desired information. // for the desired information.
@ -216,8 +217,8 @@ class CartDebug : public DebuggerSystem
/** /**
Load/save Distella config file (Distella directives) Load/save Distella config file (Distella directives)
*/ */
string loadConfigFile(const string& file = ""); string loadConfigFile(string file = "");
string saveConfigFile(const string& file = ""); string saveConfigFile(string file = "");
/** /**
Show Distella directives (both set by the user and determined by Distella) Show Distella directives (both set by the user and determined by Distella)
@ -274,6 +275,8 @@ class CartDebug : public DebuggerSystem
int extractValue(const char* c) const; int extractValue(const char* c) const;
private: private:
const OSystem& myOSystem;
CartState myState; CartState myState;
CartState myOldState; CartState myOldState;

View File

@ -211,10 +211,9 @@ void Debugger::setConsole(Console* console)
delete myCartDebug; delete myCartDebug;
// Register any RAM areas in the Cartridge // Register any RAM areas in the Cartridge
// Zero-page RAM is automatically recognized by CartDebug // Zero-page RAM is automatically recognized by CartDebug
myCartDebug = new CartDebug(*this, *myConsole, myConsole->cartridge().ramAreas(), myCartDebug = new CartDebug(*this, *myConsole, *myOSystem);
myOSystem->settings());
cerr << myOSystem->romFile() << endl;
myCartDebug->loadSymbolFile(myOSystem->romFile()); myCartDebug->loadSymbolFile(myOSystem->romFile());
myCartDebug->loadConfigFile();
delete myRiotDebug; delete myRiotDebug;
myRiotDebug = new RiotDebug(*this, *myConsole); myRiotDebug = new RiotDebug(*this, *myConsole);
@ -256,8 +255,7 @@ string Debugger::autoExec()
ostringstream buf; ostringstream buf;
// autoexec.stella is always run // autoexec.stella is always run
FilesystemNode autoexec(myOSystem->baseDir() + BSPF_PATH_SEPARATOR + FilesystemNode autoexec(myOSystem->baseDir() + "autoexec.stella");
"autoexec.stella");
buf << "autoExec():" << endl buf << "autoExec():" << endl
<< myParser->exec(autoexec) << endl; << myParser->exec(autoexec) << endl;

View File

@ -1024,7 +1024,6 @@ void DebuggerParser::executeJump()
((address & 0xFFF) >= 0)) ((address & 0xFFF) >= 0))
address--; address--;
cerr << "address " << dec << address << " on line " << dec << line << endl;
if(line >= 0 && address >= 0) if(line >= 0 && address >= 0)
{ {
debugger->myRom->scrollTo(line); debugger->myRom->scrollTo(line);

View File

@ -673,16 +673,14 @@ void Console::setControllers(const string& rommd5)
} }
else if(right == "ATARIVOX") else if(right == "ATARIVOX")
{ {
const string& eepromfile = myOSystem->eepromDir() + BSPF_PATH_SEPARATOR + const string& eepromfile = myOSystem->eepromDir() + "atarivox_eeprom.dat";
"atarivox_eeprom.dat";
myControllers[rightPort] = new AtariVox(Controller::Right, *myEvent, myControllers[rightPort] = new AtariVox(Controller::Right, *myEvent,
*mySystem, myOSystem->serialPort(), *mySystem, myOSystem->serialPort(),
myOSystem->settings().getString("avoxport"), eepromfile); myOSystem->settings().getString("avoxport"), eepromfile);
} }
else if(right == "SAVEKEY") else if(right == "SAVEKEY")
{ {
const string& eepromfile = myOSystem->eepromDir() + BSPF_PATH_SEPARATOR + const string& eepromfile = myOSystem->eepromDir() + "savekey_eeprom.dat";
"savekey_eeprom.dat";
myControllers[rightPort] = new SaveKey(Controller::Right, *myEvent, *mySystem, myControllers[rightPort] = new SaveKey(Controller::Right, *myEvent, *mySystem,
eepromfile); eepromfile);
} }

View File

@ -572,8 +572,8 @@ void EventHandler::poll(uInt64 time)
case SDLK_s: // Ctrl-s saves properties to a file case SDLK_s: // Ctrl-s saves properties to a file
{ {
string filename = myOSystem->baseDir() + BSPF_PATH_SEPARATOR + string filename = myOSystem->baseDir() +
myOSystem->console().properties().get(Cartridge_Name) + ".pro"; myOSystem->console().properties().get(Cartridge_Name) + ".pro";
ofstream out(filename.c_str(), ios::out); ofstream out(filename.c_str(), ios::out);
if(out) if(out)
{ {
@ -1992,13 +1992,9 @@ void EventHandler::takeSnapshot(uInt32 number)
{ {
// Figure out the correct snapshot name // Figure out the correct snapshot name
string filename; string filename;
string sspath = myOSystem->snapshotDir();
bool showmessage = number == 0; bool showmessage = number == 0;
string sspath = myOSystem->snapshotDir() +
if(sspath.length() > 0) myOSystem->console().properties().get(Cartridge_Name);
if(sspath.substr(sspath.length()-1) != BSPF_PATH_SEPARATOR)
sspath += BSPF_PATH_SEPARATOR;
sspath += myOSystem->console().properties().get(Cartridge_Name);
// Check whether we want multiple snapshots created // Check whether we want multiple snapshots created
if(number > 0) if(number > 0)

View File

@ -299,7 +299,7 @@ class AbstractFilesystemNode
* *
* @note This method is very architecture dependent, please check the concrete implementation for more information. * @note This method is very architecture dependent, please check the concrete implementation for more information.
*/ */
virtual string getName() const = 0; virtual string getName() const = 0;
/** /**
* Returns the 'path' of the current node, usable in fopen(). * Returns the 'path' of the current node, usable in fopen().

View File

@ -311,44 +311,28 @@ void OSystem::setConfigPaths()
FilesystemNode node; FilesystemNode node;
string s; string s;
s = mySettings->getString("statedir"); validatePath("statedir", "state", myStateDir);
if(s == "") s = myBaseDir + BSPF_PATH_SEPARATOR + "state";
node = FilesystemNode(s);
myStateDir = node.getPath();
mySettings->setString("statedir", node.getRelativePath());
if(!node.isDirectory())
AbstractFilesystemNode::makeDir(myStateDir);
s = mySettings->getString("ssdir"); validatePath("ssdir", "snapshots", mySnapshotDir);
if(s == "") s = myBaseDir + BSPF_PATH_SEPARATOR + "snapshots";
node = FilesystemNode(s);
mySnapshotDir = node.getPath();
mySettings->setString("ssdir", node.getRelativePath());
if(!node.isDirectory())
AbstractFilesystemNode::makeDir(mySnapshotDir);
s = mySettings->getString("eepromdir"); validatePath("eepromdir", "", myEEPROMDir);
if(s == "") s = myBaseDir;
node = FilesystemNode(s); validatePath("cfgdir", "cfg", myCfgDir);
myEEPROMDir = node.getPath();
mySettings->setString("eepromdir", node.getRelativePath());
if(!node.isDirectory())
AbstractFilesystemNode::makeDir(myEEPROMDir);
s = mySettings->getString("cheatfile"); s = mySettings->getString("cheatfile");
if(s == "") s = myBaseDir + BSPF_PATH_SEPARATOR + "stella.cht"; if(s == "") s = myBaseDir + "stella.cht";
node = FilesystemNode(s); node = FilesystemNode(s);
myCheatFile = node.getPath(); myCheatFile = node.getPath();
mySettings->setString("cheatfile", node.getRelativePath()); mySettings->setString("cheatfile", node.getRelativePath());
s = mySettings->getString("palettefile"); s = mySettings->getString("palettefile");
if(s == "") s = myBaseDir + BSPF_PATH_SEPARATOR + "stella.pal"; if(s == "") s = myBaseDir + "stella.pal";
node = FilesystemNode(s); node = FilesystemNode(s);
myPaletteFile = node.getPath(); myPaletteFile = node.getPath();
mySettings->setString("palettefile", node.getRelativePath()); mySettings->setString("palettefile", node.getRelativePath());
s = mySettings->getString("propsfile"); s = mySettings->getString("propsfile");
if(s == "") s = myBaseDir + BSPF_PATH_SEPARATOR + "stella.pro"; if(s == "") s = myBaseDir + "stella.pro";
node = FilesystemNode(s); node = FilesystemNode(s);
myPropertiesFile = node.getPath(); myPropertiesFile = node.getPath();
mySettings->setString("propsfile", node.getRelativePath()); mySettings->setString("propsfile", node.getRelativePath());
@ -369,7 +353,10 @@ void OSystem::setBaseDir(const string& basedir)
FilesystemNode node(basedir); FilesystemNode node(basedir);
myBaseDir = node.getPath(); myBaseDir = node.getPath();
if(!node.isDirectory()) if(!node.isDirectory())
{
AbstractFilesystemNode::makeDir(myBaseDir); AbstractFilesystemNode::makeDir(myBaseDir);
myBaseDir = FilesystemNode(node.getPath()).getPath();
}
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -866,6 +853,22 @@ void OSystem::resetLoopTiming()
myTimingInfo.totalFrames = 0; myTimingInfo.totalFrames = 0;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::validatePath(const string& setting, const string& partialpath,
string& fullpath)
{
const string& s = mySettings->getString(setting) != "" ?
mySettings->getString(setting) : myBaseDir + partialpath;
FilesystemNode node = FilesystemNode(s);
if(!node.isDirectory())
{
AbstractFilesystemNode::makeDir(s);
node = FilesystemNode(node.getPath());
}
fullpath = node.getPath();
mySettings->setString(setting, node.getRelativePath());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::setDefaultJoymap(Event::Type event, EventMode mode) void OSystem::setDefaultJoymap(Event::Type event, EventMode mode)
{ {

View File

@ -276,6 +276,11 @@ class OSystem
*/ */
const string& eepromDir() const { return myEEPROMDir; } const string& eepromDir() const { return myEEPROMDir; }
/**
Return the full/complete directory name for storing Distella cfg files.
*/
const string& cfgDir() const { return myCfgDir; }
/** /**
This method should be called to get the full path of the cheat file. This method should be called to get the full path of the cheat file.
@ -540,6 +545,7 @@ class OSystem
string myStateDir; string myStateDir;
string mySnapshotDir; string mySnapshotDir;
string myEEPROMDir; string myEEPROMDir;
string myCfgDir;
string myCheatFile; string myCheatFile;
string myConfigFile; string myConfigFile;
@ -641,6 +647,14 @@ class OSystem
*/ */
void resetLoopTiming(); void resetLoopTiming();
/**
Validate the directory name, and create it if necessary.
Also, update the settings with the new name. For now, validation
means that the path must always end with the appropriate separator.
*/
void validatePath(const string& setting, const string& partialpath,
string& fullpath);
// Copy constructor isn't supported by this class so make it private // Copy constructor isn't supported by this class so make it private
OSystem(const OSystem&); OSystem(const OSystem&);

View File

@ -102,6 +102,7 @@ Settings::Settings(OSystem* osystem)
setInternal("palettefile", ""); setInternal("palettefile", "");
setInternal("propsfile", ""); setInternal("propsfile", "");
setInternal("eepromdir", ""); setInternal("eepromdir", "");
setInternal("cfgdir", "");
// ROM browser options // ROM browser options
setInternal("uselauncher", "true"); setInternal("uselauncher", "true");
@ -418,6 +419,7 @@ void Settings::usage()
<< " -palettefile <file> Full pathname of user-defined palette file\n" << " -palettefile <file> Full pathname of user-defined palette file\n"
<< " -propsfile <file> Full pathname of ROM properties file\n" << " -propsfile <file> Full pathname of ROM properties file\n"
<< " -eepromdir <dir> Directory in which to save EEPROM files\n" << " -eepromdir <dir> Directory in which to save EEPROM files\n"
<< " -cfgdir <dir> Directory in which to save Distella config files\n"
<< " -avoxport <name> The name of the serial port where an AtariVox is connected\n" << " -avoxport <name> The name of the serial port where an AtariVox is connected\n"
<< " -maxres <WxH> Used by developers to force the maximum size of the application window\n" << " -maxres <WxH> Used by developers to force the maximum size of the application window\n"
<< " -holdreset Start the emulator with the Game Reset switch held down\n" << " -holdreset Start the emulator with the Game Reset switch held down\n"
@ -433,6 +435,7 @@ void Settings::usage()
<< endl << endl
<< " -resolvedata <never| Set automatic code vs. data determination in the disassembler\n" << " -resolvedata <never| Set automatic code vs. data determination in the disassembler\n"
<< " always|auto>\n" << " always|auto>\n"
<< " -gfxformat <2|16> Set base to use for displaying GFX sections in the disassembler\n"
<< " -debuggerres <WxH> The resolution to use in debugger mode\n" << " -debuggerres <WxH> The resolution to use in debugger mode\n"
<< " -break <address> Set a breakpoint at 'address'\n" << " -break <address> Set a breakpoint at 'address'\n"
<< " -debug Start in debugger mode\n" << " -debug Start in debugger mode\n"

View File

@ -61,7 +61,7 @@ bool StateManager::toggleRecordMode()
{ {
myActiveMode = kOffMode; myActiveMode = kOffMode;
string moviefile = /*myOSystem->baseDir() + BSPF_PATH_SEPARATOR +*/ "test.inp"; string moviefile = /*myOSystem->baseDir() +*/ "test.inp";
if(myMovieWriter.isOpen()) if(myMovieWriter.isOpen())
myMovieWriter.close(); myMovieWriter.close();
if(!myMovieWriter.open(moviefile)) if(!myMovieWriter.open(moviefile))
@ -109,7 +109,7 @@ bool StateManager::toggleRewindMode()
{ {
myActiveMode = kOffMode; myActiveMode = kOffMode;
string moviefile = /*myOSystem->baseDir() + BSPF_PATH_SEPARATOR +*/ "test.inp"; string moviefile = /*myOSystem->baseDir() + */ "test.inp";
if(myMovieReader.isOpen()) if(myMovieReader.isOpen())
myMovieReader.close(); myMovieReader.close();
if(!myMovieReader.open(moviefile)) if(!myMovieReader.open(moviefile))
@ -178,7 +178,7 @@ void StateManager::loadState(int slot)
if(slot < 0) slot = myCurrentSlot; if(slot < 0) slot = myCurrentSlot;
ostringstream buf; ostringstream buf;
buf << myOSystem->stateDir() << BSPF_PATH_SEPARATOR buf << myOSystem->stateDir()
<< myOSystem->console().properties().get(Cartridge_Name) << myOSystem->console().properties().get(Cartridge_Name)
<< ".st" << slot; << ".st" << slot;
@ -222,7 +222,7 @@ void StateManager::saveState(int slot)
if(slot < 0) slot = myCurrentSlot; if(slot < 0) slot = myCurrentSlot;
ostringstream buf; ostringstream buf;
buf << myOSystem->stateDir() << BSPF_PATH_SEPARATOR buf << myOSystem->stateDir()
<< myOSystem->console().properties().get(Cartridge_Name) << myOSystem->console().properties().get(Cartridge_Name)
<< ".st" << slot; << ".st" << slot;

View File

@ -222,9 +222,7 @@ void FileSnapDialog::saveConfig()
void FileSnapDialog::setDefaults() void FileSnapDialog::setDefaults()
{ {
FilesystemNode node; FilesystemNode node;
string basedir = instance().baseDir(); const string& basedir = instance().baseDir();
if(basedir.compare(basedir.length()-1, 1, BSPF_PATH_SEPARATOR, 0, 1) != 0)
basedir.append(BSPF_PATH_SEPARATOR);
node = FilesystemNode("~"); node = FilesystemNode("~");
myRomPath->setEditString(node.getRelativePath()); myRomPath->setEditString(node.getRelativePath());

View File

@ -147,11 +147,7 @@ void RomAuditDialog::auditRoms()
// Only rename the file if we found a valid properties entry // Only rename the file if we found a valid properties entry
if(name != "" && name != files[idx].getDisplayName()) if(name != "" && name != files[idx].getDisplayName())
{ {
// Check for terminating separator const string& newfile = node.getPath() + name + "." + extension;
string newfile = auditPath;
if(newfile.find_last_of(BSPF_PATH_SEPARATOR) != newfile.length()-1)
newfile += BSPF_PATH_SEPARATOR;
newfile += name + "." + extension;
if(files[idx].getPath() != newfile) if(files[idx].getPath() != newfile)
if(AbstractFilesystemNode::renameFile(files[idx].getPath(), newfile)) if(AbstractFilesystemNode::renameFile(files[idx].getPath(), newfile))

View File

@ -109,8 +109,8 @@ void RomInfoWidget::parseProperties()
myRomInfo.clear(); myRomInfo.clear();
// Get a valid filename representing a snapshot file for this rom // Get a valid filename representing a snapshot file for this rom
const string& filename = instance().snapshotDir() + BSPF_PATH_SEPARATOR + const string& filename = instance().snapshotDir() +
myProperties.get(Cartridge_Name) + ".png"; myProperties.get(Cartridge_Name) + ".png";
// Read the PNG file // Read the PNG file
try try

View File

@ -161,7 +161,13 @@ POSIXFilesystemNode::POSIXFilesystemNode(const string& p, bool verify)
_displayName = lastPathComponent(_path); _displayName = lastPathComponent(_path);
if (verify) if (verify)
{
setFlags(); setFlags();
// Add a trailing slash, if necessary
if (_isDirectory && _path.length() > 0 && _path[_path.length()-1] != '/')
_path += '/';
}
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -278,7 +278,7 @@ WindowsFilesystemNode::WindowsFilesystemNode(const string& p)
_isDirectory = ((fileAttribs & FILE_ATTRIBUTE_DIRECTORY) != 0); _isDirectory = ((fileAttribs & FILE_ATTRIBUTE_DIRECTORY) != 0);
_isValid = true; _isValid = true;
// Add a trailing slash, if necessary. // Add a trailing backslash, if necessary
if (_isDirectory && _path.length() > 0 && _path[_path.length()-1] != '\\') if (_isDirectory && _path.length() > 0 && _path[_path.length()-1] != '\\')
_path += '\\'; _path += '\\';
} }