diff options
Diffstat (limited to 'backends/fs')
| -rw-r--r-- | backends/fs/psp/psp-fs-factory.cpp | 8 | ||||
| -rw-r--r-- | backends/fs/psp/psp-fs.cpp | 62 | ||||
| -rw-r--r-- | backends/fs/psp/psp-stream.cpp | 230 | ||||
| -rw-r--r-- | backends/fs/psp/psp-stream.h | 70 | 
4 files changed, 360 insertions, 10 deletions
diff --git a/backends/fs/psp/psp-fs-factory.cpp b/backends/fs/psp/psp-fs-factory.cpp index 27bee4de86..7ed84de034 100644 --- a/backends/fs/psp/psp-fs-factory.cpp +++ b/backends/fs/psp/psp-fs-factory.cpp @@ -34,7 +34,13 @@ AbstractFSNode *PSPFilesystemFactory::makeRootFileNode() const {  AbstractFSNode *PSPFilesystemFactory::makeCurrentDirectoryFileNode() const {  	char buf[MAXPATHLEN]; -	return getcwd(buf, MAXPATHLEN) ? new PSPFilesystemNode(buf) : NULL; +	char * ret = 0; + +	PowerMan.beginCriticalSection(); +	ret = getcwd(buf, MAXPATHLEN); +	PowerMan.endCriticalSection(); + +	return (ret ? new PSPFilesystemNode(buf) : NULL);  }  AbstractFSNode *PSPFilesystemFactory::makeFileNodePath(const Common::String &path) const { diff --git a/backends/fs/psp/psp-fs.cpp b/backends/fs/psp/psp-fs.cpp index f5ff65c9fa..03247e86ad 100644 --- a/backends/fs/psp/psp-fs.cpp +++ b/backends/fs/psp/psp-fs.cpp @@ -26,7 +26,8 @@  #include "engines/engine.h"  #include "backends/fs/abstract-fs.h" -#include "backends/fs/stdiostream.h" +#include "backends/fs/psp/psp-stream.h" +#include "backends/platform/psp/powerman.h"  #include <sys/stat.h>  #include <unistd.h> @@ -35,6 +36,9 @@  #define	ROOT_PATH	"ms0:/" +#include "backends/platform/psp/trace.h" + +  /**   * Implementation of the ScummVM file system API based on PSPSDK API.   * @@ -61,13 +65,13 @@ public:  	 */  	PSPFilesystemNode(const Common::String &p, bool verify = true); -	virtual bool exists() const { return access(_path.c_str(), F_OK) == 0; } +	virtual bool exists() const;  	virtual Common::String getDisplayName() const { return _displayName; }  	virtual Common::String getName() const { return _displayName; }  	virtual Common::String getPath() const { return _path; }  	virtual bool isDirectory() const { return _isDirectory; } -	virtual bool isReadable() const { return access(_path.c_str(), R_OK) == 0; } -	virtual bool isWritable() const { return access(_path.c_str(), W_OK) == 0; } +	virtual bool isReadable() const; +	virtual bool isWritable() const;  	virtual AbstractFSNode *getChild(const Common::String &n) const;  	virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const; @@ -94,11 +98,44 @@ PSPFilesystemNode::PSPFilesystemNode(const Common::String &p, bool verify) {  	if (verify) {  		struct stat st; +		PowerMan.beginCriticalSection();  		_isValid = (0 == stat(_path.c_str(), &st)); +		PowerMan.endCriticalSection();  		_isDirectory = S_ISDIR(st.st_mode);  	}  } +bool PSPFilesystemNode::exists() const { +	int ret = 0; + +	PowerMan.beginCriticalSection();	// Make sure to block in case of suspend +	ret = access(_path.c_str(), F_OK); +	PowerMan.endCriticalSection(); +	 +	return ret == 0; +} + +bool PSPFilesystemNode::isReadable() const { +	int ret = 0; + +	PowerMan.beginCriticalSection();	// Make sure to block in case of suspend +	ret = access(_path.c_str(), R_OK); +	PowerMan.endCriticalSection(); +	 +	return ret == 0; +} + +bool PSPFilesystemNode::isWritable() const { +	int ret = 0; + +	PowerMan.beginCriticalSection();	// Make sure to block in case of suspend +	ret = access(_path.c_str(), W_OK); +	PowerMan.endCriticalSection(); +	 +	return ret == 0; +} + +  AbstractFSNode *PSPFilesystemNode::getChild(const Common::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. @@ -117,6 +154,10 @@ bool PSPFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool  	//TODO: honor the hidden flag +	bool ret = true; + +	PowerMan.beginCriticalSection();	// Make sure to block in case of suspend +	  	int dfd  = sceIoDopen(_path.c_str());  	if (dfd > 0) {  		SceIoDirent dir; @@ -149,10 +190,13 @@ bool PSPFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool  		}  		sceIoDclose(dfd); -		return true; -	} else { -		return false; +		ret = true; +	} else { // dfd <= 0 +		ret = false;  	} + +	PowerMan.endCriticalSection(); +	return ret;  }  AbstractFSNode *PSPFilesystemNode::getParent() const { @@ -166,11 +210,11 @@ AbstractFSNode *PSPFilesystemNode::getParent() const {  }  Common::SeekableReadStream *PSPFilesystemNode::createReadStream() { -	return StdioStream::makeFromPath(getPath().c_str(), false); +	return PSPIoStream::makeFromPath(getPath(), false);  }  Common::WriteStream *PSPFilesystemNode::createWriteStream() { -	return StdioStream::makeFromPath(getPath().c_str(), true); +	return PSPIoStream::makeFromPath(getPath(), true);  }  #endif //#ifdef __PSP__ diff --git a/backends/fs/psp/psp-stream.cpp b/backends/fs/psp/psp-stream.cpp new file mode 100644 index 0000000000..fac4067f46 --- /dev/null +++ b/backends/fs/psp/psp-stream.cpp @@ -0,0 +1,230 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ +#ifdef __PSP__ + +#include "backends/fs/psp/psp-stream.h" +#include "backends/platform/psp/trace.h" +#include <errno.h> + +PSPIoStream::PSPIoStream(const Common::String &path, bool writeMode) +: StdioStream((void *)1), _path(path), _writeMode(writeMode) { + +	assert(!path.empty()); + +	_handle = (void *)0;		// Need to do this since base class asserts not 0. + +	PowerMan.registerSuspend(this);	 // Register with the powermanager to be suspended + +} + +PSPIoStream::~PSPIoStream() { +	PowerMan.unregisterSuspend(this); // Unregister with powermanager to be suspended +								 // Must do this before fclose() or resume() will reopen. + +	fclose((FILE *)_handle); +} + +// Function to open the file pointed to by the path. +// +// +void * PSPIoStream::open() { +	if (PowerMan.beginCriticalSection()==PowerManager::Blocked) { +		// No need to open. Just return the _handle resume() already opened. +		PSPDebugTrace("Suspended in PSPIoStream::open\n"); +	} else { +		_handle = fopen(_path.c_str(), _writeMode ? "wb" : "rb"); 	// open +	} +	 +	PowerMan.endCriticalSection(); + +	return _handle; +} + +bool PSPIoStream::err() const { +	bool ret; + +	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) +		PSPDebugTrace("Suspended in PSPIoStream::err()\n"); + +	ret = ferror((FILE *)_handle) != 0; + +	PowerMan.endCriticalSection(); + +	return ret; +} + +void PSPIoStream::clearErr() { +	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) +		PSPDebugTrace("Suspended in PSPIoStream::clearErr()\n"); + +	clearerr((FILE *)_handle); + +	PowerMan.endCriticalSection(); +} + +bool PSPIoStream::eos() const { +	bool ret; + +	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) +		PSPDebugTrace("Suspended in PSPIoStream::eos()\n"); + +	ret = feof((FILE *)_handle) != 0; + +	PowerMan.endCriticalSection(); + +	return ret; +} + +int32 PSPIoStream::pos() const { +	int32 ret; + +	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) +		PSPDebugTrace("Suspended in PSPIoStream::pos()\n"); + +	ret = ftell((FILE *)_handle); + +	PowerMan.endCriticalSection(); + +	return ret; +} + + +int32 PSPIoStream::size() const { +	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) +		PSPDebugTrace("Suspended in PSPIoStream::size()\n"); + +	int32 oldPos = ftell((FILE *)_handle); +	fseek((FILE *)_handle, 0, SEEK_END); +	int32 length = ftell((FILE *)_handle); +	fseek((FILE *)_handle, oldPos, SEEK_SET); + +	PowerMan.endCriticalSection(); + +	return length; +} + +bool PSPIoStream::seek(int32 offs, int whence) { +	int ret = 0; + +	// Check if we can access the file +	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) +		PSPDebugTrace("Suspended in PSPIoStream::seek()\n"); + +	ret = fseek((FILE *)_handle, offs, whence); + +	PowerMan.endCriticalSection(); + +	return ret == 0; +} + +uint32 PSPIoStream::read(void *ptr, uint32 len) { +	int ret = 0; + +	// Check if we can access the file +	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) +		PSPDebugTrace("Suspended in PSPIoStream::read()\n"); + +	ret = fread((byte *)ptr, 1, len, (FILE *)_handle); +	 +	PowerMan.endCriticalSection(); +	 +	return ret; +} + +uint32 PSPIoStream::write(const void *ptr, uint32 len) { +	int ret = 0; + +	// Check if we can access the file +	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) +		PSPDebugTrace("Suspended in PSPIoStream::read()\n"); + +	ret = fwrite(ptr, 1, len, (FILE *)_handle); + +	PowerMan.endCriticalSection(); + +	return ret; +} + +bool PSPIoStream::flush() { +	int ret = 0; + +	// Check if we can access the file +	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) +		PSPDebugTrace("Suspended in PSPIoStream::read()\n"); + +	ret = fflush((FILE *)_handle); + +	PowerMan.endCriticalSection(); + +	return ret == 0; +} + +// For the PSP, since we're building in suspend support, we moved opening +// the actual file to an open function since we need an actual PSPIoStream object to suspend. +// +PSPIoStream *PSPIoStream::makeFromPath(const Common::String &path, bool writeMode) { +	PSPIoStream *stream = new PSPIoStream(path, writeMode); + +	if (stream->open() > 0) { +		return stream; +	} else { +		delete stream; +		return 0; +	} +} + +/* + *  Function to suspend the IO stream (called by PowerManager) + */ +int PSPIoStream::suspend() { +	if (_handle > 0) { +		_pos = ftell((FILE *)_handle);	// Save our position +		fclose((FILE *)_handle);		// close our file descriptor +		_handle = 0;					// Set handle to null +	} + +	return 0; +} + +/* + *  Function to resume the IO stream (called by Power Manager) + */ +int PSPIoStream::resume() { +	int ret = 0; + +	// We reopen our file descriptor +	_handle = fopen(_path.c_str(), _writeMode ? "wb" : "rb"); +	if (_handle <= 0) { +		PSPDebugTrace("PSPIoStream::resume(): Couldn't reopen file %s\n", _path.c_str()); +		ret = -1;; +	} + +	// Resume our previous position +	if(_handle > 0) fseek((FILE *)_handle, _pos, SEEK_SET); + +	return ret; +} + +#endif /* __PSP__ */ diff --git a/backends/fs/psp/psp-stream.h b/backends/fs/psp/psp-stream.h new file mode 100644 index 0000000000..0363c92416 --- /dev/null +++ b/backends/fs/psp/psp-stream.h @@ -0,0 +1,70 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef PSPSTREAM_H_ +#define PSPSTREAM_H_ + +#include "backends/fs/stdiostream.h" +#include "backends/platform/psp/powerman.h" +#include "common/list.h" + +/* + *  Class to handle special suspend/resume needs of PSP IO Streams + */ +class PSPIoStream : public StdioStream, public Suspendable { +protected: +	Common::String _path;			/* Need to maintain for reopening after suspend */ +	bool _writeMode;				/* "" */ +	unsigned int _pos;				/* "" */ + +public: +	/** +	 * Given a path, invoke fopen on that path and wrap the result in a +	 * PSPIoStream instance. +	 */ +	static PSPIoStream *makeFromPath(const Common::String &path, bool writeMode); + +	PSPIoStream(const Common::String &path, bool writeMode); +	virtual ~PSPIoStream(); + +	void * open();		// open the file pointed to by the file path + +	bool err() const; +	void clearErr(); +	bool eos() const; + +	virtual uint32 write(const void *dataPtr, uint32 dataSize); +	virtual bool flush(); + +	virtual int32 pos() const; +	virtual int32 size() const; +	virtual bool seek(int32 offs, int whence = SEEK_SET); +	virtual uint32 read(void *dataPtr, uint32 dataSize); + +	int suspend();		/* Suspendable interface (power manager) */ +	int resume();		/* " " */ +}; + +#endif /* PSPSTREAM_H_ */  | 
