reverted lua related changes before broken state and changed savegame layer to prevent touch lua library

This commit is contained in:
Pawel Kolodziejski 2006-05-13 10:16:19 +00:00
parent 3306ae4792
commit ca87f8b052
8 changed files with 257 additions and 370 deletions

View file

@ -456,6 +456,14 @@ void Engine::mainLoop() {
} }
} }
void Engine::savegameGzread(void *data, int size) {
gzread(g_engine->_savegameFileHandle, data, size);
}
void Engine::savegameGzwrite(void *data, int size) {
gzwrite(g_engine->_savegameFileHandle, data, size);
}
void Engine::savegameRestore() { void Engine::savegameRestore() {
printf("Engine::savegameRestore() started.\n"); printf("Engine::savegameRestore() started.\n");
_savegameLoadRequest = false; _savegameLoadRequest = false;
@ -466,6 +474,7 @@ void Engine::savegameRestore() {
strcpy(filename, _savegameFileName); strcpy(filename, _savegameFileName);
} }
_savedState = new SaveGame(filename, false); _savedState = new SaveGame(filename, false);
_savegameFileHandle = _savedState->fileHandle();
g_imuse->stopAllSounds(); g_imuse->stopAllSounds();
g_imuse->resetState(); g_imuse->resetState();
@ -485,7 +494,7 @@ void Engine::savegameRestore() {
//Primitive_Restore(_savedState); //Primitive_Restore(_savedState);
//Smush_Restore(_savedState); //Smush_Restore(_savedState);
g_imuse->restoreState(_savedState); g_imuse->restoreState(_savedState);
lua_Restore(_savedState); lua_Restore(savegameGzread);
// unlock resources // unlock resources
delete _savedState; delete _savedState;
@ -506,6 +515,7 @@ void Engine::savegameSave() {
strcpy(filename, _savegameFileName); strcpy(filename, _savegameFileName);
} }
_savedState = new SaveGame(filename, true); _savedState = new SaveGame(filename, true);
_savegameFileHandle = _savedState->fileHandle();
g_imuse->pause(true); g_imuse->pause(true);
g_smush->pause(true); g_smush->pause(true);
@ -521,7 +531,7 @@ void Engine::savegameSave() {
//Primitive_Save(_savedState); //Primitive_Save(_savedState);
//Smush_Save(_savedState); //Smush_Save(_savedState);
g_imuse->saveState(_savedState); g_imuse->saveState(_savedState);
lua_Save(_savedState); lua_Save(savegameGzwrite);
delete _savedState; delete _savedState;

View file

@ -29,6 +29,7 @@
#include "primitives.h" #include "primitives.h"
#include "font.h" #include "font.h"
#include "lua.h" #include "lua.h"
#include "savegame.h"
#include <cstdlib> #include <cstdlib>
#include <list> #include <list>
@ -155,10 +156,13 @@ public:
void savegameSave(); void savegameSave();
void savegameRestore(); void savegameRestore();
void savegameCallback(); void savegameCallback();
static void savegameGzread(void *data, int size);
static void savegameGzwrite(void *data, int size);
bool _savegameLoadRequest; bool _savegameLoadRequest;
bool _savegameSaveRequest; bool _savegameSaveRequest;
char *_savegameFileName; char *_savegameFileName;
gzFile _savegameFileHandle;
SaveGame *_savedState; SaveGame *_savedState;
Engine(); Engine();

166
lua.cpp
View file

@ -47,8 +47,6 @@
extern Imuse *g_imuse; extern Imuse *g_imuse;
static int tagSTAT, tagACTR, tagCOLR, tagFONT, tagVBUF, tagPRIM, tagTEXT;
#define strmatch(src, dst) (strlen(src) == strlen(dst) && strcmp(src, dst) == 0) #define strmatch(src, dst) (strlen(src) == strlen(dst) && strcmp(src, dst) == 0)
#define DEBUG_FUNCTION() debugFunction("Function", __FUNCTION__) #define DEBUG_FUNCTION() debugFunction("Function", __FUNCTION__)
@ -57,35 +55,35 @@ static void stubWarning(char *funcName);
static inline bool isObject(int num) { static inline bool isObject(int num) {
lua_Object param = lua_getparam(num); lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == tagSTAT) if (lua_isuserdata(param) && lua_tag(param) == MKID('STAT'))
return true; return true;
return false; return false;
} }
static inline bool isActor(int num) { static inline bool isActor(int num) {
lua_Object param = lua_getparam(num); lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == tagACTR) if (lua_isuserdata(param) && lua_tag(param) == MKID('ACTR'))
return true; return true;
return false; return false;
} }
static inline bool isColor(int num) { static inline bool isColor(int num) {
lua_Object param = lua_getparam(num); lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == tagCOLR) if (lua_isuserdata(param) && lua_tag(param) == MKID('COLR'))
return true; return true;
return false; return false;
} }
static inline bool isFont(int num) { static inline bool isFont(int num) {
lua_Object param = lua_getparam(num); lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == tagFONT) if (lua_isuserdata(param) && lua_tag(param) == MKID('FONT'))
return true; return true;
return false; return false;
} }
static inline bool isBitmapObject(int num) { static inline bool isBitmapObject(int num) {
lua_Object param = lua_getparam(num); lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == tagVBUF) if (lua_isuserdata(param) && lua_tag(param) == MKID('VBUF'))
return true; return true;
return false; return false;
} }
@ -93,7 +91,7 @@ static inline bool isBitmapObject(int num) {
// Helper functions to ensure the arguments we get are what we expect // Helper functions to ensure the arguments we get are what we expect
static inline ObjectState *check_object(int num) { static inline ObjectState *check_object(int num) {
lua_Object param = lua_getparam(num); lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == tagSTAT) if (lua_isuserdata(param) && lua_tag(param) == MKID('STAT'))
return static_cast<ObjectState *>(lua_getuserdata(param)); return static_cast<ObjectState *>(lua_getuserdata(param));
luaL_argerror(num, "objectstate expected"); luaL_argerror(num, "objectstate expected");
return NULL; return NULL;
@ -101,7 +99,7 @@ static inline ObjectState *check_object(int num) {
static inline Actor *check_actor(int num) { static inline Actor *check_actor(int num) {
lua_Object param = lua_getparam(num); lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == tagACTR) if (lua_isuserdata(param) && lua_tag(param) == MKID('ACTR'))
return static_cast<Actor *>(lua_getuserdata(param)); return static_cast<Actor *>(lua_getuserdata(param));
luaL_argerror(num, "actor expected"); luaL_argerror(num, "actor expected");
return NULL; return NULL;
@ -109,7 +107,7 @@ static inline Actor *check_actor(int num) {
static inline Color *check_color(int num) { static inline Color *check_color(int num) {
lua_Object param = lua_getparam(num); lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == tagCOLR) if (lua_isuserdata(param) && lua_tag(param) == MKID('COLR'))
return static_cast<Color *>(lua_getuserdata(param)); return static_cast<Color *>(lua_getuserdata(param));
luaL_argerror(num, "color expected"); luaL_argerror(num, "color expected");
return NULL; return NULL;
@ -117,7 +115,7 @@ static inline Color *check_color(int num) {
static inline Font *check_font(int num) { static inline Font *check_font(int num) {
lua_Object param = lua_getparam(num); lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == tagFONT) if (lua_isuserdata(param) && lua_tag(param) == MKID('FONT'))
return static_cast<Font *>(lua_getuserdata(param)); return static_cast<Font *>(lua_getuserdata(param));
luaL_argerror(num, "font expected"); luaL_argerror(num, "font expected");
return NULL; return NULL;
@ -125,7 +123,7 @@ static inline Font *check_font(int num) {
static inline PrimitiveObject *check_primobject(int num) { static inline PrimitiveObject *check_primobject(int num) {
lua_Object param = lua_getparam(num); lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == tagPRIM) if (lua_isuserdata(param) && lua_tag(param) == MKID('PRIM'))
return static_cast<PrimitiveObject *>(lua_getuserdata(param)); return static_cast<PrimitiveObject *>(lua_getuserdata(param));
luaL_argerror(num, "primitive (rectangle) expected"); luaL_argerror(num, "primitive (rectangle) expected");
return NULL; return NULL;
@ -133,7 +131,7 @@ static inline PrimitiveObject *check_primobject(int num) {
static inline TextObject *check_textobject(int num) { static inline TextObject *check_textobject(int num) {
lua_Object param = lua_getparam(num); lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == tagTEXT) if (lua_isuserdata(param) && lua_tag(param) == MKID('TEXT'))
return static_cast<TextObject *>(lua_getuserdata(param)); return static_cast<TextObject *>(lua_getuserdata(param));
luaL_argerror(num, "textobject expected"); luaL_argerror(num, "textobject expected");
return NULL; return NULL;
@ -141,7 +139,7 @@ static inline TextObject *check_textobject(int num) {
static inline Bitmap *check_bitmapobject(int num) { static inline Bitmap *check_bitmapobject(int num) {
lua_Object param = lua_getparam(num); lua_Object param = lua_getparam(num);
if (lua_isuserdata(param) && lua_tag(param) == tagVBUF) if (lua_isuserdata(param) && lua_tag(param) == MKID('VBUF'))
return static_cast<Bitmap *>(lua_getuserdata(param)); return static_cast<Bitmap *>(lua_getuserdata(param));
luaL_argerror(num, "image object expected"); luaL_argerror(num, "image object expected");
return NULL; return NULL;
@ -300,10 +298,6 @@ static void CheckForFile() {
// Color functions // Color functions
static void gc_color() {
delete check_color(1);
}
static unsigned char clamp_color(int c) { static unsigned char clamp_color(int c) {
if (c < 0) if (c < 0)
return 0; return 0;
@ -318,7 +312,7 @@ static void MakeColor() {
DEBUG_FUNCTION(); DEBUG_FUNCTION();
c = new Color (clamp_color(check_int(1)), clamp_color(check_int(2)), clamp_color(check_int(3))); c = new Color (clamp_color(check_int(1)), clamp_color(check_int(2)), clamp_color(check_int(3)));
lua_pushusertag(c, tagCOLR); lua_pushusertag(c, MKID('COLR'));
} }
static void GetColorComponents() { static void GetColorComponents() {
@ -355,12 +349,6 @@ static void WriteRegistryValue() {
// Actor functions // Actor functions
static void gc_actor() {
Actor *actor = check_actor(1);
g_engine->killActor(actor);
delete actor;
}
static void LoadActor() { static void LoadActor() {
const char *name; const char *name;
@ -369,7 +357,7 @@ static void LoadActor() {
name = "<unnamed>"; name = "<unnamed>";
else else
name = luaL_check_string(1); name = luaL_check_string(1);
lua_pushusertag(new Actor(name), tagACTR); lua_pushusertag(new Actor(name), MKID('ACTR'));
} }
static void GetActorTimeScale() { static void GetActorTimeScale() {
@ -397,7 +385,7 @@ static void GetCameraActor() {
DEBUG_FUNCTION(); DEBUG_FUNCTION();
stubWarning("VERIFY: GetCameraActor"); stubWarning("VERIFY: GetCameraActor");
act = g_engine->selectedActor(); act = g_engine->selectedActor();
lua_pushusertag(act, tagACTR); lua_pushusertag(act, MKID('ACTR'));
} }
static void SetSayLineDefaults() { static void SetSayLineDefaults() {
@ -448,7 +436,7 @@ static void GetActorTalkColor() {
DEBUG_FUNCTION(); DEBUG_FUNCTION();
act = check_actor(1); act = check_actor(1);
c = new Color(act->talkColor()); c = new Color(act->talkColor());
lua_pushusertag(c, tagCOLR); lua_pushusertag(c, MKID('COLR'));
} }
static void SetActorRestChore() { static void SetActorRestChore() {
@ -1397,7 +1385,7 @@ static void GetVisibleThings() {
// Consider the active actor visible // Consider the active actor visible
if (sel == (*i) || sel->angleTo(*(*i)) < 90) { if (sel == (*i) || sel->angleTo(*(*i)) < 90) {
lua_pushobject(result); lua_pushobject(result);
lua_pushusertag(*i, tagACTR); lua_pushusertag(*i, MKID('ACTR'));
lua_pushnumber(1); lua_pushnumber(1);
lua_settable(); lua_settable();
} }
@ -2196,15 +2184,6 @@ static void killBitmapPrimitives(Bitmap *bitmap)
} }
} }
static void gc_bitmap() {
Bitmap *bitmap;
DEBUG_FUNCTION();
bitmap = check_bitmapobject(1);
killBitmapPrimitives(bitmap);
bitmap->luaGc();
}
static void GetImage() { static void GetImage() {
char *bitmapName; char *bitmapName;
@ -2212,7 +2191,7 @@ static void GetImage() {
bitmapName = luaL_check_string(1); bitmapName = luaL_check_string(1);
Bitmap *image = g_resourceloader->loadBitmap(bitmapName); Bitmap *image = g_resourceloader->loadBitmap(bitmapName);
image->luaRef(); image->luaRef();
lua_pushusertag(image, tagVBUF); lua_pushusertag(image, MKID('VBUF'));
} }
static void FreeImage() { static void FreeImage() {
@ -2301,12 +2280,6 @@ static void Exit() {
g_driver->quit(); g_driver->quit();
} }
static void gc_textobject() {
TextObject *textObject = check_textobject(1);
g_engine->killTextObject(textObject);
delete textObject;
}
/* Check for an existing object by a certain name /* Check for an existing object by a certain name
* this function is used by several functions that look * this function is used by several functions that look
* for text objects to see if they need to be created/modified/destroyed. * for text objects to see if they need to be created/modified/destroyed.
@ -2422,7 +2395,7 @@ static void MakeTextObject() {
textObject->createBitmap(); textObject->createBitmap();
g_engine->registerTextObject(textObject); g_engine->registerTextObject(textObject);
lua_pushusertag(textObject, tagTEXT); lua_pushusertag(textObject, MKID('TEXT'));
lua_pushnumber(textObject->getBitmapWidth()); lua_pushnumber(textObject->getBitmapWidth());
lua_pushnumber(textObject->getBitmapHeight()); lua_pushnumber(textObject->getBitmapHeight());
} }
@ -2509,7 +2482,8 @@ static void StartFullscreenMovie() {
// Clean out any text objects on the display before running the // Clean out any text objects on the display before running the
// movie, otherwise things like Bruno's "Nice bathrobe." will stay // movie, otherwise things like Bruno's "Nice bathrobe." will stay
// on-screen the whole movie // on-screen the whole movie
ExpireText(); // ExpireText(); --- disable above hack
CleanBuffer();
g_engine->setMode(ENGINE_MODE_SMUSH); g_engine->setMode(ENGINE_MODE_SMUSH);
pushbool(g_smush->play(luaL_check_string(1), 0, 0)); pushbool(g_smush->play(luaL_check_string(1), 0, 0));
} }
@ -2553,12 +2527,6 @@ static void PauseMovie() {
g_smush->pause(lua_isnil(lua_getparam(1)) != 0); g_smush->pause(lua_isnil(lua_getparam(1)) != 0);
} }
static void gc_primitive() {
PrimitiveObject *primitive = check_primobject(1);
g_engine->killPrimitiveObject(primitive);
delete primitive;
}
static void PurgePrimitiveQueue() { static void PurgePrimitiveQueue() {
DEBUG_FUNCTION(); DEBUG_FUNCTION();
g_engine->killPrimitiveObjects(); g_engine->killPrimitiveObjects();
@ -2587,7 +2555,7 @@ static void DrawLine() {
lua_pushobject(tableObj); lua_pushobject(tableObj);
lua_pushstring("color"); lua_pushstring("color");
lua_Object colorObj = lua_gettable(); lua_Object colorObj = lua_gettable();
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == tagCOLR) { if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID('COLR')) {
color = static_cast<Color *>(lua_getuserdata(colorObj)); color = static_cast<Color *>(lua_getuserdata(colorObj));
} }
} }
@ -2595,7 +2563,7 @@ static void DrawLine() {
PrimitiveObject *p = new PrimitiveObject(); PrimitiveObject *p = new PrimitiveObject();
p->createLine(x1, x2, y1, y2, color); p->createLine(x1, x2, y1, y2, color);
g_engine->registerPrimitiveObject(p); g_engine->registerPrimitiveObject(p);
lua_pushusertag(p, tagPRIM); lua_pushusertag(p, MKID('PRIM'));
} }
static void ChangePrimitive() { static void ChangePrimitive() {
@ -2631,7 +2599,7 @@ static void ChangePrimitive() {
lua_pushobject(tableObj); lua_pushobject(tableObj);
lua_pushstring("color"); lua_pushstring("color");
lua_Object colorObj = lua_gettable(); lua_Object colorObj = lua_gettable();
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == tagCOLR) { if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID('COLR')) {
color = static_cast<Color *>(lua_getuserdata(colorObj)); color = static_cast<Color *>(lua_getuserdata(colorObj));
pmodify->setColor(color); pmodify->setColor(color);
} }
@ -2664,7 +2632,7 @@ static void DrawRectangle() {
lua_pushobject(tableObj); lua_pushobject(tableObj);
lua_pushstring("color"); lua_pushstring("color");
lua_Object colorObj = lua_gettable(); lua_Object colorObj = lua_gettable();
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == tagCOLR) { if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID('COLR')) {
color = static_cast<Color *>(lua_getuserdata(colorObj)); color = static_cast<Color *>(lua_getuserdata(colorObj));
} }
@ -2678,7 +2646,7 @@ static void DrawRectangle() {
PrimitiveObject *p = new PrimitiveObject(); PrimitiveObject *p = new PrimitiveObject();
p->createRectangle(x1, x2, y1, y2, color, filled); p->createRectangle(x1, x2, y1, y2, color, filled);
g_engine->registerPrimitiveObject(p); g_engine->registerPrimitiveObject(p);
lua_pushusertag(p, tagPRIM); lua_pushusertag(p, MKID('PRIM'));
} }
static void BlastRect() { static void BlastRect() {
@ -2702,7 +2670,7 @@ static void BlastRect() {
lua_pushobject(tableObj); lua_pushobject(tableObj);
lua_pushstring("color"); lua_pushstring("color");
lua_Object colorObj = lua_gettable(); lua_Object colorObj = lua_gettable();
if (lua_isuserdata(colorObj) && lua_tag(colorObj) == tagCOLR) { if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID('COLR')) {
color = static_cast<Color *>(lua_getuserdata(colorObj)); color = static_cast<Color *>(lua_getuserdata(colorObj));
} }
@ -2742,13 +2710,6 @@ static void GetDiskFreeSpace() {
lua_pushnumber(50); lua_pushnumber(50);
} }
// Objectstate functions
static void gc_object() {
ObjectState *state = check_object(1);
g_engine->currScene()->deleteObjectState(state);
delete state;
}
static void NewObjectState() { static void NewObjectState() {
ObjectState *state = NULL; ObjectState *state = NULL;
ObjectState::Position pos; ObjectState::Position pos;
@ -2768,7 +2729,7 @@ static void NewObjectState() {
state = new ObjectState(setupID, pos, bitmap, zbitmap, visible); state = new ObjectState(setupID, pos, bitmap, zbitmap, visible);
g_engine->currScene()->addObjectState(state); g_engine->currScene()->addObjectState(state);
lua_pushusertag(state, tagSTAT); lua_pushusertag(state, MKID('STAT'));
} }
static void FreeObjectState() { static void FreeObjectState() {
@ -2784,7 +2745,7 @@ static void SendObjectToBack() {
DEBUG_FUNCTION(); DEBUG_FUNCTION();
param = lua_getparam(1); param = lua_getparam(1);
if (lua_isuserdata(param) && lua_tag(param) == tagSTAT) { if (lua_isuserdata(param) && lua_tag(param) == MKID('STAT')) {
ObjectState *state = static_cast<ObjectState *>(lua_getuserdata(param)); ObjectState *state = static_cast<ObjectState *>(lua_getuserdata(param));
// moving object to top in list ? // moving object to top in list ?
g_engine->currScene()->moveObjectStateToFirst(state); g_engine->currScene()->moveObjectStateToFirst(state);
@ -2796,7 +2757,7 @@ static void SendObjectToFront() {
DEBUG_FUNCTION(); DEBUG_FUNCTION();
param = lua_getparam(1); param = lua_getparam(1);
if (lua_isuserdata(param) && lua_tag(param) == tagSTAT) { if (lua_isuserdata(param) && lua_tag(param) == MKID('STAT')) {
ObjectState *state = static_cast<ObjectState *>(lua_getuserdata(param)); ObjectState *state = static_cast<ObjectState *>(lua_getuserdata(param));
// moving object to last in list ? // moving object to last in list ?
g_engine->currScene()->moveObjectStateToLast(state); g_engine->currScene()->moveObjectStateToLast(state);
@ -2832,7 +2793,7 @@ static void ScreenShot() {
g_engine->setMode(mode); g_engine->setMode(mode);
if (screenshot) { if (screenshot) {
screenshot->luaRef(); screenshot->luaRef();
lua_pushusertag(screenshot, tagVBUF); lua_pushusertag(screenshot, MKID('VBUF'));
} else { } else {
lua_pushnil(); lua_pushnil();
} }
@ -2855,17 +2816,16 @@ static void StoreSaveGameImage(SaveGame *savedState) {
g_engine->updateDisplayScene(); g_engine->updateDisplayScene();
screenshot = g_driver->getScreenshot(width, height); screenshot = g_driver->getScreenshot(width, height);
g_engine->setMode(mode); g_engine->setMode(mode);
savedState->beginSection('SIMG'); savedState->writeTag('SIMG');
if (screenshot) { if (screenshot) {
int size = screenshot->width() * screenshot->height() * sizeof(uint16); int size = screenshot->width() * screenshot->height() * sizeof(uint16);
screenshot->setNumber(0); screenshot->setNumber(0);
char *data = screenshot->getData(); char *data = screenshot->getData();
savedState->writeBlock(data, size); savedState->write(data, size);
} else { } else {
error("Unable to store screenshot!"); error("Unable to store screenshot!");
} }
savedState->endSection();
printf("StoreSaveGameImage() finished.\n"); printf("StoreSaveGameImage() finished.\n");
} }
@ -2883,18 +2843,17 @@ static void GetSaveGameImage() {
DEBUG_FUNCTION(); DEBUG_FUNCTION();
filename = luaL_check_string(1); filename = luaL_check_string(1);
SaveGame *savedState = new SaveGame(filename, false); SaveGame *savedState = new SaveGame(filename, false);
dataSize = savedState->beginSection('SIMG'); dataSize = savedState->checkTag('SIMG');
data = (char *)malloc(dataSize); data = (char *)malloc(dataSize);
savedState->readBlock(data, dataSize); savedState->read(data, dataSize);
screenshot = new Bitmap(data, width, height, "screenshot"); screenshot = new Bitmap(data, width, height, "screenshot");
if (screenshot) { if (screenshot) {
screenshot->luaRef(); screenshot->luaRef();
lua_pushusertag(screenshot, tagVBUF); lua_pushusertag(screenshot, MKID('VBUF'));
} else { } else {
lua_pushnil(); lua_pushnil();
error("Could not restore screenshot from file!"); error("Could not restore screenshot from file!");
} }
savedState->endSection();
printf("GetSaveGameImage() finished.\n"); printf("GetSaveGameImage() finished.\n");
} }
@ -2911,7 +2870,7 @@ static void SubmitSaveGameData() {
savedState = g_engine->savedState(); savedState = g_engine->savedState();
if (savedState == NULL) if (savedState == NULL)
error("Cannot obtain saved game!"); error("Cannot obtain saved game!");
savedState->beginSection('SUBS'); savedState->writeTag('SUBS');
count = 0; count = 0;
for (;;) { for (;;) {
lua_pushobject(table); lua_pushobject(table);
@ -2922,10 +2881,9 @@ static void SubmitSaveGameData() {
break; break;
str = lua_getstring(table2); str = lua_getstring(table2);
int len = strlen(str) + 1; int len = strlen(str) + 1;
savedState->writeBlock(&len, sizeof(int)); savedState->write(&len, sizeof(int));
savedState->writeBlock(str, len); savedState->write(str, len);
} }
savedState->endSection();
printf("SubmitSaveGameData() finished.\n"); printf("SubmitSaveGameData() finished.\n");
StoreSaveGameImage(savedState); StoreSaveGameImage(savedState);
} }
@ -2939,7 +2897,7 @@ static void GetSaveGameData() {
DEBUG_FUNCTION(); DEBUG_FUNCTION();
filename = luaL_check_string(1); filename = luaL_check_string(1);
SaveGame *savedState = new SaveGame(filename, false); SaveGame *savedState = new SaveGame(filename, false);
dataSize = savedState->beginSection('SUBS'); dataSize = savedState->checkTag('SUBS');
result = lua_createtable(); result = lua_createtable();
@ -2950,8 +2908,8 @@ static void GetSaveGameData() {
for (;;) { for (;;) {
if (dataSize <= 0) if (dataSize <= 0)
break; break;
savedState->readBlock(&strSize, sizeof(int)); savedState->read(&strSize, sizeof(int));
savedState->readBlock(str, strSize); savedState->read(str, strSize);
lua_pushobject(result); lua_pushobject(result);
lua_pushnumber(count); lua_pushnumber(count);
lua_pushstring(str); lua_pushstring(str);
@ -2960,7 +2918,6 @@ static void GetSaveGameData() {
dataSize -= 4; dataSize -= 4;
count++; count++;
} }
savedState->endSection();
lua_pushobject(result); lua_pushobject(result);
delete savedState; delete savedState;
@ -3001,20 +2958,16 @@ static void Save() {
g_engine->_savegameSaveRequest = true; g_engine->_savegameSaveRequest = true;
} }
static int SaveCallback(int /*tag*/, int value, SaveGame * /*savedState*/) { static int SaveCallback(int /*tag*/, int value, SaveRestoreFunc /*savedState*/) {
DEBUG_FUNCTION(); DEBUG_FUNCTION();
return value; return value;
} }
static int RestoreCallback(int /*tag*/, int value, SaveGame * /*savedState*/) { static int RestoreCallback(int /*tag*/, int value, SaveRestoreFunc /*savedState*/) {
DEBUG_FUNCTION(); DEBUG_FUNCTION();
return value; return value;
} }
static void gc_font() {
check_font(1)->luaGc();
}
static void LockFont() { static void LockFont() {
lua_Object param1; lua_Object param1;
@ -3025,7 +2978,7 @@ static void LockFont() {
Font *result = g_resourceloader->loadFont(fontName); Font *result = g_resourceloader->loadFont(fontName);
if (result) { if (result) {
result->luaRef(); result->luaRef();
lua_pushusertag(result, tagFONT); lua_pushusertag(result, MKID('FONT'));
} }
} }
} }
@ -3089,7 +3042,7 @@ static void Display() {
} }
// refreshDrawMode ensures that the blinking cursor // refreshDrawMode ensures that the blinking cursor
// for the "text entry" renders correctly // for the "text entry" renders correctly
g_engine->refreshDrawMode(); //g_engine->refreshDrawMode(); -- disabled above hack
} }
static void EngineDisplay() { static void EngineDisplay() {
@ -3161,10 +3114,10 @@ static void debugFunction(char *debugMessage, const char *funcName) {
else if (lua_istable(lua_getparam(i))) else if (lua_istable(lua_getparam(i)))
fprintf(output, "{...}"); fprintf(output, "{...}");
else if (lua_isuserdata(lua_getparam(i))) { else if (lua_isuserdata(lua_getparam(i))) {
if (lua_tag(lua_getparam(i)) == tagACTR) { if (lua_tag(lua_getparam(i)) == MKID('ACTR')) {
Actor *a = check_actor(i); Actor *a = check_actor(i);
fprintf(output, "<actor \"%s\">", a->name()); fprintf(output, "<actor \"%s\">", a->name());
} else if (lua_tag(lua_getparam(i)) == tagCOLR) { } else if (lua_tag(lua_getparam(i)) == MKID('COLR')) {
Color *c = check_color(i); Color *c = check_color(i);
fprintf(output, "<color #%02x%02x%02x>", c->red(), c->green(), c->blue()); fprintf(output, "<color #%02x%02x%02x>", c->red(), c->green(), c->blue());
} else } else
@ -3779,29 +3732,6 @@ void register_lua() {
lua_pushnumber(0x8000); lua_pushnumber(0x8000);
lua_setglobal("HOT"); lua_setglobal("HOT");
// Create userdata tags, and set gc tagmethods
tagSTAT = lua_newtag();
tagACTR = lua_newtag();
tagCOLR = lua_newtag();
tagFONT = lua_newtag();
tagVBUF = lua_newtag();
tagPRIM = lua_newtag();
tagTEXT = lua_newtag();
lua_pushcfunction(gc_object);
lua_settagmethod(tagSTAT, "gc");
lua_pushcfunction(gc_actor);
lua_settagmethod(tagACTR, "gc");
lua_pushcfunction(gc_color);
lua_settagmethod(tagCOLR, "gc");
lua_pushcfunction(gc_font);
lua_settagmethod(tagFONT, "gc");
lua_pushcfunction(gc_bitmap);
lua_settagmethod(tagVBUF, "gc");
lua_pushcfunction(gc_primitive);
lua_settagmethod(tagPRIM, "gc");
lua_pushcfunction(gc_textobject);
lua_settagmethod(tagTEXT, "gc");
saveCallback = SaveCallback; saveCallback = SaveCallback;
restoreCallback = RestoreCallback; restoreCallback = RestoreCallback;
} }

View file

@ -106,59 +106,42 @@ static void recreateObj(TObject *obj) {
} }
} }
void restoreObjectValue(lua_Type *objectType, void *objectValue, SaveGame *savedState) { void lua_Restore(SaveRestoreFunc restoreFunc) {
int length;
savedState->readBlock(objectType, sizeof(lua_Type));
savedState->readBlock(&length, sizeof(int));
savedState->readBlock(objectValue, length);
}
void lua_Restore(SaveGame *savedState) {
printf("lua_Restore() started.\n"); printf("lua_Restore() started.\n");
lua_close(); lua_close();
L = luaM_new(lua_State); L = luaM_new(lua_State);
lua_resetglobals(); lua_resetglobals();
savedState->beginSection('LUAS'); restoreFunc(&arrayStringsCount, sizeof(int));
savedState->readBlock(&arrayStringsCount, sizeof(int)); restoreFunc(&arrayClosuresCount, sizeof(int));
savedState->readBlock(&arrayClosuresCount, sizeof(int)); restoreFunc(&arrayHashTablesCount, sizeof(int));
savedState->readBlock(&arrayHashTablesCount, sizeof(int)); restoreFunc(&arrayProtoFuncsCount, sizeof(int));
savedState->readBlock(&arrayProtoFuncsCount, sizeof(int));
int rootGlobalCount; int rootGlobalCount;
savedState->readBlock(&rootGlobalCount, sizeof(int)); restoreFunc(&rootGlobalCount, sizeof(int));
arrayStrings = (ArrayIDObj *)luaM_malloc(sizeof(ArrayIDObj) * arrayStringsCount); arrayStrings = (ArrayIDObj *)luaM_malloc(sizeof(ArrayIDObj) * arrayStringsCount);
ArrayIDObj *arraysObj = arrayStrings; ArrayIDObj *arraysObj = arrayStrings;
int maxStringsLength; int maxStringsLength;
savedState->readBlock(&maxStringsLength, sizeof(int)); restoreFunc(&maxStringsLength, sizeof(int));
char *tempStringBuffer = (char *)luaM_malloc(maxStringsLength); char *tempStringBuffer = (char *)luaM_malloc(maxStringsLength);
int i; int i;
for (i = 0; i < arrayStringsCount; i++) { for (i = 0; i < arrayStringsCount; i++) {
restoreFunc(&arraysObj->idObj, sizeof(unsigned int));
int constIndex; int constIndex;
restoreFunc(&constIndex, sizeof(int));
lua_Type tag; lua_Type tag;
restoreFunc(&tag, sizeof(int));
void *value; void *value;
restoreFunc(&value, sizeof(void *));
// Restore the string object
savedState->readBlock(&arraysObj->idObj, sizeof(TaggedString *));
// Restore the constant index
savedState->readBlock(&constIndex, sizeof(int));
// Restore the object value
restoreObjectValue(&tag, &value, savedState);
TaggedString *tempString; TaggedString *tempString;
if (constIndex != -1) { if (constIndex != -1) {
long length; long length;
// Restore the string length restoreFunc(&length, sizeof(long));
savedState->readBlock(&length, sizeof(long)); restoreFunc(tempStringBuffer, length);
if (length == 0) {
tempString = luaS_newlstr("", 0);
} else {
// Restore the string value
savedState->readBlock(tempStringBuffer, length);
tempString = luaS_newlstr(tempStringBuffer, length); tempString = luaS_newlstr(tempStringBuffer, length);
}
tempString->u.s.globalval.ttype = tag; tempString->u.s.globalval.ttype = tag;
tempString->u.s.globalval.value.ts = (TaggedString *)value; tempString->u.s.globalval.value.ts = (TaggedString *)value;
} else { } else {
@ -167,7 +150,7 @@ void lua_Restore(SaveGame *savedState) {
else else
tempString = luaS_createudata(value, tag); tempString = luaS_createudata(value, tag);
if (restoreCallback != NULL) { if (restoreCallback != NULL) {
tempString->u.s.globalval.value.ts = (TaggedString *)restoreCallback(tempString->u.s.globalval.ttype, (long)tempString->u.s.globalval.value.ts, savedState); tempString->u.s.globalval.value.ts = (TaggedString *)restoreCallback(tempString->u.s.globalval.ttype, (long)tempString->u.s.globalval.value.ts, restoreFunc);
} }
} }
tempString->constindex = constIndex; tempString->constindex = constIndex;
@ -181,15 +164,16 @@ void lua_Restore(SaveGame *savedState) {
arraysObj = (ArrayIDObj *)luaM_malloc(sizeof(ArrayIDObj) * arrayClosuresCount); arraysObj = (ArrayIDObj *)luaM_malloc(sizeof(ArrayIDObj) * arrayClosuresCount);
arrayClosures = arraysObj; arrayClosures = arraysObj;
for (i = 0; i < arrayClosuresCount; i++) { for (i = 0; i < arrayClosuresCount; i++) {
savedState->readBlock(&arraysObj->idObj, sizeof(Closure *)); restoreFunc(&arraysObj->idObj, sizeof(unsigned int));
int countElements; int countElements;
savedState->readBlock(&countElements, sizeof(int)); restoreFunc(&countElements, sizeof(int));
tempClosure = (Closure *)luaM_malloc((countElements * sizeof(TObject)) + sizeof(Closure)); tempClosure = (Closure *)luaM_malloc((countElements * sizeof(TObject)) + sizeof(Closure));
luaO_insertlist(&L->rootcl, (GCnode *)tempClosure); luaO_insertlist(&L->rootcl, (GCnode *)tempClosure);
tempClosure->nelems = countElements; tempClosure->nelems = countElements;
for (l = 0; l <= tempClosure->nelems; l++) { for (l = 0; l <= tempClosure->nelems; l++) {
restoreObjectValue(&tempClosure->consts[l].ttype, &tempClosure->consts[l].value, savedState); restoreFunc(&tempClosure->consts[l].ttype, sizeof(lua_Type));
restoreFunc(&tempClosure->consts[l].value, sizeof(Value));
} }
arraysObj->object = tempClosure; arraysObj->object = tempClosure;
arraysObj++; arraysObj++;
@ -199,17 +183,19 @@ void lua_Restore(SaveGame *savedState) {
arraysObj = (ArrayIDObj *)luaM_malloc(sizeof(ArrayIDObj) * arrayHashTablesCount); arraysObj = (ArrayIDObj *)luaM_malloc(sizeof(ArrayIDObj) * arrayHashTablesCount);
arrayHashTables = arraysObj; arrayHashTables = arraysObj;
for (i = 0; i < arrayHashTablesCount; i++) { for (i = 0; i < arrayHashTablesCount; i++) {
savedState->readBlock(&arraysObj->idObj, sizeof(Hash *)); restoreFunc(&arraysObj->idObj, sizeof(unsigned int));
tempHash = luaM_new(Hash); tempHash = luaM_new(Hash);
savedState->readBlock(&tempHash->nhash, sizeof(unsigned int)); restoreFunc(&tempHash->nhash, sizeof(int));
savedState->readBlock(&tempHash->nuse, sizeof(int)); restoreFunc(&tempHash->nuse, sizeof(int));
savedState->readBlock(&tempHash->htag, sizeof(int)); restoreFunc(&tempHash->htag, sizeof(int));
tempHash->node = hashnodecreate(tempHash->nhash); tempHash->node = hashnodecreate(tempHash->nhash);
luaO_insertlist(&L->roottable, (GCnode *)tempHash); luaO_insertlist(&L->roottable, (GCnode *)tempHash);
for (l = 0; l < tempHash->nuse; l++) { for (l = 0; l < tempHash->nuse; l++) {
restoreObjectValue(&tempHash->node[l].ref.ttype, &tempHash->node[l].ref.value, savedState); restoreFunc(&tempHash->node[l].ref.ttype, sizeof(lua_Type));
restoreObjectValue(&tempHash->node[l].val.ttype, &tempHash->node[l].val.value, savedState); restoreFunc(&tempHash->node[l].ref.value, sizeof(Value));
restoreFunc(&tempHash->node[l].val.ttype, sizeof(lua_Type));
restoreFunc(&tempHash->node[l].val.value, sizeof(Value));
} }
arraysObj->object = tempHash; arraysObj->object = tempHash;
arraysObj++; arraysObj++;
@ -219,20 +205,21 @@ void lua_Restore(SaveGame *savedState) {
arrayProtoFuncs = (ArrayIDObj *)luaM_malloc(sizeof(ArrayIDObj) * arrayProtoFuncsCount); arrayProtoFuncs = (ArrayIDObj *)luaM_malloc(sizeof(ArrayIDObj) * arrayProtoFuncsCount);
arraysObj = arrayProtoFuncs; arraysObj = arrayProtoFuncs;
for (i = 0; i < arrayProtoFuncsCount; i++) { for (i = 0; i < arrayProtoFuncsCount; i++) {
savedState->readBlock(&arraysObj->idObj, sizeof(TProtoFunc *)); restoreFunc(&arraysObj->idObj, sizeof(unsigned int));
tempProtoFunc = luaM_new(TProtoFunc); tempProtoFunc = luaM_new(TProtoFunc);
luaO_insertlist(&L->rootproto, (GCnode *)tempProtoFunc); luaO_insertlist(&L->rootproto, (GCnode *)tempProtoFunc);
savedState->readBlock(&tempProtoFunc->fileName, sizeof(TaggedString *)); restoreFunc(&tempProtoFunc->fileName, sizeof(TaggedString *));
savedState->readBlock(&tempProtoFunc->lineDefined, sizeof(unsigned int)); restoreFunc(&tempProtoFunc->lineDefined, sizeof(int));
savedState->readBlock(&tempProtoFunc->nconsts, sizeof(unsigned int)); restoreFunc(&tempProtoFunc->nconsts, sizeof(int));
tempProtoFunc->consts = (TObject *)luaM_malloc(tempProtoFunc->nconsts * sizeof(TObject)); tempProtoFunc->consts = (TObject *)luaM_malloc(tempProtoFunc->nconsts * sizeof(TObject));
for (l = 0; l < tempProtoFunc->nconsts; l++) { for (l = 0; l < tempProtoFunc->nconsts; l++) {
restoreObjectValue(&tempProtoFunc->consts[l].ttype, &tempProtoFunc->consts[l].value, savedState); restoreFunc(&tempProtoFunc->consts[l].ttype, sizeof(lua_Type));
restoreFunc(&tempProtoFunc->consts[l].value, sizeof(Value));
} }
int countVariables; int countVariables;
savedState->readBlock(&countVariables, sizeof(int)); restoreFunc(&countVariables, sizeof(int));
if (countVariables != 0) { if (countVariables != 0) {
tempProtoFunc->locvars = (LocVar *)luaM_malloc(countVariables * sizeof(LocVar)); tempProtoFunc->locvars = (LocVar *)luaM_malloc(countVariables * sizeof(LocVar));
} else { } else {
@ -240,14 +227,14 @@ void lua_Restore(SaveGame *savedState) {
} }
for (l = 0; l < countVariables; l++) { for (l = 0; l < countVariables; l++) {
savedState->readBlock(&tempProtoFunc->locvars[l].varname, sizeof(TaggedString *)); restoreFunc(&tempProtoFunc->locvars[l].varname, sizeof(TaggedString *));
savedState->readBlock(&tempProtoFunc->locvars[l].line, sizeof(int)); restoreFunc(&tempProtoFunc->locvars[l].line, sizeof(int));
} }
int codeSize; int codeSize;
savedState->readBlock(&codeSize, sizeof(int)); restoreFunc(&codeSize, sizeof(int));
tempProtoFunc->code = (lua_Byte *)luaM_malloc(codeSize); tempProtoFunc->code = (lua_Byte *)luaM_malloc(codeSize);
savedState->readBlock(tempProtoFunc->code, codeSize); restoreFunc(tempProtoFunc->code, codeSize);
arraysObj->object = tempProtoFunc; arraysObj->object = tempProtoFunc;
arraysObj++; arraysObj++;
} }
@ -318,7 +305,7 @@ void lua_Restore(SaveGame *savedState) {
TObject tempObj; TObject tempObj;
TaggedString *tempString = NULL; TaggedString *tempString = NULL;
tempObj.ttype = LUA_T_STRING; tempObj.ttype = LUA_T_STRING;
savedState->readBlock(&tempObj.value, sizeof(TaggedString *)); restoreFunc(&tempObj.value, sizeof(TaggedString *));
recreateObj(&tempObj); recreateObj(&tempObj);
tempString = (TaggedString *)tempObj.value.ts; tempString = (TaggedString *)tempObj.value.ts;
assert(tempString); assert(tempString);
@ -327,44 +314,47 @@ void lua_Restore(SaveGame *savedState) {
} }
tempListString->head.next = NULL; tempListString->head.next = NULL;
restoreObjectValue(&L->errorim.ttype, &L->errorim.value, savedState); restoreFunc(&L->errorim.ttype, sizeof(lua_Type));
restoreFunc(&L->errorim.value, sizeof(Value));
recreateObj(&L->errorim); recreateObj(&L->errorim);
savedState->readBlock(&L->IMtable_size, sizeof(int)); restoreFunc(&L->IMtable_size, sizeof(int));
L->IMtable = (IM *)luaM_malloc(L->IMtable_size * sizeof(IM)); L->IMtable = (IM *)luaM_malloc(L->IMtable_size * sizeof(IM));
for (i = 0; i < L->IMtable_size; i++) { for (i = 0; i < L->IMtable_size; i++) {
IM *im = &L->IMtable[i]; IM *im = &L->IMtable[i];
for (l = 0; l < IM_N; l++) { for (l = 0; l < IM_N; l++) {
restoreObjectValue(&im->int_method[l].ttype, &im->int_method[l].value, savedState); restoreFunc(&im->int_method[l].ttype, sizeof(lua_Type));
restoreFunc(&im->int_method[l].value, sizeof(Value));
recreateObj(&im->int_method[l]); recreateObj(&im->int_method[l]);
} }
} }
savedState->readBlock(&L->last_tag, sizeof(int)); restoreFunc(&L->last_tag, sizeof(int));
savedState->readBlock(&L->refSize, sizeof(int)); restoreFunc(&L->refSize, sizeof(int));
L->refArray = (ref *)luaM_malloc(L->refSize * sizeof(ref)); L->refArray = (ref *)luaM_malloc(L->refSize * sizeof(ref));
for (i = 0; i < L->refSize; i++) { for (i = 0; i < L->refSize; i++) {
restoreObjectValue(&L->refArray[i].o.ttype, &L->refArray[i].o.value, savedState); restoreFunc(&L->refArray[i].o.ttype, sizeof(lua_Type));
restoreFunc(&L->refArray[i].o.value, sizeof(Value));
recreateObj(&L->refArray[i].o); recreateObj(&L->refArray[i].o);
savedState->readBlock(&L->refArray[i].status, sizeof(Status)); restoreFunc(&L->refArray[i].status, sizeof(Status));
} }
savedState->readBlock(&L->GCthreshold, sizeof(unsigned long)); restoreFunc(&L->GCthreshold, sizeof(unsigned long));
savedState->readBlock(&L->nblocks, sizeof(unsigned long)); restoreFunc(&L->nblocks, sizeof(unsigned long));
savedState->readBlock(&L->Mbuffsize, sizeof(int)); restoreFunc(&L->Mbuffsize, sizeof(int));
L->Mbuffer = (char *)luaM_malloc(L->Mbuffsize); L->Mbuffer = (char *)luaM_malloc(L->Mbuffsize);
savedState->readBlock(L->Mbuffer, L->Mbuffsize); restoreFunc(L->Mbuffer, L->Mbuffsize);
int MbaseOffset; int MbaseOffset;
savedState->readBlock(&MbaseOffset, sizeof(int)); restoreFunc(&MbaseOffset, sizeof(int));
L->Mbuffbase = MbaseOffset + L->Mbuffer; L->Mbuffbase = MbaseOffset + L->Mbuffer;
savedState->readBlock(&L->Mbuffnext, sizeof(int)); restoreFunc(&L->Mbuffnext, sizeof(int));
savedState->readBlock(&globalTaskSerialId, sizeof(int)); restoreFunc(&globalTaskSerialId, sizeof(int));
int countTasks; int countTasks;
lua_Task *tempTask = NULL; lua_Task *tempTask = NULL;
savedState->readBlock(&countTasks, sizeof(int)); restoreFunc(&countTasks, sizeof(int));
lua_Task *prevTask = L->root_task; lua_Task *prevTask = L->root_task;
for (l = 0; l < countTasks; l++) { for (l = 0; l < countTasks; l++) {
tempTask = luaM_new(lua_Task); tempTask = luaM_new(lua_Task);
@ -373,31 +363,32 @@ void lua_Restore(SaveGame *savedState) {
prevTask = tempTask; prevTask = tempTask;
int stackLastSize; int stackLastSize;
savedState->readBlock(&stackLastSize, sizeof(int)); restoreFunc(&stackLastSize, sizeof(int));
tempTask->stack.stack = (TObject *)luaM_malloc(stackLastSize * sizeof(TObject)); tempTask->stack.stack = (TObject *)luaM_malloc(stackLastSize * sizeof(TObject));
tempTask->stack.last = tempTask->stack.stack + stackLastSize - 1; tempTask->stack.last = tempTask->stack.stack + stackLastSize - 1;
int stackTopSize; int stackTopSize;
savedState->readBlock(&stackTopSize, sizeof(int)); restoreFunc(&stackTopSize, sizeof(int));
tempTask->stack.top = tempTask->stack.stack + stackTopSize; tempTask->stack.top = tempTask->stack.stack + stackTopSize;
for (i = 0; i < stackTopSize; i++) { for (i = 0; i < stackTopSize; i++) {
restoreObjectValue(&tempTask->stack.stack[i].ttype, &tempTask->stack.stack[i].value, savedState); restoreFunc(&tempTask->stack.stack[i].ttype, sizeof(lua_Type));
restoreFunc(&tempTask->stack.stack[i].value, sizeof(Value));
recreateObj(&tempTask->stack.stack[i]); recreateObj(&tempTask->stack.stack[i]);
} }
savedState->readBlock(&tempTask->Cstack.base, sizeof(StkId)); restoreFunc(&tempTask->Cstack.base, sizeof(StkId));
savedState->readBlock(&tempTask->Cstack.lua2C, sizeof(StkId)); restoreFunc(&tempTask->Cstack.lua2C, sizeof(StkId));
savedState->readBlock(&tempTask->Cstack.num, sizeof(int)); restoreFunc(&tempTask->Cstack.num, sizeof(int));
savedState->readBlock(&tempTask->numCblocks, sizeof(int)); restoreFunc(&tempTask->numCblocks, sizeof(int));
for (i = 0; i < tempTask->numCblocks; i++) { for (i = 0; i < tempTask->numCblocks; i++) {
savedState->readBlock(&tempTask->Cblocks[i].base, sizeof(StkId)); restoreFunc(&tempTask->Cblocks[i].base, sizeof(StkId));
savedState->readBlock(&tempTask->Cblocks[i].lua2C, sizeof(StkId)); restoreFunc(&tempTask->Cblocks[i].lua2C, sizeof(StkId));
savedState->readBlock(&tempTask->Cblocks[i].num, sizeof(int)); restoreFunc(&tempTask->Cblocks[i].num, sizeof(int));
} }
int pcOffset, taskCi; int pcOffset, taskCi;
savedState->readBlock(&tempTask->base_ci_size, sizeof(int)); restoreFunc(&tempTask->base_ci_size, sizeof(int));
tempTask->base_ci = (CallInfo *)luaM_malloc(tempTask->base_ci_size * sizeof(CallInfo)); tempTask->base_ci = (CallInfo *)luaM_malloc(tempTask->base_ci_size * sizeof(CallInfo));
memset(tempTask->base_ci, 0, sizeof(CallInfo) * tempTask->base_ci_size); memset(tempTask->base_ci, 0, sizeof(CallInfo) * tempTask->base_ci_size);
CallInfo *tempCi = tempTask->base_ci; CallInfo *tempCi = tempTask->base_ci;
@ -405,35 +396,35 @@ void lua_Restore(SaveGame *savedState) {
for (i = 0; i < countCi; i++) { for (i = 0; i < countCi; i++) {
TObject tempObj; TObject tempObj;
tempObj.ttype = LUA_T_CLOSURE; tempObj.ttype = LUA_T_CLOSURE;
savedState->readBlock(&tempObj.value, sizeof(Closure *)); restoreFunc(&tempObj.value, sizeof(Closure *));
recreateObj(&tempObj); recreateObj(&tempObj);
tempCi->c = (Closure *)tempObj.value.cl; tempCi->c = (Closure *)tempObj.value.cl;
tempObj.ttype = LUA_T_PROTO; tempObj.ttype = LUA_T_PROTO;
savedState->readBlock(&tempObj.value, sizeof(TProtoFunc *)); restoreFunc(&tempObj.value, sizeof(TProtoFunc *));
recreateObj(&tempObj); recreateObj(&tempObj);
tempCi->tf = (TProtoFunc *)tempObj.value.tf; tempCi->tf = (TProtoFunc *)tempObj.value.tf;
savedState->readBlock(&pcOffset, sizeof(int)); restoreFunc(&pcOffset, sizeof(int));
if (pcOffset != 0) if (pcOffset != 0)
tempCi->pc = tempCi->tf->code + pcOffset; tempCi->pc = tempCi->tf->code + pcOffset;
else else
tempCi->pc = NULL; tempCi->pc = NULL;
savedState->readBlock(&tempCi->base, sizeof(StkId)); restoreFunc(&tempCi->base, sizeof(StkId));
savedState->readBlock(&tempCi->nResults, sizeof(int)); restoreFunc(&tempCi->nResults, sizeof(int));
tempCi++; tempCi++;
} }
savedState->readBlock(&taskCi, sizeof(int)); restoreFunc(&taskCi, sizeof(int));
tempTask->ci = tempTask->base_ci + taskCi; tempTask->ci = tempTask->base_ci + taskCi;
tempTask->end_ci = tempTask->base_ci + countCi; tempTask->end_ci = tempTask->base_ci + countCi;
int Mbasepos; int Mbasepos;
savedState->readBlock(&Mbasepos, sizeof(int)); restoreFunc(&Mbasepos, sizeof(int));
tempTask->Mbuffbase = Mbasepos + tempTask->Mbuffer; tempTask->Mbuffbase = Mbasepos + tempTask->Mbuffer;
savedState->readBlock(&tempTask->Mbuffnext, sizeof(int)); restoreFunc(&tempTask->Mbuffnext, sizeof(int));
savedState->readBlock(&tempTask->Tstate, sizeof(TaskState)); restoreFunc(&tempTask->Tstate, sizeof(TaskState));
savedState->readBlock(&tempTask->id, sizeof(int)); restoreFunc(&tempTask->id, sizeof(int));
} }
L->last_task = tempTask; L->last_task = tempTask;
@ -451,6 +442,5 @@ void lua_Restore(SaveGame *savedState) {
arrayProtoFuncs = NULL; arrayProtoFuncs = NULL;
arrayStrings = NULL; arrayStrings = NULL;
savedState->endSection();
printf("lua_Restore() finished.\n"); printf("lua_Restore() finished.\n");
} }

View file

@ -14,22 +14,16 @@
SaveRestoreCallback saveCallback = NULL; SaveRestoreCallback saveCallback = NULL;
static void saveObjectValue(TObject *object, SaveGame *savedState) { static void saveObjectValue(TObject *object, SaveRestoreFunc saveFunc) {
int length; saveFunc(&object->ttype, sizeof(lua_Type));
// Note: Now stores the length of the object value
// ("unsigned int" and "Value" are different lengths)
savedState->writeBlock(&object->ttype, sizeof(lua_Type));
if (object->ttype == LUA_T_CPROTO) { if (object->ttype == LUA_T_CPROTO) {
luaL_libList *list = list_of_libs; luaL_libList *list = list_of_libs;
unsigned long idObj = 0; unsigned int idObj = 0;
while (list != NULL) { while (list != NULL) {
for (int l = 0; l < list->number; l++) { for (int l = 0; l < list->number; l++) {
if (list->list[l].func == object->value.f) { if (list->list[l].func == object->value.f) {
idObj = (idObj << 16) | l; idObj = (idObj << 16) | l;
length = sizeof(unsigned long); saveFunc(&idObj, sizeof(unsigned int));
savedState->writeBlock(&length, sizeof(int));
savedState->writeBlock(&idObj, length);
return; return;
} }
} }
@ -38,9 +32,7 @@ static void saveObjectValue(TObject *object, SaveGame *savedState) {
} }
assert(0); assert(0);
} else { } else {
length = sizeof(Value); saveFunc(&object->value, sizeof(Value));
savedState->writeBlock(&length, sizeof(int));
savedState->writeBlock(&object->value, length);
} }
} }
@ -60,10 +52,9 @@ static int opcodeSizeTable[] = {
2, 3, 2, 3, 2, 3, 2, 1, 1, 3, 2, 2, 2, 2, 3, 2, 1, 1 2, 3, 2, 3, 2, 3, 2, 1, 1, 3, 2, 2, 2, 2, 3, 2, 1, 1
}; };
void lua_Save(SaveGame *savedState) { void lua_Save(SaveRestoreFunc saveFunc) {
printf("lua_Save() started.\n"); printf("lua_Save() started.\n");
savedState->beginSection('LUAS');
lua_collectgarbage(0); lua_collectgarbage(0);
int i, l; int i, l;
int countElements = 0; int countElements = 0;
@ -82,7 +73,7 @@ void lua_Save(SaveGame *savedState) {
} }
} }
savedState->writeBlock(&countElements, sizeof(int)); saveFunc(&countElements, sizeof(int));
countElements = 0; countElements = 0;
GCnode *tempNode; GCnode *tempNode;
@ -91,7 +82,7 @@ void lua_Save(SaveGame *savedState) {
countElements++; countElements++;
tempNode = tempNode->next; tempNode = tempNode->next;
} }
savedState->writeBlock(&countElements, sizeof(int)); saveFunc(&countElements, sizeof(int));
countElements = 0; countElements = 0;
tempNode = L->roottable.next; tempNode = L->roottable.next;
@ -99,7 +90,7 @@ void lua_Save(SaveGame *savedState) {
countElements++; countElements++;
tempNode = tempNode->next; tempNode = tempNode->next;
} }
savedState->writeBlock(&countElements, sizeof(int)); saveFunc(&countElements, sizeof(int));
countElements = 0; countElements = 0;
tempNode = L->rootproto.next; tempNode = L->rootproto.next;
@ -107,7 +98,7 @@ void lua_Save(SaveGame *savedState) {
countElements++; countElements++;
tempNode = tempNode->next; tempNode = tempNode->next;
} }
savedState->writeBlock(&countElements, sizeof(int)); saveFunc(&countElements, sizeof(int));
countElements = 0; countElements = 0;
tempNode = L->rootglobal.next; tempNode = L->rootglobal.next;
@ -115,9 +106,9 @@ void lua_Save(SaveGame *savedState) {
countElements++; countElements++;
tempNode = tempNode->next; tempNode = tempNode->next;
} }
savedState->writeBlock(&countElements, sizeof(int)); saveFunc(&countElements, sizeof(int));
savedState->writeBlock(&maxStringLength, sizeof(int)); saveFunc(&maxStringLength, sizeof(int));
TaggedString *tempString; TaggedString *tempString;
for (i = 0; i < NUM_HASHS; i++) { for (i = 0; i < NUM_HASHS; i++) {
@ -125,24 +116,17 @@ void lua_Save(SaveGame *savedState) {
for (l = 0; l < tempStringTable->size; l++) { for (l = 0; l < tempStringTable->size; l++) {
if ((tempStringTable->hash[l] != NULL) && (tempStringTable->hash[l] != &EMPTY)) { if ((tempStringTable->hash[l] != NULL) && (tempStringTable->hash[l] != &EMPTY)) {
tempString = tempStringTable->hash[l]; tempString = tempStringTable->hash[l];
// Save the string object saveFunc(&tempString, sizeof(TaggedString *));
savedState->writeBlock(&tempString, sizeof(TaggedString *)); saveFunc(&tempString->constindex, sizeof(int));
// Save the constant index
savedState->writeBlock(&tempString->constindex, sizeof(int));
if (tempString->constindex != -1) { if (tempString->constindex != -1) {
// Save the object value saveObjectValue(&tempString->u.s.globalval, saveFunc);
saveObjectValue(&tempString->u.s.globalval, savedState); saveFunc(&tempString->u.s.len, sizeof(long));
// Save the string length saveFunc(tempString->str, tempString->u.s.len);
savedState->writeBlock(&tempString->u.s.len, sizeof(long));
// Save the string value
if (tempString->u.s.len != 0)
savedState->writeBlock(tempString->str, tempString->u.s.len);
} else { } else {
if (saveCallback != NULL) { if (saveCallback != NULL) {
tempString->u.s.globalval.value.ts = (TaggedString *)saveCallback(tempString->u.s.globalval.ttype, (long)tempString->u.s.globalval.value.ts, savedState); tempString->u.s.globalval.value.ts = (TaggedString *)saveCallback(tempString->u.s.globalval.ttype, (long)tempString->u.s.globalval.value.ts, saveFunc);
} }
// Save the object value saveObjectValue(&tempString->u.s.globalval, saveFunc);
saveObjectValue(&tempString->u.s.globalval, savedState);
} }
} }
} }
@ -150,18 +134,18 @@ void lua_Save(SaveGame *savedState) {
Closure *tempClosure = (Closure *)L->rootcl.next; Closure *tempClosure = (Closure *)L->rootcl.next;
while (tempClosure != NULL) { while (tempClosure != NULL) {
savedState->writeBlock(&tempClosure, sizeof(Closure *)); saveFunc(&tempClosure, sizeof(Closure *));
savedState->writeBlock(&tempClosure->nelems, sizeof(int)); saveFunc(&tempClosure->nelems, sizeof(int));
for(i = 0; i <= tempClosure->nelems; i++) { for(i = 0; i <= tempClosure->nelems; i++) {
saveObjectValue(&tempClosure->consts[i], savedState); saveObjectValue(&tempClosure->consts[i], saveFunc);
} }
tempClosure = (Closure *)tempClosure->head.next; tempClosure = (Closure *)tempClosure->head.next;
} }
Hash *tempHash = (Hash *)L->roottable.next; Hash *tempHash = (Hash *)L->roottable.next;
while (tempHash != NULL) { while (tempHash != NULL) {
savedState->writeBlock(&tempHash, sizeof(Hash *)); saveFunc(&tempHash, sizeof(Hash *));
savedState->writeBlock(&tempHash->nhash, sizeof(unsigned int)); saveFunc(&tempHash->nhash, sizeof(unsigned int));
int countUsedHash = 0; int countUsedHash = 0;
for(i = 0; i < tempHash->nhash; i++) { for(i = 0; i < tempHash->nhash; i++) {
Node *newNode = &tempHash->node[i]; Node *newNode = &tempHash->node[i];
@ -169,13 +153,13 @@ void lua_Save(SaveGame *savedState) {
countUsedHash++; countUsedHash++;
} }
} }
savedState->writeBlock(&countUsedHash, sizeof(int)); saveFunc(&countUsedHash, sizeof(int));
savedState->writeBlock(&tempHash->htag, sizeof(int)); saveFunc(&tempHash->htag, sizeof(int));
for (i = 0; i < tempHash->nhash; i++) { for (i = 0; i < tempHash->nhash; i++) {
Node *newNode = &tempHash->node[i]; Node *newNode = &tempHash->node[i];
if ((newNode->val.ttype != LUA_T_NIL) && (newNode->ref.ttype != LUA_T_NIL)) { if ((newNode->val.ttype != LUA_T_NIL) && (newNode->ref.ttype != LUA_T_NIL)) {
saveObjectValue(&tempHash->node[i].ref, savedState); saveObjectValue(&tempHash->node[i].ref, saveFunc);
saveObjectValue(&tempHash->node[i].val, savedState); saveObjectValue(&tempHash->node[i].val, saveFunc);
} }
} }
tempHash = (Hash *)tempHash->head.next; tempHash = (Hash *)tempHash->head.next;
@ -183,22 +167,22 @@ void lua_Save(SaveGame *savedState) {
TProtoFunc *tempProtoFunc = (TProtoFunc *)L->rootproto.next; TProtoFunc *tempProtoFunc = (TProtoFunc *)L->rootproto.next;
while (tempProtoFunc != NULL) { while (tempProtoFunc != NULL) {
savedState->writeBlock(&tempProtoFunc, sizeof(TProtoFunc *)); saveFunc(&tempProtoFunc, sizeof(TProtoFunc *));
savedState->writeBlock(&tempProtoFunc->fileName, sizeof(TaggedString *)); saveFunc(&tempProtoFunc->fileName, sizeof(TaggedString *));
savedState->writeBlock(&tempProtoFunc->lineDefined, sizeof(unsigned int)); saveFunc(&tempProtoFunc->lineDefined, sizeof(unsigned int));
savedState->writeBlock(&tempProtoFunc->nconsts, sizeof(unsigned int)); saveFunc(&tempProtoFunc->nconsts, sizeof(unsigned int));
for (i = 0; i < tempProtoFunc->nconsts; i++) { for (i = 0; i < tempProtoFunc->nconsts; i++) {
saveObjectValue(&tempProtoFunc->consts[i], savedState); saveObjectValue(&tempProtoFunc->consts[i], saveFunc);
} }
int countVariables = 0; int countVariables = 0;
if (tempProtoFunc->locvars) { if (tempProtoFunc->locvars) {
for (; tempProtoFunc->locvars[countVariables++].line != -1;) { } for (; tempProtoFunc->locvars[countVariables++].line != -1;) { }
} }
savedState->writeBlock(&countVariables, sizeof(int)); saveFunc(&countVariables, sizeof(int));
for (i = 0; i < countVariables; i++) { for (i = 0; i < countVariables; i++) {
savedState->writeBlock(&tempProtoFunc->locvars[i].varname, sizeof(TaggedString *)); saveFunc(&tempProtoFunc->locvars[i].varname, sizeof(TaggedString *));
savedState->writeBlock(&tempProtoFunc->locvars[i].line, sizeof(int)); saveFunc(&tempProtoFunc->locvars[i].line, sizeof(int));
} }
Byte *codePtr = tempProtoFunc->code + 2; Byte *codePtr = tempProtoFunc->code + 2;
@ -209,45 +193,45 @@ void lua_Save(SaveGame *savedState) {
tmpPtr += opcodeSizeTable[opcodeId]; tmpPtr += opcodeSizeTable[opcodeId];
} while (opcodeId != ENDCODE); } while (opcodeId != ENDCODE);
int codeSize = (tmpPtr - codePtr) + 2; int codeSize = (tmpPtr - codePtr) + 2;
savedState->writeBlock(&codeSize, sizeof(int)); saveFunc(&codeSize, sizeof(int));
savedState->writeBlock(tempProtoFunc->code, codeSize); saveFunc(tempProtoFunc->code, codeSize);
tempProtoFunc = (TProtoFunc *)tempProtoFunc->head.next; tempProtoFunc = (TProtoFunc *)tempProtoFunc->head.next;
} }
tempString = (TaggedString *)L->rootglobal.next; tempString = (TaggedString *)L->rootglobal.next;
while (tempString != NULL) { while (tempString != NULL) {
savedState->writeBlock(&tempString, sizeof(TaggedString *)); saveFunc(&tempString, sizeof(TaggedString *));
tempString = (TaggedString *)tempString->head.next; tempString = (TaggedString *)tempString->head.next;
} }
saveObjectValue(&L->errorim, savedState); saveObjectValue(&L->errorim, saveFunc);
IM *tempIm = L->IMtable; IM *tempIm = L->IMtable;
savedState->writeBlock(&L->IMtable_size, sizeof(int)); saveFunc(&L->IMtable_size, sizeof(int));
for (i = 0; i < L->IMtable_size; i++) { for (i = 0; i < L->IMtable_size; i++) {
for (l = 0; l < IM_N; l++) { for (l = 0; l < IM_N; l++) {
saveObjectValue(&tempIm->int_method[l], savedState); saveObjectValue(&tempIm->int_method[l], saveFunc);
} }
tempIm++; tempIm++;
} }
savedState->writeBlock(&L->last_tag, sizeof(int)); saveFunc(&L->last_tag, sizeof(int));
savedState->writeBlock(&L->refSize, sizeof(int)); saveFunc(&L->refSize, sizeof(int));
for (i = 0 ; i < L->refSize; i++) { for (i = 0 ; i < L->refSize; i++) {
saveObjectValue(&L->refArray[i].o, savedState); saveObjectValue(&L->refArray[i].o, saveFunc);
savedState->writeBlock(&L->refArray[i].status, sizeof(Status)); saveFunc(&L->refArray[i].status, sizeof(Status));
} }
savedState->writeBlock(&L->GCthreshold, sizeof(unsigned long)); saveFunc(&L->GCthreshold, sizeof(unsigned long));
savedState->writeBlock(&L->nblocks, sizeof(unsigned long)); saveFunc(&L->nblocks, sizeof(unsigned long));
savedState->writeBlock(&L->Mbuffsize, sizeof(int)); saveFunc(&L->Mbuffsize, sizeof(int));
savedState->writeBlock(L->Mbuffer, L->Mbuffsize); saveFunc(L->Mbuffer, L->Mbuffsize);
int MbaseOffset = L->Mbuffbase - L->Mbuffer; int MbaseOffset = L->Mbuffbase - L->Mbuffer;
savedState->writeBlock(&MbaseOffset, sizeof(int)); saveFunc(&MbaseOffset, sizeof(int));
savedState->writeBlock(&L->Mbuffnext, sizeof(int)); saveFunc(&L->Mbuffnext, sizeof(int));
savedState->writeBlock(&globalTaskSerialId, sizeof(int)); saveFunc(&globalTaskSerialId, sizeof(int));
int countTasks = 0; int countTasks = 0;
lua_Task *tempTask = L->root_task->next; lua_Task *tempTask = L->root_task->next;
@ -255,61 +239,60 @@ void lua_Save(SaveGame *savedState) {
countTasks++; countTasks++;
tempTask = tempTask->next; tempTask = tempTask->next;
} }
savedState->writeBlock(&countTasks, sizeof(int)); saveFunc(&countTasks, sizeof(int));
tempTask = L->root_task->next; tempTask = L->root_task->next;
while (tempTask != NULL) { while (tempTask != NULL) {
int stackLastSize = (tempTask->stack.last - tempTask->stack.stack) + 1; int stackLastSize = (tempTask->stack.last - tempTask->stack.stack) + 1;
savedState->writeBlock(&stackLastSize, sizeof(int)); saveFunc(&stackLastSize, sizeof(int));
int stackTopSize = tempTask->stack.top - tempTask->stack.stack; int stackTopSize = tempTask->stack.top - tempTask->stack.stack;
savedState->writeBlock(&stackTopSize, sizeof(int)); saveFunc(&stackTopSize, sizeof(int));
for (i = 0; i < stackTopSize; i++) { for (i = 0; i < stackTopSize; i++) {
saveObjectValue(&tempTask->stack.stack[i], savedState); saveObjectValue(&tempTask->stack.stack[i], saveFunc);
} }
savedState->writeBlock(&tempTask->Cstack.base, sizeof(StkId)); saveFunc(&tempTask->Cstack.base, sizeof(StkId));
savedState->writeBlock(&tempTask->Cstack.lua2C, sizeof(StkId)); saveFunc(&tempTask->Cstack.lua2C, sizeof(StkId));
savedState->writeBlock(&tempTask->Cstack.num, sizeof(int)); saveFunc(&tempTask->Cstack.num, sizeof(int));
savedState->writeBlock(&tempTask->numCblocks, sizeof(int)); saveFunc(&tempTask->numCblocks, sizeof(int));
for (i = 0; i < tempTask->numCblocks; i++) { for (i = 0; i < tempTask->numCblocks; i++) {
savedState->writeBlock(&tempTask->Cblocks[i].base, sizeof(StkId)); saveFunc(&tempTask->Cblocks[i].base, sizeof(StkId));
savedState->writeBlock(&tempTask->Cblocks[i].lua2C, sizeof(StkId)); saveFunc(&tempTask->Cblocks[i].lua2C, sizeof(StkId));
savedState->writeBlock(&tempTask->Cblocks[i].num, sizeof(int)); saveFunc(&tempTask->Cblocks[i].num, sizeof(int));
} }
int pcOffset, taskCi = -1; int pcOffset, taskCi = -1;
savedState->writeBlock(&tempTask->base_ci_size, sizeof(int)); saveFunc(&tempTask->base_ci_size, sizeof(int));
assert(tempTask->base_ci); assert(tempTask->base_ci);
CallInfo *tempCi = tempTask->base_ci; CallInfo *tempCi = tempTask->base_ci;
int countCi = tempTask->base_ci_size / sizeof(CallInfo); int countCi = tempTask->base_ci_size / sizeof(CallInfo);
for (i = 0; i < countCi; i++) { for (i = 0; i < countCi; i++) {
savedState->writeBlock(&tempCi->c, sizeof(Closure *)); saveFunc(&tempCi->c, sizeof(Closure *));
savedState->writeBlock(&tempCi->tf, sizeof(TProtoFunc *)); saveFunc(&tempCi->tf, sizeof(TProtoFunc *));
if ((tempCi->pc != NULL) && (tempTask->ci->tf != NULL)) if ((tempCi->pc != NULL) && (tempTask->ci->tf != NULL))
pcOffset = tempCi->pc - tempCi->tf->code; pcOffset = tempCi->pc - tempCi->tf->code;
else else
pcOffset = 0; pcOffset = 0;
savedState->writeBlock(&pcOffset, sizeof(int)); saveFunc(&pcOffset, sizeof(int));
savedState->writeBlock(&tempCi->base, sizeof(StkId)); saveFunc(&tempCi->base, sizeof(StkId));
savedState->writeBlock(&tempCi->nResults, sizeof(int)); saveFunc(&tempCi->nResults, sizeof(int));
if (tempCi == tempTask->ci) if (tempCi == tempTask->ci)
taskCi = i; taskCi = i;
tempCi++; tempCi++;
} }
assert(taskCi != -1); assert(taskCi != -1);
savedState->writeBlock(&taskCi, sizeof(int)); saveFunc(&taskCi, sizeof(int));
MbaseOffset = tempTask->Mbuffbase - tempTask->Mbuffer; MbaseOffset = tempTask->Mbuffbase - tempTask->Mbuffer;
savedState->writeBlock(&MbaseOffset, sizeof(int)); saveFunc(&MbaseOffset, sizeof(int));
savedState->writeBlock(&tempTask->Mbuffnext, sizeof(int)); saveFunc(&tempTask->Mbuffnext, sizeof(int));
savedState->writeBlock(&tempTask->Tstate, sizeof(TaskState)); saveFunc(&tempTask->Tstate, sizeof(TaskState));
savedState->writeBlock(&tempTask->id, sizeof(int)); saveFunc(&tempTask->id, sizeof(int));
tempTask = tempTask->next; tempTask = tempTask->next;
} }
savedState->endSection();
printf("lua_Save() finished.\n"); printf("lua_Save() finished.\n");
} }

View file

@ -28,15 +28,14 @@ typedef unsigned int lua_Object;
typedef struct lua_State lua_State; typedef struct lua_State lua_State;
extern lua_State *lua_state; extern lua_State *lua_state;
#include "savegame.h" typedef void (*SaveRestoreFunc)(void *, int);
typedef int (*SaveRestoreCallback)(int, int, SaveRestoreFunc);
typedef int (*SaveRestoreCallback)(int, int, SaveGame *);
extern SaveRestoreCallback saveCallback; extern SaveRestoreCallback saveCallback;
extern SaveRestoreCallback restoreCallback; extern SaveRestoreCallback restoreCallback;
void lua_Save(SaveGame *); void lua_Save(SaveRestoreFunc);
void lua_Restore(SaveGame *); void lua_Restore(SaveRestoreFunc);
void lua_removelibslists(void); void lua_removelibslists(void);

View file

@ -29,8 +29,7 @@
// Constructor. Should create/open a saved game // Constructor. Should create/open a saved game
SaveGame::SaveGame(char *filename, bool saving) : SaveGame::SaveGame(char *filename, bool saving) :
_saving(saving), _currentSection(0) _saving(saving) {
{
if (_saving) { if (_saving) {
uint32 tag = SAVEGAME_HEADERTAG; uint32 tag = SAVEGAME_HEADERTAG;
uint32 version = SAVEGAME_VERSION; uint32 version = SAVEGAME_VERSION;
@ -64,58 +63,31 @@ SaveGame::~SaveGame() {
gzclose(_fileHandle); gzclose(_fileHandle);
} }
uint32 SaveGame::beginSection(uint32 sectionTag) { int SaveGame::read(void *data, int size) {
if (_currentSection != 0)
error("Tried to begin a new save game section with ending old section!");
_currentSection = sectionTag;
_sectionSize = 0;
_sectionBuffer = (char *) malloc(_sectionSize);
if (!_saving) {
uint32 tag = 0;
while (tag != sectionTag) {
free(_sectionBuffer);
gzread(_fileHandle, &tag, sizeof(uint32));
if (tag == SAVEGAME_FOOTERTAG)
error("Unable to find requested section of savegame!");
gzread(_fileHandle, &_sectionSize, sizeof(uint32));
_sectionBuffer = (char *) malloc(_sectionSize);
gzread(_fileHandle, _sectionBuffer, _sectionSize);
}
}
_sectionPtr = 0;
return _sectionSize;
}
void SaveGame::endSection() {
if (_currentSection == 0)
error("Tried to end a save game section without starting a section!");
if(_saving) {
gzwrite(_fileHandle, &_currentSection, sizeof(uint32));
gzwrite(_fileHandle, &_sectionSize, sizeof(uint32));
gzwrite(_fileHandle, _sectionBuffer, _sectionSize);
}
free(_sectionBuffer);
_currentSection = 0;
}
void SaveGame::readBlock(void *data, int size) {
if (_saving) if (_saving)
error("SaveGame::readBlock called when storing a savegame!"); error("SaveGame::readBlock called when storing a savegame!");
if (_currentSection == 0) return gzread(_fileHandle, data, size);
error("Tried to read a block without starting a section!");
memcpy(data, &_sectionBuffer[_sectionPtr], size);
_sectionPtr += size;
} }
void SaveGame::writeBlock(void *data, int size) { int SaveGame::checkTag(uint32 tag) {
uint32 readTag;
int res = read(&readTag, 4);
assert(res == 4);
if (readTag != tag) {
error("SaveGame::readAndCheck: Wrong tag. Expected: %d", tag);
}
return res;
}
int SaveGame::write(void *data, int size) {
if (!_saving) if (!_saving)
error("SaveGame::writeBlock called when restoring a savegame!"); error("SaveGame::writeBlock called when restoring a savegame!");
if (_currentSection == 0) return gzwrite(_fileHandle, data, size);
error("Tried to write a block without starting a section!"); }
_sectionBuffer = (char *) realloc(_sectionBuffer, _sectionSize + size);
if (_sectionBuffer == NULL) int SaveGame::writeTag(uint32 tag) {
error("Failed to allocate space for buffer!"); int res = write(&tag, 4);
memcpy(&_sectionBuffer[_sectionSize], data, size); assert(res == 4);
_sectionSize += size; return res;
} }

View file

@ -24,6 +24,7 @@
#define SAVEGAME_H #define SAVEGAME_H
#include "debug.h" #include "debug.h"
#include "lua.h"
#include <zlib.h> #include <zlib.h>
class SaveGame { class SaveGame {
@ -31,18 +32,16 @@ public:
SaveGame(char *filename, bool saving); SaveGame(char *filename, bool saving);
~SaveGame(); ~SaveGame();
uint32 beginSection(uint32 sectionTag); int read(void *data, int size);
void endSection(); int checkTag(uint32 tag);
void readBlock(void *data, int size); int write(void *data, int size);
void writeBlock(void *data, int size); int writeTag(uint32 tag);
gzFile fileHandle() { return _fileHandle; }
protected: protected:
bool _saving; bool _saving;
gzFile _fileHandle; gzFile _fileHandle;
uint32 _currentSection;
uint32 _sectionSize;
uint32 _sectionPtr;
char *_sectionBuffer;
}; };
#endif #endif