From a5aa5c0d73fa3c9faec0ba167cb88d3595f089e5 Mon Sep 17 00:00:00 2001 From: Marcus Comstedt Date: Sun, 10 Aug 2003 20:49:13 +0000 Subject: [PATCH] Harmonized SaveFile API with File API a bit. svn-id: r9626 --- backends/PalmOS/Src/palmsave.cpp | 24 +++--- backends/dc/vmsave.cpp | 17 ++-- common/module.mk | 3 +- common/savefile.cpp | 131 +++++++++++++++++++++++++++++++ common/savefile.h | 42 +++++++--- scumm/saveload.cpp | 45 +++++------ 6 files changed, 202 insertions(+), 60 deletions(-) create mode 100644 common/savefile.cpp diff --git a/backends/PalmOS/Src/palmsave.cpp b/backends/PalmOS/Src/palmsave.cpp index b19e8494f49..224a5c12a75 100644 --- a/backends/PalmOS/Src/palmsave.cpp +++ b/backends/PalmOS/Src/palmsave.cpp @@ -36,10 +36,9 @@ public: ~PalmSaveFile(); bool is_open() { return file != NULL; } +protected: int fread(void *buf, int size, int cnt); - int fwrite(void *buf, int size, int cnt); -// must be removed - int feof() { return ::feof(file); } + int fwrite(const void *buf, int size, int cnt); private : FILE *file; @@ -71,7 +70,7 @@ int PalmSaveFile::fread(void *buf, int size, int cnt) { return ::fread(buf, size, cnt, file); } -int PalmSaveFile::fwrite(void *buf, int size, int cnt) { +int PalmSaveFile::fwrite(const void *buf, int size, int cnt) { UInt32 fullsize = size*cnt; if (fullsize <= MAX_BLOCK) @@ -104,8 +103,12 @@ public: void list_savefiles(const char *prefix, bool *marks, int num); }; -SaveFile *PalmSaveFileManager::open_savefile(const char *filename, bool saveOrLoad) { - PalmSaveFile *sf = new PalmSaveFile(filename, (saveOrLoad? "wb":"rb")); +SaveFile *PalmSaveFileManager::open_savefile(const char *filename, const char *dirname, bool saveOrLoad) { + char buf[256]; + + join_paths(filename, dirname, buf, sizeof(buf)); + + PalmSaveFile *sf = new PalmSaveFile(buf, (saveOrLoad? "wb":"rb")); if(!sf->is_open()) { delete sf; @@ -115,21 +118,20 @@ SaveFile *PalmSaveFileManager::open_savefile(const char *filename, bool saveOrLo return sf; } -void PalmSaveFileManager::list_savefiles(const char *prefix, bool *marks, int num) { +void PalmSaveFileManager::list_savefiles(const char *prefix, const char *direcory, bool *marks, int num) { FileRef fileRef; // try to open the dir - Err e = VFSFileOpen(gVars->volRefNum, SCUMMVM_SAVEPATH, vfsModeRead, &fileRef); + Err e = VFSFileOpen(gVars->volRefNum, directory, vfsModeRead, &fileRef); memset(marks, false, num*sizeof(bool)); if (e != errNone) return; // enumerate all files - Char *nameonly = strrchr(prefix,'/') + 1; UInt32 dirEntryIterator = vfsIteratorStart; Char filename[32]; FileInfoType info = {0, filename, 32}; - UInt16 length = StrLen(nameonly); + UInt16 length = StrLen(prefix); int slot = 0; while (dirEntryIterator != vfsIteratorStop) { @@ -138,7 +140,7 @@ void PalmSaveFileManager::list_savefiles(const char *prefix, bool *marks, int nu if (e != expErrEnumerationEmpty) { // there is something if (StrLen(info.nameP) == (length + 2)) { // consider max 99, filename length is ok - if (StrNCaselessCompare(nameonly, info.nameP, length) == 0) { // this seems to be a save file + if (StrNCaselessCompare(prefix, info.nameP, length) == 0) { // this seems to be a save file if (isdigit(info.nameP[length]) && isdigit(info.nameP[length+1])) { slot = StrAToI(filename + length); diff --git a/backends/dc/vmsave.cpp b/backends/dc/vmsave.cpp index fa2c2f566f9..8eaf06f83c2 100644 --- a/backends/dc/vmsave.cpp +++ b/backends/dc/vmsave.cpp @@ -224,6 +224,10 @@ private: int pos, size; char filename[16]; +protected: + virtual int fread(void *buf, int size, int cnt); + virtual int fwrite(const void *buf, int size, int cnt); + public: VMSave(const char *_filename, bool _saveOrLoad) : issave(_saveOrLoad), pos(0), buffer(NULL) @@ -235,9 +239,6 @@ public: ~VMSave(); - virtual int fread(void *buf, int size, int cnt); - virtual int fwrite(void *buf, int size, int cnt); - bool readSaveGame() { return ::readSaveGame(buffer, size, filename); } @@ -257,11 +258,11 @@ public: }; class VMSaveManager : public SaveFileManager { - virtual SaveFile *open_savefile(const char *filename, bool saveOrLoad); - virtual void list_savefiles(const char *prefix, bool *marks, int num); + virtual SaveFile *open_savefile(const char *filename, const char *directory, bool saveOrLoad); + virtual void list_savefiles(const char *prefix, const char *directory, bool *marks, int num); }; -SaveFile *VMSaveManager::open_savefile(const char *filename, +SaveFile *VMSaveManager::open_savefile(const char *filename, const char *directory, bool saveOrLoad) { VMSave *s = new VMSave(filename, saveOrLoad); @@ -314,7 +315,7 @@ int VMSave::fread(void *buf, int sz, int cnt) return cnt; } -int VMSave::fwrite(void *buf, int sz, int cnt) +int VMSave::fwrite(const void *buf, int sz, int cnt) { if (!issave) return -1; @@ -331,7 +332,7 @@ int VMSave::fwrite(void *buf, int sz, int cnt) } -void VMSaveManager::list_savefiles(const char *prefix, +void VMSaveManager::list_savefiles(const char *prefix, const char *directory, bool *marks, int num) { memset(marks, false, num*sizeof(bool)); diff --git a/common/module.mk b/common/module.mk index 56092b637c6..e0e898335f0 100644 --- a/common/module.mk +++ b/common/module.mk @@ -8,7 +8,8 @@ MODULE_OBJS = \ common/scaler.o \ common/str.o \ common/timer.o \ - common/util.o + common/util.o \ + common/savefile.o # Include common rules include common.rules diff --git a/common/savefile.cpp b/common/savefile.cpp new file mode 100644 index 00000000000..7d99f0e5d3e --- /dev/null +++ b/common/savefile.cpp @@ -0,0 +1,131 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2002-2003 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "common/savefile.h" +#include "common/util.h" +#include "common/engine.h" // For debug/warning/error + +uint32 SaveFile::read(void *ptr, uint32 size) +{ + return fread(ptr, 1, size); +} + +byte SaveFile::readByte() +{ + byte b; + if (fread(&b, 1, 1) != 1) + return 0; + return b; +} + +uint16 SaveFile::readUint16LE() { + uint16 a = readByte(); + uint16 b = readByte(); + return a | (b << 8); +} + +uint32 SaveFile::readUint32LE() { + uint32 a = readUint16LE(); + uint32 b = readUint16LE(); + return (b << 16) | a; +} + +uint16 SaveFile::readUint16BE() { + uint16 b = readByte(); + uint16 a = readByte(); + return a | (b << 8); +} + +uint32 SaveFile::readUint32BE() { + uint32 b = readUint16BE(); + uint32 a = readUint16BE(); + return (b << 16) | a; +} + +uint32 SaveFile::write(const void *ptr, uint32 size) +{ + return fwrite(ptr, 1, size); +} + +void SaveFile::writeByte(byte value) +{ + fwrite(&value, 1, 1); +} + +void SaveFile::writeUint16LE(uint16 value) { + writeByte((byte)(value & 0xff)); + writeByte((byte)(value >> 8)); +} + +void SaveFile::writeUint32LE(uint32 value) { + writeUint16LE((uint16)(value & 0xffff)); + writeUint16LE((uint16)(value >> 16)); +} + +void SaveFile::writeUint16BE(uint16 value) { + writeByte((byte)(value >> 8)); + writeByte((byte)(value & 0xff)); +} + +void SaveFile::writeUint32BE(uint32 value) { + writeUint16BE((uint16)(value >> 16)); + writeUint16BE((uint16)(value & 0xffff)); +} + +SaveFile *SaveFileManager::open_savefile(const char *filename, const char *directory, bool saveOrLoad) +{ + char buf[256]; + join_paths(filename, directory, buf, sizeof(buf)); + StdioSaveFile *sf = new StdioSaveFile(buf, + (saveOrLoad? "wb":"rb")); + if (!sf->is_open()) { + delete sf; + sf = NULL; + } + return sf; +} + +void SaveFileManager::join_paths(const char *filename, const char *directory, + char *buf, int bufsize) +{ + buf[bufsize-1] = '\0'; + strncpy(buf, directory, bufsize-1); + +#ifdef WIN32 + // Fix for Win98 issue related with game directory pointing to root drive ex. "c:\" + if ((buf[0] != 0) && (buf[1] == ':') && (buf[2] == '\\') && (buf[3] == 0)) { + buf[2] = 0; + } +#endif + + const int dirLen = strlen(buf); + + if (dirLen > 0) { +#ifdef __MORPHOS__ + if (buf[dirLen-1] != ':' && buf[dirLen-1] != '/') +#endif + +#if !defined(__GP32__) && !defined(__PALM_OS__) + strncat(buf, "/", bufsize-1); // prevent double / +#endif + } + strncat(buf, filename, bufsize-1); +} diff --git a/common/savefile.h b/common/savefile.h index 3f8afb5a8cd..31271c656df 100644 --- a/common/savefile.h +++ b/common/savefile.h @@ -23,14 +23,34 @@ #ifndef COMMON_SAVEFILE_H #define COMMON_SAVEFILE_H +#include "stdafx.h" +#include "common/scummsys.h" + #include #include class SaveFile { public: virtual ~SaveFile() {} + + /* Compatible with File API */ + uint32 read(void *ptr, uint32 size); + byte readByte(); + uint16 readUint16LE(); + uint32 readUint32LE(); + uint16 readUint16BE(); + uint32 readUint32BE(); + uint32 write(const void *ptr, uint32 size); + void writeByte(byte value); + void writeUint16LE(uint16 value); + void writeUint32LE(uint32 value); + void writeUint16BE(uint16 value); + void writeUint32BE(uint32 value); + +protected: + /* Only for internal use, use File compatible API above instead */ virtual int fread(void *buf, int size, int cnt) = 0; - virtual int fwrite(void *buf, int size, int cnt) = 0; + virtual int fwrite(const void *buf, int size, int cnt) = 0; }; class StdioSaveFile : public SaveFile { @@ -45,10 +65,10 @@ public: bool is_open() { return fh != NULL; } - +protected: int fread(void *buf, int size, int cnt) { return ::fread(buf, size, cnt, fh); } - int fwrite(void *buf, int size, int cnt) + int fwrite(const void *buf, int size, int cnt) { return ::fwrite(buf, size, cnt, fh); } }; @@ -57,20 +77,16 @@ class SaveFileManager { public: virtual ~SaveFileManager() {} - virtual SaveFile *open_savefile(const char *filename, bool saveOrLoad) { - StdioSaveFile *sf = new StdioSaveFile(filename, - (saveOrLoad? "wb":"rb")); - if (!sf->is_open()) { - delete sf; - sf = NULL; - } - return sf; - } + virtual SaveFile *open_savefile(const char *filename, const char *directory, bool saveOrLoad); - virtual void list_savefiles(const char * /* prefix */, bool *marks, int num) { + virtual void list_savefiles(const char * /* prefix */, const char *directory, bool *marks, int num) { memset(marks, true, num * sizeof(bool)); } +protected: + void join_paths(const char *filename, const char *directory, + char *buf, int bufsize); + }; #endif diff --git a/scumm/saveload.cpp b/scumm/saveload.cpp index 56eb2fb39e0..85194f4b815 100644 --- a/scumm/saveload.cpp +++ b/scumm/saveload.cpp @@ -61,7 +61,7 @@ bool Scumm::saveState(int slot, bool compat, SaveFileManager *mgr) { makeSavegameName(filename, slot, compat); - if (!(out = mgr->open_savefile(filename, true))) + if (!(out = mgr->open_savefile(filename, getSavePath(), true))) return false; memcpy(hdr.name, _saveLoadName, sizeof(hdr.name)); @@ -70,7 +70,7 @@ bool Scumm::saveState(int slot, bool compat, SaveFileManager *mgr) { hdr.size = 0; hdr.ver = TO_LE_32(CURRENT_VER); - out->fwrite(&hdr, sizeof(hdr), 1); + out->write(&hdr, sizeof(hdr)); Serializer ser(out, true, CURRENT_VER); saveOrLoad(&ser, CURRENT_VER); @@ -88,10 +88,10 @@ bool Scumm::loadState(int slot, bool compat, SaveFileManager *mgr) { byte *roomptr; makeSavegameName(filename, slot, compat); - if (!(out = mgr->open_savefile(filename, false))) + if (!(out = mgr->open_savefile(filename, getSavePath(), false))) return false; - out->fread(&hdr, sizeof(hdr), 1); + out->read(&hdr, sizeof(hdr)); if (hdr.type != MKID('SCVM')) { warning("Invalid savegame '%s'", filename); delete out; @@ -221,12 +221,11 @@ bool Scumm::loadState(int slot, bool compat, SaveFileManager *mgr) { } void Scumm::makeSavegameName(char *out, int slot, bool compatible) { - const char *dir = getSavePath(); #ifndef __PALM_OS__ - sprintf(out, "%s%s.%c%.2d", dir, _game_name, compatible ? 'c' : 's', slot); + sprintf(out, "%s.%c%.2d", _game_name, compatible ? 'c' : 's', slot); #else - sprintf(out, "%s%s.%s%.2d", dir, _game_name, compatible ? "c" : "s", slot); + sprintf(out, "%s.%s%.2d", _game_name, compatible ? "c" : "s", slot); #endif } @@ -234,7 +233,7 @@ void Scumm::listSavegames(bool *marks, int num, SaveFileManager *mgr) { char prefix[256]; makeSavegameName(prefix, 99, false); prefix[strlen(prefix)-2] = 0; - mgr->list_savefiles(prefix, marks, num); + mgr->list_savefiles(prefix, getSavePath(), marks, num); } bool Scumm::getSavegameName(int slot, char *desc, SaveFileManager *mgr) { @@ -244,14 +243,14 @@ bool Scumm::getSavegameName(int slot, char *desc, SaveFileManager *mgr) { int len; makeSavegameName(filename, slot, false); - if (!(out = mgr->open_savefile(filename, false))) { + if (!(out = mgr->open_savefile(filename, getSavePath(), false))) { strcpy(desc, ""); return false; } - len = out->fread(&hdr, sizeof(hdr), 1); + len = out->read(&hdr, sizeof(hdr)); delete out; - if (len != 1 || hdr.type != MKID('SCVM')) { + if (len != sizeof(hdr) || hdr.type != MKID('SCVM')) { strcpy(desc, "Invalid savegame"); return false; } @@ -710,43 +709,35 @@ void Scumm::saveLoadResource(Serializer *ser, int type, int idx) { } void Serializer::saveBytes(void *b, int len) { - _saveLoadStream->fwrite(b, 1, len); + _saveLoadStream->write(b, len); } void Serializer::loadBytes(void *b, int len) { - _saveLoadStream->fread(b, 1, len); + _saveLoadStream->read(b, len); } void Serializer::saveUint32(uint32 d) { - uint32 e = FROM_LE_32(d); - saveBytes(&e, 4); + _saveLoadStream->writeUint32LE(d); } void Serializer::saveWord(uint16 d) { - uint16 e = FROM_LE_16(d); - saveBytes(&e, 2); + _saveLoadStream->writeUint16LE(d); } void Serializer::saveByte(byte b) { - saveBytes(&b, 1); + _saveLoadStream->writeByte(b); } uint32 Serializer::loadUint32() { - uint32 e; - loadBytes(&e, 4); - return FROM_LE_32(e); + return _saveLoadStream->readUint32LE(); } uint16 Serializer::loadWord() { - uint16 e; - loadBytes(&e, 2); - return FROM_LE_16(e); + return _saveLoadStream->readUint16LE(); } byte Serializer::loadByte() { - byte e; - loadBytes(&e, 1); - return e; + return _saveLoadStream->readByte(); } void Serializer::saveArrayOf(void *b, int len, int datasize, byte filetype) {