aboutsummaryrefslogtreecommitdiff
path: root/backends/fs
diff options
context:
space:
mode:
authorRuediger Hanke2002-11-15 15:12:30 +0000
committerRuediger Hanke2002-11-15 15:12:30 +0000
commit1d17168202da7f16d71de4fc05b798a145731036 (patch)
tree66f15870a559e8771322e571f6b3ccd4a07e7aaf /backends/fs
parent18bb6f73048b2ef29e783cf31f849f448bbe8716 (diff)
downloadscummvm-rg350-1d17168202da7f16d71de4fc05b798a145731036.tar.gz
scummvm-rg350-1d17168202da7f16d71de4fc05b798a145731036.tar.bz2
scummvm-rg350-1d17168202da7f16d71de4fc05b798a145731036.zip
FS backend for MorphOS
svn-id: r5566
Diffstat (limited to 'backends/fs')
-rw-r--r--backends/fs/morphos/abox-fs.cpp259
1 files changed, 259 insertions, 0 deletions
diff --git a/backends/fs/morphos/abox-fs.cpp b/backends/fs/morphos/abox-fs.cpp
new file mode 100644
index 0000000000..054c5d86b1
--- /dev/null
+++ b/backends/fs/morphos/abox-fs.cpp
@@ -0,0 +1,259 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2002 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Header$
+ */
+
+#if defined(__MORPHOS__)
+
+#include <proto/dos.h>
+
+#include <stdio.h>
+
+#include "common/engine.h"
+#include "../fs.h"
+
+/*
+ * Implementation of the ScummVM file system API based on the MorphOS A-Box API.
+ */
+
+class ABoxFilesystemNode : public FilesystemNode {
+ protected:
+ BPTR _lock;
+ String _displayName;
+ bool _isDirectory;
+ bool _isValid;
+ String _path;
+
+ public:
+ ABoxFilesystemNode();
+ ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name = NULL);
+ ABoxFilesystemNode(const ABoxFilesystemNode *node);
+ ~ABoxFilesystemNode();
+
+ virtual String displayName() const { return _displayName; }
+ virtual bool isValid() const { return _isValid; }
+ virtual bool isDirectory() const { return _isDirectory; }
+ virtual String path() const { return _path; }
+
+ virtual FSList *listDir() const;
+ static FSList *listRoot();
+ virtual FilesystemNode *parent() const;
+ virtual FilesystemNode *clone() const { return new ABoxFilesystemNode(this); }
+};
+
+
+FilesystemNode *FilesystemNode::getRoot()
+{
+ return new ABoxFilesystemNode();
+}
+
+ABoxFilesystemNode::ABoxFilesystemNode()
+{
+ _displayName = "All Drives";
+ _isValid = true;
+ _isDirectory = true;
+ _path = "";
+ _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;
+ warning("Error while retrieving path name: %d", IoErr());
+ return;
+ }
+ bufsize *= 2;
+ }
+
+ _isValid = false;
+
+ FileInfoBlock *fib = (FileInfoBlock*) AllocDosObject(DOS_FIB, NULL);
+ if (fib == NULL)
+ {
+ warning("Failed to allocate memory for FileInfoBlock");
+ return;
+ }
+
+ if (Examine(lock, fib) != DOSFALSE)
+ {
+ _isDirectory = fib->fib_EntryType > 0;
+ if (_isDirectory)
+ {
+ _lock = DupLock(lock);
+ _isValid = (_lock != NULL);
+ }
+ else
+ _isValid = true;
+ }
+ FreeDosObject(DOS_FIB, fib);
+}
+
+ABoxFilesystemNode::ABoxFilesystemNode(const ABoxFilesystemNode *node)
+{
+ _displayName = node->_displayName;
+ _isValid = node->_isValid;
+ _isDirectory = node->_isDirectory;
+ _path = node->_path;
+ _lock = DupLock(node->_lock);
+}
+
+ABoxFilesystemNode::~ABoxFilesystemNode()
+{
+ if (_lock)
+ {
+ UnLock(_lock);
+ _lock = NULL;
+ }
+}
+
+FSList *ABoxFilesystemNode::listDir() const
+{
+ FSList *myList = new FSList();
+
+ if (!_isValid)
+ error("listDir() called on invalid node");
+
+ if (!_isDirectory)
+ error("listDir() called on file node");
+
+ if (_lock == NULL)
+ {
+ /* This is the root node */
+ return listRoot();
+ }
+
+ /* "Normal" file system directory */
+ FileInfoBlock *fib = (FileInfoBlock*) AllocDosObject(DOS_FIB, NULL);
+
+ if (fib == NULL)
+ {
+ warning("Failed to allocate memory for FileInfoBlock");
+ return myList;
+ }
+
+ if (Examine(_lock, fib) != DOSFALSE)
+ {
+ while (ExNext(_lock, fib) != DOSFALSE)
+ {
+ ABoxFilesystemNode entry;
+ entry._displayName = fib->fib_FileName;
+ entry._isDirectory = fib->fib_EntryType > 0;
+ entry._path = _path;
+ entry._path += fib->fib_FileName;
+ if (entry._isDirectory)
+ entry._path += "/";
+ myList->push_back(entry);
+ }
+
+ if (IoErr() != ERROR_NO_MORE_ENTRIES)
+ warning("Error while reading directory: %d", IoErr());
+ }
+
+ FreeDosObject(DOS_FIB, fib);
+
+ return myList;
+}
+
+FilesystemNode *ABoxFilesystemNode::parent() const
+{
+ FilesystemNode *node = NULL;
+
+ if (!_isDirectory)
+ error("parent() called on file node");
+
+ if (_lock == NULL)
+ /* Parent of the root is the root itself */
+ node = const_cast<ABoxFilesystemNode*>(this);
+ else
+ {
+ BPTR parent_lock = ParentDir(_lock);
+ if (parent_lock)
+ {
+ node = new ABoxFilesystemNode(parent_lock);
+ UnLock(parent_lock);
+ }
+ else
+ node = new ABoxFilesystemNode();
+ }
+
+ return node;
+}
+
+FSList *ABoxFilesystemNode::listRoot()
+{
+ FSList *myList = new FSList();
+ DosList *dosList;
+ CONST ULONG lockDosListFlags = LDF_READ | LDF_VOLUMES;
+ char name[256];
+
+ dosList = LockDosList(lockDosListFlags);
+ if (dosList == NULL)
+ {
+ warning("Could not lock dos list");
+ return myList;
+ }
+
+ 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
+ )
+ {
+ ABoxFilesystemNode *entry;
+ CONST_STRPTR volume_name = (CONST_STRPTR)BADDR(dosList->dol_Name)+1;
+ CONST_STRPTR device_name = (CONST_STRPTR)((struct Task *)dosList->dol_Task->mp_SigTask)->tc_Node.ln_Name;
+ BPTR volume_lock;
+
+ strcpy(name, volume_name);
+ strcat(name, ":");
+ volume_lock = Lock(name, SHARED_LOCK);
+ if (volume_lock)
+ {
+ sprintf(name, "%s (%s)", volume_name, device_name);
+ entry = new ABoxFilesystemNode(volume_lock, name);
+ if (entry->isValid())
+ myList->push_back(*entry);
+ UnLock(volume_lock);
+ }
+ }
+ dosList = NextDosEntry(dosList, LDF_VOLUMES);
+ }
+
+ UnLockDosList(lockDosListFlags);
+
+ return myList;
+}
+
+#endif // defined(__MORPHOS__)
+