From 804910c42219ddbbc428f619515952c1474e9096 Mon Sep 17 00:00:00 2001 From: Max Lingua Date: Wed, 4 Mar 2009 03:55:00 +0000 Subject: - 0.13.x friendly ;-) - new GUI/themes - no more funky colors! - load/delete saved games - cleaned-up Makefile.PS2 : - dropped multiple extra paths - dropped deprecated deps (UCL, MPEG2) - all possible devices are supported to store, play and save games: - CD - HD - USB - MC - REMOTE ! (this could actually be anywhere on the internet as long as you run "ps2client listen" on the machine on the other side that hosts the games) - tested from : - ps2link - uLE - toxicOS - tested with: - bass - bs1 - mi1 - comi - indy4 - ft - ite - ihnm - elvira1 - dig - kyra - lure - simon2 - goblins1 Played all those games in 1 session using RTL. Very smooth, sub-second RTL experience. No crash! - new PAL/NTSC detection : we are now reading the flavor from PS2 ROM, it should work on all PS2 slim too - new PAL TV centering : no more missing chunk of games on top/bottom - we can now read the savefiles from Linux/SDL and other backends! if you add that you can read them from remote together with the games that you already have there, you can imagine the fun ;-) - we fully implement RTL with every games/engine - we nicely reboot / shutdown on quit - fully support for themes/savegames paths. Run from MC, play the games on remote and store your data on USB or HD. No limits! - universal write/read for every media (of course no write on CD/DVD!) - fully async / DMA read-write access to every media (even MC!) - optimized cache/read-ahead for every media - now COMI is fast and enjoyable from remote as it is from CD ;-) - non polluting MC storage, just 1 folder + 1 icon, so that you can copy all your settings / saved games to another MC in one go! svn-id: r39102 --- backends/fs/ps2/ps2-fs-factory.cpp | 14 +- backends/fs/ps2/ps2-fs-factory.h | 4 +- backends/fs/ps2/ps2-fs.cpp | 413 ++++++++++++++------- backends/platform/ps2/Gs2dScreen.cpp | 39 +- backends/platform/ps2/Makefile.ps2 | 61 +-- backends/platform/ps2/asyncfio.cpp | 30 ++ backends/platform/ps2/asyncfio.h | 3 + backends/platform/ps2/fileio.cpp | 570 +++++++++------------------- backends/platform/ps2/fileio.h | 58 ++- backends/platform/ps2/icon.cpp | 60 ++- backends/platform/ps2/icon.h | 31 ++ backends/platform/ps2/irxboot.cpp | 45 ++- backends/platform/ps2/irxboot.h | 19 +- backends/platform/ps2/ps2debug.cpp | 22 ++ backends/platform/ps2/ps2debug.h | 2 +- backends/platform/ps2/ps2temp.h | 63 ++++ backends/platform/ps2/rawsavefile.cpp | 168 --------- backends/platform/ps2/rawsavefile.h | 74 ---- backends/platform/ps2/rpckbd.h | 22 ++ backends/platform/ps2/savefile.cpp | 273 -------------- backends/platform/ps2/savefile.h | 116 ------ backends/platform/ps2/savefilemgr.cpp | 676 ++++++++++------------------------ backends/platform/ps2/savefilemgr.h | 66 +--- backends/platform/ps2/systemps2.cpp | 288 +++++++++++---- backends/platform/ps2/systemps2.h | 26 +- 25 files changed, 1286 insertions(+), 1857 deletions(-) create mode 100644 backends/platform/ps2/icon.h create mode 100644 backends/platform/ps2/ps2temp.h delete mode 100644 backends/platform/ps2/rawsavefile.cpp delete mode 100644 backends/platform/ps2/rawsavefile.h delete mode 100644 backends/platform/ps2/savefile.cpp delete mode 100644 backends/platform/ps2/savefile.h diff --git a/backends/fs/ps2/ps2-fs-factory.cpp b/backends/fs/ps2/ps2-fs-factory.cpp index 77fb4b0866..18478b4f3d 100644 --- a/backends/fs/ps2/ps2-fs-factory.cpp +++ b/backends/fs/ps2/ps2-fs-factory.cpp @@ -37,18 +37,6 @@ AbstractFSNode *Ps2FilesystemFactory::makeCurrentDirectoryFileNode() const { } AbstractFSNode *Ps2FilesystemFactory::makeFileNodePath(const Common::String &path) const { - // return new Ps2FilesystemNode(path); - - Ps2FilesystemNode *nf = new Ps2FilesystemNode(path, true); -/* - int fd = fio.dopen(path.c_str()); - if (fd < 0) { - nf->_isDirectory = false; - } - else { - fio.dclose(fd); - } -*/ - return nf; // new Ps2FilesystemNode(path, true); + return new Ps2FilesystemNode(path, true); } #endif diff --git a/backends/fs/ps2/ps2-fs-factory.h b/backends/fs/ps2/ps2-fs-factory.h index 3a1dec252d..ca2ae670c4 100644 --- a/backends/fs/ps2/ps2-fs-factory.h +++ b/backends/fs/ps2/ps2-fs-factory.h @@ -18,8 +18,8 @@ * 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$ + * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-0-13-0/backends/fs/ps2/ps2-fs-factory.h $ + * $Id: ps2-fs-factory.h 35648 2009-01-01 15:06:43Z sev $ */ #ifndef PS2_FILESYSTEM_FACTORY_H diff --git a/backends/fs/ps2/ps2-fs.cpp b/backends/fs/ps2/ps2-fs.cpp index a8dcb4d2bb..57bdc8620f 100644 --- a/backends/fs/ps2/ps2-fs.cpp +++ b/backends/fs/ps2/ps2-fs.cpp @@ -33,6 +33,10 @@ #include "backends/platform/ps2/systemps2.h" #include "backends/platform/ps2/ps2debug.h" +#include + +#include "ps2temp.h" + #define DEFAULT_MODE (FIO_S_IRUSR | FIO_S_IWUSR | FIO_S_IRGRP | FIO_S_IWGRP | FIO_S_IROTH | FIO_S_IWOTH) extern AsyncFio fio; @@ -52,10 +56,12 @@ protected: Common::String _path; bool _isDirectory; bool _isRoot; + bool _isHere; + bool _verified; private: - char *getDeviceDescription(const char *path) const; - bool getDirectoryFlag(const char *path); + char *getDeviceDescription() const; + void doverify(); public: /** @@ -76,23 +82,28 @@ public: */ Ps2FilesystemNode(const Ps2FilesystemNode *node); - virtual bool exists(void) const; - virtual Common::String getDisplayName() const { return _displayName; } virtual Common::String getName() const { return _displayName; } virtual Common::String getPath() const { return _path; } + virtual bool exists() const { + // printf("%s : is %d\n", _path.c_str(), _isHere); + return _isHere; + } + virtual bool isDirectory() const { + // printf("%s : dir %d\n", _path.c_str(), _isDirectory); return _isDirectory; } virtual bool isReadable() const { - return exists(); + return _isHere; } virtual bool isWritable() const { - // The only writable device on the ps2 is the memory card - return false; + if (strncmp(_path.c_str(), "cdfs", 4)==0) + return false; + return true; // exists(); // creating ? } virtual AbstractFSNode *clone() const { return new Ps2FilesystemNode(this); } @@ -100,60 +111,110 @@ public: virtual bool getChildren(AbstractFSList &list, ListMode mode, bool hidden) const; virtual AbstractFSNode *getParent() const; - virtual Common::SeekableReadStream *createReadStream(); - virtual Common::WriteStream *createWriteStream(); + virtual Common::SeekableReadStream *openForReading(); + virtual Common::WriteStream *openForWriting(); + + int getDev() { return 0; }; }; +const char *_lastPathComponent(const Common::String &str) { + if (str.empty()) + return ""; + + const char *start = str.c_str(); + const char *cur = start + str.size() - 2; + + while (cur >= start && *cur != '/' && *cur != ':') { + --cur; + } + + cur++; + + // printf("lastPathComponent path=%s token=%s\n", start, cur); + + return cur; +} + Ps2FilesystemNode::Ps2FilesystemNode() { + printf("NEW FSNODE()\n"); + + _isHere = true; _isDirectory = true; _isRoot = true; - _displayName = "PlayStation 2"; + _verified = false; + _displayName = Common::String("PlayStation 2"); _path = ""; } Ps2FilesystemNode::Ps2FilesystemNode(const Common::String &path) { + printf("NEW FSNODE(%s)\n", path.c_str()); + _path = path; - _isDirectory = true; - if (strcmp(path.c_str(), "") == 0) { + + if (path.empty()) { + _isHere = true; + _isDirectory = true; /* root is always a dir */ _isRoot = true; _displayName = Common::String("PlayStation 2"); + _verified = true; + } else if (path.lastChar() == ':') { + _isHere = true; + _isDirectory = true; /* devs are always a dir */ + _isRoot = false; + _displayName = getDeviceDescription(); + _verified = true; } else { + _verified = false; + doverify(); + if (!_isHere) + return; + + _displayName = _lastPathComponent(_path); + + if (_isDirectory && _path.lastChar() != '/') + _path+= '/'; + _isRoot = false; - const char *dsplName = NULL, *pos = path.c_str(); - while (*pos) - if (*pos++ == '/') - dsplName = pos; - if (dsplName) - _displayName = Common::String(dsplName); - else - _displayName = getDeviceDescription(path.c_str()); } } Ps2FilesystemNode::Ps2FilesystemNode(const Common::String &path, bool verify) { + printf("NEW FSNODE(%s, %d)\n", path.c_str(), verify); + _path = path; - if (strcmp(path.c_str(), "") == 0) { - _isRoot = true; /* root is always a dir*/ + if (path.empty()) { + _isHere = true; + _isDirectory = true; /* root is always a dir */ + _isRoot = true; _displayName = Common::String("PlayStation 2"); - _isDirectory = true; - } else { + _verified = true; + } else if (path.lastChar() == ':') { + _isHere = true; + _isDirectory = true; /* devs are always a dir */ _isRoot = false; - const char *dsplName = NULL, *pos = path.c_str(); - while (*pos) - if (*pos++ == '/') - dsplName = pos; - - if (dsplName) { - _displayName = Common::String(dsplName); - if (verify) - _isDirectory = getDirectoryFlag(path.c_str()); - else - _isDirectory = false; + _displayName = getDeviceDescription(); + _verified = true; + } else { + _verified = false; + if (verify) { + doverify(); + + if (!_isHere) + return; + } else { - _displayName = getDeviceDescription(path.c_str()); - _isDirectory = true; /* devices are always dir */ + _verified = false; + _isDirectory = false; + _isHere = false; // true } + + _displayName = _lastPathComponent(_path); + + if (_isDirectory && _path.lastChar() != '/') + _path+= '/'; + + _isRoot = false; } } @@ -162,61 +223,149 @@ Ps2FilesystemNode::Ps2FilesystemNode(const Ps2FilesystemNode *node) { _isDirectory = node->_isDirectory; _path = node->_path; _isRoot = node->_isRoot; + _isHere = node->_isHere; + _verified = node->_verified; } -bool Ps2FilesystemNode::exists(void) const { +void Ps2FilesystemNode::doverify(void) { + PS2Device medium; + int fd; - dbg_printf("Ps2FilesystemNode::exists: path \"%s\": ", _path.c_str()); + if (_verified) + return; - if (_path[4] != ':') { // don't bother for relative path... they always fail on PS2! - dbg_printf("NO, relative path\n"); - return false; + _verified = true; + + printf(" verify: %s -> ", _path.c_str()); + +#if 0 + if (_path.empty()) { + printf("PlayStation 2 Root !\n"); + _verified = true; + return; } - if (_path[0] == 'h') { // bypass host - dbg_printf("NO, host device ignored\n"); - return false; + if (_path.lastChar() == ':') { + printf("Dev: %s\n", _path.c_str()); + _verified = true; + return; } +#endif - int fd = fio.open(_path.c_str(), O_RDONLY); - if (fd == -EISDIR) { - dbg_printf("YES, directory\n"); - return true; - } else if (fd >= 0) { - dbg_printf("YES, file\n"); - fio.close(fd); - return true; + if (_path[3] != ':' && _path[4] != ':') { + printf("relative path !\n"); + _isHere = false; + _isDirectory = false; + return; } - printf("NO, not found\n"); - return false; -} + medium = _getDev(_path); + if (medium == ERR_DEV) { + _isHere = false; + _isDirectory = false; + return; + } -bool Ps2FilesystemNode::getDirectoryFlag(const char *path) { - if (strncmp(path, "host:", 5) == 0) - return true; // Can't get listings from host: right now + switch (medium) { +#if 0 + case HD_DEV: /*stat*/ + case USB_DEV: + iox_stat_t stat; - int fd = fio.open(_path.c_str(), O_RDONLY); + fileXioGetStat(_path.c_str(), &stat); + fileXioWaitAsync(FXIO_WAIT, &fd); - if (fd == -EISDIR) { - dbg_printf(" romeo : new node [ %s ] is a dir\n", path); - return true; - } else if (fd >=0) { - dbg_printf(" romeo : new node [ %s ] is -not- a dir (%d)\n", path, fd); + if (!fd) { + printf(" yes [stat]\n"); + return true; + } + break; +#endif + + case CD_DEV: /*no stat*/ + case HD_DEV: + case USB_DEV: + case HOST_DEV: + case MC_DEV: +#if 1 + fd = fio.open(_path.c_str(), O_RDONLY); + + printf("_path = %s -- fio.open -> %d\n", _path.c_str(), fd); + + if (fd >=0) { fio.close(fd); - } else - dbg_printf(" romeo : new node [ %s ] is -not- (%d)\n", path, fd); + printf(" yes [open]\n"); + _isHere = true; + if (medium==MC_DEV && _path.lastChar()=='/') + _isDirectory = true; + else + _isDirectory = false; + return; + } - return false; + fd = fio.dopen(_path.c_str()); + if (fd >=0) { + fio.dclose(fd); + printf(" yes [dopen]\n"); + _isHere = true; + _isDirectory = true; + return; + } + +#else + fileXioOpen(_path.c_str(), O_RDONLY, DEFAULT_MODE); + fileXioWaitAsync(FXIO_WAIT, &fd); + if (fd>=0) { + fileXioClose(fd); + fileXioWaitAsync(FXIO_WAIT, &fd); + return true; + } + + fileXioDopen(_path.c_str()); + fileXioWaitAsync(FXIO_WAIT, &fd); + if (fd>=0) { + fileXioDclose(fd); + fileXioWaitAsync(FXIO_WAIT, &fd); + return true; + } +#endif + break; + case ERR_DEV: + _isHere = false; + _isDirectory = false; + break; + } + + _isHere = false; + _isDirectory = false; + + printf(" no\n"); + return; } AbstractFSNode *Ps2FilesystemNode::getChild(const Common::String &n) const { + + printf("getChild : %s\n", n.c_str()); + if (!_isDirectory) return NULL; - char listDir[256]; - sprintf(listDir, "%s/", _path.c_str()); - int fd = fio.dopen(listDir); + if (_isRoot) { + if (n.lastChar() == ':') + return new Ps2FilesystemNode(n); + else + return NULL; + } + + return new Ps2FilesystemNode(_path+n, 1); + +/* + int fd; + + if (_path == "pfs0:") + fd = fio.dopen("pfs0:/"); + else + fd = fio.dopen(_path.c_str()); if (fd >= 0) { iox_dirent_t dirent; @@ -225,15 +374,18 @@ AbstractFSNode *Ps2FilesystemNode::getChild(const Common::String &n) const { if (strcmp(n.c_str(), dirent.name) == 0) { Ps2FilesystemNode *dirEntry = new Ps2FilesystemNode(); + dirEntry->_isHere = true; dirEntry->_isDirectory = (bool)(dirent.stat.mode & FIO_S_IFDIR); dirEntry->_isRoot = false; dirEntry->_path = _path; - dirEntry->_path += "/"; dirEntry->_path += dirent.name; - + if (dirEntry->_isDirectory && dirEntry->_path.lastChar() != '/') + dirEntry->_path += '/'; dirEntry->_displayName = dirent.name; + dirEntry->_verified = true; + fio.dclose(fd); return dirEntry; } @@ -242,109 +394,120 @@ AbstractFSNode *Ps2FilesystemNode::getChild(const Common::String &n) const { } return NULL; +*/ } bool Ps2FilesystemNode::getChildren(AbstractFSList &list, ListMode mode, bool hidden) const { //TODO: honor the hidden flag + // printf("getChildren\n"); + if (!_isDirectory) return false; if (_isRoot) { - Ps2FilesystemNode dirEntry; - dirEntry._isDirectory = true; - dirEntry._isRoot = false; - dirEntry._path = "cdfs:"; - dirEntry._displayName = getDeviceDescription(dirEntry._path.c_str()); - list.push_back(new Ps2FilesystemNode(&dirEntry)); - - if (g_systemPs2->hddPresent()) { - dirEntry._path = "pfs0:"; - dirEntry._displayName = getDeviceDescription(dirEntry._path.c_str()); - list.push_back(new Ps2FilesystemNode(&dirEntry)); - } + list.push_back(new Ps2FilesystemNode("cdfs:")); + + if (g_systemPs2->hddPresent()) + list.push_back(new Ps2FilesystemNode("pfs0:")); + + if (g_systemPs2->usbMassPresent()) + list.push_back(new Ps2FilesystemNode("mass:")); + + if (g_systemPs2->getBootDevice()==HOST_DEV || g_systemPs2->netPresent()) + list.push_back(new Ps2FilesystemNode("host:")); + + if (g_systemPs2->mcPresent()) + list.push_back(new Ps2FilesystemNode("mc0:")); - if (g_systemPs2->usbMassPresent()) { - dirEntry._path = "mass:"; - dirEntry._displayName = getDeviceDescription(dirEntry._path.c_str()); - list.push_back(new Ps2FilesystemNode(&dirEntry)); - } return true; } else { - char listDir[256]; int fd; - if (_path.lastChar() == '/' /* || _path.lastChar() == ':'*/) + if (_path == "pfs0:") + fd = fio.dopen("pfs0:/"); + else fd = fio.dopen(_path.c_str()); - else { - sprintf(listDir, "%s/", _path.c_str()); - fd = fio.dopen(listDir); - } + + // printf("dopen = %d\n", fd); if (fd >= 0) { iox_dirent_t dirent; Ps2FilesystemNode dirEntry; int dreadRes; while ((dreadRes = fio.dread(fd, &dirent)) > 0) { + if (dirent.name[0] == '.') continue; // ignore '.' and '..' - if (((mode == Common::FSNode::kListDirectoriesOnly) && (dirent.stat.mode & FIO_S_IFDIR)) || - ((mode == Common::FSNode::kListFilesOnly) && !(dirent.stat.mode & FIO_S_IFDIR)) || - (mode == Common::FSNode::kListAll)) { + if ( (mode == Common::FSNode::kListAll) || + + ((mode == Common::FSNode::kListDirectoriesOnly) && + (dirent.stat.mode & FIO_S_IFDIR)) || + + ((mode == Common::FSNode::kListFilesOnly) && + !(dirent.stat.mode & FIO_S_IFDIR)) ) { + + dirEntry._isHere = true; dirEntry._isDirectory = (bool)(dirent.stat.mode & FIO_S_IFDIR); dirEntry._isRoot = false; dirEntry._path = _path; - if (_path.lastChar() != '/') - dirEntry._path += "/"; dirEntry._path += dirent.name; - + if (dirEntry._isDirectory && dirEntry._path.lastChar() != '/') + dirEntry._path += '/'; dirEntry._displayName = dirent.name; + dirEntry._verified = true; + list.push_back(new Ps2FilesystemNode(&dirEntry)); } } fio.dclose(fd); return true; - } else - return false; + } } + return false; } AbstractFSNode *Ps2FilesystemNode::getParent() const { + // printf("Ps2FilesystemNode::getParent : path = %s\n", _path.c_str()); + if (_isRoot) - return new Ps2FilesystemNode(this); + return new Ps2FilesystemNode(this); // FIXME : 0 ??? - const char *slash = NULL; - const char *cnt = _path.c_str(); + if (_path.lastChar() == ':') // devs + return new Ps2FilesystemNode(); // N: default is root - while (*cnt) { - if (*cnt == '/') - slash = cnt; - cnt++; - } + const char *start = _path.c_str(); + const char *end = _lastPathComponent(_path); - if (slash) - return new Ps2FilesystemNode(Common::String(_path.c_str(), slash - _path.c_str())); - else - return new Ps2FilesystemNode(); -} + Common::String str(start, end - start); + // printf(" parent = %s\n", str.c_str()); + return new Ps2FilesystemNode(str, true); +} -char *Ps2FilesystemNode::getDeviceDescription(const char *path) const { - if (strncmp(path, "cdfs", 4) == 0) +char *Ps2FilesystemNode::getDeviceDescription() const { + if (strncmp(_path.c_str(), "cdfs", 4) == 0) return "DVD Drive"; - else if (strncmp(path, "mass", 4) == 0) - return "USB Mass Storage"; - else + else if (strncmp(_path.c_str(), "pfs0", 4) == 0) return "Harddisk"; + else if (strncmp(_path.c_str(), "mass", 4) == 0) + return "USB Mass Storage"; + else if (strncmp(_path.c_str(), "host", 4) == 0) + return "Host"; + else if (strncmp(_path.c_str(), "mc0", 3) == 0) + return "Memory Card"; + else + return "WTF ???"; } -Common::SeekableReadStream *Ps2FilesystemNode::createReadStream() { - return StdioStream::makeFromPath(getPath().c_str(), false); +Common::SeekableReadStream *Ps2FilesystemNode::openForReading() { + Common::SeekableReadStream *ss = StdioStream::makeFromPath(getPath().c_str(), false); + return ss; } -Common::WriteStream *Ps2FilesystemNode::createWriteStream() { +Common::WriteStream *Ps2FilesystemNode::openForWriting() { return StdioStream::makeFromPath(getPath().c_str(), true); } diff --git a/backends/platform/ps2/Gs2dScreen.cpp b/backends/platform/ps2/Gs2dScreen.cpp index 51c10c10f2..050c0d56f9 100644 --- a/backends/platform/ps2/Gs2dScreen.cpp +++ b/backends/platform/ps2/Gs2dScreen.cpp @@ -47,7 +47,7 @@ enum Buffers { #define ANIM_STACK_SIZE (1024 * 32) #define DEFAULT_PAL_X 175 -#define DEFAULT_PAL_Y 60 +#define DEFAULT_PAL_Y 72 // 60 #define DEFAULT_NTSC_X 165 #define DEFAULT_NTSC_Y 45 #define ORG_X 256 @@ -141,18 +141,31 @@ Gs2dScreen::Gs2dScreen(uint16 width, uint16 height, TVMode tvMode) { clearOverlay(); if (tvMode == TV_DONT_CARE) { +#if 1 + char romver[8]; + int fd = fioOpen("rom0:ROMVER", O_RDONLY); + fioRead(fd, &romver, 8); + fioClose(fd); + + if (romver[4] == 'E') + _videoMode = TV_PAL; + else + _videoMode = TV_NTSC; +#else if (PAL_NTSC_FLAG == 'E') _videoMode = TV_PAL; else _videoMode = TV_NTSC; +#endif } else _videoMode = tvMode; + // _videoMode = TV_NTSC; printf("Setting up %s mode\n", (_videoMode == TV_PAL) ? "PAL" : "NTSC"); - - // set screen size, 640x544 for pal, 640x448 for ntsc + + // set screen size, 640x512 for pal, 640x448 for ntsc _tvWidth = 640; - _tvHeight = ((_videoMode == TV_PAL) ? 544 : 448); + _tvHeight = ((_videoMode == TV_PAL) ? 512 /*544*/ : 448); kFullScreen[0].z = kFullScreen[1].z = 0; kFullScreen[0].x = ORIGIN_X; kFullScreen[0].y = ORIGIN_Y; @@ -175,7 +188,7 @@ Gs2dScreen::Gs2dScreen(uint16 width, uint16 height, TVMode tvMode) { _clutPtrs[TEXT] = _clutPtrs[SCREEN] + 0x2000; _texPtrs[SCREEN] = _clutPtrs[SCREEN] + 0x3000; _texPtrs[TEXT] = 0; // these buffers are stored in the alpha gaps of the frame buffers - _texPtrs[MOUSE] = 128 * 256 * 4; + _texPtrs[MOUSE] = 128 * 256 * 4; _texPtrs[PRINTF] = _texPtrs[MOUSE] + M_SIZE * M_SIZE * 4; _showOverlay = false; @@ -224,7 +237,7 @@ Gs2dScreen::Gs2dScreen(uint16 width, uint16 height, TVMode tvMode) { updateScreen(); createAnimTextures(); - + // create anim thread ee_thread_t animThread, thisThread; ReferThreadStatus(GetThreadId(), &thisThread); @@ -535,6 +548,16 @@ void Gs2dScreen::clearPrintfOverlay(void) { void Gs2dScreen::copyOverlayRect(const uint16 *buf, uint16 pitch, uint16 x, uint16 y, uint16 w, uint16 h) { WaitSema(g_DmacSema); + + // warning("_overlayBuf [dst] = %x", _overlayBuf); + // warning("buf [src] = %x", buf); + + // warning("pitch=%d _width=%d - x=%d y=%d w=%d h=%d", + // pitch, _width, x, y, w, h); + + if (x >= 65535) x=0; + if (y >= 65535) y=0; + _overlayChanged = true; uint16 *dest = _overlayBuf + y * _width + x; for (uint32 cnt = 0; cnt < h; cnt++) { @@ -636,7 +659,7 @@ void Gs2dScreen::animThread(void) { do { WaitSema(g_AnimSema); } while ((!_systemQuit) && (!g_RunAnim)); - + if (_systemQuit) break; @@ -761,7 +784,7 @@ const uint32 Gs2dScreen::_binaryClut[16] __attribute__((aligned(64))) = { GS_RGBA( 0, 0, 0, 0x20), // scrPrintf: semitransparent GS_RGBA(0xC0, 0xC0, 0xC0, 0), // scrPrintf: red GS_RGBA(0x16, 0x16, 0xF0, 0), // scrPrintf: blue - + GS_RGBA(0xFF, 0xFF, 0xFF, 0x80), GS_RGBA(0xFF, 0xFF, 0xFF, 0x80), // unused GS_RGBA(0xFF, 0xFF, 0xFF, 0x80), GS_RGBA(0xFF, 0xFF, 0xFF, 0x80), GS_RGBA(0xFF, 0xFF, 0xFF, 0x80), GS_RGBA(0xFF, 0xFF, 0xFF, 0x80), diff --git a/backends/platform/ps2/Makefile.ps2 b/backends/platform/ps2/Makefile.ps2 index 204f4f7a16..812599d0c0 100644 --- a/backends/platform/ps2/Makefile.ps2 +++ b/backends/platform/ps2/Makefile.ps2 @@ -1,9 +1,41 @@ # $Header: Exp $ -include $(PS2SDK)/Defs.make + include $(PS2SDK)/Defs.make +PS2_EXTRA = /media/disk-1/nw8240/extras/scummvm/ports +PS2_EXTRA_INCS = /zlib/include /libmad/ee/include /SjPcm/ee/src /tremor +PS2_EXTRA_LIBS = /zlib/lib /libmad/ee/lib /SjPcm/ee/lib /tremor/tremor + +ENABLED=STATIC_PLUGIN + +#control build DISABLE_SCALERS = true DISABLE_HQ_SCALERS = true -# DISABLE_KYRA = true + +ENABLE_SCUMM = $(ENABLED) +ENABLE_SCUMM_7_8 = $(ENABLED) +ENABLE_HE = $(ENABLED) +ENABLE_AGI = $(ENABLED) +ENABLE_AGOS = $(ENABLED) +ENABLE_CINE = $(ENABLED) +ENABLE_CRUISE = $(ENABLED) +ENABLE_DRASCULA = $(ENABLED) +ENABLE_GOB = $(ENABLED) +ENABLE_IGOR = $(ENABLED) +ENABLE_KYRA = $(ENABLED) +ENABLE_LURE = $(ENABLED) +# ENABLE_M4 = $(ENABLED) +ENABLE_MADE = $(ENABLED) +ENABLE_PARALLACTION = $(ENABLED) +ENABLE_QUEEN = $(ENABLED) +ENABLE_SAGA = $(ENABLED) +ENABLE_SAGA2 = $(ENABLED) +ENABLE_IHNM = $(ENABLED) +ENABLE_SKY = $(ENABLED) +ENABLE_SWORD1 = $(ENABLED) +ENABLE_SWORD2 = $(ENABLED) +# ENABLE_TINSEL = $(ENABLED) +ENABLE_TOUCHE = $(ENABLED) + HAVE_GCC3 = true CC = ee-gcc @@ -19,22 +51,12 @@ RM = rm -f srcdir = ../../.. VPATH = $(srcdir) INCDIR = ../../../ -DEPDIR = .deps - -DEFINES = -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_MPEG2 -DUSE_ZLIB -D_EE -D__PLAYSTATION2__ -O2 -Wall -Wno-multichar +# DEPDIR = .deps -# PS2SDK-Ports from ps2dev.org's SVN repository for libmad, zlib and ucl -PS2SDK_PORTS = /mnt/winxp/scummvm/ports -PS2SDK_PORTS_INCS = /ucl /zlib/include /libmad/ee/include -PS2SDK_PORTS_LIBS = /ucl /zlib/lib /libmad/ee/lib +DEFINES = -DUSE_VORBIS -DUSE_TREMOR -DUSE_MAD -DUSE_ZLIB -D_EE -D__PLAYSTATION2__ -O2 -Wall -Wno-multichar -# we also need SjPcm, Tremor and libmpeg2 -MORE_LIBS_DIR = /mnt/winxp/scummvm/ports -MORE_LIBS_INCS = /SjPcm/ee/src /mpeg2dec/include /tremor -MORE_LIBS_LIBS = /SjPcm/ee/lib /mpeg2dec/libmpeg2 /tremor/tremor -INCLUDES = $(addprefix -I$(PS2SDK_PORTS),$(PS2SDK_PORTS_INCS)) -INCLUDES += $(addprefix -I$(MORE_LIBS_DIR),$(MORE_LIBS_INCS)) +INCLUDES = $(addprefix -I$(PS2_EXTRA),$(PS2_EXTRA_INCS)) INCLUDES += -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -I ./common -I . -I $(srcdir) -I $(srcdir)/engines TARGET = elf/scummvm.elf @@ -44,12 +66,10 @@ OBJS := backends/platform/ps2/DmaPipe.o \ backends/platform/ps2/irxboot.o \ backends/platform/ps2/ps2input.o \ backends/platform/ps2/ps2pad.o \ - backends/platform/ps2/rawsavefile.o \ - backends/platform/ps2/savefile.o \ backends/platform/ps2/savefilemgr.o \ backends/platform/ps2/fileio.o \ - backends/platform/ps2/icon.o \ backends/platform/ps2/asyncfio.o \ + backends/platform/ps2/icon.o \ backends/platform/ps2/cd.o \ backends/platform/ps2/eecodyvdfs.o \ backends/platform/ps2/rpckbd.o \ @@ -64,9 +84,8 @@ include $(srcdir)/Makefile.common LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T $(PS2SDK)/ee/startup/linkfile LDFLAGS += -L $(PS2SDK)/ee/lib -L . -LDFLAGS += $(addprefix -L$(MORE_LIBS_DIR),$(MORE_LIBS_LIBS)) -LDFLAGS += $(addprefix -L$(PS2SDK_PORTS),$(PS2SDK_PORTS_LIBS)) -LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmpeg2 -lmad -ltremor -lz -lucl -lm -lc -lfileXio -lkernel -lstdc++ +LDFLAGS += $(addprefix -L$(PS2_EXTRA),$(PS2_EXTRA_LIBS)) +LDFLAGS += -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lmad -ltremor -lz -lm -lc -lfileXio -lkernel -lstdc++ # LDFLAGS += -s all: $(TARGET) diff --git a/backends/platform/ps2/asyncfio.cpp b/backends/platform/ps2/asyncfio.cpp index 5c5230465d..f16efffbd9 100644 --- a/backends/platform/ps2/asyncfio.cpp +++ b/backends/platform/ps2/asyncfio.cpp @@ -58,6 +58,17 @@ int AsyncFio::open(const char *name, int ioMode) { return res; } +int AsyncFio::open(const char *name, int ioMode, int mode) { + WaitSema(_ioSema); + checkSync(); + int res; + fileXioOpen(name, ioMode, mode); + fileXioWaitAsync(FXIO_WAIT, &res); + SignalSema(_ioSema); + // dbg_printf("FIO: open ext(%s, %d, %d) => %d", name, ioMode, mode, res); + return res; +} + void AsyncFio::close(int handle) { WaitSema(_ioSema); checkSync(); @@ -95,6 +106,15 @@ void AsyncFio::write(int fd, const void *src, unsigned int len) { SignalSema(_ioSema); } +void AsyncFio::remove(const char *path) { + int res; + WaitSema(_ioSema); + checkSync(); + fileXioRemove(path); + fileXioWaitAsync(FXIO_WAIT, &res); + SignalSema(_ioSema); +} + int AsyncFio::seek(int fd, int offset, int whence) { int res; WaitSema(_ioSema); @@ -149,6 +169,16 @@ void AsyncFio::dclose(int fd) { SignalSema(_ioSema); } +int AsyncFio::chdir(const char *name) { + int res; + WaitSema(_ioSema); + checkSync(); + fileXioChdir(name); + fileXioWaitAsync(FXIO_WAIT, &res); + SignalSema(_ioSema); + return res; +} + int AsyncFio::mount(const char *mountpoint, const char *mountstring, int flag) { int res; WaitSema(_ioSema); diff --git a/backends/platform/ps2/asyncfio.h b/backends/platform/ps2/asyncfio.h index 4ce2aa15d1..b42141523b 100644 --- a/backends/platform/ps2/asyncfio.h +++ b/backends/platform/ps2/asyncfio.h @@ -31,14 +31,17 @@ public: AsyncFio(void); ~AsyncFio(void); int open(const char *name, int ioMode); + int open(const char *name, int ioMode, int mode); void close(int handle); void read(int fd, void *dest, unsigned int len); void write(int fd, const void *src, unsigned int len); + void remove(const char *name); int seek(int fd, int offset, int whence); int mkdir(const char *name); int dopen(const char *name); int dread(int fd, iox_dirent_t *dest); void dclose(int fd); + int chdir(const char *name); int mount(const char *mountpoint, const char *mountstring, int flag); int umount(const char *mountpoint); int sync(int fd); diff --git a/backends/platform/ps2/fileio.cpp b/backends/platform/ps2/fileio.cpp index 039e309eb9..d2186b6475 100644 --- a/backends/platform/ps2/fileio.cpp +++ b/backends/platform/ps2/fileio.cpp @@ -36,54 +36,31 @@ #include "eecodyvdfs.h" #include "common/config-manager.h" #include "backends/platform/ps2/ps2debug.h" -#include "backends/platform/ps2/savefile.h" #include "backends/platform/ps2/systemps2.h" -#define CACHE_SIZE (2048 * 32) -#define MAX_READ_STEP (2048 * 16) -#define MAX_CACHED_FILES 6 -#define CACHE_READ_THRESHOLD (16 * 2048) -#define CACHE_FILL_MIN (2048 * 24) -#define READ_ALIGN 64 // align all reads to the size of an EE cache line -#define READ_ALIGN_MASK (READ_ALIGN - 1) +#define __PS2_FILE_SEMA__ 1 +// #define __PS2_FILE_DEBUG 1 +// #define __PS2_CACHE_DEBUG__ 1 + +#define PS2_CACHE_MAX (128 * 1024) +#define PS2_CACHE_CHK (16 * 1024) extern OSystem_PS2 *g_systemPs2; +uint32 _rseek; + AsyncFio fio; -Ps2File::Ps2File(int64 cacheId) { - _cacheId = cacheId; -} +Ps2File::Ps2File(void) { + _fd = -1; + _fileSize = 0; + _filePos = 0; + _cacheSize = 0; + _cachePos = 0; + _eof = false; -Ps2File::~Ps2File(void) { -} + // _cache = (uint8 *)malloc(PS2_CACHE_MAX); -class Ps2ReadFile : public Ps2File { -public: - Ps2ReadFile(int64 cacheId, bool stream); - virtual ~Ps2ReadFile(void); - virtual bool open(const char *name); - virtual uint32 read(void *dest, uint32 len); - virtual uint32 write(const void *src, uint32 len); - virtual uint32 tell(void); - virtual uint32 size(void); - virtual int seek(int32 offset, int origin); - virtual bool eof(void); -private: - void cacheReadAhead(void); - void cacheReadSync(void); - int _fd, _sema; - uint8 *_cacheBuf; - bool _cacheOpRunning; - uint32 _filePos, _physFilePos, _cachePos; - uint32 _fileSize, _bytesInCache, _cacheOfs; - - uint32 _readBytesBlock; - bool _stream; -}; - -Ps2ReadFile::Ps2ReadFile(int64 cacheId, bool stream) : Ps2File(cacheId) { - _fd = -1; _cacheBuf = (uint8*)memalign(64, CACHE_SIZE); _cacheOpRunning = 0; @@ -91,58 +68,102 @@ Ps2ReadFile::Ps2ReadFile(int64 cacheId, bool stream) : Ps2File(cacheId) { _fileSize = _bytesInCache = _cacheOfs = 0; _cacheOpRunning = false; _readBytesBlock = 0; - _stream = stream; + _stream = true; +#ifdef __PS2_FILE_SEMA__ ee_sema_t newSema; newSema.init_count = 1; newSema.max_count = 1; _sema = CreateSema(&newSema); assert(_sema >= 0); +#endif } -Ps2ReadFile::~Ps2ReadFile(void) { - if (_cacheOpRunning) - cacheReadSync(); - free(_cacheBuf); - if (_fd >= 0) +Ps2File::~Ps2File(void) { + if (_fd >= 0) { fio.close(_fd); + uint32 r = fio.sync(_fd); + printf("close [%d] - sync'd = %d\n", _fd, r); + } + + // free(_cache); + free(_cacheBuf); + +#ifdef __PS2_FILE_SEMA__ DeleteSema(_sema); +#endif } -bool Ps2ReadFile::open(const char *name) { +bool Ps2File::open(const char *name, int mode) { assert(_fd < 0); - _fd = fio.open(name, O_RDONLY); + + _fd = fio.open(name, mode); + + printf("open %s [%d]\n", name, _fd); + if (_fd >= 0) { _fileSize = fio.seek(_fd, 0, SEEK_END); - fio.seek(_fd, 0, SEEK_SET); + if (mode == O_RDONLY) + // if (!(mode & O_APPEND)) + fio.seek(_fd, 0, SEEK_SET); + + printf(" _fileSize = %d\n", _fileSize); + printf(" _filePos = %d\n", _filePos); + return true; } else return false; } -uint32 Ps2ReadFile::tell(void) { +int32 Ps2File::tell(void) { +#ifdef __PS2_FILE_SEMA__ WaitSema(_sema); - uint32 res = _filePos; +#endif + int32 res = _filePos; +#ifdef __PS2_FILE_SEMA__ SignalSema(_sema); +#endif return res; } -uint32 Ps2ReadFile::size(void) { +int32 Ps2File::size(void) { +#ifdef __PS2_FILE_SEMA__ WaitSema(_sema); - uint32 res = _fileSize; +#endif + int32 res = _fileSize; +#ifdef __PS2_FILE_SEMA__ SignalSema(_sema); +#endif return res; } -bool Ps2ReadFile::eof(void) { +bool Ps2File::eof(void) { +#ifdef __PS2_FILE_SEMA__ WaitSema(_sema); - bool res = (_filePos == _fileSize); +#endif + bool res = _eof; // (_filePos == _fileSize); + // bool res = (_filePos >= _fileSize); +#ifdef __PS2_FILE_SEMA__ SignalSema(_sema); + + // printf(" EOF [%d] : %d of %d -> %d\n", _fd, _filePos, _fileSize, res); +#endif return res; } -int Ps2ReadFile::seek(int32 offset, int origin) { +bool Ps2File::getErr(void) { + return _eof; +} + +void Ps2File::setErr(bool err) { + _eof = err; +} + +int Ps2File::seek(int32 offset, int origin) { +#ifdef __PS2_FILE_SEMA__ WaitSema(_sema); +#endif + _rseek = 0; int seekDest; int res = -1; switch (origin) { @@ -160,14 +181,27 @@ int Ps2ReadFile::seek(int32 offset, int origin) { break; } if ((seekDest >= 0) && (seekDest <= (int)_fileSize)) { + // _rseek = fio.sync(_fd); _filePos = seekDest; + // fio.seek(_fd, _filePos, SEEK_SET); + // fio.sync(_fd); + // _cacheSize = 0; + _eof = false; res = 0; } + else _eof = true; + + // printf("seek [%d] %d %d\n", _fd, offset, origin); + // printf(" res = %d\n", res); + +#ifdef __PS2_FILE_SEMA__ SignalSema(_sema); +#endif + return res; } -void Ps2ReadFile::cacheReadAhead(void) { +void Ps2File::cacheReadAhead(void) { if (_cacheOpRunning) { // there's already some cache read running if (fio.poll(_fd)) // did it finish? @@ -191,7 +225,7 @@ void Ps2ReadFile::cacheReadAhead(void) { _cachePos = cachePosEnd = _filePos & ~READ_ALIGN_MASK; assert(_filePos == _physFilePos); } else { - uint32 cacheDiff = _filePos - _cachePos; + uint32 cacheDiff = _filePos - _cachePos; assert(_bytesInCache >= cacheDiff); cacheDiff &= ~READ_ALIGN_MASK; _bytesInCache -= cacheDiff; @@ -201,7 +235,7 @@ void Ps2ReadFile::cacheReadAhead(void) { if (_physFilePos != cachePosEnd) { sioprintf("unexpected _physFilePos %d cache %d %d\n", _physFilePos, _cacheOfs, _bytesInCache); - assert(!(cachePosEnd & READ_ALIGN_MASK)); + // assert(!(cachePosEnd & READ_ALIGN_MASK)); // romeo _physFilePos = fio.seek(_fd, cachePosEnd, SEEK_SET); if (_physFilePos != cachePosEnd) { sioprintf("cache seek error: seek to %d instead of %d, fs = %d\n", _physFilePos, cachePosEnd, _fileSize); @@ -223,7 +257,7 @@ void Ps2ReadFile::cacheReadAhead(void) { } } -void Ps2ReadFile::cacheReadSync(void) { +void Ps2File::cacheReadSync(void) { if (_cacheOpRunning) { int res = fio.sync(_fd); assert(res >= 0); @@ -233,8 +267,30 @@ void Ps2ReadFile::cacheReadSync(void) { } } -uint32 Ps2ReadFile::read(void *dest, uint32 len) { +uint32 Ps2File::read(void *dest, uint32 len) { + // uint32 r=0, d=0, ds=0, sz=0; +#ifdef __PS2_FILE_SEMA__ WaitSema(_sema); +#endif + +#ifdef __PS2_FILE_DEBUG__ + printf("read (1) : _filePos = %d\n", _filePos); + printf("read (1) : _cachePos = %d\n", _cachePos); +#endif + + if (_filePos >= _fileSize) { + _eof = true; +#ifdef __PS2_FILE_SEMA__ + SignalSema(_sema); +#endif + return 0; + } + + if ((_filePos+len) > _fileSize) { + len = _fileSize-_filePos; + _eof = true; + } + uint8 *destBuf = (uint8*)dest; if ((_filePos < _cachePos) || (_filePos + len > _cachePos + _bytesInCache)) cacheReadSync(); // we have to read from CD, sync cache. @@ -287,195 +343,60 @@ uint32 Ps2ReadFile::read(void *dest, uint32 len) { return destBuf - (uint8*)dest; } -uint32 Ps2ReadFile::write(const void *src, uint32 len) { - sioprintf("write request on Ps2ReadFile!\n"); - SleepThread(); - return 0; -} +uint32 Ps2File::write(const void *src, uint32 len) { + uint32 w; +#ifdef __PS2_FILE_SEMA__ + WaitSema(_sema); +#endif + _cacheSize = 0; -struct TocNode { - char name[64]; - TocNode *next, *sub; - bool isDir; - uint8 nameLen; -}; - -class TocManager { -public: - TocManager(void); - ~TocManager(void); - void readEntries(const char *root); - int64 fileExists(const char *name); - bool haveEntries(void); -private: - void readDir(const char *path, TocNode **node, int level); - TocNode *_rootNode; - char _root[256]; - uint8 _rootLen; -}; - -static TocManager tocManager; - -struct FioHandleCache { - Ps2File *file; - FioHandleCache *next, *prev; -}; - -static FioHandleCache *cacheListStart = NULL; -static FioHandleCache *cacheListEnd = NULL; -static int cacheListLen = 0; -static int openFileCount = 0; -static int cacheListSema = -1; - -static bool checkedPath = false; - -Ps2File *findInCache(int64 id); + w = fio.sync(_fd); + assert(w==0); -FILE *ps2_fopen(const char *fname, const char *mode) { - if (cacheListSema == -1) { - ee_sema_t newSema; - newSema.init_count = 1; - newSema.max_count = 1; - cacheListSema = CreateSema(&newSema); - assert(cacheListSema >= 0); - } + fio.seek(_fd, _filePos, SEEK_SET); + fio.write(_fd, src, len); - if (((mode[0] != 'r') && (mode[0] != 'w')) || ((mode[1] != '\0') && (mode[1] != 'b'))) { - printf("unsupported mode \"%s\" for file \"%s\"\n", mode, fname); - return NULL; + w = fio.sync(_fd); + +#ifdef __PS2_FILE_SEMA__ + SignalSema(_sema); +#endif + + if (w) { + _filePos += w; + if (w < len) + _eof = true; + return w; } - bool rdOnly = (mode[0] == 'r'); - - if (strnicmp(fname, "mc0:", 4) == 0) { - // File access to the memory card (for scummvm.ini) has to go through the savefilemanager - Ps2File *file; - if (rdOnly) - file = new Ps2McReadFile((Ps2SaveFileManager *)g_systemPs2->getSavefileManager()); - else - file = new Ps2McWriteFile((Ps2SaveFileManager *)g_systemPs2->getSavefileManager()); - if (file->open(fname + 4)) // + 4 to skip "mc0:" - return (FILE *)file; - - delete file; - return NULL; - } else { - // Regular access to one of the devices - - printf("ps2_fopen = %s\n", fname); // romeo : temp - - if (!rdOnly) - return NULL; // we only provide readaccess for cd,dvd,hdd,usb - - if (!checkedPath && g_engine) { - // are we playing from cd/dvd? - const char *gameDataPath = ConfMan.get("path").c_str(); - printf("Read TOC dir: %s\n", gameDataPath); - if (strncmp(gameDataPath, "cdfs:", 5) != 0) - driveStop(); // no, we aren't. stop the drive. it's noisy. - // now cache the dir tree - tocManager.readEntries(gameDataPath); - checkedPath = true; - } - int64 cacheId = -1; - if (tocManager.haveEntries()) - cacheId = tocManager.fileExists(fname); + return 0; +} - if (cacheId != 0) { - Ps2File *file = findInCache(cacheId); - if (file) { - printf(" findInCache(%x)\n", cacheId); // romeo : temp - return (FILE*)file; - } +FILE *ps2_fopen(const char *fname, const char *mode) { + Ps2File *file = new Ps2File(); + int _mode = O_RDONLY; - bool isAudioFile = strstr(fname, ".bun") || strstr(fname, ".BUN") || strstr(fname, ".Bun"); - file = new Ps2ReadFile(cacheId, isAudioFile); + printf("fopen(%s, %s)\n", fname, mode); - if (file->open(fname)) { - openFileCount++; - printf(" new cacheID = %x\n", cacheId); // romeo : temp - return (FILE*)file; - } else - delete file; - } - return NULL; - } -} + if (mode[0] == 'r' && mode [1] == 'w') + _mode = O_RDWR; + else if (mode[0] == 'w') + _mode = O_WRONLY | O_CREAT; + else if (mode[0] == 'a') + _mode = O_RDWR | O_CREAT | O_APPEND; -void checkCacheListLen(void) { - while ((cacheListLen > MAX_CACHED_FILES) || ((openFileCount > 13) && cacheListLen)) { - assert(cacheListEnd && cacheListStart); - delete cacheListEnd->file; - if (cacheListEnd->prev) { - cacheListEnd->prev->next = NULL; - FioHandleCache *temp = cacheListEnd; - cacheListEnd = cacheListEnd->prev; - delete temp; - } else { - assert(cacheListEnd == cacheListStart); - assert(cacheListLen == 1); - delete cacheListEnd; - cacheListEnd = cacheListStart = NULL; - } - cacheListLen--; - openFileCount--; - } + if (file->open(fname, _mode)) + return (FILE *)file; + else + return NULL; } int ps2_fclose(FILE *stream) { Ps2File *file = (Ps2File*)stream; - if (file->_cacheId > 0) { // this is a file on the CD, could be smart to cache it - FioHandleCache *newHandle = new FioHandleCache; - newHandle->file = file; - file->seek(0, SEEK_SET); - - WaitSema(cacheListSema); - if (!cacheListEnd) { - assert(!cacheListStart); - newHandle->prev = newHandle->next = NULL; - cacheListEnd = cacheListStart = newHandle; - } else { - assert(cacheListStart); - newHandle->prev = NULL; - newHandle->next = cacheListStart; - cacheListStart->prev = newHandle; - cacheListStart = newHandle; - } - cacheListLen++; - checkCacheListLen(); - SignalSema(cacheListSema); - } else { - openFileCount--; - delete file; - } - return 0; -} -Ps2File *findInCache(int64 id) { - if (id <= 0) - return NULL; - WaitSema(cacheListSema); - FioHandleCache *node = cacheListStart; - while (node) { - if (node->file->_cacheId == id) { - if (node == cacheListStart) - cacheListStart = node->next; - if (node == cacheListEnd) - cacheListEnd = node->prev; - if (node->prev) - node->prev->next = node->next; - if (node->next) - node->next->prev = node->prev; - Ps2File *ret = node->file; - delete node; - cacheListLen--; - SignalSema(cacheListSema); - return ret; - } else - node = node->next; - } - SignalSema(cacheListSema); - return NULL; + delete file; + + return 0; } int ps2_fseek(FILE *stream, long offset, int origin) { @@ -503,40 +424,6 @@ int ps2_fgetc(FILE *stream) { return EOF; } -char *ps2_fgets(char *buf, int n, FILE *stream) { - char *retVal = buf; - while (n--) { - if (n == 0) - *buf = '\0'; - else { - char c = ps2_fgetc(stream); - if (c == EOF) - return NULL; - if ((c == '\r') || (c == '\n')) { - *buf++ = '\0'; - return retVal; - } - *buf++ = c; - } - } - return retVal; -} - -int ps2_fprintf(FILE *pOut, const char *zFormat, ...) { - va_list ap; - char resStr[2048]; - - va_start(ap,zFormat); - int res = vsnprintf(resStr, 2048, zFormat, ap); - va_end(ap); - if ((pOut == stderr) || (pOut == stdout)) { - printf("%s", resStr); - sioprintf("%s", resStr); - } else - res = ps2_fwrite(resStr, 1, res, pOut); - return res; -} - size_t ps2_fwrite(const void *buf, size_t r, size_t n, FILE *stream) { assert(r != 0); return ((Ps2File*)stream)->write(buf, r * n) / r; @@ -557,137 +444,36 @@ int ps2_fputs(const char *s, FILE *stream) { return EOF; } -int ps2_fflush(FILE *stream) { - printf("fflush not implemented\n"); - return 0; -} - -TocManager::TocManager(void) { - _rootNode = NULL; -} +int ps2_fprintf(FILE *pOut, const char *zFormat, ...) { + va_list ap; + char resStr[2048]; -TocManager::~TocManager(void) { -} + va_start(ap,zFormat); + int res = vsnprintf(resStr, 2048, zFormat, ap); + va_end(ap); + if ((pOut == stderr) || (pOut == stdout)) { + printf("%s", resStr); + sioprintf("%s", resStr); + } else + res = ps2_fwrite(resStr, 1, res, pOut); -bool TocManager::haveEntries(void) { - return _rootNode != NULL; + return res; } -void TocManager::readEntries(const char *root) { - _rootLen = strlen(root); - strcpy(_root, root); - while (_root[_rootLen - 1] == '/') { - _rootLen--; - _root[_rootLen] = '\0'; - } - char readPath[256]; - sprintf(readPath, "%s/", _root); - printf("readDir: %s (root: %s )\n", readPath, root); - readDir(readPath, &_rootNode, 0); +int ps2_fflush(FILE *stream) { + // printf("fflush not implemented\n"); + return 0; } -void TocManager::readDir(const char *path, TocNode **node, int level) { - if (level <= 2) { // we don't scan deeper than that - iox_dirent_t dirent; - int fd = fio.dopen(path); - TocNode *eNode = NULL; // = *node; // entry node - bool first = true; - - printf("path=%s - level=%d fd=%d\n", path, level, fd); // romeo : temp - if (fd >= 0) { - while (fio.dread(fd, &dirent) > 0) { - if (dirent.name[0] != '.') { // skip '.' & '..' - romeo : check - // --- do we have them on PS2? - *node = new TocNode; - if (first) { - eNode = *node; - first = false; - } - (*node)->sub = (*node)->next = NULL; - (*node)->nameLen = strlen(dirent.name); - memcpy((*node)->name, dirent.name, (*node)->nameLen + 1); - - if (dirent.stat.mode & FIO_S_IFDIR) { - (*node)->isDir = true; - printf("dirent.name = %s [DIR]\n", dirent.name); - } - else { - (*node)->isDir = false; - printf("dirent.name = %s\n", dirent.name); - } - - node = &((*node)->next); - } - } - - fio.dclose(fd); - } +int ps2_ferror(FILE *stream) { + int err = ((Ps2File*)stream)->getErr(); - TocNode *iNode = eNode; - char nextPath[256]; + if (err) + printf("ferror -> %d\n", err); - while (iNode) { - if (iNode->isDir == true) { - sprintf(nextPath, "%s%s/", path, iNode->name); - readDir(nextPath, &(iNode->sub), level + 1); - } - iNode = iNode->next; - } - - } - - /* - ** Wizard of Oz' trick (to get all games running from USB on PS2): - - 1. Make a list of files / dirs in level #0 (dclose before continuing) - - 2. Go through the dirs : dopen / dread them / mark dirs / dclose - - It's a safe recursion, cause it recurses on 'isDir' nodes - after dclosing the higher hierarchy - */ + return err; } -int64 TocManager::fileExists(const char *name) { - if (((name[_rootLen] != '/') && (name[_rootLen] != '\0')) || (strnicmp(name, _root, _rootLen) != 0)) { - for (int i = 0; i < 8; i++) - if (name[i] == ':') // we don't know the content of other drives, - return -1; // assume file exists - else if ((name[i] == '/') || (name[i] == '\\')) - return 0; // does not exists (this is probably ScummVM trying the 'current directory'.) - return 0; - } - - uint8 nameLen = strlen(name); - - name += _rootLen + 1; - nameLen -= _rootLen + 1; - - TocNode *node = _rootNode; - int64 retId = 1; - while (node) { - if (((name[node->nameLen] == '/') || (name[node->nameLen] == '\0')) && (strnicmp(name, node->name, node->nameLen) == 0)) { - name += node->nameLen; - nameLen -= node->nameLen; - if (node->isDir) { - if (nameLen) { - name++; // skip '/' - nameLen--; - node = node->sub; - retId <<= 10; - } else - return 0; // can't open a directory with fopen() - } else { - if (nameLen == 0) - return retId; // ok, found - else - return 0; // here's a file, but there's something left in the path - } - } else { - node = node->next; - retId++; - } - } - return 0; // does not exist +void ps2_clearerr(FILE *stream) { + ((Ps2File*)stream)->setErr(false); } - diff --git a/backends/platform/ps2/fileio.h b/backends/platform/ps2/fileio.h index d09d7313a6..6c2b9402a3 100644 --- a/backends/platform/ps2/fileio.h +++ b/backends/platform/ps2/fileio.h @@ -32,21 +32,56 @@ typedef signed long int64; #include #include "common/scummsys.h" + +#define CACHE_SIZE (2048 * 32) +#define MAX_READ_STEP (2048 * 16) +#define MAX_CACHED_FILES 6 +#define CACHE_READ_THRESHOLD (16 * 2048) +#define CACHE_FILL_MIN (2048 * 24) +#define READ_ALIGN 64 // align all reads to the size of an EE cache line +#define READ_ALIGN_MASK (READ_ALIGN - 1) + + class Ps2File { public: - Ps2File(int64 cacheId); + Ps2File(void); virtual ~Ps2File(void); - virtual bool open(const char *name) = 0; - virtual uint32 read(void *dest, uint32 len) = 0; - virtual uint32 write(const void *src, uint32 len) = 0; - virtual uint32 tell(void) = 0; - virtual uint32 size(void) = 0; - virtual int seek(int32 offset, int origin) = 0; - virtual bool eof(void) = 0; - int64 _cacheId; + virtual bool open(const char *name, int mode); + virtual uint32 read(void *dest, uint32 len); + virtual uint32 write(const void *src, uint32 len); + virtual int32 tell(void); + virtual int32 size(void); + virtual int seek(int32 offset, int origin); + virtual bool eof(void); + virtual bool getErr(void); + virtual void setErr(bool); + + private: -}; + void cacheReadAhead(void); + void cacheReadSync(void); + + int _fd; + uint32 _fileSize; + uint32 _filePos; + uint32 _cacheSize; + uint32 _cachePos; + // uint8 cache[2048]; + uint8 *_cache; + + int _eof; + int _sema; + + + uint8 *_cacheBuf; + bool _cacheOpRunning; + uint32 _physFilePos; + uint32 _bytesInCache, _cacheOfs; + + uint32 _readBytesBlock; + bool _stream; +}; FILE *ps2_fopen(const char *fname, const char *mode); int ps2_fclose(FILE *stream); @@ -64,5 +99,8 @@ int ps2_fputc(int c, FILE *stream); int ps2_fputs(const char *s, FILE *stream); int ps2_fprintf(FILE *pOut, const char *zFormat, ...); +int ps2_ferror(FILE *stream); +void ps2_clearerr(FILE *stream); + #endif // __PS2FILE_IO__ diff --git a/backends/platform/ps2/icon.cpp b/backends/platform/ps2/icon.cpp index bc30c5290d..9b88d0bb68 100644 --- a/backends/platform/ps2/icon.cpp +++ b/backends/platform/ps2/icon.cpp @@ -23,36 +23,40 @@ * */ -#include "backends/platform/ps2/savefilemgr.h" -#include "backends/platform/ps2/Gs2dScreen.h" -#include "backends/platform/ps2/GsDefs.h" +#include "Gs2dScreen.h" +#include "GsDefs.h" -const iconIVECTOR Ps2SaveFileManager::_bgcolor[4] = { +#include +#include "icon.h" + +const char _info[] = "ScummVM\nFolder"; + +const iconIVECTOR _bgcolor[4] = { { 68, 23, 116, 0 }, // top left { 255, 255, 255, 0 }, // top right { 255, 255, 255, 0 }, // bottom left { 68, 23, 116, 0 }, // bottom right }; -const iconFVECTOR Ps2SaveFileManager::_lightdir[3] = { +const iconFVECTOR _lightdir[3] = { { 0.5, 0.5, 0.5, 0.0 }, { 0.0,-0.4,-0.1, 0.0 }, {-0.5,-0.5, 0.5, 0.0 }, }; -const iconFVECTOR Ps2SaveFileManager::_lightcol[3] = { +const iconFVECTOR _lightcol[3] = { { 0.3, 0.3, 0.3, 0.00 }, { 0.4, 0.4, 0.4, 0.00 }, { 0.5, 0.5, 0.5, 0.00 }, }; -const iconFVECTOR Ps2SaveFileManager::_ambient = { 0.50, 0.50, 0.50, 0.00 }; +const iconFVECTOR _ambient = { 0.50, 0.50, 0.50, 0.00 }; -// Source File: stdico2.rle +// Source File: stdico2.rle // Orig. Offset: 0 / 0x00000000 -// Length: 14018 / 0x000036C2 (bytes) +// Length: 14018 / 0x000036C2 (bytes) -const uint8 Ps2SaveFileManager::_rleIcoData[14018] = { +const uint8 _rleIcoData[14018] = { 0xCC, 0x41, 0x00, 0x00, 0xCC, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x24, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x00, 0xF7, 0x00, 0xFE, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0E, 0x7F, 0x7F, @@ -932,4 +936,40 @@ const uint8 Ps2SaveFileManager::_rleIcoData[14018] = { 0x00, 0x00 }; +uint16 PS2Icon::decompressData(uint16 **data) { + uint16 inPos = 1; + uint16 *rleData = (uint16*)_rleIcoData; + uint16 resSize = rleData[0]; + uint16 *resData = (uint16*)malloc(resSize * sizeof(uint16)); + uint16 outPos = 0; + + while (outPos < resSize) { + uint16 len = rleData[inPos++]; + while (len--) + resData[outPos++] = 0x7FFF; + len = rleData[inPos++]; + while (len--) + resData[outPos++] = rleData[inPos++]; + } + assert(outPos == resSize); + + *data = resData; + return resSize; +} +void PS2Icon::setup(mcIcon *icon) { + char title[256]; + memset(icon, 0, sizeof(mcIcon)); + memcpy(icon->head, "PS2D", 4); + icon->nlOffset = strlen(_info) + 1; + strcpy(title, _info); + strcpy_sjis((short*)&(icon->title), title); + icon->trans = 0x10; + memcpy(icon->bgCol, _bgcolor, sizeof(_bgcolor)); + memcpy(icon->lightDir, _lightdir, sizeof(_lightdir)); + memcpy(icon->lightCol, _lightcol, sizeof(_lightcol)); + memcpy(icon->lightAmbient, _ambient, sizeof(_ambient)); + strcpy((char*)icon->view, "scummvm.icn"); + strcpy((char*)icon->copy, "scummvm.icn"); + strcpy((char*)icon->del, "scummvm.icn"); +} diff --git a/backends/platform/ps2/icon.h b/backends/platform/ps2/icon.h new file mode 100644 index 0000000000..0e7d096c45 --- /dev/null +++ b/backends/platform/ps2/icon.h @@ -0,0 +1,31 @@ +/* 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. + * + */ + +class PS2Icon { +public: + PS2Icon() {}; + + ~PS2Icon() {}; + + uint16 decompressData(uint16 **data); + void setup(mcIcon *icon); +}; diff --git a/backends/platform/ps2/irxboot.cpp b/backends/platform/ps2/irxboot.cpp index 91c45294c6..fa3e047bf6 100644 --- a/backends/platform/ps2/irxboot.cpp +++ b/backends/platform/ps2/irxboot.cpp @@ -33,54 +33,53 @@ #include "backends/platform/ps2/irxboot.h" #include "backends/platform/ps2/ps2debug.h" +#include "ps2temp.h" + static const char hddArg[] = "-o" "\0" "8" "\0" "-n" "\0" "20"; static const char pfsArg[] = "-m" "\0" "2" "\0" "-o" "\0" "32" "\0" "-n" "\0" "72"; // "\0" "-debug"; +static const char netArg[] = "192.168.0.10" "\0" "255.255.255.0" "\0" "192.168.0.1"; IrxFile irxFiles[] = { { "SIO2MAN", BIOS, NOTHING, NULL, 0 }, - { "MCMAN", BIOS, NOTHING, NULL, 0 }, + { "MCMAN", BIOS, NOTHING, NULL, 0 }, { "MCSERV", BIOS, NOTHING, NULL, 0 }, { "PADMAN", BIOS, NOTHING, NULL, 0 }, { "LIBSD", BIOS, NOTHING, NULL, 0 }, - { "IOMANX.IRX", SYSTEM /*| NOT_HOST*/, NOTHING, NULL, 0 }, // already loaded by ps2link + { "IOMANX.IRX", SYSTEM, NOTHING, NULL, 0 }, { "FILEXIO.IRX", SYSTEM, NOTHING, NULL, 0 }, { "CODYVDFS.IRX", SYSTEM, NOTHING, NULL, 0 }, { "SJPCM.IRX", SYSTEM, NOTHING, NULL, 0 }, { "USBD.IRX", USB | OPTIONAL | DEPENDANCY, USB_DRIVER, NULL, 0 }, + { "USB_MASS.IRX", USB | OPTIONAL, MASS_DRIVER, NULL, 0 }, { "PS2MOUSE.IRX", USB | OPTIONAL, MOUSE_DRIVER, NULL, 0 }, { "RPCKBD.IRX", USB | OPTIONAL, KBD_DRIVER, NULL, 0 }, - { "USBHDFSD.IRX", USB | OPTIONAL, MASS_DRIVER, NULL, 0 }, - { "PS2DEV9.IRX", HDD | OPTIONAL | DEPENDANCY, HDD_DRIVER, NULL, 0 }, + { "POWEROFF.IRX", HDD | OPTIONAL | NOT_HOST | DEPENDANCY, HDD_DRIVER, NULL, 0 }, + { "PS2DEV9.IRX", HDD | OPTIONAL | NOT_HOST | DEPENDANCY, HDD_DRIVER, NULL, 0 }, { "PS2ATAD.IRX", HDD | OPTIONAL | DEPENDANCY, HDD_DRIVER, NULL, 0 }, { "PS2HDD.IRX", HDD | OPTIONAL | DEPENDANCY, HDD_DRIVER, hddArg, sizeof(hddArg) }, { "PS2FS.IRX", HDD | OPTIONAL | DEPENDANCY, HDD_DRIVER, pfsArg, sizeof(pfsArg) }, - { "POWEROFF.IRX", HDD | OPTIONAL | DEPENDANCY, HDD_DRIVER, NULL, 0 } + { "PS2IP.IRX", NET | NOT_HOST, NET_DRIVER, NULL, 0 }, + { "PS2SMAP.IRX", NET | NOT_HOST, NET_DRIVER, netArg, sizeof(netArg) }, + { "PS2HOST.IRX", NET | NOT_HOST, NET_DRIVER, NULL, 0 } }; static const int numIrxFiles = sizeof(irxFiles) / sizeof(irxFiles[0]); -BootDevice detectBootPath(const char *elfPath, char *bootPath) { - - BootDevice device; - - if (strncasecmp(elfPath, "cdrom0:", 7) == 0) - device = CDROM; - else if (strncasecmp(elfPath, "host", 4) == 0) - device = HOST; - else - device = OTHER; +PS2Device detectBootPath(const char *elfPath, char *bootPath) { - sioprintf("elf path: %s, device %d\n", elfPath, device); + PS2Device device = _getDev(elfPath); + printf("elf path: %s, device %d\n", elfPath, device); + strcpy(bootPath, elfPath); char *pathPos = bootPath; char seperator; - if (device == CDROM) { + if (device == CD_DEV) { // CDVD uses '\' as seperator while (*pathPos) { if (*pathPos == '/') @@ -102,7 +101,7 @@ BootDevice detectBootPath(const char *elfPath, char *bootPath) { pathPos = strchr(bootPath, ':'); if (pathPos) { - if ((pathPos[0] == ':') && (device == CDROM)) { + if ((pathPos[0] == ':') && (device == CD_DEV)) { pathPos[1] = '\\'; pathPos[2] = '\0'; } else @@ -111,19 +110,19 @@ BootDevice detectBootPath(const char *elfPath, char *bootPath) { } else { sioprintf("path not recognized, default to host.\n"); strcpy(bootPath, "host:"); - device = UNKNOWN; + device = HOST_DEV; // UNKNOWN; } return device; } -int loadIrxModules(int device, const char *irxPath, IrxReference **modules) { +int loadIrxModules(int device, const char *irxPath, IrxReference **modules) { IrxReference *resModules = (IrxReference *)malloc(numIrxFiles * sizeof(IrxReference)); IrxReference *curModule = resModules; for (int i = 0; i < numIrxFiles; i++) { curModule->fileRef = irxFiles + i; - if ((device == HOST) && (irxFiles[i].flags & NOT_HOST)) + if ((device == HOST_DEV) && (irxFiles[i].flags & NOT_HOST)) continue; if ((irxFiles[i].flags & TYPEMASK) == BIOS) { @@ -139,7 +138,7 @@ int loadIrxModules(int device, const char *irxPath, IrxReference **modules) { curModule->loc = IRX_BUFFER; curModule->path = (char *)malloc(256); - sprintf(curModule->path, "%s%s%s", irxPath, irxFiles[i].name, (device == CDROM) ? ";1" : ""); + sprintf(curModule->path, "%s%s%s", irxPath, irxFiles[i].name, (device == CD_DEV) ? ";1" : ""); int fd = fioOpen(curModule->path, O_RDONLY); if (fd < 0) { // IRX not found @@ -159,7 +158,7 @@ int loadIrxModules(int device, const char *irxPath, IrxReference **modules) { // we simply can't find it. sioprintf("Can't open %s: %d\n", curModule->path, fd); // restore the path where we originally expected the file, for error message (later, after boot up) - sprintf(curModule->path, "%s%s%s", irxPath, irxFiles[i].name, (device == CDROM) ? ";1" : ""); + sprintf(curModule->path, "%s%s%s", irxPath, irxFiles[i].name, (device == CD_DEV) ? ";1" : ""); } } } diff --git a/backends/platform/ps2/irxboot.h b/backends/platform/ps2/irxboot.h index 612d7f61c5..82ae06518c 100644 --- a/backends/platform/ps2/irxboot.h +++ b/backends/platform/ps2/irxboot.h @@ -33,11 +33,12 @@ enum IrxFlags { SYSTEM = 1, USB = 2, HDD = 3, - TYPEMASK = 3, + NET = 4, + TYPEMASK = 7, - OPTIONAL = 4, - DEPENDANCY = 8, - NOT_HOST = 16 + OPTIONAL = 8, + DEPENDANCY = 16, + NOT_HOST = 32 }; enum IrxPurpose { @@ -46,7 +47,8 @@ enum IrxPurpose { USB_DRIVER, MOUSE_DRIVER, KBD_DRIVER, - MASS_DRIVER + MASS_DRIVER, + NET_DRIVER }; enum IrxLocation { @@ -54,12 +56,14 @@ enum IrxLocation { IRX_FILE }; +/* enum BootDevice { HOST = 0, CDROM, - OTHER, - UNKNOWN + MASS, + OTHER }; +*/ struct IrxFile { const char *name; @@ -80,7 +84,6 @@ struct IrxReference { int errorCode; }; -BootDevice detectBootPath(const char *elfPath, char *bootPath); int loadIrxModules(int device, const char *irxPath, IrxReference **modules); #endif // __IRXBOOT_H__ diff --git a/backends/platform/ps2/ps2debug.cpp b/backends/platform/ps2/ps2debug.cpp index 272d256232..1fc3d50170 100644 --- a/backends/platform/ps2/ps2debug.cpp +++ b/backends/platform/ps2/ps2debug.cpp @@ -1,3 +1,25 @@ +/* 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. + * + */ + #include "ps2debug.h" #include #include diff --git a/backends/platform/ps2/ps2debug.h b/backends/platform/ps2/ps2debug.h index 2b128ec9df..8ef06cf150 100644 --- a/backends/platform/ps2/ps2debug.h +++ b/backends/platform/ps2/ps2debug.h @@ -26,7 +26,7 @@ #ifndef __PS2DEBUG_H__ #define __PS2DEBUG_H__ -#define dbg_printf sioprintf +#define dbg_printf printf void sioprintf(const char *zFormat, ...); diff --git a/backends/platform/ps2/ps2temp.h b/backends/platform/ps2/ps2temp.h new file mode 100644 index 0000000000..afffc6de2b --- /dev/null +++ b/backends/platform/ps2/ps2temp.h @@ -0,0 +1,63 @@ +/* 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. + * + */ + +// #define __USE_LIBMC__ +#include "backends/fs/ps2/ps2-fs-factory.h" + +enum PS2Device { + CD_DEV = 0, + HD_DEV, + USB_DEV, + HOST_DEV, + MC_DEV, + ERR_DEV = -1 +}; + +inline PS2Device _getDev(const char *s) { +#if 0 + if (s==NULL || strlen(s) < 3) + return -1; +#endif + + if (s[0] == 'c') + return CD_DEV; + else if (s[0] == 'p') + return HD_DEV; + else if (strncmp(s, "ma", 2) == 0) + return USB_DEV; + else if (s[0] == 'h') + return HOST_DEV; + else if (strncmp(s, "mc", 2) == 0) + return MC_DEV; + else + return ERR_DEV; // -1; +} + +inline PS2Device _getDev(Common::String& cs) { + const char *s = cs.c_str(); + return _getDev(s); +} + +inline PS2Device _getDev(Common::FSNode& n) { + const char *s = n.getPath().c_str(); + return _getDev(s); +} diff --git a/backends/platform/ps2/rawsavefile.cpp b/backends/platform/ps2/rawsavefile.cpp deleted file mode 100644 index aa3cc57fe7..0000000000 --- a/backends/platform/ps2/rawsavefile.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* 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$ - * - */ - -#include "backends/platform/ps2/rawsavefile.h" -#include "backends/platform/ps2/savefilemgr.h" - -RawReadFile::RawReadFile(McAccess *mcAccess) { - _mcAccess = mcAccess; - _size = -1; - _pos = 0; - _buf = NULL; - _eof = false; -} - -RawReadFile::~RawReadFile(void) { - if (_buf) - free(_buf); -} - -bool RawReadFile::bufOpen(const char *path) { - int handle = _mcAccess->open(path, O_RDONLY); - printf("RawReadFile Open: \"%s\" => %d\n", path, handle); - if (handle >= 0) { - _size = _mcAccess->size(handle); - _buf = (uint8 *)memalign(64, _size); - int res = _mcAccess->read(handle, _buf, _size); - if (res != _size) { - free(_buf); - _size = -1; - _buf = NULL; - } - _mcAccess->close(handle); - } else { - _size = -1; - _buf = NULL; - } - _pos = 0; - return (_buf != NULL); -} - -int RawReadFile::bufTell(void) const { - return _pos; -} - -int RawReadFile::bufSeek(int ofs, int whence) { - switch (whence) { - case SEEK_SET: - _pos = ofs; - break; - case SEEK_CUR: - _pos += ofs; - break; - case SEEK_END: - _pos = _size + ofs; - break; - } - if (_pos < 0) - _pos = 0; - else if (_pos > _size) - _pos = _size; - - _eof = false; - return _pos; -} - -int RawReadFile::bufRead(void *dest, int size) { - if (_pos + size > _size) { - size = _size - _pos; - _eof = true; - } - memcpy(dest, _buf + _pos, size); - _pos += size; - return size; -} - -int RawReadFile::bufSize(void) const { - return _size; -} - -bool RawReadFile::bufEof(void) const { - return _eof; -} - -void RawReadFile::bufClearErr(void) const { - _eof = false; -} - -RawWriteFile::RawWriteFile(McAccess *mcAccess) { - _mcAccess = mcAccess; - _size = 64 * 1024; - - _buf = (uint8 *)memalign(64, _size); - _pos = 0; - _handle = -1; -} - -RawWriteFile::~RawWriteFile() { - if (_pos != 0) { - printf("RawWriteFile d'tor: file wasn't flushed!\n"); - bufFlush(); - } - free(_buf); - if (_handle >= 0) - _mcAccess->close(_handle); -} - -bool RawWriteFile::bufOpen(const char *path) { - _handle = _mcAccess->open(path, O_WRONLY | O_CREAT); - strcpy(_filename, path); - return (_handle >= 0); -} - -void RawWriteFile::bufWrite(const void *buf, int len) { - while (_pos + len > _size) { - _size = _size * 2; - _buf = (uint8 *)realloc(_buf, _size); - } - memcpy(_buf + _pos, buf, len); - _pos += len; -} - -bool RawWriteFile::bufFlush(void) { - int result = _mcAccess->write(_handle, _buf, _pos); - if (_pos != result) { - if (result > 0) { - memmove(_buf, _buf + result, _pos - result); - _pos -= result; - } - return false; - } - _pos = 0; - return true; -} - -int RawWriteFile::bufTell(void) const { - return _pos; -} - -void RawWriteFile::removeFile(void) { - if (_handle >= 0) - _mcAccess->close(_handle); - _handle = -1; - _pos = 0; - - _mcAccess->remove(_filename); -} diff --git a/backends/platform/ps2/rawsavefile.h b/backends/platform/ps2/rawsavefile.h deleted file mode 100644 index 8e0dba4ab9..0000000000 --- a/backends/platform/ps2/rawsavefile.h +++ /dev/null @@ -1,74 +0,0 @@ -/* 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 __RAWSAVEFILE_H__ -#define __RAWSAVEFILE_H__ - -#include "common/scummsys.h" - -class McAccess; - -class RawReadFile { -public: - RawReadFile(McAccess *mcAccess); - virtual ~RawReadFile(); - - bool bufOpen(const char *path); - int bufRead(void *dest, int size); - int bufTell(void) const; - int bufSeek(int ofs, int whence); - int bufSize(void) const; - bool bufEof(void) const; - void bufClearErr(void); -protected: - McAccess *_mcAccess; - int _size; - uint8 *_buf; - int _pos; - bool _eof; -}; - -class RawWriteFile { -public: - RawWriteFile(McAccess *mcAccess); - virtual ~RawWriteFile(); - - bool bufOpen(const char *path); - void bufWrite(const void *buf, int len); - int bufTell(void) const; - - bool bufFlush(void); - void removeFile(); -protected: - char _filename[128]; - - McAccess *_mcAccess; - uint8 *_buf; - int _size, _pos; - int _handle; -}; - -#endif // __RAWSAVEFILE_H__ - diff --git a/backends/platform/ps2/rpckbd.h b/backends/platform/ps2/rpckbd.h index 329d95b294..bc94cddf1b 100644 --- a/backends/platform/ps2/rpckbd.h +++ b/backends/platform/ps2/rpckbd.h @@ -1,3 +1,25 @@ +/* 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 __RPCKBD_H__ #define __RPCKBD_H__ diff --git a/backends/platform/ps2/savefile.cpp b/backends/platform/ps2/savefile.cpp deleted file mode 100644 index bfcaf0f57f..0000000000 --- a/backends/platform/ps2/savefile.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/* 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$ - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "backends/platform/ps2/savefile.h" -#include "backends/platform/ps2/rawsavefile.h" -#include "backends/platform/ps2/Gs2dScreen.h" -#include "backends/platform/ps2/systemps2.h" -#include "backends/platform/ps2/savefilemgr.h" -#include "backends/platform/ps2/ps2debug.h" -#include "backends/fs/abstract-fs.h" - -#define UCL_MAGIC 0x314C4355 - -AutoSaveFile::AutoSaveFile(Ps2SaveFileManager *saveMan, const char *filename) { - strcpy(_fileName, filename); - _saveMan = saveMan; - _bufSize = 65536; - _buf = (uint8*)memalign(64, _bufSize); - _bufPos = 0; -} - -AutoSaveFile::~AutoSaveFile(void) { - _saveMan->writeSaveNonblocking(_fileName, _buf, _bufPos); - free(_buf); -} - -uint32 AutoSaveFile::write(const void *ptr, uint32 size) { - uint32 bytesFree = _bufSize - _bufPos; - if (bytesFree < size) { - uint32 allocBytes = (size > 32 * 1024) ? size : 32 * 1024; - _bufSize += allocBytes; - _buf = (uint8*)realloc(_buf, _bufSize); - bytesFree = _bufSize - _bufPos; - } - memcpy(_buf + _bufPos, ptr, size); - _bufPos += size; - return size; -} - - -UclInSaveFile::UclInSaveFile(const char *filename, Gs2dScreen *screen, McAccess *mcAccess) : RawReadFile(mcAccess) { - _screen = screen; - - _err = true; - - if (bufOpen(filename)) { - if ((_size > 8) && (*(uint32 *)_buf == UCL_MAGIC)) { - uint32 resSize = *(uint32 *)(_buf + 4); - uint8 *decBuf = (uint8 *)malloc(resSize + 2048); - int res = ucl_nrv2e_decompress_8(_buf + 8, _size - 8, decBuf, &resSize, NULL); - if ((res >= 0) && (resSize == *(uint32 *)(_buf + 4))) { - free(_buf); - _buf = decBuf; - _size = resSize; - _err = false; - _pos = 0; - } else - free(decBuf); - } - } - if (_err) { - if (_buf) - free(_buf); - _buf = NULL; - _size = -1; - } -} - -UclInSaveFile::~UclInSaveFile(void) { - _screen->wantAnim(false); -} - -bool UclInSaveFile::err(void) const { - return _err; -} - -void UclInSaveFile::clearErr(void) { - _err = false; - bufClearErr(); -} - -bool UclInSaveFile::eos(void) const { - return bufEof(); -} - -int32 UclInSaveFile::pos(void) const { - return bufTell(); -} - -int32 UclInSaveFile::size(void) const { - return bufSize(); -} - -bool UclInSaveFile::seek(int pos, int whence) { - bufSeek(pos, whence); - return true; -} - -uint32 UclInSaveFile::read(void *ptr, uint32 size) { - return (uint32)bufRead(ptr, (int)size); -} - -bool UclInSaveFile::skip(uint32 offset) { - bufSeek(offset, SEEK_CUR); - return true; -} - -UclOutSaveFile::UclOutSaveFile(const char *filename, OSystem_PS2 *system, Gs2dScreen *screen, McAccess *mc) : RawWriteFile(mc) { - _screen = screen; - _system = system; - strcpy(_fileName, filename); - - _err = !bufOpen(filename); - - _wasFlushed = false; -} - -UclOutSaveFile::~UclOutSaveFile(void) { - if (_pos != 0) { - printf("Engine didn't call SaveFile::flush()\n"); - flush(); - if (err()) { - // unable to save to memory card and it's too late to return an error code to the engine - _system->msgPrintf(5000, "!WARNING!\nCan't write to memory card.\nGame was NOT saved."); - printf("~UclOutSaveFile: Flush failed!\n"); - } - } - _screen->wantAnim(false); -} - -uint32 UclOutSaveFile::write(const void *ptr, uint32 size) { - bufWrite(ptr, (int)size); - return size; -} - -bool UclOutSaveFile::err(void) const { - return _err; -} - -void UclOutSaveFile::clearErr(void) { - _err = false; -} - -bool UclOutSaveFile::flush(void) { - if (_pos != 0) { - if (_wasFlushed) { - printf("Multiple calls to UclOutSaveFile::flush!\n"); - _err = true; - return false; - } - uint32 compSize = _pos * 2; - uint8 *compBuf = (uint8*)memalign(64, compSize + 8); - *(uint32*)(compBuf + 0) = UCL_MAGIC; - *(uint32*)(compBuf + 4) = _pos; // uncompressed size - int res = ucl_nrv2e_99_compress(_buf, _pos, compBuf + 8, &compSize, NULL, 10, NULL, NULL); - assert(res >= 0); - - free(_buf); - _buf = compBuf; - _size = _pos * 2; - _pos = compSize + 8; - if (!bufFlush()) { - printf("UclOutSaveFile::flush failed!\n"); - _err = true; - removeFile(); - } - _wasFlushed = true; - } - return true; -} - -/* ----------------------------------------- Glue Classes for POSIX Memory Card Access ----------------------------------------- */ - -Ps2McReadFile::Ps2McReadFile(Ps2SaveFileManager *saveMan) : RawReadFile(saveMan->getMcAccess()), Ps2File(-1) { -} - -Ps2McReadFile::~Ps2McReadFile(void) { -} - -bool Ps2McReadFile::open(const char *name) { - return bufOpen(name); -} - -uint32 Ps2McReadFile::read(void *dest, uint32 len) { - return (uint32)bufRead(dest, (int)len); -} - -uint32 Ps2McReadFile::write(const void *src, uint32 len) { - printf("Write access on Ps2McReadFile!\n"); - return 0; -} - -int32 Ps2McReadFile::tell(void) { - return bufTell(); -} - -int32 Ps2McReadFile::size(void) { - return bufSize(); -} - -int Ps2McReadFile::seek(int32 offset, int origin) { - return bufSeek(offset, origin); -} - -bool Ps2McReadFile::eof(void) { - return bufTell() == bufSize(); -} - - -Ps2McWriteFile::Ps2McWriteFile(Ps2SaveFileManager *saveMan) : RawWriteFile(saveMan->getMcAccess()), Ps2File(-1) { -} - -Ps2McWriteFile::~Ps2McWriteFile() { -} - -bool Ps2McWriteFile::open(const char *name) { - return bufOpen(name); -} - -uint32 Ps2McWriteFile::read(void *dest, uint32 len) { - printf("Read request on Ps2McWriteFile!\n"); - return 0; -} - -uint32 Ps2McWriteFile::write(const void *src, uint32 len) { - bufWrite(src, (int)len); - return len; -} - -int32 Ps2McWriteFile::tell(void) { - return bufTell(); -} - -int32 Ps2McWriteFile::size(void) { - return bufTell(); -} - -int Ps2McWriteFile::seek(int32 offset, int origin) { - printf("SEEK Request on Ps2McWriteFile!\n"); - SleepThread(); - return 0; -} - diff --git a/backends/platform/ps2/savefile.h b/backends/platform/ps2/savefile.h deleted file mode 100644 index 0c0cf922f4..0000000000 --- a/backends/platform/ps2/savefile.h +++ /dev/null @@ -1,116 +0,0 @@ -/* 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 __PS2_SAVEFILE__ -#define __PS2_SAVEFILE__ - -class McAccess; -class OSystem_PS2; -class Gs2dScreen; -class Ps2SaveFileManager; - -#include "common/scummsys.h" -#include "common/savefile.h" -#include "backends/platform/ps2/rawsavefile.h" -#include "backends/platform/ps2/fileio.h" - -class UclOutSaveFile : public Common::OutSaveFile, public RawWriteFile { -public: - UclOutSaveFile(const char *filename, OSystem_PS2 *system, Gs2dScreen *screen, McAccess *mc); - virtual ~UclOutSaveFile(void); - virtual uint32 write(const void *ptr, uint32 size); - virtual bool flush(void); - virtual bool err(void) const; - virtual void clearErr(void); -private: - OSystem_PS2 *_system; - Gs2dScreen *_screen; - - bool _err, _wasFlushed; - char _fileName[128]; -}; - -class UclInSaveFile : public Common::InSaveFile, public RawReadFile { -public: - UclInSaveFile(const char *filename, Gs2dScreen *screen, McAccess *mc); - virtual ~UclInSaveFile(void); - virtual bool eos(void) const; - virtual uint32 read(void *ptr, uint32 size); - virtual bool err(void) const; - virtual void clearErr(void); - virtual bool skip(uint32 offset); - - virtual int32 pos(void) const; - virtual int32 size(void) const; - virtual bool seek(int pos, int whence = SEEK_SET); -private: - Gs2dScreen *_screen; - bool _err; -}; - -class AutoSaveFile : public Common::OutSaveFile { -public: - AutoSaveFile(Ps2SaveFileManager *saveMan, const char *filename); - ~AutoSaveFile(void); - virtual uint32 write(const void *ptr, uint32 size); - virtual bool flush(void) {} - virtual bool err(void) const { return false; } - virtual void clearErr(void) {} -private: - Ps2SaveFileManager *_saveMan; - char _fileName[256]; - uint8 *_buf; - uint32 _bufSize, _bufPos; -}; - -// Glue-classes, not only do we have to provide MC access through the savefilemanager, but also using -// posix file i/o, since that's what's the configmanager expects for storing the scummvm.ini - -class Ps2McReadFile : public RawReadFile, public Ps2File { -public: - Ps2McReadFile(Ps2SaveFileManager *saveMan); - virtual ~Ps2McReadFile(void); - virtual bool open(const char *name); - virtual uint32 read(void *dest, uint32 len); - virtual uint32 write(const void *src, uint32 len); - virtual int32 tell(void); - virtual int32 size(void); - virtual int seek(int32 offset, int origin); - virtual bool eof(void); -}; - -class Ps2McWriteFile : public RawWriteFile, public Ps2File { -public: - Ps2McWriteFile(Ps2SaveFileManager *saveMan); - virtual ~Ps2McWriteFile(void); - virtual bool open(const char *name); - virtual uint32 read(void *dest, uint32 len); - virtual uint32 write(const void *src, uint32 len); - virtual int32 tell(void); - virtual int32 size(void); - virtual int seek(int32 offset, int origin); -}; - -#endif // __PS2_SAVEFILE__ diff --git a/backends/platform/ps2/savefilemgr.cpp b/backends/platform/ps2/savefilemgr.cpp index 3e93b954c7..410d209d12 100644 --- a/backends/platform/ps2/savefilemgr.cpp +++ b/backends/platform/ps2/savefilemgr.cpp @@ -23,550 +23,258 @@ * */ -#include -#include -#include -#include -#include -#include -#include -#include -#include "backends/platform/ps2/savefile.h" -#include "backends/platform/ps2/Gs2dScreen.h" -#include "backends/platform/ps2/systemps2.h" -#include "backends/fs/abstract-fs.h" -#include "backends/platform/ps2/ps2debug.h" - -#include "common/scummsys.h" - -#include "backends/platform/ps2/savefilemgr.h" -#include "backends/platform/ps2/savefile.h" - -extern void *_gp; - -#define PORT 0 -#define SLOT 0 -// port 0, slot 0: memory card in first slot. - -McAccess::McAccess(int port, int slot) { - _port = port; - _slot = slot; - ee_sema_t newSema; - newSema.init_count = 1; - newSema.max_count = 1; - _sema = CreateSema(&newSema); - - assert(mcInit(MC_TYPE_MC) >= 0); -} +#include "common/config-manager.h" +#include "backends/saves/compressed/compressed-saves.h" -McAccess::~McAccess(void) { - DeleteSema(_sema); -} +#ifdef __USE_LIBMC__ + #include +#endif -int McAccess::open(const char *name, int mode) { - int res; - WaitSema(_sema); - mcOpen(_port, _slot, name, mode); - mcSync(0, NULL, &res); - SignalSema(_sema); - return res; -} +#include "asyncfio.h" +#include "savefilemgr.h" +#include "Gs2dScreen.h" +#include "ps2temp.h" -int McAccess::close(int fd) { - int res; - WaitSema(_sema); - mcClose(fd); - mcSync(0, NULL, &res); - SignalSema(_sema); - return res; -} +extern AsyncFio fio; -int McAccess::size(int fd) { - int res, size; - WaitSema(_sema); - mcSeek(fd, 0, SEEK_END); - mcSync(0, NULL, &size); - mcSeek(fd, 0, SEEK_SET); - mcSync(0, NULL, &res); - SignalSema(_sema); - assert(res == 0); - return size; +Ps2SaveFileManager::Ps2SaveFileManager(OSystem_PS2 *system, Gs2dScreen *screen) { + // _system = system; + _screen = screen; } -int McAccess::read(int fd, void *buf, int size) { - int res; - WaitSema(_sema); - mcRead(fd, buf, size); - mcSync(0, NULL, &res); - SignalSema(_sema); - return res; -} +Ps2SaveFileManager::~Ps2SaveFileManager() { -int McAccess::write(int fd, const void *buf, int size) { - int res; - WaitSema(_sema); - mcWrite(fd, buf, size); - mcSync(0, NULL, &res); - SignalSema(_sema); - return res; } -int McAccess::mkDir(const char *name) { - int res; - WaitSema(_sema); - mcMkDir(_port, _slot, name); - mcSync(0, NULL, &res); - SignalSema(_sema); - return res; -} -int McAccess::remove(const char *name) { - int res; - WaitSema(_sema); - mcDelete(_port, _slot, name); - mcSync(0, NULL, &res); - SignalSema(_sema); - return res; -} +bool Ps2SaveFileManager::mcCheck(const char *path) { + // Common::FSNode dir(Common::String(path), 1); // FIXED in gcc 3.4.x + const Common::String str(path); + Common::FSNode dir(str); + + // int res; + + printf("mcCheck\n"); + + if (!dir.exists()) { + printf("! exist -> create : "); +#ifdef __USE_LIBMC__ + printf("%s\n", path+4); + // WaitSema(_sema); + mcSync(0, NULL, NULL); + mcMkDir(0 /*port*/, 0 /*slot*/, path+4); + mcSync(0, NULL, &res); + printf("sync : %d\n", res); + // SignalSema(_sema); +#else + printf("%s\n", path); + fio.mkdir(path); +#endif + } -int McAccess::getDir(const char *name, unsigned int mode, int max, void *dest) { - int res; - WaitSema(_sema); - mcGetDir(_port, _slot, name, mode, max, (mcTable*)dest); - mcSync(0, NULL, &res); - SignalSema(_sema); - return res; + // TODO: res; + return true; } -int McAccess::getInfo(int *type, int *free, int *format) { - int res; - WaitSema(_sema); - mcGetInfo(_port, _slot, type, free, format); - mcSync(0, NULL, &res); - SignalSema(_sema); - return res; +void Ps2SaveFileManager::mcSplit(char *full, char *game, char *ext) { + // TODO } -#define MAX_MC_ENTRIES 16 +Common::InSaveFile *Ps2SaveFileManager::openForLoading(const char *filename) { + Common::FSNode savePath(ConfMan.get("savepath")); // TODO: is this fast? + Common::SeekableReadStream *sf; -void runSaveThread(Ps2SaveFileManager *param); + if (!savePath.exists() || !savePath.isDirectory()) + return NULL; -Ps2SaveFileManager::Ps2SaveFileManager(OSystem_PS2 *system, Gs2dScreen *screen) { - _system = system; - _screen = screen; - _mc = new McAccess(PORT, SLOT); - - _mcDirList = (mcTable*)memalign(64, MAX_MC_ENTRIES * sizeof(mcTable)); - _mcDirName[0] = '\0'; - _mcCheckTime = 0; - _mcNeedsUpdate = true; - - for (int mcCheckCount = 0; mcCheckCount < 3; mcCheckCount++) { - /* retry mcGetInfo 3 times. It slows down startup without mc considerably, - but cheap 3rd party memory cards apparently fail to get detected once in a while */ - - int mcType, mcFree, mcFormat; - int res = _mc->getInfo(&mcType, &mcFree, &mcFormat); - - if ((res == 0) || (res == -1)) { // mc okay - _mcPresent = true; - printf("MC okay, result = %d. Type %d, Free %d, Format %d\n", res, mcType, mcFree, mcFormat); - checkMainDirectory(); - break; - } else { - _mcPresent = false; - printf("MC failed, not present or not formatted, code %d\n", res); + // _screen->wantAnim(true); + + if (_getDev(savePath) == MC_DEV) { + // if (strncmp(savePath.getPath().c_str(), "mc0:", 4) == 0) { + char *game=0, *ext=0, path[32], temp[32]; + + // FIXME : hack for indy4 iq-points + if (strcmp(filename, "iq-points") == 0) { + mcCheck("mc0:ScummVM/indy4"); + sprintf(path, "mc0:ScummVM/indy4/iq-points"); } - } + // FIXME : hack for bs1 saved games + else if (strcmp(filename, "SAVEGAME.INF") == 0) { + mcCheck("mc0:ScummVM/sword1"); + sprintf(path, "mc0:ScummVM/sword1/SAVEGAME.INF"); + } + else { + printf("MC : filename = %s\n", filename); + strcpy(temp, filename); - // create save thread - ee_sema_t newSema; - newSema.init_count = 0; - newSema.max_count = 1; - _autoSaveSignal = CreateSema(&newSema); - _autoSaveBuf = NULL; - _autoSaveSize = 0; - _systemQuit = false; - - ee_thread_t saveThread, thisThread; - ReferThreadStatus(GetThreadId(), &thisThread); - - saveThread.initial_priority = thisThread.current_priority + 1; - saveThread.stack_size = 8 * 1024; - _autoSaveStack = malloc(saveThread.stack_size); - saveThread.stack = _autoSaveStack; - saveThread.func = (void *)runSaveThread; - saveThread.gp_reg = &_gp; - - _autoSaveTid = CreateThread(&saveThread); - assert(_autoSaveTid >= 0); - StartThread(_autoSaveTid, this); -} + // mcSplit(temp, game, ext); + game = strdup(strtok(temp, ".")); + ext = strdup(strtok(NULL, "*")); + sprintf(path, "mc0:ScummVM/%s", game); // per game path -Ps2SaveFileManager::~Ps2SaveFileManager(void) { -} + // mcCheck(path); // needed on load ? + sprintf(path, "mc0:ScummVM/%s/%s.sav", game, ext); + } -void Ps2SaveFileManager::checkMainDirectory(void) { - // verify that the main directory (scummvm config + icon) exists - int ret, fd; - _mcNeedsUpdate = true; - ret = _mc->getDir("/ScummVM/*", 0, MAX_MC_ENTRIES, _mcDirList); - printf("/ScummVM/* res = %d\n", ret); - if (ret <= 0) { // assume directory doesn't exist - printf("Dir doesn't exist\n"); - ret = _mc->mkDir("/ScummVM"); - if (ret >= 0) { - fd = _mc->open("/ScummVM/scummvm.icn", O_WRONLY | O_CREAT); - if (fd >= 0) { - uint16 icoSize; - uint16 *icoBuf = decompressIconData(&icoSize); - ret = _mc->write(fd, icoBuf, icoSize * 2); - _mc->close(fd); - free(icoBuf); - - printf(".icn written\n"); - setupIcon("/ScummVM/icon.sys", "scummvm.icn", "ScummVM", "Configuration"); - } else - printf("Can't create icon file: %d\n", fd); - } else - printf("can't create scummvm directory: %d\n", ret); - } -} + free(game); + free(ext); -void Ps2SaveFileManager::splitPath(const char *fileName, char *dir, char *name) { - strcpy(dir, fileName); - char *ext = strchr(dir, '.'); - if (ext) { - *ext = '\0'; - ext++; - } - if (ext && *ext) - sprintf(name, "%s.ucl", ext); - else - strcpy(name, "save.ucl"); -} + Common::FSNode file(path); -bool Ps2SaveFileManager::mcReadyForDir(const char *dir) { - if (_mcNeedsUpdate || ((_system->getMillis() - _mcCheckTime) > 2000) || !_mcPresent) { - // check if memory card was exchanged/removed in the meantime - int mcType, mcFree, mcFormat, mcResult; - mcResult = _mc->getInfo(&mcType, &mcFree, &mcFormat); - if (mcResult != 0) { // memory card was exchanged - _mcNeedsUpdate = true; - if (mcResult == -1) { // yes, it was exchanged - checkMainDirectory(); // make sure ScummVM dir and icon are there - } else { // no memorycard in slot or not formatted or something like that - _mcPresent = false; - printf("MC not found, error code %d\n", mcResult); - return false; - } - } - _mcPresent = true; - _mcCheckTime = _system->getMillis(); - } - if (_mcNeedsUpdate || strcmp(_mcDirName, dir)) { - strcpy(_mcDirName, dir); - char dirStr[256]; - sprintf(dirStr, "/ScummVM-%s/*", dir); - _mcEntries = _mc->getDir(dirStr, 0, MAX_MC_ENTRIES, _mcDirList); - _mcNeedsUpdate = false; - } - return (_mcEntries >= 0); -} + if(!file.exists()) + return NULL; -Common::InSaveFile *Ps2SaveFileManager::openForLoading(const char *filename) { - _screen->wantAnim(true); + sf = file.openForReading(); - char dir[256], name[256]; - splitPath(filename, dir, name); - printf("openForLoading: \"%s\" => \"%s\" + \"%s\"\n", filename, dir, name); - if (mcReadyForDir(dir)) { - printf("Ready\n"); - bool fileExists = false; - for (int i = 0; i < _mcEntries; i++) - if (strcmp(name, (char*)_mcDirList[i].name) == 0) - fileExists = true; - if (fileExists) { - printf("Found!\n"); - char fullName[256]; - sprintf(fullName, "/ScummVM-%s/%s", dir, name); - UclInSaveFile *file = new UclInSaveFile(fullName, _screen, _mc); - if (file) { - if (!file->ioFailed()) - return file; - else { - printf("IoFailed\n"); - delete file; - } - } - } else - printf("file %s (%s) doesn't exist\n", filename, name); - } - _screen->wantAnim(false); - return NULL; -} + } else { + Common::FSNode file = savePath.getChild(filename); -Common::OutSaveFile *Ps2SaveFileManager::openForSaving(const char *filename) { - int res; - char dir[256], name[256]; + if(!file.exists()) + return NULL; - _screen->wantAnim(true); - splitPath(filename, dir, name); - - if (!mcReadyForDir(dir)) { - if (_mcPresent) { // directory doesn't seem to exist yet - char fullPath[256]; - sprintf(fullPath, "/ScummVM-%s", dir); - res = _mc->mkDir(fullPath); - - char icoSysDest[256], saveDesc[256]; - sprintf(icoSysDest, "%s/icon.sys", fullPath); - strcpy(saveDesc, dir); - if ((saveDesc[0] >= 'a') && (saveDesc[0] <= 'z')) - saveDesc[0] += 'A' - 'a'; - setupIcon(icoSysDest, "../ScummVM/scummvm.icn", saveDesc, "Savegames"); - } + sf = file.openForReading(); } - if (_mcPresent) { - char fullPath[256]; - sprintf(fullPath, "/ScummVM-%s/%s", dir, name); - if (strstr(filename, ".s00") || strstr(filename, ".ASD") || strstr(filename, ".asd")) { - // this is an autosave - AutoSaveFile *file = new AutoSaveFile(this, fullPath); - return file; - } else { - UclOutSaveFile *file = new UclOutSaveFile(fullPath, _system, _screen, _mc); - if (!file->ioFailed()) { - // we're creating a file, mc will have to be updated next time - _mcNeedsUpdate = true; - return file; - } else { - printf("UCL out create failed!\n"); - delete file; - } - } - } + // _screen->wantAnim(false); - _screen->wantAnim(false); - return NULL; + return wrapInSaveFile(sf); } -void Ps2SaveFileManager::listSavefiles(const char *prefix, bool *marks, int num) { +Common::OutSaveFile *Ps2SaveFileManager::openForSaving(const char *filename) { + Common::FSNode savePath(ConfMan.get("savepath")); // TODO: is this fast? + Common::WriteStream *sf; + + printf("openForSaving : %s\n", filename); + + if (!savePath.exists() || !savePath.isDirectory()) + return NULL; + _screen->wantAnim(true); - int mcType, mcFree, mcFormat, mcResult; - mcResult = _mc->getInfo(&mcType, &mcFree, &mcFormat); - - memset(marks, false, num * sizeof(bool)); - - if ((mcResult == 0) || (mcResult == -1)) { - // there's a memory card in the slot. - if (mcResult == -1) - _mcNeedsUpdate = true; - - mcTable *mcEntries = (mcTable*)memalign(64, sizeof(mcTable) * MAX_MC_ENTRIES); - - char dirStr[256], ext[256], mcSearchStr[256]; - strcpy(dirStr, prefix); - char *pos = strchr(dirStr, '.'); - if (pos) { - strcpy(ext, pos + 1); - *pos = '\0'; - } else - ext[0] = '\0'; - sprintf(mcSearchStr, "/ScummVM-%s/%s*", dirStr, ext); - - int numEntries = _mc->getDir(mcSearchStr, 0, MAX_MC_ENTRIES, mcEntries); - - int searchLen = strlen(ext); - for (int i = 0; i < numEntries; i++) - if ((((char*)mcEntries[i].name)[0] != '.') && stricmp((char*)mcEntries[i].name, "icon.sys")) { - char *stopCh; - int destNum = (int)strtoul((char*)mcEntries[i].name + searchLen, &stopCh, 10); - if ((!stopCh) || strcmp(stopCh, ".ucl")) - printf("unexpected end %s in name %s, search %s\n", stopCh, (char*)mcEntries[i].name, prefix); - if (destNum < num) - marks[destNum] = true; - } - free(mcEntries); + if (_getDev(savePath) == MC_DEV) { + // if (strncmp(savePath.getPath().c_str(), "mc0:", 4) == 0) { + char *game=0, *ext=0, path[32], temp[32]; + + // FIXME : hack for indy4 iq-points + if (strcmp(filename, "iq-points") == 0) { + mcCheck("mc0:ScummVM/indy4"); + sprintf(path, "mc0:ScummVM/indy4/iq-points"); + } + // FIXME : hack for bs1 saved games + else if (strcmp(filename, "SAVEGAME.INF") == 0) { + mcCheck("mc0:ScummVM/sword1"); + sprintf(path, "mc0:ScummVM/sword1/SAVEGAME.INF"); + } + else { + strcpy(temp, filename); + + // mcSplit(temp, game, ext); + game = strdup(strtok(temp, ".")); + ext = strdup(strtok(NULL, "*")); + sprintf(path, "mc0:ScummVM/%s", game); // per game path + mcCheck(path); + sprintf(path, "mc0:ScummVM/%s/%s.sav", game, ext); + } + + Common::FSNode file(path); + sf = file.openForWriting(); + free(game); + free(ext); + } else { + Common::FSNode file = savePath.getChild(filename); + sf = file.openForWriting(); } + _screen->wantAnim(false); + return wrapOutSaveFile(sf); } -Common::StringList Ps2SaveFileManager::listSavefiles(const char *regex) { - _screen->wantAnim(true); - Common::StringList results; - int mcType, mcFree, mcFormat, mcResult; - - printf("listSavefiles -> regex=%s\n", regex); - - mcResult = _mc->getInfo(&mcType, &mcFree, &mcFormat); +bool Ps2SaveFileManager::removeSavefile(const char *filename) { + Common::FSNode savePath(ConfMan.get("savepath")); // TODO: is this fast? + Common::FSNode file; - if ((mcResult == 0) || (mcResult == -1)) { - // there's a memory card in the slot. - if (mcResult == -1) - _mcNeedsUpdate = true; + if (!savePath.exists() || !savePath.isDirectory()) + return false; - mcTable *mcEntries = (mcTable*)memalign(64, sizeof(mcTable) * MAX_MC_ENTRIES); + if (_getDev(savePath) == MC_DEV) { + // if (strncmp(savePath.getPath().c_str(), "mc0:", 4) == 0) { + char *game=0, *ext=0, path[32], temp[32]; + strcpy(temp, filename); - char temp[256], mcSearchStr[256], *dir, *ext; - strcpy(temp, regex); - dir = strdup(strtok(temp, ".")); + // mcSplit(temp, game, ext); + game = strdup(strtok(temp, ".")); ext = strdup(strtok(NULL, "*")); - - printf("dir = %s - ext = %s\n", dir, ext); - - sprintf(mcSearchStr, "/ScummVM-%s/%s*", dir, ext); - - int numEntries = _mc->getDir(mcSearchStr, 0, MAX_MC_ENTRIES, mcEntries); - char *name; - for (int i = 0; i < numEntries; i++) { - name = (char*)mcEntries[i].name; - - if ((name[0] != '.') && stricmp(name, "icon.sys")) { - printf(" name = %s\n", (char*)mcEntries[i].name); - if (Common::matchString(name, "s*.ucl")) { - sprintf(temp, "%s.%s%c%c", dir, ext, name[1], name[2]); - results.push_back(temp); - printf(" -> match [%s] ;-)\n", temp); - } - else { - results.push_back(name); // ;-) - printf(" -> no match :-(\n"); - } - } - } - free(mcEntries); - free(dir); + sprintf(path, "mc0:ScummVM/%s", game); // per game path + mcCheck(path); + sprintf(path, "mc0:ScummVM/%s/%s.sav", game, ext); + file = Common::FSNode(path); + free(game); free(ext); - } + } else { + file = savePath.getChild(filename); + } + + if (!file.exists() || file.isDirectory()) + return false; - _screen->wantAnim(false); + fio.remove(file.getPath().c_str()); - return results; + return true; } -bool Ps2SaveFileManager::removeSavefile(const char *filename) { +Common::StringList Ps2SaveFileManager::listSavefiles(const char *pattern) { + Common::FSNode savePath(ConfMan.get("savepath")); // TODO: is this fast? + Common::String _dir; + Common::String search; + bool _mc = (_getDev(savePath) == MC_DEV); + // (strncmp(savePath.getPath().c_str(), "mc0:", 4) == 0); + char *game=0, path[32], temp[32]; - char dir[64], name[64], fullPath[128]; + if (!savePath.exists() || !savePath.isDirectory()) + return Common::StringList(); - splitPath(filename, dir, name); - sprintf(fullPath, "/ScummVM-%s/%s", dir, name); + printf("listSavefiles = %s\n", pattern); - int res = _mc->remove(fullPath); - return (res == 0); -} + if (_mc) { + strcpy(temp, pattern); -const char *Ps2SaveFileManager::getSavePath(void) const { - return "mc0:"; -} + // mcSplit(temp, game, ext); + game = strdup(strtok(temp, ".")); + sprintf(path, "mc0:ScummVM/%s", game); // per game path + mcCheck(path); -bool Ps2SaveFileManager::setupIcon(const char *dest, const char *ico, const char *descr1, const char *descr2) { - mcIcon icon_sys; - memset(&icon_sys, 0, sizeof(mcIcon)); - memcpy(icon_sys.head, "PS2D", 4); - char title[256]; - if (!stricmp("SAVEGAME", descr1)) { // these are broken sword 1 savegames - sprintf(title, "BSword1\n%s", descr2); - icon_sys.nlOffset = 8; - } else { - sprintf(title, "%s\n%s", descr1, descr2); - icon_sys.nlOffset = strlen(descr1) + 1; + sprintf(path, "mc0:ScummVM/%s/", game); + _dir = Common::String(path); + search = Common::String("*.sav"); } - strcpy_sjis((short*)&(icon_sys.title), title); - icon_sys.trans = 0x10; - memcpy(icon_sys.bgCol, _bgcolor, sizeof(_bgcolor)); - memcpy(icon_sys.lightDir, _lightdir, sizeof(_lightdir)); - memcpy(icon_sys.lightCol, _lightcol, sizeof(_lightcol)); - memcpy(icon_sys.lightAmbient, _ambient, sizeof(_ambient)); - strcpy((char*)icon_sys.view, ico); - strcpy((char*)icon_sys.copy, ico); - strcpy((char*)icon_sys.del, ico); - - int fd, res; - fd = _mc->open(dest, O_WRONLY | O_CREAT); - if (fd >= 0) { - res = _mc->write(fd, &icon_sys, sizeof(icon_sys)); - _mc->close(fd); - return (res == sizeof(icon_sys)); - } else - return false; -} - -uint16 *Ps2SaveFileManager::decompressIconData(uint16 *size) { - uint16 inPos = 1; - uint16 *rleData = (uint16*)_rleIcoData; - uint16 resSize = rleData[0]; - uint16 *resData = (uint16*)malloc(resSize * sizeof(uint16)); - uint16 outPos = 0; - while (outPos < resSize) { - uint16 len = rleData[inPos++]; - while (len--) - resData[outPos++] = 0x7FFF; - len = rleData[inPos++]; - while (len--) - resData[outPos++] = rleData[inPos++]; + else { + _dir = Common::String(savePath.getPath()); + search = Common::String(pattern); } - *size = resSize; - assert(outPos == resSize); - return resData; -} -void runSaveThread(Ps2SaveFileManager *param) { - param->saveThread(); -} + Common::FSDirectory dir(_dir); + Common::ArchiveMemberList savefiles; + Common::StringList results; -void Ps2SaveFileManager::writeSaveNonblocking(char *name, void *buf, uint32 size) { - if (buf && size && !_systemQuit) { - strcpy(_autoSaveName, name); - assert(!_autoSaveBuf); - _autoSaveBuf = (uint8*)malloc(size); - memcpy(_autoSaveBuf, buf, size); - _autoSaveSize = size; - SignalSema(_autoSaveSignal); - } -} + printf("dir = %s --- reg = %s\n", _dir.c_str(), search.c_str()); -void Ps2SaveFileManager::saveThread(void) { - while (!_systemQuit) { - WaitSema(_autoSaveSignal); - if (_autoSaveBuf && _autoSaveSize) { - UclOutSaveFile *outSave = new UclOutSaveFile(_autoSaveName, _system, _screen, _mc); - if (!outSave->ioFailed()) { - outSave->write(_autoSaveBuf, _autoSaveSize); - outSave->flush(); + if (dir.listMatchingMembers(savefiles, search) > 0) { + for (Common::ArchiveMemberList::const_iterator file = savefiles.begin(); file != savefiles.end(); ++file) { + if (_mc) { // convert them back in ScummVM names + strncpy(temp, (*file)->getName().c_str(), 3); + temp[3] = '\0'; + sprintf(path, "%s.%s", game, temp); + results.push_back(path); + printf(" --> found = %s -> %s\n", (*file)->getName().c_str(), path); + } + else { + results.push_back((*file)->getName()); + printf(" --> found = %s\n", (*file)->getName().c_str()); } - if (outSave->ioFailed()) - _system->msgPrintf(5000, "Writing autosave to %s failed", _autoSaveName); - delete outSave; - free(_autoSaveBuf); - _autoSaveBuf = NULL; - _autoSaveSize = 0; - _mcNeedsUpdate = true; // we've created a file, mc will have to be updated - _screen->wantAnim(false); } } - ExitThread(); -} - -void Ps2SaveFileManager::quit(void) { - _systemQuit = true; - ee_thread_t statSave, statThis; - ReferThreadStatus(GetThreadId(), &statThis); - ChangeThreadPriority(_autoSaveTid, statThis.current_priority - 1); - do { // wait until thread called ExitThread() - SignalSema(_autoSaveSignal); - ReferThreadStatus(_autoSaveTid, &statSave); - } while (statSave.status != 0x10); + free(game); - DeleteThread(_autoSaveTid); - free(_autoSaveStack); -} - -McAccess *Ps2SaveFileManager::getMcAccess(void) { - return _mc; + return results; } - - diff --git a/backends/platform/ps2/savefilemgr.h b/backends/platform/ps2/savefilemgr.h index 794c2aeb9c..806aae0913 100644 --- a/backends/platform/ps2/savefilemgr.h +++ b/backends/platform/ps2/savefilemgr.h @@ -26,32 +26,12 @@ #ifndef __SAVEFILEMGR_H__ #define __SAVEFILEMGR_H__ -#include -#include "common/savefile.h" +// #include "common/savefile.h" +#include "backends/saves/default/default-saves.h" class Gs2dScreen; class OSystem_PS2; - -class McAccess { -public: - McAccess(int port, int slot); - ~McAccess(void); - int open(const char *name, int mode); - int close(int fd); - int size(int fd); - int read(int fd, void *buf, int size); - int write(int fd, const void *buf, int size); - int mkDir(const char *name); - int getDir(const char *name, unsigned int mode, int max, void *dest); - int getInfo(int *type, int *free, int *format); - int remove(const char *name); - -private: - int _sema; - int _port, _slot; -}; - class Ps2SaveFileManager : public Common::SaveFileManager { public: Ps2SaveFileManager(OSystem_PS2 *system, Gs2dScreen *screen); @@ -59,49 +39,19 @@ public: virtual Common::InSaveFile *openForLoading(const char *filename); virtual Common::OutSaveFile *openForSaving(const char *filename); - virtual void listSavefiles(const char *prefix, bool *marks, int num); - virtual Common::StringList listSavefiles(const char *regex); virtual bool removeSavefile(const char *filename); - /** Get the path to the save game directory. */ - virtual const char *getSavePath() const; + // void writeSaveNonblocking(char *name, void *buf, uint32 size); + // void saveThread(void); + // void quit(void); - void writeSaveNonblocking(char *name, void *buf, uint32 size); - void saveThread(void); - void quit(void); - - McAccess *getMcAccess(void); private: - bool setupIcon(const char *dest, const char *ico, const char *descr1, const char *descr2); - - bool mcReadyForDir(const char *dir); - - void checkMainDirectory(void); - void splitPath(const char *fileName, char *dir, char *name); - uint16 *decompressIconData(uint16 *size); + bool mcCheck(const char *dir); + void mcSplit(char *full, char *game, char *ext); + int _sema; Gs2dScreen *_screen; - OSystem_PS2 *_system; - McAccess *_mc; - - int _autoSaveTid; - int _autoSaveSignal; - void *_autoSaveStack; - volatile bool _systemQuit; - uint8 *_autoSaveBuf; - uint32 _autoSaveSize; - char _autoSaveName[256]; - - mcTable *_mcDirList; - int _mcEntries; - char _mcDirName[256]; - bool _mcNeedsUpdate, _mcPresent; - uint32 _mcCheckTime; - - static const uint8 _rleIcoData[14018]; - static const iconIVECTOR _bgcolor[4]; - static const iconFVECTOR _lightdir[3], _lightcol[3], _ambient; }; #endif // __SAVEFILE_MGR_H__ diff --git a/backends/platform/ps2/systemps2.cpp b/backends/platform/ps2/systemps2.cpp index e4852e67fa..5b24f5bb3e 100644 --- a/backends/platform/ps2/systemps2.cpp +++ b/backends/platform/ps2/systemps2.cpp @@ -52,6 +52,7 @@ #include "backends/platform/ps2/asyncfio.h" #include "eecodyvdfs.h" #include "graphics/surface.h" +#include "graphics/scaler.h" #include "graphics/font.h" #include "backends/timer/default/default-timer.h" #include "sound/mixer_intern.h" @@ -59,6 +60,12 @@ #include "backends/platform/ps2/ps2debug.h" #include "backends/fs/ps2/ps2-fs-factory.h" +#include "backends/saves/default/default-saves.h" +#include "common/config-manager.h" + +#include "icon.h" +#include "ps2temp.h" + // asm("mfc0 %0, $9\n" : "=r"(tickStart)); extern void *_gp; @@ -76,12 +83,16 @@ volatile uint32 msecCount = 0; OSystem_PS2 *g_systemPs2; +int gBitFormat = 1555; + #define FOREVER 2147483647 namespace Graphics { extern const NewFont g_sysfont; }; +PS2Device detectBootPath(const char *elfPath, char *bootPath); + extern AsyncFio fio; extern "C" int scummvm_main(int argc, char *argv[]); @@ -159,7 +170,7 @@ void gluePowerOffCallback(void *system) { void OSystem_PS2::startIrxModules(int numModules, IrxReference *modules) { - _usbMassLoaded = _useMouse = _useKbd = _useHdd = false; + _usbMassLoaded = _useMouse = _useKbd = _useHdd = _useNet = false; int res = 0, rv = 0; for (int i = 0; i < numModules; i++) { @@ -189,13 +200,16 @@ void OSystem_PS2::startIrxModules(int numModules, IrxReference *modules) { case HDD_DRIVER: _useHdd = true; break; + case NET_DRIVER: + _useNet = true; + break; default: break; } } } else sioprintf("Module \"%s\" wasn't found: %d\n", modules[i].path, modules[i].errorCode); - + if ((modules[i].errorCode < 0) || (res < 0) || (rv < 0)) { if (!(modules[i].fileRef->flags & OPTIONAL)) { if (modules[i].errorCode < 0) @@ -206,7 +220,7 @@ void OSystem_PS2::startIrxModules(int numModules, IrxReference *modules) { quit(); } } - + if (modules[i].buffer) free(modules[i].buffer); } else { @@ -234,13 +248,13 @@ OSystem_PS2::OSystem_PS2(const char *elfPath) { _screen->wantAnim(true); - char irxPath[256]; - _bootDevice = detectBootPath(elfPath, irxPath); + _bootPath = (char *)malloc(128); + _bootDevice = detectBootPath(elfPath, _bootPath); IrxReference *modules; - int numModules = loadIrxModules(_bootDevice, irxPath, &modules); + int numModules = loadIrxModules(_bootDevice, _bootPath, &modules); - if (_bootDevice != HOST) { + if (_bootDevice != HOST_DEV) { sioprintf("Resetting IOP.\n"); cdvdInit(CDVD_EXIT); cdvdExit(); @@ -255,6 +269,14 @@ OSystem_PS2::OSystem_PS2(const char *elfPath) { SifLoadFileInit(); cdvdInit(CDVD_INIT_WAIT); } + else { + // romeo : HOST : pre-load + + // TODO: avoid re-loading USB_MASS.IRX -> it will jam mass: + + // TODO: ps2link 1.46 will stall on "poweroff" init / cb + } + startIrxModules(numModules, modules); int res; @@ -277,15 +299,11 @@ OSystem_PS2::OSystem_PS2(const char *elfPath) { if ((hddCheckPresent() < 0) || (hddCheckFormatted() < 0)) _useHdd = false; - dbg_printf("romeo : hddCheckPresent done : %d\n", _useHdd); + //hddPreparePoweroff(); + poweroffInit(); - hddPreparePoweroff(); - //poweroffInit(); - dbg_printf("romeo : hddPreparePoweroff done\n"); - - hddSetUserPoweroffCallback(gluePowerOffCallback, this); - //poweroffSetCallback(gluePowerOffCallback, this); - dbg_printf("romeo : hddSetUserPoweroffCallback done\n"); + //hddSetUserPoweroffCallback(gluePowerOffCallback, this); + poweroffSetCallback(gluePowerOffCallback, this); } fileXioSetBlockMode(FXIO_NOWAIT); @@ -296,7 +314,7 @@ OSystem_PS2::OSystem_PS2(const char *elfPath) { readRtcTime(); if (_useHdd) { - printf("romeo : trying to mount...\n"); + // TODO : make partition path configurable if (fio.mount("pfs0:", "hdd0:+ScummVM", 0) >= 0) printf("Successfully mounted!\n"); else @@ -320,13 +338,16 @@ void OSystem_PS2::init(void) { sioprintf("Initializing ps2Input\n"); _input = new Ps2Input(this, _useMouse, _useKbd); + prepMC(); + makeConfigPath(); + _screen->wantAnim(false); _screen->clearScreen(); - - // OSystem::initBackend(); // romeo } OSystem_PS2::~OSystem_PS2(void) { + free(_bootPath); + free(_configFile); } void OSystem_PS2::initTimer(void) { @@ -457,22 +478,38 @@ void OSystem_PS2::soundThread(void) { ExitThread(); } +bool OSystem_PS2::mcPresent(void) { + int fd = fio.dopen("mc0:"); + + if (fd > 0) { + fio.dclose(fd); + return true; + } + + return false; +} + bool OSystem_PS2::hddPresent(void) { return _useHdd; } bool OSystem_PS2::usbMassPresent(void) { - if (_usbMassLoaded) { - int testFd = fio.dopen("mass:/"); - if (testFd >= 0) - fio.dclose(testFd); - if (testFd != -ENODEV) + int fd = fio.dopen("mass:"); + + if (fd > 0) { + fio.dclose(fd); return true; + } } + return false; } +bool OSystem_PS2::netPresent(void) { + return _useNet; +} + void OSystem_PS2::initSize(uint width, uint height) { printf("initializing new size: (%d/%d)...", width, height); _screen->newScreenSize(width, height); @@ -668,7 +705,7 @@ void OSystem_PS2::msgPrintf(int millis, char *format, ...) { while ((*lnEnd) && (*lnEnd != '\n')) lnEnd++; *lnEnd = '\0'; - + Common::String str(lnSta); int width = Graphics::g_sysfont.getStringWidth(str); if (width > maxWidth) @@ -698,7 +735,7 @@ void OSystem_PS2::msgPrintf(int millis, char *format, ...) { void OSystem_PS2::powerOffCallback(void) { sioprintf("powerOffCallback\n"); - _saveManager->quit(); + // _saveManager->quit(); // romeo if (_useHdd) { sioprintf("umount\n"); fio.umount("pfs0:"); @@ -710,12 +747,12 @@ void OSystem_PS2::powerOffCallback(void) { } void OSystem_PS2::quit(void) { - sioprintf("OSystem_PS2::quit called\n"); - if (_bootDevice == HOST) { - sioprintf("OSystem_PS2::quit (HOST)\n"); + printf("OSystem_PS2::quit called\n"); + if (_bootDevice == HOST_DEV) { + printf("OSystem_PS2::quit (HOST)\n"); SleepThread(); } else { - sioprintf("OSystem_PS2::quit (bootdev=%d)\n", _bootDevice); + printf("OSystem_PS2::quit (bootdev=%d)\n", _bootDevice); if (_useHdd) { driveStandby(); fio.umount("pfs0:"); @@ -724,26 +761,26 @@ void OSystem_PS2::quit(void) { _screen->wantAnim(false); _systemQuit = true; ee_thread_t statSound, statTimer; - sioprintf("Waiting for timer and sound thread to end\n"); + printf("Waiting for timer and sound thread to end\n"); do { // wait until both threads called ExitThread() ReferThreadStatus(_timerTid, &statTimer); ReferThreadStatus(_soundTid, &statSound); } while ((statSound.status != 0x10) || (statTimer.status != 0x10)); - sioprintf("Done\n"); + printf("Done\n"); DeleteThread(_timerTid); DeleteThread(_soundTid); free(_timerStack); free(_soundStack); - sioprintf("Stopping timer\n"); + printf("Stopping timer\n"); DisableIntc(INT_TIMER0); RemoveIntcHandler(INT_TIMER0, _intrId); - _saveManager->quit(); + // _saveManager->quit(); // romeo _screen->quit(); padEnd(); // stop pad library cdvdInit(CDVD_EXIT); - sioprintf("resetting iop\n"); + printf("resetting iop\n"); SifIopReset(NULL, 0); SifExitRpc(); while (!SifIopSync()); @@ -752,41 +789,168 @@ void OSystem_PS2::quit(void) { SifExitRpc(); FlushCache(0); SifLoadFileExit(); - sioprintf("Restarting ScummVM\n"); - LoadExecPS2("cdrom0:\\SCUMMVM.ELF", 0, NULL); // resets the console and executes the ELF - } -} -void OSystem_PS2::makeConfigPath(char *dest) { - // FIXME: Maybe merge this method into createConfigReadStream/createConfigWriteStream ? - FILE *handle; - strcpy(dest, "cdfs:/ScummVM.ini"); - handle = ps2_fopen(dest, "r"); - if (usbMassPresent() && !handle) { - strcpy(dest, "mass:/ScummVM.ini"); - handle = ps2_fopen(dest, "r"); + // TODO : let user choose from reboot and forking an ELF on exit + + // reboot (default) + #if 1 + + LoadExecPS2("", 0, NULL); + + // LoadExecPS2("rom0:OSDSYS",0,NULL); + + // ("rom0:OSDSYS", NULL) + // ("", 0, NULL); + + /* back to PS2 Browser */ +/* + __asm__ __volatile__( + " li $3, 0x04;" + " syscall;" + " nop;" + ); +*/ + +/* + SifIopReset("rom0:UNDL ", 0); + while (!SifIopSync()) ; + // SifIopReboot(...); +*/ + #else + // reset + load ELF from CD + printf("Restarting ScummVM\n"); + LoadExecPS2("cdrom0:\\SCUMMVM.ELF", 0, NULL); + #endif } - if (handle) - ps2_fclose(handle); - else - strcpy(dest, "mc0:ScummVM/scummvm.ini"); } -Common::SeekableReadStream *OSystem_PS2::createConfigReadStream() { - char configFile[MAXPATHLEN]; - makeConfigPath(configFile); - Common::FSNode file(configFile); - return file.createReadStream(); +bool OSystem_PS2::runningFromHost(void) { + return (_bootDevice == HOST_DEV); } -Common::WriteStream *OSystem_PS2::createConfigWriteStream() { - char configFile[MAXPATHLEN]; - makeConfigPath(configFile); - Common::FSNode file(configFile); - return file.createWriteStream(); +bool OSystem_PS2::prepMC() { + FILE *f; + bool prep = false; + + if (!mcPresent()) + return prep; + + printf("prepMC 0\n"); + // Common::String str("mc0:ScummVM/") + // Common::FSNode scumDir(str); + Common::FSNode scumDir("mc0:ScummVM/"); + + printf("prepMC 00\n"); + + if (!scumDir.exists()) { + uint16 *data, size; + + PS2Icon _ico; + mcIcon icon; + + printf("prepMC I\n"); + + size = _ico.decompressData(&data); + + printf("prepMC II\n"); + + _ico.setup(&icon); + +#ifdef __USE_LIBMC__ + int res; + mcInit(MC_TYPE_MC); + mcSync(0, NULL, NULL); + mcMkDir(0,0,"ScummVM"); + mcSync(0, NULL, &res); + // TODO : icon +#else + fio.mkdir("mc0:ScummVM"); + f = ps2_fopen("mc0:ScummVM/scummvm.icn", "w"); + + printf("f = %p\n", f); + + ps2_fwrite(data, size, 2, f); + ps2_fclose(f); + + f = ps2_fopen("mc0:ScummVM/icon.sys", "w"); + + printf("f = %p\n", f); + + ps2_fwrite(&icon, sizeof(icon), 1, f); + ps2_fclose(f); +#endif + free(data); + + printf("prepMC II\n"); + + prep = true; + } + + return prep; } -bool OSystem_PS2::runningFromHost(void) { - return (_bootDevice == HOST); +void OSystem_PS2::makeConfigPath() { + FILE *src, *dst; + char path[128], *buf; + int32 size; + + // Common::FSNode scumIni("mc0:ScummVM/ScummVM.ini"); // gcc bug ! + + switch (_bootDevice) { + case CD_DEV: + { + Common::FSNode scumIni("mc0:ScummVM/ScummVM.ini"); + if (!scumIni.exists()) { + + src = ps2_fopen("cdfs:ScummVM.ini", "r"); + if (src) { + size = ((Ps2File *)src)->size(); + buf = (char *)malloc(size); + ps2_fread(buf, size, 1, src); + ps2_fclose(src); + + dst = ps2_fopen("mc0:ScummVM/ScummVM.ini", "w"); + if (dst) { + ps2_fwrite(buf, size, 1, dst); + ps2_fclose(dst); + sprintf(path, "mc0:ScummVM/ScummVM.ini"); + } + else { + sprintf(path, "cdfs:ScummVM.ini"); + } + + free(buf); + } + } + } + break; + + case MC_DEV: + sprintf(path, "mc0:ScummVM/ScummVM.ini"); + break; + + case HD_DEV: + case USB_DEV: + case HOST_DEV: + sprintf(path, "%sScummVM.ini", _bootPath); + break; + } + + src = ps2_fopen(path, "r"); + if (!src) + sprintf(path, "mc0:ScummVM/ScummVM.ini"); + else + ps2_fclose(src); + + _configFile = strdup(path); } +Common::SeekableReadStream *OSystem_PS2::openConfigFileForReading() { + Common::FSNode file(_configFile); + return file.openForReading(); +} + +Common::WriteStream *OSystem_PS2::openConfigFileForWriting() { + Common::FSNode file(_configFile); + return file.openForWriting(); +} diff --git a/backends/platform/ps2/systemps2.h b/backends/platform/ps2/systemps2.h index 7f29677ba5..ba3fc1b7ff 100644 --- a/backends/platform/ps2/systemps2.h +++ b/backends/platform/ps2/systemps2.h @@ -26,9 +26,10 @@ #ifndef SYSTEMPS2_H #define SYSTEMPS2_H -#include "backends/base-backend.h" +#include "common/system.h" class DefaultTimerManager; +class DefaultSaveFileManager; class Gs2dScreen; class Ps2Input; @@ -52,7 +53,7 @@ namespace Audio { class MixerImpl; }; -class OSystem_PS2 : public BaseBackend { +class OSystem_PS2 : public OSystem { public: OSystem_PS2(const char *elfPath); virtual ~OSystem_PS2(void); @@ -76,8 +77,6 @@ public: virtual void clearOverlay(); virtual void grabOverlay(OverlayColor *buf, int pitch); virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); - virtual int16 getOverlayHeight() { return getHeight(); } - virtual int16 getOverlayWidth() { return getWidth(); } virtual bool showMouse(bool visible); @@ -109,10 +108,10 @@ public: virtual void quit(); - virtual Common::SeekableReadStream *createConfigReadStream(); - virtual Common::WriteStream *createConfigWriteStream(); + virtual Common::SeekableReadStream *openConfigFileForReading(); + virtual Common::WriteStream *openConfigFileForWriting(); - virtual Graphics::PixelFormat getOverlayFormat() const { return Graphics::createPixelFormat<555>(); } + virtual Graphics::PixelFormat getOverlayFormat() const { return Graphics::createPixelFormat<1555>(); } virtual Common::SaveFileManager *getSavefileManager(); virtual FilesystemFactory *getFilesystemFactory(); @@ -122,13 +121,19 @@ public: void timerThread(void); void soundThread(void); void msgPrintf(int millis, char *format, ...); - void makeConfigPath(char *dest); + void makeConfigPath(void); + bool prepMC(); void powerOffCallback(void); + + bool mcPresent(void); bool hddPresent(void); bool usbMassPresent(void); + bool netPresent(void); bool runningFromHost(void); + int getBootDevice() { return _bootDevice; } + private: void startIrxModules(int numModules, IrxReference *modules); @@ -141,9 +146,10 @@ private: bool _mouseVisible; - bool _useMouse, _useKbd, _useHdd, _usbMassLoaded; + bool _useMouse, _useKbd, _useHdd, _usbMassLoaded, _useNet; Ps2SaveFileManager *_saveManager; + // DefaultSaveFileManager *_saveManager; Gs2dScreen *_screen; Ps2Input *_input; @@ -161,6 +167,8 @@ private: static const GraphicsMode _graphicsMode; int _bootDevice; + char *_bootPath; + char *_configFile; }; #endif // SYSTEMPS2_H -- cgit v1.2.3