diff --git a/src/common/FSNodeZIP.hxx b/src/common/FSNodeZIP.hxx index e81113632..59517a636 100644 --- a/src/common/FSNodeZIP.hxx +++ b/src/common/FSNodeZIP.hxx @@ -59,7 +59,6 @@ class FilesystemNodeZIP : public AbstractFSNode bool isFile() const { return _numFiles == 1; } bool isReadable() const { return _realNode && _realNode->isReadable(); } bool isWritable() const { return false; } - bool isAbsolute() const { return _realNode && _realNode->isAbsolute(); } ////////////////////////////////////////////////////////// // For now, ZIP files cannot be modified in any way diff --git a/src/debugger/CartDebug.cxx b/src/debugger/CartDebug.cxx index 1a01fbc43..a5c03d2b8 100644 --- a/src/debugger/CartDebug.cxx +++ b/src/debugger/CartDebug.cxx @@ -646,225 +646,205 @@ int CartDebug::getAddress(const string& label) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartDebug::loadSymbolFile(string file) +string CartDebug::loadSymbolFile() { - if(file == "") - file = myOSystem.romFile(); + // Currently, the default naming/location for symbol files is: + // 1) ROM dir based on properties entry name - string::size_type spos; - if( (spos = file.find_last_of('.')) != string::npos ) - file.replace(spos, file.size(), ".sym"); - else - file += ".sym"; - - FilesystemNode node(file); - if(node.exists() && node.isFile()) + if(mySymbolFile == "") { - ifstream in(node.getPath().c_str()); - if(!in.is_open()) - return DebuggerParser::red("symbol file '" + node.getShortPath() + "' not found"); + const string& propsname = + myConsole.properties().get(Cartridge_Name) + ".sym"; - myUserAddresses.clear(); - myUserLabels.clear(); - - while(!in.eof()) - { - string label; - int value = -1; - - getline(in, label); - stringstream buf; - buf << label; - buf >> label >> hex >> value; - - if(label.length() > 0 && label[0] != '-' && value >= 0) - addLabel(label, value); - } - in.close(); - return "loaded " + node.getShortPath() + " OK"; + FilesystemNode case1(FilesystemNode(myOSystem.romFile()).getParent().getPath() + + propsname); + if(case1.isFile() && case1.isReadable()) + mySymbolFile = case1.getPath(); + else + return DebuggerParser::red("symbol file not found in:\n " + case1.getShortPath()); } - return DebuggerParser::red("symbol file '" + node.getShortPath() + "' not found"); + + FilesystemNode node(mySymbolFile); + ifstream in(node.getPath().c_str()); + if(!in.is_open()) + return DebuggerParser::red("symbol file '" + node.getShortPath() + "' not readable"); + + myUserAddresses.clear(); + myUserLabels.clear(); + + while(!in.eof()) + { + string label; + int value = -1; + + getline(in, label); + stringstream buf; + buf << label; + buf >> label >> hex >> value; + + if(label.length() > 0 && label[0] != '-' && value >= 0) + addLabel(label, value); + } + in.close(); + myDebugger.rom().invalidate(); + + return "loaded " + node.getShortPath() + " OK"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartDebug::loadConfigFile(string file) +string CartDebug::loadConfigFile() { - FilesystemNode node(file); + // There are two possible locations for loading config files + // (in order of decreasing relevance): + // 1) ROM dir based on properties entry name + // 2) CFG dir based on properties entry name - if(file == "") + if(myCfgFile == "") { - // There are three possible locations for loading config files - // (in order of decreasing relevance): - // 1) ROM dir based on properties entry name - // 2) ROM dir based on actual ROM name - // 3) CFG dir based on properties entry name - const string& propsname = myConsole.properties().get(Cartridge_Name) + ".cfg"; - // Case 1 FilesystemNode case1(FilesystemNode(myOSystem.romFile()).getParent().getPath() + propsname); - if(case1.exists()) - { - node = case1; - } + FilesystemNode case2(myOSystem.cfgDir() + propsname); + + if(case1.isFile() && case1.isReadable()) + myCfgFile = case1.getPath(); + else if(case2.isFile() && case2.isReadable()) + myCfgFile = case2.getPath(); else - { - 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 case2(file); - if(case2.exists()) - { - node = case2; - } - else // Use global config file based on properties cart name - { - FilesystemNode case3(myOSystem.cfgDir() + propsname); - if(case3.exists()) - node = case3; - } - } + return DebuggerParser::red("config file not found in:\n " + + case1.getShortPath() + "\n " + case2.getShortPath()); } - if(node.exists() && node.isFile()) + FilesystemNode node(myCfgFile); + ifstream in(node.getPath().c_str()); + if(!in.is_open()) + return "Unable to load directives from " + node.getPath(); + + // Erase all previous directives + for(Common::Array::iterator bi = myBankInfo.begin(); + bi != myBankInfo.end(); ++bi) { - ifstream in(node.getPath().c_str()); - if(!in.is_open()) - return "Unable to load directives from " + node.getPath(); - - // Erase all previous directives - for(Common::Array::iterator bi = myBankInfo.begin(); - bi != myBankInfo.end(); ++bi) - { - bi->directiveList.clear(); - } - - 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")) - { - // TODO - figure out what to do with this - buf >> hex >> start; - } - else if(BSPF_startsWithIgnoreCase(directive, "CODE")) - { - buf >> hex >> start >> hex >> end; - addDirective(CartDebug::CODE, start, end, currentbank); - } - else if(BSPF_startsWithIgnoreCase(directive, "GFX")) - { - buf >> hex >> start >> hex >> end; - addDirective(CartDebug::GFX, start, end, currentbank); - } - else if(BSPF_startsWithIgnoreCase(directive, "PGFX")) - { - buf >> hex >> start >> hex >> end; - addDirective(CartDebug::PGFX, start, end, currentbank); - } - else if(BSPF_startsWithIgnoreCase(directive, "DATA")) - { - buf >> hex >> start >> hex >> end; - addDirective(CartDebug::DATA, start, end, currentbank); - } - else if(BSPF_startsWithIgnoreCase(directive, "ROW")) - { - buf >> hex >> start; - buf >> hex >> end; - addDirective(CartDebug::ROW, start, end, currentbank); - } - } - } - in.close(); - - return "loaded " + node.getShortPath() + " OK"; + bi->directiveList.clear(); } - else - return DebuggerParser::red("config file not found"); + + 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")) + { + // TODO - figure out what to do with this + buf >> hex >> start; + } + else if(BSPF_startsWithIgnoreCase(directive, "CODE")) + { + buf >> hex >> start >> hex >> end; + addDirective(CartDebug::CODE, start, end, currentbank); + } + else if(BSPF_startsWithIgnoreCase(directive, "GFX")) + { + buf >> hex >> start >> hex >> end; + addDirective(CartDebug::GFX, start, end, currentbank); + } + else if(BSPF_startsWithIgnoreCase(directive, "PGFX")) + { + buf >> hex >> start >> hex >> end; + addDirective(CartDebug::PGFX, start, end, currentbank); + } + else if(BSPF_startsWithIgnoreCase(directive, "DATA")) + { + buf >> hex >> start >> hex >> end; + addDirective(CartDebug::DATA, start, end, currentbank); + } + else if(BSPF_startsWithIgnoreCase(directive, "ROW")) + { + buf >> hex >> start; + buf >> hex >> end; + addDirective(CartDebug::ROW, start, end, currentbank); + } + } + } + in.close(); + myDebugger.rom().invalidate(); + + return "loaded " + node.getShortPath() + " OK"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartDebug::saveConfigFile(string file) +string CartDebug::saveConfigFile() { - FilesystemNode node(file); + // While there are two possible locations for loading config files, + // the main 'config' directory is used whenever possible when saving, + // unless the rom-specific file already exists + + FilesystemNode node; + + FilesystemNode case0(myCfgFile); + if(myCfgFile != "" && case0.isFile() && case0.isWritable()) + node = case0; + else + { + const string& propsname = + myConsole.properties().get(Cartridge_Name) + ".cfg"; + + node = FilesystemNode(myOSystem.cfgDir() + propsname); + } const string& name = myConsole.properties().get(Cartridge_Name); const string& md5 = myConsole.properties().get(Cartridge_MD5); - if(file == "") + ofstream out(node.getPath().c_str()); + if(!out.is_open()) + return "Unable to save directives to " + node.getShortPath(); + + // Store all bank information + out << "//Stella.pro: \"" << name << "\"" << endl + << "//MD5: " << md5 << endl + << endl; + for(uInt32 b = 0; b < myConsole.cartridge().bankCount(); ++b) { - // There are two possible locations for saving config files - // (in order of decreasing relevance): - // 1) ROM dir based on properties entry name - // 2) ROM dir based on actual ROM name - // - // In either case, we're using the properties entry, since even ROMs that - // don't have a proper entry have a temporary one inserted by OSystem - node = FilesystemNode(FilesystemNode( - myOSystem.romFile()).getParent().getPath() + name + ".cfg"); + out << "[" << b << "]" << endl; + getBankDirectives(out, myBankInfo[b]); } + out.close(); - if(node.isFile()) - { - ofstream out(node.getPath().c_str()); - if(!out.is_open()) - return "Unable to save directives to " + node.getPath(); - - // Store all bank information - out << "//Stella.pro: \"" << name << "\"" << endl - << "//MD5: " << md5 << endl - << endl; - for(uInt32 b = 0; b < myConsole.cartridge().bankCount(); ++b) - { - out << "[" << b << "]" << endl; - getBankDirectives(out, myBankInfo[b]); - } - out.close(); - - return "saved " + node.getShortPath() + " OK"; - } - else - return DebuggerParser::red("config file not found"); + return "saved " + node.getShortPath() + " OK"; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string CartDebug::saveDisassembly(string file) +string CartDebug::saveDisassembly() { #define ALIGN(x) setfill(' ') << left << setw(x) @@ -877,7 +857,7 @@ string CartDebug::saveDisassembly(string file) // Some boilerplate, similar to what DiStella adds time_t currtime; time(&currtime); - buf << "; Disassembly of " << file << "\n" + buf << "; Disassembly of " << myOSystem.romFile() << "\n" << "; Disassembled " << ctime(&currtime) << "; Using Stella " << STELLA_VERSION << "\n;\n" << "; Settings used: TODO - add args\n;\n" @@ -994,6 +974,20 @@ string CartDebug::saveDisassembly(string file) return DebuggerParser::red("not save to file yet"); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string CartDebug::saveRom() +{ + const string& path = "~" BSPF_PATH_SEPARATOR + + myConsole.properties().get(Cartridge_Name) + ".a26"; + + FilesystemNode node(path); + ofstream out(node.getPath().c_str(), ios::out | ios::binary); + if(out.is_open() && myConsole.cartridge().save(out)) + return "saved ROM as " + node.getShortPath(); + else + return DebuggerParser::red("failed to save ROM"); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string CartDebug::listConfig(int bank) { diff --git a/src/debugger/CartDebug.hxx b/src/debugger/CartDebug.hxx index c6c71b92d..694b47418 100644 --- a/src/debugger/CartDebug.hxx +++ b/src/debugger/CartDebug.hxx @@ -230,16 +230,21 @@ class CartDebug : public DebuggerSystem int getAddress(const string& label) const; /** - Load user equates from the given symbol file (as generated by DASM). + Load user equates from symbol file (as generated by DASM). */ - string loadSymbolFile(string file = ""); + string loadSymbolFile(); /** - Load/save Distella config file (Distella directives) and disassembly + Load/save Distella config files (Distella directives) */ - string loadConfigFile(string file = ""); - string saveConfigFile(string file = ""); - string saveDisassembly(string file = ""); + string loadConfigFile(); + string saveConfigFile(); + + /** + Save disassembly and ROM file + */ + string saveDisassembly(); + string saveRom(); /** Show Distella directives (both set by the user and determined by Distella) @@ -357,6 +362,9 @@ class CartDebug : public DebuggerSystem // The maximum length of all labels currently defined uInt16 myLabelLength; + // Filenames to use for various I/O (currently these are hardcoded) + string mySymbolFile, myCfgFile, myDisasmFile, myRomFile; + /// Table of instruction mnemonics static const char* ourTIAMnemonicR[64]; // read mode static const char* ourTIAMnemonicW[128]; // write mode diff --git a/src/debugger/Debugger.cxx b/src/debugger/Debugger.cxx index 4b0e2fd41..71c21cb9d 100644 --- a/src/debugger/Debugger.cxx +++ b/src/debugger/Debugger.cxx @@ -813,19 +813,6 @@ void Debugger::getCompletions(const char* in, StringList& list) const list.push_back(pseudo_registers[i][0]); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string Debugger::saveROM(const string& filename) const -{ - string path = FilesystemNode::createAbsolutePath(filename, "~", "a26"); - FilesystemNode node(path); - - ofstream out(node.getPath().c_str(), ios::out | ios::binary); - if(out.is_open() && myConsole.cartridge().save(out)) - return node.getShortPath(); - else - return ""; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Debugger::lockBankswitchState() { diff --git a/src/debugger/Debugger.hxx b/src/debugger/Debugger.hxx index 54b1dcb5e..0a2c134d7 100644 --- a/src/debugger/Debugger.hxx +++ b/src/debugger/Debugger.hxx @@ -75,7 +75,6 @@ class Debugger : public DialogContainer // Make these friend classes, to ease communications with the debugger // Although it isn't enforced, these classes should use accessor methods // directly, and not touch the instance variables - friend class DebuggerDialog; friend class DebuggerParser; friend class EventHandler; @@ -132,6 +131,11 @@ class Debugger : public DialogContainer */ void getCompletions(const char* in, StringList& list) const; + /** + The dialog/GUI associated with the debugger + */ + Dialog& dialog() const { return *myDialog; } + /** The debugger subsystem responsible for all CPU state */ @@ -152,10 +156,12 @@ class Debugger : public DialogContainer */ TIADebug& tiaDebug() const { return *myTiaDebug; } - DebuggerParser& parser() const { return *myParser; } - PackedBitArray& breakpoints() const { return *myBreakPoints; } - PackedBitArray& readtraps() const { return *myReadTraps; } - PackedBitArray& writetraps() const { return *myWriteTraps; } + DebuggerParser& parser() const { return *myParser; } + PackedBitArray& breakpoints() const { return *myBreakPoints; } + PackedBitArray& readtraps() const { return *myReadTraps; } + PackedBitArray& writetraps() const { return *myWriteTraps; } + PromptWidget& prompt() const { return myDialog->prompt(); } + RomWidget& rom() const { return myDialog->rom(); } /** Run the debugger command and return the result. @@ -240,8 +246,6 @@ class Debugger : public DialogContainer void setBreakPoint(int bp, bool set); - string saveROM(const string& filename) const; - bool setBank(int bank); bool patchROM(int addr, int value); @@ -294,9 +298,6 @@ class Debugger : public DialogContainer void reset(); void clearAllBreakPoints(); - PromptWidget& prompt() { return myDialog->prompt(); } - RomWidget& rom() { return myDialog->rom(); }; - void saveState(int state); void loadState(int state); diff --git a/src/debugger/DebuggerParser.cxx b/src/debugger/DebuggerParser.cxx index 0d8bd7cf3..b800b2998 100644 --- a/src/debugger/DebuggerParser.cxx +++ b/src/debugger/DebuggerParser.cxx @@ -1152,12 +1152,7 @@ void DebuggerParser::executeListtraps() // "loadconfig" void DebuggerParser::executeLoadconfig() { - if(argCount == 1) - commandResult << debugger.cartDebug().loadConfigFile(argStrings[0]); - else - commandResult << debugger.cartDebug().loadConfigFile(); - - debugger.rom().invalidate(); + commandResult << debugger.cartDebug().loadConfigFile(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1174,8 +1169,7 @@ void DebuggerParser::executeLoadstate() // "loadsym" void DebuggerParser::executeLoadsym() { - commandResult << debugger.cartDebug().loadSymbolFile(argStrings[0]); - debugger.rom().invalidate(); + commandResult << debugger.cartDebug().loadSymbolFile(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1416,31 +1410,21 @@ void DebuggerParser::executeSave() // "saveconfig" void DebuggerParser::executeSaveconfig() { - if(argCount == 1) - commandResult << debugger.cartDebug().saveConfigFile(argStrings[0]); - else - commandResult << debugger.cartDebug().saveConfigFile(); + commandResult << debugger.cartDebug().saveConfigFile(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // "savedis" void DebuggerParser::executeSavedisassembly() { - if(argCount == 1) - commandResult << debugger.cartDebug().saveDisassembly(argStrings[0]); - else - commandResult << debugger.cartDebug().saveDisassembly(); + commandResult << debugger.cartDebug().saveDisassembly(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // "saverom" void DebuggerParser::executeSaverom() { - const string& result = debugger.saveROM(argStrings[0]); - if(result != "") - commandResult << "saved ROM as " << result; - else - commandResult << red("failed to save ROM"); + commandResult << debugger.cartDebug().saveRom(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1917,10 +1901,10 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "loadconfig", - "Load Distella config file [from file xx]", + "Load Distella config file", false, true, - { kARG_FILE, kARG_MULTI_BYTE }, + { kARG_END_ARGS }, &DebuggerParser::executeLoadconfig }, @@ -1935,10 +1919,10 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "loadsym", - "Load symbol file named xx", + "Load symbol file", + false, true, - true, - { kARG_FILE, kARG_END_ARGS }, + { kARG_END_ARGS }, &DebuggerParser::executeLoadsym }, @@ -2079,28 +2063,28 @@ DebuggerParser::Command DebuggerParser::commands[kNumCommands] = { { "saveconfig", - "Save Distella config file [to file xx]", + "Save Distella config file", false, false, - { kARG_FILE, kARG_MULTI_BYTE }, + { kARG_END_ARGS }, &DebuggerParser::executeSaveconfig }, { "savedis", - "Save Distella disassembly [to file xx]", + "Save Distella disassembly", false, false, - { kARG_FILE, kARG_MULTI_BYTE }, + { kARG_END_ARGS }, &DebuggerParser::executeSavedisassembly }, { "saverom", - "Save (possibly patched) ROM to file xx", - true, + "Save (possibly patched) ROM", false, - { kARG_FILE, kARG_END_ARGS }, + false, + { kARG_END_ARGS }, &DebuggerParser::executeSaverom }, diff --git a/src/emucore/FSNode.cxx b/src/emucore/FSNode.cxx index 19ee3566a..766c25e59 100644 --- a/src/emucore/FSNode.cxx +++ b/src/emucore/FSNode.cxx @@ -135,12 +135,6 @@ bool FilesystemNode::isWritable() const return _realNode ? _realNode->isWritable() : false; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool FilesystemNode::isAbsolute() const -{ - return _realNode ? _realNode->isAbsolute() : false; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FilesystemNode::makeDir() { @@ -184,30 +178,3 @@ uInt32 FilesystemNode::read(uInt8*& image) const else throw "ZLIB open/read error"; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string FilesystemNode::createAbsolutePath( - const string& p, const string& startpath, const string& ext) -{ - FilesystemNode node(p); - string path = node.getShortPath(); - - // Is path already absolute, or does it start with the given startpath? - // If not, we prepend the given startpath - if(!BSPF_startsWithIgnoreCase(p, startpath+BSPF_PATH_SEPARATOR) && - !node.isAbsolute()) - path = startpath + BSPF_PATH_SEPARATOR + p; - - // Does the path have a valid extension? - // If not, we append the given extension - string::size_type idx = path.find_last_of('.'); - if(idx != string::npos) - { - if(!BSPF_equalsIgnoreCase(path.c_str() + idx + 1, ext)) - path = path.replace(idx+1, ext.length(), ext); - } - else - path += "." + ext; - - return path; -} diff --git a/src/emucore/FSNode.hxx b/src/emucore/FSNode.hxx index c1dc3c87a..426c0c1a3 100644 --- a/src/emucore/FSNode.hxx +++ b/src/emucore/FSNode.hxx @@ -213,13 +213,6 @@ class FilesystemNode */ virtual bool isWritable() const; - /** - * Indicates whether the path is a fully-qualified, absolute pathname. - * - * @return bool true if the object contains an absolute path, false otherwise. - */ - virtual bool isAbsolute() const; - /** * Create a directory from the current node path. * @@ -246,15 +239,6 @@ class FilesystemNode */ virtual uInt32 read(uInt8*& buffer) const; - // TODO - this function is deprecated, and will be removed soon ... - /** - Create an absolute pathname from the given path (if it isn't already - absolute), pre-pending 'startpath' when necessary. If the path doesn't - have an extension matching 'ext', append it to the path. - */ - static string createAbsolutePath(const string& p, const string& startpath, - const string& ext); - private: Common::SharedPtr _realNode; FilesystemNode(AbstractFSNode* realNode); @@ -363,13 +347,6 @@ class AbstractFSNode */ virtual bool isWritable() const = 0; - /** - * Indicates whether the path is a fully-qualified, absolute pathname. - * - * @return bool true if the object contains an absolute path, false otherwise. - */ - virtual bool isAbsolute() const = 0; - /** * Create a directory from the current node path. * diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index f9587f85b..4e6a8cd6e 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -724,12 +724,11 @@ Console* OSystem::openConsole(const FilesystemNode& romfile, string& md5, // and that the md5 (and hence the cart) has changed if(props.get(Cartridge_MD5) != cartmd5) { - const string& name = props.get(Cartridge_Name); if(!myPropSet->getMD5(cartmd5, props)) { // Cart md5 wasn't found, so we create a new props for it props.set(Cartridge_MD5, cartmd5); - props.set(Cartridge_Name, name+id); + props.set(Cartridge_Name, props.get(Cartridge_Name)+id); myPropSet->insert(props, false); } } diff --git a/src/emucore/PropsSet.cxx b/src/emucore/PropsSet.cxx index a52402c1f..6ce761f3c 100644 --- a/src/emucore/PropsSet.cxx +++ b/src/emucore/PropsSet.cxx @@ -153,13 +153,20 @@ void PropertiesSet::getMD5WithInsert(const FilesystemNode& rom, { if(!getMD5(md5, properties)) { - // Create a name suitable for using in properties - size_t pos = rom.getName().find_last_of("/\\"); - const string& name = pos == string::npos ? rom.getName() : - rom.getName().substr(pos+1); - properties.set(Cartridge_MD5, md5); - properties.set(Cartridge_Name, name); + + // Create a name suitable for using in properties + const string& filename = rom.getName(); + 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); + insert(properties, false); } } diff --git a/src/gui/BrowserDialog.cxx b/src/gui/BrowserDialog.cxx index 840321326..38c696d79 100644 --- a/src/gui/BrowserDialog.cxx +++ b/src/gui/BrowserDialog.cxx @@ -123,7 +123,8 @@ BrowserDialog::~BrowserDialog() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void BrowserDialog::show(const string& title, const string& startpath, - BrowserDialog::ListMode mode, int cmd) + BrowserDialog::ListMode mode, int cmd, + const string& ext) { _title->setLabel(title); _cmd = cmd; @@ -131,13 +132,15 @@ void BrowserDialog::show(const string& title, const string& startpath, switch(_mode) { - case FileLoad: + case FileLoad: _fileList->setFileListMode(FilesystemNode::kListAll); + _fileList->setFileExtension(ext); _selected->setEditable(false); break; case FileSave: _fileList->setFileListMode(FilesystemNode::kListAll); + _fileList->setFileExtension(ext); _selected->setEditable(false); // FIXME - disable user input for now break; @@ -191,6 +194,7 @@ void BrowserDialog::handleCommand(CommandSender* sender, int cmd, switch (cmd) { case kChooseCmd: + case FileListWidget::ItemActivated: // Send a signal to the calling class that a selection has been made // Since we aren't derived from a widget, we don't have a 'data' or 'id' if(_cmd) sendCommand(_cmd, -1, -1); @@ -206,7 +210,6 @@ void BrowserDialog::handleCommand(CommandSender* sender, int cmd, break; case FileListWidget::ItemChanged: - case FileListWidget::ItemActivated: updateUI(); break; diff --git a/src/gui/BrowserDialog.hxx b/src/gui/BrowserDialog.hxx index bc80afdb7..a8bc6ab91 100644 --- a/src/gui/BrowserDialog.hxx +++ b/src/gui/BrowserDialog.hxx @@ -49,7 +49,7 @@ class BrowserDialog : public Dialog, public CommandSender /** Place the browser window onscreen, using the given attributes */ void show(const string& title, const string& startpath, - BrowserDialog::ListMode mode, int cmd); + BrowserDialog::ListMode mode, int cmd, const string& ext = ""); /** Get resulting file node (called after receiving kChooseCmd) */ const FilesystemNode& getResult() const; diff --git a/src/gui/FileListWidget.cxx b/src/gui/FileListWidget.cxx index e8af12c65..285870305 100644 --- a/src/gui/FileListWidget.cxx +++ b/src/gui/FileListWidget.cxx @@ -26,7 +26,8 @@ FileListWidget::FileListWidget(GuiObject* boss, const GUI::Font& font, int x, int y, int w, int h) : StringListWidget(boss, font, x, y, w, h), - _fsmode(FilesystemNode::kListAll) + _fsmode(FilesystemNode::kListAll), + _extension("") { // This widget is special, in that it catches signals and redirects them setTarget(this); @@ -68,6 +69,8 @@ void FileListWidget::setLocation(const FilesystemNode& node, string select) bool isDir = content[idx].isDirectory(); if(isDir) name = " [" + name + "]"; + else if(!BSPF_endsWithIgnoreCase(name, _extension)) + continue; _gameList.appendGame(name, content[idx].getPath(), "", isDir); } @@ -110,14 +113,17 @@ void FileListWidget::handleCommand(CommandSender* sender, int cmd, int data, int case ListWidget::kActivatedCmd: case ListWidget::kDoubleClickedCmd: - cmd = ItemActivated; if(_gameList.isDir(data)) { + cmd = ItemChanged; if(_gameList.name(data) == " [..]") selectParent(); else setLocation(FilesystemNode(_gameList.path(data))); } + else + cmd = ItemActivated; + break; default: diff --git a/src/gui/FileListWidget.hxx b/src/gui/FileListWidget.hxx index e41ac4253..c083f6cf1 100644 --- a/src/gui/FileListWidget.hxx +++ b/src/gui/FileListWidget.hxx @@ -53,6 +53,7 @@ class FileListWidget : public StringListWidget /** Determines how to display files/folders */ void setFileListMode(FilesystemNode::ListMode mode) { _fsmode = mode; } + void setFileExtension(const string& ext) { _extension = ext; } /** Set current location (file or directory) */ void setLocation(const FilesystemNode& node, string select = ""); @@ -70,6 +71,7 @@ class FileListWidget : public StringListWidget private: FilesystemNode::ListMode _fsmode; FilesystemNode _node, _selected; + string _extension; GameList _gameList; }; diff --git a/src/gui/FileSnapDialog.cxx b/src/gui/FileSnapDialog.cxx index 6568e8ac5..ec86578eb 100644 --- a/src/gui/FileSnapDialog.cxx +++ b/src/gui/FileSnapDialog.cxx @@ -327,57 +327,49 @@ void FileSnapDialog::handleCommand(CommandSender* sender, int cmd, case kRomDirChosenCmd: { - FilesystemNode dir(myBrowser->getResult()); - myRomPath->setEditString(dir.getShortPath()); + myRomPath->setEditString(myBrowser->getResult().getShortPath()); break; } case kSnapSaveDirChosenCmd: { - FilesystemNode dir(myBrowser->getResult()); - mySnapSavePath->setEditString(dir.getShortPath()); + mySnapSavePath->setEditString(myBrowser->getResult().getShortPath()); break; } case kSnapLoadDirChosenCmd: { - FilesystemNode dir(myBrowser->getResult()); - mySnapLoadPath->setEditString(dir.getShortPath()); + mySnapLoadPath->setEditString(myBrowser->getResult().getShortPath()); break; } case kCheatFileChosenCmd: { - FilesystemNode dir(myBrowser->getResult()); - myCheatFile->setEditString(dir.getShortPath()); + myCheatFile->setEditString(myBrowser->getResult().getShortPath()); break; } case kPaletteFileChosenCmd: { - FilesystemNode dir(myBrowser->getResult()); - myPaletteFile->setEditString(dir.getShortPath()); + myPaletteFile->setEditString(myBrowser->getResult().getShortPath()); break; } case kPropsFileChosenCmd: { - FilesystemNode dir(myBrowser->getResult()); - myPropsFile->setEditString(dir.getShortPath()); + myPropsFile->setEditString(myBrowser->getResult().getShortPath()); break; } case kNVRamDirChosenCmd: { - FilesystemNode dir(myBrowser->getResult()); - myNVRamPath->setEditString(dir.getShortPath()); + myNVRamPath->setEditString(myBrowser->getResult().getShortPath()); break; } case kStateDirChosenCmd: { - FilesystemNode dir(myBrowser->getResult()); - myStatePath->setEditString(dir.getShortPath()); + myStatePath->setEditString(myBrowser->getResult().getShortPath()); break; } diff --git a/src/unix/FSNodePOSIX.cxx b/src/unix/FSNodePOSIX.cxx index 0a9e05388..f29b07598 100644 --- a/src/unix/FSNodePOSIX.cxx +++ b/src/unix/FSNodePOSIX.cxx @@ -205,12 +205,6 @@ bool FilesystemNodePOSIX::getChildren(AbstractFSList& myList, ListMode mode, return true; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool FilesystemNodePOSIX::isAbsolute() const -{ - return _path.length() > 0 && (_path[0] == '~' || _path[0] == '/'); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FilesystemNodePOSIX::makeDir() { diff --git a/src/unix/FSNodePOSIX.hxx b/src/unix/FSNodePOSIX.hxx index 898d8cf1e..f26d2a358 100644 --- a/src/unix/FSNodePOSIX.hxx +++ b/src/unix/FSNodePOSIX.hxx @@ -75,7 +75,6 @@ class FilesystemNodePOSIX : public AbstractFSNode bool isFile() const { return _isFile; } bool isReadable() const { return access(_path.c_str(), R_OK) == 0; } bool isWritable() const { return access(_path.c_str(), W_OK) == 0; } - bool isAbsolute() const; bool makeDir(); bool rename(const string& newfile); diff --git a/src/win32/FSNodeWin32.cxx b/src/win32/FSNodeWin32.cxx index 09f9d0874..ab2d92150 100644 --- a/src/win32/FSNodeWin32.cxx +++ b/src/win32/FSNodeWin32.cxx @@ -283,12 +283,6 @@ bool FilesystemNodeWin32:: return true; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool FilesystemNodeWin32::isAbsolute() const -{ - return _path.length() >= 2 && (_path[0] == '~' || _path[1] == ':'); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FilesystemNodeWin32::makeDir() { diff --git a/src/win32/FSNodeWin32.hxx b/src/win32/FSNodeWin32.hxx index 2c1d83c32..3e62e5a15 100644 --- a/src/win32/FSNodeWin32.hxx +++ b/src/win32/FSNodeWin32.hxx @@ -70,7 +70,6 @@ class FilesystemNodeWin32 : public AbstractFSNode bool isFile() const { return _isFile; } bool isReadable() const; bool isWritable() const; - bool isAbsolute() const; bool makeDir(); bool rename(const string& newfile);