diff --git a/docs/graphics/launcher.png b/docs/graphics/launcher.png index 86f1318cd..440592116 100644 Binary files a/docs/graphics/launcher.png and b/docs/graphics/launcher.png differ diff --git a/docs/graphics/rom_browser.png b/docs/graphics/rom_browser.png index 3fca4021e..2139b1196 100644 Binary files a/docs/graphics/rom_browser.png and b/docs/graphics/rom_browser.png differ diff --git a/docs/graphics/romaudit.png b/docs/graphics/romaudit.png index 7aa89eaaa..f4f3a370e 100644 Binary files a/docs/graphics/romaudit.png and b/docs/graphics/romaudit.png differ diff --git a/docs/index.html b/docs/index.html index 9881630af..a7a46c691 100644 --- a/docs/index.html +++ b/docs/index.html @@ -559,10 +559,14 @@ but for Windows it means your 'My Documents' folder.
Selecting a new path for an item is done by clicking the appropriate button(s) - (in this case, 'Rom path' was selected). Note that although the rom path - was '~/src/stella', it expands to '/home/stephena/src/stella' in the browser:
+ (in this case, 'Rom path' was selected), which will show a browser as follows: +The browser should be self-explanatory. The 'Go Up' button moves to the parent + folder (if it exists), and the 'Base Dir' button moves to the base directory where, + by default, all Stella-related files are stored. Click 'Choose' to select an item, + or 'Cancel' to exit the browser.
+Once you've changed your settings, you can start emulation by selecting a ROM and pressing 'Enter' or clicking 'Select', or double-clicking a ROM. Note that some games require you to 'Reset' the console before you start playing. In this diff --git a/src/emucore/FSNode.cxx b/src/emucore/FSNode.cxx index 367185fbb..a6cf6feb7 100644 --- a/src/emucore/FSNode.cxx +++ b/src/emucore/FSNode.cxx @@ -129,6 +129,13 @@ string FilesystemNode::getPath() const return _realNode->getPath(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string FilesystemNode::getRelativePath() const +{ + assert(_realNode); + return _realNode->getRelativePath(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FilesystemNode::isDirectory() const { diff --git a/src/emucore/FSNode.hxx b/src/emucore/FSNode.hxx index cdb1147f2..b7bc9f6fb 100644 --- a/src/emucore/FSNode.hxx +++ b/src/emucore/FSNode.hxx @@ -165,8 +165,7 @@ class FilesystemNode virtual string getName() const; /** - * Return a string representation of the file which can be passed to fopen(), - * and is suitable for archiving (i.e. writing to the config file). + * Return a string representation of the file which can be passed to fopen(). * This will usually be a 'path' (hence the name of the method), but can * be anything that fulfills the above criterions. * @@ -177,6 +176,18 @@ class FilesystemNode */ virtual string getPath() const; + /** + * Return a string representation of the file which contains the '~' + * symbol (if applicable), and is suitable for archiving (i.e. writing + * to the config file). + * + * @note Do not assume that this string contains (back)slashes or any + * other kind of 'path separators'. + * + * @return the 'path' represented by this filesystem node + */ + virtual string getRelativePath() const; + /** * Determine whether this node has a parent. */ @@ -294,6 +305,11 @@ class AbstractFilesystemNode */ virtual string getPath() const = 0; + /** + * Returns the 'path' of the current node, containing '~' and for archiving. + */ + virtual string getRelativePath() const = 0; + /** * Indicates whether this path refers to a directory or not. */ diff --git a/src/gui/BrowserDialog.cxx b/src/gui/BrowserDialog.cxx index 3fb96a22f..aa9cdd96d 100644 --- a/src/gui/BrowserDialog.cxx +++ b/src/gui/BrowserDialog.cxx @@ -81,6 +81,11 @@ BrowserDialog::BrowserDialog(GuiObject* boss, const GUI::Font& font) buttonWidth, buttonHeight, "Go up", kGoUpCmd); addFocusWidget(_goUpButton); + _basedirButton = + new ButtonWidget(this, font, 15 + buttonWidth, _h - buttonHeight - 10, + buttonWidth, buttonHeight, "Base Dir", kBaseDirCmd); + addFocusWidget(_basedirButton); + #ifndef MAC_OSX b = new ButtonWidget(this, font, _w - 2 * (buttonWidth + 7), _h - buttonHeight - 10, buttonWidth, buttonHeight, "Choose", kChooseCmd); @@ -157,7 +162,7 @@ void BrowserDialog::updateListing() _nodeList->clear(); // Update the path display - _currentPath->setLabel(_node.getPath()); + _currentPath->setLabel(_node.getRelativePath()); // Read in the data from the file system FSList content; @@ -210,6 +215,11 @@ void BrowserDialog::handleCommand(CommandSender* sender, int cmd, updateListing(); break; + case kBaseDirCmd: + _node = FilesystemNode(instance().baseDir(false)); + updateListing(); + break; + case kListItemActivatedCmd: case kListItemDoubleClickedCmd: { diff --git a/src/gui/BrowserDialog.hxx b/src/gui/BrowserDialog.hxx index 3f6f582f4..757120e82 100644 --- a/src/gui/BrowserDialog.hxx +++ b/src/gui/BrowserDialog.hxx @@ -51,8 +51,9 @@ class BrowserDialog : public Dialog, public CommandSender private: enum { - kChooseCmd = 'CHOS', - kGoUpCmd = 'GOUP' + kChooseCmd = 'CHOS', + kGoUpCmd = 'GOUP', + kBaseDirCmd = 'BADR' }; int _cmd; @@ -61,6 +62,7 @@ class BrowserDialog : public Dialog, public CommandSender StaticTextWidget* _currentPath; StaticTextWidget* _title; ButtonWidget* _goUpButton; + ButtonWidget* _basedirButton; FilesystemNode _node; GameList* _nodeList; diff --git a/src/gui/FileSnapDialog.cxx b/src/gui/FileSnapDialog.cxx index 81dde1345..0ad49c8f0 100644 --- a/src/gui/FileSnapDialog.cxx +++ b/src/gui/FileSnapDialog.cxx @@ -273,49 +273,49 @@ void FileSnapDialog::handleCommand(CommandSender* sender, int cmd, case kRomDirChosenCmd: { FilesystemNode dir(myBrowser->getResult()); - myRomPath->setEditString(dir.getPath()); + myRomPath->setEditString(dir.getRelativePath()); break; } case kStateDirChosenCmd: { FilesystemNode dir(myBrowser->getResult()); - myStatePath->setEditString(dir.getPath()); + myStatePath->setEditString(dir.getRelativePath()); break; } case kCheatFileChosenCmd: { FilesystemNode dir(myBrowser->getResult()); - myCheatFile->setEditString(dir.getPath()); + myCheatFile->setEditString(dir.getRelativePath()); break; } case kPaletteFileChosenCmd: { FilesystemNode dir(myBrowser->getResult()); - myPaletteFile->setEditString(dir.getPath()); + myPaletteFile->setEditString(dir.getRelativePath()); break; } case kPropsFileChosenCmd: { FilesystemNode dir(myBrowser->getResult()); - myPropsFile->setEditString(dir.getPath()); + myPropsFile->setEditString(dir.getRelativePath()); break; } case kSnapDirChosenCmd: { FilesystemNode dir(myBrowser->getResult()); - mySnapPath->setEditString(dir.getPath()); + mySnapPath->setEditString(dir.getRelativePath()); break; } case kEEPROMDirChosenCmd: { FilesystemNode dir(myBrowser->getResult()); - myEEPROMPath->setEditString(dir.getPath()); + myEEPROMPath->setEditString(dir.getRelativePath()); break; } diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index dfaf2334e..521d5ea87 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -266,7 +266,7 @@ void LauncherDialog::updateListing() myPrevDirButton->setEnabled(myCurrentNode.hasParent()); // Show current directory - myDir->setLabel(myCurrentNode.getPath()); + myDir->setLabel(myCurrentNode.getRelativePath()); // Now fill the list widget with the contents of the GameList StringList l; diff --git a/src/unix/FSNodePOSIX.cxx b/src/unix/FSNodePOSIX.cxx index 7eef8a0b5..7d562b441 100644 --- a/src/unix/FSNodePOSIX.cxx +++ b/src/unix/FSNodePOSIX.cxx @@ -61,6 +61,7 @@ class POSIXFilesystemNode : public AbstractFilesystemNode virtual string getDisplayName() const { return _displayName; } virtual string getName() const { return _displayName; } virtual string getPath() const { return _path; } + virtual string getRelativePath() const; virtual bool isDirectory() const { return _isDirectory; } virtual bool isReadable() const { return access(_path.c_str(), R_OK) == 0; } virtual bool isWritable() const { return access(_path.c_str(), W_OK) == 0; } @@ -135,7 +136,7 @@ POSIXFilesystemNode::POSIXFilesystemNode(const string& p, bool verify) if (home != NULL && strlen(home) < MAXPATHLEN) { _path = home; - // Skip over the tilda. We know that p contains at least + // Skip over the tilde. We know that p contains at least // two chars, so this is safe: _path += p.c_str() + 1; } @@ -162,6 +163,26 @@ POSIXFilesystemNode::POSIXFilesystemNode(const string& p, bool verify) setFlags(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string POSIXFilesystemNode::getRelativePath() const +{ + // If the path starts with the home directory, replace it with '~' + const char* home = getenv("HOME"); + if(home != NULL) + { + int len = strlen(home); + if(strncmp(_path.c_str(), home, len) == 0) + { + string path = "~"; + const char* offset = _path.c_str() + len; + if(*offset != '/') path += "/"; + path += offset; + return path; + } + } + return _path; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool POSIXFilesystemNode::getChildren(AbstractFSList& myList, ListMode mode, bool hidden) const diff --git a/src/win32/FSNodeWin32.cxx b/src/win32/FSNodeWin32.cxx index 92074dbb6..45e5cb0f8 100644 --- a/src/win32/FSNodeWin32.cxx +++ b/src/win32/FSNodeWin32.cxx @@ -139,6 +139,7 @@ class WindowsFilesystemNode : public AbstractFilesystemNode virtual string getDisplayName() const { return _displayName; } virtual string getName() const { return _displayName; } virtual string getPath() const { return _path; } + virtual string getRelativePath() const; virtual bool isDirectory() const { return _isDirectory; } virtual bool isReadable() const { return _access(_path.c_str(), R_OK) == 0; } virtual bool isWritable() const { return _access(_path.c_str(), W_OK) == 0; } @@ -328,6 +329,27 @@ WindowsFilesystemNode::WindowsFilesystemNode(const string& p) _isPseudoRoot = false; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string WindowsFilesystemNode::getRelativePath() const +{ + // If the path starts with the home directory, replace it with '~' + const string& home = myDocsFinder.getPath(); + if(home != "") + { + // Windows file system not case sensitive + int len = home.length(); + if(BSPF_strncasecmp(home.c_str(), _path.substr(0, len).c_str()) == 0) + { + string path = "~"; + const char* offset = _path.c_str() + len; + if(*offset != '\\') path += '\\'; + path += offset; + return path; + } + } + return _path; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool WindowsFilesystemNode:: getChildren(AbstractFSList& myList, ListMode mode, bool hidden) const