From 70988527c64947fd7fe3c361907e9f0806b0cb5c Mon Sep 17 00:00:00 2001 From: cpasjuste Date: Wed, 1 Mar 2017 14:00:17 -0600 Subject: PSP2: Add Playstation Vita (PSP2) support --- backends/fs/posix/posix-fs.cpp | 7 +- backends/fs/psp2/psp2-dirent.cpp | 241 +++++++++++++++++++++++++++++++++++ backends/fs/psp2/psp2-dirent.h | 59 +++++++++ backends/fs/psp2/psp2-fs-factory.cpp | 45 +++++++ backends/fs/psp2/psp2-fs-factory.h | 41 ++++++ 5 files changed, 392 insertions(+), 1 deletion(-) create mode 100644 backends/fs/psp2/psp2-dirent.cpp create mode 100644 backends/fs/psp2/psp2-dirent.h create mode 100644 backends/fs/psp2/psp2-fs-factory.cpp create mode 100644 backends/fs/psp2/psp2-fs-factory.h (limited to 'backends/fs') diff --git a/backends/fs/posix/posix-fs.cpp b/backends/fs/posix/posix-fs.cpp index 4434bcba97..3f90fc1a19 100644 --- a/backends/fs/posix/posix-fs.cpp +++ b/backends/fs/posix/posix-fs.cpp @@ -20,7 +20,7 @@ * */ -#if defined(POSIX) || defined(PLAYSTATION3) +#if defined(POSIX) || defined(PLAYSTATION3) || defined(PSP2) // Re-enable some forbidden symbols to avoid clashes with stat.h and unistd.h. // Also with clock() in sys/time.h in some Mac OS X SDKs. @@ -36,7 +36,12 @@ #include #include +#ifdef PSP2 +#include "backends/fs/psp2/psp2-dirent.h" +#define mkdir sceIoMkdir +#else #include +#endif #include #include #include diff --git a/backends/fs/psp2/psp2-dirent.cpp b/backends/fs/psp2/psp2-dirent.cpp new file mode 100644 index 0000000000..aefd1a067d --- /dev/null +++ b/backends/fs/psp2/psp2-dirent.cpp @@ -0,0 +1,241 @@ +/* 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. + * + */ + +/* + +Copyright (C) 2016, David "Davee" Morgan + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#include "psp2-dirent.h" +#include +#include +#include + +#include +#include +#include + +#define SCE_ERRNO_MASK 0xFF + + +struct DIR_ { + SceUID uid; + struct dirent dir; + int refcount; + char *dirname; + int index; +}; + +static inline void grab_dir(DIR *dirp) { + __sync_add_and_fetch(&dirp->refcount, 1); +} + +static inline void drop_dir(DIR *dirp) { + if (__sync_add_and_fetch(&dirp->refcount, 1) == 0) { + free(dirp->dirname); + free(dirp); + } +} + +static inline void release_drop_dir(DIR *dirp) { + if (__sync_add_and_fetch(&dirp->refcount, 2) == 0) { + free(dirp->dirname); + free(dirp); + } +} + +static inline void atomic_exchange(int *obj, int desired) { + __sync_synchronize(); + __sync_lock_test_and_set(obj, desired); +} + +#ifdef F_closedir +int closedir(DIR *dirp) { + if (!dirp) { + errno = EBADF; + return -1; + } + + grab_dir(dirp); + + int res = sceIoDclose(dirp->uid); + + if (res < 0) { + errno = res & SCE_ERRNO_MASK; + drop_dir(dirp); + return -1; + } + + release_drop_dir(dirp); + + errno = 0; + return 0; +} +#endif + +#if F_opendir +DIR *opendir(const char *dirname) { + SceUID uid = sceIoDopen(dirname); + + if (uid < 0) { + errno = uid & SCE_ERRNO_MASK; + return NULL; + } + + DIR *dirp = (DIR *)calloc(1, sizeof(DIR)); + + if (!dirp) { + sceIoDclose(uid); + errno = ENOMEM; + return NULL; + } + + dirp->refcount = 1; + dirp->uid = uid; + dirp->dirname = strdup(dirname); + dirp->index = 0; + + errno = 0; + return dirp; +} +#endif + +#ifdef F_readdir +struct dirent *readdir(DIR *dirp) { + if (!dirp) { + errno = EBADF; + return NULL; + } + + grab_dir(dirp); + + int res = sceIoDread(dirp->uid, (SceIoDirent *)&dirp->dir); + + if (res < 0) { + errno = res & SCE_ERRNO_MASK; + drop_dir(dirp); + return NULL; + } + + if (res == 0) { + errno = 0; + drop_dir(dirp); + return NULL; + } + + __sync_add_and_fetch(&dirp->index, 1); + + struct dirent *dir = &dirp->dir; + drop_dir(dirp); + return dir; +} +#endif +#ifdef F_readdir_r +int readdir_r(DIR *dirp, struct dirent *x, struct dirent **y) { + errno = ENOSYS; + return -1; +} +#endif + +#ifdef F_rewinddir +void rewinddir(DIR *dirp) { + if (!dirp) { + errno = EBADF; + return; + } + + grab_dir(dirp); + + SceUID dirfd = sceIoDopen(dirp->dirname); + + if (dirfd < 0) { + errno = dirfd & SCE_ERRNO_MASK; + drop_dir(dirp); + return; + } + + sceIoDclose(dirp->uid); + atomic_exchange(&dirp->uid, dirfd); + atomic_exchange(&dirp->index, 0); + + drop_dir(dirp); +} +#endif + +#ifdef F_seekdir +void seekdir(DIR *dirp, long int index) { + if (!dirp) { + errno = EBADF; + return; + } + + grab_dir(dirp); + + if (index < dirp->index) + rewinddir(dirp); + + if (index < dirp->index) { + drop_dir(dirp); + return; + } + + while (index != dirp->index) { + if (!readdir(dirp)) { + errno = ENOENT; + drop_dir(dirp); + return; + } + } + + drop_dir(dirp); +} +#endif + +#ifdef F_telldir +long int telldir(DIR *dirp) { + if (!dirp) { + errno = EBADF; + return -1; + } + + return dirp->index; +} +#endif diff --git a/backends/fs/psp2/psp2-dirent.h b/backends/fs/psp2/psp2-dirent.h new file mode 100644 index 0000000000..0e56976404 --- /dev/null +++ b/backends/fs/psp2/psp2-dirent.h @@ -0,0 +1,59 @@ +/* + +Copyright (C) 2016, David "Davee" Morgan + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +*/ + +#ifndef _PSP2_DIRENT_H_ +#define _PSP2_DIRENT_H_ + +#include +#include + +#include + +#define F_opendir 1 +#define F_readdir 1 +#define F_closedir 1 + +struct dirent +{ + /** File status. */ + SceIoStat d_stat; + /** File name. */ + char d_name[256]; + /** Device-specific data. */ + void *d_private; + int dummy; +}; + +struct DIR_; +typedef struct DIR_ DIR; + +int closedir(DIR *); +DIR *opendir(const char *); +struct dirent *readdir(DIR *); +int readdir_r(DIR *, struct dirent *, struct dirent **); +void rewinddir(DIR *); +void seekdir(DIR *, long int); +long int telldir(DIR *); + +#endif /* _PSP2_DIRENT_H_ */ diff --git a/backends/fs/psp2/psp2-fs-factory.cpp b/backends/fs/psp2/psp2-fs-factory.cpp new file mode 100644 index 0000000000..68d91122b8 --- /dev/null +++ b/backends/fs/psp2/psp2-fs-factory.cpp @@ -0,0 +1,45 @@ +/* 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. + * + */ + +// Re-enable some forbidden symbols to avoid clashes with stat.h and unistd.h. +// Also with clock() in sys/time.h in some Mac OS X SDKs. +#define FORBIDDEN_SYMBOL_EXCEPTION_time_h +#define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h +#define FORBIDDEN_SYMBOL_EXCEPTION_mkdir +#define FORBIDDEN_SYMBOL_EXCEPTION_exit //Needed for IRIX's unistd.h + +#include "backends/fs/posix/posix-fs-factory.h" +#include "backends/fs/posix/posix-fs.h" +#include "backends/fs/psp2/psp2-fs-factory.h" + +AbstractFSNode *PSP2FilesystemFactory::makeRootFileNode() const { + return new POSIXFilesystemNode("ux0:"); +} + +AbstractFSNode *PSP2FilesystemFactory::makeCurrentDirectoryFileNode() const { + return makeRootFileNode(); +} + +AbstractFSNode *PSP2FilesystemFactory::makeFileNodePath(const Common::String &path) const { + assert(!path.empty()); + return new POSIXFilesystemNode(path); +} diff --git a/backends/fs/psp2/psp2-fs-factory.h b/backends/fs/psp2/psp2-fs-factory.h new file mode 100644 index 0000000000..3429b815ae --- /dev/null +++ b/backends/fs/psp2/psp2-fs-factory.h @@ -0,0 +1,41 @@ +/* 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. + * + */ + +#ifndef PSP2_FILESYSTEM_FACTORY_H +#define PSP2_FILESYSTEM_FACTORY_H + +#include "backends/fs/posix/posix-fs-factory.h" + +/** + * Creates PSP2FilesystemFactory objects. + * + * Parts of this class are documented in the base interface class, FilesystemFactory. + */ + +class PSP2FilesystemFactory : public FilesystemFactory { +protected: + virtual AbstractFSNode *makeRootFileNode() const; + virtual AbstractFSNode *makeCurrentDirectoryFileNode() const; + virtual AbstractFSNode *makeFileNodePath(const Common::String &path) const; +}; + +#endif /*PSP2_FILESYSTEM_FACTORY_H*/ -- cgit v1.2.3