Some cleanup of dead code, and changes to the file I/O in the debugger.

For now (and the next release), filenames are hardcoded to sane defaults.
Eventually, the code may be extended to use BrowserDialog to query the names,
but it's taking much too long to get working, and I want to get a new release
done before the end of May.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2734 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2013-05-16 19:11:44 +00:00
parent 89e36662fe
commit f533fcad34
19 changed files with 260 additions and 348 deletions

View File

@ -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

View File

@ -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<BankInfo>::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<BankInfo>::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)
{

View File

@ -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

View File

@ -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()
{

View File

@ -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);

View File

@ -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
},

View File

@ -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;
}

View File

@ -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<AbstractFSNode> _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.
*

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
@ -133,11 +134,13 @@ void BrowserDialog::show(const string& title, const string& startpath,
{
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;

View File

@ -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;

View File

@ -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:

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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()
{

View File

@ -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);

View File

@ -283,12 +283,6 @@ bool FilesystemNodeWin32::
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FilesystemNodeWin32::isAbsolute() const
{
return _path.length() >= 2 && (_path[0] == '~' || _path[1] == ':');
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FilesystemNodeWin32::makeDir()
{

View File

@ -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);