New savefile backend system (bye bye NONSTANDARD_SAVE...)
svn-id: r6007
This commit is contained in:
parent
fadf55aad0
commit
83da387eef
12 changed files with 314 additions and 132 deletions
|
@ -6,7 +6,7 @@ VPATH = ../..
|
||||||
|
|
||||||
CXX = sh-elf-g++ -ml -m4-single-only
|
CXX = sh-elf-g++ -ml -m4-single-only
|
||||||
CXXFLAGS= -O1 -Wno-multichar
|
CXXFLAGS= -O1 -Wno-multichar
|
||||||
DEFINES = -D__DC__ -DNONSTANDARD_PORT -DNONSTANDARD_SAVE
|
DEFINES = -D__DC__ -DNONSTANDARD_PORT
|
||||||
LDFLAGS := -Wl,-Ttext,0x8c010000 -nostartfiles ronin/crt0.o
|
LDFLAGS := -Wl,-Ttext,0x8c010000 -nostartfiles ronin/crt0.o
|
||||||
INCLUDES:= -I./ -I../.. -I../../common
|
INCLUDES:= -I./ -I../.. -I../../common
|
||||||
CPPFLAGS= $(DEFINES) $(INCLUDES)
|
CPPFLAGS= $(DEFINES) $(INCLUDES)
|
||||||
|
|
|
@ -84,6 +84,9 @@ class OSystem_Dreamcast : public OSystem {
|
||||||
virtual void unlock_mutex(void *mutex);
|
virtual void unlock_mutex(void *mutex);
|
||||||
virtual void delete_mutex(void *mutex);
|
virtual void delete_mutex(void *mutex);
|
||||||
|
|
||||||
|
// Savefile handling
|
||||||
|
virtual SaveFileManager *get_savefile_manager();
|
||||||
|
|
||||||
|
|
||||||
static OSystem *create();
|
static OSystem *create();
|
||||||
|
|
||||||
|
|
|
@ -155,6 +155,33 @@ static bool tryLoad(char *&buffer, int &size, const char *filename, int vm)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tryList(const char *prefix, bool *marks, int num, int vm)
|
||||||
|
{
|
||||||
|
struct vmsinfo info;
|
||||||
|
struct superblock super;
|
||||||
|
struct dir_iterator iter;
|
||||||
|
struct dir_entry de;
|
||||||
|
int pl = strlen(prefix);
|
||||||
|
|
||||||
|
if(!vmsfs_check_unit(vm, 0, &info))
|
||||||
|
return;
|
||||||
|
if(!vmsfs_get_superblock(&info, &super))
|
||||||
|
return;
|
||||||
|
vmsfs_open_dir(&super, &iter);
|
||||||
|
while(vmsfs_next_dir_entry(&iter, &de))
|
||||||
|
if(de.entry[0]) {
|
||||||
|
char buf[16], *endp = NULL;
|
||||||
|
strncpy(buf, (char *)de.entry+4, 12);
|
||||||
|
buf[12] = 0;
|
||||||
|
int l = strlen(buf);
|
||||||
|
long i = 42;
|
||||||
|
if(l > pl && !strncmp(buf, prefix, pl) &&
|
||||||
|
(i = strtol(buf+pl, &endp, 10))>=0 && i<num &&
|
||||||
|
(endp - buf) == l)
|
||||||
|
marks[i] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
vmsaveResult writeSaveGame(const char *gamename, const char *data, int size,
|
vmsaveResult writeSaveGame(const char *gamename, const char *data, int size,
|
||||||
const char *filename, class Icon &icon)
|
const char *filename, class Icon &icon)
|
||||||
{
|
{
|
||||||
|
@ -190,104 +217,130 @@ bool readSaveGame(char *&buffer, int &size, const char *filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct vmStreamContext {
|
class VMSave : public SaveFile {
|
||||||
|
private:
|
||||||
bool issave;
|
bool issave;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
int pos, size;
|
int pos, size;
|
||||||
char filename[16];
|
char filename[16];
|
||||||
};
|
|
||||||
|
|
||||||
bool SerializerStream::fopen(const char *filename, const char *mode)
|
public:
|
||||||
{
|
VMSave(const char *_filename, bool _saveOrLoad)
|
||||||
vmStreamContext *c = new vmStreamContext;
|
: issave(_saveOrLoad), pos(0), buffer(NULL)
|
||||||
context = c;
|
{
|
||||||
if(strchr(mode, 'w')) {
|
strncpy(filename, _filename, 16);
|
||||||
c->issave = true;
|
if(issave)
|
||||||
strncpy(c->filename, filename, 16);
|
buffer = new char[size = MAX_SAVE_SIZE];
|
||||||
c->pos = 0;
|
}
|
||||||
c->buffer = new char[c->size = MAX_SAVE_SIZE];
|
|
||||||
return true;
|
~VMSave();
|
||||||
} else if(readSaveGame(c->buffer, c->size, filename)) {
|
|
||||||
if(c->size > 0 && c->buffer[0] != 'S') {
|
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); }
|
||||||
|
|
||||||
|
void tryUncompress()
|
||||||
|
{
|
||||||
|
if(size > 0 && buffer[0] != 'S') {
|
||||||
// Data does not start with "SCVM". Maybe compressed?
|
// Data does not start with "SCVM". Maybe compressed?
|
||||||
char *expbuf = new char[MAX_SAVE_SIZE];
|
char *expbuf = new char[MAX_SAVE_SIZE];
|
||||||
unsigned long destlen = MAX_SAVE_SIZE;
|
unsigned long destlen = MAX_SAVE_SIZE;
|
||||||
if(!uncompress((Bytef*)expbuf, &destlen, (Bytef*)c->buffer, c->size)) {
|
if(!uncompress((Bytef*)expbuf, &destlen, (Bytef*)buffer, size)) {
|
||||||
delete(c->buffer);
|
delete(buffer);
|
||||||
c->buffer = expbuf;
|
buffer = expbuf;
|
||||||
c->size = destlen;
|
size = destlen;
|
||||||
} else delete expbuf;
|
} else delete expbuf;
|
||||||
}
|
}
|
||||||
c->issave = false;
|
}
|
||||||
c->pos = 0;
|
};
|
||||||
return true;
|
|
||||||
|
class VMSaveManager : public SaveFileManager {
|
||||||
|
virtual SaveFile *open_savefile(const char *filename, bool saveOrLoad);
|
||||||
|
virtual void list_savefiles(const char *prefix, bool *marks, int num);
|
||||||
|
};
|
||||||
|
|
||||||
|
SaveFile *VMSaveManager::open_savefile(const char *filename,
|
||||||
|
bool saveOrLoad)
|
||||||
|
{
|
||||||
|
VMSave *s = new VMSave(filename, saveOrLoad);
|
||||||
|
if(saveOrLoad)
|
||||||
|
return s;
|
||||||
|
else if(s->readSaveGame()) {
|
||||||
|
s->tryUncompress();
|
||||||
|
return s;
|
||||||
} else {
|
} else {
|
||||||
delete c;
|
delete s;
|
||||||
context = NULL;
|
return NULL;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerStream::fclose()
|
VMSave::~VMSave()
|
||||||
{
|
{
|
||||||
extern const char *gGameName;
|
extern const char *gGameName;
|
||||||
extern Icon icon;
|
extern Icon icon;
|
||||||
|
|
||||||
if(context) {
|
if(issave) {
|
||||||
vmStreamContext *c = (vmStreamContext *)context;
|
if(pos) {
|
||||||
if(c->issave) {
|
// Try compression
|
||||||
if(c->pos) {
|
char *compbuf = new char[pos];
|
||||||
// Try compression
|
unsigned long destlen = pos;
|
||||||
char *compbuf = new char[c->pos];
|
if(!compress((Bytef*)compbuf, &destlen, (Bytef*)buffer, pos)) {
|
||||||
unsigned long destlen = c->pos;
|
delete buffer;
|
||||||
if(!compress((Bytef*)compbuf, &destlen, (Bytef*)c->buffer, c->pos)) {
|
buffer = compbuf;
|
||||||
delete c->buffer;
|
pos = destlen;
|
||||||
c->buffer = compbuf;
|
} else delete compbuf;
|
||||||
c->pos = destlen;
|
|
||||||
} else delete compbuf;
|
|
||||||
}
|
|
||||||
displaySaveResult(writeSaveGame(gGameName, c->buffer,
|
|
||||||
c->pos, c->filename, icon));
|
|
||||||
}
|
}
|
||||||
delete c->buffer;
|
displaySaveResult(writeSaveGame(gGameName, buffer,
|
||||||
delete c;
|
pos, filename, icon));
|
||||||
context = NULL;
|
|
||||||
}
|
}
|
||||||
|
delete buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SerializerStream::fread(void *buf, int size, int cnt)
|
int VMSave::fread(void *buf, int sz, int cnt)
|
||||||
{
|
{
|
||||||
vmStreamContext *c = (vmStreamContext *)context;
|
if (issave)
|
||||||
|
|
||||||
if (!c || c->issave)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
int nbyt = size*cnt;
|
int nbyt = sz*cnt;
|
||||||
if (c->pos + nbyt > c->size) {
|
if (pos + nbyt > size) {
|
||||||
cnt = (c->size - c->pos)/size;
|
cnt = (size - pos)/sz;
|
||||||
nbyt = size*cnt;
|
nbyt = sz*cnt;
|
||||||
}
|
}
|
||||||
if (nbyt)
|
if (nbyt)
|
||||||
memcpy(buf, c->buffer + c->pos, nbyt);
|
memcpy(buf, buffer + pos, nbyt);
|
||||||
c->pos += nbyt;
|
pos += nbyt;
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SerializerStream::fwrite(void *buf, int size, int cnt)
|
int VMSave::fwrite(void *buf, int sz, int cnt)
|
||||||
{
|
{
|
||||||
vmStreamContext *c = (vmStreamContext *)context;
|
if (!issave)
|
||||||
|
|
||||||
if (!c || !c->issave)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
int nbyt = size*cnt;
|
int nbyt = sz*cnt;
|
||||||
if (c->pos + nbyt > c->size) {
|
if (pos + nbyt > size) {
|
||||||
cnt = (c->size - c->pos)/size;
|
cnt = (size - pos)/sz;
|
||||||
nbyt = size*cnt;
|
nbyt = sz*cnt;
|
||||||
}
|
}
|
||||||
if (nbyt)
|
if (nbyt)
|
||||||
memcpy(c->buffer + c->pos, buf, nbyt);
|
memcpy(buffer + pos, buf, nbyt);
|
||||||
c->pos += nbyt;
|
pos += nbyt;
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void VMSaveManager::list_savefiles(const char *prefix,
|
||||||
|
bool *marks, int num)
|
||||||
|
{
|
||||||
|
memset(marks, false, num*sizeof(bool));
|
||||||
|
|
||||||
|
for(int i=0; i<24; i++)
|
||||||
|
tryList(prefix, marks, num, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveFileManager *OSystem_Dreamcast::get_savefile_manager()
|
||||||
|
{
|
||||||
|
return new VMSaveManager();
|
||||||
|
}
|
||||||
|
|
|
@ -1221,26 +1221,47 @@ extern "C" int write(int fd, void *p, size_t n);
|
||||||
int write(int fd, void *p, size_t n) { return 0; } //ph0x hack!
|
int write(int fd, void *p, size_t n) { return 0; } //ph0x hack!
|
||||||
|
|
||||||
// fixme - unnecessary?
|
// fixme - unnecessary?
|
||||||
int SerializerStream::fwrite(void *buf, int size, int cnt) {
|
class GP32SaveFile : public SaveFile {
|
||||||
// implement me
|
private:
|
||||||
return ::fwrite(buf, size, cnt, (FILE*)context);
|
FILE *fh;
|
||||||
|
public:
|
||||||
|
GP32SaveFile(FILE *f) : fh(f) { }
|
||||||
|
|
||||||
|
~GP32SaveFile();
|
||||||
|
|
||||||
|
int fread(void *buf, int size, int cnt);
|
||||||
|
int fwrite(void *buf, int size, int cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SerializerStream::fopen(const char *filename, const char *mode) {
|
class GP32SaveFileManager : public SaveFileManager {
|
||||||
// implement me
|
SaveFile *open_savefile(const char *filename, bool saveOrLoad);
|
||||||
(FILE*)context = ::fopen(filename, mode);
|
|
||||||
//if (tolower(mode[0])=='w') error("Autosaving..");
|
|
||||||
return context != NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializerStream::fclose() {
|
int GP32SaveFile::fwrite(void *buf, int size, int cnt) {
|
||||||
// implement me
|
// implement me
|
||||||
::fclose((FILE*)context);
|
return ::fwrite(buf, size, cnt, fh);
|
||||||
}
|
}
|
||||||
int SerializerStream::fread(void *buf, int size, int cnt) {
|
|
||||||
// implement me
|
|
||||||
return ::fread(buf, size, cnt, (FILE*)context);
|
|
||||||
|
|
||||||
|
SaveFile GP32SaveFileManager::open_savefile(const char *filename,
|
||||||
|
bool saveOrLoad) {
|
||||||
|
// implement me
|
||||||
|
FILE *fh = ::fopen(filename, (saveOrLoad? "wb":"rb"));
|
||||||
|
//if (saveOrLoad) error("Autosaving..");
|
||||||
|
return fh? new GP32SaveFile(fh) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GP32SaveFile::~GP32SaveFile() {
|
||||||
|
// implement me
|
||||||
|
::fclose(fh);
|
||||||
|
}
|
||||||
|
int GP32SaveFile::fread(void *buf, int size, int cnt) {
|
||||||
|
// implement me
|
||||||
|
return ::fread(buf, size, cnt, fh);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveFileManager *OSystem_GP32::get_savefile_manager() {
|
||||||
|
return new GP32SaveFileManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts 8bit rgb values to a GP32 palette value
|
// Converts 8bit rgb values to a GP32 palette value
|
||||||
|
|
|
@ -115,6 +115,10 @@ public:
|
||||||
void grab_overlay(int16 *buf, int pitch);
|
void grab_overlay(int16 *buf, int pitch);
|
||||||
void copy_rect_overlay(const int16 *buf, int pitch, int x, int y, int w, int h);
|
void copy_rect_overlay(const int16 *buf, int pitch, int x, int y, int w, int h);
|
||||||
|
|
||||||
|
// Savefiles
|
||||||
|
SaveFileManager *get_savefile_manager();
|
||||||
|
|
||||||
|
|
||||||
static OSystem *create(int gfx_mode, bool full_screen);
|
static OSystem *create(int gfx_mode, bool full_screen);
|
||||||
private:
|
private:
|
||||||
typedef void ScalerProc(uint8 *srcPtr, uint32 srcPitch, uint8 *deltaPtr,
|
typedef void ScalerProc(uint8 *srcPtr, uint32 srcPitch, uint8 *deltaPtr,
|
||||||
|
|
90
common/savefile.h
Normal file
90
common/savefile.h
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
/* ScummVM - Scumm Interpreter
|
||||||
|
* Copyright (C) 2001 Ludvig Strigeus
|
||||||
|
* Copyright (C) 2001/2002 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$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMMON_SAVEFILE_H
|
||||||
|
#define COMMON_SAVEFILE_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
class SaveFile {
|
||||||
|
public:
|
||||||
|
virtual ~SaveFile() {}
|
||||||
|
virtual int fread(void *buf, int size, int cnt) = 0;
|
||||||
|
virtual int fwrite(void *buf, int size, int cnt) = 0;
|
||||||
|
#ifdef _WIN32_WCE
|
||||||
|
//Should go away. See scumm/saveload.cpp and scumm/imuse.cpp
|
||||||
|
virtual int fseek(long offs, int whence) = 0;
|
||||||
|
virtual int feof() = 0;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
class StdioSaveFile : public SaveFile {
|
||||||
|
private:
|
||||||
|
FILE *fh;
|
||||||
|
public:
|
||||||
|
StdioSaveFile(const char *filename, const char *mode)
|
||||||
|
{ fh = ::fopen(filename, mode); }
|
||||||
|
~StdioSaveFile()
|
||||||
|
{ if(fh) ::fclose(fh); }
|
||||||
|
|
||||||
|
|
||||||
|
bool is_open() { return fh != NULL; }
|
||||||
|
|
||||||
|
|
||||||
|
int fread(void *buf, int size, int cnt)
|
||||||
|
{ return ::fread(buf, size, cnt, fh); }
|
||||||
|
int fwrite(void *buf, int size, int cnt)
|
||||||
|
{ return ::fwrite(buf, size, cnt, fh); }
|
||||||
|
#ifdef _WIN32_WCE
|
||||||
|
int fseek(long offs, int whence)
|
||||||
|
{ return ::fseek(fh, offs, whence); }
|
||||||
|
int feof()
|
||||||
|
{ return ::feof(fh); }
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
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 void list_savefiles(const char *prefix,
|
||||||
|
bool *marks, int num)
|
||||||
|
{
|
||||||
|
memset(marks, true, num*sizeof(bool));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -240,7 +240,6 @@
|
||||||
#define CDECL
|
#define CDECL
|
||||||
#define SCUMM_NEED_ALIGNMENT
|
#define SCUMM_NEED_ALIGNMENT
|
||||||
#define SCUMM_LITTLE_ENDIAN
|
#define SCUMM_LITTLE_ENDIAN
|
||||||
#define NONSTANDARD_SAVE
|
|
||||||
|
|
||||||
#define scumm_stricmp stricmp
|
#define scumm_stricmp stricmp
|
||||||
#define CHECK_HEAP
|
#define CHECK_HEAP
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#define COMMON_SYSTEM_H
|
#define COMMON_SYSTEM_H
|
||||||
|
|
||||||
#include "scummsys.h"
|
#include "scummsys.h"
|
||||||
|
#include "savefile.h"
|
||||||
|
|
||||||
class Timer;
|
class Timer;
|
||||||
|
|
||||||
|
@ -180,6 +181,12 @@ public:
|
||||||
g = (((color>>5)&0x3F) << 2);
|
g = (((color>>5)&0x3F) << 2);
|
||||||
b = ((color&0x1F) << 3);
|
b = ((color&0x1F) << 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Savefile management
|
||||||
|
virtual SaveFileManager *get_savefile_manager()
|
||||||
|
{
|
||||||
|
return new SaveFileManager();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -406,12 +406,20 @@ void SaveLoadDialog::fillList()
|
||||||
ScummVM::StringList l;
|
ScummVM::StringList l;
|
||||||
char name[32];
|
char name[32];
|
||||||
int i = _saveMode ? 1 : 0;
|
int i = _saveMode ? 1 : 0;
|
||||||
|
bool avail_saves[81];
|
||||||
|
SaveFileManager *mgr = _scumm->_system->get_savefile_manager();
|
||||||
|
|
||||||
|
_scumm->listSavegames(avail_saves, 81, mgr);
|
||||||
for (; i <= 80; i++) { // 80 - got this value from the old GUI
|
for (; i <= 80; i++) { // 80 - got this value from the old GUI
|
||||||
_scumm->getSavegameName(i, name);
|
if(avail_saves[i])
|
||||||
|
_scumm->getSavegameName(i, name, mgr);
|
||||||
|
else
|
||||||
|
name[0] = 0;
|
||||||
l.push_back(name);
|
l.push_back(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete mgr;
|
||||||
|
|
||||||
_savegameList->setList(l);
|
_savegameList->setList(l);
|
||||||
_savegameList->setNumberingMode(_saveMode ? kListNumberingOne : kListNumberingZero);
|
_savegameList->setNumberingMode(_saveMode ? kListNumberingOne : kListNumberingZero);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,15 +39,15 @@ struct SaveGameHeader {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
bool Scumm::saveState(int slot, bool compat)
|
bool Scumm::saveState(int slot, bool compat, SaveFileManager *mgr)
|
||||||
{
|
{
|
||||||
char filename[256];
|
char filename[256];
|
||||||
SerializerStream out;
|
SaveFile *out;
|
||||||
SaveGameHeader hdr;
|
SaveGameHeader hdr;
|
||||||
|
|
||||||
makeSavegameName(filename, slot, compat);
|
makeSavegameName(filename, slot, compat);
|
||||||
|
|
||||||
if (!out.fopen(filename, "wb"))
|
if (!(out = mgr->open_savefile(filename, true)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
memcpy(hdr.name, _saveLoadName, sizeof(hdr.name));
|
memcpy(hdr.name, _saveLoadName, sizeof(hdr.name));
|
||||||
|
@ -56,32 +56,32 @@ bool Scumm::saveState(int slot, bool compat)
|
||||||
hdr.size = 0;
|
hdr.size = 0;
|
||||||
hdr.ver = TO_LE_32(CURRENT_VER);
|
hdr.ver = TO_LE_32(CURRENT_VER);
|
||||||
|
|
||||||
out.fwrite(&hdr, sizeof(hdr), 1);
|
out->fwrite(&hdr, sizeof(hdr), 1);
|
||||||
|
|
||||||
Serializer ser(out, true, CURRENT_VER);
|
Serializer ser(out, true, CURRENT_VER);
|
||||||
saveOrLoad(&ser, CURRENT_VER);
|
saveOrLoad(&ser, CURRENT_VER);
|
||||||
|
|
||||||
out.fclose();
|
delete out;
|
||||||
debug(1, "State saved as '%s'", filename);
|
debug(1, "State saved as '%s'", filename);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Scumm::loadState(int slot, bool compat)
|
bool Scumm::loadState(int slot, bool compat, SaveFileManager *mgr)
|
||||||
{
|
{
|
||||||
char filename[256];
|
char filename[256];
|
||||||
SerializerStream out;
|
SaveFile *out;
|
||||||
int i, j;
|
int i, j;
|
||||||
SaveGameHeader hdr;
|
SaveGameHeader hdr;
|
||||||
int sb, sh;
|
int sb, sh;
|
||||||
|
|
||||||
makeSavegameName(filename, slot, compat);
|
makeSavegameName(filename, slot, compat);
|
||||||
if (!out.fopen(filename, "rb"))
|
if (!(out = mgr->open_savefile(filename, false)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
out.fread(&hdr, sizeof(hdr), 1);
|
out->fread(&hdr, sizeof(hdr), 1);
|
||||||
if (hdr.type != MKID('SCVM')) {
|
if (hdr.type != MKID('SCVM')) {
|
||||||
warning("Invalid savegame '%s'", filename);
|
warning("Invalid savegame '%s'", filename);
|
||||||
out.fclose();
|
delete out;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ bool Scumm::loadState(int slot, bool compat)
|
||||||
if (hdr.ver < VER_V7 || hdr.ver > CURRENT_VER)
|
if (hdr.ver < VER_V7 || hdr.ver > CURRENT_VER)
|
||||||
{
|
{
|
||||||
warning("Invalid version of '%s'", filename);
|
warning("Invalid version of '%s'", filename);
|
||||||
out.fclose();
|
delete out;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ bool Scumm::loadState(int slot, bool compat)
|
||||||
|
|
||||||
Serializer ser(out, false, hdr.ver);
|
Serializer ser(out, false, hdr.ver);
|
||||||
saveOrLoad(&ser, hdr.ver);
|
saveOrLoad(&ser, hdr.ver);
|
||||||
out.fclose();
|
delete out;
|
||||||
|
|
||||||
sb = _screenB;
|
sb = _screenB;
|
||||||
sh = _screenH;
|
sh = _screenH;
|
||||||
|
@ -174,20 +174,28 @@ void Scumm::makeSavegameName(char *out, int slot, bool compatible)
|
||||||
sprintf(out, "%s%s.%c%.2d", dir, _game_name, compatible ? 'c' : 's', slot);
|
sprintf(out, "%s%s.%c%.2d", dir, _game_name, compatible ? 'c' : 's', slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Scumm::getSavegameName(int slot, char *desc)
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Scumm::getSavegameName(int slot, char *desc, SaveFileManager *mgr)
|
||||||
{
|
{
|
||||||
char filename[256];
|
char filename[256];
|
||||||
SerializerStream out;
|
SaveFile *out;
|
||||||
SaveGameHeader hdr;
|
SaveGameHeader hdr;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
makeSavegameName(filename, slot, false);
|
makeSavegameName(filename, slot, false);
|
||||||
if (!out.fopen(filename, "rb")) {
|
if (!(out = mgr->open_savefile(filename, false))) {
|
||||||
strcpy(desc, "");
|
strcpy(desc, "");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
len = out.fread(&hdr, sizeof(hdr), 1);
|
len = out->fread(&hdr, sizeof(hdr), 1);
|
||||||
out.fclose();
|
delete out;
|
||||||
|
|
||||||
if (len != 1 || hdr.type != MKID('SCVM')) {
|
if (len != 1 || hdr.type != MKID('SCVM')) {
|
||||||
strcpy(desc, "Invalid savegame");
|
strcpy(desc, "Invalid savegame");
|
||||||
|
@ -652,12 +660,12 @@ void Scumm::saveLoadResource(Serializer *ser, int type, int idx)
|
||||||
|
|
||||||
void Serializer::saveBytes(void *b, int len)
|
void Serializer::saveBytes(void *b, int len)
|
||||||
{
|
{
|
||||||
_saveLoadStream.fwrite(b, 1, len);
|
_saveLoadStream->fwrite(b, 1, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Serializer::loadBytes(void *b, int len)
|
void Serializer::loadBytes(void *b, int len)
|
||||||
{
|
{
|
||||||
_saveLoadStream.fread(b, 1, len);
|
_saveLoadStream->fread(b, 1, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32_WCE
|
#ifdef _WIN32_WCE
|
||||||
|
@ -666,11 +674,11 @@ void Serializer::loadBytes(void *b, int len)
|
||||||
|
|
||||||
bool Serializer::checkEOFLoadStream()
|
bool Serializer::checkEOFLoadStream()
|
||||||
{
|
{
|
||||||
if (!fseek(_saveLoadStream.out, 1, SEEK_CUR))
|
if (!_saveLoadStream->fseek(1, SEEK_CUR))
|
||||||
return true;
|
return true;
|
||||||
if (feof(_saveLoadStream.out))
|
if (_saveLoadStream->feof())
|
||||||
return true;
|
return true;
|
||||||
fseek(_saveLoadStream.out, -1, SEEK_CUR);
|
_saveLoadStream->fseek(-1, SEEK_CUR);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,38 +85,12 @@ struct SaveLoadEntry {
|
||||||
uint8 maxVersion;
|
uint8 maxVersion;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SerializerStream {
|
|
||||||
#ifdef NONSTANDARD_SAVE
|
|
||||||
void *context;
|
|
||||||
|
|
||||||
bool fopen(const char *filename, const char *mode);
|
|
||||||
void fclose();
|
|
||||||
int fread(void *buf, int size, int cnt);
|
|
||||||
int fwrite(void *buf, int size, int cnt);
|
|
||||||
#else
|
|
||||||
FILE *out;
|
|
||||||
|
|
||||||
FILE *fopen(const char *filename, const char *mode) {
|
|
||||||
return out = ::fopen(filename, mode);
|
|
||||||
}
|
|
||||||
void fclose() {
|
|
||||||
::fclose(out);
|
|
||||||
}
|
|
||||||
int fread(void *buf, int size, int cnt) {
|
|
||||||
return ::fread(buf, size, cnt, out);
|
|
||||||
}
|
|
||||||
int fwrite(void *buf, int size, int cnt) {
|
|
||||||
return ::fwrite(buf, size, cnt, out);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef int SerializerSaveReference(void *me, byte type, void *ref);
|
typedef int SerializerSaveReference(void *me, byte type, void *ref);
|
||||||
typedef void *SerializerLoadReference(void *me, byte type, int ref);
|
typedef void *SerializerLoadReference(void *me, byte type, int ref);
|
||||||
|
|
||||||
class Serializer {
|
class Serializer {
|
||||||
public:
|
public:
|
||||||
Serializer(SerializerStream stream, bool saveOrLoad, uint32 savegameVersion)
|
Serializer(SaveFile *stream, bool saveOrLoad, uint32 savegameVersion)
|
||||||
: _save_ref(0), _load_ref(0), _ref_me(0),
|
: _save_ref(0), _load_ref(0), _ref_me(0),
|
||||||
_saveLoadStream(stream), _saveOrLoad(saveOrLoad),
|
_saveLoadStream(stream), _saveOrLoad(saveOrLoad),
|
||||||
_savegameVersion(savegameVersion)
|
_savegameVersion(savegameVersion)
|
||||||
|
@ -146,7 +120,7 @@ public:
|
||||||
void loadBytes(void *b, int len);
|
void loadBytes(void *b, int len);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SerializerStream _saveLoadStream;
|
SaveFile *_saveLoadStream;
|
||||||
bool _saveOrLoad;
|
bool _saveOrLoad;
|
||||||
uint32 _savegameVersion;
|
uint32 _savegameVersion;
|
||||||
|
|
||||||
|
|
|
@ -439,13 +439,28 @@ public:
|
||||||
bool _saveLoadCompatible;
|
bool _saveLoadCompatible;
|
||||||
char _saveLoadName[32];
|
char _saveLoadName[32];
|
||||||
|
|
||||||
bool saveState(int slot, bool compat);
|
bool saveState(int slot, bool compat, SaveFileManager *mgr);
|
||||||
bool loadState(int slot, bool compat);
|
bool loadState(int slot, bool compat, SaveFileManager *mgr);
|
||||||
|
bool saveState(int slot, bool compat)
|
||||||
|
{
|
||||||
|
SaveFileManager *mgr = _system->get_savefile_manager();
|
||||||
|
bool result = saveState(slot, compat, mgr);
|
||||||
|
delete mgr;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
bool loadState(int slot, bool compat)
|
||||||
|
{
|
||||||
|
SaveFileManager *mgr = _system->get_savefile_manager();
|
||||||
|
bool result = loadState(slot, compat, mgr);
|
||||||
|
delete mgr;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
void saveOrLoad(Serializer *s, uint32 savegameVersion);
|
void saveOrLoad(Serializer *s, uint32 savegameVersion);
|
||||||
|
|
||||||
bool getSavegameName(int slot, char *desc);
|
bool getSavegameName(int slot, char *desc, SaveFileManager *mgr);
|
||||||
void makeSavegameName(char *out, int slot, bool compatible);
|
void makeSavegameName(char *out, int slot, bool compatible);
|
||||||
void saveLoadResource(Serializer *ser, int type, int index);
|
void saveLoadResource(Serializer *ser, int type, int index);
|
||||||
|
void listSavegames(bool *marks, int num, SaveFileManager *mgr);
|
||||||
|
|
||||||
/* Heap and memory management */
|
/* Heap and memory management */
|
||||||
uint32 _maxHeapThreshold, _minHeapThreshold;
|
uint32 _maxHeapThreshold, _minHeapThreshold;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue