From 05bd724b1c6f7bb5d6cd0b3e8e92b6a89bcd5099 Mon Sep 17 00:00:00 2001 From: Ari Johnson Date: Wed, 14 Feb 2007 03:39:17 +0000 Subject: [PATCH] Fixed script state saving and loading on big-endian machines git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@1100 4a71c877-e1ca-e34f-864e-861f7616d084 --- lib/script/evntsave.c | 141 +++++++++++++++++++++++++++++------------- src/scriptobj.c | 52 +++++++++++++--- 2 files changed, 140 insertions(+), 53 deletions(-) diff --git a/lib/script/evntsave.c b/lib/script/evntsave.c index ecbfd974e..69f8085c7 100644 --- a/lib/script/evntsave.c +++ b/lib/script/evntsave.c @@ -85,9 +85,11 @@ static BOOL eventSaveContext(char *pBuffer, UDWORD *pSize) //not hashed strcpy(pPos, pScriptID); //not hashed pPos += strlen(pScriptID) + 1; *((UDWORD*)pPos) = (UDWORD)hashedName; + endian_udword((UDWORD*)pPos); pPos += sizeof(UDWORD); *((SWORD*)pPos) = (SWORD)numVars; + endian_sword((SWORD*)pPos); pPos += sizeof(SWORD); *pPos = (UBYTE)psCCont->release; @@ -109,7 +111,10 @@ static BOOL eventSaveContext(char *pBuffer, UDWORD *pSize) { ASSERT( psVal->type < SWORD_MAX, "eventSaveContext: variable type number too big" ); + *((SWORD*)pPos) = (SWORD)psVal->type; + endian_sword((SWORD*)pPos); + pPos += sizeof(SWORD); } size += sizeof(SWORD); @@ -120,7 +125,10 @@ static BOOL eventSaveContext(char *pBuffer, UDWORD *pSize) // internal type - just store the DWORD value if (pBuffer != NULL) { - *((UDWORD *)pPos) = (UDWORD)psVal->v.ival; //TODO: make it save strings properly +/* FIXME: this does not work for VAL_OBJ_GETSET, VAL_FUNC_EXTERN, or VAL_STRING */ + *((UDWORD *)pPos) = (UDWORD)psVal->v.ival; + endian_udword((UDWORD*)pPos); + pPos += sizeof(UDWORD); } @@ -152,6 +160,8 @@ static BOOL eventSaveContext(char *pBuffer, UDWORD *pSize) if (pBuffer != NULL) { *pValSize = (UWORD)valSize; + endian_uword((UWORD*)pValSize); + pPos += valSize; } size += valSize; @@ -175,6 +185,7 @@ static BOOL eventSaveContext(char *pBuffer, UDWORD *pSize) if (pBuffer != NULL) { *((SWORD *)pBuffer) = (SWORD)numContext; + endian_sword((SWORD*)pBuffer); } *pSize = size; @@ -199,6 +210,7 @@ static BOOL eventLoadContext(SDWORD version, char *pBuffer, UDWORD *pSize) pPos = pBuffer; // get the number of contexts in the save file + endian_sword((SWORD*)pPos); numContext = *((SWORD *)pPos); pPos += sizeof(SWORD); size += sizeof(SWORD); @@ -213,6 +225,9 @@ static BOOL eventLoadContext(SDWORD version, char *pBuffer, UDWORD *pSize) // check the number of variables numVars = psCode->numGlobals + psCode->arraySize; + + endian_sword((SWORD*)pPos); + if (numVars != *((SWORD*)pPos)) { debug( LOG_ERROR, "eventLoadContext: number of context variables does not match the script code" ); @@ -239,7 +254,8 @@ static BOOL eventLoadContext(SDWORD version, char *pBuffer, UDWORD *pSize) for(i=0; i < numVars; i+= 1) { // get the variable type - type = (INTERP_TYPE)*pPos; + endian_sword((SWORD*)pPos); + type = (INTERP_TYPE) *((SWORD*)pPos); pPos += sizeof(SWORD); size += sizeof(SWORD); @@ -248,6 +264,8 @@ static BOOL eventLoadContext(SDWORD version, char *pBuffer, UDWORD *pSize) { data.type = type; + endian_udword((UDWORD*)pPos); + switch (type) { case VAL_BOOL: data.v.bval = *((BOOL*)pPos); @@ -270,16 +288,19 @@ static BOOL eventLoadContext(SDWORD version, char *pBuffer, UDWORD *pSize) size += sizeof(UDWORD); break; case VAL_STRING: +/* FIXME: this would never work */ data.v.sval = pPos; pPos += sizeof(char*); size += sizeof(char*); break; case VAL_OBJ_GETSET: +/* FIXME: saving pointer on disk! */ data.v.pObjGetSet = *((SCRIPT_VARFUNC*)pPos); pPos += sizeof(SCRIPT_VARFUNC); size += sizeof(SCRIPT_VARFUNC); break; case VAL_FUNC_EXTERN: +/* FIXME: saving pointer on disk! */ data.v.pFuncExtern = *((SCRIPT_FUNC*)pPos); pPos += sizeof(SCRIPT_FUNC); size += sizeof(SCRIPT_FUNC); @@ -304,7 +325,9 @@ static BOOL eventLoadContext(SDWORD version, char *pBuffer, UDWORD *pSize) ASSERT( loadFunc != NULL, "eventLoadContext: no load function for type %d\n", type ); + endian_uword((UWORD*)pPos); valSize = *((UWORD *)pPos); + pPos += sizeof(UWORD); size += sizeof(UWORD); @@ -340,6 +363,7 @@ static BOOL eventLoadContextHashed(SDWORD version, char *pBuffer, UDWORD *pSize) { UDWORD size, valSize; SDWORD numVars, i, numContext, context; + SWORD savedNumVars; SCRIPT_CONTEXT *psCCont; INTERP_TYPE type; SCR_VAL_LOAD loadFunc; @@ -354,6 +378,7 @@ static BOOL eventLoadContextHashed(SDWORD version, char *pBuffer, UDWORD *pSize) pPos = pBuffer; // get the number of contexts in the save file + endian_sword((SWORD *)pPos); numContext = *((SWORD *)pPos); pPos += sizeof(SWORD); size += sizeof(SWORD); @@ -365,6 +390,7 @@ static BOOL eventLoadContextHashed(SDWORD version, char *pBuffer, UDWORD *pSize) //notHashed pScriptID = (char *)pPos; //notHashed psCode = resGetData("SCRIPT", pScriptID); //notHashed pPos += strlen(pScriptID) + 1; + endian_udword((UDWORD*)pPos); hashedName = *((UDWORD*)pPos); pPos += sizeof(UDWORD); psCode = (SCRIPT_CODE*)resGetDataFromHash("SCRIPT", hashedName); @@ -372,7 +398,9 @@ static BOOL eventLoadContextHashed(SDWORD version, char *pBuffer, UDWORD *pSize) // check the number of variables numVars = psCode->numGlobals + psCode->arraySize; - if (numVars != *((SWORD*)pPos)) + endian_sword((SWORD*)pPos); + savedNumVars = *((SWORD*)pPos); + if (numVars != savedNumVars) { debug( LOG_ERROR, "eventLoadContext: number of context variables does not match the script code" ); abort(); @@ -398,54 +426,60 @@ static BOOL eventLoadContextHashed(SDWORD version, char *pBuffer, UDWORD *pSize) for(i=0; i < numVars; i+= 1) { // get the variable type - type = (INTERP_TYPE)*pPos; + endian_sword((SWORD*)pPos); + type = (INTERP_TYPE) *((SWORD*)pPos); pPos += sizeof(SWORD); size += sizeof(SWORD); // get the variable value if (type < VAL_USERTYPESTART) { - data.type = type; + data.type = type; - switch (type) { - case VAL_BOOL: - data.v.bval = *((BOOL*)pPos); - pPos += sizeof(BOOL); - size += sizeof(BOOL); - break; - case VAL_FLOAT: - data.v.fval = *((float*)pPos); - pPos += sizeof(float); - size += sizeof(float); - break; - case VAL_INT: - case VAL_TRIGGER: - case VAL_EVENT: - case VAL_VOID: - case VAL_OPCODE: - case VAL_PKOPCODE: - data.v.ival = *((UDWORD *)pPos); - pPos += sizeof(UDWORD); - size += sizeof(UDWORD); - break; - case VAL_STRING: - data.v.sval = pPos; - pPos += sizeof(char*); - size += sizeof(char*); - break; - case VAL_OBJ_GETSET: - data.v.pObjGetSet = *((SCRIPT_VARFUNC*)pPos); - pPos += sizeof(SCRIPT_VARFUNC); - size += sizeof(SCRIPT_VARFUNC); - break; - case VAL_FUNC_EXTERN: - data.v.pFuncExtern = *((SCRIPT_FUNC*)pPos); - pPos += sizeof(SCRIPT_FUNC); - size += sizeof(SCRIPT_FUNC); - break; - default: - ASSERT( FALSE, "eventLoadContext: invalid internal type" ); - } + endian_udword((UDWORD*)pPos); + + switch (type) { + case VAL_BOOL: + data.v.bval = *((BOOL*)pPos); + pPos += sizeof(BOOL); + size += sizeof(BOOL); + break; + case VAL_FLOAT: + data.v.fval = *((float*)pPos); + pPos += sizeof(float); + size += sizeof(float); + break; + case VAL_INT: + case VAL_TRIGGER: + case VAL_EVENT: + case VAL_VOID: + case VAL_OPCODE: + case VAL_PKOPCODE: + data.v.ival = *((UDWORD *)pPos); + pPos += sizeof(UDWORD); + size += sizeof(UDWORD); + break; + case VAL_STRING: +/* FIXME: this would never work! */ + data.v.sval = pPos; + pPos += sizeof(char*); + size += sizeof(char*); + break; + case VAL_OBJ_GETSET: +/* FIXME: saving pointer on disk! */ + data.v.pObjGetSet = *((SCRIPT_VARFUNC*)pPos); + pPos += sizeof(SCRIPT_VARFUNC); + size += sizeof(SCRIPT_VARFUNC); + break; + case VAL_FUNC_EXTERN: +/* TODO: saving pointer on disk! */ + data.v.pFuncExtern = *((SCRIPT_FUNC*)pPos); + pPos += sizeof(SCRIPT_FUNC); + size += sizeof(SCRIPT_FUNC); + break; + default: + ASSERT( FALSE, "eventLoadContext: invalid internal type" ); + } // set the value in the context if (!eventSetContextVar(psCCont, (UDWORD)i, &data)) @@ -463,7 +497,9 @@ static BOOL eventLoadContextHashed(SDWORD version, char *pBuffer, UDWORD *pSize) ASSERT( loadFunc != NULL, "eventLoadContext: no load function for type %d\n", type ); + endian_uword((UWORD*)pPos); valSize = *((UWORD *)pPos); + pPos += sizeof(UWORD); size += sizeof(UWORD); @@ -557,6 +593,8 @@ static BOOL eventSaveTriggerList(ACTIVE_TRIGGER *psList, char *pBuffer, UDWORD * if (pBuffer != NULL) { *((UDWORD*)pPos) = psCurr->testTime; + endian_udword((UDWORD*)pPos); + pPos += sizeof(UDWORD); if (!eventGetContextIndex(psCurr->psContext, &context)) { @@ -565,14 +603,19 @@ static BOOL eventSaveTriggerList(ACTIVE_TRIGGER *psList, char *pBuffer, UDWORD * return FALSE; } *((SWORD*)pPos) = (SWORD)context; + endian_sword((SWORD*)pPos); pPos += sizeof(SWORD); *((SWORD*)pPos) = psCurr->type; + endian_sword((SWORD*)pPos); pPos += sizeof(SWORD); *((SWORD*)pPos) = psCurr->trigger; + endian_sword((SWORD*)pPos); pPos += sizeof(SWORD); *((UWORD*)pPos) = psCurr->event; + endian_uword((UWORD*)pPos); pPos += sizeof(UWORD); *((UWORD*)pPos) = psCurr->offset; + endian_uword((UWORD*)pPos); pPos += sizeof(UWORD); } size += sizeof(UDWORD) + sizeof(SWORD)*3 + sizeof(UWORD)*2; @@ -580,6 +623,7 @@ static BOOL eventSaveTriggerList(ACTIVE_TRIGGER *psList, char *pBuffer, UDWORD * if (pBuffer != NULL) { *((SDWORD*)pBuffer) = numTriggers; + endian_sdword((SDWORD*)pBuffer); } *pSize = size; @@ -602,15 +646,18 @@ static BOOL eventLoadTriggerList(SDWORD version, char *pBuffer, UDWORD *pSize) pPos = pBuffer; // get the number of triggers + endian_sdword((SDWORD*)pPos); numTriggers = *((SDWORD*)pPos); pPos += sizeof(SDWORD); size += sizeof(SDWORD); for(i=0; iaFileType[2] = 'n'; psHdr->aFileType[3] = 't'; psHdr->version = version; + endian_udword(&psHdr->version); pPos += sizeof(EVENT_SAVE_HDR); @@ -741,6 +793,7 @@ BOOL eventLoadState(char *pBuffer, UDWORD fileSize, BOOL bHashed) // Get the header psHdr = (EVENT_SAVE_HDR *)pPos; + endian_udword(&psHdr->version); if (strncmp(psHdr->aFileType, "evnt", 4) != 0) { debug( LOG_ERROR, "eventLoadState: invalid file header" ); diff --git a/src/scriptobj.c b/src/scriptobj.c index cba59c1d6..d0dc9e1d7 100644 --- a/src/scriptobj.c +++ b/src/scriptobj.c @@ -683,6 +683,8 @@ BOOL scrValDefSave(INTERP_VAL *psVal, char *pBuffer, UDWORD *pSize) ASSERT( psObj == (BASE_OBJECT *)psVal->v.oval,"scrValDefSave failed to find object, continue" ); #endif } + + endian_udword((UDWORD*)pBuffer); } *pSize = sizeof(UDWORD); break; @@ -723,6 +725,7 @@ BOOL scrValDefSave(INTERP_VAL *psVal, char *pBuffer, UDWORD *pSize) { *((UDWORD*)pBuffer) = ((DROID_TEMPLATE *)psVal->v.oval)->multiPlayerID; } + endian_udword((UDWORD*)pBuffer); } *pSize = sizeof(UDWORD); break; @@ -737,6 +740,7 @@ BOOL scrValDefSave(INTERP_VAL *psVal, char *pBuffer, UDWORD *pSize) { *((UDWORD*)pBuffer) = strresGetIDfromString(psStringRes, psVal->v.sval); } + endian_udword((UDWORD*)pBuffer); } *pSize = sizeof(UDWORD); break; @@ -793,21 +797,29 @@ BOOL scrValDefSave(INTERP_VAL *psVal, char *pBuffer, UDWORD *pSize) // store the run data *((SDWORD *)pPos) = psGroup->sRunData.sPos.x; + endian_sdword((SDWORD*)pPos); pPos += sizeof(SDWORD); *((SDWORD *)pPos) = psGroup->sRunData.sPos.y; + endian_sdword((SDWORD*)pPos); pPos += sizeof(SDWORD); *((SDWORD *)pPos) = psGroup->sRunData.forceLevel; + endian_sdword((SDWORD*)pPos); pPos += sizeof(SDWORD); *((SDWORD *)pPos) = psGroup->sRunData.leadership; + endian_sdword((SDWORD*)pPos); pPos += sizeof(SDWORD); *((SDWORD *)pPos) = psGroup->sRunData.healthLevel; + endian_sdword((SDWORD*)pPos); pPos += sizeof(SDWORD); // now store the droids for(psCDroid=((DROID_GROUP *)psVal->v.oval)->psList; psCDroid; psCDroid=psCDroid->psGrpNext) { checkValidId(psCDroid->id); + *((UDWORD *)pPos) = psCDroid->id; + endian_udword((UDWORD*)pPos); + pPos += sizeof(UDWORD); } } @@ -828,6 +840,7 @@ BOOL scrValDefSave(INTERP_VAL *psVal, char *pBuffer, UDWORD *pSize) if (pBuffer) { *((UDWORD *) pBuffer) = sound_GetTrackHashName((SDWORD)psVal->v.ival); + endian_udword((UDWORD*)pBuffer); } *pSize = sizeof(UDWORD); break; @@ -837,6 +850,7 @@ BOOL scrValDefSave(INTERP_VAL *psVal, char *pBuffer, UDWORD *pSize) if (pBuffer) { *((UDWORD *)pBuffer) = psVal->v.ival; + endian_udword((UDWORD*)pBuffer); } *pSize = sizeof(UDWORD); break; @@ -879,15 +893,17 @@ BOOL scrValDefLoad(SDWORD version, INTERP_VAL *psVal, char *pBuffer, UDWORD size case ST_STRUCTURE: case ST_FEATURE: id = *((UDWORD *)pBuffer); + endian_udword(&id); + if (id == UDWORD_MAX) { psVal->v.oval = NULL; } else { - if (!scrvGetBaseObj(*((UDWORD*)pBuffer), (BASE_OBJECT **)&(psVal->v.oval))) + if (!scrvGetBaseObj(id, (BASE_OBJECT **)&(psVal->v.oval))) { - debug( LOG_ERROR, "scrValDefLoad: couldn't find object id %d", *((UDWORD*)pBuffer) ); + debug( LOG_ERROR, "scrValDefLoad: couldn't find object id %d", id ); abort(); } } @@ -997,6 +1013,8 @@ BOOL scrValDefLoad(SDWORD version, INTERP_VAL *psVal, char *pBuffer, UDWORD size break; case ST_TEMPLATE: id = *((UDWORD *)pBuffer); + endian_udword(&id); + if (id == UDWORD_MAX) { psVal->v.oval = NULL; @@ -1006,19 +1024,21 @@ BOOL scrValDefLoad(SDWORD version, INTERP_VAL *psVal, char *pBuffer, UDWORD size psVal->v.oval = (void*)IdToTemplate(id, ANYPLAYER); if ((DROID_TEMPLATE*)(psVal->v.oval) == NULL) { - debug( LOG_ERROR, "scrValDefLoad: couldn't find template id %d", *((UDWORD *)pBuffer) ); + debug( LOG_ERROR, "scrValDefLoad: couldn't find template id %d", id ); abort(); } } break; case ST_TEXTSTRING: - if (*((UDWORD *)pBuffer) == UDWORD_MAX) + id = *((UDWORD *)pBuffer); + endian_udword(&id); + if (id == UDWORD_MAX) { psVal->v.sval = '\0'; } else { - psVal->v.sval = strresGetString(psStringRes, *((UDWORD *)pBuffer)); + psVal->v.sval = strresGetString(psStringRes, id); } break; case ST_LEVEL: @@ -1077,12 +1097,16 @@ BOOL scrValDefLoad(SDWORD version, INTERP_VAL *psVal, char *pBuffer, UDWORD size // load the retreat data psGroup = (DROID_GROUP*)(psVal->v.oval); + endian_sdword((SDWORD*)pPos); psGroup->sRunData.sPos.x = *((SDWORD *)pPos); pPos += sizeof(SDWORD); + endian_sdword((SDWORD*)pPos); psGroup->sRunData.sPos.y = *((SDWORD *)pPos); pPos += sizeof(SDWORD); + endian_sdword((SDWORD*)pPos); psGroup->sRunData.forceLevel = (UBYTE)(*((SDWORD *)pPos)); pPos += sizeof(SDWORD); + endian_sdword((SDWORD*)pPos); psGroup->sRunData.leadership = (UBYTE)(*((SDWORD *)pPos)); pPos += sizeof(SDWORD); } @@ -1093,14 +1117,19 @@ BOOL scrValDefLoad(SDWORD version, INTERP_VAL *psVal, char *pBuffer, UDWORD size // load the retreat data psGroup = (DROID_GROUP*)(psVal->v.oval); + endian_sdword((SDWORD*)pPos); psGroup->sRunData.sPos.x = *((SDWORD *)pPos); pPos += sizeof(SDWORD); + endian_sdword((SDWORD*)pPos); psGroup->sRunData.sPos.y = *((SDWORD *)pPos); pPos += sizeof(SDWORD); + endian_sdword((SDWORD*)pPos); psGroup->sRunData.forceLevel = (UBYTE)(*((SDWORD *)pPos)); pPos += sizeof(SDWORD); + endian_sdword((SDWORD*)pPos); psGroup->sRunData.leadership = (UBYTE)(*((SDWORD *)pPos)); pPos += sizeof(SDWORD); + endian_sdword((SDWORD*)pPos); psGroup->sRunData.healthLevel = (UBYTE)(*((SDWORD *)pPos)); pPos += sizeof(SDWORD); } @@ -1108,9 +1137,11 @@ BOOL scrValDefLoad(SDWORD version, INTERP_VAL *psVal, char *pBuffer, UDWORD size // load the droids while (members > 0) { - if (!scrvGetBaseObj(*((UDWORD*)pPos), (BASE_OBJECT **)&psCDroid)) + endian_udword((UDWORD*)pPos); + id = *((UDWORD *) pPos); + if (!scrvGetBaseObj(id, (BASE_OBJECT **)&psCDroid)) { - debug( LOG_ERROR, "scrValDefLoad: couldn't find object id %d", *((UDWORD*)pBuffer) ); + debug( LOG_ERROR, "scrValDefLoad: couldn't find object id %d", id ); abort(); } else @@ -1124,7 +1155,9 @@ BOOL scrValDefLoad(SDWORD version, INTERP_VAL *psVal, char *pBuffer, UDWORD size break; case ST_SOUND: // find audio id - index = audio_GetTrackIDFromHash( *((UDWORD *)pBuffer) ); + id = *((UDWORD *) pBuffer); + endian_udword(&id); + index = audio_GetTrackIDFromHash( id ); if (index == SAMPLE_NOT_FOUND) { // find empty id @@ -1136,7 +1169,7 @@ BOOL scrValDefLoad(SDWORD version, INTERP_VAL *psVal, char *pBuffer, UDWORD size break; } // set track vals - audio_SetTrackValsHashName( *((UDWORD *)pBuffer), FALSE, index, 100, + audio_SetTrackValsHashName( id, FALSE, index, 100, 1, 1800 ); } psVal->v.ival = index; @@ -1146,6 +1179,7 @@ BOOL scrValDefLoad(SDWORD version, INTERP_VAL *psVal, char *pBuffer, UDWORD size default: // just set the contents directly psVal->v.ival = *((UDWORD *)pBuffer); + endian_udword(&psVal->v.ival); break; }