diff options
Diffstat (limited to 'backends')
46 files changed, 1719 insertions, 1922 deletions
diff --git a/backends/fs/abstract-fs-factory.h b/backends/fs/abstract-fs-factory.h new file mode 100644 index 0000000000..41bfaaa34b --- /dev/null +++ b/backends/fs/abstract-fs-factory.h @@ -0,0 +1,48 @@ +#ifndef ABSTRACT_FILESYSTEM_FACTORY_H +#define ABSTRACT_FILESYSTEM_FACTORY_H + +#include "common/str.h" + +/** + * Creates concrete FilesystemNode objects depending on the current architecture. + */ +class AbstractFilesystemFactory { +public: + typedef Common::String String; + + /** + * Destructor. + */ + virtual ~AbstractFilesystemFactory() {}; + + /** + * Returns a node representing the "current directory". + * If your system does not support this concept, you can either try to + * emulate it or simply return some "sensible" default directory node, + * e.g. the same value as getRoot() returns. + */ + virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const = 0; + + /** + * Construct a node based on a path; the path is in the same format as it + * would be for calls to fopen(). + * + * Furthermore getNodeForPath(oldNode.path()) should create a new node + * identical to oldNode. Hence, we can use the "path" value for persistent + * storage e.g. in the config file. + * + * @param path The path string to create a FilesystemNode for. + */ + virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const = 0; + + /** + * Returns a special node representing the filesystem root. + * The starting point for any file system browsing. + * + * On Unix, this will be simply the node for / (the root directory). + * On Windows, it will be a special node which "contains" all drives (C:, D:, E:). + */ + virtual AbstractFilesystemNode *makeRootFileNode() const = 0; +}; + +#endif /*ABSTRACT_FILESYSTEM_FACTORY_H*/ diff --git a/backends/fs/abstract-fs.h b/backends/fs/abstract-fs.h index 09b08cfe60..371c38a495 100644 --- a/backends/fs/abstract-fs.h +++ b/backends/fs/abstract-fs.h @@ -27,7 +27,6 @@ #include "common/array.h" #include "common/str.h" - #include "common/fs.h" class AbstractFilesystemNode; @@ -49,86 +48,88 @@ protected: typedef FilesystemNode::ListMode ListMode; /** - * The parent node of this directory. - * The parent of the root is the root itself. - */ - virtual AbstractFilesystemNode *parent() const = 0; - - /** - * The child node with the given name. If no child with this name + * Returns the child node with the given name. If no child with this name * exists, returns 0. When called on a non-directory node, it should * handle this gracefully by returning 0. * + * Example: + * Calling getChild() for a node with path "/foo/bar" using name="file.txt", + * would produce a new node with "/foo/bar/file.txt" as path. + * + * @note This function will append a separator char (\ or /) to the end of the + * path if needed. + * * @note Handling calls on non-dir nodes gracefully makes it possible to * switch to a lazy type detection scheme in the future. + * + * @param name String containing the name of the child to create a new node. */ - virtual AbstractFilesystemNode *child(const String &name) const = 0; - + virtual AbstractFilesystemNode *getChild(const String &name) const = 0; /** - * Returns a special node representing the FS root. The starting point for - * any file system browsing. - * On Unix, this will be simply the node for / (the root directory). - * On Windows, it will be a special node which "contains" all drives (C:, D:, E:). + * The parent node of this directory. + * The parent of the root is the root itself. */ - static AbstractFilesystemNode *getRoot(); + virtual AbstractFilesystemNode *getParent() const = 0; +public: /** - * Returns a node representing the "current directory". If your system does - * not support this concept, you can either try to emulate it or - * simply return some "sensible" default directory node, e.g. the same - * value as getRoot() returns. + * Destructor. */ - static AbstractFilesystemNode *getCurrentDirectory(); + virtual ~AbstractFilesystemNode() {} + /* + * Indicates whether the object refered by this path exists in the filesystem or not. + */ + virtual bool exists() const = 0; /** - * Construct a node based on a path; the path is in the same format as it - * would be for calls to fopen(). - * - * Furthermore getNodeForPath(oldNode.path()) should create a new node - * identical to oldNode. Hence, we can use the "path" value for persistent - * storage e.g. in the config file. - * - * @todo: This is of course a place where non-portable code easily will sneak - * in, because the format of the path used here is not well-defined. - * So we really should reconsider this API and try to come up with - * something which is more portable but still flexible enough for our - * purposes. + * Return a list of child nodes of this directory node. If called on a node + * that does not represent a directory, false is returned. + * + * @param list List to put the contents of the directory in. + * @param mode Mode to use while listing the directory. + * @param hidden Whether to include hidden files or not in the results. + * + * @return true if succesful, false otherwise (e.g. when the directory does not exist). */ - static AbstractFilesystemNode *getNodeForPath(const String &path); + virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const = 0; + /** + * Returns a human readable path string. + * + * @note By default, this method returns the value of getName(). + */ + virtual String getDisplayName() const { return getName(); } -public: - virtual ~AbstractFilesystemNode() {} - - virtual String name() const = 0; + /** + * Returns a string with an architecture dependent path description. + */ + virtual String getName() const = 0; - // By default, we use the actual file name as 'display name'. - virtual String displayName() const { return name(); } - - virtual bool isValid() const = 0; - + /** + * Returns the 'path' of the current node, usable in fopen(). + */ + virtual String getPath() const = 0; + + /** + * Indicates whether this path refers to a directory or not. + */ virtual bool isDirectory() const = 0; /** - * Return the 'path' of the current node, usable in fopen(). See also - * the static getNodeForPath() method. + * Indicates whether this path can be read from or not. */ - virtual String path() const = 0; - virtual bool listDir(AbstractFSList &list, ListMode mode) const = 0; - + virtual bool isReadable() const = 0; + + /** + * Indicates whether this path can be written to or not. + */ + virtual bool isWritable() const = 0; /* TODO: - bool exists(); - - bool isDirectory(); bool isFile(); - - bool isReadable(); - bool isWriteable(); */ }; - #endif diff --git a/backends/fs/amigaos4/amigaos4-fs-factory.cpp b/backends/fs/amigaos4/amigaos4-fs-factory.cpp new file mode 100644 index 0000000000..becbd49003 --- /dev/null +++ b/backends/fs/amigaos4/amigaos4-fs-factory.cpp @@ -0,0 +1,16 @@ +#include "backends/fs/amigaos4/amigaos4-fs-factory.h" +#include "backends/fs/amigaos4/amigaos4-fs.cpp" + +DECLARE_SINGLETON(AmigaOSFilesystemFactory); + +AbstractFilesystemNode *AmigaOSFilesystemFactory::makeRootFileNode() const { + return new AmigaOSFilesystemNode(); +} + +AbstractFilesystemNode *AmigaOSFilesystemFactory::makeCurrentDirectoryFileNode() const { + return new AmigaOSFilesystemNode(); +} + +AbstractFilesystemNode *AmigaOSFilesystemFactory::makeFileNodePath(const String &path) const { + return new AmigaOSFilesystemNode(path); +} diff --git a/backends/fs/amigaos4/amigaos4-fs-factory.h b/backends/fs/amigaos4/amigaos4-fs-factory.h new file mode 100644 index 0000000000..ed8af24648 --- /dev/null +++ b/backends/fs/amigaos4/amigaos4-fs-factory.h @@ -0,0 +1,27 @@ +#ifndef AMIGAOS_FILESYSTEM_FACTORY_H +#define AMIGAOS_FILESYSTEM_FACTORY_H + +#include "common/singleton.h" +#include "backends/fs/abstract-fs-factory.h" + +/** + * Creates AmigaOSFilesystemNode objects. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemFactory. + */ +class AmigaOSFilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<AmigaOSFilesystemFactory> { +public: + typedef Common::String String; + + virtual AbstractFilesystemNode *makeRootFileNode() const; + virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const; + virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const; + +protected: + AmigaOSFilesystemFactory() {}; + +private: + friend class Common::Singleton<SingletonBaseType>; +}; + +#endif /*AMIGAOS_FILESYSTEM_FACTORY_H*/ diff --git a/backends/fs/amigaos4/amigaos4-fs.cpp b/backends/fs/amigaos4/amigaos4-fs.cpp index ffed8bc87c..88af467ae5 100644 --- a/backends/fs/amigaos4/amigaos4-fs.cpp +++ b/backends/fs/amigaos4/amigaos4-fs.cpp @@ -38,58 +38,76 @@ #include <common/stdafx.h> #include "common/util.h" - #include "engines/engine.h" #include "backends/fs/abstract-fs.h" #define ENTER() /* debug(6, "Enter") */ #define LEAVE() /* debug(6, "Leave") */ - const uint32 kExAllBufferSize = 40960; // TODO: is this okay for sure? +/** + * Implementation of the ScummVM file system API. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemNode. + */ class AmigaOSFilesystemNode : public AbstractFilesystemNode { - protected: - BPTR _pFileLock; - String _sDisplayName; - bool _bIsDirectory; - bool _bIsValid; - String _sPath; - - public: - AmigaOSFilesystemNode(); - AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayName = 0); - AmigaOSFilesystemNode(const String &p); - - // Note: Copy constructor is needed because it duplicates the file lock - AmigaOSFilesystemNode(const AmigaOSFilesystemNode &node); - - virtual ~AmigaOSFilesystemNode(); - - virtual String displayName() const { return _sDisplayName; }; - virtual String name() const { return _sDisplayName; }; - virtual bool isValid() const { return _bIsValid; }; - virtual bool isDirectory() const { return _bIsDirectory; }; - virtual String path() const { return _sPath; }; - - virtual bool listDir(AbstractFSList &list, ListMode mode) const; - virtual AbstractFSList listVolumes() const; - virtual AbstractFilesystemNode *parent() const; - virtual AbstractFilesystemNode *child(const String &n) const; +protected: + BPTR _pFileLock; + String _sDisplayName; + String _sPath; + bool _bIsDirectory; + bool _bIsValid; + +public: + /** + * Creates a AmigaOSFilesystemNode with the root node as path. + */ + AmigaOSFilesystemNode(); + + /** + * Creates a AmigaOSFilesystemNode for a given path. + * + * @param path String with the path the new node should point to. + */ + AmigaOSFilesystemNode(const String &p); + + /** + * FIXME: document this constructor. + */ + AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayName = 0); + + /** + * Copy constructor. + * + * @note Needed because it duplicates the file lock + */ + AmigaOSFilesystemNode(const AmigaOSFilesystemNode &node); + + /** + * Destructor. + */ + virtual ~AmigaOSFilesystemNode(); + + virtual bool exists() const { return true; } //FIXME: this is just a stub + virtual String getDisplayName() const { return _sDisplayName; }; + virtual String getName() const { return _sDisplayName; }; + virtual String getPath() const { return _sPath; }; + virtual bool isDirectory() const { return _bIsDirectory; }; + virtual bool isReadable() const { return true; } //FIXME: this is just a stub + virtual bool isValid() const { return _bIsValid; }; + virtual bool isWritable() const { return true; } //FIXME: this is just a stub + + virtual AbstractFilesystemNode *getChild(const String &n) const; + virtual bool getChildren(AbstractFSList &list, ListMode mode) const; + virtual AbstractFilesystemNode *getParent() const; + + /** + * Creates a list with all the volumes present in the root node. + */ + virtual AbstractFSList listVolumes() const; }; -AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { - return AbstractFilesystemNode::getRoot(); -} - -AbstractFilesystemNode *AbstractFilesystemNode::getRoot() { - return new AmigaOSFilesystemNode(); -} - -AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) { - return new AmigaOSFilesystemNode(path); -} - AmigaOSFilesystemNode::AmigaOSFilesystemNode() { ENTER(); _sDisplayName = "Available Disks"; @@ -100,7 +118,6 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode() { LEAVE(); } - AmigaOSFilesystemNode::AmigaOSFilesystemNode(const String &p) { ENTER(); @@ -150,7 +167,6 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(const String &p) { const char c = _sPath.lastChar(); if (c != '/' && c != ':') _sPath += '/'; - } else { //_bIsDirectory = false; @@ -170,7 +186,7 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayNam int bufSize = MAXPATHLEN; _pFileLock = 0; - while (1) { + while (true) { char *n = new char[bufSize]; if (IDOS->NameFromLock(pLock, (STRPTR)n, bufSize) != DOSFALSE) { _sPath = n; @@ -186,6 +202,7 @@ AmigaOSFilesystemNode::AmigaOSFilesystemNode(BPTR pLock, const char *pDisplayNam delete [] n; return; } + bufSize *= 2; delete [] n; } @@ -238,7 +255,31 @@ AmigaOSFilesystemNode::~AmigaOSFilesystemNode() { LEAVE(); } -bool AmigaOSFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const { +AbstractFilesystemNode *AmigaOSFilesystemNode::getChild(const String &n) const { + if (!_bIsDirectory) { + debug(6, "Not a directory"); + return 0; + } + + String newPath(_sPath); + + if (_sPath.lastChar() != '/') + newPath += '/'; + + newPath += n; + BPTR lock = IDOS->Lock(newPath.c_str(), SHARED_LOCK); + + if (!lock) { + debug(6, "Bad path"); + return 0; + } + + IDOS->UnLock(lock); + + return new AmigaOSFilesystemNode(newPath); +} + +bool AmigaOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode) const { ENTER(); if (!_bIsValid) { @@ -308,10 +349,11 @@ bool AmigaOSFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const } LEAVE(); + return true; } -AbstractFilesystemNode *AmigaOSFilesystemNode::parent() const { +AbstractFilesystemNode *AmigaOSFilesystemNode::getParent() const { ENTER(); if (!_bIsDirectory) { @@ -337,33 +379,8 @@ AbstractFilesystemNode *AmigaOSFilesystemNode::parent() const { node = new AmigaOSFilesystemNode(); LEAVE(); - return node; -} - -AbstractFilesystemNode *AmigaOSFilesystemNode::child(const String &n) const { - if (!_bIsDirectory) { - debug(6, "Not a directory"); - return 0; - } - - String newPath(_sPath); - - if (_sPath.lastChar() != '/') - newPath += '/'; - - newPath += n; - - BPTR lock = IDOS->Lock(newPath.c_str(), SHARED_LOCK); - - if (!lock) { - debug(6, "Bad path"); - return 0; - } - - IDOS->UnLock(lock); - - return new AmigaOSFilesystemNode(newPath); + return node; } AbstractFSList AmigaOSFilesystemNode::listVolumes() const { @@ -431,7 +448,8 @@ AbstractFSList AmigaOSFilesystemNode::listVolumes() const { IDOS->UnLockDosList(kLockFlags); LEAVE(); + return myList; } -#endif +#endif //defined(__amigaos4__) diff --git a/backends/fs/dc/dc-fs.cpp b/backends/fs/dc/dc-fs.cpp index 010ca20276..070c9b075b 100644 --- a/backends/fs/dc/dc-fs.cpp +++ b/backends/fs/dc/dc-fs.cpp @@ -25,40 +25,62 @@ #if defined(__DC__) #include "common/stdafx.h" - #include "backends/fs/abstract-fs.h" #include <ronin/cdfs.h> #include <stdio.h> #include <unistd.h> -/* - * Implementation of the ScummVM file system API based on ronin. +/** + * Implementation of the ScummVM file system API based on POSIX. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemNode. */ - class RoninCDFilesystemNode : public AbstractFilesystemNode { protected: String _displayName; + String _path; bool _isDirectory; bool _isValid; - String _path; public: + /** + * Creates a RoninCDFilesystemNode with the root node as path. + */ RoninCDFilesystemNode(); + + /** + * Creates a RoninCDFilesystemNode for a given path. + * + * @param path String with the path the new node should point to. + * @param verify true if the isValid and isDirectory flags should be verified during the construction. + */ RoninCDFilesystemNode(const String &path, bool verify); - virtual String displayName() const { return _displayName; } - virtual String name() const { return _displayName; } - virtual bool isValid() const { return _isValid; } + virtual bool exists() const { return true; } //FIXME: this is just a stub + virtual String getDisplayName() const { return _displayName; } + virtual String getName() const { return _displayName; } + virtual String getPath() const { return _path; } virtual bool isDirectory() const { return _isDirectory; } - virtual String path() const { return _path; } + virtual bool isReadable() const { return true; } //FIXME: this is just a stub + virtual bool isValid() const { return _isValid; } + virtual bool isWritable() const { return true; } //FIXME: this is just a stub - virtual bool listDir(AbstractFSList &list, ListMode mode) const; - virtual AbstractFilesystemNode *parent() const; - virtual AbstractFilesystemNode *child(const String &n) const; + virtual AbstractFilesystemNode *getChild(const String &n) const; + virtual bool getChildren(AbstractFSList &list, ListMode mode) const; + virtual AbstractFilesystemNode *getParent() const; }; - +/** + * Returns the last component of a given path. + * + * Examples: + * /foo/bar.txt would return /bar.txt + * /foo/bar/ would return /bar/ + * + * @param str String containing the path. + * @return Pointer to the first char of the last component inside str. + */ static const char *lastPathComponent(const Common::String &str) { const char *start = str.c_str(); const char *cur = start + str.size() - 2; @@ -70,22 +92,6 @@ static const char *lastPathComponent(const Common::String &str) { return cur + 1; } - -AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { - // Since there is no way to _set_ the current directory, - // it will always be /... - - return getRoot(); -} - -AbstractFilesystemNode *AbstractFilesystemNode::getRoot() { - return new RoninCDFilesystemNode(); -} - -AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) { - return new RoninCDFilesystemNode(path, true); -} - RoninCDFilesystemNode::RoninCDFilesystemNode() { // The root dir. _path = "/"; @@ -118,10 +124,23 @@ RoninCDFilesystemNode::RoninCDFilesystemNode(const String &p, bool verify) { } } -bool RoninCDFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const { +AbstractFilesystemNode *RoninCDFilesystemNode::getChild(const String &n) const { + // FIXME: Pretty lame implementation! We do no error checking to speak + // of, do not check if this is a special node, etc. assert(_isDirectory); - DIR *dirp = opendir(_path.c_str()); + + String newPath(_path); + if (_path.lastChar() != '/') + newPath += '/'; + newPath += n; + + return new RoninCDFilesystemNode(newPath, true); +} +bool RoninCDFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode) const { + assert(_isDirectory); + + DIR *dirp = opendir(_path.c_str()); struct dirent *dp; if (dirp == NULL) @@ -150,35 +169,22 @@ bool RoninCDFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const if (entry._isDirectory) entry._path += "/"; + myList.push_back(new RoninCDFilesystemNode(entry)); } closedir(dirp); + return true; } -AbstractFilesystemNode *RoninCDFilesystemNode::parent() const { +AbstractFilesystemNode *RoninCDFilesystemNode::getParent() const { if (_path == "/") return 0; const char *start = _path.c_str(); const char *end = lastPathComponent(_path); - RoninCDFilesystemNode *p = new RoninCDFilesystemNode(String(start, end - start), false); - - return p; -} - -AbstractFilesystemNode *RoninCDFilesystemNode::child(const String &n) const { - // FIXME: Pretty lame implementation! We do no error checking to speak - // of, do not check if this is a special node, etc. - assert(_isDirectory); - String newPath(_path); - if (_path.lastChar() != '/') - newPath += '/'; - newPath += n; - RoninCDFilesystemNode *p = new RoninCDFilesystemNode(newPath, true); - - return p; + return new RoninCDFilesystemNode(String(start, end - start), false); } #endif // defined(__DC__) diff --git a/backends/fs/dc/ronincd-fs-factory.cpp b/backends/fs/dc/ronincd-fs-factory.cpp new file mode 100644 index 0000000000..0229a44c45 --- /dev/null +++ b/backends/fs/dc/ronincd-fs-factory.cpp @@ -0,0 +1,16 @@ +#include "backends/fs/dc/ronincd-fs-factory.h" +#include "backends/fs/dc/dc-fs.cpp" + +DECLARE_SINGLETON(RoninCDFilesystemFactory); + +AbstractFilesystemNode *RoninCDFilesystemFactory::makeRootFileNode() const { + return new RoninCDFilesystemNode(); +} + +AbstractFilesystemNode *RoninCDFilesystemFactory::makeCurrentDirectoryFileNode() const { + return new RoninCDFilesystemNode(); +} + +AbstractFilesystemNode *RoninCDFilesystemFactory::makeFileNodePath(const String &path) const { + return new RoninCDFilesystemNode(path, true); +} diff --git a/backends/fs/dc/ronincd-fs-factory.h b/backends/fs/dc/ronincd-fs-factory.h new file mode 100644 index 0000000000..426ef7ef2c --- /dev/null +++ b/backends/fs/dc/ronincd-fs-factory.h @@ -0,0 +1,27 @@ +#ifndef RONINCD_FILESYSTEM_FACTORY_H +#define RONINCD_FILESYSTEM_FACTORY_H + +#include "common/singleton.h" +#include "backends/fs/abstract-fs-factory.h" + +/** + * Creates RoninCDFilesystemNode objects. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemFactory. + */ +class RoninCDFilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<RoninCDFilesystemFactory> { +public: + typedef Common::String String; + + virtual AbstractFilesystemNode *makeRootFileNode() const; + virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const; + virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const; + +protected: + RoninCDFilesystemFactory() {}; + +private: + friend class Common::Singleton<SingletonBaseType>; +}; + +#endif /*RONINCD_FILESYSTEM_FACTORY_H*/ diff --git a/backends/fs/ds/ds-fs-factory.cpp b/backends/fs/ds/ds-fs-factory.cpp new file mode 100644 index 0000000000..7e64b37411 --- /dev/null +++ b/backends/fs/ds/ds-fs-factory.cpp @@ -0,0 +1,29 @@ +#include "backends/fs/ds/ds-fs-factory.h" +#include "backends/fs/ds/ds-fs.cpp" +#include "dsmain.h" //for the isGBAMPAvailable() function + +DECLARE_SINGLETON(DSFilesystemFactory); + +AbstractFilesystemNode *DSFilesystemFactory::makeRootFileNode() const { + if (DS::isGBAMPAvailable()) { + return new DS::GBAMPFileSystemNode(); + } else { + return new DS::DSFileSystemNode(); + } +} + +AbstractFilesystemNode *DSFilesystemFactory::makeCurrentDirectoryFileNode() const { + if (DS::isGBAMPAvailable()) { + return new DS::GBAMPFileSystemNode(); + } else { + return new DS::DSFileSystemNode(); + } +} + +AbstractFilesystemNode *DSFilesystemFactory::makeFileNodePath(const String &path) const { + if (DS::isGBAMPAvailable()) { + return new DS::GBAMPFileSystemNode(path); + } else { + return new DS::DSFileSystemNode(path); + } +} diff --git a/backends/fs/ds/ds-fs-factory.h b/backends/fs/ds/ds-fs-factory.h new file mode 100644 index 0000000000..a2e96aa548 --- /dev/null +++ b/backends/fs/ds/ds-fs-factory.h @@ -0,0 +1,27 @@ +#ifndef DS_FILESYSTEM_FACTORY_H +#define DS_FILESYSTEM_FACTORY_H + +#include "common/singleton.h" +#include "backends/fs/abstract-fs-factory.h" + +/** + * Creates DSFilesystemNode objects. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemFactory. + */ +class DSFilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<DSFilesystemFactory> { +public: + typedef Common::String String; + + virtual AbstractFilesystemNode *makeRootFileNode() const; + virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const; + virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const; + +protected: + DSFilesystemFactory() {}; + +private: + friend class Common::Singleton<SingletonBaseType>; +}; + +#endif /*DS_FILESYSTEM_FACTORY_H*/ diff --git a/backends/fs/ds/ds-fs.cpp b/backends/fs/ds/ds-fs.cpp index abfd0397c6..c0138459a9 100644 --- a/backends/fs/ds/ds-fs.cpp +++ b/backends/fs/ds/ds-fs.cpp @@ -20,24 +20,18 @@ * */ - #include "stdafx.h" #include "str.h" -#include "fs.h" #include "common/util.h" //#include <NDS/ARM9/console.h> //basic print funcionality #include "ds-fs.h" #include "dsmain.h" #include "gba_nds_fat.h" - namespace DS { - - - ////////////////////////////////////////////////////////////// -// DSFileSystemNode - Flash ROM file system using Zip files +// DSFileSystemNode - Flash ROM file system using Zip files // ////////////////////////////////////////////////////////////// ZipFile* DSFileSystemNode::_zipFile = NULL; @@ -66,7 +60,6 @@ DSFileSystemNode::DSFileSystemNode(const String& path) { char disp[128]; char* pathStr = (char *) path.c_str(); - int lastSlash = 3; for (int r = 0; r < (int) strlen(pathStr) - 1; r++) { if (path[r] == '\\') { @@ -81,13 +74,10 @@ DSFileSystemNode::DSFileSystemNode(const String& path) { // _isValid = true; // _isDirectory = false; - - if (!strncmp(pathStr, "ds:/", 4)) { pathStr += 4; } - if (*pathStr == '\0') { _isValid = true; _isDirectory = true; @@ -130,35 +120,10 @@ DSFileSystemNode::DSFileSystemNode(const String& path, bool isDir) { } DSFileSystemNode::DSFileSystemNode(const DSFileSystemNode* node) { - + //TODO: not implemented? } -AbstractFilesystemNode* DSFileSystemNode::parent() const { -// consolePrintf("parent\n"); - DSFileSystemNode *p; - - if (_path != "ds:/") { - char *path = (char *) _path.c_str(); - int lastSlash = 4; - - for (int r = 4; r < (int) strlen((char *) path); r++) { - if (path[r] == '\\') { - lastSlash = r; - } - } - - p = new DSFileSystemNode(String(path, lastSlash)); - ((DSFileSystemNode *) (p))->_isDirectory = true; - } else { - p = new DSFileSystemNode(); - } - - return p; - -} - - -AbstractFilesystemNode *DSFileSystemNode::child(const Common::String& n) const { +AbstractFilesystemNode *DSFileSystemNode::getChild(const Common::String& n) const { if (_path.lastChar() == '\\') { return new DSFileSystemNode(_path + n); } else { @@ -168,14 +133,10 @@ AbstractFilesystemNode *DSFileSystemNode::child(const Common::String& n) const { return NULL; } - -bool DSFileSystemNode::listDir(AbstractFSList &dirList, ListMode mode) const { +bool DSFileSystemNode::getChildren(AbstractFSList &dirList, ListMode mode) const { // consolePrintf("Listdir\n"); - - // consolePrintf("Directory\n"); - char temp[128]; strcpy(temp, _path.c_str()); @@ -190,14 +151,13 @@ bool DSFileSystemNode::listDir(AbstractFSList &dirList, ListMode mode) const { /* // This is the root dir, so add the RAM folder DSFileSystemNode* dsfsn = new DSFileSystemNode("ds:/ram"); dsfsn->_isDirectory = true; - dirList->push_back(wrap(dsfsn));*/ + dirList->push_back(wrap(dsfsn)); +*/ } } else { _zipFile->changeDirectory(temp); } - - if (_zipFile->restartFile()) { do { char n[128]; @@ -218,12 +178,32 @@ bool DSFileSystemNode::listDir(AbstractFSList &dirList, ListMode mode) const { return true; } +AbstractFilesystemNode* DSFileSystemNode::getParent() const { +// consolePrintf("parent\n"); + DSFileSystemNode *p; + if (_path != "ds:/") { + char *path = (char *) _path.c_str(); + int lastSlash = 4; + + for (int r = 4; r < (int) strlen((char *) path); r++) { + if (path[r] == '\\') { + lastSlash = r; + } + } + p = new DSFileSystemNode(String(path, lastSlash)); + ((DSFileSystemNode *) (p))->_isDirectory = true; + } else { + p = new DSFileSystemNode(); + } + + return p; +} -///////////////////////////////////////////////////////////////////////// -// GBAMPFileSystemNode - File system using GBA Movie Player and CF card -///////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// +// GBAMPFileSystemNode - File system using GBA Movie Player and CF card // +////////////////////////////////////////////////////////////////////////// GBAMPFileSystemNode::GBAMPFileSystemNode() { _displayName = "mp:/"; @@ -290,35 +270,10 @@ GBAMPFileSystemNode::GBAMPFileSystemNode(const String& path, bool isDirectory) { GBAMPFileSystemNode::GBAMPFileSystemNode(const GBAMPFileSystemNode* node) { - -} - - -AbstractFilesystemNode* GBAMPFileSystemNode::parent() const { -// consolePrintf("parent\n"); - GBAMPFileSystemNode *p; - - if (_path != "mp:/") { - char *path = (char *) _path.c_str(); - int lastSlash = 4; - - for (int r = 4; r < (int) strlen((char *) path); r++) { - if (path[r] == '/') { - lastSlash = r; - } - } - - p = new GBAMPFileSystemNode(String(path, lastSlash)); - p->_isDirectory = true; - } else { - p = new GBAMPFileSystemNode(); - } - - return p; - + //TODO: not implemented? } -AbstractFilesystemNode *GBAMPFileSystemNode::child(const Common::String& n) const { +AbstractFilesystemNode *GBAMPFileSystemNode::getChild(const Common::String& n) const { if (_path.lastChar() == '\\') { return new DSFileSystemNode(_path + n); } else { @@ -328,7 +283,7 @@ AbstractFilesystemNode *GBAMPFileSystemNode::child(const Common::String& n) cons return NULL; } -bool GBAMPFileSystemNode::listDir(AbstractFSList& dirList, ListMode mode) const { +bool GBAMPFileSystemNode::getChildren(AbstractFSList& dirList, ListMode mode) const { // consolePrintf("Listdir\n"); enum { TYPE_NO_MORE = 0, TYPE_FILE = 1, TYPE_DIR = 2 }; @@ -346,7 +301,6 @@ bool GBAMPFileSystemNode::listDir(AbstractFSList& dirList, ListMode mode) const pathTemp++; } - // consolePrintf("This dir: %s\n", path); FAT_chdir(path); @@ -369,8 +323,6 @@ bool GBAMPFileSystemNode::listDir(AbstractFSList& dirList, ListMode mode) const // dsfsn->_isDirectory = entryType == DIR; dirList.push_back((dsfsn)); } - - } else { // consolePrintf("Skipping %s\n", fname); } @@ -385,6 +337,28 @@ bool GBAMPFileSystemNode::listDir(AbstractFSList& dirList, ListMode mode) const return true; } +AbstractFilesystemNode* GBAMPFileSystemNode::getParent() const { +// consolePrintf("parent\n"); + GBAMPFileSystemNode *p; + + if (_path != "mp:/") { + char *path = (char *) _path.c_str(); + int lastSlash = 4; + + for (int r = 4; r < (int) strlen((char *) path); r++) { + if (path[r] == '/') { + lastSlash = r; + } + } + + p = new GBAMPFileSystemNode(String(path, lastSlash)); + p->_isDirectory = true; + } else { + p = new GBAMPFileSystemNode(); + } + + return p; +} // Stdio replacements #define MAX_FILE_HANDLES 32 @@ -393,9 +367,6 @@ bool inited = false; DS::fileHandle handle[MAX_FILE_HANDLES]; FILE* std_fopen(const char* name, const char* mode) { - - - if (!inited) { for (int r = 0; r < MAX_FILE_HANDLES; r++) { handle[r].used = false; @@ -403,9 +374,6 @@ FILE* std_fopen(const char* name, const char* mode) { inited = true; currentDir[0] = '\0'; } - - - char* realName = (char *) name; @@ -413,7 +381,7 @@ FILE* std_fopen(const char* name, const char* mode) { if ((name[0] == 'd') && (name[1] == 's') && (name[2] == ':') && (name[3] == '/')) { realName += 4; } - + if ((name[0] == 'm') && (name[1] == 'p') && (name[2] == ':') && (name[3] == '/')) { realName += 4; } @@ -421,7 +389,6 @@ FILE* std_fopen(const char* name, const char* mode) { // consolePrintf("Open file:"); // consolePrintf("'%s', [%s]", realName, mode); - if (DS::isGBAMPAvailable()) { FAT_chdir("/"); @@ -443,10 +410,9 @@ FILE* std_fopen(const char* name, const char* mode) { return (FILE *) result; } - // Fail to open file for writing. It's in ROM! - + // Allocate a file handle int r = 0; while (handle[r].used) r++; @@ -459,7 +425,6 @@ FILE* std_fopen(const char* name, const char* mode) { handle[r].sramFile = (DSSaveFile *) DSSaveFileManager::instance()->openSavefile(realName, false); } - if (handle[r].sramFile) { handle[r].used = true; handle[r].pos = 0; @@ -513,6 +478,7 @@ FILE* std_fopen(const char* name, const char* mode) { return NULL; } } + void std_fclose(FILE* handle) { if (DS::isGBAMPAvailable()) { @@ -528,14 +494,9 @@ void std_fclose(FILE* handle) { } size_t std_fread(const void* ptr, size_t size, size_t numItems, FILE* handle) { - // consolePrintf("fread %d,%d %d ", size, numItems, ptr); - - if (DS::isGBAMPAvailable()) { - - int bytes = FAT_fread((void *) ptr, size, numItems, (FAT_FILE *) handle); if (!std_feof(handle)) { return numItems; @@ -560,27 +521,24 @@ size_t std_fread(const void* ptr, size_t size, size_t numItems, FILE* handle) { } - return item;*/ - - + return item; +*/ int items = 0; //for (int r = 0; r < numItems; r++) { if (!std_feof(handle)) { - - - /* for (int t = 0; t < size; t++) { if (feof(handle)) eof = true; *(((char *) (ptr)) + r * size + t) = getc(handle); }*/ int left = size * numItems; int bytesRead = -1; + while ((left > 0) && (!FAT_feof((FAT_FILE *) handle))) { int amount = left > 8192? 8192: left; // do { bytesRead = FAT_fread((void *) ptr, 1, amount, (FAT_FILE *) handle); - /* if (bytesRead == 0) { +/* if (bytesRead == 0) { consolePrintf("Pos:%d items:%d num:%d amount:%d read:%d\n", ftell(handle), items, numItems, amount, bytesRead); left++; @@ -592,27 +550,24 @@ size_t std_fread(const void* ptr, size_t size, size_t numItems, FILE* handle) { fread(ptr, 1024, 1, handle); swiWaitForVBlank(); //while (true); - }*/ - //} while (bytesRead == 0); + } + + } while (bytesRead == 0); +*/ left -= bytesRead; ptr = ((char *) (ptr)) + bytesRead; } items = numItems - (left / size); - - - - + // FAT_fread((void *) ptr, size, 1, ((int) (handle)) - 1); - // ptr = ((char *) (ptr)) + size; - +// ptr = ((char *) (ptr)) + size; } - //} +// } // consolePrintf("...done %d \n", items) return items; - } if (handle->sramFile) { @@ -630,7 +585,6 @@ size_t std_fread(const void* ptr, size_t size, size_t numItems, FILE* handle) { return bytes / size; } - if (handle->pos + size * numItems > handle->size) { numItems = (handle->size - handle->pos) / size; if (numItems < 0) numItems = 0; @@ -639,10 +593,8 @@ size_t std_fread(const void* ptr, size_t size, size_t numItems, FILE* handle) { // consolePrintf("read %d ", size * numItems); memcpy((void *) ptr, handle->data + handle->pos, size * numItems); - handle->pos += size * numItems; - return numItems; } @@ -657,7 +609,6 @@ size_t std_fwrite(const void* ptr, size_t size, size_t numItems, FILE* handle) { //consolePrintf("fwrite size=%d\n", size * numItems); if (DS::isGBAMPAvailable()) { - FAT_fwrite(((char *) (ptr)), size, numItems, (FAT_FILE *) handle); return numItems; @@ -675,7 +626,6 @@ size_t std_fwrite(const void* ptr, size_t size, size_t numItems, FILE* handle) { return numItems; } - if (handle->sramFile) { handle->sramFile->write(ptr, size); return size; @@ -704,6 +654,7 @@ bool std_feof(FILE* handle) { } void std_fflush(FILE* handle) { + //FIXME: not implemented? // consolePrintf("fflush "); } @@ -711,7 +662,6 @@ char* std_fgets(char* str, int size, FILE* file) { // consolePrintf("fgets file=%d ", file); if (DS::isGBAMPAvailable()) { - char* s = str; while ((*s++ = std_getc(file)) >= 32) { // consolePrintf("%d ", *s); @@ -723,7 +673,6 @@ char* std_fgets(char* str, int size, FILE* file) { return str; } - if (file->sramFile) { file->pos--; int p = -1; @@ -743,7 +692,6 @@ char* std_fgets(char* str, int size, FILE* file) { } long int std_ftell(FILE* handle) { - if (DS::isGBAMPAvailable()) { return FAT_ftell((FAT_FILE *) handle); } @@ -758,39 +706,30 @@ int std_fseek(FILE* handle, long int offset, int whence) { return FAT_fseek((FAT_FILE *) handle, offset, whence); } - switch (whence) { - case SEEK_CUR: { + case SEEK_CUR: handle->pos += offset; break; - } - - case SEEK_SET: { + case SEEK_SET: handle->pos = offset; break; - } - - case SEEK_END: { + case SEEK_END: handle->pos = handle->size + offset; break; - } - - default: { + default: handle->pos = offset; break; - } - } return 0; } void std_clearerr(FILE* handle) { + //FIXME: not implemented? // consolePrintf("clearerr "); } int std_getc(FILE* handle) { - if (DS::isGBAMPAvailable()) { char c; FAT_fread(&c, 1, 1, (FAT_FILE *) handle); @@ -852,24 +791,3 @@ int std_ferror(FILE* handle) { } } // namespace DS - -// These functions are added to AbstractFileSystemNode and are therefore outside -// the DS namespace. - -AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { -// consolePrintf("New node"); - - if (DS::isGBAMPAvailable()) { - return new DS::GBAMPFileSystemNode(); - } else { - return new DS::DSFileSystemNode(); - } -} - -AbstractFilesystemNode* AbstractFilesystemNode::getNodeForPath(const String& path) { - if (DS::isGBAMPAvailable()) { - return new DS::GBAMPFileSystemNode(path); - } else { - return new DS::DSFileSystemNode(path); - } -} diff --git a/backends/fs/ds/ds-fs.h b/backends/fs/ds/ds-fs.h index ef651b7ea7..e3014d0d2e 100644 --- a/backends/fs/ds/ds-fs.h +++ b/backends/fs/ds/ds-fs.h @@ -23,8 +23,6 @@ #ifndef _DS_FS_H #define _DS_FS_H - - //#include <NDS/ARM9/console.h> #include "fs.h" #include "zipreader.h" @@ -32,81 +30,134 @@ #include "scummconsole.h" #include "gba_nds_fat.h" #include "backends/fs/abstract-fs.h" -//#include "backends/fs/fs.h" namespace DS { /** + * Implementation of the ScummVM file system API. * This class is used when a Flash cart is in use. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemNode. */ class DSFileSystemNode : public AbstractFilesystemNode { protected: - static ZipFile* _zipFile; - typedef class Common::String String; + static ZipFile* _zipFile; + String _displayName; + String _path; bool _isDirectory; bool _isValid; - String _path; int _refCountVal; public: + /** + * Creates a DSFilesystemNode with the root node as path. + */ DSFileSystemNode(); + + /** + * Creates a DSFilesystemNode for a given path. + * + * @param path String with the path the new node should point to. + */ DSFileSystemNode(const String &path); - DSFileSystemNode(const DSFileSystemNode *node); + + /** + * Creates a DSFilesystemNode for a given path. + * + * @param path String with the path the new node should point to. + * @param path true if path is a directory, false otherwise. + */ DSFileSystemNode(const String& path, bool isDir); - virtual String displayName() const { return _displayName; } - virtual String name() const { return _displayName; } - virtual bool isValid() const { return _isValid; } + /** + * Copy constructor. + */ + DSFileSystemNode(const DSFileSystemNode *node); + + virtual bool exists() const { return true; } //FIXME: this is just a stub + virtual String getDisplayName() const { return _displayName; } + virtual String getName() const { return _displayName; } + virtual String getPath() const { return _path; } virtual bool isDirectory() const { return _isDirectory; } - virtual String path() const { return _path; } + virtual bool isReadable() const { return true; } //FIXME: this is just a stub + virtual bool isValid() const { return _isValid; } + virtual bool isWritable() const { return true; } //FIXME: this is just a stub - virtual bool listDir(AbstractFSList &list, ListMode mode = FilesystemNode::kListDirectoriesOnly) const; - virtual AbstractFilesystemNode *parent() const; + /** + * Returns a copy of this node. + */ virtual AbstractFilesystemNode *clone() const { return new DSFileSystemNode(this); } - virtual AbstractFilesystemNode *child(const Common::String& name) const; + virtual AbstractFilesystemNode *getChild(const Common::String& name) const; + virtual bool getChildren(AbstractFSList &list, ListMode mode = FilesystemNode::kListDirectoriesOnly) const; + virtual AbstractFilesystemNode *getParent() const; + + /** + * Returns the zip file this node points to. + * TODO: check this documentation. + */ static ZipFile* getZip() { return _zipFile; } }; - -/** + /** + * Implementation of the ScummVM file system API. * This class is used when the GBAMP (GBA Movie Player) is used with a CompactFlash card. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemNode. */ class GBAMPFileSystemNode : public AbstractFilesystemNode { protected: typedef class Common::String String; String _displayName; + String _path; bool _isDirectory; bool _isValid; - String _path; - int _refCountVal; public: + /** + * Creates a GBAMPFilesystemNode with the root node as path. + */ GBAMPFileSystemNode(); + + /** + * Creates a GBAMPFilesystemNode for a given path. + * + * @param path String with the path the new node should point to. + */ GBAMPFileSystemNode(const String &path); + + /** + * Creates a DSFilesystemNode for a given path. + * + * @param path String with the path the new node should point to. + * @param path true if path is a directory, false otherwise. + */ GBAMPFileSystemNode(const String &path, bool isDirectory); + + /** + * Copy constructor. + */ GBAMPFileSystemNode(const GBAMPFileSystemNode *node); - virtual String displayName() const { return _displayName; } - virtual String name() const { return _displayName; } - - virtual bool isValid() const { return _isValid; } + virtual String getDisplayName() const { return _displayName; } + virtual String getName() const { return _displayName; } + virtual String getPath() const { return _path; } virtual bool isDirectory() const { return _isDirectory; } - virtual String path() const { return _path; } - virtual bool listDir(AbstractFSList &list, ListMode mode = FilesystemNode::kListDirectoriesOnly) const; - virtual AbstractFilesystemNode *parent() const; - virtual AbstractFilesystemNode *clone() const { return new GBAMPFileSystemNode(this); } - virtual AbstractFilesystemNode *child(const Common::String& name) const; + virtual bool isValid() const { return _isValid; } + /** + * Returns a copy of this node. + */ + virtual AbstractFilesystemNode *clone() const { return new GBAMPFileSystemNode(this); } + virtual AbstractFilesystemNode *getChild(const Common::String& name) const; + virtual bool getChildren(AbstractFSList &list, ListMode mode = FilesystemNode::kListDirectoriesOnly) const; + virtual AbstractFilesystemNode *getParent() const; }; - - - struct fileHandle { int pos; bool used; @@ -116,7 +167,6 @@ struct fileHandle { DSSaveFile* sramFile; }; - #undef stderr #undef stdout #undef stdin @@ -140,6 +190,6 @@ void std_clearerr(FILE* handle); void std_cwd(char* dir); void std_fflush(FILE* handle); -} +} //namespace DS -#endif +#endif //_DS_FS_H diff --git a/backends/fs/fs-factory-maker.cpp b/backends/fs/fs-factory-maker.cpp new file mode 100644 index 0000000000..bae3d1a30a --- /dev/null +++ b/backends/fs/fs-factory-maker.cpp @@ -0,0 +1,113 @@ +#include "backends/fs/abstract-fs-factory.h" + +/* + * All the following includes choose, at compile time, which specific backend will be used + * during the execution of the ScummVM. + * + * It has to be done this way because not all the necessary libraries will be available in + * all build environments. Additionally, this results in smaller binaries. + */ +#if defined(__amigaos4__) + #include "backends/fs/amigaos4/amigaos4-fs-factory.cpp" +#endif + +#if defined(__DC__) + #include "backends/fs/dc/ronincd-fs-factory.cpp" +#endif + +#if defined(__DS__) + #include "backends/fs/ds/ds-fs-factory.cpp" +#endif + +#if defined(__GP32__) + #include "backends/fs/gp32/gp32-fs-factory.cpp" +#endif + +#if defined(__MORPHOS__) + #include "backends/fs/morphos/abox-fs-factory.cpp" +#endif + +#if defined(PALMOS_MODE) + #include "backends/fs/palmos/palmos-fs-factory.cpp" +#endif + +#if defined(__PLAYSTATION2__) + #include "backends/fs/ps2/ps2-fs-factory.cpp" +#endif + +#if defined(__PSP__) + #include "backends/fs/psp/psp-fs-factory.cpp" +#endif + +#if defined(__SYMBIAN32__) + #include "backends/fs/symbian/symbian-fs-factory.cpp" +#endif + +#if defined(UNIX) + #include "backends/fs/posix/posix-fs-factory.cpp" +#endif + +#if defined(WIN32) + #include "backends/fs/windows/windows-fs-factory.cpp" +#endif + +/** + * Creates concrete FilesystemFactory objects depending on the current architecture. + */ +class FilesystemFactoryMaker { +public: + + /** + * Returns the correct concrete factory depending on the current build architecture. + */ + static AbstractFilesystemFactory *makeFactory(); + +protected: + FilesystemFactoryMaker() {}; // avoid instances of this class +}; + +AbstractFilesystemFactory *FilesystemFactoryMaker::makeFactory(){ + #if defined(__amigaos4__) + return &AmigaOSFilesystemFactory::instance(); + #endif + + #if defined(__DC__) + return &RoninCDFilesystemFactory::instance(); + #endif + + #if defined(__DS__) + return &DSFilesystemFactory::instance(); + #endif + + #if defined(__GP32__) + return &GP32FilesystemFactory::instance(); + #endif + + #if defined(__MORPHOS__) + return &ABoxFilesystemFactory::instance(); + #endif + + #if defined(PALMOS_MODE) + return &PalmOSFilesystemFactory::instance(); + #endif + + #if defined(__PLAYSTATION2__) + return &Ps2FilesystemFactory::instance(); + #endif + + #if defined(__PSP__) + return &PSPFilesystemFactory::instance(); + #endif + + #if defined(__SYMBIAN32__) + return &SymbianFilesystemFactory::instance(); + #endif + + #if defined(UNIX) + return &POSIXFilesystemFactory::instance(); + #endif + + #if defined(WIN32) + return &WindowsFilesystemFactory::instance(); + #endif +} diff --git a/backends/fs/gp32/gp32-fs-factory.cpp b/backends/fs/gp32/gp32-fs-factory.cpp new file mode 100644 index 0000000000..6328836c0e --- /dev/null +++ b/backends/fs/gp32/gp32-fs-factory.cpp @@ -0,0 +1,16 @@ +#include "backends/fs/gp32/gp32-fs-factory.h" +#include "backends/fs/gp32/gp32-fs.cpp" + +DECLARE_SINGLETON(GP32FilesystemFactory); + +AbstractFilesystemNode *GP32FilesystemFactory::makeRootFileNode() const { + return new GP32FilesystemNode(); +} + +AbstractFilesystemNode *GP32FilesystemFactory::makeCurrentDirectoryFileNode() const { + return new GP32FilesystemNode(); +} + +AbstractFilesystemNode *GP32FilesystemFactory::makeFileNodePath(const String &path) const { + return new GP32FilesystemNode(path); +} diff --git a/backends/fs/gp32/gp32-fs-factory.h b/backends/fs/gp32/gp32-fs-factory.h new file mode 100644 index 0000000000..fc15b52bc6 --- /dev/null +++ b/backends/fs/gp32/gp32-fs-factory.h @@ -0,0 +1,27 @@ +#ifndef GP32_FILESYSTEM_FACTORY_H +#define GP32_FILESYSTEM_FACTORY_H + +#include "common/singleton.h" +#include "backends/fs/abstract-fs-factory.h" + +/** + * Creates GP32FilesystemNode objects. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemFactory. + */ +class GP32FilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<GP32FilesystemFactory> { +public: + typedef Common::String String; + + virtual AbstractFilesystemNode *makeRootFileNode() const; + virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const; + virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const; + +protected: + GP32FilesystemFactory() {}; + +private: + friend class Common::Singleton<SingletonBaseType>; +}; + +#endif /*GP32_FILESYSTEM_FACTORY_H*/ diff --git a/backends/fs/gp32/gp32-fs.cpp b/backends/fs/gp32/gp32-fs.cpp index 017fa98349..92968b5976 100644 --- a/backends/fs/gp32/gp32-fs.cpp +++ b/backends/fs/gp32/gp32-fs.cpp @@ -24,38 +24,80 @@ */ #include "stdafx.h" - #include "backends/fs/abstract-fs.h" +#define MAX_PATH_SIZE 256 + +/** + * Implementation of the ScummVM file system API. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemNode. + */ class GP32FilesystemNode : public AbstractFilesystemNode { protected: String _displayName; + String _path; bool _isDirectory; bool _isRoot; - String _path; public: + /** + * Creates a GP32FilesystemNode with the root node as path. + */ GP32FilesystemNode(); + + /** + * Creates a GP32FilesystemNode for a given path. + * + * @param path String with the path the new node should point to. + */ GP32FilesystemNode(const String &path); - virtual String displayName() const { return _displayName; } - virtual String name() const { return _displayName; } + virtual String getDisplayName() const { return _displayName; } + virtual String getName() const { return _displayName; } + virtual String getPath() const { return _path; } + virtual bool isDirectory() const { return _isDirectory; } // FIXME: isValid should return false if this Node can't be used! - // client code can rely on the return value. + // so client code can rely on the return value. + virtual bool isReadable() const { return true; } //FIXME: this is just a stub virtual bool isValid() const { return true; } - virtual bool isDirectory() const { return _isDirectory; } - virtual String path() const { return _path; } + virtual bool isWritable() const { return true; } //FIXME: this is just a stub - virtual bool listDir(AbstractFSList &list, ListMode mode) const; - virtual AbstractFilesystemNode *parent() const; - virtual AbstractFilesystemNode *child(const String &n) const; + virtual AbstractFilesystemNode *getChild(const String &n) const; + virtual bool getChildren(AbstractFSList &list, ListMode mode) const; + virtual AbstractFilesystemNode *getParent() const; }; -#define MAX_PATH_SIZE 256 - const char gpRootPath[] = "gp:\\"; //char gpCurrentPath[MAX_PATH_SIZE] = "gp:\\"; // must end with '\' +/** + * Returns the last component of a given path. + * + * Examples: + * gp:\foo\bar.txt would return "\bar.txt" + * gp:\foo\bar\ would return "\bar\" + * + * @param str Path to obtain the last component from. + * @return Pointer to the first char of the last component inside str. + */ +static const char *lastPathComponent(const Common::String &str) { + const char *start = str.c_str(); + const char *cur = start + str.size() - 2; + + while (cur >= start && *cur != '\\') { + --cur; + } + + return cur + 1; +} + +/** + * FIXME: document this function. + * + * @param path + * @param convPath + */ int gpMakePath(const char *path, char *convPath) { // copy root or current directory const char *p; @@ -106,18 +148,6 @@ int gpMakePath(const char *path, char *convPath) { return 0; } -AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { - return AbstractFilesystemNode::getRoot(); -} - -AbstractFilesystemNode *AbstractFilesystemNode::getRoot() { - return new GP32FilesystemNode(); -} - -AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) { - return new GP32FilesystemNode(path); -} - GP32FilesystemNode::GP32FilesystemNode() { _isDirectory = true; _isRoot = true; @@ -132,8 +162,8 @@ GP32FilesystemNode::GP32FilesystemNode(const String &path) { gpMakePath(path.c_str(), convPath); _path = convPath; - pos = convPath; + while (*pos) if (*pos++ == '\\') dsplName = pos; @@ -150,14 +180,25 @@ GP32FilesystemNode::GP32FilesystemNode(const String &path) { _isDirectory = true; } -bool GP32FilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const { +AbstractFilesystemNode *GP32FilesystemNode::getChild(const String &n) const { + // FIXME: Pretty lame implementation! We do no error checking to speak + // of, do not check if this is a special node, etc. + assert(_isDirectory); + + String newPath(_path); + if (_path.lastChar() != '\\') + newPath += '\\'; + newPath += n; + + return new GP32FilesystemNode(newPath); +} + +bool GP32FilesystemNode::getChildren(AbstractFSList &myList, ListMode mode) const { assert(_isDirectory); GPDIRENTRY dirEntry; GPFILEATTR attr; - GP32FilesystemNode entry; - uint32 read; if (mode == FilesystemNode::kListAll) @@ -168,9 +209,11 @@ bool GP32FilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const { int startIdx = 0; // current file String listDir(_path); //listDir += "/"; + while (GpDirEnumList(listDir.c_str(), startIdx++, 1, &dirEntry, &read) == SM_OK) { if (dirEntry.name[0] == '.') continue; + entry._displayName = dirEntry.name; entry._path = _path; entry._path += dirEntry.name; @@ -194,18 +237,7 @@ bool GP32FilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const { return true; } -static const char *lastPathComponent(const Common::String &str) { - const char *start = str.c_str(); - const char *cur = start + str.size() - 2; - - while (cur >= start && *cur != '\\') { - --cur; - } - - return cur + 1; -} - -AbstractFilesystemNode *GP32FilesystemNode::parent() const { +AbstractFilesystemNode *GP32FilesystemNode::getParent() const { if(_isRoot) return 0; @@ -218,16 +250,3 @@ AbstractFilesystemNode *GP32FilesystemNode::parent() const { return p; } - -AbstractFilesystemNode *GP32FilesystemNode::child(const String &n) const { - // FIXME: Pretty lame implementation! We do no error checking to speak - // of, do not check if this is a special node, etc. - assert(_isDirectory); - String newPath(_path); - if (_path.lastChar() != '\\') - newPath += '\\'; - newPath += n; - GP32FilesystemNode *p = new GP32FilesystemNode(newPath); - - return p; -} diff --git a/backends/fs/morphos/abox-fs-factory.cpp b/backends/fs/morphos/abox-fs-factory.cpp new file mode 100644 index 0000000000..9de810c361 --- /dev/null +++ b/backends/fs/morphos/abox-fs-factory.cpp @@ -0,0 +1,16 @@ +#include "backends/fs/morphos/abox-fs-factory.h" +#include "backends/fs/morphos/abox-fs.cpp" + +DECLARE_SINGLETON(ABoxFilesystemFactory); + +AbstractFilesystemNode *ABoxFilesystemFactory::makeRootFileNode() const { + return new ABoxFilesystemNode(); +} + +AbstractFilesystemNode *ABoxFilesystemFactory::makeCurrentDirectoryFileNode() const { + return new ABoxFilesystemNode(); +} + +AbstractFilesystemNode *ABoxFilesystemFactory::makeFileNodePath(const String &path) const { + return new ABoxFilesystemNode(path); +} diff --git a/backends/fs/morphos/abox-fs-factory.h b/backends/fs/morphos/abox-fs-factory.h new file mode 100644 index 0000000000..35f4472b8b --- /dev/null +++ b/backends/fs/morphos/abox-fs-factory.h @@ -0,0 +1,27 @@ +#ifndef ABOX_FILESYSTEM_FACTORY_H +#define ABOX_FILESYSTEM_FACTORY_H + +#include "common/singleton.h" +#include "backends/fs/abstract-fs-factory.h" + +/** + * Creates ABoxFilesystemNode objects. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemFactory. + */ +class ABoxFilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<ABoxFilesystemFactory> { +public: + typedef Common::String String; + + virtual AbstractFilesystemNode *makeRootFileNode() const; + virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const; + virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const; + +protected: + ABoxFilesystemFactory() {}; + +private: + friend class Common::Singleton<SingletonBaseType>; +}; + +#endif /*ABOX_FILESYSTEM_FACTORY_H*/ diff --git a/backends/fs/morphos/abox-fs.cpp b/backends/fs/morphos/abox-fs.cpp index 8206e83030..8f46f9a9a8 100644 --- a/backends/fs/morphos/abox-fs.cpp +++ b/backends/fs/morphos/abox-fs.cpp @@ -35,52 +35,66 @@ #include "base/engine.h" #include "backends/fs/abstract-fs.h" -/* +/** * Implementation of the ScummVM file system API based on the MorphOS A-Box API. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemNode. */ - class ABoxFilesystemNode : public AbstractFilesystemNode { - protected: - BPTR _lock; - String _displayName; - bool _isDirectory; - bool _isValid; - String _path; - - public: - ABoxFilesystemNode(); - ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name = NULL); - ABoxFilesystemNode(const String &p); - ABoxFilesystemNode(const ABoxFilesystemNode &node); - - ~ABoxFilesystemNode(); - - virtual String displayName() const { return _displayName; } - virtual String name() const { return _displayName; }; - virtual bool isValid() const { return _isValid; } - virtual bool isDirectory() const { return _isDirectory; } - virtual String path() const { return _path; } - - virtual bool listDir(AbstractFSList &list, ListMode mode) const; - static AbstractFSList listRoot(); - virtual AbstractFilesystemNode *parent() const; - virtual AbstractFilesystemNode *child(const String &name) const; +protected: + BPTR _lock; + String _displayName; + String _path; + bool _isDirectory; + bool _isValid; + +public: + /** + * Creates a ABoxFilesystemNode with the root node as path. + */ + ABoxFilesystemNode(); + + /** + * Creates a ABoxFilesystemNode for a given path. + * + * @param path String with the path the new node should point to. + */ + ABoxFilesystemNode(const String &p); + + /** + * FIXME: document this constructor. + */ + ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name = NULL); + + /** + * Copy constructor. + */ + ABoxFilesystemNode(const ABoxFilesystemNode &node); + + /** + * Destructor. + */ + ~ABoxFilesystemNode(); + + virtual bool exists() const { return true; } //FIXME: this is just a stub + virtual String getDisplayName() const { return _displayName; } + virtual String getName() const { return _displayName; }; + virtual String getPath() const { return _path; } + virtual bool isDirectory() const { return _isDirectory; } + virtual bool isReadable() const { return true; } //FIXME: this is just a stub + virtual bool isValid() const { return _isValid; } + virtual bool isWritable() const { return true; } //FIXME: this is just a stub + + virtual AbstractFilesystemNode *getChild(const String &name) const; + virtual bool getChildren(AbstractFSList &list, ListMode mode) const; + virtual AbstractFilesystemNode *getParent() const; + + /** + * Return the list of child nodes for the root node. + */ + static AbstractFSList getRootChildren(); }; - -AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { - return AbstractFilesystemNode::getRoot(); -} - -AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) { - return new ABoxFilesystemNode(path); -} - -AbstractFilesystemNode *AbstractFilesystemNode::getRoot() -{ - return new ABoxFilesystemNode(); -} - ABoxFilesystemNode::ABoxFilesystemNode() { _displayName = "Mounted Volumes"; @@ -90,57 +104,6 @@ ABoxFilesystemNode::ABoxFilesystemNode() _lock = NULL; } -ABoxFilesystemNode::ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name) -{ - int bufsize = 256; - - _lock = NULL; - for (;;) - { - char name[bufsize]; - if (NameFromLock(lock, name, bufsize) != DOSFALSE) - { - _path = name; - _displayName = display_name ? display_name : FilePart(name); - break; - } - if (IoErr() != ERROR_LINE_TOO_LONG) - { - _isValid = false; - debug(6, "Error while retrieving path name: %ld", IoErr()); - return; - } - bufsize *= 2; - } - - _isDirectory = false; - _isValid = false; - - FileInfoBlock *fib = (FileInfoBlock*) AllocDosObject(DOS_FIB, NULL); - if (fib == NULL) - { - debug(6, "Failed to allocate memory for FileInfoBlock"); - return; - } - - if (Examine(lock, fib) != DOSFALSE) - { - _isDirectory = fib->fib_EntryType > 0; - if (_isDirectory) - { - if (fib->fib_EntryType != ST_ROOT) - _path += "/"; - _lock = DupLock(lock); - _isValid = (_lock != NULL); - } - else - { - _isValid = true; - } - } - FreeDosObject(DOS_FIB, fib); -} - ABoxFilesystemNode::ABoxFilesystemNode(const String &p) { int len = 0, offset = p.size(); @@ -168,7 +131,6 @@ ABoxFilesystemNode::ABoxFilesystemNode(const String &p) { } // Check whether the node exists and if it is a directory - BPTR pLock = Lock((STRPTR)_path.c_str(), SHARED_LOCK); if (pLock) { @@ -198,6 +160,58 @@ ABoxFilesystemNode::ABoxFilesystemNode(const String &p) { FreeDosObject(DOS_FIB, fib); } +ABoxFilesystemNode::ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name) +{ + int bufsize = 256; + + _lock = NULL; + for (;;) + { + char name[bufsize]; + if (NameFromLock(lock, name, bufsize) != DOSFALSE) + { + _path = name; + _displayName = display_name ? display_name : FilePart(name); + break; + } + if (IoErr() != ERROR_LINE_TOO_LONG) + { + _isValid = false; + debug(6, "Error while retrieving path name: %ld", IoErr()); + return; + } + bufsize *= 2; + } + + _isDirectory = false; + _isValid = false; + + FileInfoBlock *fib = (FileInfoBlock*) AllocDosObject(DOS_FIB, NULL); + if (fib == NULL) + { + debug(6, "Failed to allocate memory for FileInfoBlock"); + return; + } + + if (Examine(lock, fib) != DOSFALSE) + { + _isDirectory = fib->fib_EntryType > 0; + if (_isDirectory) + { + if (fib->fib_EntryType != ST_ROOT) + _path += "/"; + _lock = DupLock(lock); + _isValid = (_lock != NULL); + } + else + { + _isValid = true; + } + } + + FreeDosObject(DOS_FIB, fib); +} + ABoxFilesystemNode::ABoxFilesystemNode(const ABoxFilesystemNode& node) { _displayName = node._displayName; @@ -216,7 +230,27 @@ ABoxFilesystemNode::~ABoxFilesystemNode() } } -bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const +AbstractFilesystemNode *ABoxFilesystemNode::getChild(const String &name) const { + assert(_isDirectory); + String newPath(_path); + + if (_path.lastChar() != '/') + newPath += '/'; + newPath += name; + + BPTR lock = Lock(newPath.c_str(), SHARED_LOCK); + + if (!lock) + { + return 0; + } + + UnLock(lock); + + return new ABoxFilesystemNode(newPath); +} + +bool ABoxFilesystemNode::getChildren(AbstractFSList &list, ListMode mode) const { if (!_isValid) { @@ -232,7 +266,7 @@ bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const if (_lock == NULL) { /* This is the root node */ - myList = listRoot(); + list = getRootChildren(); return true; } @@ -266,7 +300,7 @@ bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const if (entry) { if (entry->isValid()) - myList.push_back(entry); + list.push_back(entry); else delete entry; } @@ -284,7 +318,7 @@ bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const return true; } -AbstractFilesystemNode *ABoxFilesystemNode::parent() const +AbstractFilesystemNode *ABoxFilesystemNode::getParent() const { AbstractFilesystemNode *node = NULL; @@ -309,29 +343,9 @@ AbstractFilesystemNode *ABoxFilesystemNode::parent() const return node; } -AbstractFilesystemNode *ABoxFilesystemNode::child(const String &name) const { - assert(_isDirectory); - String newPath(_path); - - if (_path.lastChar() != '/') - newPath += '/'; - newPath += name; - - BPTR lock = Lock(newPath.c_str(), SHARED_LOCK); - - if (!lock) - { - return 0; - } - - UnLock(lock); - - return new ABoxFilesystemNode(newPath); -} - -AbstractFSList ABoxFilesystemNode::listRoot() +AbstractFSList ABoxFilesystemNode::getRootChildren() { - AbstractFSList myList; + AbstractFSList list; DosList *dosList; CONST ULONG lockDosListFlags = LDF_READ | LDF_VOLUMES; char name[256]; @@ -339,15 +353,15 @@ AbstractFSList ABoxFilesystemNode::listRoot() dosList = LockDosList(lockDosListFlags); if (dosList == NULL) { - return myList; + return list; } dosList = NextDosEntry(dosList, LDF_VOLUMES); while (dosList) { - if (dosList->dol_Type == DLT_VOLUME && // Should always be true, but ... - dosList->dol_Name && // Same here - dosList->dol_Task // Will be NULL if volume is removed from drive but still in use by some program + if (dosList->dol_Type == DLT_VOLUME && // Should always be true, but ... + dosList->dol_Name && // Same here + dosList->dol_Task // Will be NULL if volume is removed from drive but still in use by some program ) { ABoxFilesystemNode *entry; @@ -365,7 +379,7 @@ AbstractFSList ABoxFilesystemNode::listRoot() if (entry) { if (entry->isValid()) - myList.push_back(entry); + list.push_back(entry); else delete entry; } @@ -377,9 +391,7 @@ AbstractFSList ABoxFilesystemNode::listRoot() UnLockDosList(lockDosListFlags); - return myList; + return list; } #endif // defined(__MORPHOS__) - - diff --git a/backends/fs/palmos/palmos-fs-factory.cpp b/backends/fs/palmos/palmos-fs-factory.cpp new file mode 100644 index 0000000000..1b0db0f042 --- /dev/null +++ b/backends/fs/palmos/palmos-fs-factory.cpp @@ -0,0 +1,16 @@ +#include "backends/fs/palmos/palmos-fs-factory.h" +#include "backends/fs/palmos/palmos-fs.cpp" + +DECLARE_SINGLETON(PalmOSFilesystemFactory); + +AbstractFilesystemNode *PalmOSFilesystemFactory::makeRootFileNode() const { + return new PalmOSFilesystemNode(); +} + +AbstractFilesystemNode *PalmOSFilesystemFactory::makeCurrentDirectoryFileNode() const { + return new PalmOSFilesystemNode(); +} + +AbstractFilesystemNode *PalmOSFilesystemFactory::makeFileNodePath(const String &path) const { + return new PalmOSFilesystemNode(path); +} diff --git a/backends/fs/palmos/palmos-fs-factory.h b/backends/fs/palmos/palmos-fs-factory.h new file mode 100644 index 0000000000..cfe246e806 --- /dev/null +++ b/backends/fs/palmos/palmos-fs-factory.h @@ -0,0 +1,27 @@ +#ifndef PALMOS_FILESYSTEM_FACTORY_H +#define PALMOS_FILESYSTEM_FACTORY_H + +#include "common/singleton.h" +#include "backends/fs/abstract-fs-factory.h" + +/** + * Creates PalmOSFilesystemNode objects. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemFactory. + */ +class PalmOSFilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<PalmOSFilesystemFactory> { +public: + typedef Common::String String; + + virtual AbstractFilesystemNode *makeRootFileNode() const; + virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const; + virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const; + +protected: + PalmOSFilesystemFactory() {}; + +private: + friend class Common::Singleton<SingletonBaseType>; +}; + +#endif /*PALMOS_FILESYSTEM_FACTORY_H*/ diff --git a/backends/fs/palmos/palmos-fs.cpp b/backends/fs/palmos/palmos-fs.cpp index 2c524bb830..eae3581196 100644 --- a/backends/fs/palmos/palmos-fs.cpp +++ b/backends/fs/palmos/palmos-fs.cpp @@ -30,36 +30,68 @@ #include "common/stdafx.h" #include "backends/fs/abstract-fs.h" -/* +/** * Implementation of the ScummVM file system API based on PalmOS VFS API. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemNode. */ - class PalmOSFilesystemNode : public AbstractFilesystemNode { protected: String _displayName; + String _path; bool _isDirectory; bool _isValid; bool _isPseudoRoot; - String _path; public: + /** + * Creates a PalmOSFilesystemNode with the root node as path. + */ PalmOSFilesystemNode(); + + /** + * Creates a POSIXFilesystemNode for a given path. + * + * @param path String with the path the new node should point to. + */ PalmOSFilesystemNode(const String &p); - virtual String displayName() const { return _displayName; } - virtual String name() const { return _displayName; } - virtual bool isValid() const { return _isValid; } + virtual bool exists() const { return true; } //FIXME: this is just a stub + virtual String getDisplayName() const { return _displayName; } + virtual String getName() const { return _displayName; } + virtual String getPath() const { return _path; } virtual bool isDirectory() const { return _isDirectory; } - virtual String path() const { return _path; } + virtual bool isReadable() const { return true; } //FIXME: this is just a stub + virtual bool isValid() const { return _isValid; } + virtual bool isWritable() const { return true; } //FIXME: this is just a stub - virtual bool listDir(AbstractFSList &list, ListMode mode) const; - virtual AbstractFilesystemNode *parent() const; - virtual AbstractFilesystemNode *child(const String &n) const; + virtual AbstractFilesystemNode *getChild(const String &n) const; + virtual bool getChildren(AbstractFSList &list, ListMode mode) const; + virtual AbstractFilesystemNode *getParent() const; private: - static void addFile (AbstractFSList &list, ListMode mode, const Char *base, FileInfoType* find_data); + /** + * Adds a single WindowsFilesystemNode to a given list. + * This method is used by getChildren() to populate the directory entries list. + * + * @param list List to put the file entry node in. + * @param mode Mode to use while adding the file entry to the list. + * @param base String with the directory being listed. + * @param find_data Describes a file that the FindFirstFile, FindFirstFileEx, or FindNextFile functions find. + */ + static void addFile(AbstractFSList &list, ListMode mode, const Char *base, FileInfoType* find_data); }; +/** + * Returns the last component of a given path. + * + * Examples: + * /foo/bar.txt would return /bar.txt + * /foo/bar/ would return /bar/ + * + * @param str String containing the path. + * @return Pointer to the first char of the last component inside str. + */ static const char *lastPathComponent(const Common::String &str) { const char *start = str.c_str(); const char *cur = start + str.size() - 2; @@ -95,19 +127,6 @@ void PalmOSFilesystemNode::addFile(AbstractFSList &list, ListMode mode, const ch list.push_back(new PalmOSFilesystemNode(entry)); } -AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { - return AbstractFilesystemNode::getRoot(); -} - -AbstractFilesystemNode *AbstractFilesystemNode::getRoot() { - return new PalmOSFilesystemNode(); -} - -AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) { - return new PalmOSFilesystemNode(path); -} - - PalmOSFilesystemNode::PalmOSFilesystemNode() { _isDirectory = true; _displayName = "Root"; @@ -122,13 +141,13 @@ PalmOSFilesystemNode::PalmOSFilesystemNode(const String &p) { UInt32 attr; FileRef handle; - Err e = VFSFileOpen(gVars->VFS.volRefNum, _path.c_str(), vfsModeRead, &handle); - if (!e) { - e = VFSFileGetAttributes(handle, &attr); + Err error = VFSFileOpen(gVars->VFS.volRefNum, _path.c_str(), vfsModeRead, &handle); + if (!error) { + error = VFSFileGetAttributes(handle, &attr); VFSFileClose(handle); } - if (e) { + if (error) { _isValid = false; _isDirectory = false; @@ -139,8 +158,31 @@ PalmOSFilesystemNode::PalmOSFilesystemNode(const String &p) { _isPseudoRoot = false; } -bool PalmOSFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const { - Err e; +AbstractFilesystemNode *PalmOSFilesystemNode::getChild(const String &n) const { + assert(_isDirectory); + + String newPath(_path); + if (_path.lastChar() != '/') + newPath += '/'; + newPath += n; + + FileRef handle; + UInt32 attr; + Err error = VFSFileOpen(gVars->VFS.volRefNum, newPath.c_str(), vfsModeRead, &handle); + if (error) + return 0; + + error = VFSFileGetAttributes(handle, &attr); + VFSFileClose(handle); + + if (error || !(attr & vfsFileAttrDirectory)) + return 0; + + return new PalmOSFilesystemNode(newPath); +} + +bool PalmOSFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode) const { + Err error; Char nameP[256]; FileInfoType desc; FileRef handle; @@ -148,14 +190,14 @@ bool PalmOSFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const desc.nameP = nameP; desc.nameBufLen = 256; - e = VFSFileOpen(gVars->VFS.volRefNum, _path.c_str(), vfsModeRead, &handle); + error = VFSFileOpen(gVars->VFS.volRefNum, _path.c_str(), vfsModeRead, &handle); - if (e) + if (error) return false; while(dirIterator != expIteratorStop) { - e = VFSDirEntryEnumerate(handle, &dirIterator, &desc); - if (!e) { + error = VFSDirEntryEnumerate(handle, &dirIterator, &desc); + if (!error) { addFile(myList, mode, _path.c_str(), &desc); } } @@ -165,8 +207,7 @@ bool PalmOSFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const return true; } - -AbstractFilesystemNode *PalmOSFilesystemNode::parent() const { +AbstractFilesystemNode *PalmOSFilesystemNode::getParent() const { PalmOSFilesystemNode *p = 0; if (!_isPseudoRoot) { @@ -180,31 +221,7 @@ AbstractFilesystemNode *PalmOSFilesystemNode::parent() const { p->_displayName = lastPathComponent(p->_path); p->_isPseudoRoot =(p->_path == "/"); } - return p; -} - - -AbstractFilesystemNode *PalmOSFilesystemNode::child(const String &n) const { - assert(_isDirectory); - String newPath(_path); - - if (_path.lastChar() != '/') - newPath += '/'; - newPath += n; - - FileRef handle; - UInt32 attr; - Err e = VFSFileOpen(gVars->VFS.volRefNum, newPath.c_str(), vfsModeRead, &handle); - if (e) - return 0; - e = VFSFileGetAttributes(handle, &attr); - VFSFileClose(handle); - - if (e || !(attr & vfsFileAttrDirectory)) - return 0; - - PalmOSFilesystemNode *p = new PalmOSFilesystemNode(newPath); return p; } diff --git a/backends/fs/posix/posix-fs-factory.cpp b/backends/fs/posix/posix-fs-factory.cpp new file mode 100644 index 0000000000..bed3dc5f8f --- /dev/null +++ b/backends/fs/posix/posix-fs-factory.cpp @@ -0,0 +1,18 @@ +#include "backends/fs/posix/posix-fs-factory.h" +#include "backends/fs/posix/posix-fs.cpp" + +DECLARE_SINGLETON(POSIXFilesystemFactory); + +AbstractFilesystemNode *POSIXFilesystemFactory::makeRootFileNode() const { + return new POSIXFilesystemNode(); +} + +AbstractFilesystemNode *POSIXFilesystemFactory::makeCurrentDirectoryFileNode() const { + char buf[MAXPATHLEN]; + getcwd(buf, MAXPATHLEN); + return new POSIXFilesystemNode(buf, true); +} + +AbstractFilesystemNode *POSIXFilesystemFactory::makeFileNodePath(const String &path) const { + return new POSIXFilesystemNode(path, true); +} diff --git a/backends/fs/posix/posix-fs-factory.h b/backends/fs/posix/posix-fs-factory.h new file mode 100644 index 0000000000..93f0ac115b --- /dev/null +++ b/backends/fs/posix/posix-fs-factory.h @@ -0,0 +1,27 @@ +#ifndef POSIX_FILESYSTEM_FACTORY_H +#define POSIX_FILESYSTEM_FACTORY_H + +#include "common/singleton.h" +#include "backends/fs/abstract-fs-factory.h" + +/** + * Creates POSIXFilesystemNode objects. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemFactory. + */ +class POSIXFilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<POSIXFilesystemFactory> { +public: + typedef Common::String String; + + virtual AbstractFilesystemNode *makeRootFileNode() const; + virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const; + virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const; + +protected: + POSIXFilesystemFactory() {}; + +private: + friend class Common::Singleton<SingletonBaseType>; +}; + +#endif /*POSIX_FILESYSTEM_FACTORY_H*/ diff --git a/backends/fs/posix/posix-fs.cpp b/backends/fs/posix/posix-fs.cpp index ba1668a390..385bab833c 100644 --- a/backends/fs/posix/posix-fs.cpp +++ b/backends/fs/posix/posix-fs.cpp @@ -25,7 +25,6 @@ #if defined(UNIX) #include "common/stdafx.h" - #include "backends/fs/abstract-fs.h" #ifdef MACOSX @@ -37,33 +36,61 @@ #include <stdio.h> #include <unistd.h> -/* +/** * Implementation of the ScummVM file system API based on POSIX. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemNode. */ - class POSIXFilesystemNode : public AbstractFilesystemNode { protected: String _displayName; + String _path; bool _isDirectory; bool _isValid; - String _path; public: + /** + * Creates a POSIXFilesystemNode with the root node as path. + */ POSIXFilesystemNode(); + + /** + * Creates a POSIXFilesystemNode for a given path. + * + * @param path String with the path the new node should point to. + * @param verify true if the isValid and isDirectory flags should be verified during the construction. + */ POSIXFilesystemNode(const String &path, bool verify); - - virtual String displayName() const { return _displayName; } - virtual String name() const { return _displayName; } - virtual bool isValid() const { return _isValid; } + + virtual bool exists() const { return access(_path.c_str(), F_OK) == 0; } + virtual String getDisplayName() const { return _displayName; } + virtual String getName() const { return _displayName; } + virtual String getPath() const { return _path; } virtual bool isDirectory() const { return _isDirectory; } - virtual String path() const { return _path; } - - virtual bool listDir(AbstractFSList &list, ListMode mode) const; - virtual AbstractFilesystemNode *parent() const; - virtual AbstractFilesystemNode *child(const String &n) const; + virtual bool isReadable() const { return access(_path.c_str(), R_OK) == 0; } + virtual bool isWritable() const { return access(_path.c_str(), W_OK) == 0; } + + virtual AbstractFilesystemNode *getChild(const String &n) const; + virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const; + virtual AbstractFilesystemNode *getParent() const; + +private: + /** + * Tests and sets the _isValid and _isDirectory flags, using the stat() function. + */ + virtual void setFlags(); }; - +/** + * Returns the last component of a given path. + * + * Examples: + * /foo/bar.txt would return /bar.txt + * /foo/bar/ would return /bar/ + * + * @param str String containing the path. + * @return Pointer to the first char of the last component inside str. + */ static const char *lastPathComponent(const Common::String &str) { const char *start = str.c_str(); const char *cur = start + str.size() - 2; @@ -75,18 +102,11 @@ static const char *lastPathComponent(const Common::String &str) { return cur + 1; } -AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { - char buf[MAXPATHLEN]; - getcwd(buf, MAXPATHLEN); - return new POSIXFilesystemNode(buf, true); -} - -AbstractFilesystemNode *AbstractFilesystemNode::getRoot() { - return new POSIXFilesystemNode(); -} - -AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) { - return new POSIXFilesystemNode(path, true); +void POSIXFilesystemNode::setFlags() { + struct stat st; + + _isValid = (0 == stat(_path.c_str(), &st)); + _isDirectory = _isValid ? S_ISDIR(st.st_mode) : false; } POSIXFilesystemNode::POSIXFilesystemNode() { @@ -123,30 +143,44 @@ POSIXFilesystemNode::POSIXFilesystemNode(const String &p, bool verify) { _path = p; _displayName = lastPathComponent(_path); - _isValid = true; - _isDirectory = true; if (verify) { - struct stat st; - _isValid = (0 == stat(_path.c_str(), &st)); - _isDirectory = _isValid ? S_ISDIR(st.st_mode) : false; + setFlags(); } } -bool POSIXFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const { +AbstractFilesystemNode *POSIXFilesystemNode::getChild(const String &n) const { + // FIXME: Pretty lame implementation! We do no error checking to speak + // of, do not check if this is a special node, etc. assert(_isDirectory); - DIR *dirp = opendir(_path.c_str()); + + String newPath(_path); + if (_path.lastChar() != '/') + newPath += '/'; + newPath += n; + + return new POSIXFilesystemNode(newPath, true); +} +bool POSIXFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const { + assert(_isDirectory); + + DIR *dirp = opendir(_path.c_str()); struct dirent *dp; if (dirp == NULL) return false; - // ... loop over dir entries using readdir + // loop over dir entries using readdir while ((dp = readdir(dirp)) != NULL) { - // Skip 'invisible' files - if (dp->d_name[0] == '.') + // Skip 'invisible' files if necessary + if (dp->d_name[0] == '.' && !hidden) { + continue; + } + // Skip '.' and '..' to avoid cycles + if((dp->d_name[0] == '.' && dp->d_name[1] == 0) || (dp->d_name[0] == '.' && dp->d_name[1] == '.')) { continue; + } String newPath(_path); if (newPath.lastChar() != '/') @@ -156,18 +190,18 @@ bool POSIXFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const { POSIXFilesystemNode entry(newPath, false); #if defined(SYSTEM_NOT_SUPPORTING_D_TYPE) - // TODO: d_type is not part of POSIX, so it might not be supported - // on some of our targets. For those systems where it isn't supported, - // add this #elif case, which tries to use stat() instead. - struct stat st; - entry._isValid = (0 == stat(entry._path.c_str(), &st)); - entry._isDirectory = entry._isValid ? S_ISDIR(st.st_mode) : false; + /* TODO: d_type is not part of POSIX, so it might not be supported + * on some of our targets. For those systems where it isn't supported, + * add this #elif case, which tries to use stat() instead. + * + * The d_type method is used to avoid costly recurrent stat() calls in big + * directories. + */ + entry.setFlags(); #else if (dp->d_type == DT_UNKNOWN) { // Fall back to stat() - struct stat st; - entry._isValid = (0 == stat(entry._path.c_str(), &st)); - entry._isDirectory = entry._isValid ? S_ISDIR(st.st_mode) : false; + entry.setFlags(); } else { entry._isValid = (dp->d_type == DT_DIR) || (dp->d_type == DT_REG) || (dp->d_type == DT_LNK); if (dp->d_type == DT_LNK) { @@ -194,35 +228,22 @@ bool POSIXFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const { if (entry._isDirectory) entry._path += "/"; + myList.push_back(new POSIXFilesystemNode(entry)); } closedir(dirp); + return true; } -AbstractFilesystemNode *POSIXFilesystemNode::parent() const { +AbstractFilesystemNode *POSIXFilesystemNode::getParent() const { if (_path == "/") return 0; const char *start = _path.c_str(); const char *end = lastPathComponent(_path); - POSIXFilesystemNode *p = new POSIXFilesystemNode(String(start, end - start), false); - - return p; -} - -AbstractFilesystemNode *POSIXFilesystemNode::child(const String &n) const { - // FIXME: Pretty lame implementation! We do no error checking to speak - // of, do not check if this is a special node, etc. - assert(_isDirectory); - String newPath(_path); - if (_path.lastChar() != '/') - newPath += '/'; - newPath += n; - POSIXFilesystemNode *p = new POSIXFilesystemNode(newPath, true); - - return p; + return new POSIXFilesystemNode(String(start, end - start), false); } -#endif // defined(UNIX) +#endif //#if defined(UNIX) diff --git a/backends/fs/ps2/ps2-fs-factory.cpp b/backends/fs/ps2/ps2-fs-factory.cpp new file mode 100644 index 0000000000..5f10974501 --- /dev/null +++ b/backends/fs/ps2/ps2-fs-factory.cpp @@ -0,0 +1,16 @@ +#include "backends/fs/ps2/ps2-fs-factory.h" +#include "backends/fs/ps2/ps2-fs.cpp" + +DECLARE_SINGLETON(Ps2FilesystemFactory); + +AbstractFilesystemNode *Ps2FilesystemFactory::makeRootFileNode() const { + return new Ps2FilesystemNode(); +} + +AbstractFilesystemNode *Ps2FilesystemFactory::makeCurrentDirectoryFileNode() const { + return new Ps2FilesystemNode(); +} + +AbstractFilesystemNode *Ps2FilesystemFactory::makeFileNodePath(const String &path) const { + return new Ps2FilesystemNode(path); +} diff --git a/backends/fs/ps2/ps2-fs-factory.h b/backends/fs/ps2/ps2-fs-factory.h new file mode 100644 index 0000000000..6f0da114c5 --- /dev/null +++ b/backends/fs/ps2/ps2-fs-factory.h @@ -0,0 +1,27 @@ +#ifndef PS2_FILESYSTEM_FACTORY_H +#define PS2_FILESYSTEM_FACTORY_H + +#include "common/singleton.h" +#include "backends/fs/abstract-fs-factory.h" + +/** + * Creates PS2FilesystemNode objects. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemFactory. + */ +class Ps2FilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<Ps2FilesystemFactory> { +public: + typedef Common::String String; + + virtual AbstractFilesystemNode *makeRootFileNode() const; + virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const; + virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const; + +protected: + Ps2FilesystemFactory() {}; + +private: + friend class Common::Singleton<SingletonBaseType>; +}; + +#endif /*PS2_FILESYSTEM_FACTORY_H*/ diff --git a/backends/fs/ps2/ps2-fs.cpp b/backends/fs/ps2/ps2-fs.cpp index afe1842e43..9d8e360f64 100644 --- a/backends/fs/ps2/ps2-fs.cpp +++ b/backends/fs/ps2/ps2-fs.cpp @@ -32,44 +32,52 @@ extern AsyncFio fio; extern OSystem_PS2 *g_systemPs2; +/** + * Implementation of the ScummVM file system API based on the Ps2SDK. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemNode. + */ class Ps2FilesystemNode : public AbstractFilesystemNode { protected: String _displayName; + String _path; bool _isDirectory; bool _isRoot; - String _path; public: - Ps2FilesystemNode(void); - Ps2FilesystemNode(const Ps2FilesystemNode *node); + /** + * Creates a PS2FilesystemNode with the root node as path. + */ + Ps2FilesystemNode(); + + /** + * Creates a PS2FilesystemNode for a given path. + * + * @param path String with the path the new node should point to. + */ Ps2FilesystemNode(const String &path); + + /** + * Copy constructor. + */ + Ps2FilesystemNode(const Ps2FilesystemNode *node); - virtual String displayName() const { return _displayName; } - virtual String name() const { return _displayName; } - virtual bool isValid() const { return !_isRoot; } + virtual bool exists() const { return true; } //FIXME: this is just a stub + virtual String getDisplayName() const { return _displayName; } + virtual String getName() const { return _displayName; } + virtual String getPath() const { return _path; } virtual bool isDirectory() const { return _isDirectory; } - virtual String path() const { return _path; } + virtual bool isReadable() const { return true; } //FIXME: this is just a stub + virtual bool isValid() const { return !_isRoot; } + virtual bool isWritable() const { return true; } //FIXME: this is just a stub - //virtual FSList listDir(ListMode) const; - virtual bool listDir(AbstractFSList &list, ListMode mode) const; - virtual AbstractFilesystemNode *parent() const; virtual AbstractFilesystemNode *clone() const { return new Ps2FilesystemNode(this); } - virtual AbstractFilesystemNode *child(const String &n) const; + virtual AbstractFilesystemNode *getChild(const String &n) const; + virtual bool getChildren(AbstractFSList &list, ListMode mode) const; + virtual AbstractFilesystemNode *getParent() const; }; -AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { - return AbstractFilesystemNode::getRoot(); -} - -AbstractFilesystemNode *AbstractFilesystemNode::getRoot(void) { - return new Ps2FilesystemNode(); -} - -AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) { - return new Ps2FilesystemNode(path); -} - -Ps2FilesystemNode::Ps2FilesystemNode(void) { +Ps2FilesystemNode::Ps2FilesystemNode() { _isDirectory = true; _isRoot = true; _displayName = "PlayStation 2"; @@ -108,7 +116,41 @@ Ps2FilesystemNode::Ps2FilesystemNode(const Ps2FilesystemNode *node) { _isRoot = node->_isRoot; } -bool Ps2FilesystemNode::listDir(AbstractFSList &list, ListMode mode) const { +AbstractFilesystemNode *Ps2FilesystemNode::getChild(const String &n) const { + if (!_isDirectory) + return NULL; + + char listDir[256]; + sprintf(listDir, "%s/", _path.c_str()); + int fd = fio.dopen(listDir); + + if (fd >= 0) { + iox_dirent_t dirent; + + while (fio.dread(fd, &dirent) > 0) { + if (strcmp(n.c_str(), dirent.name) == 0) { + Ps2FilesystemNode *dirEntry = new Ps2FilesystemNode(); + + dirEntry->_isDirectory = (bool)(dirent.stat.mode & FIO_S_IFDIR); + dirEntry->_isRoot = false; + + dirEntry->_path = _path; + dirEntry->_path += "/"; + dirEntry->_path += dirent.name; + + dirEntry->_displayName = dirent.name; + + fio.dclose(fd); + return dirEntry; + } + } + fio.dclose(fd); + } + + return NULL; +} + +bool Ps2FilesystemNode::getChildren(AbstractFSList &list, ListMode mode) const { if (!_isDirectory) return false; @@ -135,6 +177,7 @@ bool Ps2FilesystemNode::listDir(AbstractFSList &list, ListMode mode) const { } else { char listDir[256]; int fd; + if (_path.lastChar() == '/') fd = fio.dopen(_path.c_str()); else { @@ -173,7 +216,7 @@ bool Ps2FilesystemNode::listDir(AbstractFSList &list, ListMode mode) const { } } -AbstractFilesystemNode *Ps2FilesystemNode::parent() const { +AbstractFilesystemNode *Ps2FilesystemNode::getParent() const { if (_isRoot) return new Ps2FilesystemNode(this); @@ -191,36 +234,3 @@ AbstractFilesystemNode *Ps2FilesystemNode::parent() const { else return new Ps2FilesystemNode(); } - -AbstractFilesystemNode *Ps2FilesystemNode::child(const String &n) const { - if (!_isDirectory) - return NULL; - - char listDir[256]; - sprintf(listDir, "%s/", _path.c_str()); - int fd = fio.dopen(listDir); - - if (fd >= 0) { - iox_dirent_t dirent; - - while (fio.dread(fd, &dirent) > 0) { - if (strcmp(n.c_str(), dirent.name) == 0) { - Ps2FilesystemNode *dirEntry = new Ps2FilesystemNode(); - - dirEntry->_isDirectory = (bool)(dirent.stat.mode & FIO_S_IFDIR); - dirEntry->_isRoot = false; - - dirEntry->_path = _path; - dirEntry->_path += "/"; - dirEntry->_path += dirent.name; - - dirEntry->_displayName = dirent.name; - - fio.dclose(fd); - return dirEntry; - } - } - fio.dclose(fd); - } - return NULL; -} diff --git a/backends/fs/psp/psp-fs-factory.cpp b/backends/fs/psp/psp-fs-factory.cpp new file mode 100644 index 0000000000..6fc829baf1 --- /dev/null +++ b/backends/fs/psp/psp-fs-factory.cpp @@ -0,0 +1,16 @@ +#include "backends/fs/psp/psp-fs-factory.h" +#include "backends/fs/psp/psp_fs.cpp" + +DECLARE_SINGLETON(PSPFilesystemFactory); + +AbstractFilesystemNode *PSPFilesystemFactory::makeRootFileNode() const { + return new PSPFilesystemNode(); +} + +AbstractFilesystemNode *PSPFilesystemFactory::makeCurrentDirectoryFileNode() const { + return new PSPFilesystemNode(); +} + +AbstractFilesystemNode *PSPFilesystemFactory::makeFileNodePath(const String &path) const { + return new PSPFilesystemNode(path, true); +} diff --git a/backends/fs/psp/psp-fs-factory.h b/backends/fs/psp/psp-fs-factory.h new file mode 100644 index 0000000000..b1a44b90c4 --- /dev/null +++ b/backends/fs/psp/psp-fs-factory.h @@ -0,0 +1,27 @@ +#ifndef PSP_FILESYSTEM_FACTORY_H +#define PSP_FILESYSTEM_FACTORY_H + +#include "common/singleton.h" +#include "backends/fs/abstract-fs-factory.h" + +/** + * Creates PSPFilesystemNode objects. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemFactory. + */ +class PSPFilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<PSPFilesystemFactory> { +public: + typedef Common::String String; + + virtual AbstractFilesystemNode *makeRootFileNode() const; + virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const; + virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const; + +protected: + PSPFilesystemFactory() {}; + +private: + friend class Common::Singleton<SingletonBaseType>; +}; + +#endif /*PSP_FILESYSTEM_FACTORY_H*/ diff --git a/backends/fs/psp/psp_fs.cpp b/backends/fs/psp/psp_fs.cpp index 3f25a63f86..5b0faf3847 100644 --- a/backends/fs/psp/psp_fs.cpp +++ b/backends/fs/psp/psp_fs.cpp @@ -23,8 +23,8 @@ */ #ifdef __PSP__ -#include "engines/engine.h" +#include "engines/engine.h" #include "backends/fs/abstract-fs.h" #include <sys/stat.h> @@ -32,39 +32,65 @@ #define ROOT_PATH "ms0:/" - -/* +/** * Implementation of the ScummVM file system API based on PSPSDK API. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemNode. */ - class PSPFilesystemNode : public AbstractFilesystemNode { protected: String _displayName; + String _path; bool _isDirectory; bool _isValid; - String _path; public: + /** + * Creates a PSPFilesystemNode with the root node as path. + */ PSPFilesystemNode(); + + /** + * Creates a PSPFilesystemNode for a given path. + * + * @param path String with the path the new node should point to. + * @param verify true if the isValid and isDirectory flags should be verified during the construction. + */ PSPFilesystemNode(const Common::String &p, bool verify); - virtual String displayName() const { return _displayName; } - virtual String name() const { return _displayName; } - virtual bool isValid() const { return _isValid; } + virtual bool exists() const { return true; } //FIXME: this is just a stub + virtual String getDisplayName() const { return _displayName; } + virtual String getName() const { return _displayName; } + virtual String getPath() const { return _path; } virtual bool isDirectory() const { return _isDirectory; } - virtual String path() const { return _path; } + virtual bool isReadable() const { return true; } //FIXME: this is just a stub + virtual bool isValid() const { return _isValid; } + virtual bool isWritable() const { return true; } //FIXME: this is just a stub - virtual bool listDir(AbstractFSList &list, ListMode mode) const; - virtual AbstractFilesystemNode *parent() const; - virtual AbstractFilesystemNode *child(const String &n) const; + virtual AbstractFilesystemNode *getChild(const String &n) const; + virtual bool getChildren(AbstractFSList &list, ListMode mode) const; + virtual AbstractFilesystemNode *getParent() const; }; -AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { - return AbstractFilesystemNode::getRoot(); -} +/** + * Returns the last component of a given path. + * + * Examples: + * /foo/bar.txt would return /bar.txt + * /foo/bar/ would return /bar/ + * + * @param str String containing the path. + * @return Pointer to the first char of the last component inside str. + */ +static const char *lastPathComponent(const Common::String &str) { + const char *start = str.c_str(); + const char *cur = start + str.size() - 2; -AbstractFilesystemNode *AbstractFilesystemNode::getRoot() { - return new PSPFilesystemNode(); + while (cur >= start && *cur != '/') { + --cur; + } + + return cur + 1; } PSPFilesystemNode::PSPFilesystemNode() { @@ -89,12 +115,20 @@ PSPFilesystemNode::PSPFilesystemNode(const Common::String &p, bool verify) { } } -AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) { - return new PSPFilesystemNode(path, true); -} +AbstractFilesystemNode *PSPFilesystemNode::getChild(const String &n) const { + // FIXME: Pretty lame implementation! We do no error checking to speak + // of, do not check if this is a special node, etc. + assert(_isDirectory); + + String newPath(_path); + if (_path.lastChar() != '/') + newPath += '/'; + newPath += n; + return new PSPFilesystemNode(newPath, true); +} -bool PSPFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const { +bool PSPFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode) const { assert(_isDirectory); int dfd = sceIoDopen(_path.c_str()); @@ -133,18 +167,7 @@ bool PSPFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const { } } -static const char *lastPathComponent(const Common::String &str) { - const char *start = str.c_str(); - const char *cur = start + str.size() - 2; - - while (cur >= start && *cur != '/') { - --cur; - } - - return cur + 1; -} - -AbstractFilesystemNode *PSPFilesystemNode::parent() const { +AbstractFilesystemNode *PSPFilesystemNode::getParent() const { assert(_isValid); if (_path == ROOT_PATH) @@ -153,22 +176,7 @@ AbstractFilesystemNode *PSPFilesystemNode::parent() const { const char *start = _path.c_str(); const char *end = lastPathComponent(_path); - PSPFilesystemNode *p = new PSPFilesystemNode(String(start, end - start), false); - - return p; -} - -AbstractFilesystemNode *PSPFilesystemNode::child(const String &n) const { - // FIXME: Pretty lame implementation! We do no error checking to speak - // of, do not check if this is a special node, etc. - assert(_isDirectory); - String newPath(_path); - if (_path.lastChar() != '/') - newPath += '/'; - newPath += n; - PSPFilesystemNode *p = new PSPFilesystemNode(newPath, true); - - return p; + return new PSPFilesystemNode(String(start, end - start), false); } -#endif // PSP +#endif //#ifdef __PSP__ diff --git a/backends/fs/symbian/symbian-fs-factory.cpp b/backends/fs/symbian/symbian-fs-factory.cpp new file mode 100644 index 0000000000..87b1f0f05d --- /dev/null +++ b/backends/fs/symbian/symbian-fs-factory.cpp @@ -0,0 +1,18 @@ +#include "backends/fs/symbian/symbian-fs-factory.h" +#include "backends/fs/symbian/symbian-fs.cpp" + +DECLARE_SINGLETON(SymbianFilesystemFactory); + +AbstractFilesystemNode *SymbianFilesystemFactory::makeRootFileNode() const { + return new SymbianFilesystemNode(true); +} + +AbstractFilesystemNode *SymbianFilesystemFactory::makeCurrentDirectoryFileNode() const { + char path[MAXPATHLEN]; + getcwd(path, MAXPATHLEN); + return new SymbianFilesystemNode(path); +} + +AbstractFilesystemNode *SymbianFilesystemFactory::makeFileNodePath(const String &path) const { + return new SymbianFilesystemNode(path); +} diff --git a/backends/fs/symbian/symbian-fs-factory.h b/backends/fs/symbian/symbian-fs-factory.h new file mode 100644 index 0000000000..69749cbd7e --- /dev/null +++ b/backends/fs/symbian/symbian-fs-factory.h @@ -0,0 +1,27 @@ +#ifndef SYMBIAN_FILESYSTEM_FACTORY_H +#define SYMBIAN_FILESYSTEM_FACTORY_H + +#include "common/singleton.h" +#include "backends/fs/abstract-fs-factory.h" + +/** + * Creates SymbianFilesystemNode objects. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemFactory. + */ +class SymbianFilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<SymbianFilesystemFactory> { +public: + typedef Common::String String; + + virtual AbstractFilesystemNode *makeRootFileNode() const; + virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const; + virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const; + +protected: + SymbianFilesystemFactory() {}; + +private: + friend class Common::Singleton<SingletonBaseType>; +}; + +#endif /*SYMBIAN_FILESYSTEM_FACTORY_H*/ diff --git a/backends/fs/symbian/symbian-fs.cpp b/backends/fs/symbian/symbian-fs.cpp index 8a4c2abaf2..5c3dd74f5c 100644 --- a/backends/fs/symbian/symbian-fs.cpp +++ b/backends/fs/symbian/symbian-fs.cpp @@ -31,33 +31,58 @@ #include <f32file.h> #include <bautils.h> -/* +/** * Implementation of the ScummVM file system API based on POSIX. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemNode. */ - class SymbianFilesystemNode : public AbstractFilesystemNode { protected: String _displayName; + String _path; bool _isDirectory; bool _isValid; - String _path; bool _isPseudoRoot; public: + /** + * Creates a SymbianFilesystemNode with the root node as path. + * + * @param aIsRoot true if the node will be a pseudo root, false otherwise. + */ SymbianFilesystemNode(bool aIsRoot); + + /** + * Creates a SymbianFilesystemNode for a given path. + * + * @param path String with the path the new node should point to. + */ SymbianFilesystemNode(const String &path); - virtual String displayName() const { return _displayName; } - virtual String name() const { return _displayName; } - virtual bool isValid() const { return _isValid; } + + virtual bool exists() const { return true; } //FIXME: this is just a stub + virtual String getDisplayName() const { return _displayName; } + virtual String getName() const { return _displayName; } + virtual String getPath() const { return _path; } virtual bool isDirectory() const { return _isDirectory; } - virtual String path() const { return _path; } + virtual bool isReadable() const { return true; } //FIXME: this is just a stub + virtual bool isValid() const { return _isValid; } + virtual bool isWritable() const { return true; } //FIXME: this is just a stub - virtual bool listDir(AbstractFSList &list, ListMode mode) const; - virtual AbstractFilesystemNode *parent() const; - virtual AbstractFilesystemNode *child(const String &n) const; + virtual AbstractFilesystemNode *getChild(const String &n) const; + virtual bool getChildren(AbstractFSList &list, ListMode mode) const; + virtual AbstractFilesystemNode *getParent() const; }; - +/** + * Returns the last component of a given path. + * + * Examples: + * c:\foo\bar.txt would return "\bar.txt" + * c:\foo\bar\ would return "\bar\" + * + * @param str Path to obtain the last component from. + * @return Pointer to the first char of the last component inside str. + */ static const char *lastPathComponent(const Common::String &str) { const char *start = str.c_str(); const char *cur = start + str.size() - 2; @@ -69,6 +94,11 @@ static const char *lastPathComponent(const Common::String &str) { return cur + 1; } +/** + * Fixes the path by changing all slashes to backslashes. + * + * @param path String with the path to be fixed. + */ static void fixFilePath(Common::String& path) { TInt len = path.size(); @@ -79,20 +109,6 @@ static void fixFilePath(Common::String& path) { } } -AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { - char path[MAXPATHLEN]; - getcwd(path, MAXPATHLEN); - return new SymbianFilesystemNode(path); -} - -AbstractFilesystemNode *AbstractFilesystemNode::getRoot() { - return new SymbianFilesystemNode(true); -} - -AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) { - return new SymbianFilesystemNode(path); -} - SymbianFilesystemNode::SymbianFilesystemNode(bool aIsRoot) { _path = ""; _isValid = true; @@ -128,7 +144,26 @@ SymbianFilesystemNode::SymbianFilesystemNode(const String &path) { } } -bool SymbianFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const { +AbstractFilesystemNode *SymbianFilesystemNode::getChild(const String &n) const { + assert(_isDirectory); + String newPath(_path); + + if (_path.lastChar() != '\\') + newPath += '\\'; + newPath += n; + + TPtrC8 ptr((const unsigned char*) newPath.c_str(), newPath.size()); + TFileName fname; + fname.Copy(ptr); + TBool isFolder = EFalse; + BaflUtils::IsFolder(CEikonEnv::Static()->FsSession(), fname, isFolder); + if(!isFolder) + return 0; + + return new SymbianFilesystemNode(newPath); +} + +bool SymbianFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode) const { assert(_isDirectory); if (_isPseudoRoot) { @@ -199,18 +234,18 @@ bool SymbianFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const } CleanupStack::PopAndDestroy(dirPtr); } - } + return true; } -AbstractFilesystemNode *SymbianFilesystemNode::parent() const { +AbstractFilesystemNode *SymbianFilesystemNode::getParent() const { SymbianFilesystemNode *p =NULL; // Root node is its own parent. Still we can't just return this // as the GUI code will call delete on the old node. if (!_isPseudoRoot && _path.size() > 3) { - p=new SymbianFilesystemNode(false); + p = new SymbianFilesystemNode(false); const char *start = _path.c_str(); const char *end = lastPathComponent(_path); @@ -221,29 +256,10 @@ AbstractFilesystemNode *SymbianFilesystemNode::parent() const { } else { - p=new SymbianFilesystemNode(true); + p = new SymbianFilesystemNode(true); } + return p; } -AbstractFilesystemNode *SymbianFilesystemNode::child(const String &n) const { - assert(_isDirectory); - String newPath(_path); - - if (_path.lastChar() != '\\') - newPath += '\\'; - newPath += n; - - TPtrC8 ptr((const unsigned char*) newPath.c_str(), newPath.size()); - TFileName fname; - fname.Copy(ptr); - TBool isFolder = EFalse; - BaflUtils::IsFolder(CEikonEnv::Static()->FsSession(), fname, isFolder); - if(!isFolder) - return 0; - - SymbianFilesystemNode *p = new SymbianFilesystemNode(newPath); - return p; -} - -#endif // defined(__SYMBIAN32__) +#endif //#if defined (__SYMBIAN32__) diff --git a/backends/fs/windows/windows-fs-factory.cpp b/backends/fs/windows/windows-fs-factory.cpp new file mode 100644 index 0000000000..76b62e5deb --- /dev/null +++ b/backends/fs/windows/windows-fs-factory.cpp @@ -0,0 +1,16 @@ +#include "backends/fs/windows/windows-fs-factory.h" +#include "backends/fs/windows/windows-fs.cpp" + +DECLARE_SINGLETON(WindowsFilesystemFactory); + +AbstractFilesystemNode *WindowsFilesystemFactory::makeRootFileNode() const { + return new WindowsFilesystemNode(); +} + +AbstractFilesystemNode *WindowsFilesystemFactory::makeCurrentDirectoryFileNode() const { + return new WindowsFilesystemNode(NULL, true); +} + +AbstractFilesystemNode *WindowsFilesystemFactory::makeFileNodePath(const String &path) const { + return new WindowsFilesystemNode(path, false); +} diff --git a/backends/fs/windows/windows-fs-factory.h b/backends/fs/windows/windows-fs-factory.h new file mode 100644 index 0000000000..7d17802b52 --- /dev/null +++ b/backends/fs/windows/windows-fs-factory.h @@ -0,0 +1,27 @@ +#ifndef WINDOWS_FILESYSTEM_FACTORY_H +#define WINDOWS_FILESYSTEM_FACTORY_H + +#include "common/singleton.h" +#include "backends/fs/abstract-fs-factory.h" + +/** + * Creates WindowsFilesystemNode objects. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemFactory. + */ +class WindowsFilesystemFactory : public AbstractFilesystemFactory, public Common::Singleton<WindowsFilesystemFactory> { +public: + typedef Common::String String; + + virtual AbstractFilesystemNode *makeRootFileNode() const; + virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const; + virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const; + +protected: + WindowsFilesystemFactory() {}; + +private: + friend class Common::Singleton<SingletonBaseType>; +}; + +#endif /*WINDOWS_FILESYSTEM_FACTORY_H*/ diff --git a/backends/fs/windows/windows-fs.cpp b/backends/fs/windows/windows-fs.cpp index 0e12c4a96a..5a9e1c65b6 100644 --- a/backends/fs/windows/windows-fs.cpp +++ b/backends/fs/windows/windows-fs.cpp @@ -29,6 +29,7 @@ #endif #include "common/stdafx.h" #include "backends/fs/abstract-fs.h" +#include <io.h> #include <stdio.h> #include <stdlib.h> #ifndef _WIN32_WCE @@ -36,39 +37,93 @@ #endif #include <tchar.h> -/* +/** * Implementation of the ScummVM file system API based on Windows API. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemNode. */ - class WindowsFilesystemNode : public AbstractFilesystemNode { protected: String _displayName; + String _path; bool _isDirectory; - bool _isValid; bool _isPseudoRoot; - String _path; + bool _isValid; public: + /** + * Creates a WindowsFilesystemNode with the root node as path. + * + * In regular windows systems, a virtual root path is used "". + * In windows CE, the "\" root is used instead. + */ WindowsFilesystemNode(); - WindowsFilesystemNode(const String &path); - - virtual String displayName() const { return _displayName; } - virtual String name() const { return _displayName; } - virtual bool isValid() const { return _isValid; } + + /** + * Creates a WindowsFilesystemNode for a given path. + * + * Examples: + * path=c:\foo\bar.txt, currentDir=false -> c:\foo\bar.txt + * path=c:\foo\bar.txt, currentDir=true -> current directory + * path=NULL, currentDir=true -> current directory + * + * @param path String with the path the new node should point to. + * @param currentDir if true, the path parameter will be ignored and the resulting node will point to the current directory. + */ + WindowsFilesystemNode(const String &path, const bool currentDir); + + virtual bool exists() const { return _access(_path.c_str(), F_OK) == 0; } + virtual String getDisplayName() const { return _displayName; } + virtual String getName() const { return _displayName; } + virtual String getPath() const { return _path; } virtual bool isDirectory() const { return _isDirectory; } - virtual String path() const { return _path; } + virtual bool isReadable() const { return _access(_path.c_str(), R_OK) == 0; } + virtual bool isValid() const { return _isValid; } + virtual bool isWritable() const { return _access(_path.c_str(), W_OK) == 0; } - virtual bool listDir(AbstractFSList &list, ListMode mode) const; - virtual AbstractFilesystemNode *parent() const; - virtual AbstractFilesystemNode *child(const String &n) const; + virtual AbstractFilesystemNode *getChild(const String &n) const; + virtual bool getChildren(AbstractFSList &list, ListMode mode) const; + virtual AbstractFilesystemNode *getParent() const; private: - static char *toAscii(TCHAR *x); - static const TCHAR* toUnicode(const char *x); - static void addFile (AbstractFSList &list, ListMode mode, const char *base, WIN32_FIND_DATA* find_data); + /** + * Adds a single WindowsFilesystemNode to a given list. + * This method is used by getChildren() to populate the directory entries list. + * + * @param list List to put the file entry node in. + * @param mode Mode to use while adding the file entry to the list. + * @param base String with the directory being listed. + * @param find_data Describes a file that the FindFirstFile, FindFirstFileEx, or FindNextFile functions find. + */ + static void addFile(AbstractFSList &list, ListMode mode, const char *base, WIN32_FIND_DATA* find_data); + + /** + * Converts a Unicode string to Ascii format. + * + * @param str String to convert from Unicode to Ascii. + * @return str in Ascii format. + */ + static char *toAscii(TCHAR *str); + + /** + * Converts an Ascii string to Unicode format. + * + * @param str String to convert from Ascii to Unicode. + * @return str in Unicode format. + */ + static const TCHAR* toUnicode(const char *str); }; - +/** + * Returns the last component of a given path. + * + * Examples: + * c:\foo\bar.txt would return "\bar.txt" + * c:\foo\bar\ would return "\bar\" + * + * @param str Path to obtain the last component from. + * @return Pointer to the first char of the last component inside str. + */ static const char *lastPathComponent(const Common::String &str) { const char *start = str.c_str(); const char *cur = start + str.size() - 2; @@ -80,27 +135,6 @@ static const char *lastPathComponent(const Common::String &str) { return cur + 1; } -char* WindowsFilesystemNode::toAscii(TCHAR *x) { - -#ifndef UNICODE - return (char*)x; -#else - static char asciiString[MAX_PATH]; - WideCharToMultiByte(CP_ACP, 0, x, _tcslen(x) + 1, asciiString, sizeof(asciiString), NULL, NULL); - return asciiString; -#endif -} - -const TCHAR* WindowsFilesystemNode::toUnicode(const char *x) { -#ifndef UNICODE - return (const TCHAR *)x; -#else - static TCHAR unicodeString[MAX_PATH]; - MultiByteToWideChar(CP_ACP, 0, x, strlen(x) + 1, unicodeString, sizeof(unicodeString) / sizeof(TCHAR)); - return unicodeString; -#endif -} - void WindowsFilesystemNode::addFile(AbstractFSList &list, ListMode mode, const char *base, WIN32_FIND_DATA* find_data) { WindowsFilesystemNode entry; char *asciiName = toAscii(find_data->cFileName); @@ -128,25 +162,24 @@ void WindowsFilesystemNode::addFile(AbstractFSList &list, ListMode mode, const c list.push_back(new WindowsFilesystemNode(entry)); } -AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() { - char path[MAX_PATH]; - GetCurrentDirectory(MAX_PATH, path); - - // Add a trailing slash, if necessary. - if (path[0] != 0) { - if (path[strlen(path) - 1] != '\\') - strcat(path, "\\"); - } - - return new WindowsFilesystemNode(path); -} - -AbstractFilesystemNode *AbstractFilesystemNode::getRoot() { - return new WindowsFilesystemNode(); +char* WindowsFilesystemNode::toAscii(TCHAR *str) { +#ifndef UNICODE + return (char*)str; +#else + static char asciiString[MAX_PATH]; + WideCharToMultiByte(CP_ACP, 0, str, _tcslen(str) + 1, asciiString, sizeof(asciiString), NULL, NULL); + return asciiString; +#endif } -AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) { - return new WindowsFilesystemNode(path); +const TCHAR* WindowsFilesystemNode::toUnicode(const char *str) { +#ifndef UNICODE + return (const TCHAR *)str; +#else + static TCHAR unicodeString[MAX_PATH]; + MultiByteToWideChar(CP_ACP, 0, str, strlen(str) + 1, unicodeString, sizeof(unicodeString) / sizeof(TCHAR)); + return unicodeString; +#endif } WindowsFilesystemNode::WindowsFilesystemNode() { @@ -165,26 +198,55 @@ WindowsFilesystemNode::WindowsFilesystemNode() { #endif } -WindowsFilesystemNode::WindowsFilesystemNode(const String &p) { - assert(p.size() > 0); +WindowsFilesystemNode::WindowsFilesystemNode(const String &p, const bool currentDir) { + if (currentDir) { + char path[MAX_PATH]; + GetCurrentDirectory(MAX_PATH, path); - _path = p; + // Add a trailing slash, if necessary. + if (path[0] != 0) { + if (path[strlen(path) - 1] != '\\') + strcat(path, "\\"); + } + _path = path; + } + else { + assert(p.size() > 0); + _path = p; + } + _displayName = lastPathComponent(_path); // Check whether it is a directory, and whether the file actually exists DWORD fileAttribs = GetFileAttributes(toUnicode(_path.c_str())); if (fileAttribs == INVALID_FILE_ATTRIBUTES) { - _isValid = false; _isDirectory = false; + _isValid = false; } else { - _isValid = true; _isDirectory = ((fileAttribs & FILE_ATTRIBUTE_DIRECTORY) != 0); + _isValid = true; } _isPseudoRoot = false; } -bool WindowsFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const { +AbstractFilesystemNode *WindowsFilesystemNode::getChild(const String &n) const { + assert(_isDirectory); + + String newPath(_path); + if (_path.lastChar() != '\\') + newPath += '\\'; + newPath += n; + + // Check whether the directory actually exists + DWORD fileAttribs = GetFileAttributes(toUnicode(newPath.c_str())); + if (fileAttribs == INVALID_FILE_ATTRIBUTES) + return 0; + + return new WindowsFilesystemNode(newPath, false); +} + +bool WindowsFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode) const { assert(_isDirectory); if (_isPseudoRoot) { @@ -218,9 +280,12 @@ bool WindowsFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const sprintf(searchPath, "%s*", _path.c_str()); handle = FindFirstFile(toUnicode(searchPath), &desc); + if (handle == INVALID_HANDLE_VALUE) return false; + addFile(myList, mode, _path.c_str(), &desc); + while (FindNextFile(handle, &desc)) addFile(myList, mode, _path.c_str(), &desc); @@ -230,10 +295,12 @@ bool WindowsFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const return true; } -AbstractFilesystemNode *WindowsFilesystemNode::parent() const { +AbstractFilesystemNode *WindowsFilesystemNode::getParent() const { assert(_isValid || _isPseudoRoot); + if (_isPseudoRoot) return 0; + WindowsFilesystemNode *p = new WindowsFilesystemNode(); if (_path.size() > 3) { const char *start = _path.c_str(); @@ -246,23 +313,8 @@ AbstractFilesystemNode *WindowsFilesystemNode::parent() const { p->_displayName = lastPathComponent(p->_path); p->_isPseudoRoot = false; } + return p; } -AbstractFilesystemNode *WindowsFilesystemNode::child(const String &n) const { - assert(_isDirectory); - String newPath(_path); - if (_path.lastChar() != '\\') - newPath += '\\'; - newPath += n; - - // Check whether the directory actually exists - DWORD fileAttribs = GetFileAttributes(toUnicode(newPath.c_str())); - if (fileAttribs == INVALID_FILE_ATTRIBUTES) - return 0; - - WindowsFilesystemNode *p = new WindowsFilesystemNode(newPath); - return p; -} - -#endif // WIN32 +#endif //#ifdef WIN32 diff --git a/backends/platform/PalmOS/Src/launcher/forms/formSelect.cpp b/backends/platform/PalmOS/Src/launcher/forms/formSelect.cpp index 641d646bb2..085fb2499a 100755 --- a/backends/platform/PalmOS/Src/launcher/forms/formSelect.cpp +++ b/backends/platform/PalmOS/Src/launcher/forms/formSelect.cpp @@ -18,8 +18,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * $URL$ - * $Id$ + * $URL:https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/branches/gsoc2007-fsnode/backends/platform/PalmOS/Src/launcher/forms/formSelect.cpp $ + * $Id:formSelect.cpp 26949 2007-05-26 20:23:24Z david_corrales $ * */ diff --git a/backends/platform/ds/arm9/makefile.in b/backends/platform/ds/arm9/makefile.in deleted file mode 100644 index e7a7da4a59..0000000000 --- a/backends/platform/ds/arm9/makefile.in +++ /dev/null @@ -1,350 +0,0 @@ -#BUILD_PLUGINS = 1 -#libndsdir = $(DEVKITPRO)/libnds -libndsdir = /home/neil/devkitpro/libnds - -# Select the build you want by uncommenting one of the following lines: - -DS_BUILD_A = 1 -#DS_BUILD_B = 1 -#DS_BUILD_C = 1 -#DS_BUILD_D = 1 - -# Uncomment the following line to build in support for MP3 audio -# using libmad: -USE_MAD = 1 - -# Uncomment the following line to enable support for the -# ace DS Debugger (remembering to make the same change in the arm7 makefile): -#USE_DEBUGGER = 1 -# NOTE: The header and libs for the debugger is assumed to be in the libnds -# folder. - -VPATH = $(srcdir) - -# Command to build libmad is: -# ./configure --host=arm-elf --enable-speed --enable-sso -enable-fpm=arm CFLAGS='-specs=ds_arm9.specs -mthumb-interwork' - - -ifdef DS_BUILD_A - DEFINES = -DDS_SCUMM_BUILD -DDS_BUILD_A - LOGO = logoa.bmp - DISABLE_HE = 1 - #DISABLE_SCUMM = 1 - DISABLE_SCUMM_7_8 = 1 - DISABLE_AGOS = 1 - DISABLE_SKY = 1 - DISABLE_SWORD1 = 1 - DISABLE_SWORD2 = 1 - DISABLE_QUEEN = 1 - DISABLE_SAGA = 1 - DISABLE_KYRA = 1 - DISABLE_GOB = 1 - DISABLE_LURE = 1 - DISABLE_CINE = 1 - DISABLE_AGI = 1 - DISABLE_TOUCHE = 1 - DISABLE_PARALLACTION = 1 - BUILD=scummvm-A -endif - -ifdef DS_BUILD_B - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_B - LOGO = logob.bmp - DISABLE_HE = 1 - DISABLE_SCUMM = 1 - DISABLE_SCUMM_7_8 = 1 - DISABLE_AGOS = 1 - #DISABLE_SKY = 1 - DISABLE_SWORD1 = 1 - DISABLE_SWORD2 = 1 - #DISABLE_QUEEN = 1 - DISABLE_SAGA = 1 - DISABLE_KYRA = 1 - DISABLE_GOB = 1 - DISABLE_LURE = 1 - DISABLE_CINE = 1 - DISABLE_AGI = 1 - DISABLE_TOUCHE = 1 - DISABLE_PARALLACTION = 1 - BUILD=scummvm-B -endif - -ifdef DS_BUILD_C - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_C - LOGO = logoc.bmp - DISABLE_HE = 1 - DISABLE_SCUMM = 1 - DISABLE_SCUMM_7_8 = 1 - #DISABLE_AGOS = 1 - DISABLE_SKY = 1 - DISABLE_SWORD1 = 1 - DISABLE_SWORD2 = 1 - DISABLE_QUEEN = 1 - DISABLE_SAGA = 1 - #DISABLE_KYRA = 1 - #DISABLE_GOB = 1 - DISABLE_LURE = 1 - DISABLE_CINE = 1 - DISABLE_AGI = 1 - DISABLE_TOUCHE = 1 - DISABLE_PARALLACTION = 1 - BUILD=scummvm-C -endif - -ifdef DS_BUILD_D - DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_D - LOGO = logoc.bmp - DISABLE_HE = 1 - DISABLE_SCUMM = 1 - DISABLE_SCUMM_7_8 = 1 - DISABLE_AGOS = 1 - DISABLE_SKY = 1 - DISABLE_SWORD1 = 1 - DISABLE_SWORD2 = 1 - DISABLE_QUEEN = 1 - DISABLE_SAGA = 1 - DISABLE_KYRA = 1 - DISABLE_GOB = 1 - DISABLE_LURE = 1 - #DISABLE_CINE = 1 - #DISABLE_AGI = 1 - DISABLE_TOUCHE = 1 - DISABLE_PARALLACTION = 1 - BUILD=scummvm-A -endif - - -ARM7BIN := -7 $(CURDIR)/../../arm7/arm7.bin -ICON := -b ../../../logo.bmp "ScummVM;By Neil Millstone;" - -CC = arm-eabi-gcc -CXX = arm-eabi-g++ - -CFLAGS = -Wno-multichar -Wall -Os\ - -Wno-multichar -mcpu=arm9tdmi -mtune=arm9tdmi \ - -mcpu=arm9tdmi -mtune=arm9tdmi -fomit-frame-pointer\ - -ffast-math -mthumb-interwork - -ifdef USE_DEBUGGER - DEFINES += -DUSE_DEBUGGER - CFLAGS += -g -endif - -CXXFLAGS= $(CFLAGS) -Wno-non-virtual-dtor -Wno-non-virtual-dtor \ - -fno-exceptions -fno-rtti - -ASFLAGS = -mcpu=arm9tdmi -mthumb-interwork -DEFINES += -D__DS__ -DNDS -DARM9 -DNONSTANDARD_PORT -DDISABLE_FANCY_THEMES -DDISABLE_DEFAULT_SAVEFILEMANAGER -ifdef USE_MAD - DEFINES += -DUSE_MAD -endif - - -LDFLAGS = -specs=ds_arm9.specs -mthumb-interwork -mno-fpu -Wl,-Map,map.txt - -INCLUDES= -I./ -I$(portdir)/$(BUILD) -I$(srcdir) -I$(srcdir)/common -I$(portdir)/source -I$(portdir)/source/compressor -I$(portdir)/source/fat \ - -I$(srcdir)/backends/fs -I$(srcdir)/backends/fs/ds -I$(portdir)/data -I$(libndsdir)/include -I$(portdir)/../commoninclude\ - -I$(srcdir)/scumm -I$(libndsdir)/include -I$(libndsdir)/include/nds -I$(srcdir)/engines -I$(portdir)/source/mad\ - -I$(portdir)/source/libcartreset - - -LIBS = -lm -L$(libndsdir)/lib -L$(portdir)/lib -lnds9 -ifdef USE_MAD - LIBS += -lmad -endif -ifdef USE_DEBUGGER - LIBS += -ldsdebugger -ldswifi9 -endif - -#-Lscumm -lscumm -Lbase -lbase -Lcommon -lcommon -Lgraphics -lgraphics -Lgui -lgui -Lsound -lsound -EXECUTABLE = scummvm.elf -PLUGIN_PREFIX = -PLUGIN_SUFFIX = .plg -PLUGIN_EXTRA_DEPS = plugin.x plugin.syms scummvm.elf -PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,-Tplugin.x,--just-symbols,scummvm.elf,--retain-symbols-file,plugin.syms -L$(ronindir)/lib -MKDIR = mkdir -p -RM = rm -f -RM_REC = rm -rf -AR = arm-eabi-ar cru -RANLIB = arm-eabi-ranlib -OBJCOPY = arm-eabi-objcopy -AS = arm-eabi-as -HAVE_GCC3 = true -DISABLE_SCALERS = true - -ifdef BUILD_PLUGINS -DEFINES += -DDYNAMIC_MODULES -PRE_OBJS_FLAGS = -Wl,--whole-archive -POST_OBJS_FLAGS = -Wl,--no-whole-archive -endif - -PORT_OBJS := $(portdir)/source/blitters.o $(portdir)/source/cdaudio.o $(portdir)/source/dsmain.o \ - $(portdir)/../../../fs/ds/ds-fs.o $(portdir)/source/gbampsave.o $(portdir)/source/scummhelp.o\ - $(portdir)/source/osystem_ds.o $(portdir)/source/portdefs.o $(portdir)/source/ramsave.o\ - $(portdir)/source/scummconsole.o $(portdir)/source/touchkeyboard.o $(portdir)/source/zipreader.o\ - $(portdir)/source/dsoptions.o $(portdir)/source/keys.o - -DATA_OBJS := $(portdir)/data/icons.o $(portdir)/data/keyboard.o $(portdir)/data/keyboard_pal.o $(portdir)/data/default_font.o - - -COMPRESSOR_OBJS := $(portdir)/source/compressor/lz.o - -FAT_OBJS := $(portdir)/source/fat/disc_io.o $(portdir)/source/fat/gba_nds_fat.o\ - $(portdir)/source/fat/io_fcsr.o $(portdir)/source/fat/io_m3cf.o\ - $(portdir)/source/fat/io_mpcf.o $(portdir)/source/fat/io_sccf.o\ - $(portdir)/source/fat/io_m3sd.o\ - $(portdir)/source/fat/io_nmmc.o $(portdir)/source/fat/io_scsd.o \ - $(portdir)/source/fat/io_scsd_asm.o \ - $(portdir)/source/fat/io_njsd.o \ - $(portdir)/source/fat/io_mmcf.o \ - $(portdir)/source/fat/io_sd_common.o \ - $(portdir)/source/fat/io_m3_common.o \ - $(portdir)/source/fat/io_dldi.o \ - $(portdir)/source/fat/m3sd.o - - -# $(portdir)/source/fat/io_cf_common.o $(portdir)/source/fat/io_m3_common.o\ -# $(portdir)/source/fat/io_sd_common.o $(portdir)/source/fat/io_scsd_s.o \ -# $(portdir)/source/fat/io_sc_common.o $(portdir)/source/fat/io_sd_common.o - -LIBCARTRESET_OBJS := $(portdir)/source/libcartreset/cartreset.o - - - -OBJS := $(DATA_OBJS) $(LIBCARTRESET_OBJS) $(PORT_OBJS) $(COMPRESSOR_OBJS) $(FAT_OBJS) - - - -MODULE_DIRS += . - -ndsall: - @[ -d $(BUILD) ] || mkdir -p $(BUILD) - make -C ./$(BUILD) -f ../makefile scummvm.nds - -include $(srcdir)/Makefile.common - -clean: - $(RM) $(OBJS) $(EXECUTABLE) - rm -fr $(BUILD) - -plugin_dist : - find . -name '*.plg' | while read p; do \ - sh-elf-strip -g -o "`basename \"$$p\" | tr '[:lower:]' '[:upper:]'`" "$$p"; \ - done - -dist : SCUMMVM.BIN plugins plugin_dist - - -#--------------------------------------------------------------------------------- -# canned command sequence for binary data -#--------------------------------------------------------------------------------- -#define bin2o -# bin2s $< | $(AS) -mthumb -mthumb-interwork -o $(@) -# echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_raw_end[];" > `(echo $(<F) | tr . _)`.h -# echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_raw[];" >> `(echo $(<F) | tr . _)`.h -# echo "extern const u32" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_raw_size";" >> `(echo $(<F) | tr . _)`.h -#endef - - -define bin2o - bin2s $< | $(AS) -mthumb -mthumb-interwork -o $(@) - echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"_end[];" > `(echo $(<F) | tr . _)`.h - echo "extern const u8" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> `(echo $(<F) | tr . _)`.h - echo "extern const u32" `(echo $(<F) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> `(echo $(<F) | tr . _)`.h -endef - - -#define bin2o -# @echo $(*) -# cp $(<) $(*).tmp -# $(OBJCOPY) -I binary -O elf32-littlearm -B arm \ -# --rename-section .data=.rodata \ -# --redefine-sym _binary_$(subst .,_,$(subst /,_,$(*)))_tmp_start=$(notdir $*)\ -# --redefine-sym _binary_$(subst .,_,$(subst /,_,$(*)))_tmp_end=$(notdir $*)_end\ -# $(*).tmp $(@) -# echo "extern const u8" $(notdir $*)"[] __attribute__ ((aligned (4)));" > $(*).h -# echo "extern const u32" $(notdir $(*))_size[]";" >> $(*).h -# -# echo $(*).h -# rm $(*).tmp -#endef - -############## -# Replacement rule for the one in makefile.common -############## -ifndef HAVE_GCC3 -# If you use GCC, disable the above and enable this for intelligent -# dependency tracking. -.cpp.o: - $(MKDIR) $(*D)/$(DEPDIR) - $(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d2" $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o -# $(ECHO) "$(*D)/" > $(*D)/$(DEPDIR)/$(*F).d - $(CAT) "$(*D)/$(DEPDIR)/$(*F).d2" >> "$(*D)/$(DEPDIR)/$(*F).d" - $(RM) "$(*D)/$(DEPDIR)/$(*F).d2" -else -# If you even have GCC 3.x, you can use this build rule, which is safer; the above -# rule can get you into a bad state if you Ctrl-C at the wrong moment. -# Also, with this GCC inserts additional dummy rules for the involved headers, -# which ensures a smooth compilation even if said headers become obsolete. -.cpp.o: - $(MKDIR) $(*D)/$(DEPDIR) -# $(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o - $(CXX) -MMD -MF "$(*D)/$(DEPDIR)/$(*F).d" $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o -endif - - -#--------------------------------------------------------------------------------- - -#--------------------------------------------------------------------------------- -%.o : %.pcx -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @$(bin2o) - -#--------------------------------------------------------------------------------- -%.o : %.bin -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @$(bin2o) - -#--------------------------------------------------------------------------------- -%.o : %.raw -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @$(bin2o) - -#--------------------------------------------------------------------------------- -%.o : %.pal -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @$(bin2o) - -#--------------------------------------------------------------------------------- -%.o : %.map -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @$(bin2o) - -#--------------------------------------------------------------------------------- -%.o : %.mdl -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @$(bin2o) - -#--------------------------------------------------------------------------------- -%.nds: %.bin - @echo ndstool -c $@ -9 scummvm.bin $(ARM7BIN) -b ../../$(LOGO) "$(shell basename $@);ScummVM @VERSION@;DS Port" - ndstool -c $@ -9 scummvm.bin $(ARM7BIN) -b ../../$(LOGO) "$(shell basename $@);ScummVM @VERSION@;DS Port" - dsbuild $@ -l ../ndsloader.bin - - padbin 16 $(basename $@).ds.gba - -#--------------------------------------------------------------------------------- -%.bin: %.elf - $(OBJCOPY) -S scummvm.elf scummvm-stripped.elf - $(OBJCOPY) -O binary scummvm-stripped.elf scummvm.bin - -#%.o: %.s -# $(MKDIR) $(*D)/$(DEPDIR) -# $(CXX) -Wp,-MMD,"$(*D)/$(DEPDIR)/$(*F).d",-MQ,"$@",-MP $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o - diff --git a/backends/platform/symbian/res/scummvm.cer b/backends/platform/symbian/res/scummvm.cer deleted file mode 100644 index 70b765e6b4..0000000000 --- a/backends/platform/symbian/res/scummvm.cer +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDXTCCAxqgAwIBAgIBADALBgcqhkjOOAQDBQAwgZIxEDAOBgNVBAoTB1NjdW1t -Vk0xfjB8BgNVBAMTdVNjdW1tVk0gUzYwdjM3OThiOTk0MDg2OTFhZThlZWM2N2Zl -NGUxYmZjOTQ1YTI0YjRmYjZmMTlmMGJiNzE2N2FjYWEwYzBlNjc0OTM3MmEyY2Qw -YjNiMmY5MWRmMGQyNTQwZjdlYzc0YzllNzhhYWJlMzkwZTAeFw0wNzA2MTAxOTQ4 -NTJaFw0wODA2MDkxOTQ4NTJaMIGSMRAwDgYDVQQKEwdTY3VtbVZNMX4wfAYDVQQD -E3VTY3VtbVZNIFM2MHYzNzk4Yjk5NDA4NjkxYWU4ZWVjNjdmZTRlMWJmYzk0NWEy -NGI0ZmI2ZjE5ZjBiYjcxNjdhY2FhMGMwZTY3NDkzNzJhMmNkMGIzYjJmOTFkZjBk -MjU0MGY3ZWM3NGM5ZTc4YWFiZTM5MGUwggG3MIIBKwYHKoZIzjgEATCCAR4CgYEA -ydXBoDldKAiq3DmfGPwReY9qHEMEh4AyuK5N4M7PvCSYUWU6sWp9PQJ1DDXOm54o -k8IicM9/dmNdQVAGah2Oi5wizbaYV3HkFufLQOQdaOFg7uclJKp+4cnPsG8lz4DS -j6o9kRxANZ9vJgE7qxWG5HnEPNm/l0mDbyWbtbAT//sCFQDCZT2JjR+U+o2orfUL -tcojrwdLSQKBgGdx5eoIaGOxIXgP7ttNdL+7qOYMJD2wI93o5eRiLOaTme276pr3 -oYv3VVRZJa6UXD298b705ia/XQqO6KA9QJgPMjJnwD/8ydcZyZqmX6sNpv6dc7AN -y/6BJN6DO0xUc9BTkQr4cYBhfkc1mYTBzxOj7bi4aATBjcCXzDXXyT2bA4GFAAKB -gQCXsapLABnAVfz60pOQt+Kcl3x+/Rz+vXoItLg3O8cVjooi/q0uaaXF/AnO2njb -lLHbQX3zmv/+tvD2PSyFtgNgscyTf/EECqWMK94Lb0/Jw1rvdNO86eWzsW7UzArF -5KjJbUn64+PTSU8m7GTqGN4NFh6yFBk//Z2ljy+Zt0WZBDALBgcqhkjOOAQDBQAD -MAAwLQIUJUCWx57QyGsiPM5w5qvX3ZYF0/kCFQC47QWyrzi4dr2y2iDNWsln7La4 -Qw== ------END CERTIFICATE----- diff --git a/backends/platform/symbian/res/scummvm.key b/backends/platform/symbian/res/scummvm.key deleted file mode 100644 index 62e3d3858c..0000000000 --- a/backends/platform/symbian/res/scummvm.key +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN DSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,AA4358B4EE40C19C - -OyPKZgptp6jQoGEckxKO4fHS9IL72F0rHduv4qguYHdKeyjREgWDN6+/QhI3SQWu -9bch/oyo/mhO6ZcLjOukBVaygYNw8VTnuEUITmPPrLo7Hcrs12y5jr6MCJ1XBho8 -K0eBwJpqEYFlRZcGqLhJVcPbREEZAOY522MsnT4V3Sa2yerK0AWMSXSTjWRPVxlo -RdqB7vdU/zp3FZvV1gXp+aAOb0WoUbZZYo5r4JnHS+6DGHJfWtXucz4VhcrYxLa8 -xNE3WvTvnIyudG1Yc4J5pl0fpS7wBHQHFtqv2ncRWhY49r9RNR6bfMLZULZj8mwo -QRYkUeaAkdEkTiYlVl/KQ1i3Hh1qupaQwxF/WqCtfbvLA6KlzYLllTnGwsRHujid -f97fGt1z8uWGtzDWQzKW3nY0I2psAA/bCYwL88G1aOPEyp4Ql1lkyxRm4Tw7Zu5M -pF09dAgkFVvPH5Bn7o05ZS9ruNhF5K/5QNg3WTVDhZEqkqiXWRGXaEhc6ZfoK/+H -ne1d3+QfKEX8rxAtjX1hVNkNG1ivmIExpa45wUmSE2pOIj31ny0gK1tCv4mdgEDL -elR3M/oAw0BdxBn9LqmDaQ== ------END DSA PRIVATE KEY----- diff --git a/backends/platform/wince/README-WinCE.txt b/backends/platform/wince/README-WinCE.txt deleted file mode 100644 index 17371f9c57..0000000000 --- a/backends/platform/wince/README-WinCE.txt +++ /dev/null @@ -1,616 +0,0 @@ -ScummVM Windows CE FAQ -Last updated: $Date$ -Release version: 0.10.0 ------------------------------------------------------------------------- - -New in this version -------------------- - -0.10.0: -Major improvements have taken place in this version, mostly for behind- -the-scenes stuff. First, we have migrated to GCC for building the Windows -CE port. This helped take care of some obscure compiler bugs which were -in there for quite a long time. It has also lead to efficient code -generation due to GCC's advanced capabilities and consequently increased -runtime speed. The second important change was the overhaul of the SDL -library port. The benefits from this are twofold: The real-time code paths -have been optimized, including contributed ARM assembly code for critical -functions. Further, the screen display and mouse/keyboard input code has -been partially rewritten to allow for increased compatibility across all -devices. -Due to the update of keyboard handling code, the keycodes have changed -slightly. Running this version of ScummVM will overwrite your key bindings -with the new defaults. See the section on how to play on Smartphones and -Pocket PCs below for the new default keybindings. - ------------------------------------------------------------------------- - -This document is intended to give common answers to specific ScummVM -issues on Windows CE, in 3 sections - * "General questions" : browse this section to get started and see - general issues - * "Game specific questions" : lists some common game specific issues - * "Support and links" : how to get support if you're still puzzled - ------------------------------------------------------------------------- -General questions ------------------------------------------------------------------------- - -Which devices are supported ? ------------------------------ - -Official build --------------- - -The official build is based on the ARM architecture and should work with any -Pocket PC 2000, Pocket PC 2002, Pocket PC 2003, Pocket PC 2003 SE, Smartphone -2002, Smartphone 2003 or Windows Mobile based device. - -Support for old ARM architectures (Handheld PCs, Palm Size PCs) and other CPUs -(MIPS, SH3) is discontinued. Feel free to generate builds for these -architectures and contact us to include them on ScummVM website. - -Games supported ---------------- - -The Windows CE port of ScummVM supports all available game engines. - -ScummVM distinguishes devices based on two characteristics: Type and resolution. -Supported types of devices are Smartphones (usually no stylus) and Pocket PCs -(stylus). The supported resolutions are 176x220 (Smartphone), 240x240 (QVGA -square), 240x320 (QVGA), 320x240 (QVGA landscape), 480x640 (VGA). Devices with -resolutions larger than VGA should also be supported with automatic screen -centering. - -* Low resolution Smartphones (176x220) - -Support is only provided for all 320x200 or 320x240 games. The font can get -hard to read (you should prefer talkie games, or wear glasses :-P) -Games with 640x480 resolution such as COMI or BSWORD cannot be scaled down -to this resolution and still be playable. - -* QVGA square devices (240x240) - -Only 320x200 or 320x240 games are supported due to lack of downsampling scaler. - -* QVGA Pocket PCs or Smartphones (240x320 or 320x240) - -All games are playable in these devices. Landscape devices may not be able to -rotate the screen around. - -* VGA (640x480) or higher Pocket PCs - -All non VGA games should work properly on these devices. They can be resized -with different scalers. Moreover, VGA games will be displayed in true VGA mode. - -Partial / Discontinued support ------------------------------- - -Support for the following devices is not complete, not working properly or -discontinued because the device is now obsolete. Feel free to contribute and -improve the port for your favorite device, or use the last release built with -the previous port architecture (0.5.1) which was less resource hungry and -supported more exotic devices. - -* "Paletted" devices (non "true color") - -These devices will be supported through the GDI layer which will slow down the -games a lot. You can try to disable the music/sound effects to get a better -game experience. - -* "Mono" devices - -I don't even think anything will be displayed on these devices :) you can try -and report your success ... - -* MIPS/SH3 devices with QVGA resolution (240x320), "true color" - -Some devices may be a bit too slow, especially if direct screen access (GAPI) -is not supported on these devices. - -* ARM/MIPS/SH3 devices with VGA resolution (640x480) (Palm Size PC / Handheld - PC platform) - -True VGA games will probably be too slow to run properly on these devices even -if they can support them ... - -* ARM/MIPS/SH3 devices with desktop resolution (800x600) (Handheld PC platform) - -No, there will never be ANY scaler supporting 800x600 resolution, because -320x200 games CANNOT be resized to a 800x600 by a simple operation. - -And the device will probably be too slow to perform any kind of graphic -transform anyway :) - -How do I install ScummVM for Windows CE ? ------------------------------------------ - -Simple! Unpack the release package on your desktop pc, then copy all its contents -to a folder on your device. Typically, you should at least have scummvm.exe, -modern.ini and modern.zip in the same directory. Finally, upload your beloved games -and fire it up :-) - -Some devices (like Pocket PC 2000) require GAPI to be present. - -How do I install a game ? -------------------------- - -You'll at least need to copy all the data files from your game, in a -sub-directory of your game directory. - -You'll need to put the data files in a directory named after ScummVM game -name (see "Supported Games" section in ScummVM readme) for the games having -"generic" data files (.LFL files). Recent games can be put in any directory. - -You can compress the multimedia files (sound/video) as described in the -ScummVM readme. - -You can compress the audio tracks of Loom or Monkey Island 1 as described in -the ScummVM readme. If you are running these games on a slow device with Ogg -Vorbis compression, it's recommended to sample the files to 11 kHz (this sample -rate is not supported by other versions of ScummVM). - -If you need more details, you can check SirDave's mini-manual online available -at: http://forums.scummvm.org/viewtopic.php?t=936 -and at: http://www.pocketmatrix.com/forums/viewtopic.php?t=8606 - -How do I run a game ? ---------------------- - -If it's the first time you're running ScummVM for Windows CE, have installed or -removed games, you need to rescan your game directory. - * Select Add Game, tap the root directory of your games, and tap "Yes" to begin - an automatic scan of the installed games. - -Usually all games are detected and you can start playing right away. If your -game is not detected check its directory name and your data files. - -To play a game, tap on its name then tap the "Start" button or double tap its -name. - -How do I play a game on a Pocket PC or Handheld PC device ? ------------------------------------------------------------ - -The stylus is your mouse cursor, and a tap is a left mouse button click. - -As the Pocket PC lacks some keys, a toolbar is displayed at the bottom of the -screen to make the most common functions just a tap away - * The disk icon opens ScummVM options menu to save your game, or change your - current game settings (depends on the game) - * The movie icon skips a non interactive sequence, the current dialog or - behaves like the ESC key on a regular keyboard (depends on the game) - * The sound icon turns all sound effects and music off and on - * The key icon allow you to map a key action to a device button - * The monkey icon switches between portrait, landscape and inverse landscape - mode (depends on the display drivers) - -You can map additional actions on your device hardware buttons using the -"Options" / "Key" menu in the ScummVM options menu. To associate an action to -a key, tap the action, then the "Map" button and press the hardware key. -The following actions are available : - - * Pause : pause the game - * Save : open ScummVM option menu - * Quit : quit ScummVM (without saving, be careful when using it) - * Skip : skip a non interactive sequence, the current dialog or - behaves like the ESC key on a regular keyboard - * Hide : hide or display the toolbar - * Keyboard : hide or display the virtual keyboard - * Sound : turns all sound effects and music off and on - * Right click : acts as a right mouse button click - * Cursor : hide or display the mouse cursor - * Free look : go in or out of free-look mode. In this mode, you can tap - the screen to look for interesting locations without walking. - * Zoom up : magnify the upper part of the screen for 640x480 games - rendered on a QVGA device. - * Zoom down : magnify the lower part of the screen for 640x480 games - rendered on a QVGA device. - * Multi Function : this key performs a different function depending on the game - : Full Throttle -> win an action sequence (cheat) - : Fate of Atlantis -> sucker punch (cheat) - : Bargon -> F1 (start the game) - : All AGI games -> bring up the predictive input dialog - * Bind keys : map a key action to a device button - * Up,Down,Left : - Right, : emulate mouse/stylus behavior - Left Click : - -The default key bindings for Pocket PCs are (note that not all keys are mapped): - * Up, Down, Left, Right : (dpad) arrow keys - * Left Click : softkey A - -If you start a game when a Right click mapping is necessary, ScummVM will ask -you to map one of your hardware key to this action before playing. Just press -the key you want to map if you see this message. - -Notes: -- THE TOOLBAR CAN BE CYCLED BY DOUBLE TAPPING (SEE BELOW) -- YOU MUST HIDE THE TOOLBAR TO SCROLL THROUGH THE INVENTORY IN ZAK -- YOU MUST DISPLAY THE KEYBOARD TO FIGHT IN INDIANA JONES 3 -- YOU MUST MAP THE RIGHT CLICK ACTION TO PLAY SEVERAL GAMES - -How do I hide the toolbar ? ---------------------------- - -Note: THIS IS A VERY USEFUL AND SOMETIMES NECESSARY SHORTCUT - -Double tapping the stylus at the top of the screen will switch between a -visible toolbar panel, a virtual keyboard, and hiding panel. If any part of -the screen is obscured by the toolbar (like the load/save game dialogs) you can -use the invisible panel mode to get to it. For 320x200 games on QVGA Pocket -PCs, when the panel is hidden the game screen is resized to 320x240 (aspect -ratio correction) for better gaming experience. - -How do I play a game on a Smartphone device ? ---------------------------------------------- - -On non-stylus devices, the mouse cursor is emulated via a set of keys. -The cursor will move faster if you keep the key down. You can tweak this -behaviour in the configuration file described below. - -Here is -the list of available actions for Smartphones: - - * Up,Down,Left : - Right, : emulate mouse/stylus behavior - Left Click : - Right Click : - * Save : open ScummVM option menu - * Skip : skip a non interactive sequence, the current dialog or - behaves like the ESC key on a regular keyboard - * Zone : switch between the 3 different mouse zones - * Multi Function : this key performs a different function depending on the game - : Full Throttle -> win an action sequence (cheat) - : Fate of Atlantis -> sucker punch (cheat) - : Bargon -> F1 (start the game) - : All AGI games -> bring up the predictive input dialog - * Bind keys : map a key action to a device button - * Keyboard : hide or display the virtual keyboard - * Rotate : rotate the screen (also rotates dpad keys) - * Quit : quit ScummVM (without saving, be careful when using it) - -The "Zone" key is a *very* valuable addition allowing you to jump quickly -between three screen zones : the game zone, the verbs zone and the inventory -zone. When you switch to a zone the cursor will be reset to its former location -in this zone. - -The default key map for these actions is: - - * Up, Down, Left, Right : (dpad) arrow keys - * Left Click : softkey A - * Right Click : softkey B - * Save : call/talk - * Skip : back - * Zone : 9 - * Multi Function : 8 - * Bind keys : end call - * Keyboard : (dpad) enter - * Rotate : 5 - * Quit : 0 - -You can change the key mapping at any time by bringing up the key mapping menu -(Bind keys action). - -How do I tweak the configuration of ScummVM ? ---------------------------------------------- - -See the section regarding the configuration file (scummvm.ini) in ScummVM -README file - the same keywords apply. - -Some parameters are specific to this port : - -Game specific sections (f.e. [monkey2]) - performance options - - * high_sample_rate bool Desktop quality (22 kHz) sound output if set. - 11 kHz otherwise. The default is 11 kHz. - If you have a fast device, you can set this to - true to enjoy better sound effects and music. - * FM_high_quality bool Desktop quality FM synthesis if set. Lower - quality otherwise. The default is low quality. - You can change this if you have a fast device. - * sound_thread_priority int Set the priority of the sound thread (0, 1, 2). - Depending on the release, this is set to 1 - internally (above normal). If you get sound - stuttering try setting this to a higher value. - Set to 0 if your device is fast enough or if - you prefer better audio/video synchronization. - * Smush_force_redraw int Force a Smush frame redraw every X missed - frames. Mainly used for Full Throttle action - sequences. Setting it lower gives more - priority to screen redraws. Setting it higher - gives more priority to stylus/keyboard input. - The default is 30. - -Game specific sections (f.e. [monkey2]) - game options - - * landscape int 0: Portrait, 1: Landscape, 2: Inverse Landscape - You can also use this in the [scummvm] section - in QVGA Pocket PCs to display the launcher in - landscape, for example, at startup. - -[scummvm] section - keys definition - -You usually do not wish to modify these values directly, as they are set -by the option dialog, and are only given here for reference. - - * action_mapping_version int Mapping version linked to ScummVM version. - * action_mapping string Hex codes describing the key associated to - each different action. - * debuglevel int Debug Level 1 is used by the WinCE port - for reporting diagnostic output in the - scummvm_stdout.txt and scummvm.stderr.txt - files in the current working directory. - -[scummvm] section - mouse emulation tuning - -You can tweak these parameters to customize how the cursor is handled. - - * repeatTrigger int Number of milliseconds a key must be held to - consider being repeated. - * repeatX int Number of key repeat events before changing - horizontal cursor behaviour. - * stepX1 int Horizontal cursor offset value when the key is - not repeated. - * stepX2 int Horizontal cursor offset value when the key is - repeated less than repeatX. - * stepX3 int Horizontal cursor offset value when the key is - repeated more than repeatX. - * repeatY int Number of key repeat events before changing - vertical cursor behaviour. - * stepY1 int Vertical cursor offset value when the key is - not repeated. - * stepY2 int Horizontal cursor offset value when the key is - repeated less than repeatY. - * stepY3 int Vertical cursor offset value when the key is - repeated more than repeatY. - ------------------------------------------------------------------------- -Game specific questions ------------------------------------------------------------------------- - ---------------- --- All Games -- ---------------- - -I need to press a special key ------------------------------ - -Bring up the virtual keyboard. On Smartphones take a look at the Keyboard action above. -On Pocket PCs it's easier to double-tap at the top of the screen. - -The panel is obscuring the playfield area ------------------------------------------ - -Double tap at the top of the screen to hide it. As an aside, the aspect ratio -correction scaler will kick in if the game/device combo is appropriate. - -How do I name my save games ? ------------------------------ - -Use the virtual keyboard (Keyboard action). - -ScummVM is stuck for some reason --------------------------------- - -Bind and use the quit action to quit. - -I cannot rotate the screen to landscape/inverse landscape ---------------------------------------------------------- - -Depending on the video driver, ScummVM may opt to not provide such functionality. -In general, when ScummVM starts in normal "portrait" orientation, the device driver -reports better display characteristics and you should consider launching from portrait. - -I'm having problems. Is there diagnostic output available ? ------------------------------------------------------------ - -Insert a line in the [scummvm] section of scummvm.ini with the following: -debuglevel=1 -Run ScummVM. When it closes scummvm_stdout.txt and scummvm_stderr.txt files will be -available at the program directory (see section above). - -ScummVM crashes and returns to desktop --------------------------------------- - -File a bug report including diagnostic output (see previous question). - --------------------------- --- Beneath a Steel Sky -- --------------------------- - -Introduction movie is too slow or never ends ... -------------------------------------------------- - -Skip it :) - -How can I open the inventory in Beneath a Steel Sky ? ---------------------------------------------------- - -Tap the top of the screen. Check your stylus calibration if you still cannot -open it. - -How can I use an item in Beneath a Steel Sky ? ----------------------------------------------- - -You need to map the right click button (see the General Questions section). - ----------------------------- --- Curse of Monkey Island -- ----------------------------- - -How can I open the inventory in Curse of Monkey Island ? ------------------------------------------------------- - -You need to map the right click button (see the General Questions section). - -I'm experiencing random crashes ... ------------------------------------- - -This game has high memory requirements, and may crash sometimes on low -memory devices. Continue your game with the latest automatically saved -game and everything should be fine. -You can consider removing the music and voice files (VOXDISK.BUN, MUSDISK.BUN) -to lower these requirements. - -Sound synchronization is lost in Curse of Monkey Island videos --------------------------------------------------------------- - -Use a faster device :-( - --------------------- --- Full Throttle -- --------------------- - -I'm experiencing random crashes ... ------------------------------------- - -This game has high memory requirements, and may crash sometimes on low -memory devices. Continue your game with the latest automatically saved -game and everything should be fine. -You can consider removing the voice file (MONSTER.SOU) and disable the -music to lower these requirements. - ----------------------------------------- --- Indiana Jones and the Last Crusade -- ----------------------------------------- - -How can I fight in Indiana Jones and the Last Crusade ? ------------------------------------------------------ - -You need to map the keyboard button (see the General Questions section). - ---------------- --- Sam & Max -- ---------------- - -How can I change the current action ? -------------------------------------- - -You need to map the right click button (see the General Questions section). - -How can I exit a mini game ? ----------------------------- - -Use the skip toolbar icon (see the General Questions section). - -------------------- --- Simon 1 and 2 -- -------------------- - -How can I save or quit in Simon ? --------------------------------- - -"Use" (use the use verb :p) the postcard. The ScummVM option dialog is disabled -in Simon games. - -On Smartphone, you'll need to push the Action button (center of the pad) to -quit the game. - -------------- --- The Dig -- -------------- - -I'm experiencing random crashes ... ------------------------------------- - -This game has high memory requirements, and may crash sometimes on low -memory devices. Continue your game with the latest automatically saved -game and everything should be fine. -You can consider removing the music and voice files (VOXDISK.BUN, MUSDISK.BUN) -to lower these requirements. - --------------------- --- Zak Mc Kracken -- --------------------- - -How can I scroll through my inventory items in Zak Mc Kracken ? ---------------------------------------------------------------- - -You need to map the hide toolbar button (see the General Questions section) or -double tap at the top of the screen (from 0.8.0+) - ------------------------- --- Broken Sword 1 & 2 -- ------------------------- - -I've installed the movies pack but they are not playing/they are slow ---------------------------------------------------------------------- - -MPEG 2 playback takes too much memory in the current release, and may prevent -movies from playing in VGA mode. Consider changing to the DXA cutscene pack -which is many times faster. - ---------------- --- Gobliiins -- ---------------- - -How do I enter a code ? ------------------------ - -Use the virtual keyboard. - -------------------- --- Bargon Attack -- -------------------- - -How do I start the game (F1 : Game, F2 : Demo) ----------------------------------------------- - -Use the Multi Function action. - ----------------------- --- AGI engine games -- ----------------------- - -Do you expect me to play these games on keyboard less devices ? ---------------------------------------------------------------- - -Sure we do :-) -If you want to get some mileage on your stylus you can use the virtual keyboard. -There is a very useful alternative though, the AGI engine's predictive input dialog. -It requires a dictionary to be present. Just tap on the command line or use the -Multi Function action to bring it up. On Smartphones, when the dialog is shown -all key mapping is disabled temporarily (including mouse emulation). Input is -performed either by pressing the phone's numeric keypad keys and dpad enter to -close the dialog, or by navigating the buttons using the dpad arrows and pressing -with dpad enter. Check the main Readme file for more information on this. - ------------------------------------------------------------------------- -Support ------------------------------------------------------------------------- - -Help, I've read everything and ... ------------------------------------ - -Luckily, as there is a huge variety of Windows CE devices, a specific forum -is dedicated to this ScummVM port. You can ask your question on the WinCE -ScummVM forum available at http://forums.scummvm.org/viewforum.php?f=6 - -Some older questions and very nice tutorials are still available on the historic -PocketMatrix forum at http://www.pocketmatrix.com/forums/viewforum.php?f=20 -where the community is always glad to help and have dealt with all the bugs for -many years now :) - -I think I found a bug, ScummVM crashes in ... ---------------------------------------------- - -See the "Reporting Bugs" section in ScummVM readme. - -If you have a Pocket PC or Handheld PC, be sure to include its resolution (obtained -on the second dialog displayed on the "About" menu) in your bug report. - -If you cannot reproduce this bug on another ScummVM version, you can cross -post your bug report on ScummVM forums. - -I want to compile my own ScummVM for Windows CE ------------------------------------------------ - -Take a look at: -http://wiki.scummvm.org/index.php/Compiling_ScummVM/Windows_CE - - ------------------------------------------------------------------------- -Good Luck and Happy Adventuring! -The ScummVM team. -http://www.scummvm.org/ ------------------------------------------------------------------------- diff --git a/backends/plugins/dc/dc-provider.cpp b/backends/plugins/dc/dc-provider.cpp index 166852655b..db0242f7d8 100644 --- a/backends/plugins/dc/dc-provider.cpp +++ b/backends/plugins/dc/dc-provider.cpp @@ -114,14 +114,14 @@ PluginList DCPluginProvider::getPlugins() { // Scan for all plugins in this directory FilesystemNode dir(PLUGIN_DIRECTORY); FSList files; - if (!dir.listDir(files, FilesystemNode::kListFilesOnly)) { + if (!dir.getChildren(files, FilesystemNode::kListFilesOnly)) { error("Couldn't open plugin directory '%s'", PLUGIN_DIRECTORY); } for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) { - Common::String name(i->name()); + Common::String name(i->getName()); if (name.hasPrefix(PLUGIN_PREFIX) && name.hasSuffix(PLUGIN_SUFFIX)) { - pl.push_back(new DCPlugin(i->path())); + pl.push_back(new DCPlugin(i->getPath())); } } diff --git a/backends/plugins/posix/posix-provider.cpp b/backends/plugins/posix/posix-provider.cpp index ce319840a4..03ee1c204f 100644 --- a/backends/plugins/posix/posix-provider.cpp +++ b/backends/plugins/posix/posix-provider.cpp @@ -107,14 +107,14 @@ PluginList POSIXPluginProvider::getPlugins() { // Scan for all plugins in this directory FilesystemNode dir(PLUGIN_DIRECTORY); FSList files; - if (!dir.listDir(files, FilesystemNode::kListFilesOnly)) { + if (!dir.getChildren(files, FilesystemNode::kListFilesOnly)) { error("Couldn't open plugin directory '%s'", PLUGIN_DIRECTORY); } for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) { - Common::String name(i->name()); + Common::String name(i->getName()); if (name.hasPrefix(PLUGIN_PREFIX) && name.hasSuffix(PLUGIN_SUFFIX)) { - pl.push_back(new POSIXPlugin(i->path())); + pl.push_back(new POSIXPlugin(i->getPath())); } } diff --git a/backends/plugins/sdl/sdl-provider.cpp b/backends/plugins/sdl/sdl-provider.cpp index 0f67c9a691..cb09af20ca 100644 --- a/backends/plugins/sdl/sdl-provider.cpp +++ b/backends/plugins/sdl/sdl-provider.cpp @@ -107,14 +107,14 @@ PluginList SDLPluginProvider::getPlugins() { // Scan for all plugins in this directory FilesystemNode dir(PLUGIN_DIRECTORY); FSList files; - if (!dir.listDir(files, FilesystemNode::kListFilesOnly)) { + if (!dir.getChildren(files, FilesystemNode::kListFilesOnly)) { error("Couldn't open plugin directory '%s'", PLUGIN_DIRECTORY); } for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) { - Common::String name(i->name()); + Common::String name(i->getName()); if (name.hasPrefix(PLUGIN_PREFIX) && name.hasSuffix(PLUGIN_SUFFIX)) { - pl.push_back(new SDLPlugin(i->path())); + pl.push_back(new SDLPlugin(i->getPath())); } } diff --git a/backends/plugins/win32/win32-provider.cpp b/backends/plugins/win32/win32-provider.cpp index eeea3b805c..b340c23709 100644 --- a/backends/plugins/win32/win32-provider.cpp +++ b/backends/plugins/win32/win32-provider.cpp @@ -110,14 +110,14 @@ PluginList Win32PluginProvider::getPlugins() { // Scan for all plugins in this directory FilesystemNode dir(PLUGIN_DIRECTORY); FSList files; - if (!dir.listDir(files, FilesystemNode::kListFilesOnly)) { + if (!dir.getChildren(files, FilesystemNode::kListFilesOnly)) { error("Couldn't open plugin directory '%s'", PLUGIN_DIRECTORY); } for (FSList::const_iterator i = files.begin(); i != files.end(); ++i) { - Common::String name(i->name()); + Common::String name(i->getName()); if (name.hasPrefix(PLUGIN_PREFIX) && name.hasSuffix(PLUGIN_SUFFIX)) { - pl.push_back(new Win32Plugin(i->path())); + pl.push_back(new Win32Plugin(i->getPath())); } } |