mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-31 07:53:36 +00:00
FS backend for MorphOS
svn-id: r5566
This commit is contained in:
parent
18bb6f7304
commit
1d17168202
@ -11,6 +11,7 @@ INCS = scumm/scumm.h common/scummsys.h common/stdafx.h
|
||||
|
||||
BACKEND_OBJS = \
|
||||
backends/fs/posix/posix-fs.o \
|
||||
backends/fs/morphos/abox-fs.o \
|
||||
backends/fs/windows/windows-fs.o
|
||||
|
||||
COMMON_OBJS = \
|
||||
|
259
backends/fs/morphos/abox-fs.cpp
Normal file
259
backends/fs/morphos/abox-fs.cpp
Normal file
@ -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__)
|
||||
|
Loading…
x
Reference in New Issue
Block a user