//------------------------------------------------------------------------- /* Copyright (C) 2010 EDuke32 developers and contributors This file is part of EDuke32. EDuke32 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ //------------------------------------------------------------------------- #include "duke3d.h" #include "common_game.h" #include "gamevars.h" #include "gamedef.h" #include "osd.h" #include "savegame.h" #define _gamevars_c_ #include "gamestructures.c" extern int32_t OSD_errors; void Gv_RefreshPointers(void); extern void G_FreeMapState(int32_t mapnum); static void Gv_Free(void) /* called from Gv_ReadSave() and Gv_ResetVars() */ { // call this function as many times as needed. int32_t i=(MAXGAMEVARS-1); // AddLog("Gv_Free"); for (; i>=0; i--) { if ((aGameVars[i].dwFlags & GAMEVAR_USER_MASK) && aGameVars[i].val.plValues) { Bfree(aGameVars[i].val.plValues); aGameVars[i].val.plValues=NULL; } aGameVars[i].dwFlags |= GAMEVAR_RESET; if (i >= MAXGAMEARRAYS) continue; if ((aGameArrays[i].dwFlags & GAMEARRAY_NORMAL) && aGameArrays[i].plValues) { Bfree(aGameArrays[i].plValues); aGameArrays[i].plValues=NULL; } aGameArrays[i].dwFlags |= GAMEARRAY_RESET; } g_gameVarCount=g_gameArrayCount=0; hash_init(&h_gamevars); hash_init(&h_arrays); return; } static void Gv_Clear(void) { // only call this function ONCE... int32_t i=(MAXGAMEVARS-1); //AddLog("Gv_Clear"); for (; i>=0; i--) { if (aGameVars[i].szLabel) Bfree(aGameVars[i].szLabel); aGameVars[i].szLabel=NULL; if ((aGameVars[i].dwFlags & GAMEVAR_USER_MASK) && aGameVars[i].val.plValues) { Bfree(aGameVars[i].val.plValues); aGameVars[i].val.plValues=NULL; } aGameVars[i].val.lValue=0; aGameVars[i].dwFlags |= GAMEVAR_RESET; if (i >= MAXGAMEARRAYS) continue; if (aGameArrays[i].szLabel) Bfree(aGameArrays[i].szLabel); aGameArrays[i].szLabel=NULL; if ((aGameArrays[i].dwFlags & GAMEARRAY_NORMAL) && aGameArrays[i].plValues) { Bfree(aGameArrays[i].plValues); aGameArrays[i].plValues=NULL; } aGameArrays[i].dwFlags |= GAMEARRAY_RESET; } g_gameVarCount=g_gameArrayCount=0; hash_init(&h_gamevars); hash_init(&h_arrays); return; } int32_t Gv_ReadSave(int32_t fil, int32_t newbehav) { int32_t i, j; char savedstate[MAXVOLUMES*MAXLEVELS]; char tbuf[12]; if (newbehav) { if (kread(fil, tbuf, 12)!=12) goto corrupt; if (Bmemcmp(tbuf, "BEG: EDuke32", 12)) { OSD_Printf("BEG ERR\n"); return 2; } } Bmemset(&savedstate,0,sizeof(savedstate)); // AddLog("Reading gamevars from savegame"); Gv_Free(); // nuke 'em from orbit, it's the only way to be sure... // Bsprintf(g_szBuf,"CP:%s %d",__FILE__,__LINE__); // AddLog(g_szBuf); if (kdfread(&g_gameVarCount,sizeof(g_gameVarCount),1,fil) != 1) goto corrupt; for (i=0; ivars[j]) MapInfo[i].savedstate->vars[j] = (intptr_t *)Bcalloc(MAXPLAYERS,sizeof(intptr_t)); if (kdfread(&MapInfo[i].savedstate->vars[j][0],sizeof(intptr_t) * MAXPLAYERS, 1, fil) != 1) goto corrupt; } else if (aGameVars[j].dwFlags & GAMEVAR_PERACTOR) { // if (!MapInfo[i].savedstate->vars[j]) MapInfo[i].savedstate->vars[j] = (intptr_t *)Bcalloc(MAXSPRITES,sizeof(intptr_t)); if (kdfread(&MapInfo[i].savedstate->vars[j][0],sizeof(intptr_t), MAXSPRITES, fil) != MAXSPRITES) goto corrupt; } } } else if (MapInfo[i].savedstate) { G_FreeMapState(i); } } if (!newbehav) { intptr_t l; if (kdfread(&l,sizeof(l),1,fil) != 1) goto corrupt; if (kdfread(g_szBuf,l,1,fil) != 1) goto corrupt; g_szBuf[l]=0; OSD_Printf("%s\n",g_szBuf); } else { if (kread(fil, tbuf, 12)!=12) goto corrupt; if (Bmemcmp(tbuf, "EOF: EDuke32", 12)) { OSD_Printf("EOF ERR\n"); return 2; } } #if 0 { FILE *fp; AddLog("Dumping Vars..."); fp=fopen("xxx.txt","w"); if (fp) { Gv_DumpValues(fp); fclose(fp); } AddLog("Done Dumping..."); } #endif return(0); corrupt: return(1); } void Gv_WriteSave(FILE *fil, int32_t newbehav) { int32_t i, j; char savedstate[MAXVOLUMES*MAXLEVELS]; Bmemset(&savedstate,0,sizeof(savedstate)); // AddLog("Saving Game Vars to File"); if (newbehav) fwrite("BEG: EDuke32", 12, 1, fil); dfwrite(&g_gameVarCount,sizeof(g_gameVarCount),1,fil); for (i=0; ivars[j][0],sizeof(intptr_t) * MAXPLAYERS, 1, fil); } else if (aGameVars[j].dwFlags & GAMEVAR_PERACTOR) { dfwrite(&MapInfo[i].savedstate->vars[j][0],sizeof(intptr_t), MAXSPRITES, fil); } } } if (!newbehav) { intptr_t l; Bsprintf(g_szBuf,"EOF: EDuke32"); l=Bstrlen(g_szBuf); dfwrite(&l,sizeof(l),1,fil); dfwrite(g_szBuf,l,1,fil); } else fwrite("EOF: EDuke32", 12, 1, fil); } void Gv_DumpValues(void) { int32_t i; OSD_Printf("// Current Game Definitions\n\n"); for (i=0; i= MAXGAMEARRAYS) { g_numCompilerErrors++; C_ReportError(-1); initprintf("%s:%d: error: too many arrays!\n",g_szScriptFileName,g_lineNumber); return 0; } if (Bstrlen(pszLabel) > (MAXARRAYLABEL-1)) { g_numCompilerErrors++; C_ReportError(-1); initprintf("%s:%d: error: array name `%s' exceeds limit of %d characters.\n",g_szScriptFileName,g_lineNumber,pszLabel, MAXARRAYLABEL); return 0; } i = hash_find(&h_arrays,pszLabel); if (i >=0 && !(aGameArrays[i].dwFlags & GAMEARRAY_RESET)) { // found it it's a duplicate in error g_numCompilerWarnings++; if (aGameArrays[i].dwFlags&GAMEARRAY_TYPE_MASK) { C_ReportError(-1); initprintf("ignored redefining system array `%s'.", pszLabel); } else C_ReportError(WARNING_DUPLICATEDEFINITION); return 0; } i = g_gameArrayCount; if (aGameArrays[i].szLabel == NULL) aGameArrays[i].szLabel=(char *)Bcalloc(MAXVARLABEL,sizeof(uint8_t)); if (aGameArrays[i].szLabel != pszLabel) Bstrcpy(aGameArrays[i].szLabel,pszLabel); if (!(dwFlags & GAMEARRAY_TYPE_MASK)) aGameArrays[i].plValues=(intptr_t *)Bcalloc(asize,GAR_ELTSZ); else aGameArrays[i].plValues=(intptr_t *)arrayptr; aGameArrays[i].size=asize; aGameArrays[i].dwFlags = dwFlags & ~GAMEARRAY_RESET; g_gameArrayCount++; hash_add(&h_arrays, aGameArrays[i].szLabel, i, 1); return 1; } int32_t Gv_NewVar(const char *pszLabel, intptr_t lValue, uint32_t dwFlags) { int32_t i, j; //Bsprintf(g_szBuf,"Gv_NewVar(%s, %d, %X)",pszLabel, lValue, dwFlags); //AddLog(g_szBuf); if (g_gameVarCount >= MAXGAMEVARS) { g_numCompilerErrors++; C_ReportError(-1); initprintf("%s:%d: error: too many gamevars!\n",g_szScriptFileName,g_lineNumber); return 0; } if (Bstrlen(pszLabel) > (MAXVARLABEL-1)) { g_numCompilerErrors++; C_ReportError(-1); initprintf("%s:%d: error: variable name `%s' exceeds limit of %d characters.\n",g_szScriptFileName,g_lineNumber,pszLabel, MAXVARLABEL); return 0; } i = hash_find(&h_gamevars,pszLabel); if (i >= 0 && !(aGameVars[i].dwFlags & GAMEVAR_RESET)) { // found it... if (aGameVars[i].dwFlags & (GAMEVAR_PTR_MASK)) { C_ReportError(-1); initprintf("%s:%d: warning: cannot redefine internal gamevar `%s'.\n",g_szScriptFileName,g_lineNumber,label+(g_numLabels<<6)); return 0; } else if (!(aGameVars[i].dwFlags & GAMEVAR_DEFAULT) && !(aGameVars[i].dwFlags & GAMEVAR_SYSTEM)) { // it's a duplicate in error g_numCompilerWarnings++; C_ReportError(WARNING_DUPLICATEDEFINITION); return 0; } } if (i == -1) i = g_gameVarCount; // Set values if ((aGameVars[i].dwFlags & GAMEVAR_SYSTEM) == 0) { if (aGameVars[i].szLabel == NULL) aGameVars[i].szLabel = (char *)Bcalloc(MAXVARLABEL,sizeof(uint8_t)); if (aGameVars[i].szLabel != pszLabel) Bstrcpy(aGameVars[i].szLabel,pszLabel); aGameVars[i].dwFlags=dwFlags; if (aGameVars[i].dwFlags & GAMEVAR_USER_MASK) { // only free if not system if (aGameVars[i].val.plValues) Bfree(aGameVars[i].val.plValues); aGameVars[i].val.plValues=NULL; } } // if existing is system, they only get to change default value.... aGameVars[i].lDefault = lValue; aGameVars[i].dwFlags &= ~GAMEVAR_RESET; if (i == g_gameVarCount) { // we're adding a new one. hash_add(&h_gamevars, aGameVars[i].szLabel, g_gameVarCount++, 0); } if (aGameVars[i].dwFlags & GAMEVAR_PERPLAYER) { if (!aGameVars[i].val.plValues) aGameVars[i].val.plValues = (intptr_t *)Bcalloc(MAXPLAYERS,sizeof(intptr_t)); for (j=MAXPLAYERS-1; j>=0; j--) aGameVars[i].val.plValues[j]=lValue; } else if (aGameVars[i].dwFlags & GAMEVAR_PERACTOR) { if (!aGameVars[i].val.plValues) aGameVars[i].val.plValues = (intptr_t *)Bcalloc(MAXSPRITES,sizeof(intptr_t)); for (j=MAXSPRITES-1; j>=0; j--) aGameVars[i].val.plValues[j]=lValue; } else aGameVars[i].val.lValue = lValue; return 1; } void __fastcall A_ResetVars(register int32_t iActor) { register int32_t i=(MAXGAMEVARS-1); do { if ((aGameVars[i].dwFlags & (GAMEVAR_PERACTOR|GAMEVAR_NODEFAULT)) == GAMEVAR_PERACTOR) aGameVars[i].val.plValues[iActor]=aGameVars[i].lDefault; } while (i--); } static int32_t Gv_GetVarIndex(const char *szGameLabel) { int32_t i = hash_find(&h_gamevars,szGameLabel); if (i == -1) { OSD_Printf(OSD_ERROR "Gv_GetVarDataPtr(): INTERNAL ERROR: couldn't find gamevar %s!\n",szGameLabel); return 0; } return i; } int32_t __fastcall Gv_GetVar(register int32_t id, register int32_t iActor, register int32_t iPlayer) { if (id == g_iThisActorID) return iActor; if (id == MAXGAMEVARS) return(*insptr++); { register intptr_t negateResult = id&(MAXGAMEVARS<<1); if (id >= g_gameVarCount) { if (id&(MAXGAMEVARS<<2)) // array { register int32_t index=Gv_GetVar(*insptr++,iActor,iPlayer); id &= (MAXGAMEVARS-1);// ~((MAXGAMEVARS<<2)|(MAXGAMEVARS<<1)); if ((unsigned)index >= (unsigned)aGameArrays[id].size) { iActor = index; goto badindex; } return ((aGameArrays[id].plValues[index] ^ -negateResult) + negateResult); } if (id&(MAXGAMEVARS<<3)) // struct shortcut vars { register int32_t index=Gv_GetVar(*insptr++, iActor, iPlayer); switch ((id&(MAXGAMEVARS-1)) - g_iSpriteVarID) { case 0: //if (id == g_iSpriteVarID) { int32_t parm2 = 0, label = *insptr++; /*OSD_Printf("%d %d %d\n",__LINE__,index,label);*/ if (ActorLabels[label].flags & LABEL_HASPARM2) parm2 = Gv_GetVar(*insptr++, iActor, iPlayer); if ((unsigned)index >= MAXSPRITES) { iPlayer = index; goto badsprite; } return ((VM_AccessSpriteX(index, label, parm2) ^ -negateResult) + negateResult); } case 3: //else if (id == g_iPlayerVarID) { int32_t parm2 = 0, label = *insptr++; if (PlayerLabels[label].flags & LABEL_HASPARM2) parm2 = Gv_GetVar(*insptr++, iActor, iPlayer); if (index == vm.g_i) index = vm.g_p; if ((unsigned)index >= MAXPLAYERS) { iPlayer = index; goto badplayer; } return ((VM_AccessPlayerX(index, label, parm2) ^ -negateResult) + negateResult); } case 4: //else if (id == g_iActorVarID) return ((Gv_GetVar(*insptr++, index, iPlayer) ^ -negateResult) + negateResult); case 1: //else if (id == g_iSectorVarID) if (index == vm.g_i) index = sprite[vm.g_i].sectnum; if ((unsigned)index >= MAXSECTORS) { iPlayer = index; insptr++; goto badsector; } return ((VM_AccessSectorX(index, *insptr++) ^ -negateResult) + negateResult); case 2: //else if (id == g_iWallVarID) if ((unsigned)index >= MAXWALLS) { iPlayer = index; insptr++; goto badwall; } return ((VM_AccessWallX(index, *insptr++) ^ -negateResult) + negateResult); default: goto wtf; } } id &= (MAXGAMEVARS-1); if (!negateResult) goto badvarid; } switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK)) { default: return ((aGameVars[id].val.lValue ^ -negateResult) + negateResult); case GAMEVAR_PERPLAYER: if ((unsigned)iPlayer >= MAXPLAYERS) goto bad_id; return ((aGameVars[id].val.plValues[iPlayer] ^ -negateResult) + negateResult); case GAMEVAR_PERACTOR: if ((unsigned)iActor >= MAXSPRITES) goto bad_id; return ((aGameVars[id].val.plValues[iActor] ^ -negateResult) + negateResult); case GAMEVAR_INTPTR: return (((*((int32_t *)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult); case GAMEVAR_SHORTPTR: return (((*((int16_t *)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult); case GAMEVAR_CHARPTR: return (((*((char *)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult); } } bad_id: CON_ERRPRINTF("Gv_GetVar(): invalid sprite/player ID %d/%d\n", iActor,iPlayer); return -1; badvarid: CON_ERRPRINTF("Gv_GetVar(): invalid gamevar ID (%d)\n", id); return -1; badindex: CON_ERRPRINTF("Gv_GetVar(): invalid array index (%s[%d])\n", aGameArrays[id].szLabel,iActor); return -1; badplayer: CON_ERRPRINTF("Gv_GetVar(): invalid player ID %d\n", iPlayer); return -1; badsprite: CON_ERRPRINTF("Gv_GetVar(): invalid sprite ID %d\n", iPlayer); return -1; badsector: CON_ERRPRINTF("Gv_GetVar(): invalid sector ID %d\n", iPlayer); return -1; badwall: CON_ERRPRINTF("Gv_GetVar(): invalid wall ID %d\n", iPlayer); return -1; wtf: CON_ERRPRINTF("Gv_GetVar(): WTF?\n"); return -1; } void __fastcall Gv_SetVar(register int32_t id, register int32_t lValue, register int32_t iActor, register int32_t iPlayer) { if ((unsigned)id >= (unsigned)g_gameVarCount) goto badvarid; //Bsprintf(g_szBuf,"SGVI: %d (\"%s\") to %d for %d %d",id,aGameVars[id].szLabel,lValue,iActor,iPlayer); //AddLog(g_szBuf); switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK)) { default: aGameVars[id].val.lValue=lValue; return; case GAMEVAR_PERPLAYER: if ((unsigned)iPlayer > MAXPLAYERS-1) goto badindex; // for the current player aGameVars[id].val.plValues[iPlayer]=lValue; return; case GAMEVAR_PERACTOR: if ((unsigned)iActor > MAXSPRITES-1) goto badindex; aGameVars[id].val.plValues[iActor]=lValue; return; case GAMEVAR_INTPTR: *((int32_t *)aGameVars[id].val.lValue)=(int32_t)lValue; return; case GAMEVAR_SHORTPTR: *((int16_t *)aGameVars[id].val.lValue)=(int16_t)lValue; return; case GAMEVAR_CHARPTR: *((uint8_t *)aGameVars[id].val.lValue)=(uint8_t)lValue; return; } badvarid: CON_ERRPRINTF("Gv_SetVar(): invalid gamevar (%d) from sprite %d (%d), player %d\n", id,vm.g_i,TrackerCast(sprite[vm.g_i].picnum),vm.g_p); return; badindex: CON_ERRPRINTF("Gv_SetVar(): invalid index (%d) for gamevar %s from sprite %d, player %d\n", aGameVars[id].dwFlags & GAMEVAR_PERACTOR ? iActor : iPlayer, aGameVars[id].szLabel,vm.g_i,vm.g_p); return; } int32_t __fastcall Gv_GetVarX(register int32_t id) { if (id == g_iThisActorID) return vm.g_i; if (id == MAXGAMEVARS) return(*insptr++); { register intptr_t negateResult = id&(MAXGAMEVARS<<1); if (id >= g_gameVarCount) { if (id&(MAXGAMEVARS<<2)) // array { register int32_t index=Gv_GetVarX(*insptr++); int32_t siz; id &= (MAXGAMEVARS-1);// ~((MAXGAMEVARS<<2)|(MAXGAMEVARS<<1)); if (aGameArrays[id].dwFlags & GAMEARRAY_VARSIZE) siz = Gv_GetVarX(aGameArrays[id].size); else siz = aGameArrays[id].size; if (index < 0 || index >= siz) { negateResult = index; goto badindex; } switch (aGameArrays[id].dwFlags & GAMEARRAY_TYPE_MASK) { case 0: case GAMEARRAY_OFINT: return (((int32_t *)aGameArrays[id].plValues)[index] ^ -negateResult) + negateResult; case GAMEARRAY_OFSHORT: return (((int16_t *)aGameArrays[id].plValues)[index] ^ -negateResult) + negateResult; case GAMEARRAY_OFCHAR: return (((uint8_t *)aGameArrays[id].plValues)[index] ^ -negateResult) + negateResult; default: goto arraywtf; } } if (id&(MAXGAMEVARS<<3)) // struct shortcut vars { int32_t index=Gv_GetVarX(*insptr++); switch ((id&(MAXGAMEVARS-1)) - g_iSpriteVarID) { case 0: //if (id == g_iSpriteVarID) { register int32_t parm2 = 0, label = *insptr++; /*OSD_Printf("%d %d %d\n",__LINE__,index,label);*/ if (ActorLabels[label].flags & LABEL_HASPARM2) parm2 = Gv_GetVarX(*insptr++); if ((unsigned)index >= MAXSPRITES) { id = index; goto badsprite; } return ((VM_AccessSpriteX(index, label, parm2) ^ -negateResult) + negateResult); } case 3: //else if (id == g_iPlayerVarID) { register int32_t parm2 = 0, label = *insptr++; if (PlayerLabels[label].flags & LABEL_HASPARM2) parm2 = Gv_GetVarX(*insptr++); if (index == vm.g_i) index = vm.g_p; if ((unsigned)index >= MAXPLAYERS) { id = index; goto badplayer; } return ((VM_AccessPlayerX(index, label, parm2) ^ -negateResult) + negateResult); } case 4: //else if (id == g_iActorVarID) return ((Gv_GetVar(*insptr++, index, vm.g_p) ^ -negateResult) + negateResult); case 1: //else if (id == g_iSectorVarID) if (index == vm.g_i) index = sprite[vm.g_i].sectnum; if ((unsigned)index >= MAXSECTORS) { id = index; insptr++; goto badsector; } return ((VM_AccessSectorX(index, *insptr++) ^ -negateResult) + negateResult); case 2: //else if (id == g_iWallVarID) if ((unsigned)index >= MAXWALLS) { id = index; insptr++; goto badwall; } return ((VM_AccessWallX(index, *insptr++) ^ -negateResult) + negateResult); default: goto wtf; } } id &= (MAXGAMEVARS-1); if (!negateResult) goto badvarid; } switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK)) { default: return ((aGameVars[id].val.lValue ^ -negateResult) + negateResult); case GAMEVAR_PERPLAYER: if ((unsigned)vm.g_p >= MAXPLAYERS) { id = vm.g_p; goto badplayer; } return ((aGameVars[id].val.plValues[vm.g_p] ^ -negateResult) + negateResult); case GAMEVAR_PERACTOR: return ((aGameVars[id].val.plValues[vm.g_i] ^ -negateResult) + negateResult); case GAMEVAR_INTPTR: return (((*((int32_t *)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult); case GAMEVAR_SHORTPTR: return (((*((int16_t *)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult); case GAMEVAR_CHARPTR: return (((*((uint8_t *)aGameVars[id].val.lValue)) ^ -negateResult) + negateResult); } badindex: CON_ERRPRINTF("Gv_GetVarX(): invalid array index (%s[%d])\n", aGameArrays[id].szLabel, (int32_t)negateResult); return -1; badvarid: CON_ERRPRINTF("Gv_GetVarX(): invalid gamevar ID (%d)\n", id); return -1; badplayer: CON_ERRPRINTF("Gv_GetVarX(): invalid player ID %d\n", id); return -1; badsprite: CON_ERRPRINTF("Gv_GetVarX(): invalid sprite ID %d\n", id); return -1; badsector: CON_ERRPRINTF("Gv_GetVarX(): invalid sector ID %d\n", id); return -1; badwall: CON_ERRPRINTF("Gv_GetVarX(): invalid wall ID %d\n", id); return -1; arraywtf: CON_ERRPRINTF("Gv_GetVarX() (array): WTF?\n"); return -1; wtf: CON_ERRPRINTF("Gv_GetVarX(): WTF?\n"); return -1; } } void __fastcall Gv_SetVarX(register int32_t id, register int32_t lValue) { switch (aGameVars[id].dwFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK)) { default: aGameVars[id].val.lValue=lValue; return; case GAMEVAR_PERPLAYER: if ((unsigned)vm.g_p > MAXPLAYERS-1) goto badindex; aGameVars[id].val.plValues[vm.g_p]=lValue; return; case GAMEVAR_PERACTOR: if ((unsigned)vm.g_i > MAXSPRITES-1) goto badindex; aGameVars[id].val.plValues[vm.g_i]=lValue; return; case GAMEVAR_INTPTR: *((int32_t *)aGameVars[id].val.lValue)=(int32_t)lValue; return; case GAMEVAR_SHORTPTR: *((int16_t *)aGameVars[id].val.lValue)=(int16_t)lValue; return; case GAMEVAR_CHARPTR: *((uint8_t *)aGameVars[id].val.lValue)=(uint8_t)lValue; return; } badindex: CON_ERRPRINTF("Gv_SetVar(): invalid index (%d) for gamevar %s\n", aGameVars[id].dwFlags & GAMEVAR_PERACTOR ? vm.g_i : vm.g_p, aGameVars[id].szLabel); return; } int32_t Gv_GetVarByLabel(const char *szGameLabel, int32_t lDefault, int32_t iActor, int32_t iPlayer) { int32_t i = hash_find(&h_gamevars,szGameLabel); if (i < 0) return lDefault; return Gv_GetVar(i, iActor, iPlayer); } #if !defined LUNATIC static intptr_t *Gv_GetVarDataPtr(const char *szGameLabel) { int32_t i = hash_find(&h_gamevars,szGameLabel); if (i < 0) return NULL; if (aGameVars[i].dwFlags & (GAMEVAR_PERACTOR | GAMEVAR_PERPLAYER)) { if (!aGameVars[i].val.plValues) CON_ERRPRINTF("Gv_GetVarDataPtr(): INTERNAL ERROR: NULL array !!!\n"); return aGameVars[i].val.plValues; } return &(aGameVars[i].val.lValue); } #endif void Gv_ResetSystemDefaults(void) { // call many times... int32_t i; #if !defined LUNATIC int32_t j; char aszBuf[64]; //AddLog("ResetWeaponDefaults"); for (j=MAXPLAYERS-1; j>=0; j--) { for (i=MAX_WEAPONS-1; i>=0; i--) { Bsprintf(aszBuf,"WEAPON%d_CLIP",i); aplWeaponClip[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); Bsprintf(aszBuf,"WEAPON%d_RELOAD",i); aplWeaponReload[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); Bsprintf(aszBuf,"WEAPON%d_FIREDELAY",i); aplWeaponFireDelay[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); Bsprintf(aszBuf,"WEAPON%d_TOTALTIME",i); aplWeaponTotalTime[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); Bsprintf(aszBuf,"WEAPON%d_HOLDDELAY",i); aplWeaponHoldDelay[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); Bsprintf(aszBuf,"WEAPON%d_FLAGS",i); aplWeaponFlags[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); Bsprintf(aszBuf,"WEAPON%d_SHOOTS",i); aplWeaponShoots[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); if ((unsigned)aplWeaponShoots[i][j] >= MAXTILES) aplWeaponShoots[i][j] = 0; Bsprintf(aszBuf,"WEAPON%d_SPAWNTIME",i); aplWeaponSpawnTime[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); Bsprintf(aszBuf,"WEAPON%d_SPAWN",i); aplWeaponSpawn[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); Bsprintf(aszBuf,"WEAPON%d_SHOTSPERBURST",i); aplWeaponShotsPerBurst[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); Bsprintf(aszBuf,"WEAPON%d_WORKSLIKE",i); aplWeaponWorksLike[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); Bsprintf(aszBuf,"WEAPON%d_INITIALSOUND",i); aplWeaponInitialSound[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); Bsprintf(aszBuf,"WEAPON%d_FIRESOUND",i); aplWeaponFireSound[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); Bsprintf(aszBuf,"WEAPON%d_SOUND2TIME",i); aplWeaponSound2Time[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); Bsprintf(aszBuf,"WEAPON%d_SOUND2SOUND",i); aplWeaponSound2Sound[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); Bsprintf(aszBuf,"WEAPON%d_RELOADSOUND1",i); aplWeaponReloadSound1[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); Bsprintf(aszBuf,"WEAPON%d_RELOADSOUND2",i); aplWeaponReloadSound2[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); Bsprintf(aszBuf,"WEAPON%d_SELECTSOUND",i); aplWeaponSelectSound[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); Bsprintf(aszBuf,"WEAPON%d_FLASHCOLOR",i); aplWeaponFlashColor[i][j]=Gv_GetVarByLabel(aszBuf,0, -1, j); } } #endif g_iReturnVarID=Gv_GetVarIndex("RETURN"); g_iWeaponVarID=Gv_GetVarIndex("WEAPON"); g_iWorksLikeVarID=Gv_GetVarIndex("WORKSLIKE"); g_iZRangeVarID=Gv_GetVarIndex("ZRANGE"); g_iAngRangeVarID=Gv_GetVarIndex("ANGRANGE"); g_iAimAngleVarID=Gv_GetVarIndex("AUTOAIMANGLE"); g_iLoTagID=Gv_GetVarIndex("LOTAG"); g_iHiTagID=Gv_GetVarIndex("HITAG"); g_iTextureID=Gv_GetVarIndex("TEXTURE"); g_iThisActorID=Gv_GetVarIndex("THISACTOR"); g_iSpriteVarID=Gv_GetVarIndex("sprite"); g_iSectorVarID=Gv_GetVarIndex("sector"); g_iWallVarID=Gv_GetVarIndex("wall"); g_iPlayerVarID=Gv_GetVarIndex("player"); g_iActorVarID=Gv_GetVarIndex("actorvar"); for (i=MAXTILES-1; i>=0; i--) Bmemcpy(&ProjectileData[i], &g_tile[i].defproj, sizeof(projectile_t)); //AddLog("EOF:ResetWeaponDefaults"); } static weapondata_t weapondefaults[MAX_WEAPONS] = { /* WorksLike, Clip, Reload, FireDelay, TotalTime, HoldDelay, Flags, Shoots, SpawnTime, Spawn, ShotsPerBurst, InitialSound, FireSound, Sound2Time, Sound2Sound, ReloadSound1, ReloadSound2, SelectSound, FlashColor */ { KNEE_WEAPON, 0, 0, 7, 14, 0, WEAPON_NOVISIBLE | WEAPON_RANDOMRESTART | WEAPON_AUTOMATIC, KNEE__STATIC, 0, 0, 0, 0, 0, 0, 0, EJECT_CLIP, INSERT_CLIP, 0, 0 }, { PISTOL_WEAPON, /*NAM?20:*/12, /*NAM?50:*/27, 2, 5, 0, /*NAM?WEAPON_HOLSTER_CLEARS_CLIP:*/0 | WEAPON_RELOAD_TIMING, SHOTSPARK1__STATIC, 2, SHELL__STATIC, 0, 0, PISTOL_FIRE, 0, 0, EJECT_CLIP, INSERT_CLIP, INSERT_CLIP, 255+(95<<8) }, { SHOTGUN_WEAPON, 0, 13, 4, 30, 0, WEAPON_CHECKATRELOAD, SHOTGUN__STATIC, 24, SHOTGUNSHELL__STATIC, 7, 0, SHOTGUN_FIRE, 15, SHOTGUN_COCK, EJECT_CLIP, INSERT_CLIP, SHOTGUN_COCK, 255+(95<<8) }, { CHAINGUN_WEAPON, 0, 0, 3, 12, 3, WEAPON_AUTOMATIC | WEAPON_FIREEVERYTHIRD | WEAPON_AMMOPERSHOT | WEAPON_SPAWNTYPE3 | WEAPON_RESET, CHAINGUN__STATIC, 1, SHELL__STATIC, 0, 0, CHAINGUN_FIRE, 0, 0, EJECT_CLIP, INSERT_CLIP, SELECT_WEAPON, 255+(95<<8) }, { RPG_WEAPON, 0, 0, 4, 20, 0, 0, RPG__STATIC, 0, 0, 0, 0, 0, 0, 0, EJECT_CLIP, INSERT_CLIP, SELECT_WEAPON, 255+(95<<8) }, { HANDBOMB_WEAPON, 0, 30, 6, 19, 12, WEAPON_THROWIT, HEAVYHBOMB__STATIC, 0, 0, 0, 0, 0, 0, 0, EJECT_CLIP, INSERT_CLIP, 0, 0 }, { SHRINKER_WEAPON, 0, 0, 10, /*NAM?30:*/12, 0, WEAPON_GLOWS, SHRINKER__STATIC, 0, 0, 0, SHRINKER_FIRE, 0, 0, 0, EJECT_CLIP, INSERT_CLIP, SELECT_WEAPON, 128+(255<<8)+(128<<16) }, { DEVISTATOR_WEAPON, 0, 0, 3, 6, 5, WEAPON_FIREEVERYOTHER | WEAPON_AMMOPERSHOT, RPG__STATIC, 0, 0, 2, CAT_FIRE, 0, 0, 0, EJECT_CLIP, INSERT_CLIP, SELECT_WEAPON, 255+(95<<8) }, { TRIPBOMB_WEAPON, 0, 16, 3, 16, 7, WEAPON_NOVISIBLE | WEAPON_STANDSTILL | WEAPON_CHECKATRELOAD, HANDHOLDINGLASER__STATIC, 0, 0, 0, 0, 0, 0, 0, EJECT_CLIP, INSERT_CLIP, 0, 0 }, { FREEZE_WEAPON, 0, 0, 3, 5, 0, WEAPON_RESET, FREEZEBLAST__STATIC, 0, 0, 0, CAT_FIRE, CAT_FIRE, 0, 0, EJECT_CLIP, INSERT_CLIP, SELECT_WEAPON, 128+(128<<8)+(255<<16) }, { HANDREMOTE_WEAPON, 0, 10, 2, 10, 0, WEAPON_BOMB_TRIGGER | WEAPON_NOVISIBLE, 0, 0, 0, 0, 0, 0, 0, 0, EJECT_CLIP, INSERT_CLIP, 0, 0 }, { GROW_WEAPON, 0, 0, 3, /*NAM?30:*/5, 0, WEAPON_GLOWS, GROWSPARK__STATIC, /*NAM?2:*/0, /*NAM?SHELL:*/0, 0, 0, /*NAM?0:*/EXPANDERSHOOT, 0, 0, EJECT_CLIP, INSERT_CLIP, SELECT_WEAPON, 255+(95<<8) }, }; // KEEPINSYNC with what is contained above // XXX: ugly static int32_t G_StaticToDynamicTile(int32_t tile) { switch (tile) { case CHAINGUN__STATIC: return CHAINGUN; case FREEZEBLAST__STATIC: return FREEZEBLAST; case GROWSPARK__STATIC: return GROWSPARK; case HANDHOLDINGLASER__STATIC: return HANDHOLDINGLASER; case HEAVYHBOMB__STATIC: return HEAVYHBOMB; case KNEE__STATIC: return KNEE; case RPG__STATIC: return RPG; case SHELL__STATIC: return SHELL; case SHOTGUNSHELL__STATIC: return SHOTGUNSHELL; case SHOTGUN__STATIC: return SHOTGUN; case SHOTSPARK1__STATIC: return SHOTSPARK1; case SHRINKER__STATIC: return SHRINKER; default: return tile; } } #ifdef LUNATIC # define ADDWEAPONVAR(Weapidx, Membname) do { \ int32_t j; \ for (j=0; j=0; i--) { Bsprintf(aszBuf,"WEAPON%d_CLIP",i); aplWeaponClip[i]=Gv_GetVarDataPtr(aszBuf); if (!aplWeaponClip[i]) { initprintf("ERROR: NULL weapon! WTF?!\n"); // exit(0); G_Shutdown(); } Bsprintf(aszBuf,"WEAPON%d_RELOAD",i); aplWeaponReload[i]=Gv_GetVarDataPtr(aszBuf); Bsprintf(aszBuf,"WEAPON%d_FIREDELAY",i); aplWeaponFireDelay[i]=Gv_GetVarDataPtr(aszBuf); Bsprintf(aszBuf,"WEAPON%d_TOTALTIME",i); aplWeaponTotalTime[i]=Gv_GetVarDataPtr(aszBuf); Bsprintf(aszBuf,"WEAPON%d_HOLDDELAY",i); aplWeaponHoldDelay[i]=Gv_GetVarDataPtr(aszBuf); Bsprintf(aszBuf,"WEAPON%d_FLAGS",i); aplWeaponFlags[i]=Gv_GetVarDataPtr(aszBuf); Bsprintf(aszBuf,"WEAPON%d_SHOOTS",i); aplWeaponShoots[i]=Gv_GetVarDataPtr(aszBuf); Bsprintf(aszBuf,"WEAPON%d_SPAWNTIME",i); aplWeaponSpawnTime[i]=Gv_GetVarDataPtr(aszBuf); Bsprintf(aszBuf,"WEAPON%d_SPAWN",i); aplWeaponSpawn[i]=Gv_GetVarDataPtr(aszBuf); Bsprintf(aszBuf,"WEAPON%d_SHOTSPERBURST",i); aplWeaponShotsPerBurst[i]=Gv_GetVarDataPtr(aszBuf); Bsprintf(aszBuf,"WEAPON%d_WORKSLIKE",i); aplWeaponWorksLike[i]=Gv_GetVarDataPtr(aszBuf); Bsprintf(aszBuf,"WEAPON%d_INITIALSOUND",i); aplWeaponInitialSound[i]=Gv_GetVarDataPtr(aszBuf); Bsprintf(aszBuf,"WEAPON%d_FIRESOUND",i); aplWeaponFireSound[i]=Gv_GetVarDataPtr(aszBuf); Bsprintf(aszBuf,"WEAPON%d_SOUND2TIME",i); aplWeaponSound2Time[i]=Gv_GetVarDataPtr(aszBuf); Bsprintf(aszBuf,"WEAPON%d_SOUND2SOUND",i); aplWeaponSound2Sound[i]=Gv_GetVarDataPtr(aszBuf); Bsprintf(aszBuf,"WEAPON%d_RELOADSOUND1",i); aplWeaponReloadSound1[i]=Gv_GetVarDataPtr(aszBuf); Bsprintf(aszBuf,"WEAPON%d_RELOADSOUND2",i); aplWeaponReloadSound2[i]=Gv_GetVarDataPtr(aszBuf); Bsprintf(aszBuf,"WEAPON%d_SELECTSOUND",i); aplWeaponSelectSound[i]=Gv_GetVarDataPtr(aszBuf); Bsprintf(aszBuf,"WEAPON%d_FLASHCOLOR",i); aplWeaponFlashColor[i]=Gv_GetVarDataPtr(aszBuf); } #endif } void Gv_RefreshPointers(void) { aGameVars[Gv_GetVarIndex("RESPAWN_MONSTERS")].val.lValue = (intptr_t)&ud.respawn_monsters; aGameVars[Gv_GetVarIndex("RESPAWN_ITEMS")].val.lValue = (intptr_t)&ud.respawn_items; aGameVars[Gv_GetVarIndex("RESPAWN_INVENTORY")].val.lValue = (intptr_t)&ud.respawn_inventory; aGameVars[Gv_GetVarIndex("MONSTERS_OFF")].val.lValue = (intptr_t)&ud.monsters_off; aGameVars[Gv_GetVarIndex("MARKER")].val.lValue = (intptr_t)&ud.marker; aGameVars[Gv_GetVarIndex("FFIRE")].val.lValue = (intptr_t)&ud.ffire; aGameVars[Gv_GetVarIndex("LEVEL")].val.lValue = (intptr_t)&ud.level_number; aGameVars[Gv_GetVarIndex("VOLUME")].val.lValue = (intptr_t)&ud.volume_number; aGameVars[Gv_GetVarIndex("COOP")].val.lValue = (intptr_t)&ud.coop; aGameVars[Gv_GetVarIndex("MULTIMODE")].val.lValue = (intptr_t)&ud.multimode; aGameVars[Gv_GetVarIndex("myconnectindex")].val.lValue = (intptr_t)&myconnectindex; aGameVars[Gv_GetVarIndex("screenpeek")].val.lValue = (intptr_t)&screenpeek; aGameVars[Gv_GetVarIndex("currentweapon")].val.lValue = (intptr_t)&g_currentweapon; aGameVars[Gv_GetVarIndex("gs")].val.lValue = (intptr_t)&g_gs; aGameVars[Gv_GetVarIndex("looking_arc")].val.lValue = (intptr_t)&g_looking_arc; aGameVars[Gv_GetVarIndex("gun_pos")].val.lValue = (intptr_t)&g_gun_pos; aGameVars[Gv_GetVarIndex("weapon_xoffset")].val.lValue = (intptr_t)&g_weapon_xoffset; aGameVars[Gv_GetVarIndex("weaponcount")].val.lValue = (intptr_t)&g_kb; aGameVars[Gv_GetVarIndex("looking_angSR1")].val.lValue = (intptr_t)&g_looking_angSR1; aGameVars[Gv_GetVarIndex("xdim")].val.lValue = (intptr_t)&xdim; aGameVars[Gv_GetVarIndex("ydim")].val.lValue = (intptr_t)&ydim; aGameVars[Gv_GetVarIndex("windowx1")].val.lValue = (intptr_t)&windowx1; aGameVars[Gv_GetVarIndex("windowx2")].val.lValue = (intptr_t)&windowx2; aGameVars[Gv_GetVarIndex("windowy1")].val.lValue = (intptr_t)&windowy1; aGameVars[Gv_GetVarIndex("windowy2")].val.lValue = (intptr_t)&windowy2; aGameVars[Gv_GetVarIndex("totalclock")].val.lValue = (intptr_t)&totalclock; aGameVars[Gv_GetVarIndex("lastvisinc")].val.lValue = (intptr_t)&lastvisinc; aGameVars[Gv_GetVarIndex("numsectors")].val.lValue = (intptr_t)&numsectors; aGameVars[Gv_GetVarIndex("numplayers")].val.lValue = (intptr_t)&numplayers; aGameVars[Gv_GetVarIndex("current_menu")].val.lValue = (intptr_t)&g_currentMenu; aGameVars[Gv_GetVarIndex("viewingrange")].val.lValue = (intptr_t)&viewingrange; aGameVars[Gv_GetVarIndex("yxaspect")].val.lValue = (intptr_t)&yxaspect; aGameVars[Gv_GetVarIndex("gravitationalconstant")].val.lValue = (intptr_t)&g_spriteGravity; aGameVars[Gv_GetVarIndex("gametype_flags")].val.lValue = (intptr_t)&GametypeFlags[ud.coop]; aGameVars[Gv_GetVarIndex("framerate")].val.lValue = (intptr_t)&g_currentFrameRate; aGameVars[Gv_GetVarIndex("camerax")].val.lValue = (intptr_t)&ud.camera.x; aGameVars[Gv_GetVarIndex("cameray")].val.lValue = (intptr_t)&ud.camera.y; aGameVars[Gv_GetVarIndex("cameraz")].val.lValue = (intptr_t)&ud.camera.z; aGameVars[Gv_GetVarIndex("cameraang")].val.lValue = (intptr_t)&ud.cameraang; aGameVars[Gv_GetVarIndex("camerahoriz")].val.lValue = (intptr_t)&ud.camerahoriz; aGameVars[Gv_GetVarIndex("camerasect")].val.lValue = (intptr_t)&ud.camerasect; aGameVars[Gv_GetVarIndex("cameradist")].val.lValue = (intptr_t)&g_cameraDistance; aGameVars[Gv_GetVarIndex("cameraclock")].val.lValue = (intptr_t)&g_cameraClock; aGameVars[Gv_GetVarIndex("myx")].val.lValue = (intptr_t)&my.x; aGameVars[Gv_GetVarIndex("myy")].val.lValue = (intptr_t)&my.y; aGameVars[Gv_GetVarIndex("myz")].val.lValue = (intptr_t)&my.z; aGameVars[Gv_GetVarIndex("omyx")].val.lValue = (intptr_t)&omy.x; aGameVars[Gv_GetVarIndex("omyy")].val.lValue = (intptr_t)&omy.y; aGameVars[Gv_GetVarIndex("omyz")].val.lValue = (intptr_t)&omy.z; aGameVars[Gv_GetVarIndex("myvelx")].val.lValue = (intptr_t)&myvel.x; aGameVars[Gv_GetVarIndex("myvely")].val.lValue = (intptr_t)&myvel.y; aGameVars[Gv_GetVarIndex("myvelz")].val.lValue = (intptr_t)&myvel.z; aGameVars[Gv_GetVarIndex("myhoriz")].val.lValue = (intptr_t)&myhoriz; aGameVars[Gv_GetVarIndex("myhorizoff")].val.lValue = (intptr_t)&myhorizoff; aGameVars[Gv_GetVarIndex("omyhoriz")].val.lValue = (intptr_t)&omyhoriz; aGameVars[Gv_GetVarIndex("omyhorizoff")].val.lValue = (intptr_t)&omyhorizoff; aGameVars[Gv_GetVarIndex("myang")].val.lValue = (intptr_t)&myang; aGameVars[Gv_GetVarIndex("omyang")].val.lValue = (intptr_t)&omyang; aGameVars[Gv_GetVarIndex("mycursectnum")].val.lValue = (intptr_t)&mycursectnum; aGameVars[Gv_GetVarIndex("myjumpingcounter")].val.lValue = (intptr_t)&myjumpingcounter; aGameVars[Gv_GetVarIndex("myjumpingtoggle")].val.lValue = (intptr_t)&myjumpingtoggle; aGameVars[Gv_GetVarIndex("myonground")].val.lValue = (intptr_t)&myonground; aGameVars[Gv_GetVarIndex("myhardlanding")].val.lValue = (intptr_t)&myhardlanding; aGameVars[Gv_GetVarIndex("myreturntocenter")].val.lValue = (intptr_t)&myreturntocenter; aGameVars[Gv_GetVarIndex("display_mirror")].val.lValue = (intptr_t)&display_mirror; aGameVars[Gv_GetVarIndex("randomseed")].val.lValue = (intptr_t)&randomseed; aGameVars[Gv_GetVarIndex("NUMWALLS")].val.lValue = (intptr_t)&numwalls; aGameVars[Gv_GetVarIndex("NUMSECTORS")].val.lValue = (intptr_t)&numsectors; aGameVars[Gv_GetVarIndex("Numsprites")].val.lValue = (intptr_t)&Numsprites; aGameVars[Gv_GetVarIndex("lastsavepos")].val.lValue = (intptr_t)&g_lastSaveSlot; #ifdef USE_OPENGL aGameVars[Gv_GetVarIndex("rendmode")].val.lValue = (intptr_t)&rendmode; #endif }