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

View file

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

170
lua.cpp
View file

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

View file

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

View file

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

View file

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

View file

@ -29,8 +29,7 @@
// Constructor. Should create/open a saved game
SaveGame::SaveGame(char *filename, bool saving) :
_saving(saving), _currentSection(0)
{
_saving(saving) {
if (_saving) {
uint32 tag = SAVEGAME_HEADERTAG;
uint32 version = SAVEGAME_VERSION;
@ -64,58 +63,31 @@ SaveGame::~SaveGame() {
gzclose(_fileHandle);
}
uint32 SaveGame::beginSection(uint32 sectionTag) {
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) {
int SaveGame::read(void *data, int size) {
if (_saving)
error("SaveGame::readBlock called when storing a savegame!");
if (_currentSection == 0)
error("Tried to read a block without starting a section!");
memcpy(data, &_sectionBuffer[_sectionPtr], size);
_sectionPtr += size;
return gzread(_fileHandle, data, 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)
error("SaveGame::writeBlock called when restoring a savegame!");
if (_currentSection == 0)
error("Tried to write a block without starting a section!");
_sectionBuffer = (char *) realloc(_sectionBuffer, _sectionSize + size);
if (_sectionBuffer == NULL)
error("Failed to allocate space for buffer!");
memcpy(&_sectionBuffer[_sectionSize], data, size);
_sectionSize += size;
return gzwrite(_fileHandle, data, size);
}
int SaveGame::writeTag(uint32 tag) {
int res = write(&tag, 4);
assert(res == 4);
return res;
}

View file

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