mirror of https://github.com/stella-emu/stella.git
Added first pass of filesystem handling. We can now see a listing in the
launcher window, and double-clicking on a listed file will start that ROM. Some optimizations WRT launcher stuff. Specifically, it was not necessary to delete and re-create the launcher dialog all the time. It's all starting to come together ... git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@415 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
16ee1f8e7f
commit
7deea3a6a6
|
@ -13,7 +13,7 @@
|
||||||
## See the file "license" for information on usage and redistribution of
|
## See the file "license" for information on usage and redistribution of
|
||||||
## this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
## this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
##
|
##
|
||||||
## $Id: makefile,v 1.75 2005-05-06 18:38:59 stephena Exp $
|
## $Id: makefile,v 1.76 2005-05-09 18:58:17 stephena Exp $
|
||||||
##============================================================================
|
##============================================================================
|
||||||
|
|
||||||
##============================================================================
|
##============================================================================
|
||||||
|
@ -126,7 +126,7 @@ linux:
|
||||||
$(MAKE) $(SMP) stella \
|
$(MAKE) $(SMP) stella \
|
||||||
EXE_NAME="stella" \
|
EXE_NAME="stella" \
|
||||||
OPTIONS="$(OPTIONS) -DBSPF_UNIX -DUNIX -DHAVE_GETTIMEOFDAY" \
|
OPTIONS="$(OPTIONS) -DBSPF_UNIX -DUNIX -DHAVE_GETTIMEOFDAY" \
|
||||||
OBJS="$(OBJECTS) SettingsUNIX.o OSystemUNIX.o"
|
OBJS="$(OBJECTS) SettingsUNIX.o OSystemUNIX.o FSNodePOSIX.o"
|
||||||
|
|
||||||
linux-gl:
|
linux-gl:
|
||||||
$(MAKE) $(SMP) stella \
|
$(MAKE) $(SMP) stella \
|
||||||
|
@ -134,20 +134,20 @@ linux-gl:
|
||||||
LDFLAGS="$(LDFLAGS) -L/usr/X11R6/lib" \
|
LDFLAGS="$(LDFLAGS) -L/usr/X11R6/lib" \
|
||||||
LDLIBS="$(LDLIBS) -lGL" \
|
LDLIBS="$(LDLIBS) -lGL" \
|
||||||
OPTIONS="$(OPTIONS) -DBSPF_UNIX -DUNIX -DHAVE_GETTIMEOFDAY -DDISPLAY_OPENGL" \
|
OPTIONS="$(OPTIONS) -DBSPF_UNIX -DUNIX -DHAVE_GETTIMEOFDAY -DDISPLAY_OPENGL" \
|
||||||
OBJS="$(OBJECTS) FrameBufferGL.o SettingsUNIX.o OSystemUNIX.o"
|
OBJS="$(OBJECTS) FrameBufferGL.o SettingsUNIX.o OSystemUNIX.o FSNodePOSIX.o"
|
||||||
|
|
||||||
win32:
|
win32:
|
||||||
$(MAKE) $(SMP) stella \
|
$(MAKE) $(SMP) stella \
|
||||||
EXE_NAME="stella.exe" \
|
EXE_NAME="stella.exe" \
|
||||||
OPTIONS="$(OPTIONS) -DBSPF_WIN32 -DWIN32" \
|
OPTIONS="$(OPTIONS) -DBSPF_WIN32 -DWIN32" \
|
||||||
OBJS="$(OBJECTS) SettingsWin32.o OSystemWin32.o"
|
OBJS="$(OBJECTS) SettingsWin32.o OSystemWin32.o FSNodeWin32.o"
|
||||||
|
|
||||||
win32-gl:
|
win32-gl:
|
||||||
$(MAKE) $(SMP) stella \
|
$(MAKE) $(SMP) stella \
|
||||||
EXE_NAME="stella.exe" \
|
EXE_NAME="stella.exe" \
|
||||||
LDLIBS="$(LDLIBS) -lopengl32" \
|
LDLIBS="$(LDLIBS) -lopengl32" \
|
||||||
OPTIONS="$(OPTIONS) -DBSPF_WIN32 -DWIN32 -DDISPLAY_OPENGL -DTEXTURES_ARE_LOST" \
|
OPTIONS="$(OPTIONS) -DBSPF_WIN32 -DWIN32 -DDISPLAY_OPENGL -DTEXTURES_ARE_LOST" \
|
||||||
OBJS="$(OBJECTS) FrameBufferGL.o SettingsWin32.o OSystemWin32.o"
|
OBJS="$(OBJECTS) FrameBufferGL.o SettingsWin32.o FSNodeWin32.o"
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
@ -168,7 +168,7 @@ CORE_OBJS = Booster.o Cart.o Cart2K.o Cart3F.o Cart4K.o CartAR.o CartDPC.o \
|
||||||
Event.o Joystick.o Keyboard.o M6532.o MD5.o MediaSrc.o Paddles.o \
|
Event.o Joystick.o Keyboard.o M6532.o MD5.o MediaSrc.o Paddles.o \
|
||||||
Props.o PropsSet.o Random.o SoundNull.o Switches.o Settings.o TIA.o \
|
Props.o PropsSet.o Random.o SoundNull.o Switches.o Settings.o TIA.o \
|
||||||
Serializer.o Deserializer.o EventHandler.o FrameBuffer.o \
|
Serializer.o Deserializer.o EventHandler.o FrameBuffer.o \
|
||||||
OSystem.o \
|
OSystem.o FSNode.o \
|
||||||
$(M6502_OBJS) $(GUI_OBJS)
|
$(M6502_OBJS) $(GUI_OBJS)
|
||||||
|
|
||||||
stella: $(CORE_OBJS) $(OBJS)
|
stella: $(CORE_OBJS) $(OBJS)
|
||||||
|
@ -316,18 +316,27 @@ Settings.o: $(CORE)/Settings.cxx $(CORE)/Settings.hxx
|
||||||
OSystem.o: $(CORE)/OSystem.cxx $(CORE)/OSystem.hxx
|
OSystem.o: $(CORE)/OSystem.cxx $(CORE)/OSystem.hxx
|
||||||
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(CORE)/OSystem.cxx
|
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(CORE)/OSystem.cxx
|
||||||
|
|
||||||
|
FSNode.o: $(CORE)/FSNode.cxx $(CORE)/FSNode.hxx
|
||||||
|
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(CORE)/FSNode.cxx
|
||||||
|
|
||||||
SettingsUNIX.o: $(SRC)/unix/SettingsUNIX.cxx $(SRC)/unix/SettingsUNIX.hxx
|
SettingsUNIX.o: $(SRC)/unix/SettingsUNIX.cxx $(SRC)/unix/SettingsUNIX.hxx
|
||||||
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(SRC)/unix/SettingsUNIX.cxx
|
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(SRC)/unix/SettingsUNIX.cxx
|
||||||
|
|
||||||
OSystemUNIX.o: $(SRC)/unix/OSystemUNIX.cxx $(SRC)/unix/OSystemUNIX.hxx
|
OSystemUNIX.o: $(SRC)/unix/OSystemUNIX.cxx $(SRC)/unix/OSystemUNIX.hxx
|
||||||
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(SRC)/unix/OSystemUNIX.cxx
|
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(SRC)/unix/OSystemUNIX.cxx
|
||||||
|
|
||||||
|
FSNodePOSIX.o: $(SRC)/unix/FSNodePOSIX.cxx
|
||||||
|
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(SRC)/unix/FSNodePOSIX.cxx
|
||||||
|
|
||||||
SettingsWin32.o: $(SRC)/win32/SettingsWin32.cxx $(SRC)/win32/SettingsWin32.hxx
|
SettingsWin32.o: $(SRC)/win32/SettingsWin32.cxx $(SRC)/win32/SettingsWin32.hxx
|
||||||
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(SRC)/win32/SettingsWin32.cxx
|
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(SRC)/win32/SettingsWin32.cxx
|
||||||
|
|
||||||
OSystemWin32.o: $(SRC)/win32/OSystemWin32.cxx $(SRC)/win32/OSystemWin32.hxx
|
OSystemWin32.o: $(SRC)/win32/OSystemWin32.cxx $(SRC)/win32/OSystemWin32.hxx
|
||||||
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(SRC)/win32/OSystemWin32.cxx
|
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(SRC)/win32/OSystemWin32.cxx
|
||||||
|
|
||||||
|
FSNodeWin32.o: $(SRC)/win32/FSNodeWin32.cxx
|
||||||
|
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(SRC)/win32/FSNodeWin32.cxx
|
||||||
|
|
||||||
SoundNull.o: $(COMMON)/SoundNull.cxx $(COMMON)/SoundNull.hxx
|
SoundNull.o: $(COMMON)/SoundNull.cxx $(COMMON)/SoundNull.hxx
|
||||||
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(COMMON)/SoundNull.cxx
|
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(COMMON)/SoundNull.cxx
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
//
|
||||||
// $Id: mainSDL.cxx,v 1.37 2005-05-06 18:38:59 stephena Exp $
|
// $Id: mainSDL.cxx,v 1.38 2005-05-09 18:58:18 stephena Exp $
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
#include "PropsSet.hxx"
|
#include "PropsSet.hxx"
|
||||||
#include "Sound.hxx"
|
#include "Sound.hxx"
|
||||||
#include "Settings.hxx"
|
#include "Settings.hxx"
|
||||||
|
#include "FSNode.hxx"
|
||||||
#include "OSystem.hxx"
|
#include "OSystem.hxx"
|
||||||
|
|
||||||
#if defined(UNIX)
|
#if defined(UNIX)
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// SSSS tt lll lll
|
||||||
|
// SS SS tt ll ll
|
||||||
|
// SS tttttt eeee ll ll aaaa
|
||||||
|
// SSSS tt ee ee ll ll aa
|
||||||
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||||
|
// SS SS tt ee ll ll aa aa
|
||||||
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
|
//
|
||||||
|
// Copyright (c) 1995-2005 by Bradford W. Mott
|
||||||
|
//
|
||||||
|
// See the file "license" for information on usage and redistribution of
|
||||||
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
|
//
|
||||||
|
// $Id: FSNode.cxx,v 1.1 2005-05-09 18:58:18 stephena Exp $
|
||||||
|
//
|
||||||
|
// Based on code from ScummVM - Scumm Interpreter
|
||||||
|
// Copyright (C) 2002-2004 The ScummVM project
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#include "bspf.hxx"
|
||||||
|
#include "GuiUtils.hxx"
|
||||||
|
#include "FSNode.hxx"
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void FSList::sort()
|
||||||
|
{
|
||||||
|
// Simple selection sort
|
||||||
|
for (Int32 i = 0; i < _size-1; i++)
|
||||||
|
{
|
||||||
|
Int32 min = i;
|
||||||
|
for (Int32 j = i+1; j < _size; j++)
|
||||||
|
if (_data[j] < _data[min])
|
||||||
|
min = j;
|
||||||
|
if (min != i)
|
||||||
|
SWAP(_data[min], _data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
FilesystemNode AbstractFilesystemNode::wrap(AbstractFilesystemNode *node)
|
||||||
|
{
|
||||||
|
FilesystemNode wrapper;
|
||||||
|
wrapper._realNode = node;
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
FilesystemNode::FilesystemNode()
|
||||||
|
{
|
||||||
|
_realNode = getRoot();
|
||||||
|
_refCount = new int(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
FilesystemNode::FilesystemNode(const FilesystemNode &node)
|
||||||
|
: AbstractFilesystemNode()
|
||||||
|
{
|
||||||
|
_realNode = node._realNode;
|
||||||
|
_refCount = node._refCount;
|
||||||
|
++(*_refCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
#ifdef MACOSX
|
||||||
|
FilesystemNode::FilesystemNode(const string& p)
|
||||||
|
{
|
||||||
|
_realNode = getNodeForPath(p);
|
||||||
|
_refCount = new int(1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
FilesystemNode::~FilesystemNode()
|
||||||
|
{
|
||||||
|
decRefCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void FilesystemNode::decRefCount()
|
||||||
|
{
|
||||||
|
--(*_refCount);
|
||||||
|
if (*_refCount <= 0)
|
||||||
|
{
|
||||||
|
delete _refCount;
|
||||||
|
delete _realNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
FilesystemNode &FilesystemNode::operator =(const FilesystemNode &node)
|
||||||
|
{
|
||||||
|
++(*node._refCount);
|
||||||
|
|
||||||
|
decRefCount();
|
||||||
|
|
||||||
|
_realNode = node._realNode;
|
||||||
|
_refCount = node._refCount;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
FilesystemNode FilesystemNode::getParent() const
|
||||||
|
{
|
||||||
|
AbstractFilesystemNode *node = _realNode->parent();
|
||||||
|
|
||||||
|
if(node == 0)
|
||||||
|
return *this;
|
||||||
|
else
|
||||||
|
return AbstractFilesystemNode::wrap(node);
|
||||||
|
}
|
|
@ -0,0 +1,209 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// SSSS tt lll lll
|
||||||
|
// SS SS tt ll ll
|
||||||
|
// SS tttttt eeee ll ll aaaa
|
||||||
|
// SSSS tt ee ee ll ll aa
|
||||||
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||||
|
// SS SS tt ee ll ll aa aa
|
||||||
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
|
//
|
||||||
|
// Copyright (c) 1995-2005 by Bradford W. Mott
|
||||||
|
//
|
||||||
|
// See the file "license" for information on usage and redistribution of
|
||||||
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
|
//
|
||||||
|
// $Id: FSNode.hxx,v 1.1 2005-05-09 18:58:18 stephena Exp $
|
||||||
|
//
|
||||||
|
// Based on code from ScummVM - Scumm Interpreter
|
||||||
|
// Copyright (C) 2002-2004 The ScummVM project
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#ifndef FS_NODE_HXX
|
||||||
|
#define FS_NODE_HXX
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The API described in this header is meant to allow for file system browsing in a
|
||||||
|
* portable fashions. To this ends, multiple or single roots have to be supported
|
||||||
|
* (compare Unix with a single root, Windows with multiple roots C:, D:, ...).
|
||||||
|
*
|
||||||
|
* To this end, we abstract away from paths; implementations can be based on
|
||||||
|
* paths (and it's left to them whether / or \ or : is the path separator :-);
|
||||||
|
* but it is also possible to use inodes or vrefs (MacOS 9) or anything else.
|
||||||
|
*
|
||||||
|
* NOTE: Backends still have to provide a way to extract a path from a FSIntern
|
||||||
|
*
|
||||||
|
* You may ask now: "isn't this cheating? Why do we go through all this when we use
|
||||||
|
* a path in the end anyway?!?".
|
||||||
|
* Well, for once as long as we don't provide our own file open/read/write API, we
|
||||||
|
* still have to use fopen(). Since all our targets already support fopen(), it should
|
||||||
|
* be possible to get a fopen() compatible string for any file system node.
|
||||||
|
*
|
||||||
|
* Secondly, with this abstraction layer, we still avoid a lot of complications based on
|
||||||
|
* differences in FS roots, different path separators, or even systems with no real
|
||||||
|
* paths (MacOS 9 doesn't even have the notion of a "current directory").
|
||||||
|
* And if we ever want to support devices with no FS in the classical sense (Palm...),
|
||||||
|
* we can build upon this.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO - Instead of starting with getRoot(), we should rather add a getDefaultDir()
|
||||||
|
* call that on Unix might return the current dir or the users home dir...
|
||||||
|
* i.e. the root dir is usually not the best starting point for browsing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Array.hxx"
|
||||||
|
|
||||||
|
class FilesystemNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of multiple file system nodes. E.g. the contents of a given directory.
|
||||||
|
*/
|
||||||
|
class FSList : public Array<FilesystemNode>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void sort();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File system node.
|
||||||
|
*/
|
||||||
|
class AbstractFilesystemNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
Flag to tell listDir() which kind of files to list.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
kListFilesOnly = 1,
|
||||||
|
kListDirectoriesOnly = 2,
|
||||||
|
kListAll = 3
|
||||||
|
} ListMode;
|
||||||
|
|
||||||
|
virtual ~AbstractFilesystemNode() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Return display name, used by e.g. the GUI to present the file in the file browser.
|
||||||
|
|
||||||
|
@return the display name
|
||||||
|
*/
|
||||||
|
virtual string displayName() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Is this node valid (i.e. referring to an actual FS object)?
|
||||||
|
*/
|
||||||
|
virtual bool isValid() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Is this node a directory or not?
|
||||||
|
*/
|
||||||
|
virtual bool isDirectory() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
A path representation suitable for use with fopen()
|
||||||
|
*/
|
||||||
|
virtual string path() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
List the content of this directory node.
|
||||||
|
If this node is not a directory, throw an exception or call error().
|
||||||
|
*/
|
||||||
|
virtual FSList listDir(ListMode mode = kListDirectoriesOnly) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Compare the name of this node to the name of another.
|
||||||
|
*/
|
||||||
|
virtual bool operator< (const AbstractFilesystemNode& node) const
|
||||||
|
{
|
||||||
|
string first = displayName();
|
||||||
|
string second = node.displayName();
|
||||||
|
transform(first.begin(), first.end(), first.begin(), (int(*)(int)) tolower);
|
||||||
|
transform(second.begin(), second.end(), second.begin(), (int(*)(int)) tolower);
|
||||||
|
return first < second;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO:
|
||||||
|
bool exists();
|
||||||
|
|
||||||
|
bool isDirectory();
|
||||||
|
bool isFile();
|
||||||
|
|
||||||
|
bool isReadable();
|
||||||
|
bool isWriteable();
|
||||||
|
*/
|
||||||
|
|
||||||
|
protected:
|
||||||
|
friend class FilesystemNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
The parent node of this directory.
|
||||||
|
The parent of the root is the root itself.
|
||||||
|
*/
|
||||||
|
virtual AbstractFilesystemNode *parent() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is a rather ugly hack which is used internally by the
|
||||||
|
* actual node implementions to wrap up raw nodes inside FilesystemNode
|
||||||
|
* objects. We probably want to get rid of this eventually and replace it
|
||||||
|
* with a cleaner / more elegant solution, but for now it works.
|
||||||
|
* @note This takes over ownership of node. Do not delete it yourself,
|
||||||
|
* else you'll get ugly crashes. You've been warned!
|
||||||
|
*/
|
||||||
|
static FilesystemNode wrap(AbstractFilesystemNode *node);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FilesystemNode : public AbstractFilesystemNode
|
||||||
|
{
|
||||||
|
friend class AbstractFilesystemNode;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FilesystemNode();
|
||||||
|
FilesystemNode(const FilesystemNode& node);
|
||||||
|
#ifdef MACOSX
|
||||||
|
FilesystemNode(const string& path);
|
||||||
|
#endif
|
||||||
|
~FilesystemNode();
|
||||||
|
|
||||||
|
FilesystemNode &operator =(const FilesystemNode &node);
|
||||||
|
|
||||||
|
FilesystemNode getParent() const;
|
||||||
|
|
||||||
|
virtual string displayName() const { return _realNode->displayName(); }
|
||||||
|
virtual bool isValid() const { return _realNode->isValid(); }
|
||||||
|
virtual bool isDirectory() const { return _realNode->isDirectory(); }
|
||||||
|
virtual string path() const { return _realNode->path(); }
|
||||||
|
|
||||||
|
virtual FSList listDir(ListMode mode = kListDirectoriesOnly) const
|
||||||
|
{ return _realNode->listDir(mode); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void decRefCount();
|
||||||
|
|
||||||
|
virtual AbstractFilesystemNode* parent() const { return 0; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
AbstractFilesystemNode *_realNode;
|
||||||
|
int *_refCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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:).
|
||||||
|
*/
|
||||||
|
static AbstractFilesystemNode* getRoot();
|
||||||
|
|
||||||
|
#ifdef MACOSX
|
||||||
|
/*
|
||||||
|
* Construct a node based on a path; the path is in the same format as it
|
||||||
|
* would be for calls to fopen().
|
||||||
|
*
|
||||||
|
* I.e. getNodeForPath(oldNode.path()) should create a new node identical to oldNode.
|
||||||
|
*/
|
||||||
|
static AbstractFilesystemNode* getNodeForPath(const string& path);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -13,7 +13,7 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
//
|
||||||
// $Id: Launcher.cxx,v 1.2 2005-05-06 22:50:15 stephena Exp $
|
// $Id: Launcher.cxx,v 1.3 2005-05-09 18:58:19 stephena Exp $
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "OSystem.hxx"
|
#include "OSystem.hxx"
|
||||||
|
@ -36,8 +36,10 @@ Launcher::~Launcher()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Launcher::initialize()
|
void Launcher::initialize()
|
||||||
{
|
{
|
||||||
delete myBaseDialog;
|
// We only create one instance of this dialog, since each time we do so,
|
||||||
myBaseDialog = new LauncherDialog(myOSystem, 0, 0, kLauncherWidth, kLauncherHeight);
|
// the ROM listing is read from disk. This can be very expensive.
|
||||||
|
if(myBaseDialog == NULL)
|
||||||
|
myBaseDialog = new LauncherDialog(myOSystem, 0, 0, kLauncherWidth, kLauncherHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -13,13 +13,14 @@
|
||||||
// See the file "license" for information on usage and redistribution of
|
// See the file "license" for information on usage and redistribution of
|
||||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
//
|
//
|
||||||
// $Id: LauncherDialog.cxx,v 1.3 2005-05-08 17:38:23 stephena Exp $
|
// $Id: LauncherDialog.cxx,v 1.4 2005-05-09 18:58:19 stephena Exp $
|
||||||
//
|
//
|
||||||
// Based on code from ScummVM - Scumm Interpreter
|
// Based on code from ScummVM - Scumm Interpreter
|
||||||
// Copyright (C) 2002-2004 The ScummVM project
|
// Copyright (C) 2002-2004 The ScummVM project
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include "OSystem.hxx"
|
#include "OSystem.hxx"
|
||||||
|
#include "FSNode.hxx"
|
||||||
#include "Widget.hxx"
|
#include "Widget.hxx"
|
||||||
#include "ListWidget.hxx"
|
#include "ListWidget.hxx"
|
||||||
#include "Dialog.hxx"
|
#include "Dialog.hxx"
|
||||||
|
@ -78,9 +79,6 @@ LauncherDialog::LauncherDialog(OSystem* osystem, uInt16 x, uInt16 y,
|
||||||
myList->setEditable(false);
|
myList->setEditable(false);
|
||||||
myList->setNumberingMode(kListNumberingOff);
|
myList->setNumberingMode(kListNumberingOff);
|
||||||
|
|
||||||
// Populate the list
|
|
||||||
updateListing();
|
|
||||||
|
|
||||||
// Restore last selection
|
// Restore last selection
|
||||||
/*
|
/*
|
||||||
string last = ConfMan.get(String("lastselectedgame"), ConfigManager::kApplicationDomain);
|
string last = ConfMan.get(String("lastselectedgame"), ConfigManager::kApplicationDomain);
|
||||||
|
@ -114,6 +112,10 @@ LauncherDialog::~LauncherDialog()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void LauncherDialog::loadConfig()
|
void LauncherDialog::loadConfig()
|
||||||
{
|
{
|
||||||
|
// Assume that if the list is empty, this is the first time that loadConfig()
|
||||||
|
// has been called (and we should reload the list).
|
||||||
|
if(myList->getList().isEmpty())
|
||||||
|
updateListing();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -135,10 +137,35 @@ void LauncherDialog::close()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void LauncherDialog::updateListing()
|
void LauncherDialog::updateListing()
|
||||||
{
|
{
|
||||||
// FIXME - add bulk of KStella code here wrt loading from stella.cache
|
|
||||||
cerr << "LauncherDialog::updateListing()\n";
|
cerr << "LauncherDialog::updateListing()\n";
|
||||||
|
|
||||||
|
// Figure out if the ROM dir has changed since we last accessed it.
|
||||||
|
// If so, we do a full reload from disk (takes quite some time).
|
||||||
|
// Otherwise, we can use the cache file (which is much faster).
|
||||||
|
// FIXME - actually implement the following code
|
||||||
/*
|
/*
|
||||||
Common::StringList l;
|
if(... ROM_DIR_CHANGED ...)
|
||||||
|
loadListFromDisk();
|
||||||
|
else if( ... CACHE_FILE_EXISTS)
|
||||||
|
loadListFromCache();
|
||||||
|
else // we have no other choice
|
||||||
|
loadListFromDisk();
|
||||||
|
*/
|
||||||
|
|
||||||
|
StringList l;
|
||||||
|
|
||||||
|
FilesystemNode t;
|
||||||
|
FilesystemNode dir(t);//"/local/emulators/atari/roms"); // FIXME
|
||||||
|
FSList files = dir.listDir(FilesystemNode::kListAll);
|
||||||
|
files.sort();
|
||||||
|
|
||||||
|
for (int idx = 0; idx < (int)files.size(); idx++)
|
||||||
|
l.push_back(files[idx].displayName());
|
||||||
|
|
||||||
|
/*
|
||||||
|
// ...so let's determine a list of candidates, games that
|
||||||
|
// could be contained in the specified directory.
|
||||||
|
DetectedGameList candidates(PluginManager::instance().detectGames(files));
|
||||||
|
|
||||||
// Retrieve a list of all games defined in the config file
|
// Retrieve a list of all games defined in the config file
|
||||||
_domains.clear();
|
_domains.clear();
|
||||||
|
@ -166,10 +193,9 @@ cerr << "LauncherDialog::updateListing()\n";
|
||||||
_domains.insert_at(pos, iter->_key);
|
_domains.insert_at(pos, iter->_key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_list->setList(l);
|
|
||||||
updateButtons();
|
|
||||||
*/
|
*/
|
||||||
|
myList->setList(l);
|
||||||
|
updateButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -292,19 +318,21 @@ void LauncherDialog::addGame()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void LauncherDialog::handleCommand(CommandSender* sender, uInt32 cmd, uInt32 data)
|
void LauncherDialog::handleCommand(CommandSender* sender, uInt32 cmd, uInt32 data)
|
||||||
{
|
{
|
||||||
Int32 item = myList->getSelected();
|
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case kStartCmd:
|
case kStartCmd:
|
||||||
case kListItemActivatedCmd:
|
case kListItemActivatedCmd:
|
||||||
case kListItemDoubleClickedCmd:
|
case kListItemDoubleClickedCmd:
|
||||||
cerr << "Game selected: " << item << endl;
|
{
|
||||||
// FIXME - start a new console based on the filename selected
|
if(myList->getSelected() >= 0)
|
||||||
// this is only here for testing
|
{
|
||||||
instance()->createConsole("frostbite.a26");
|
string item = myList->getSelectedString();
|
||||||
close();
|
cerr << "Game selected: " << item << endl;
|
||||||
|
instance()->createConsole(item);
|
||||||
|
close();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case kLocationCmd:
|
case kLocationCmd:
|
||||||
cerr << "kLocationCmd from LauncherDialog\n";
|
cerr << "kLocationCmd from LauncherDialog\n";
|
||||||
|
|
|
@ -0,0 +1,199 @@
|
||||||
|
//============================================================================
|
||||||
|
//
|
||||||
|
// SSSS tt lll lll
|
||||||
|
// SS SS tt ll ll
|
||||||
|
// SS tttttt eeee ll ll aaaa
|
||||||
|
// SSSS tt ee ee ll ll aa
|
||||||
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||||
|
// SS SS tt ee ll ll aa aa
|
||||||
|
// SSSS ttt eeeee llll llll aaaaa
|
||||||
|
//
|
||||||
|
// Copyright (c) 1995-2005 by Bradford W. Mott
|
||||||
|
//
|
||||||
|
// See the file "license" for information on usage and redistribution of
|
||||||
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||||
|
//
|
||||||
|
// $Id: FSNodePOSIX.cxx,v 1.1 2005-05-09 18:58:19 stephena Exp $
|
||||||
|
//
|
||||||
|
// Based on code from ScummVM - Scumm Interpreter
|
||||||
|
// Copyright (C) 2002-2004 The ScummVM project
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#include "FSNode.hxx"
|
||||||
|
|
||||||
|
#ifdef MACOSX
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implementation of the Stella file system API based on POSIX (for Linux and OSX)
|
||||||
|
*/
|
||||||
|
|
||||||
|
class POSIXFilesystemNode : public AbstractFilesystemNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
POSIXFilesystemNode();
|
||||||
|
POSIXFilesystemNode(const string& path);
|
||||||
|
POSIXFilesystemNode(const POSIXFilesystemNode* node);
|
||||||
|
|
||||||
|
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(ListMode mode = kListDirectoriesOnly) const;
|
||||||
|
virtual AbstractFilesystemNode* parent() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
string _displayName;
|
||||||
|
bool _isDirectory;
|
||||||
|
bool _isValid;
|
||||||
|
string _path;
|
||||||
|
};
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
static const char* lastPathComponent(const string& str)
|
||||||
|
{
|
||||||
|
// FIXME - use native C++ string code
|
||||||
|
const char *start = str.c_str();
|
||||||
|
const char *cur = start + str.size() - 2;
|
||||||
|
|
||||||
|
while (cur > start && *cur != '/')
|
||||||
|
--cur;
|
||||||
|
|
||||||
|
return cur+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
AbstractFilesystemNode* FilesystemNode::getRoot()
|
||||||
|
{
|
||||||
|
return new POSIXFilesystemNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
#ifdef MACOSX
|
||||||
|
AbstractFilesystemNode* FilesystemNode::getNodeForPath(const string& path)
|
||||||
|
{
|
||||||
|
return new POSIXFilesystemNode(path);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
POSIXFilesystemNode::POSIXFilesystemNode()
|
||||||
|
{
|
||||||
|
char buf[MAXPATHLEN];
|
||||||
|
getcwd(buf, MAXPATHLEN);
|
||||||
|
|
||||||
|
_path = buf;
|
||||||
|
_displayName = lastPathComponent(_path);
|
||||||
|
_path += '/';
|
||||||
|
_isValid = true;
|
||||||
|
_isDirectory = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
POSIXFilesystemNode::POSIXFilesystemNode(const string& p)
|
||||||
|
{
|
||||||
|
Int32 len = 0, offset = p.size();
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
assert(offset > 0);
|
||||||
|
|
||||||
|
_path = p;
|
||||||
|
|
||||||
|
// Extract last component from path
|
||||||
|
const char *str = p.c_str();
|
||||||
|
while (offset > 0 && str[offset-1] == '/')
|
||||||
|
offset--;
|
||||||
|
while (offset > 0 && str[offset-1] != '/')
|
||||||
|
{
|
||||||
|
len++;
|
||||||
|
offset--;
|
||||||
|
}
|
||||||
|
_displayName = string(str + offset, len);
|
||||||
|
|
||||||
|
// Check whether it is a directory, and whether the file actually exists
|
||||||
|
_isValid = (0 == stat(_path.c_str(), &st));
|
||||||
|
_isDirectory = S_ISDIR(st.st_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
POSIXFilesystemNode::POSIXFilesystemNode(const POSIXFilesystemNode* node)
|
||||||
|
{
|
||||||
|
_displayName = node->_displayName;
|
||||||
|
_isValid = node->_isValid;
|
||||||
|
_isDirectory = node->_isDirectory;
|
||||||
|
_path = node->_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
FSList POSIXFilesystemNode::listDir(ListMode mode) const
|
||||||
|
{
|
||||||
|
assert(_isDirectory);
|
||||||
|
DIR *dirp = opendir(_path.c_str());
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
struct dirent *dp;
|
||||||
|
FSList myList;
|
||||||
|
|
||||||
|
if (dirp == NULL)
|
||||||
|
return myList;
|
||||||
|
|
||||||
|
// ... loop over dir entries using readdir
|
||||||
|
while ((dp = readdir(dirp)) != NULL)
|
||||||
|
{
|
||||||
|
// Skip 'invisible' files
|
||||||
|
if (dp->d_name[0] == '.')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
POSIXFilesystemNode entry;
|
||||||
|
entry._displayName = dp->d_name;
|
||||||
|
entry._path = _path;
|
||||||
|
if (entry._path.length() > 0 && entry._path[entry._path.length()-1] != '/')
|
||||||
|
entry._path += '/';
|
||||||
|
entry._path += dp->d_name;
|
||||||
|
|
||||||
|
if (stat(entry._path.c_str(), &st))
|
||||||
|
continue;
|
||||||
|
entry._isDirectory = S_ISDIR(st.st_mode);
|
||||||
|
|
||||||
|
// Honor the chosen mode
|
||||||
|
if ((mode == kListFilesOnly && entry._isDirectory) ||
|
||||||
|
(mode == kListDirectoriesOnly && !entry._isDirectory))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (entry._isDirectory)
|
||||||
|
entry._path += "/";
|
||||||
|
|
||||||
|
myList.push_back(wrap(new POSIXFilesystemNode(&entry)));
|
||||||
|
}
|
||||||
|
closedir(dirp);
|
||||||
|
|
||||||
|
return myList;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
AbstractFilesystemNode *POSIXFilesystemNode::parent() const
|
||||||
|
{
|
||||||
|
if (_path == "/")
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
POSIXFilesystemNode* p = new POSIXFilesystemNode();
|
||||||
|
const char *start = _path.c_str();
|
||||||
|
const char *end = lastPathComponent(_path);
|
||||||
|
|
||||||
|
p->_path = string(start, end - start);
|
||||||
|
p->_displayName = lastPathComponent(p->_path);
|
||||||
|
|
||||||
|
p->_isValid = true;
|
||||||
|
p->_isDirectory = true;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
Loading…
Reference in New Issue