aboutsummaryrefslogtreecommitdiff
path: root/backends/platform/ps2/savefile.cpp
diff options
context:
space:
mode:
authorRobert Göffringmann2008-03-03 00:41:59 +0000
committerRobert Göffringmann2008-03-03 00:41:59 +0000
commit3b27b9fa438611c3a05fcf2d07a3dfde6be192fa (patch)
tree8605c47d67b779fb33ce4dda3a64a7d3caecdb4d /backends/platform/ps2/savefile.cpp
parentfc91de07dfdfe6bd29edadf739f324f30f5624d0 (diff)
downloadscummvm-rg350-3b27b9fa438611c3a05fcf2d07a3dfde6be192fa.tar.gz
scummvm-rg350-3b27b9fa438611c3a05fcf2d07a3dfde6be192fa.tar.bz2
scummvm-rg350-3b27b9fa438611c3a05fcf2d07a3dfde6be192fa.zip
the ps2 changes from the 0.11.1 release, plus some bugfixes and cleanup.
svn-id: r31034
Diffstat (limited to 'backends/platform/ps2/savefile.cpp')
-rw-r--r--backends/platform/ps2/savefile.cpp815
1 files changed, 137 insertions, 678 deletions
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;
+}