From 2d08d4e459f3c7a3cc6c88698dc14c0d1cb1548e Mon Sep 17 00:00:00 2001 From: stephena Date: Mon, 6 Sep 2010 00:17:51 +0000 Subject: [PATCH] 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 --- src/common/FrameBufferGL.cxx | 2 +- src/debugger/CartDebug.cxx | 130 +++++++++++++++++++++++++++++--- src/debugger/CartDebug.hxx | 13 ++-- src/debugger/Debugger.cxx | 8 +- src/debugger/DebuggerParser.cxx | 1 - src/emucore/Console.cxx | 6 +- src/emucore/EventHandler.cxx | 12 +-- src/emucore/FSNode.hxx | 2 +- src/emucore/OSystem.cxx | 51 +++++++------ src/emucore/OSystem.hxx | 14 ++++ src/emucore/Settings.cxx | 3 + src/emucore/StateManager.cxx | 8 +- src/gui/FileSnapDialog.cxx | 4 +- src/gui/RomAuditDialog.cxx | 6 +- src/gui/RomInfoWidget.cxx | 4 +- src/unix/FSNodePOSIX.cxx | 6 ++ src/win32/FSNodeWin32.cxx | 2 +- 17 files changed, 198 insertions(+), 74 deletions(-) diff --git a/src/common/FrameBufferGL.cxx b/src/common/FrameBufferGL.cxx index 1b57435f3..20800b426 100644 --- a/src/common/FrameBufferGL.cxx +++ b/src/common/FrameBufferGL.cxx @@ -1648,7 +1648,7 @@ GLuint FBSurfaceGL::genShader(ShaderType type) // These shader files are stored in 'BASEDIR/shaders/' char* buffer = NULL; const string& filename = - myFB.myOSystem->baseDir() + BSPF_PATH_SEPARATOR + "shaders" + + myFB.myOSystem->baseDir() + "shaders" + BSPF_PATH_SEPARATOR + fFile; ifstream in(filename.c_str()); if(in && in.is_open()) diff --git a/src/debugger/CartDebug.cxx b/src/debugger/CartDebug.cxx index 58f5ad166..6efb95407 100644 --- a/src/debugger/CartDebug.cxx +++ b/src/debugger/CartDebug.cxx @@ -26,9 +26,9 @@ #include "CartDebug.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -CartDebug::CartDebug(Debugger& dbg, Console& console, const RamAreaList& areas, - const Settings& settings) +CartDebug::CartDebug(Debugger& dbg, Console& console, const OSystem& osystem) : DebuggerSystem(dbg, console), + myOSystem(osystem), myRWPortAddress(0), myLabelLength(5) // longest pre-defined label { @@ -36,6 +36,7 @@ CartDebug::CartDebug(Debugger& dbg, Console& console, const RamAreaList& areas, addRamArea(0x80, 128, 0, 0); // Add extended RAM + const RamAreaList& areas = console.cartridge().ramAreas(); for(RamAreaList::const_iterator i = areas.begin(); i != areas.end(); ++i) 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 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) \ cerr << (d.type == CartDebug::CODE ? "CODE" : \ @@ -360,10 +362,13 @@ bool CartDebug::addDirective(CartDebug::DisasmType type, uInt16 start, uInt16 en PRINT_TAG((*d)); \ cerr << endl; - BankInfo& info = (myDebugger.cpuDebug().pc() & 0x1000) ? - myBankInfo[getBank()] : myBankInfo[myBankInfo.size()-1]; + if(bank < 0) // Do we want the current bank or ZP RAM? + bank = (myDebugger.cpuDebug().pc() & 0x1000) ? getBank() : myBankInfo.size()-1; + bank = BSPF_min(bank, bankCount() - 1); + BankInfo& info = myBankInfo[bank]; DirectiveList& list = info.directiveList; + DirectiveTag tag; tag.type = type; 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"; } @@ -676,7 +786,7 @@ string CartDebug::listConfig(int bank) << (i->type == CartDebug::CODE ? "CODE" : i->type == CartDebug::DATA ? "DATA" : "GFX") - << " " << hex << i->start << " " << hex << i->end << endl; + << " " << HEX4 << i->start << " " << HEX4 << i->end << endl; } getBankDirectives(buf, info); } diff --git a/src/debugger/CartDebug.hxx b/src/debugger/CartDebug.hxx index 774ccac1a..19275e9f7 100644 --- a/src/debugger/CartDebug.hxx +++ b/src/debugger/CartDebug.hxx @@ -74,8 +74,7 @@ class CartDebug : public DebuggerSystem } Disassembly; public: - CartDebug(Debugger& dbg, Console& console, const RamAreaList& areas, - const Settings& settings); + CartDebug(Debugger& dbg, Console& console, const OSystem& osystem); virtual ~CartDebug(); const DebuggerState& getState(); @@ -161,10 +160,12 @@ class CartDebug : public DebuggerSystem @param type Currently, CODE/DATA/GFX are supported @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 bank Bank to which these directive apply (0 indicated current bank) @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 // for the desired information. @@ -216,8 +217,8 @@ class CartDebug : public DebuggerSystem /** Load/save Distella config file (Distella directives) */ - string loadConfigFile(const string& file = ""); - string saveConfigFile(const string& file = ""); + string loadConfigFile(string file = ""); + string saveConfigFile(string file = ""); /** 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; private: + const OSystem& myOSystem; + CartState myState; CartState myOldState; diff --git a/src/debugger/Debugger.cxx b/src/debugger/Debugger.cxx index 54db1e395..3b8d54b10 100644 --- a/src/debugger/Debugger.cxx +++ b/src/debugger/Debugger.cxx @@ -211,10 +211,9 @@ void Debugger::setConsole(Console* console) delete myCartDebug; // Register any RAM areas in the Cartridge // Zero-page RAM is automatically recognized by CartDebug - myCartDebug = new CartDebug(*this, *myConsole, myConsole->cartridge().ramAreas(), - myOSystem->settings()); -cerr << myOSystem->romFile() << endl; + myCartDebug = new CartDebug(*this, *myConsole, *myOSystem); myCartDebug->loadSymbolFile(myOSystem->romFile()); + myCartDebug->loadConfigFile(); delete myRiotDebug; myRiotDebug = new RiotDebug(*this, *myConsole); @@ -256,8 +255,7 @@ string Debugger::autoExec() ostringstream buf; // autoexec.stella is always run - FilesystemNode autoexec(myOSystem->baseDir() + BSPF_PATH_SEPARATOR + - "autoexec.stella"); + FilesystemNode autoexec(myOSystem->baseDir() + "autoexec.stella"); buf << "autoExec():" << endl << myParser->exec(autoexec) << endl; diff --git a/src/debugger/DebuggerParser.cxx b/src/debugger/DebuggerParser.cxx index 7308cb91d..1575452a7 100644 --- a/src/debugger/DebuggerParser.cxx +++ b/src/debugger/DebuggerParser.cxx @@ -1024,7 +1024,6 @@ void DebuggerParser::executeJump() ((address & 0xFFF) >= 0)) address--; -cerr << "address " << dec << address << " on line " << dec << line << endl; if(line >= 0 && address >= 0) { debugger->myRom->scrollTo(line); diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index 6399cc68d..5c1036e59 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -673,16 +673,14 @@ void Console::setControllers(const string& rommd5) } else if(right == "ATARIVOX") { - const string& eepromfile = myOSystem->eepromDir() + BSPF_PATH_SEPARATOR + - "atarivox_eeprom.dat"; + const string& eepromfile = myOSystem->eepromDir() + "atarivox_eeprom.dat"; myControllers[rightPort] = new AtariVox(Controller::Right, *myEvent, *mySystem, myOSystem->serialPort(), myOSystem->settings().getString("avoxport"), eepromfile); } else if(right == "SAVEKEY") { - const string& eepromfile = myOSystem->eepromDir() + BSPF_PATH_SEPARATOR + - "savekey_eeprom.dat"; + const string& eepromfile = myOSystem->eepromDir() + "savekey_eeprom.dat"; myControllers[rightPort] = new SaveKey(Controller::Right, *myEvent, *mySystem, eepromfile); } diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 04313ac3b..e1191cd50 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -572,8 +572,8 @@ void EventHandler::poll(uInt64 time) case SDLK_s: // Ctrl-s saves properties to a file { - string filename = myOSystem->baseDir() + BSPF_PATH_SEPARATOR + - myOSystem->console().properties().get(Cartridge_Name) + ".pro"; + string filename = myOSystem->baseDir() + + myOSystem->console().properties().get(Cartridge_Name) + ".pro"; ofstream out(filename.c_str(), ios::out); if(out) { @@ -1992,13 +1992,9 @@ void EventHandler::takeSnapshot(uInt32 number) { // Figure out the correct snapshot name string filename; - string sspath = myOSystem->snapshotDir(); bool showmessage = number == 0; - - if(sspath.length() > 0) - if(sspath.substr(sspath.length()-1) != BSPF_PATH_SEPARATOR) - sspath += BSPF_PATH_SEPARATOR; - sspath += myOSystem->console().properties().get(Cartridge_Name); + string sspath = myOSystem->snapshotDir() + + myOSystem->console().properties().get(Cartridge_Name); // Check whether we want multiple snapshots created if(number > 0) diff --git a/src/emucore/FSNode.hxx b/src/emucore/FSNode.hxx index da9be650d..78ff51d4b 100644 --- a/src/emucore/FSNode.hxx +++ b/src/emucore/FSNode.hxx @@ -299,7 +299,7 @@ class AbstractFilesystemNode * * @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(). diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index 1f5730288..b171850fb 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -311,44 +311,28 @@ void OSystem::setConfigPaths() FilesystemNode node; string s; - s = mySettings->getString("statedir"); - 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); + validatePath("statedir", "state", myStateDir); - s = mySettings->getString("ssdir"); - 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); + validatePath("ssdir", "snapshots", mySnapshotDir); - s = mySettings->getString("eepromdir"); - if(s == "") s = myBaseDir; - node = FilesystemNode(s); - myEEPROMDir = node.getPath(); - mySettings->setString("eepromdir", node.getRelativePath()); - if(!node.isDirectory()) - AbstractFilesystemNode::makeDir(myEEPROMDir); + validatePath("eepromdir", "", myEEPROMDir); + + validatePath("cfgdir", "cfg", myCfgDir); s = mySettings->getString("cheatfile"); - if(s == "") s = myBaseDir + BSPF_PATH_SEPARATOR + "stella.cht"; + if(s == "") s = myBaseDir + "stella.cht"; node = FilesystemNode(s); myCheatFile = node.getPath(); mySettings->setString("cheatfile", node.getRelativePath()); s = mySettings->getString("palettefile"); - if(s == "") s = myBaseDir + BSPF_PATH_SEPARATOR + "stella.pal"; + if(s == "") s = myBaseDir + "stella.pal"; node = FilesystemNode(s); myPaletteFile = node.getPath(); mySettings->setString("palettefile", node.getRelativePath()); s = mySettings->getString("propsfile"); - if(s == "") s = myBaseDir + BSPF_PATH_SEPARATOR + "stella.pro"; + if(s == "") s = myBaseDir + "stella.pro"; node = FilesystemNode(s); myPropertiesFile = node.getPath(); mySettings->setString("propsfile", node.getRelativePath()); @@ -369,7 +353,10 @@ void OSystem::setBaseDir(const string& basedir) FilesystemNode node(basedir); myBaseDir = node.getPath(); if(!node.isDirectory()) + { AbstractFilesystemNode::makeDir(myBaseDir); + myBaseDir = FilesystemNode(node.getPath()).getPath(); + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -866,6 +853,22 @@ void OSystem::resetLoopTiming() 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) { diff --git a/src/emucore/OSystem.hxx b/src/emucore/OSystem.hxx index 857b1de79..369d1d2f7 100644 --- a/src/emucore/OSystem.hxx +++ b/src/emucore/OSystem.hxx @@ -276,6 +276,11 @@ class OSystem */ 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. @@ -540,6 +545,7 @@ class OSystem string myStateDir; string mySnapshotDir; string myEEPROMDir; + string myCfgDir; string myCheatFile; string myConfigFile; @@ -641,6 +647,14 @@ class OSystem */ 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 OSystem(const OSystem&); diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index 824168878..a490f828c 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -102,6 +102,7 @@ Settings::Settings(OSystem* osystem) setInternal("palettefile", ""); setInternal("propsfile", ""); setInternal("eepromdir", ""); + setInternal("cfgdir", ""); // ROM browser options setInternal("uselauncher", "true"); @@ -418,6 +419,7 @@ void Settings::usage() << " -palettefile Full pathname of user-defined palette file\n" << " -propsfile Full pathname of ROM properties file\n" << " -eepromdir Directory in which to save EEPROM files\n" + << " -cfgdir Directory in which to save Distella config files\n" << " -avoxport The name of the serial port where an AtariVox is connected\n" << " -maxres 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" @@ -433,6 +435,7 @@ void Settings::usage() << endl << " -resolvedata \n" + << " -gfxformat <2|16> Set base to use for displaying GFX sections in the disassembler\n" << " -debuggerres The resolution to use in debugger mode\n" << " -break
Set a breakpoint at 'address'\n" << " -debug Start in debugger mode\n" diff --git a/src/emucore/StateManager.cxx b/src/emucore/StateManager.cxx index 0ad3fd7eb..565935575 100644 --- a/src/emucore/StateManager.cxx +++ b/src/emucore/StateManager.cxx @@ -61,7 +61,7 @@ bool StateManager::toggleRecordMode() { myActiveMode = kOffMode; - string moviefile = /*myOSystem->baseDir() + BSPF_PATH_SEPARATOR +*/ "test.inp"; + string moviefile = /*myOSystem->baseDir() +*/ "test.inp"; if(myMovieWriter.isOpen()) myMovieWriter.close(); if(!myMovieWriter.open(moviefile)) @@ -109,7 +109,7 @@ bool StateManager::toggleRewindMode() { myActiveMode = kOffMode; - string moviefile = /*myOSystem->baseDir() + BSPF_PATH_SEPARATOR +*/ "test.inp"; + string moviefile = /*myOSystem->baseDir() + */ "test.inp"; if(myMovieReader.isOpen()) myMovieReader.close(); if(!myMovieReader.open(moviefile)) @@ -178,7 +178,7 @@ void StateManager::loadState(int slot) if(slot < 0) slot = myCurrentSlot; ostringstream buf; - buf << myOSystem->stateDir() << BSPF_PATH_SEPARATOR + buf << myOSystem->stateDir() << myOSystem->console().properties().get(Cartridge_Name) << ".st" << slot; @@ -222,7 +222,7 @@ void StateManager::saveState(int slot) if(slot < 0) slot = myCurrentSlot; ostringstream buf; - buf << myOSystem->stateDir() << BSPF_PATH_SEPARATOR + buf << myOSystem->stateDir() << myOSystem->console().properties().get(Cartridge_Name) << ".st" << slot; diff --git a/src/gui/FileSnapDialog.cxx b/src/gui/FileSnapDialog.cxx index 6456214cd..da66078b5 100644 --- a/src/gui/FileSnapDialog.cxx +++ b/src/gui/FileSnapDialog.cxx @@ -222,9 +222,7 @@ void FileSnapDialog::saveConfig() void FileSnapDialog::setDefaults() { FilesystemNode node; - string basedir = instance().baseDir(); - if(basedir.compare(basedir.length()-1, 1, BSPF_PATH_SEPARATOR, 0, 1) != 0) - basedir.append(BSPF_PATH_SEPARATOR); + const string& basedir = instance().baseDir(); node = FilesystemNode("~"); myRomPath->setEditString(node.getRelativePath()); diff --git a/src/gui/RomAuditDialog.cxx b/src/gui/RomAuditDialog.cxx index 94f660e18..afe3d0158 100644 --- a/src/gui/RomAuditDialog.cxx +++ b/src/gui/RomAuditDialog.cxx @@ -147,11 +147,7 @@ void RomAuditDialog::auditRoms() // Only rename the file if we found a valid properties entry if(name != "" && name != files[idx].getDisplayName()) { - // Check for terminating separator - string newfile = auditPath; - if(newfile.find_last_of(BSPF_PATH_SEPARATOR) != newfile.length()-1) - newfile += BSPF_PATH_SEPARATOR; - newfile += name + "." + extension; + const string& newfile = node.getPath() + name + "." + extension; if(files[idx].getPath() != newfile) if(AbstractFilesystemNode::renameFile(files[idx].getPath(), newfile)) diff --git a/src/gui/RomInfoWidget.cxx b/src/gui/RomInfoWidget.cxx index 6df6e1637..ca5e627a6 100644 --- a/src/gui/RomInfoWidget.cxx +++ b/src/gui/RomInfoWidget.cxx @@ -109,8 +109,8 @@ void RomInfoWidget::parseProperties() myRomInfo.clear(); // Get a valid filename representing a snapshot file for this rom - const string& filename = instance().snapshotDir() + BSPF_PATH_SEPARATOR + - myProperties.get(Cartridge_Name) + ".png"; + const string& filename = instance().snapshotDir() + + myProperties.get(Cartridge_Name) + ".png"; // Read the PNG file try diff --git a/src/unix/FSNodePOSIX.cxx b/src/unix/FSNodePOSIX.cxx index 3f64597bc..49664975b 100644 --- a/src/unix/FSNodePOSIX.cxx +++ b/src/unix/FSNodePOSIX.cxx @@ -161,7 +161,13 @@ POSIXFilesystemNode::POSIXFilesystemNode(const string& p, bool verify) _displayName = lastPathComponent(_path); if (verify) + { setFlags(); + + // Add a trailing slash, if necessary + if (_isDirectory && _path.length() > 0 && _path[_path.length()-1] != '/') + _path += '/'; + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/win32/FSNodeWin32.cxx b/src/win32/FSNodeWin32.cxx index f5198ecdf..cd00a1cf6 100644 --- a/src/win32/FSNodeWin32.cxx +++ b/src/win32/FSNodeWin32.cxx @@ -278,7 +278,7 @@ WindowsFilesystemNode::WindowsFilesystemNode(const string& p) _isDirectory = ((fileAttribs & FILE_ATTRIBUTE_DIRECTORY) != 0); _isValid = true; - // Add a trailing slash, if necessary. + // Add a trailing backslash, if necessary if (_isDirectory && _path.length() > 0 && _path[_path.length()-1] != '\\') _path += '\\'; }