diff options
25 files changed, 900 insertions, 1357 deletions
diff --git a/backends/fs/ps2/ps2-fs-factory.cpp b/backends/fs/ps2/ps2-fs-factory.cpp index 7585e4f20a..b960e39a24 100644 --- a/backends/fs/ps2/ps2-fs-factory.cpp +++ b/backends/fs/ps2/ps2-fs-factory.cpp @@ -22,7 +22,6 @@ * $Id$ */ -#if defined(__PLAYSTATION2__) #include "backends/fs/ps2/ps2-fs-factory.h" #include "backends/fs/ps2/ps2-fs.cpp" @@ -37,6 +36,17 @@ AbstractFilesystemNode *Ps2FilesystemFactory::makeCurrentDirectoryFileNode() con } AbstractFilesystemNode *Ps2FilesystemFactory::makeFileNodePath(const String &path) const { - return new Ps2FilesystemNode(path); + // 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); } -#endif diff --git a/backends/fs/ps2/ps2-fs-factory.h b/backends/fs/ps2/ps2-fs-factory.h index 1b74ae25d1..416024c905 100644 --- a/backends/fs/ps2/ps2-fs-factory.h +++ b/backends/fs/ps2/ps2-fs-factory.h @@ -30,20 +30,20 @@ /** * Creates PS2FilesystemNode objects. - * - * Parts of this class are documented in the base interface class, FilesystemFactory. + * + * Parts of this class are documented in the base interface class, AbstractFilesystemFactory. */ -class Ps2FilesystemFactory : public FilesystemFactory, public Common::Singleton<Ps2FilesystemFactory> { +class Ps2FilesystemFactory : public FilesystemFactory, public Common::Singleton<Ps2FilesystemFactory> { public: typedef Common::String String; - + virtual AbstractFilesystemNode *makeRootFileNode() const; virtual AbstractFilesystemNode *makeCurrentDirectoryFileNode() const; virtual AbstractFilesystemNode *makeFileNodePath(const String &path) const; - + protected: Ps2FilesystemFactory() {}; - + private: friend class Common::Singleton<SingletonBaseType>; }; diff --git a/backends/fs/ps2/ps2-fs.cpp b/backends/fs/ps2/ps2-fs.cpp index b972887f94..782e97b959 100644 --- a/backends/fs/ps2/ps2-fs.cpp +++ b/backends/fs/ps2/ps2-fs.cpp @@ -26,49 +26,73 @@ #include <kernel.h> #include <stdio.h> #include <stdlib.h> -#include "asyncfio.h" -#include "systemps2.h" +#include <unistd.h> +#include "backends/platform/ps2/asyncfio.h" +#include "backends/platform/ps2/fileio.h" +#include "backends/platform/ps2/systemps2.h" +#include "backends/platform/ps2/ps2debug.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; extern OSystem_PS2 *g_systemPs2; /** * Implementation of the ScummVM file system API based on the Ps2SDK. - * + * * Parts of this class are documented in the base interface class, AbstractFilesystemNode. */ class Ps2FilesystemNode : public AbstractFilesystemNode { + +friend class Ps2FilesystemFactory; + protected: String _displayName; String _path; bool _isDirectory; bool _isRoot; +private: + char *getDeviceDescription(const char *path) const; + bool getDirectoryFlag(const char *path); + public: /** * Creates a PS2FilesystemNode with the root node as path. */ Ps2FilesystemNode(); - + /** * Creates a PS2FilesystemNode for a given path. - * + * * @param path String with the path the new node should point to. */ Ps2FilesystemNode(const String &path); - + Ps2FilesystemNode(const String &path, bool verify); + /** * Copy constructor. */ Ps2FilesystemNode(const Ps2FilesystemNode *node); - virtual bool exists() const { return true; } //FIXME: this is just a stub + virtual bool exists(void) const; + virtual String getDisplayName() const { return _displayName; } virtual String getName() const { return _displayName; } virtual String getPath() const { return _path; } - virtual bool isDirectory() const { return _isDirectory; } - virtual bool isReadable() const { return true; } //FIXME: this is just a stub - virtual bool isWritable() const { return true; } //FIXME: this is just a stub + + virtual bool isDirectory() const { + return _isDirectory; + } + + virtual bool isReadable() const { + return exists(); + } + + virtual bool isWritable() const { + // The only writable device on the ps2 is the memory card + return false; + } virtual AbstractFilesystemNode *clone() const { return new Ps2FilesystemNode(this); } virtual AbstractFilesystemNode *getChild(const String &n) const; @@ -78,18 +102,24 @@ public: /** * Returns the last component of a given path. - * + * * @param str String containing the path. * @return Pointer to the first char of the last component inside str. */ const char *lastPathComponent(const Common::String &str) { - //FIXME: implement this method properly. - // This code is probably around the constructors, - // but I couldn't figure it out without having - // doubts on the correctness of my assumptions. - // Therefore, I leave it to the porter to correctly - // implement this method. - assert(false); + if (str.empty()) + return ""; + + const char *start = str.c_str(); + const char *cur = start + str.size() - 2; + + while (cur >= start && *cur != '/' && *cur != ':') { + --cur; + } + + printf("romeo : lastPathComponent = %s\n", cur + 1); + + return cur + 1; } Ps2FilesystemNode::Ps2FilesystemNode() { @@ -113,13 +143,34 @@ Ps2FilesystemNode::Ps2FilesystemNode(const String &path) { dsplName = pos; if (dsplName) _displayName = String(dsplName); - else { - if (strncmp(path.c_str(), "cdfs", 4) == 0) - _displayName = "DVD Drive"; - else if (strncmp(path.c_str(), "mass", 4) == 0) - _displayName = "USB Mass Storage"; + else + _displayName = getDeviceDescription(path.c_str()); + } +} + +Ps2FilesystemNode::Ps2FilesystemNode(const String &path, bool verify) { + _path = path; + + if (strcmp(path.c_str(), "") == 0) { + _isRoot = true; /* root is always a dir*/ + _displayName = String("PlayStation 2"); + _isDirectory = true; + } else { + _isRoot = false; + const char *dsplName = NULL, *pos = path.c_str(); + while (*pos) + if (*pos++ == '/') + dsplName = pos; + + if (dsplName) { + _displayName = String(dsplName); + if (verify) + _isDirectory = getDirectoryFlag(path.c_str()); else - _displayName = "Harddisk"; + _isDirectory = false; + } else { + _displayName = getDeviceDescription(path.c_str()); + _isDirectory = true; /* devices are always dir */ } } } @@ -131,6 +182,52 @@ Ps2FilesystemNode::Ps2FilesystemNode(const Ps2FilesystemNode *node) { _isRoot = node->_isRoot; } +bool Ps2FilesystemNode::exists(void) const { + + dbg_printf("Ps2FilesystemNode::exists: path \"%s\": ", _path.c_str()); + + if (_path[4] != ':') { // don't bother for relative path... they always fail on PS2! + dbg_printf("NO, relative path\n"); + return false; + } + + if (_path[0] == 'h') { // bypass host + dbg_printf("NO, host device ignored\n"); + return false; + } + + 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; + } + + printf("NO, not found\n"); + return false; +} + +bool Ps2FilesystemNode::getDirectoryFlag(const char *path) { + if (strncmp(path, "host:", 5) == 0) + return true; // Can't get listings from host: right now + + int fd = fio.open(_path.c_str(), O_RDONLY); + + 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); + fio.close(fd); + } else + dbg_printf(" romeo : new node [ %s ] is -not- (%d)\n", path, fd); + + return false; +} + AbstractFilesystemNode *Ps2FilesystemNode::getChild(const String &n) const { if (!_isDirectory) return NULL; @@ -138,10 +235,10 @@ AbstractFilesystemNode *Ps2FilesystemNode::getChild(const String &n) const { char listDir[256]; sprintf(listDir, "%s/", _path.c_str()); int fd = fio.dopen(listDir); - + if (fd >= 0) { iox_dirent_t dirent; - + while (fio.dread(fd, &dirent) > 0) { if (strcmp(n.c_str(), dirent.name) == 0) { Ps2FilesystemNode *dirEntry = new Ps2FilesystemNode(); @@ -161,13 +258,13 @@ AbstractFilesystemNode *Ps2FilesystemNode::getChild(const String &n) const { } fio.dclose(fd); } - + return NULL; } bool Ps2FilesystemNode::getChildren(AbstractFSList &list, ListMode mode, bool hidden) const { //TODO: honor the hidden flag - + if (!_isDirectory) return false; @@ -176,32 +273,32 @@ bool Ps2FilesystemNode::getChildren(AbstractFSList &list, ListMode mode, bool hi dirEntry._isDirectory = true; dirEntry._isRoot = false; dirEntry._path = "cdfs:"; - dirEntry._displayName = "DVD Drive"; + dirEntry._displayName = getDeviceDescription(dirEntry._path.c_str()); list.push_back(new Ps2FilesystemNode(&dirEntry)); if (g_systemPs2->hddPresent()) { dirEntry._path = "pfs0:"; - dirEntry._displayName = "Harddisk"; + dirEntry._displayName = getDeviceDescription(dirEntry._path.c_str()); list.push_back(new Ps2FilesystemNode(&dirEntry)); } if (g_systemPs2->usbMassPresent()) { dirEntry._path = "mass:"; - dirEntry._displayName = "USB Mass Storage"; + dirEntry._displayName = getDeviceDescription(dirEntry._path.c_str()); list.push_back(new Ps2FilesystemNode(&dirEntry)); } return true; } else { char listDir[256]; int fd; - - if (_path.lastChar() == '/') + + if (_path.lastChar() == '/' /* || _path.lastChar() == ':'*/) fd = fio.dopen(_path.c_str()); else { sprintf(listDir, "%s/", _path.c_str()); fd = fio.dopen(listDir); } - + if (fd >= 0) { iox_dirent_t dirent; Ps2FilesystemNode dirEntry; @@ -251,3 +348,14 @@ AbstractFilesystemNode *Ps2FilesystemNode::getParent() const { else return new Ps2FilesystemNode(); } + + +char *Ps2FilesystemNode::getDeviceDescription(const char *path) const { + if (strncmp(path, "cdfs", 4) == 0) + return "DVD Drive"; + else if (strncmp(path, "mass", 4) == 0) + return "USB Mass Storage"; + else + return "Harddisk"; +} + diff --git a/backends/platform/ps2/Gs2dScreen.cpp b/backends/platform/ps2/Gs2dScreen.cpp index e42def535c..92ba731433 100644 --- a/backends/platform/ps2/Gs2dScreen.cpp +++ b/backends/platform/ps2/Gs2dScreen.cpp @@ -33,6 +33,7 @@ #include "DmaPipe.h" #include "GsDefs.h" #include "graphics/surface.h" +#include "backends/platform/ps2/ps2debug.h" extern void *_gp; @@ -73,7 +74,6 @@ static TexVertex kPrintTex[2] = { { SCALE(320), SCALE(200) } }; -void sioprintf(const char *zFormat, ...); void runAnimThread(Gs2dScreen *param); int vblankStartHandler(int cause) { @@ -149,7 +149,7 @@ Gs2dScreen::Gs2dScreen(uint16 width, uint16 height, TVMode tvMode) { _videoMode = tvMode; printf("Setting up %s mode\n", (_videoMode == TV_PAL) ? "PAL" : "NTSC"); - + // set screen size, 640x544 for pal, 640x448 for ntsc _tvWidth = 640; _tvHeight = ((_videoMode == TV_PAL) ? 544 : 448); @@ -175,7 +175,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 +224,7 @@ Gs2dScreen::Gs2dScreen(uint16 width, uint16 height, TVMode tvMode) { updateScreen(); createAnimTextures(); - + // create anim thread ee_thread_t animThread, thisThread; ReferThreadStatus(GetThreadId(), &thisThread); @@ -253,7 +253,7 @@ void Gs2dScreen::quit(void) { _dmaPipe->waitForDma(); // wait for dmac and vblank for the last time while (g_DmacCmd || g_VblankCmd); - sioprintf("kill handlers"); + sioprintf("kill handlers\n"); DisableIntc(INT_VBLANK_START); DisableIntc(INT_VBLANK_END); DisableDmac(2); @@ -364,6 +364,30 @@ void Gs2dScreen::copyScreenRect(const uint8 *buf, int pitch, int x, int y, int w } } +void Gs2dScreen::clearScreen(void) { + WaitSema(g_DmacSema); + memset(_screenBuf, 0, _width * _height); + _screenChanged = true; + SignalSema(g_DmacSema); +} + +Graphics::Surface *Gs2dScreen::lockScreen() { + WaitSema(g_DmacSema); + + _framebuffer.pixels = _screenBuf; + _framebuffer.w = _width; + _framebuffer.h = _height; + _framebuffer.pitch = _width; // -not- _pitch; ! It's EE mem, not Tex + _framebuffer.bytesPerPixel = 1; + + return &_framebuffer; +} + +void Gs2dScreen::unlockScreen() { + _screenChanged = true; + SignalSema(g_DmacSema); +} + void Gs2dScreen::setPalette(const uint32 *pal, uint8 start, uint16 num) { assert(start + num <= 256); @@ -386,20 +410,11 @@ void Gs2dScreen::grabPalette(uint32 *pal, uint8 start, uint16 num) { } } -Graphics::Surface *Gs2dScreen::lockScreen() { +void Gs2dScreen::grabScreen(Graphics::Surface *surf) { + assert(surf); WaitSema(g_DmacSema); - - _framebuffer.pixels = _screen->pixels; - _framebuffer.w = _screen->w; - _framebuffer.h = _screen->h; - _framebuffer.pitch = _screen->pitch; - _framebuffer.bytesPerPixel = 1; - - return &_framebuffer; -} - -void Gs2dScreen::unlockScreen() { - _screenChanged = true; + surf->create(_width, _height, 1); + memcpy(surf->pixels, _screenBuf, _width * _height); SignalSema(g_DmacSema); } @@ -621,7 +636,7 @@ void Gs2dScreen::animThread(void) { do { WaitSema(g_AnimSema); } while ((!_systemQuit) && (!g_RunAnim)); - + if (_systemQuit) break; @@ -746,7 +761,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/Gs2dScreen.h b/backends/platform/ps2/Gs2dScreen.h index 471ec87789..94ef218a40 100644 --- a/backends/platform/ps2/Gs2dScreen.h +++ b/backends/platform/ps2/Gs2dScreen.h @@ -28,6 +28,7 @@ #include "sysdefs.h" #include "backends/platform/ps2/DmaPipe.h" +#include "graphics/surface.h" enum TVMode { TV_DONT_CARE = 0, @@ -56,13 +57,16 @@ public: void copyPrintfOverlay(const uint8* buf); void clearPrintfOverlay(void); + void clearScreen(void); + + Graphics::Surface *lockScreen(); + void unlockScreen(); void copyScreenRect(const uint8 *buf, int pitch, int x, int y, int w, int h); void setPalette(const uint32 *pal, uint8 start, uint16 num); void updateScreen(void); void grabPalette(uint32 *pal, uint8 start, uint16 num); - Graphics::Surface *lockScreen(); - void unlockScreen(); + void grabScreen(Graphics::Surface *surf); //- overlay routines void copyOverlayRect(const uint16 *buf, uint16 pitch, uint16 x, uint16 y, uint16 w, uint16 h); void grabOverlay(uint16 *buf, uint16 pitch); @@ -94,13 +98,12 @@ private: uint32 _clutPtrs[3]; // vram pointers uint32 _texPtrs[4]; // + Graphics::Surface _framebuffer; uint16 _width, _height, _pitch; int16 _mouseX, _mouseY, _hotSpotX, _hotSpotY; uint32 _mouseScaleX, _mouseScaleY; uint8 _mTraCol; - Graphics::Surface _framebuffer; - int _shakePos; bool _showMouse, _showOverlay, _screenChanged, _overlayChanged, _clutChanged; diff --git a/backends/platform/ps2/asyncfio.cpp b/backends/platform/ps2/asyncfio.cpp index 3051699b8b..5c5230465d 100644 --- a/backends/platform/ps2/asyncfio.cpp +++ b/backends/platform/ps2/asyncfio.cpp @@ -30,11 +30,10 @@ #include <assert.h> #include <string.h> #include <fileXio_rpc.h> +#include "backends/platform/ps2/ps2debug.h" #define DEFAULT_MODE (FIO_S_IRUSR | FIO_S_IWUSR | FIO_S_IRGRP | FIO_S_IWGRP | FIO_S_IROTH | FIO_S_IWOTH) -extern void sioprintf(const char *zFormat, ...); - AsyncFio::AsyncFio(void) { _runningOp = NULL; memset((int *)_ioSlots, 0, MAX_HANDLES * sizeof(int)); @@ -55,6 +54,7 @@ int AsyncFio::open(const char *name, int ioMode) { fileXioOpen(name, ioMode, DEFAULT_MODE); fileXioWaitAsync(FXIO_WAIT, &res); SignalSema(_ioSema); + //dbg_printf("FIO: open(%s, %d) => %d\n", name, ioMode, res); return res; } @@ -65,7 +65,7 @@ void AsyncFio::close(int handle) { int res; fileXioWaitAsync(FXIO_WAIT, &res); if (res != 0) - sioprintf("ERROR: fileXioClose failed, EC %d", res); + sioprintf("ERROR: fileXioClose failed, EC %d\n", res); _ioSlots[handle] = 0; SignalSema(_ioSema); } @@ -122,6 +122,7 @@ int AsyncFio::dopen(const char *name) { fileXioDopen(name); fileXioWaitAsync(FXIO_WAIT, &res); SignalSema(_ioSema); + dbg_printf("FIO: dopen(%s) => %d\n", name, res); return res; } @@ -141,7 +142,10 @@ void AsyncFio::dclose(int fd) { checkSync(); fileXioDclose(fd); fileXioWaitAsync(FXIO_WAIT, &res); - assert(res == 0); + //assert(res == 0); + dbg_printf("FIO: dclose(%d) => %d\n", fd, res); + if (res != 0) + sioprintf("ERROR: fileXioDclose failed, EC %d\n", res); SignalSema(_ioSema); } diff --git a/backends/platform/ps2/cd.c b/backends/platform/ps2/cd.c index cd44b3d034..5694d9a960 100644 --- a/backends/platform/ps2/cd.c +++ b/backends/platform/ps2/cd.c @@ -29,7 +29,7 @@ int cdvdInit(int mode) u8 *pkt; cdvdCd.server = NULL; - + do { if ((ret = SifBindRpc(&cdvdCd, CDVD_INIT_BIND_RPC, 0)) < 0) { return -1; @@ -40,14 +40,14 @@ int cdvdInit(int mode) } while(!cdvdCd.server); - pkt = sendBuffer; + pkt = sendBuffer; PUSHDATA( int, pkt, mode, i); pkt += i; len += i; if ((ret = SifCallRpc(&cdvdCd, 0, 0, sendBuffer, len, NULL, 0, 0, 0)) < 0) return -1; - + cdvdInitialised = 1; - + return 0; } diff --git a/backends/platform/ps2/fileio.cpp b/backends/platform/ps2/fileio.cpp index 9fcd1b4354..bc310a43f4 100644 --- a/backends/platform/ps2/fileio.cpp +++ b/backends/platform/ps2/fileio.cpp @@ -35,6 +35,9 @@ #include "common/file.h" #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) @@ -44,7 +47,7 @@ #define READ_ALIGN 64 // align all reads to the size of an EE cache line #define READ_ALIGN_MASK (READ_ALIGN - 1) -extern void sioprintf(const char *zFormat, ...); +extern OSystem_PS2 *g_systemPs2; AsyncFio fio; @@ -197,11 +200,11 @@ void Ps2ReadFile::cacheReadAhead(void) { } if (_physFilePos != cachePosEnd) { - sioprintf("unexpected _physFilePos %d cache %d %d", _physFilePos, _cacheOfs, _bytesInCache); + sioprintf("unexpected _physFilePos %d cache %d %d\n", _physFilePos, _cacheOfs, _bytesInCache); assert(!(cachePosEnd & READ_ALIGN_MASK)); _physFilePos = fio.seek(_fd, cachePosEnd, SEEK_SET); if (_physFilePos != cachePosEnd) { - sioprintf("cache seek error: seek to %d instead of %d, fs = %d", _physFilePos, cachePosEnd, _fileSize); + sioprintf("cache seek error: seek to %d instead of %d, fs = %d\n", _physFilePos, cachePosEnd, _fileSize); return; } } @@ -285,100 +288,11 @@ uint32 Ps2ReadFile::read(void *dest, uint32 len) { } uint32 Ps2ReadFile::write(const void *src, uint32 len) { - sioprintf("write request on Ps2ReadFile!"); + sioprintf("write request on Ps2ReadFile!\n"); SleepThread(); return 0; } -class Ps2WriteFile : public Ps2File { -public: - Ps2WriteFile(int64 cacheId); - virtual ~Ps2WriteFile(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: - int _fd; - uint8 *_cacheBuf; - uint32 _filePos, _bytesInCache; -}; - -Ps2WriteFile::Ps2WriteFile(int64 cacheId) : Ps2File(cacheId) { - _fd = -1; - _cacheBuf = (uint8*)malloc(CACHE_SIZE); - _filePos = _bytesInCache = 0; -} - -Ps2WriteFile::~Ps2WriteFile(void) { - if ((_fd >= 0) && (_bytesInCache)) { - fio.write(_fd, _cacheBuf, _bytesInCache); - int wrRes = fio.sync(_fd); - if (wrRes != (int)_bytesInCache) // too late to return an error - printf("Cache flush on fclose(): Unable to write %d cached bytes to mc, only %d bytes written\n", _bytesInCache, wrRes); - } - if (_fd >= 0) - fio.close(_fd); - free(_cacheBuf); -} - -bool Ps2WriteFile::open(const char *name) { - _fd = fio.open(name, O_WRONLY | O_CREAT | O_TRUNC); - return (_fd >= 0); -} - -uint32 Ps2WriteFile::read(void *dest, uint32 len) { - printf("ERROR: Read request on Ps2WriteFile\n"); - SleepThread(); - return 0; -} - -uint32 Ps2WriteFile::write(const void *src, uint32 len) { - uint32 size = len; - uint8 *srcBuf = (uint8*)src; - while (size) { - uint32 doCpy = (len > CACHE_SIZE - _bytesInCache) ? (CACHE_SIZE - _bytesInCache) : len; - if (doCpy) { - memcpy(_cacheBuf + _bytesInCache, srcBuf, doCpy); - _bytesInCache += doCpy; - srcBuf += doCpy; - size -= doCpy; - } - - if (_bytesInCache == CACHE_SIZE) { - fio.write(_fd, _cacheBuf, _bytesInCache); - if (fio.sync(_fd) != (int)_bytesInCache) { - printf("Unable to flush %d cached bytes to memory card!\n", _bytesInCache); - return 0; - } - _filePos += _bytesInCache; - _bytesInCache = 0; - } - } - return len; -} - -uint32 Ps2WriteFile::tell(void) { - return _bytesInCache + _filePos; -} - -uint32 Ps2WriteFile::size(void) { - return tell(); -} - -int Ps2WriteFile::seek(int32 offset, int origin) { - printf("Seek(%d/%d) request on Ps2WriteFile\n", offset, origin); - SleepThread(); - return 0; -} - -bool Ps2WriteFile::eof(void) { - return true; -} - struct TocNode { char name[64]; TocNode *next, *sub; @@ -426,48 +340,63 @@ FILE *ps2_fopen(const char *fname, const char *mode) { assert(cacheListSema >= 0); } - printf("ps2_fopen: %s, %s\n", fname, mode); - - 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; - } + //printf("ps2_fopen: %s, %s\n", fname, mode); 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; } - bool rdOnly = (mode[0] == 'r'); - int64 cacheId = -1; - if (rdOnly && tocManager.haveEntries()) - cacheId = tocManager.fileExists(fname); + 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 + + 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 (rdOnly && tocManager.haveEntries()) + cacheId = tocManager.fileExists(fname); - if (cacheId != 0) { - Ps2File *file = findInCache(cacheId); - if (file) - return (FILE*)file; + if (cacheId != 0) { + Ps2File *file = findInCache(cacheId); + if (file) + return (FILE*)file; - if (rdOnly) { bool isAudioFile = strstr(fname, ".bun") || strstr(fname, ".BUN") || strstr(fname, ".Bun"); file = new Ps2ReadFile(cacheId, isAudioFile); - } else - file = new Ps2WriteFile(cacheId); - if (file->open(fname)) { - openFileCount++; - return (FILE*)file; - } else - delete file; + if (file->open(fname)) { + openFileCount++; + return (FILE*)file; + } else + delete file; + } + return NULL; } - return NULL; } void checkCacheListLen(void) { @@ -554,10 +483,6 @@ uint32 ps2_ftell(FILE *stream) { return ((Ps2File*)stream)->tell(); } -uint32 ps2_fsize(FILE *stream) { - return ((Ps2File*)stream)->size(); -} - int ps2_feof(FILE *stream) { return ((Ps2File*)stream)->eof(); } diff --git a/backends/platform/ps2/fileio.h b/backends/platform/ps2/fileio.h index 4ec004ed9a..d09d7313a6 100644 --- a/backends/platform/ps2/fileio.h +++ b/backends/platform/ps2/fileio.h @@ -26,6 +26,10 @@ #ifndef __PS2FILE_IO__ #define __PS2FILE_IO__ +typedef unsigned long uint64; +typedef signed long int64; + +#include <stdio.h> #include "common/scummsys.h" class Ps2File { @@ -43,21 +47,6 @@ public: private: }; -class Ps2SmushFile : public Ps2File { -public: - Ps2SmushFile(int64 cacheId); - virtual ~Ps2SmushFile(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: - uint32 _filePos, _fileSize; - int _id; -}; FILE *ps2_fopen(const char *fname, const char *mode); int ps2_fclose(FILE *stream); @@ -65,7 +54,6 @@ int ps2_fflush(FILE *stream); int ps2_fseek(FILE *stream, long offset, int origin); uint32 ps2_ftell(FILE *stream); int ps2_feof(FILE *stream); -uint32 ps2_fsize(FILE *stream); size_t ps2_fread(void *buf, size_t r, size_t n, FILE *stream); int ps2_fgetc(FILE *stream); diff --git a/backends/platform/ps2/icon.cpp b/backends/platform/ps2/icon.cpp index 018bbdc94b..bc30c5290d 100644 --- a/backends/platform/ps2/icon.cpp +++ b/backends/platform/ps2/icon.cpp @@ -23,7 +23,7 @@ * */ -#include "backends/platform/ps2/savefile.h" +#include "backends/platform/ps2/savefilemgr.h" #include "backends/platform/ps2/Gs2dScreen.h" #include "backends/platform/ps2/GsDefs.h" diff --git a/backends/platform/ps2/iop/CoDyVDfs/iop/codyvdfs.c b/backends/platform/ps2/iop/CoDyVDfs/iop/codyvdfs.c index b423b44a1d..e5eb76fdc8 100644 --- a/backends/platform/ps2/iop/CoDyVDfs/iop/codyvdfs.c +++ b/backends/platform/ps2/iop/CoDyVDfs/iop/codyvdfs.c @@ -76,7 +76,7 @@ int cacheEnterDir(ISODirectoryRecord *dir) { cacheName = cachedDir + strlen(cachedDir); memcpy(cacheName, dir->name, dir->len_fi); cacheName[dir->len_fi] = '/'; - cacheName[dir->len_fi + 1] = '\0'; + cacheName[dir->len_fi + 1] = '\0'; return cdReadSectors(cachedDirLba, 1, cacheBuf, &rmode); } @@ -144,7 +144,7 @@ ISODirectoryRecord *findPath(const char *path) { initRootCache(); return (ISODirectoryRecord *)cacheBuf; } - + do { tok = strchr(path, '/'); if (tok) diff --git a/backends/platform/ps2/iop/CoDyVDfs/iop/fiofs.c b/backends/platform/ps2/iop/CoDyVDfs/iop/fiofs.c index 592f9ca61f..f4d512a6e4 100644 --- a/backends/platform/ps2/iop/CoDyVDfs/iop/fiofs.c +++ b/backends/platform/ps2/iop/CoDyVDfs/iop/fiofs.c @@ -86,9 +86,12 @@ int cd_open(iop_file_t *handle, const char *name, int mode) { return -EIO; rec = findPath(name); - if (!rec || IS_DIR(rec)) + if (!rec) return -ENOENT; + if (IS_DIR(rec)) + return -EISDIR; + fdSlot = allocFioHandle(); if (fdSlot < 0) return -ENFILE; @@ -159,7 +162,7 @@ int cd_read(iop_file_t *handle, void *dest, int length) { doCopy = 0x800 - readPos; if (doCopy > bytesLeft) doCopy = bytesLeft; - + memcpy(destPos, fd->buf + readPos, doCopy); readPos += doCopy; readLba += readPos >> 11; @@ -177,7 +180,7 @@ int cd_read(iop_file_t *handle, void *dest, int length) { bytesLeft &= 0x7FF; } } - return destPos - (uint8*)dest; + return destPos - (uint8*)dest; } int cd_close(iop_file_t *handle) { @@ -201,7 +204,7 @@ int cd_dopen(iop_file_t *handle, const char *path) { return -ENOENT; fdSlot = allocDioHandle(); - + if (fdSlot < 0) return -ENFILE; diff --git a/backends/platform/ps2/iop/CoDyVDfs/iop/imports.lst b/backends/platform/ps2/iop/CoDyVDfs/iop/imports.lst index eb85e04462..d3ed3b0442 100644 --- a/backends/platform/ps2/iop/CoDyVDfs/iop/imports.lst +++ b/backends/platform/ps2/iop/CoDyVDfs/iop/imports.lst @@ -24,10 +24,10 @@ I_DelDrv iomanX_IMPORTS_end sifcmd_IMPORTS_start -I_sceSifInitRpc -I_sceSifSetRpcQueue -I_sceSifRegisterRpc -I_sceSifRpcLoop +I_sceSifInitRpc +I_sceSifSetRpcQueue +I_sceSifRegisterRpc +I_sceSifRpcLoop sifcmd_IMPORTS_end stdio_IMPORTS_start @@ -59,7 +59,7 @@ thbase_IMPORTS_start I_CreateThread I_StartThread I_GetThreadId -I_DelayThread +I_DelayThread thbase_IMPORTS_end diff --git a/backends/platform/ps2/iop/CoDyVDfs/iop/rpcfs.c b/backends/platform/ps2/iop/CoDyVDfs/iop/rpcfs.c index a9bfd636c7..c46d452d2c 100644 --- a/backends/platform/ps2/iop/CoDyVDfs/iop/rpcfs.c +++ b/backends/platform/ps2/iop/CoDyVDfs/iop/rpcfs.c @@ -48,7 +48,7 @@ int initRpc(void) { thread.attr = 0; tid = CreateThread(&thread); - if (tid >= 0) + if (tid >= 0) StartThread(tid, 0); else { printf("Unable to start RPC Thread!\n"); diff --git a/backends/platform/ps2/irxboot.cpp b/backends/platform/ps2/irxboot.cpp index 01dc544f24..327e5bdc71 100644 --- a/backends/platform/ps2/irxboot.cpp +++ b/backends/platform/ps2/irxboot.cpp @@ -31,11 +31,10 @@ #include <loadfile.h> #include <malloc.h> #include "backends/platform/ps2/irxboot.h" +#include "backends/platform/ps2/ps2debug.h" -extern void sioprintf(const char *zFormat, ...); - -static const char hddArg[] = "-o" "\0" "4" "\0" "-n" "\0" "20"; -static const char pfsArg[] = "-m" "\0" "2" "\0" "-o" "\0" "16" "\0" "-n" "\0" "40" /*"\0" "-debug"*/; +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"; IrxFile irxFiles[] = { { "SIO2MAN", BIOS, NOTHING, NULL, 0 }, @@ -52,7 +51,7 @@ IrxFile irxFiles[] = { { "USBD.IRX", USB | OPTIONAL | DEPENDANCY, USB_DRIVER, NULL, 0 }, { "PS2MOUSE.IRX", USB | OPTIONAL, MOUSE_DRIVER, NULL, 0 }, { "RPCKBD.IRX", USB | OPTIONAL, KBD_DRIVER, NULL, 0 }, - { "USB_MASS.IRX", USB | OPTIONAL, MASS_DRIVER, NULL, 0 }, + { "USBHDFSD.IRX", USB | OPTIONAL, MASS_DRIVER, NULL, 0 }, { "PS2DEV9.IRX", HDD | OPTIONAL | DEPENDANCY, HDD_DRIVER, NULL, 0 }, { "PS2ATAD.IRX", HDD | OPTIONAL | DEPENDANCY, HDD_DRIVER, NULL, 0 }, @@ -74,8 +73,8 @@ BootDevice detectBootPath(const char *elfPath, char *bootPath) { else device = OTHER; - sioprintf("elf path: %s, device %d", elfPath, device); - + sioprintf("elf path: %s, device %d\n", elfPath, device); + strcpy(bootPath, elfPath); char *pathPos = bootPath; @@ -108,16 +107,16 @@ BootDevice detectBootPath(const char *elfPath, char *bootPath) { pathPos[2] = '\0'; } else pathPos[1] = '\0'; - sioprintf("done. IRX path: \"%s\"", bootPath); + sioprintf("done. IRX path: \"%s\"\n", bootPath); } else { - sioprintf("path not recognized, default to host."); + sioprintf("path not recognized, default to host.\n"); strcpy(bootPath, "host:"); device = 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; @@ -144,7 +143,7 @@ int loadIrxModules(int device, const char *irxPath, IrxReference **modules) { int fd = fioOpen(curModule->path, O_RDONLY); if (fd < 0) { // IRX not found - sioprintf("Can't open %s: %d", curModule->path, fd); + sioprintf("Can't open %s: %d\n", curModule->path, fd); // we keep the error code of the path where we originally expected the file curModule->errorCode = fd; @@ -153,12 +152,12 @@ int loadIrxModules(int device, const char *irxPath, IrxReference **modules) { fd = fioOpen(curModule->path, O_RDONLY); if (fd < 0) { // still not found, try host: - sioprintf("Can't open %s: %d", curModule->path, fd); + sioprintf("Can't open %s: %d\n", curModule->path, fd); sprintf(curModule->path, "host:%s", irxFiles[i].name); fd = fioOpen(curModule->path, O_RDONLY); if (fd < 0) { // we simply can't find it. - sioprintf("Can't open %s: %d", curModule->path, fd); + 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" : ""); } @@ -209,10 +208,11 @@ int loadIrxModules(int device, const char *irxPath, IrxReference **modules) { } curModule++; } + *modules = resModules; - sioprintf("List of %d modules:", curModule - resModules); + sioprintf("List of %d modules:\n", curModule - resModules); for (int i = 0; i < curModule - resModules; i++) - sioprintf("%s", resModules[i].path); + sioprintf("%s\n", resModules[i].path); return curModule - resModules; } diff --git a/backends/platform/ps2/ps2input.cpp b/backends/platform/ps2/ps2input.cpp index a17d38b80d..c320e79eed 100644 --- a/backends/platform/ps2/ps2input.cpp +++ b/backends/platform/ps2/ps2input.cpp @@ -250,11 +250,11 @@ bool Ps2Input::getKeyEvent(Common::Event *event, uint16 buttonCode, bool down) { return false; } -const int Ps2Input::_usbToSdlk[0x100] = { - /* 00 */ 0, - /* 01 */ 0, - /* 02 */ 0, - /* 03 */ 0, +const Common::KeyCode Ps2Input::_usbToSdlk[0x100] = { + /* 00 */ Common::KEYCODE_INVALID, + /* 01 */ Common::KEYCODE_INVALID, + /* 02 */ Common::KEYCODE_INVALID, + /* 03 */ Common::KEYCODE_INVALID, /* 04 */ Common::KEYCODE_a, /* 05 */ Common::KEYCODE_b, /* 06 */ Common::KEYCODE_c, @@ -351,200 +351,200 @@ const int Ps2Input::_usbToSdlk[0x100] = { /* 61 */ Common::KEYCODE_KP9, /* 62 */ Common::KEYCODE_KP0, /* 63 */ Common::KEYCODE_KP_PERIOD, - /* 64 */ 0, - /* 65 */ 0, - /* 66 */ 0, + /* 64 */ Common::KEYCODE_INVALID, + /* 65 */ Common::KEYCODE_INVALID, + /* 66 */ Common::KEYCODE_INVALID, /* 67 */ Common::KEYCODE_KP_EQUALS, - /* 68 */ 0, - /* 69 */ 0, - /* 6A */ 0, - /* 6B */ 0, - /* 6C */ 0, - /* 6D */ 0, - /* 6E */ 0, - /* 6F */ 0, - /* 70 */ 0, - /* 71 */ 0, - /* 72 */ 0, - /* 73 */ 0, - /* 74 */ 0, - /* 75 */ 0, - /* 76 */ 0, - /* 77 */ 0, - /* 78 */ 0, - /* 79 */ 0, - /* 7A */ 0, - /* 7B */ 0, - /* 7C */ 0, - /* 7D */ 0, - /* 7E */ 0, - /* 7F */ 0, - /* 80 */ 0, - /* 81 */ 0, - /* 82 */ 0, - /* 83 */ 0, - /* 84 */ 0, - /* 85 */ 0, - /* 86 */ 0, - /* 87 */ 0, - /* 88 */ 0, - /* 89 */ 0, - /* 8A */ 0, - /* 8B */ 0, - /* 8C */ 0, - /* 8D */ 0, - /* 8E */ 0, - /* 8F */ 0, - /* 90 */ 0, - /* 91 */ 0, - /* 92 */ 0, - /* 93 */ 0, - /* 94 */ 0, - /* 95 */ 0, - /* 96 */ 0, - /* 97 */ 0, - /* 98 */ 0, - /* 99 */ 0, - /* 9A */ 0, - /* 9B */ 0, - /* 9C */ 0, - /* 9D */ 0, - /* 9E */ 0, - /* 9F */ 0, - /* A0 */ 0, - /* A1 */ 0, - /* A2 */ 0, - /* A3 */ 0, - /* A4 */ 0, - /* A5 */ 0, - /* A6 */ 0, - /* A7 */ 0, - /* A8 */ 0, - /* A9 */ 0, - /* AA */ 0, - /* AB */ 0, - /* AC */ 0, - /* AD */ 0, - /* AE */ 0, - /* AF */ 0, - /* B0 */ 0, - /* B1 */ 0, - /* B2 */ 0, - /* B3 */ 0, - /* B4 */ 0, - /* B5 */ 0, - /* B6 */ 0, - /* B7 */ 0, - /* B8 */ 0, - /* B9 */ 0, - /* BA */ 0, - /* BB */ 0, - /* BC */ 0, - /* BD */ 0, - /* BE */ 0, - /* BF */ 0, - /* C0 */ 0, - /* C1 */ 0, - /* C2 */ 0, - /* C3 */ 0, - /* C4 */ 0, - /* C5 */ 0, - /* C6 */ 0, - /* C7 */ 0, - /* C8 */ 0, - /* C9 */ 0, - /* CA */ 0, - /* CB */ 0, - /* CC */ 0, - /* CD */ 0, - /* CE */ 0, - /* CF */ 0, - /* D0 */ 0, - /* D1 */ 0, - /* D2 */ 0, - /* D3 */ 0, - /* D4 */ 0, - /* D5 */ 0, - /* D6 */ 0, - /* D7 */ 0, - /* D8 */ 0, - /* D9 */ 0, - /* DA */ 0, - /* DB */ 0, - /* DC */ 0, - /* DD */ 0, - /* DE */ 0, - /* DF */ 0, + /* 68 */ Common::KEYCODE_INVALID, + /* 69 */ Common::KEYCODE_INVALID, + /* 6A */ Common::KEYCODE_INVALID, + /* 6B */ Common::KEYCODE_INVALID, + /* 6C */ Common::KEYCODE_INVALID, + /* 6D */ Common::KEYCODE_INVALID, + /* 6E */ Common::KEYCODE_INVALID, + /* 6F */ Common::KEYCODE_INVALID, + /* 70 */ Common::KEYCODE_INVALID, + /* 71 */ Common::KEYCODE_INVALID, + /* 72 */ Common::KEYCODE_INVALID, + /* 73 */ Common::KEYCODE_INVALID, + /* 74 */ Common::KEYCODE_INVALID, + /* 75 */ Common::KEYCODE_INVALID, + /* 76 */ Common::KEYCODE_INVALID, + /* 77 */ Common::KEYCODE_INVALID, + /* 78 */ Common::KEYCODE_INVALID, + /* 79 */ Common::KEYCODE_INVALID, + /* 7A */ Common::KEYCODE_INVALID, + /* 7B */ Common::KEYCODE_INVALID, + /* 7C */ Common::KEYCODE_INVALID, + /* 7D */ Common::KEYCODE_INVALID, + /* 7E */ Common::KEYCODE_INVALID, + /* 7F */ Common::KEYCODE_INVALID, + /* 80 */ Common::KEYCODE_INVALID, + /* 81 */ Common::KEYCODE_INVALID, + /* 82 */ Common::KEYCODE_INVALID, + /* 83 */ Common::KEYCODE_INVALID, + /* 84 */ Common::KEYCODE_INVALID, + /* 85 */ Common::KEYCODE_INVALID, + /* 86 */ Common::KEYCODE_INVALID, + /* 87 */ Common::KEYCODE_INVALID, + /* 88 */ Common::KEYCODE_INVALID, + /* 89 */ Common::KEYCODE_INVALID, + /* 8A */ Common::KEYCODE_INVALID, + /* 8B */ Common::KEYCODE_INVALID, + /* 8C */ Common::KEYCODE_INVALID, + /* 8D */ Common::KEYCODE_INVALID, + /* 8E */ Common::KEYCODE_INVALID, + /* 8F */ Common::KEYCODE_INVALID, + /* 90 */ Common::KEYCODE_INVALID, + /* 91 */ Common::KEYCODE_INVALID, + /* 92 */ Common::KEYCODE_INVALID, + /* 93 */ Common::KEYCODE_INVALID, + /* 94 */ Common::KEYCODE_INVALID, + /* 95 */ Common::KEYCODE_INVALID, + /* 96 */ Common::KEYCODE_INVALID, + /* 97 */ Common::KEYCODE_INVALID, + /* 98 */ Common::KEYCODE_INVALID, + /* 99 */ Common::KEYCODE_INVALID, + /* 9A */ Common::KEYCODE_INVALID, + /* 9B */ Common::KEYCODE_INVALID, + /* 9C */ Common::KEYCODE_INVALID, + /* 9D */ Common::KEYCODE_INVALID, + /* 9E */ Common::KEYCODE_INVALID, + /* 9F */ Common::KEYCODE_INVALID, + /* A0 */ Common::KEYCODE_INVALID, + /* A1 */ Common::KEYCODE_INVALID, + /* A2 */ Common::KEYCODE_INVALID, + /* A3 */ Common::KEYCODE_INVALID, + /* A4 */ Common::KEYCODE_INVALID, + /* A5 */ Common::KEYCODE_INVALID, + /* A6 */ Common::KEYCODE_INVALID, + /* A7 */ Common::KEYCODE_INVALID, + /* A8 */ Common::KEYCODE_INVALID, + /* A9 */ Common::KEYCODE_INVALID, + /* AA */ Common::KEYCODE_INVALID, + /* AB */ Common::KEYCODE_INVALID, + /* AC */ Common::KEYCODE_INVALID, + /* AD */ Common::KEYCODE_INVALID, + /* AE */ Common::KEYCODE_INVALID, + /* AF */ Common::KEYCODE_INVALID, + /* B0 */ Common::KEYCODE_INVALID, + /* B1 */ Common::KEYCODE_INVALID, + /* B2 */ Common::KEYCODE_INVALID, + /* B3 */ Common::KEYCODE_INVALID, + /* B4 */ Common::KEYCODE_INVALID, + /* B5 */ Common::KEYCODE_INVALID, + /* B6 */ Common::KEYCODE_INVALID, + /* B7 */ Common::KEYCODE_INVALID, + /* B8 */ Common::KEYCODE_INVALID, + /* B9 */ Common::KEYCODE_INVALID, + /* BA */ Common::KEYCODE_INVALID, + /* BB */ Common::KEYCODE_INVALID, + /* BC */ Common::KEYCODE_INVALID, + /* BD */ Common::KEYCODE_INVALID, + /* BE */ Common::KEYCODE_INVALID, + /* BF */ Common::KEYCODE_INVALID, + /* C0 */ Common::KEYCODE_INVALID, + /* C1 */ Common::KEYCODE_INVALID, + /* C2 */ Common::KEYCODE_INVALID, + /* C3 */ Common::KEYCODE_INVALID, + /* C4 */ Common::KEYCODE_INVALID, + /* C5 */ Common::KEYCODE_INVALID, + /* C6 */ Common::KEYCODE_INVALID, + /* C7 */ Common::KEYCODE_INVALID, + /* C8 */ Common::KEYCODE_INVALID, + /* C9 */ Common::KEYCODE_INVALID, + /* CA */ Common::KEYCODE_INVALID, + /* CB */ Common::KEYCODE_INVALID, + /* CC */ Common::KEYCODE_INVALID, + /* CD */ Common::KEYCODE_INVALID, + /* CE */ Common::KEYCODE_INVALID, + /* CF */ Common::KEYCODE_INVALID, + /* D0 */ Common::KEYCODE_INVALID, + /* D1 */ Common::KEYCODE_INVALID, + /* D2 */ Common::KEYCODE_INVALID, + /* D3 */ Common::KEYCODE_INVALID, + /* D4 */ Common::KEYCODE_INVALID, + /* D5 */ Common::KEYCODE_INVALID, + /* D6 */ Common::KEYCODE_INVALID, + /* D7 */ Common::KEYCODE_INVALID, + /* D8 */ Common::KEYCODE_INVALID, + /* D9 */ Common::KEYCODE_INVALID, + /* DA */ Common::KEYCODE_INVALID, + /* DB */ Common::KEYCODE_INVALID, + /* DC */ Common::KEYCODE_INVALID, + /* DD */ Common::KEYCODE_INVALID, + /* DE */ Common::KEYCODE_INVALID, + /* DF */ Common::KEYCODE_INVALID, /* E0 */ Common::KEYCODE_LCTRL, /* E1 */ Common::KEYCODE_LSHIFT, /* E2 */ Common::KEYCODE_LALT, - /* E3 */ 0, + /* E3 */ Common::KEYCODE_INVALID, /* E4 */ Common::KEYCODE_RCTRL, /* E5 */ Common::KEYCODE_RSHIFT, /* E6 */ Common::KEYCODE_RALT, - /* E7 */ 0, - /* E8 */ 0, - /* E9 */ 0, - /* EA */ 0, - /* EB */ 0, - /* EC */ 0, - /* ED */ 0, - /* EE */ 0, - /* EF */ 0, - /* F0 */ 0, - /* F1 */ 0, - /* F2 */ 0, - /* F3 */ 0, - /* F4 */ 0, - /* F5 */ 0, - /* F6 */ 0, - /* F7 */ 0, - /* F8 */ 0, - /* F9 */ 0, - /* FA */ 0, - /* FB */ 0, - /* FC */ 0, - /* FD */ 0, - /* FE */ 0, - /* FF */ 0 + /* E7 */ Common::KEYCODE_INVALID, + /* E8 */ Common::KEYCODE_INVALID, + /* E9 */ Common::KEYCODE_INVALID, + /* EA */ Common::KEYCODE_INVALID, + /* EB */ Common::KEYCODE_INVALID, + /* EC */ Common::KEYCODE_INVALID, + /* ED */ Common::KEYCODE_INVALID, + /* EE */ Common::KEYCODE_INVALID, + /* EF */ Common::KEYCODE_INVALID, + /* F0 */ Common::KEYCODE_INVALID, + /* F1 */ Common::KEYCODE_INVALID, + /* F2 */ Common::KEYCODE_INVALID, + /* F3 */ Common::KEYCODE_INVALID, + /* F4 */ Common::KEYCODE_INVALID, + /* F5 */ Common::KEYCODE_INVALID, + /* F6 */ Common::KEYCODE_INVALID, + /* F7 */ Common::KEYCODE_INVALID, + /* F8 */ Common::KEYCODE_INVALID, + /* F9 */ Common::KEYCODE_INVALID, + /* FA */ Common::KEYCODE_INVALID, + /* FB */ Common::KEYCODE_INVALID, + /* FC */ Common::KEYCODE_INVALID, + /* FD */ Common::KEYCODE_INVALID, + /* FE */ Common::KEYCODE_INVALID, + /* FF */ Common::KEYCODE_INVALID }; -const int Ps2Input::_padCodes[16] = { +const Common::KeyCode Ps2Input::_padCodes[16] = { Common::KEYCODE_1, // Select - 0, // L3 - 0, // R3 + Common::KEYCODE_INVALID, // L3 + Common::KEYCODE_INVALID, // R3 Common::KEYCODE_F5, // Start - 0, // Up - 0, // Right - 0, // Down - 0, // Left + Common::KEYCODE_INVALID, // Up + Common::KEYCODE_INVALID, // Right + Common::KEYCODE_INVALID, // Down + Common::KEYCODE_INVALID, // Left Common::KEYCODE_KP0, // L2 - 0, // R2 + Common::KEYCODE_INVALID, // R2 Common::KEYCODE_n, // L1 Common::KEYCODE_y, // R1 Common::KEYCODE_ESCAPE, // Triangle - 0, // Circle => Right mouse button - 0, // Cross => Left mouse button + Common::KEYCODE_INVALID, // Circle => Right mouse button + Common::KEYCODE_INVALID, // Cross => Left mouse button Common::KEYCODE_RETURN // Square }; -const int Ps2Input::_padFlags[16] = { - 0, // Select - 0, // L3 - 0, // R3 - 0, // Start - 0, // Up - 0, // Right - 0, // Down - 0, // Left - 0, // L2 - 0, // R2 - 0, // L1 - 0, // R1 - 0, // Triangle - 0, // Circle - 0, // Cross - 0 // Square +const Common::KeyCode Ps2Input::_padFlags[16] = { + Common::KEYCODE_INVALID, // Select + Common::KEYCODE_INVALID, // L3 + Common::KEYCODE_INVALID, // R3 + Common::KEYCODE_INVALID, // Start + Common::KEYCODE_INVALID, // Up + Common::KEYCODE_INVALID, // Right + Common::KEYCODE_INVALID, // Down + Common::KEYCODE_INVALID, // Left + Common::KEYCODE_INVALID, // L2 + Common::KEYCODE_INVALID, // R2 + Common::KEYCODE_INVALID, // L1 + Common::KEYCODE_INVALID, // R1 + Common::KEYCODE_INVALID, // Triangle + Common::KEYCODE_INVALID, // Circle + Common::KEYCODE_INVALID, // Cross + Common::KEYCODE_INVALID // Square }; diff --git a/backends/platform/ps2/ps2input.h b/backends/platform/ps2/ps2input.h index fe35af0526..266f408809 100644 --- a/backends/platform/ps2/ps2input.h +++ b/backends/platform/ps2/ps2input.h @@ -27,6 +27,7 @@ #define __PS2INPUT_H__ #include "common/system.h" +#include "common/keyboard.h" class OSystem_PS2; class Ps2Pad; @@ -54,8 +55,8 @@ private: bool _mouseLoaded, _kbdLoaded; int _keyFlags; - static const int _padCodes[16], _padFlags[16]; - static const int _usbToSdlk[0x100]; + static const Common::KeyCode _padCodes[16], _padFlags[16]; + static const Common::KeyCode _usbToSdlk[0x100]; }; #endif // __PS2INPUT_H__ diff --git a/backends/platform/ps2/ps2mutex.cpp b/backends/platform/ps2/ps2mutex.cpp index e270599013..fe76202f32 100644 --- a/backends/platform/ps2/ps2mutex.cpp +++ b/backends/platform/ps2/ps2mutex.cpp @@ -25,6 +25,17 @@ #include "backends/platform/ps2/systemps2.h" +void OSystem_PS2::initMutexes(void) { + ee_sema_t newSema; + newSema.init_count = 1; + newSema.max_count = 1; + _mutexSema = CreateSema(&newSema); + for (int i = 0; i < MAX_MUTEXES; i++) { + _mutex[i].sema = -1; + _mutex[i].count = _mutex[i].owner = 0; + } +} + OSystem::MutexRef OSystem_PS2::createMutex(void) { WaitSema(_mutexSema); Ps2Mutex *mutex = NULL; @@ -49,6 +60,7 @@ void OSystem_PS2::lockMutex(MutexRef mutex) { WaitSema(_mutexSema); Ps2Mutex *sysMutex = (Ps2Mutex*)mutex; int tid = GetThreadId(); + assert(tid != 0); if (sysMutex->owner && (sysMutex->owner == tid)) sysMutex->count++; @@ -66,6 +78,7 @@ void OSystem_PS2::unlockMutex(MutexRef mutex) { WaitSema(_mutexSema); Ps2Mutex *sysMutex = (Ps2Mutex*)mutex; int tid = GetThreadId(); + if (sysMutex->owner && sysMutex->count && (sysMutex->owner == tid)) sysMutex->count--; else { diff --git a/backends/platform/ps2/ps2time.cpp b/backends/platform/ps2/ps2time.cpp index 5bd62b640d..65b4cb90d7 100644 --- a/backends/platform/ps2/ps2time.cpp +++ b/backends/platform/ps2/ps2time.cpp @@ -24,8 +24,11 @@ */ #include "backends/platform/ps2/systemps2.h" +#include "backends/platform/ps2/ps2debug.h" #include "eecodyvdfs.h" #include <osd_config.h> +#include <time.h> + #define FROM_BCD(a) ((a >> 4) * 10 + (a & 0xF)) static int g_timeSecs; @@ -99,20 +102,12 @@ void OSystem_PS2::readRtcTime(void) { g_timeSecs = (uint32)timeSecs; } - sioprintf("Time: %d:%02d:%02d - %d.%d.%4d", g_timeSecs / (60 * 60), (g_timeSecs / 60) % 60, g_timeSecs % 60, + sioprintf("Time: %d:%02d:%02d - %d.%d.%4d\n", g_timeSecs / (60 * 60), (g_timeSecs / 60) % 60, g_timeSecs % 60, g_day, g_month, g_year + 2000); } -extern "C" time_t time(time_t *p) { - if (p) *p = (time_t)g_timeSecs; - return (time_t)g_timeSecs; -} +void OSystem_PS2::getTimeAndDate(struct tm &t) const { -extern "C" struct tm *localtime(const time_t *p) { - // FIXME: This function should actually use the value in *p! - // But the work needed for that is not necessary -- just implement - // OSystem::getTimeAndDate using the code provided here, and - // ditch the custom time & localtime methods. uint32 currentSecs = g_timeSecs + (msecCount - g_lastTimeCheck) / 1000; if (currentSecs >= SECONDS_PER_DAY) { buildNewDate(+1); @@ -120,15 +115,12 @@ extern "C" struct tm *localtime(const time_t *p) { currentSecs = g_timeSecs + (msecCount - g_lastTimeCheck) / 1000; } - static struct tm retStruct; - memset(&retStruct, 0, sizeof(retStruct)); - - retStruct.tm_hour = currentSecs / (60 * 60); - retStruct.tm_min = (currentSecs / 60) % 60; - retStruct.tm_sec = currentSecs % 60; - retStruct.tm_year = g_year + 100; - retStruct.tm_mday = g_day; - retStruct.tm_mon = g_month - 1; + t.tm_hour = currentSecs / (60 * 60); + t.tm_min = (currentSecs / 60) % 60; + t.tm_sec = currentSecs % 60; + t.tm_year = g_year + 100; + t.tm_mday = g_day; + t.tm_mon = g_month - 1; // tm_wday, tm_yday and tm_isdst are zero for now - return &retStruct; + t.tm_wday = t.tm_yday = t.tm_isdst = 0; } diff --git a/backends/platform/ps2/savefile.cpp b/backends/platform/ps2/savefile.cpp index 425a4ae09f..5ee724cd3f 100644 --- a/backends/platform/ps2/savefile.cpp +++ b/backends/platform/ps2/savefile.cpp @@ -32,192 +32,15 @@ #include <ucl/ucl.h> #include <libmc.h> #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 "common/scummsys.h" - -extern void *_gp; +#include "backends/platform/ps2/savefilemgr.h" +#include "backends/platform/ps2/ps2debug.h" +#include "backends/fs/abstract-fs.h" #define UCL_MAGIC 0x314C4355 -#define PORT 0 -#define SLOT 0 -// port 0, slot 0: memory card in first slot. - -void sioprintf(const char *zFormat, ...); - -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; -}; - -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); -} - -McAccess::~McAccess(void) { - DeleteSema(_sema); -} - -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; -} - -int McAccess::close(int fd) { - int res; - WaitSema(_sema); - mcClose(fd); - mcSync(0, NULL, &res); - SignalSema(_sema); - return res; -} - -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; -} - -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; -} - -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; -} - -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; -} - -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; -} - -class UclOutSaveFile : public Common::OutSaveFile { -public: - UclOutSaveFile(const char *filename, OSystem_PS2 *system, Gs2dScreen *screen, McAccess *mc); - virtual ~UclOutSaveFile(void); - virtual uint32 write(const void *ptr, uint32 size); - virtual void flush(void); - virtual bool ioFailed(void) const; - virtual void clearIOFailed(void); -private: - OSystem_PS2 *_system; - Gs2dScreen *_screen; - McAccess *_mc; - int _fd; - uint8 *_buf; - uint32 _bufSize, _bufPos; - bool _ioFailed, _wasFlushed; - char _fileName[128]; -}; - -class UclInSaveFile : public Common::InSaveFile { -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 ioFailed(void) const; - virtual void clearIOFailed(void); - virtual void skip(uint32 offset); - - virtual uint32 pos(void) const; - virtual uint32 size(void) const; - virtual void seek(int pos, int whence = SEEK_SET); -private: - Gs2dScreen *_screen; - McAccess *_mc; - uint8 *_buf; - uint32 _bufSize, _bufPos; - bool _ioFailed; -}; - -class AutoSaveFile : public Common::OutSaveFile { -public: - AutoSaveFile(Ps2SaveFileManager *saveMan, const char *filename); - ~AutoSaveFile(void); - virtual uint32 write(const void *ptr, uint32 size); - virtual void flush(void) {} - virtual bool ioFailed(void) { return false; }; - virtual void clearIOFailed(void) {} -private: - Ps2SaveFileManager *_saveMan; - char _fileName[256]; - uint8 *_buf; - uint32 _bufSize, _bufPos; -}; - AutoSaveFile::AutoSaveFile(Ps2SaveFileManager *saveMan, const char *filename) { strcpy(_fileName, filename); _saveMan = saveMan; @@ -244,400 +67,36 @@ uint32 AutoSaveFile::write(const void *ptr, uint32 size) { return size; } -#define MAX_MC_ENTRIES 16 - -void runSaveThread(Ps2SaveFileManager *param); -Ps2SaveFileManager::Ps2SaveFileManager(OSystem_PS2 *system, Gs2dScreen *screen) { - _system = system; +UclInSaveFile::UclInSaveFile(const char *filename, Gs2dScreen *screen, McAccess *mcAccess) : RawReadFile(mcAccess) { _screen = screen; - _mc = new McAccess(0, 0); - - _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); - } - } - - // 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); -} - -Ps2SaveFileManager::~Ps2SaveFileManager(void) { -} - -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); - } -} - -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"); -} - -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); -} - -Common::InSaveFile *Ps2SaveFileManager::openForLoading(const char *filename) { - _screen->wantAnim(true); - - char dir[256], name[256]; - splitPath(filename, dir, name); - if (mcReadyForDir(dir)) { - bool fileExists = false; - for (int i = 0; i < _mcEntries; i++) - if (strcmp(name, (char*)_mcDirList[i].name) == 0) - fileExists = true; - if (fileExists) { - 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 - delete file; - } - } else - printf("file %s (%s) doesn't exist\n", filename, name); - } - _screen->wantAnim(false); - return NULL; -} - -Common::OutSaveFile *Ps2SaveFileManager::openForSaving(const char *filename) { - int res; - char dir[256], name[256]; - - _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"); - } - } - - 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; + _ioFailed = 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; + _ioFailed = false; + _pos = 0; } else - delete file; - } - } - - _screen->wantAnim(false); - return NULL; -} - -void Ps2SaveFileManager::removeSavefile(const char *filename) { - TODO: Implement this. -} - -Common::StringList Ps2SaveFileManager::listSavefiles(const char *pattern) { - TODO: Implement this. If you don't understand what it should do, just ask - (e.g. on scummvm-devel or Fingolfin). It should be pretty simple if you - use Common::matchString from common/util.h and read the Doxygen docs, - then combine this with the old code below... - -/* -void Ps2SaveFileManager::listSavefiles(const char *prefix, bool *marks, int num) { - _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); - } - _screen->wantAnim(false); -} -*/ - - -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; - } - 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++]; - } - *size = resSize; - assert(outPos == resSize); - return resData; -} - -void runSaveThread(Ps2SaveFileManager *param) { - param->saveThread(); -} - -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); - } -} - -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 (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); - - DeleteThread(_autoSaveTid); - free(_autoSaveStack); -} - -UclInSaveFile::UclInSaveFile(const char *filename, Gs2dScreen *screen, McAccess *mc) { - _screen = screen; - _mc = mc; - int fd = _mc->open(filename, O_RDONLY); - _buf = NULL; - _bufSize = _bufPos = 0; - _ioFailed = false; - - if (fd >= 0) { - int srcSize = _mc->size(fd); - if (srcSize > 8) { - int res; - uint8 *tmpBuf = (uint8*)memalign(64, srcSize); - res = _mc->read(fd, tmpBuf, srcSize); - if ((res == srcSize) && (*(uint32*)tmpBuf == UCL_MAGIC)) { - uint32 resLen = _bufSize = *(uint32*)(tmpBuf + 4); - _buf = (uint8*)malloc(_bufSize + 2048); - res = ucl_nrv2e_decompress_8(tmpBuf + 8, srcSize - 8, _buf, &resLen, NULL); - if ((res < 0) || (resLen != _bufSize)) { - printf("Unable to decompress file %s (%d -> %d) error code %d\n", filename, srcSize, _bufSize, res); - free(_buf); - _buf = NULL; - _bufSize = 0; - } - } - free(tmpBuf); + free(decBuf); } - _mc->close(fd); } - if (!_buf) { - printf("Invalid savegame %s\n", filename); - _ioFailed = true; + if (_ioFailed) { + if (_buf) + free(_buf); + _buf = NULL; + _size = -1; } } UclInSaveFile::~UclInSaveFile(void) { - if (_buf) - free(_buf); _screen->wantAnim(false); } @@ -650,98 +109,57 @@ void UclInSaveFile::clearIOFailed(void) { } bool UclInSaveFile::eos(void) const { - return _bufPos == _bufSize; + return bufTell() == bufSize(); } uint32 UclInSaveFile::pos(void) const { - return _bufPos; + return bufTell(); } uint32 UclInSaveFile::size(void) const { - return _bufSize; + return bufSize(); } void UclInSaveFile::seek(int pos, int whence) { - int destPos; - switch (whence) { - case SEEK_SET: - destPos = pos; - break; - case SEEK_CUR: - destPos = _bufPos + pos; - break; - case SEEK_END: - destPos = _bufSize + pos; - break; - default: - return; - } - if ((destPos >= 0) && (destPos <= (int)_bufSize)) - _bufPos = (uint32)destPos; + bufSeek(pos, whence); } uint32 UclInSaveFile::read(void *ptr, uint32 size) { - if (_buf) { - uint32 bytesRemain = _bufSize - _bufPos; - if (size > bytesRemain) { - size = bytesRemain; - _ioFailed = true; - } - memcpy(ptr, _buf + _bufPos, size); - _bufPos += size; - return size; - } else { - _ioFailed = true; - return 0; - } + return (uint32)bufRead(ptr, (int)size); } void UclInSaveFile::skip(uint32 offset) { - if (_buf) { - if (_bufPos + offset <= _bufSize) - _bufPos += offset; - else - _bufPos = _bufSize; - } + bufSeek(offset, SEEK_CUR); } -UclOutSaveFile::UclOutSaveFile(const char *filename, OSystem_PS2 *system, Gs2dScreen *screen, McAccess *mc) { +UclOutSaveFile::UclOutSaveFile(const char *filename, OSystem_PS2 *system, Gs2dScreen *screen, McAccess *mc) : RawWriteFile(mc) { _screen = screen; _system = system; - _mc = mc; - _bufPos = 0; - _fd = _mc->open(filename, O_WRONLY | O_CREAT); - if (_fd >= 0) { - _bufSize = 65536; - _buf = (uint8*)malloc(_bufSize); - _ioFailed = false; - strcpy(_fileName, filename); - } else { - _ioFailed = true; - _bufSize = 0; - _buf = NULL; - } + strcpy(_fileName, filename); + + _ioFailed = !bufOpen(filename); + _wasFlushed = false; } UclOutSaveFile::~UclOutSaveFile(void) { - if (_buf) { - if (_bufPos) { - printf("Engine didn't call SaveFile::flush()\n"); - flush(); - if (ioFailed()) { - // 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"); - } + if (_pos != 0) { + printf("Engine didn't call SaveFile::flush()\n"); + flush(); + if (ioFailed()) { + // 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"); } - free(_buf); } - if (_fd >= 0) - _mc->close(_fd); _screen->wantAnim(false); } +uint32 UclOutSaveFile::write(const void *ptr, uint32 size) { + bufWrite(ptr, (int)size); + return size; +} + bool UclOutSaveFile::ioFailed(void) const { return _ioFailed; } @@ -751,63 +169,104 @@ void UclOutSaveFile::clearIOFailed(void) { } void UclOutSaveFile::flush(void) { - int res; - - if (_bufPos) { + if (_pos != 0) { if (_wasFlushed) { - // the engine flushed this file and afterwards wrote more data. - // this is unsupported because it results in savefiles that consist - // of two or more compressed segments. - printf("Error: 2nd call to UclOutSaveFile::flush!\n"); - res = -1; - } else { - uint32 compSize = _bufPos * 2; - uint8 *compBuf = (uint8*)memalign(64, compSize + 8); - *(uint32*)(compBuf + 0) = UCL_MAGIC; - *(uint32*)(compBuf + 4) = _bufPos; // uncompressed size - res = ucl_nrv2e_99_compress(_buf, _bufPos, compBuf + 8, &compSize, NULL, 10, NULL, NULL); - if (res >= 0) { - res = _mc->write(_fd, compBuf, compSize + 8); - if (res != (int)compSize + 8) { - printf("flush: write failed, %d != %d\n", res, compSize + 8); - res = -1; - } - } else - printf("Unable to compress %d bytes of savedata, errorcode %d\n", _bufPos, res); - free(compBuf); - _bufPos = 0; + printf("Multiple calls to UclOutSaveFile::flush!\n"); + _ioFailed = true; + return; } + 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); - if (res < 0) { - _ioFailed = true; + free(_buf); + _buf = compBuf; + _size = _pos * 2; + _pos = compSize + 8; + if (!bufFlush()) { printf("UclOutSaveFile::flush failed!\n"); - if (_fd >= 0) { - // the file is broken; delete it - _mc->close(_fd); - res = _mc->remove(_fileName); - if (res == 0) - printf("File %s: remove ok\n", _fileName); - else - printf("File %s: remove error %d\n", _fileName, res); - _fd = -1; - } + _ioFailed = true; + removeFile(); } + _wasFlushed = true; } } -uint32 UclOutSaveFile::write(const void *ptr, uint32 size) { - assert(_bufPos <= _bufSize); - 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; - } - assert(bytesFree >= size); - memcpy(_buf + _bufPos, ptr, size); - _bufPos += size; - return size; +/* ----------------------------------------- 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; +} + +uint32 Ps2McReadFile::tell(void) { + return bufTell(); +} + +uint32 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; +} + +uint32 Ps2McWriteFile::tell(void) { + return bufTell(); +} + +uint32 Ps2McWriteFile::size(void) { + return bufTell(); +} + +int Ps2McWriteFile::seek(int32 offset, int origin) { + printf("SEEK Request on Ps2McWriteFile!\n"); + SleepThread(); + return 0; +} + +bool Ps2McWriteFile::eof(void) { + return true; +} diff --git a/backends/platform/ps2/savefile.h b/backends/platform/ps2/savefile.h index b6019192ae..4832b8c3fe 100644 --- a/backends/platform/ps2/savefile.h +++ b/backends/platform/ps2/savefile.h @@ -26,56 +26,92 @@ #ifndef __PS2_SAVEFILE__ #define __PS2_SAVEFILE__ -#include <libmc.h> -#include "common/savefile.h" - -class Gs2dScreen; -class OSystem_PS2; class McAccess; +class OSystem_PS2; +class Gs2dScreen; +class Ps2SaveFileManager; -class Ps2SaveFileManager : public Common::SaveFileManager { -public: - Ps2SaveFileManager(OSystem_PS2 *system, Gs2dScreen *screen); - virtual ~Ps2SaveFileManager(); - - virtual Common::InSaveFile *openForLoading(const char *filename); - virtual Common::OutSaveFile *openForSaving(const char *filename); - virtual Common::StringList listSavefiles(const char *pattern); - - void writeSaveNonblocking(char *name, void *buf, uint32 size); - void saveThread(void); - void quit(void); +#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 void flush(void); + virtual bool ioFailed(void) const; + virtual void clearIOFailed(void); private: - bool setupIcon(const char *dest, const char *ico, const char *descr1, const char *descr2); - - bool mcReadyForDir(const char *dir); + OSystem_PS2 *_system; + Gs2dScreen *_screen; - void checkMainDirectory(void); - void splitPath(const char *fileName, char *dir, char *name); - uint16 *decompressIconData(uint16 *size); + bool _ioFailed, _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 ioFailed(void) const; + virtual void clearIOFailed(void); + virtual void skip(uint32 offset); + + virtual uint32 pos(void) const; + virtual uint32 size(void) const; + virtual void seek(int pos, int whence = SEEK_SET); +private: Gs2dScreen *_screen; - OSystem_PS2 *_system; - McAccess *_mc; + bool _ioFailed; +}; - int _autoSaveTid; - int _autoSaveSignal; - void *_autoSaveStack; - volatile bool _systemQuit; - uint8 *_autoSaveBuf; - uint32 _autoSaveSize; - char _autoSaveName[256]; +class AutoSaveFile : public Common::OutSaveFile { +public: + AutoSaveFile(Ps2SaveFileManager *saveMan, const char *filename); + ~AutoSaveFile(void); + virtual uint32 write(const void *ptr, uint32 size); + virtual void flush(void) {} + virtual bool ioFailed(void) { return false; }; + virtual void clearIOFailed(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 - mcTable *_mcDirList; - int _mcEntries; - char _mcDirName[256]; - bool _mcNeedsUpdate, _mcPresent; - uint32 _mcCheckTime; +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 uint32 tell(void); + virtual uint32 size(void); + virtual int seek(int32 offset, int origin); + virtual bool eof(void); +}; - static const uint8 _rleIcoData[14018]; - static const iconIVECTOR _bgcolor[4]; - static const iconFVECTOR _lightdir[3], _lightcol[3], _ambient; +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 uint32 tell(void); + virtual uint32 size(void); + virtual int seek(int32 offset, int origin); + virtual bool eof(void); }; #endif // __PS2_SAVEFILE__ diff --git a/backends/platform/ps2/systemps2.cpp b/backends/platform/ps2/systemps2.cpp index 384ec1f935..b2818ebfc0 100644 --- a/backends/platform/ps2/systemps2.cpp +++ b/backends/platform/ps2/systemps2.cpp @@ -34,7 +34,6 @@ #include <iopcontrol.h> #include <iopheap.h> #include "common/scummsys.h" -#include "../intern.h" #include "engines/engine.h" #include "backends/platform/ps2/systemps2.h" #include "backends/platform/ps2/Gs2dScreen.h" @@ -42,19 +41,22 @@ #include "backends/platform/ps2/irxboot.h" #include <sjpcm.h> #include <libhdd.h> -#include "backends/platform/ps2/savefile.h" +#include "backends/platform/ps2/savefilemgr.h" #include "common/file.h" #include "backends/platform/ps2/sysdefs.h" +#include "backends/platform/ps2/fileio.h" #include <libmc.h> #include <libpad.h> #include "backends/platform/ps2/cd.h" -#include <sio.h> #include <fileXio_rpc.h> #include "backends/platform/ps2/asyncfio.h" #include "eecodyvdfs.h" #include "graphics/surface.h" #include "graphics/font.h" - +#include "backends/timer/default/default-timer.h" +#include "sound/mixer.h" +#include "common/events.h" +#include "backends/platform/ps2/ps2debug.h" // asm("mfc0 %0, $9\n" : "=r"(tickStart)); extern void *_gp; @@ -82,17 +84,6 @@ namespace Graphics { extern AsyncFio fio; -void sioprintf(const char *zFormat, ...) { - va_list ap; - char resStr[2048]; - - va_start(ap,zFormat); - vsnprintf(resStr, 2048, zFormat, ap); - va_end(ap); - - sio_puts(resStr); -} - extern "C" int scummvm_main(int argc, char *argv[]); extern "C" int main(int argc, char *argv[]) { @@ -110,16 +101,24 @@ extern "C" int main(int argc, char *argv[]) { Don't know about NapLink, etc. The priority doesn't matter too much, but we need to be at least at prio 3, so we can have the timer thread run at prio 2 and the sound thread at prio 1 */ - sioprintf("Changing thread priority"); + sioprintf("Changing thread priority\n"); int res = ChangeThreadPriority(tid, 20); - sioprintf("Result = %d", res); + sioprintf("Result = %d\n", res); } - sioprintf("Creating system"); + sioprintf("Creating system\n"); g_system = g_systemPs2 = new OSystem_PS2(argv[0]); - sioprintf("init done. starting ScummVM."); - return scummvm_main(argc, argv); + g_systemPs2->init(); + + sioprintf("init done. starting ScummVM.\n"); + int res = scummvm_main(argc, argv); + sioprintf("scummvm_main terminated: %d\n", res); + + g_systemPs2->quit(); + + // control never gets here + return res; } s32 timerInterruptHandler(s32 cause) { @@ -158,14 +157,6 @@ void gluePowerOffCallback(void *system) { ((OSystem_PS2*)system)->powerOffCallback(); } -void mass_connect_cb(void *pkt, void *system) { - ((OSystem_PS2*)system)->setUsbMassConnected(true); -} - -void mass_disconnect_cb(void *pkt, void *system) { - ((OSystem_PS2*)system)->setUsbMassConnected(false); -} - void OSystem_PS2::startIrxModules(int numModules, IrxReference *modules) { _usbMassLoaded = _useMouse = _useKbd = _useHdd = false; @@ -174,7 +165,7 @@ void OSystem_PS2::startIrxModules(int numModules, IrxReference *modules) { for (int i = 0; i < numModules; i++) { if (modules[i].loc == IRX_FILE) { res = SifLoadModule(modules[i].path, modules[i].argSize, modules[i].args); - sioprintf("Module \"%s\": %d", modules[i].path, res); + sioprintf("Module \"%s\": %d\n", modules[i].path, res); if (res < 0) { msgPrintf(FOREVER, "\"%s\"\nnot found: %d", modules[i].path, res); delayMillis(5000); @@ -183,7 +174,7 @@ void OSystem_PS2::startIrxModules(int numModules, IrxReference *modules) { } else if (modules[i].loc == IRX_BUFFER) { if (modules[i].errorCode == 0) { res = SifExecModuleBuffer(modules[i].buffer, modules[i].size, modules[i].argSize, modules[i].args, &rv); - sioprintf("Module \"%s\": EE=%d, IOP=%d", modules[i].path, res, rv); + sioprintf("Module \"%s\": EE=%d, IOP=%d\n", modules[i].path, res, rv); if ((res >= 0) && (rv >= 0)) { switch (modules[i].fileRef->purpose) { case MASS_DRIVER: @@ -203,8 +194,8 @@ void OSystem_PS2::startIrxModules(int numModules, IrxReference *modules) { } } } else - sioprintf("Module \"%s\" wasn't found: %d", modules[i].path, modules[i].errorCode); - + 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) @@ -215,36 +206,31 @@ void OSystem_PS2::startIrxModules(int numModules, IrxReference *modules) { quit(); } } - - if (modules[i].buffer); + + if (modules[i].buffer) free(modules[i].buffer); } else { - sioprintf("module %d of %d damaged, loc %d, path %s", i, numModules, modules[i].loc, modules[i].path); + sioprintf("module %d of %d damaged, loc %d, path %s\n", i, numModules, modules[i].loc, modules[i].path); } free(modules[i].path); } free(modules); - sioprintf("done"); - sioprintf("UsbMass: %sloaded", _usbMassLoaded ? "" : "not "); - sioprintf("Mouse: %sloaded", _useMouse ? "" : "not "); - sioprintf("Kbd: %sloaded", _useKbd ? "" : "not "); - sioprintf("Hdd: %sloaded", _useHdd ? "" : "not "); + sioprintf("done\n"); + sioprintf("UsbMass: %sloaded\n", _usbMassLoaded ? "" : "not "); + sioprintf("Mouse: %sloaded\n", _useMouse ? "" : "not "); + sioprintf("Kbd: %sloaded\n", _useKbd ? "" : "not "); + sioprintf("Hdd: %sloaded\n", _useHdd ? "" : "not "); } OSystem_PS2::OSystem_PS2(const char *elfPath) { _soundStack = _timerStack = NULL; - _scummTimerProc = NULL; - _scummSoundProc = NULL; - _scummSoundParam = NULL; _printY = 0; _msgClearTime = 0; _systemQuit = false; - _usbMassConnected = false; _screen = new Gs2dScreen(320, 200, TV_DONT_CARE); - sioprintf("Initializing system..."); - initTimer(); + sioprintf("Initializing system...\n"); _screen->wantAnim(true); @@ -255,7 +241,7 @@ OSystem_PS2::OSystem_PS2(const char *elfPath) { int numModules = loadIrxModules(_bootDevice, irxPath, &modules); if (_bootDevice != HOST) { - sio_puts("Resetting IOP."); + sioprintf("Resetting IOP.\n"); cdvdInit(CDVD_EXIT); cdvdExit(); SifExitIopHeap(); @@ -264,7 +250,7 @@ OSystem_PS2::OSystem_PS2(const char *elfPath) { SifIopReset("rom0:UDNL rom0:EELOADCNF", 0); while (!SifIopSync()) ; - sio_puts("IOP synced."); + sioprintf("IOP synced.\n"); SifInitRpc(0); SifLoadFileInit(); cdvdInit(CDVD_INIT_WAIT); @@ -291,54 +277,54 @@ OSystem_PS2::OSystem_PS2(const char *elfPath) { if ((hddCheckPresent() < 0) || (hddCheckFormatted() < 0)) _useHdd = false; + dbg_printf("romeo : hddCheckPresent done : %d\n", _useHdd); + hddPreparePoweroff(); + //poweroffInit(); + dbg_printf("romeo : hddPreparePoweroff done\n"); + hddSetUserPoweroffCallback(gluePowerOffCallback, this); + //poweroffSetCallback(gluePowerOffCallback, this); + dbg_printf("romeo : hddSetUserPoweroffCallback done\n"); } fileXioSetBlockMode(FXIO_NOWAIT); _mouseVisible = false; - sioprintf("reading RTC"); + sioprintf("reading RTC\n"); readRtcTime(); if (_useHdd) { + printf("romeo : trying to mount...\n"); if (fio.mount("pfs0:", "hdd0:+ScummVM", 0) >= 0) printf("Successfully mounted!\n"); else _useHdd = false; } - sioprintf("Starting SavefileManager"); + initMutexes(); +} + +void OSystem_PS2::init(void) { + sioprintf("Timer...\n"); + _scummTimerManager = new DefaultTimerManager(); + _scummMixer = new Audio::Mixer(); + initTimer(); + + sioprintf("Starting SavefileManager\n"); _saveManager = new Ps2SaveFileManager(this, _screen); - sioprintf("Initializing ps2Input"); + sioprintf("Initializing ps2Input\n"); _input = new Ps2Input(this, _useMouse, _useKbd); - ee_sema_t newSema; - newSema.init_count = 1; - newSema.max_count = 1; - _mutexSema = CreateSema(&newSema); - for (int i = 0; i < MAX_MUTEXES; i++) { - _mutex[i].sema = -1; - _mutex[i].count = _mutex[i].owner = 0; - } - _screen->wantAnim(false); - clearScreen(); -} + _screen->clearScreen(); -OSystem_PS2::~OSystem_PS2(void) { + // OSystem::initBackend(); // romeo } -void OSystem_PS2::initBackend() { - // FIXME: Should probably move lots of stuff from the constructor to here - _mixer = new Audio::Mixer(); - _timer = new DefaultTimerManager(); - setSoundCallback(Audio::Mixer::mixCallback, _mixer); - setTimerCallback(&timer_handler, 10); - - OSystem::initBackend(); +OSystem_PS2::~OSystem_PS2(void) { } void OSystem_PS2::initTimer(void) { @@ -394,28 +380,17 @@ void OSystem_PS2::initTimer(void) { T0_COUNT = 0; T0_COMP = CLK_DIVIS; // (BUS_CLOCK / 256) / CLK_DIVIS = 100 T0_MODE = TIMER_MODE( 2, 0, 0, 0, 1, 1, 1, 0, 1, 1); - - DI(); - SifAddCmdHandler(0x12, mass_connect_cb, this); - SifAddCmdHandler(0x13, mass_disconnect_cb, this); - EI(); } void OSystem_PS2::timerThread(void) { while (!_systemQuit) { WaitSema(g_TimerThreadSema); - if (_scummTimerProc) - _scummTimerProc(0); + _scummTimerManager->handler(); } ExitThread(); } void OSystem_PS2::soundThread(void) { - ee_sema_t soundSema; - soundSema.init_count = 1; - soundSema.max_count = 1; - _soundSema = CreateSema(&soundSema); - assert(_soundSema >= 0); int16 *soundBufL = (int16*)memalign(64, SMP_PER_BLOCK * sizeof(int16) * 2); int16 *soundBufR = soundBufL + SMP_PER_BLOCK; @@ -431,55 +406,51 @@ void OSystem_PS2::soundThread(void) { bufferedSamples -= 480; cycles++; - WaitSema(_soundSema); - if (_scummSoundProc) { - if (bufferedSamples <= 8 * SMP_PER_BLOCK) { - // we have to produce more samples, call sound mixer - // the scratchpad at 0x70000000 is used as temporary soundbuffer - _scummSoundProc(_scummSoundParam, (uint8*)0x70000000, SMP_PER_BLOCK * 2 * sizeof(int16)); - - // demux data into 2 buffers, L and R - __asm__ ( - "move $t2, %1\n\t" // dest buffer right - "move $t3, %0\n\t" // dest buffer left - "lui $t8, 0x7000\n\t" // muxed buffer, fixed at 0x70000000 - "addiu $t9, $0, 100\n\t" // number of loops - "mtsab $0, 2\n\t" // set qword shift = 2 byte - - "loop:\n\t" - " lq $t4, 0($t8)\n\t" // load 8 muxed samples - " lq $t5, 16($t8)\n\t" // load 8 more muxed samples - - " qfsrv $t6, $0, $t4\n\t" // shift right for second - " qfsrv $t7, $0, $t5\n\t" // packing step (right channel) - - " ppach $t4, $t5, $t4\n\t" // combine left channel data - " ppach $t6, $t7, $t6\n\t" // right channel data - - " sq $t4, 0($t3)\n\t" // write back - " sq $t6, 0($t2)\n\t" // - - " addiu $t9, -1\n\t" // decrement loop counter - " addiu $t2, 16\n\t" // increment pointers - " addiu $t3, 16\n\t" - " addiu $t8, 32\n\t" - " bnez $t9, loop\n\t" // loop - : // outputs - : "r"(soundBufL), "r"(soundBufR) // inputs - // : "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8", "$t9" // destroyed - : "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25" // destroyed - ); - // and feed it into the SPU - // non-blocking call, the function will return before the buffer's content - // was transferred. - SjPCM_Enqueue((short int*)soundBufL, (short int*)soundBufR, SMP_PER_BLOCK, 0); - bufferedSamples += SMP_PER_BLOCK; - } + if (bufferedSamples <= 8 * SMP_PER_BLOCK) { + // we have to produce more samples, call sound mixer + // the scratchpad at 0x70000000 is used as temporary soundbuffer + //_scummSoundProc(_scummSoundParam, (uint8*)0x70000000, SMP_PER_BLOCK * 2 * sizeof(int16)); + Audio::Mixer::mixCallback(_scummMixer, (byte*)0x70000000, SMP_PER_BLOCK * 2 * sizeof(int16)); + + // demux data into 2 buffers, L and R + __asm__ ( + "move $t2, %1\n\t" // dest buffer right + "move $t3, %0\n\t" // dest buffer left + "lui $t8, 0x7000\n\t" // muxed buffer, fixed at 0x70000000 + "addiu $t9, $0, 100\n\t" // number of loops + "mtsab $0, 2\n\t" // set qword shift = 2 byte + + "loop:\n\t" + " lq $t4, 0($t8)\n\t" // load 8 muxed samples + " lq $t5, 16($t8)\n\t" // load 8 more muxed samples + + " qfsrv $t6, $0, $t4\n\t" // shift right for second + " qfsrv $t7, $0, $t5\n\t" // packing step (right channel) + + " ppach $t4, $t5, $t4\n\t" // combine left channel data + " ppach $t6, $t7, $t6\n\t" // right channel data + + " sq $t4, 0($t3)\n\t" // write back + " sq $t6, 0($t2)\n\t" // + + " addiu $t9, -1\n\t" // decrement loop counter + " addiu $t2, 16\n\t" // increment pointers + " addiu $t3, 16\n\t" + " addiu $t8, 32\n\t" + " bnez $t9, loop\n\t" // loop + : // outputs + : "r"(soundBufL), "r"(soundBufR) // inputs + // : "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8", "$t9" // destroyed + : "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25" // destroyed + ); + // and feed it into the SPU + // non-blocking call, the function will return before the buffer's content + // was transferred. + SjPCM_Enqueue((short int*)soundBufL, (short int*)soundBufR, SMP_PER_BLOCK, 0); + bufferedSamples += SMP_PER_BLOCK; } - SignalSema(_soundSema); } free(soundBufL); - DeleteSema(_soundSema); ExitThread(); } @@ -487,12 +458,16 @@ bool OSystem_PS2::hddPresent(void) { return _useHdd; } -void OSystem_PS2::setUsbMassConnected(bool stat) { - _usbMassConnected = stat; -} - bool OSystem_PS2::usbMassPresent(void) { - return _usbMassConnected; + + if (_usbMassLoaded) { + int testFd = fio.dopen("mass:/"); + if (testFd >= 0) + fio.dclose(testFd); + if (testFd != -ENODEV) + return true; + } + return false; } void OSystem_PS2::initSize(uint width, uint height) { @@ -519,12 +494,9 @@ void OSystem_PS2::copyRectToScreen(const byte *buf, int pitch, int x, int y, int _screen->copyScreenRect((const uint8*)buf, pitch, x, y, w, h); } -Graphics::Surface *OSystem_PS2::lockScreen() { - return _screen->lockScreen(); -} - -void OSystem_PS2::unlockScreen() { - _screen->unlockScreen(); +bool OSystem_PS2::grabRawScreen(Graphics::Surface *surf) { + _screen->grabScreen(surf); + return true; } void OSystem_PS2::updateScreen(void) { @@ -545,7 +517,7 @@ void OSystem_PS2::delayMillis(uint msecs) { int tid = GetThreadId(); if (tid == _soundTid) { - sioprintf("ERROR: delayMillis() from sound thread!"); + dbg_printf("ERROR: delayMillis() from sound thread!\n"); return; } @@ -558,31 +530,16 @@ void OSystem_PS2::delayMillis(uint msecs) { } } -void OSystem_PS2::setTimerCallback(OSystem::TimerProc callback, int interval) { - if (callback && (interval != 10)) - sioprintf("unhandled timer interval: %d\n", interval); - _scummTimerProc = callback; +Common::TimerManager *OSystem_PS2::getTimerManager() { + return _scummTimerManager; } int OSystem_PS2::getOutputSampleRate(void) const { return 48000; } -bool OSystem_PS2::setSoundCallback(SoundProc proc, void *param) { - assert(proc != NULL); - - WaitSema(_soundSema); - _scummSoundProc = proc; - _scummSoundParam = param; - SignalSema(_soundSema); - return true; -} - -void OSystem_PS2::clearSoundCallback(void) { - WaitSema(_soundSema); - _scummSoundProc = NULL; - _scummSoundParam = NULL; - SignalSema(_soundSema); +Audio::Mixer *OSystem_PS2::getMixer() { + return _scummMixer; } Common::SaveFileManager *OSystem_PS2::getSavefileManager(void) { @@ -646,6 +603,14 @@ void OSystem_PS2::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, i _screen->copyOverlayRect((uint16*)buf, (uint16)pitch, (uint16)x, (uint16)y, (uint16)w, (uint16)h); } +Graphics::Surface *OSystem_PS2::lockScreen() { + return _screen->lockScreen(); +} + +void OSystem_PS2::unlockScreen() { + _screen->unlockScreen(); +} + const OSystem::GraphicsMode OSystem_PS2::_graphicsMode = { NULL, NULL, 0 }; const OSystem::GraphicsMode *OSystem_PS2::getSupportedGraphicsModes(void) const { @@ -710,7 +675,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) @@ -739,41 +704,45 @@ void OSystem_PS2::msgPrintf(int millis, char *format, ...) { } void OSystem_PS2::powerOffCallback(void) { - sioprintf("powerOffCallback"); + sioprintf("powerOffCallback\n"); _saveManager->quit(); if (_useHdd) { - sioprintf("umount"); + sioprintf("umount\n"); fio.umount("pfs0:"); } - sioprintf("fxio"); + sioprintf("fxio\n"); // enable blocking FXIO so libhdd will correctly close drive, etc. fileXioSetBlockMode(FXIO_WAIT); - sioprintf("done"); + sioprintf("done\n"); } void OSystem_PS2::quit(void) { + sioprintf("OSystem_PS2::quit called\n"); if (_bootDevice == HOST) { - printf("OSystem_PS2::quit\n"); + sioprintf("OSystem_PS2::quit (HOST)\n"); SleepThread(); } else { - sioprintf("OSystem_PS2::quit"); + sioprintf("OSystem_PS2::quit (bootdev=%d)\n", _bootDevice); if (_useHdd) { driveStandby(); fio.umount("pfs0:"); } - clearSoundCallback(); - setTimerCallback(NULL, 0); + //clearSoundCallback(); + //setTimerCallback(NULL, 0); _screen->wantAnim(false); _systemQuit = true; ee_thread_t statSound, statTimer; + sioprintf("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"); DeleteThread(_timerTid); DeleteThread(_soundTid); free(_timerStack); free(_soundStack); + sioprintf("Stopping timer\n"); DisableIntc(INT_TIMER0); RemoveIntcHandler(INT_TIMER0, _intrId); @@ -782,7 +751,7 @@ void OSystem_PS2::quit(void) { padEnd(); // stop pad library cdvdInit(CDVD_EXIT); - sioprintf("resetting iop"); + sioprintf("resetting iop\n"); SifIopReset(NULL, 0); SifExitRpc(); while (!SifIopSync()); @@ -791,7 +760,7 @@ void OSystem_PS2::quit(void) { SifExitRpc(); FlushCache(0); SifLoadFileExit(); - sioprintf("Restarting ScummVM"); + sioprintf("Restarting ScummVM\n"); LoadExecPS2("cdrom0:\\SCUMMVM.ELF", 0, NULL); // resets the console and executes the ELF } } @@ -800,7 +769,7 @@ void OSystem_PS2::makeConfigPath(char *dest) { FILE *handle; strcpy(dest, "cdfs:/ScummVM.ini"); handle = ps2_fopen(dest, "r"); - if (_usbMassConnected && !handle) { + if (usbMassPresent() && !handle) { strcpy(dest, "mass:/ScummVM.ini"); handle = ps2_fopen(dest, "r"); } @@ -810,4 +779,7 @@ void OSystem_PS2::makeConfigPath(char *dest) { strcpy(dest, "mc0:ScummVM/scummvm.ini"); } +bool OSystem_PS2::runningFromHost(void) { + return (_bootDevice == HOST); +} diff --git a/backends/platform/ps2/systemps2.h b/backends/platform/ps2/systemps2.h index beae62dc0e..9dbe9be553 100644 --- a/backends/platform/ps2/systemps2.h +++ b/backends/platform/ps2/systemps2.h @@ -28,13 +28,13 @@ #include "common/system.h" +class DefaultTimerManager; + class Gs2dScreen; class Ps2Input; class Ps2SaveFileManager; struct IrxReference; -extern void sioprintf(const char *zFormat, ...); - #define MAX_MUTEXES 16 struct Ps2Mutex { @@ -43,21 +43,29 @@ struct Ps2Mutex { int count; }; +namespace Common { + class TimerManager; +}; + +namespace Audio { + class Mixer; +}; + class OSystem_PS2 : public OSystem { public: OSystem_PS2(const char *elfPath); virtual ~OSystem_PS2(void); - - virtual void initBackend(); - virtual void initSize(uint width, uint height); + void init(void); + virtual int16 getHeight(void); virtual int16 getWidth(void); virtual void setPalette(const byte *colors, uint start, uint num); virtual void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h); virtual void setShakePos(int shakeOffset); virtual void grabPalette(byte *colors, uint start, uint num); + virtual bool grabRawScreen(Graphics::Surface *surf); virtual Graphics::Surface *lockScreen(); virtual void unlockScreen(); virtual void updateScreen(); @@ -75,11 +83,10 @@ public: virtual uint32 getMillis(); virtual void delayMillis(uint msecs); - virtual void setTimerCallback(TimerProc callback, int interval); + virtual Common::TimerManager *getTimerManager(); virtual bool pollEvent(Common::Event &event); - virtual bool setSoundCallback(SoundProc proc, void *param); - virtual void clearSoundCallback(); + virtual Audio::Mixer *getMixer(); virtual int getOutputSampleRate(void) const; virtual bool openCD(int drive); @@ -105,8 +112,8 @@ public: virtual void colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b); virtual Common::SaveFileManager *getSavefileManager(); - virtual Audio::Mixer *getMixer() { return _mixer; } - virtual Common::TimerManager *getTimerManager() { return _timer; } + + virtual void getTimeAndDate(struct tm &t) const; void timerThread(void); void soundThread(void); @@ -116,25 +123,23 @@ public: void powerOffCallback(void); bool hddPresent(void); bool usbMassPresent(void); - void setUsbMassConnected(bool stat); + bool runningFromHost(void); private: void startIrxModules(int numModules, IrxReference *modules); - volatile OSystem::TimerProc _scummTimerProc; - volatile OSystem::SoundProc _scummSoundProc; - void *_scummSoundParam; - int _soundSema; - + void initMutexes(void); void initTimer(void); void readRtcTime(void); + DefaultTimerManager *_scummTimerManager; + Audio::Mixer *_scummMixer; + + bool _mouseVisible; - bool _useMouse, _useKbd, _useHdd, _usbMassLoaded, _usbMassConnected; + bool _useMouse, _useKbd, _useHdd, _usbMassLoaded; Ps2SaveFileManager *_saveManager; - Audio::Mixer *_mixer; - Common::TimerManager *_timer; Gs2dScreen *_screen; Ps2Input *_input; diff --git a/common/system.cpp b/common/system.cpp index 77cfe17e95..05c56bdd52 100644 --- a/common/system.cpp +++ b/common/system.cpp @@ -125,8 +125,11 @@ void OSystem::clearScreen() { } void OSystem::getTimeAndDate(struct tm &t) const { +#ifndef __PLAYSTATION2__ + // PS2SDK doesn't provide localtime, so this code doesn't compile time_t curTime = time(0); t = *localtime(&curTime); +#endif } /* diff --git a/graphics/mpeg_player.h b/graphics/mpeg_player.h index b0192bc8b4..1c975825a8 100644 --- a/graphics/mpeg_player.h +++ b/graphics/mpeg_player.h @@ -33,6 +33,12 @@ #ifdef USE_MPEG2 +#ifdef __PLAYSTATION2__ +typedef uint8 uint8_t; +typedef uint16 uint16_t; +typedef uint32 uint32_t; +#endif + #if !defined(_MSC_VER) #ifndef PALMOS_MODE # include <inttypes.h> |