mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-28 12:30:46 +00:00
ae5f941ad0
git-svn-id: https://svn.eduke32.com/eduke32@5821 1a8010ca-5511-0410-912e-c29ae57300e0
1900 lines
71 KiB
C
1900 lines
71 KiB
C
//-------------------------------------------------------------------------
|
|
/*
|
|
Copyright (C) 2016 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
//-------------------------------------------------------------------------
|
|
|
|
#include "duke3d.h"
|
|
#include "menus.h"
|
|
|
|
#define gamevars_c_
|
|
|
|
#ifdef LUNATIC
|
|
int32_t g_noResetVars;
|
|
LUNATIC_CB void (*A_ResetVars)(int32_t iActor);
|
|
#else
|
|
|
|
gamevar_t aGameVars[MAXGAMEVARS];
|
|
gamearray_t aGameArrays[MAXGAMEARRAYS];
|
|
int32_t g_gameVarCount=0;
|
|
int32_t g_gameArrayCount=0;
|
|
|
|
// pointers to weapon gamevar data
|
|
intptr_t *aplWeaponClip[MAX_WEAPONS]; // number of items in magazine
|
|
intptr_t *aplWeaponReload[MAX_WEAPONS]; // delay to reload (include fire)
|
|
intptr_t *aplWeaponFireDelay[MAX_WEAPONS]; // delay to fire
|
|
intptr_t *aplWeaponHoldDelay[MAX_WEAPONS]; // delay after release fire button to fire (0 for none)
|
|
intptr_t *aplWeaponTotalTime[MAX_WEAPONS]; // The total time the weapon is cycling before next fire.
|
|
intptr_t *aplWeaponFlags[MAX_WEAPONS]; // Flags for weapon
|
|
intptr_t *aplWeaponShoots[MAX_WEAPONS]; // what the weapon shoots
|
|
intptr_t *aplWeaponSpawnTime[MAX_WEAPONS]; // the frame at which to spawn an item
|
|
intptr_t *aplWeaponSpawn[MAX_WEAPONS]; // the item to spawn
|
|
intptr_t *aplWeaponShotsPerBurst[MAX_WEAPONS]; // number of shots per 'burst' (one ammo per 'burst')
|
|
intptr_t *aplWeaponWorksLike[MAX_WEAPONS]; // What original the weapon works like
|
|
intptr_t *aplWeaponInitialSound[MAX_WEAPONS]; // Sound made when weapon starts firing. zero for no sound
|
|
intptr_t *aplWeaponFireSound[MAX_WEAPONS]; // Sound made when firing (each time for automatic)
|
|
intptr_t *aplWeaponSound2Time[MAX_WEAPONS]; // Alternate sound time
|
|
intptr_t *aplWeaponSound2Sound[MAX_WEAPONS]; // Alternate sound sound ID
|
|
intptr_t *aplWeaponReloadSound1[MAX_WEAPONS]; // Sound of magazine being removed
|
|
intptr_t *aplWeaponReloadSound2[MAX_WEAPONS]; // Sound of magazine being inserted
|
|
intptr_t *aplWeaponSelectSound[MAX_WEAPONS]; // Sound of weapon being selected
|
|
intptr_t *aplWeaponFlashColor[MAX_WEAPONS]; // Muzzle flash color
|
|
|
|
# include "gamestructures.c"
|
|
|
|
// Frees the memory for the *values* of game variables and arrays. Resets their
|
|
// counts to zero. Call this function as many times as needed.
|
|
//
|
|
// Returns: old g_gameVarCount | (g_gameArrayCount<<16).
|
|
static int32_t Gv_Free(void)
|
|
{
|
|
for (int32_t i=0; i<g_gameVarCount; i++)
|
|
{
|
|
if (aGameVars[i].nFlags & GAMEVAR_USER_MASK)
|
|
ALIGNED_FREE_AND_NULL(aGameVars[i].pValues);
|
|
|
|
aGameVars[i].nFlags |= GAMEVAR_RESET;
|
|
}
|
|
|
|
for (int32_t i=0; i<g_gameArrayCount; i++)
|
|
{
|
|
if (aGameArrays[i].nFlags & GAMEARRAY_NORMAL)
|
|
ALIGNED_FREE_AND_NULL(aGameArrays[i].pValues);
|
|
|
|
aGameArrays[i].nFlags |= GAMEARRAY_RESET;
|
|
}
|
|
|
|
EDUKE32_STATIC_ASSERT(MAXGAMEVARS < 32768);
|
|
int32_t ret = g_gameVarCount | (g_gameArrayCount<<16);
|
|
g_gameVarCount = g_gameArrayCount = 0;
|
|
|
|
hash_init(&h_gamevars);
|
|
hash_init(&h_arrays);
|
|
|
|
return ret;
|
|
}
|
|
|
|
// Calls Gv_Free() and in addition frees the labels of all game variables and
|
|
// arrays.
|
|
// Only call this function ONCE...
|
|
static void Gv_Clear(void)
|
|
{
|
|
int32_t n = Gv_Free();
|
|
int32_t gameVarCount = n&65535, gameArrayCount = n>>16;
|
|
|
|
// Now, only do work that Gv_Free() hasn't done.
|
|
for (int32_t i=0; i<gameVarCount; i++)
|
|
DO_FREE_AND_NULL(aGameVars[i].szLabel);
|
|
|
|
for (int32_t i=0; i<gameArrayCount; i++)
|
|
DO_FREE_AND_NULL(aGameArrays[i].szLabel);
|
|
}
|
|
|
|
int32_t Gv_ReadSave(int32_t fil, int32_t newbehav)
|
|
{
|
|
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 (int i=0; i<g_gameVarCount; i++)
|
|
{
|
|
char *const olabel = aGameVars[i].szLabel;
|
|
|
|
if (kdfread(&aGameVars[i], sizeof(gamevar_t), 1, fil) != 1)
|
|
goto corrupt;
|
|
|
|
if (olabel == NULL)
|
|
aGameVars[i].szLabel = (char *)Xmalloc(MAXVARLABEL * sizeof(uint8_t));
|
|
else
|
|
aGameVars[i].szLabel = olabel;
|
|
|
|
if (kdfread(aGameVars[i].szLabel, MAXVARLABEL, 1, fil) != 1)
|
|
goto corrupt;
|
|
hash_add(&h_gamevars, aGameVars[i].szLabel,i, 1);
|
|
|
|
if (aGameVars[i].nFlags & GAMEVAR_PERPLAYER)
|
|
{
|
|
aGameVars[i].pValues = (intptr_t*)Xaligned_alloc(PLAYER_VAR_ALIGNMENT, MAXPLAYERS * sizeof(intptr_t));
|
|
if (kdfread(aGameVars[i].pValues,sizeof(intptr_t) * MAXPLAYERS, 1, fil) != 1) goto corrupt;
|
|
}
|
|
else if (aGameVars[i].nFlags & GAMEVAR_PERACTOR)
|
|
{
|
|
aGameVars[i].pValues = (intptr_t*)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, MAXSPRITES * sizeof(intptr_t));
|
|
if (kdfread(&aGameVars[i].pValues[0],sizeof(intptr_t), MAXSPRITES, fil) != MAXSPRITES) goto corrupt;
|
|
}
|
|
}
|
|
// Bsprintf(g_szBuf,"CP:%s %d",__FILE__,__LINE__);
|
|
// AddLog(g_szBuf);
|
|
|
|
Gv_InitWeaponPointers();
|
|
|
|
// Bsprintf(g_szBuf,"CP:%s %d",__FILE__,__LINE__);
|
|
// AddLog(g_szBuf);
|
|
Gv_RefreshPointers();
|
|
|
|
if (kdfread(&g_gameArrayCount,sizeof(g_gameArrayCount),1,fil) != 1) goto corrupt;
|
|
for (int i=0; i<g_gameArrayCount; i++)
|
|
{
|
|
if (aGameArrays[i].nFlags&GAMEARRAY_READONLY)
|
|
continue;
|
|
|
|
char *const olabel = aGameArrays[i].szLabel;
|
|
|
|
// read for .size and .dwFlags (the rest are pointers):
|
|
if (kdfread(&aGameArrays[i], sizeof(gamearray_t), 1, fil) != 1)
|
|
goto corrupt;
|
|
|
|
if (olabel == NULL)
|
|
aGameArrays[i].szLabel = (char *)Xmalloc(MAXARRAYLABEL * sizeof(uint8_t));
|
|
else
|
|
aGameArrays[i].szLabel = olabel;
|
|
|
|
if (kdfread(aGameArrays[i].szLabel,sizeof(uint8_t) * MAXARRAYLABEL, 1, fil) != 1)
|
|
goto corrupt;
|
|
hash_add(&h_arrays, aGameArrays[i].szLabel, i, 1);
|
|
|
|
intptr_t const asize = aGameArrays[i].size;
|
|
if (asize != 0)
|
|
{
|
|
aGameArrays[i].pValues = (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, asize * GAR_ELTSZ);
|
|
if (kdfread(aGameArrays[i].pValues, GAR_ELTSZ * aGameArrays[i].size, 1, fil) < 1) goto corrupt;
|
|
}
|
|
else
|
|
aGameArrays[i].pValues = NULL;
|
|
}
|
|
|
|
// Bsprintf(g_szBuf,"CP:%s %d",__FILE__,__LINE__);
|
|
// AddLog(g_szBuf);
|
|
if (kdfread(apScriptGameEvent,sizeof(apScriptGameEvent),1,fil) != 1) goto corrupt;
|
|
|
|
// Bsprintf(g_szBuf,"CP:%s %d",__FILE__,__LINE__);
|
|
// AddLog(g_szBuf);
|
|
|
|
if (kdfread(&savedstate[0],sizeof(savedstate),1,fil) != 1) goto corrupt;
|
|
|
|
for (int i=0; i<(MAXVOLUMES*MAXLEVELS); i++)
|
|
{
|
|
if (savedstate[i])
|
|
{
|
|
if (MapInfo[i].savedstate == NULL)
|
|
MapInfo[i].savedstate = (mapstate_t *)Xaligned_alloc(16, sizeof(mapstate_t));
|
|
if (kdfread(MapInfo[i].savedstate,sizeof(mapstate_t),1,fil) != sizeof(mapstate_t)) goto corrupt;
|
|
for (int j=0; j<g_gameVarCount; j++)
|
|
{
|
|
if (aGameVars[j].nFlags & GAMEVAR_NORESET) continue;
|
|
if (aGameVars[j].nFlags & GAMEVAR_PERPLAYER)
|
|
{
|
|
// if (!MapInfo[i].savedstate->vars[j])
|
|
MapInfo[i].savedstate->vars[j] = (intptr_t *)Xaligned_alloc(PLAYER_VAR_ALIGNMENT, 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].nFlags & GAMEVAR_PERACTOR)
|
|
{
|
|
// if (!MapInfo[i].savedstate->vars[j])
|
|
MapInfo[i].savedstate->vars[j] = (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, MAXSPRITES * sizeof(intptr_t));
|
|
if (kdfread(&MapInfo[i].savedstate->vars[j][0],sizeof(intptr_t), MAXSPRITES, fil) != MAXSPRITES) goto corrupt;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
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)
|
|
{
|
|
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 (int i=0; i<g_gameVarCount; i++)
|
|
{
|
|
dfwrite(&(aGameVars[i]),sizeof(gamevar_t),1,fil);
|
|
dfwrite(aGameVars[i].szLabel,sizeof(uint8_t) * MAXVARLABEL, 1, fil);
|
|
|
|
if (aGameVars[i].nFlags & GAMEVAR_PERPLAYER)
|
|
{
|
|
//Bsprintf(g_szBuf,"Writing value array for %s (%d)",aGameVars[i].szLabel,sizeof(int32_t) * MAXPLAYERS);
|
|
//AddLog(g_szBuf);
|
|
dfwrite(aGameVars[i].pValues,sizeof(intptr_t) * MAXPLAYERS, 1, fil);
|
|
}
|
|
else if (aGameVars[i].nFlags & GAMEVAR_PERACTOR)
|
|
{
|
|
//Bsprintf(g_szBuf,"Writing value array for %s (%d)",aGameVars[i].szLabel,sizeof(int32_t) * MAXSPRITES);
|
|
//AddLog(g_szBuf);
|
|
dfwrite(&aGameVars[i].pValues[0],sizeof(intptr_t), MAXSPRITES, fil);
|
|
}
|
|
}
|
|
|
|
dfwrite(&g_gameArrayCount,sizeof(g_gameArrayCount),1,fil);
|
|
|
|
for (int i=0; i<g_gameArrayCount; i++)
|
|
{
|
|
if (aGameArrays[i].nFlags&GAMEARRAY_READONLY)
|
|
continue;
|
|
|
|
// write for .size and .dwFlags (the rest are pointers):
|
|
dfwrite(&aGameArrays[i],sizeof(gamearray_t),1,fil);
|
|
|
|
dfwrite(aGameArrays[i].szLabel,sizeof(uint8_t) * MAXARRAYLABEL, 1, fil);
|
|
dfwrite(aGameArrays[i].pValues, GAR_ELTSZ * aGameArrays[i].size, 1, fil);
|
|
}
|
|
|
|
dfwrite(apScriptGameEvent,sizeof(apScriptGameEvent),1,fil);
|
|
|
|
for (int i=0; i<(MAXVOLUMES*MAXLEVELS); i++)
|
|
if (MapInfo[i].savedstate != NULL)
|
|
savedstate[i] = 1;
|
|
|
|
dfwrite(&savedstate[0],sizeof(savedstate),1,fil);
|
|
|
|
for (int i=0; i<(MAXVOLUMES*MAXLEVELS); i++)
|
|
if (MapInfo[i].savedstate)
|
|
{
|
|
dfwrite(MapInfo[i].savedstate,sizeof(mapstate_t),1,fil);
|
|
for (int j=0; j<g_gameVarCount; j++)
|
|
{
|
|
if (aGameVars[j].nFlags & GAMEVAR_NORESET) continue;
|
|
if (aGameVars[j].nFlags & GAMEVAR_PERPLAYER)
|
|
{
|
|
dfwrite(&MapInfo[i].savedstate->vars[j][0],sizeof(intptr_t) * MAXPLAYERS, 1, fil);
|
|
}
|
|
else if (aGameVars[j].nFlags & 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<g_gameVarCount; i++)
|
|
{
|
|
OSD_Printf("gamevar %s ",aGameVars[i].szLabel);
|
|
|
|
if (aGameVars[i].nFlags & (GAMEVAR_INTPTR))
|
|
OSD_Printf("%d",*((int32_t *)aGameVars[i].nValue));
|
|
else if (aGameVars[i].nFlags & (GAMEVAR_SHORTPTR))
|
|
OSD_Printf("%d",*((int16_t *)aGameVars[i].nValue));
|
|
else if (aGameVars[i].nFlags & (GAMEVAR_CHARPTR))
|
|
OSD_Printf("%d",*((char *)aGameVars[i].nValue));
|
|
else
|
|
OSD_Printf("%" PRIdPTR "",aGameVars[i].nValue);
|
|
|
|
if (aGameVars[i].nFlags & (GAMEVAR_PERPLAYER))
|
|
OSD_Printf(" GAMEVAR_PERPLAYER");
|
|
else if (aGameVars[i].nFlags & (GAMEVAR_PERACTOR))
|
|
OSD_Printf(" GAMEVAR_PERACTOR");
|
|
else
|
|
OSD_Printf(" %" PRIdPTR,aGameVars[i].nFlags/* & (GAMEVAR_USER_MASK)*/);
|
|
|
|
OSD_Printf(" // ");
|
|
if (aGameVars[i].nFlags & (GAMEVAR_SYSTEM))
|
|
OSD_Printf(" (system)");
|
|
if (aGameVars[i].nFlags & (GAMEVAR_PTR_MASK))
|
|
OSD_Printf(" (pointer)");
|
|
if (aGameVars[i].nFlags & (GAMEVAR_READONLY))
|
|
OSD_Printf(" (read only)");
|
|
if (aGameVars[i].nFlags & (GAMEVAR_SPECIAL))
|
|
OSD_Printf(" (special)");
|
|
OSD_Printf("\n");
|
|
}
|
|
OSD_Printf("\n// end of game definitions\n");
|
|
}
|
|
|
|
// XXX: This function is very strange.
|
|
void Gv_ResetVars(void) /* this is called during a new game and nowhere else */
|
|
{
|
|
Gv_Free();
|
|
|
|
osd->log.errors = 0;
|
|
|
|
for (int i=0; i<MAXGAMEVARS; i++)
|
|
{
|
|
if (aGameVars[i].szLabel != NULL)
|
|
Gv_NewVar(aGameVars[i].szLabel,
|
|
aGameVars[i].nFlags & GAMEVAR_NODEFAULT ? aGameVars[i].nValue : aGameVars[i].nDefault,
|
|
aGameVars[i].nFlags);
|
|
}
|
|
|
|
for (int i=0; i<MAXGAMEARRAYS; i++)
|
|
{
|
|
if (aGameArrays[i].szLabel != NULL && (aGameArrays[i].nFlags & GAMEARRAY_RESET))
|
|
Gv_NewArray(aGameArrays[i].szLabel,aGameArrays[i].pValues,aGameArrays[i].size,aGameArrays[i].nFlags);
|
|
}
|
|
}
|
|
|
|
int32_t Gv_NewArray(const char *pszLabel, void *arrayptr, intptr_t asize, uint32_t dwFlags)
|
|
{
|
|
int32_t i;
|
|
|
|
if (EDUKE32_PREDICT_FALSE(g_gameArrayCount >= MAXGAMEARRAYS))
|
|
{
|
|
g_numCompilerErrors++;
|
|
C_ReportError(-1);
|
|
initprintf("%s:%d: error: too many arrays!\n",g_szScriptFileName,g_lineNumber);
|
|
return 0;
|
|
}
|
|
|
|
if (EDUKE32_PREDICT_FALSE(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 (EDUKE32_PREDICT_FALSE(i >=0 && !(aGameArrays[i].nFlags & GAMEARRAY_RESET)))
|
|
{
|
|
// found it it's a duplicate in error
|
|
|
|
g_numCompilerWarnings++;
|
|
|
|
if (aGameArrays[i].nFlags&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 *)Xcalloc(MAXVARLABEL,sizeof(uint8_t));
|
|
|
|
if (aGameArrays[i].szLabel != pszLabel)
|
|
Bstrcpy(aGameArrays[i].szLabel,pszLabel);
|
|
|
|
if (!(dwFlags & GAMEARRAY_TYPE_MASK))
|
|
{
|
|
Baligned_free(aGameArrays[i].pValues);
|
|
if (asize != 0)
|
|
{
|
|
aGameArrays[i].pValues = (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, asize * GAR_ELTSZ);
|
|
Bmemset(aGameArrays[i].pValues, 0, asize * GAR_ELTSZ);
|
|
}
|
|
else
|
|
aGameArrays[i].pValues = NULL;
|
|
}
|
|
else
|
|
aGameArrays[i].pValues=(intptr_t *)arrayptr;
|
|
|
|
aGameArrays[i].size=asize;
|
|
aGameArrays[i].nFlags = 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 (EDUKE32_PREDICT_FALSE(g_gameVarCount >= MAXGAMEVARS))
|
|
{
|
|
g_numCompilerErrors++;
|
|
C_ReportError(-1);
|
|
initprintf("%s:%d: error: too many gamevars!\n",g_szScriptFileName,g_lineNumber);
|
|
return 0;
|
|
}
|
|
|
|
if (EDUKE32_PREDICT_FALSE(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].nFlags & GAMEVAR_RESET))
|
|
{
|
|
// found it...
|
|
if (EDUKE32_PREDICT_FALSE(aGameVars[i].nFlags & (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 (EDUKE32_PREDICT_FALSE(!(aGameVars[i].nFlags & GAMEVAR_SYSTEM)))
|
|
{
|
|
// it's a duplicate in error
|
|
g_numCompilerWarnings++;
|
|
C_ReportError(WARNING_DUPLICATEDEFINITION);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (i == -1)
|
|
i = g_gameVarCount;
|
|
|
|
// If it's a user gamevar...
|
|
if ((aGameVars[i].nFlags & GAMEVAR_SYSTEM) == 0)
|
|
{
|
|
// Allocate and set its label
|
|
if (aGameVars[i].szLabel == NULL)
|
|
aGameVars[i].szLabel = (char *)Xcalloc(MAXVARLABEL,sizeof(uint8_t));
|
|
|
|
if (aGameVars[i].szLabel != pszLabel)
|
|
Bstrcpy(aGameVars[i].szLabel,pszLabel);
|
|
|
|
// and the flags
|
|
aGameVars[i].nFlags=dwFlags;
|
|
|
|
// only free if per-{actor,player}
|
|
if (aGameVars[i].nFlags & GAMEVAR_USER_MASK)
|
|
ALIGNED_FREE_AND_NULL(aGameVars[i].pValues);
|
|
}
|
|
|
|
// if existing is system, they only get to change default value....
|
|
aGameVars[i].nDefault = lValue;
|
|
aGameVars[i].nFlags &= ~GAMEVAR_RESET;
|
|
|
|
if (i == g_gameVarCount)
|
|
{
|
|
// we're adding a new one.
|
|
hash_add(&h_gamevars, aGameVars[i].szLabel, g_gameVarCount++, 0);
|
|
}
|
|
|
|
// Set initial values. (Or, override values for system gamevars.)
|
|
if (aGameVars[i].nFlags & GAMEVAR_PERPLAYER)
|
|
{
|
|
if (!aGameVars[i].pValues)
|
|
{
|
|
aGameVars[i].pValues = (intptr_t *) Xaligned_alloc(PLAYER_VAR_ALIGNMENT, MAXPLAYERS * sizeof(intptr_t));
|
|
Bmemset(aGameVars[i].pValues, 0, MAXPLAYERS * sizeof(intptr_t));
|
|
}
|
|
for (j=MAXPLAYERS-1; j>=0; j--)
|
|
aGameVars[i].pValues[j]=lValue;
|
|
}
|
|
else if (aGameVars[i].nFlags & GAMEVAR_PERACTOR)
|
|
{
|
|
if (!aGameVars[i].pValues)
|
|
{
|
|
aGameVars[i].pValues = (intptr_t *) Xaligned_alloc(ACTOR_VAR_ALIGNMENT, MAXSPRITES * sizeof(intptr_t));
|
|
Bmemset(aGameVars[i].pValues, 0, MAXSPRITES * sizeof(intptr_t));
|
|
}
|
|
for (j=MAXSPRITES-1; j>=0; j--)
|
|
aGameVars[i].pValues[j]=lValue;
|
|
}
|
|
else aGameVars[i].nValue = lValue;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int32_t Gv_GetVarIndex(const char *szGameLabel)
|
|
{
|
|
int32_t i = hash_find(&h_gamevars,szGameLabel);
|
|
|
|
if (EDUKE32_PREDICT_FALSE(i == -1))
|
|
{
|
|
OSD_Printf(OSD_ERROR "Gv_GetVarIndex(): INTERNAL ERROR: couldn't find gamevar %s!\n",szGameLabel);
|
|
return 0;
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
int32_t __fastcall Gv_GetGameArrayValue(int const id, int index)
|
|
{
|
|
if (aGameArrays[id].nFlags & GAMEARRAY_STRIDE2)
|
|
index <<= 1;
|
|
|
|
int rv = -1;
|
|
|
|
switch (aGameArrays[id].nFlags & GAMEARRAY_TYPE_MASK)
|
|
{
|
|
case 0: rv = (aGameArrays[id].pValues)[index]; break;
|
|
case GAMEARRAY_OFINT: rv = ((int32_t *)aGameArrays[id].pValues)[index]; break;
|
|
case GAMEARRAY_OFSHORT: rv = ((int16_t *)aGameArrays[id].pValues)[index]; break;
|
|
case GAMEARRAY_OFCHAR: rv = ((uint8_t *)aGameArrays[id].pValues)[index]; break;
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
int32_t __fastcall Gv_GetVar(int nGameVar, int nSprite, int nPlayer)
|
|
{
|
|
if (nGameVar == g_iThisActorID)
|
|
return nSprite;
|
|
|
|
if (nGameVar == MAXGAMEVARS)
|
|
return *insptr++;
|
|
|
|
int nNegative = !!(nGameVar & (MAXGAMEVARS << 1));
|
|
|
|
if (EDUKE32_PREDICT_FALSE((nGameVar & ~(MAXGAMEVARS << 1)) >= g_gameVarCount))
|
|
goto nastyhacks;
|
|
|
|
nGameVar &= (MAXGAMEVARS - 1);
|
|
|
|
int nReturn, nFlags;
|
|
nFlags = aGameVars[nGameVar].nFlags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK);
|
|
|
|
if (nFlags == GAMEVAR_PERACTOR)
|
|
{
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nSprite >= MAXSPRITES)) goto badindex;
|
|
nReturn = aGameVars[nGameVar].pValues[nSprite];
|
|
}
|
|
else if (!nFlags) nReturn = aGameVars[nGameVar].nValue;
|
|
else if (nFlags == GAMEVAR_PERPLAYER)
|
|
{
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nPlayer >= MAXPLAYERS))
|
|
{
|
|
nSprite = nPlayer;
|
|
goto badindex;
|
|
}
|
|
nReturn = aGameVars[nGameVar].pValues[nPlayer];
|
|
}
|
|
else switch (nFlags)
|
|
{
|
|
case GAMEVAR_INTPTR: nReturn = *(int32_t *)aGameVars[nGameVar].nValue; break;
|
|
case GAMEVAR_SHORTPTR: nReturn = *(int16_t *)aGameVars[nGameVar].nValue; break;
|
|
case GAMEVAR_CHARPTR: nReturn = *(char *)aGameVars[nGameVar].nValue; break;
|
|
default: EDUKE32_UNREACHABLE_SECTION(nReturn = 0; break);
|
|
}
|
|
|
|
return (nReturn ^ -nNegative) + nNegative;
|
|
|
|
nastyhacks:
|
|
if (nGameVar & (MAXGAMEVARS << 2)) // array
|
|
{
|
|
nGameVar &= (MAXGAMEVARS - 1); // ~((MAXGAMEVARS<<2)|(MAXGAMEVARS<<1));
|
|
|
|
int nArrayIndex = Gv_GetVar(*insptr++, nSprite, nPlayer);
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)nArrayIndex >= (unsigned)aGameArrays[nGameVar].size))
|
|
{
|
|
nSprite = nArrayIndex;
|
|
goto badarrayindex;
|
|
}
|
|
|
|
nReturn = Gv_GetGameArrayValue(nGameVar, nArrayIndex);
|
|
}
|
|
else if (nGameVar&(MAXGAMEVARS<<3)) // struct shortcut vars
|
|
{
|
|
int nArrayIndexVar = *insptr++;
|
|
int nArrayIndex = Gv_GetVar(nArrayIndexVar, nSprite, nPlayer);
|
|
|
|
nGameVar &= (MAXGAMEVARS - 1);
|
|
|
|
switch (nGameVar - g_iStructVarIDs)
|
|
{
|
|
case STRUCT_SPRITE:
|
|
{
|
|
int const label = *insptr++;
|
|
|
|
nArrayIndexVar = (EDUKE32_PREDICT_FALSE(ActorLabels[label].flags & LABEL_HASPARM2)) ?
|
|
Gv_GetVar(*insptr++, nSprite, nPlayer) : 0;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXSPRITES))
|
|
{
|
|
nSprite = nArrayIndex;
|
|
goto badindex;
|
|
}
|
|
|
|
nReturn = VM_GetSprite(nArrayIndex, label, nArrayIndexVar);
|
|
break;
|
|
}
|
|
case STRUCT_TSPR:
|
|
{
|
|
int const label = *insptr++;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXSPRITES))
|
|
{
|
|
nSprite = nArrayIndex;
|
|
goto badindex;
|
|
}
|
|
|
|
nReturn = VM_GetTsprite(nArrayIndex, label);
|
|
break;
|
|
}
|
|
case STRUCT_THISPROJECTILE:
|
|
{
|
|
int const label = *insptr++;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXSPRITES))
|
|
{
|
|
nSprite = nArrayIndex;
|
|
goto badindex;
|
|
}
|
|
|
|
nReturn = VM_GetActiveProjectile(nArrayIndex, label);
|
|
break;
|
|
}
|
|
|
|
case STRUCT_PROJECTILE:
|
|
{
|
|
int const label = *insptr++;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXTILES))
|
|
{
|
|
nSprite = nArrayIndex;
|
|
goto badindex;
|
|
}
|
|
|
|
nReturn = VM_GetProjectile(nArrayIndex, label);
|
|
break;
|
|
}
|
|
case STRUCT_TILEDATA:
|
|
{
|
|
int const label = *insptr++;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXTILES))
|
|
{
|
|
nSprite = nArrayIndex;
|
|
goto badindex;
|
|
}
|
|
|
|
nReturn = VM_GetTileData(nArrayIndex, label);
|
|
break;
|
|
}
|
|
|
|
case STRUCT_PALDATA:
|
|
{
|
|
int const label = *insptr++;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXPALOOKUPS))
|
|
{
|
|
nSprite = nArrayIndex;
|
|
goto badindex;
|
|
}
|
|
|
|
nReturn = VM_GetPalData(nArrayIndex, label);
|
|
break;
|
|
}
|
|
|
|
case STRUCT_PLAYER:
|
|
{
|
|
int const label = *insptr++;
|
|
|
|
if (nArrayIndexVar == g_iThisActorID) nArrayIndex = vm.g_p;
|
|
|
|
nArrayIndexVar = (EDUKE32_PREDICT_FALSE(PlayerLabels[label].flags & LABEL_HASPARM2)) ?
|
|
Gv_GetVar(*insptr++, nSprite, nPlayer) : 0;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXPLAYERS))
|
|
{
|
|
nSprite = nArrayIndex;
|
|
goto badindex;
|
|
}
|
|
|
|
nReturn = VM_GetPlayer(nArrayIndex, label, nArrayIndexVar);
|
|
break;
|
|
}
|
|
case STRUCT_INPUT:
|
|
{
|
|
int const label = *insptr++;
|
|
|
|
if (nArrayIndexVar == g_iThisActorID) nArrayIndex = vm.g_p;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXPLAYERS))
|
|
{
|
|
nSprite = nArrayIndex;
|
|
goto badindex;
|
|
}
|
|
|
|
nReturn = VM_GetPlayerInput(nArrayIndex, label);
|
|
break;
|
|
}
|
|
|
|
case STRUCT_ACTORVAR:
|
|
case STRUCT_PLAYERVAR:
|
|
nReturn = Gv_GetVar(*insptr++, nArrayIndex, nPlayer);
|
|
break;
|
|
|
|
case STRUCT_SECTOR:
|
|
if (nArrayIndexVar == g_iThisActorID) nArrayIndex = sprite[vm.g_i].sectnum;
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXSECTORS))
|
|
{
|
|
nSprite = nArrayIndex;
|
|
insptr++;
|
|
goto badindex;
|
|
}
|
|
nReturn = VM_GetSector(nArrayIndex, *insptr++);
|
|
break;
|
|
|
|
case STRUCT_WALL:
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXWALLS))
|
|
{
|
|
nSprite = nArrayIndex;
|
|
insptr++;
|
|
goto badindex;
|
|
}
|
|
nReturn = VM_GetWall(nArrayIndex, *insptr++);
|
|
break;
|
|
|
|
case STRUCT_USERDEF:
|
|
nReturn = VM_GetUserdef(*insptr++);
|
|
break;
|
|
|
|
default:
|
|
EDUKE32_UNREACHABLE_SECTION(return -1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CON_ERRPRINTF("Gv_GetVar(): invalid gamevar ID (%d)\n", nGameVar);
|
|
return -1;
|
|
}
|
|
|
|
return (nReturn ^ -nNegative) + nNegative;
|
|
|
|
badarrayindex:
|
|
CON_ERRPRINTF("Gv_GetVar(): invalid array index (%s[%d])\n", aGameArrays[nGameVar].szLabel,nSprite);
|
|
return -1;
|
|
|
|
badindex:
|
|
CON_ERRPRINTF("Gv_GetVar(): invalid index %d for \"%s\"\n", nSprite, aGameVars[nGameVar].szLabel);
|
|
return -1;
|
|
}
|
|
|
|
void __fastcall Gv_SetVar(int const nGameVar, int32_t const nValue, int const nSprite, int const nPlayer)
|
|
{
|
|
int const nFlags = aGameVars[nGameVar].nFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK);
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)nGameVar >= (unsigned)g_gameVarCount)) goto badvarid;
|
|
|
|
if (!nFlags) aGameVars[nGameVar].nValue=nValue;
|
|
else if (nFlags == GAMEVAR_PERPLAYER)
|
|
{
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nPlayer > MAXPLAYERS-1)) goto badindex;
|
|
// for the current player
|
|
aGameVars[nGameVar].pValues[nPlayer]=nValue;
|
|
}
|
|
else if (nFlags == GAMEVAR_PERACTOR)
|
|
{
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nSprite > MAXSPRITES-1)) goto badindex;
|
|
aGameVars[nGameVar].pValues[nSprite]=nValue;
|
|
}
|
|
else
|
|
{
|
|
switch (nFlags)
|
|
{
|
|
case GAMEVAR_INTPTR: *((int32_t *)aGameVars[nGameVar].nValue) = (int32_t)nValue; break;
|
|
case GAMEVAR_SHORTPTR: *((int16_t *)aGameVars[nGameVar].nValue) = (int16_t)nValue; break;
|
|
case GAMEVAR_CHARPTR: *((uint8_t *)aGameVars[nGameVar].nValue) = (uint8_t)nValue; break;
|
|
}
|
|
}
|
|
return;
|
|
|
|
badvarid:
|
|
CON_ERRPRINTF("Gv_SetVar(): invalid gamevar (%d) from sprite %d (%d), player %d\n",
|
|
nGameVar,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[nGameVar].nFlags & GAMEVAR_PERACTOR ? nSprite : nPlayer,
|
|
aGameVars[nGameVar].szLabel,vm.g_i,vm.g_p);
|
|
}
|
|
|
|
enum
|
|
{
|
|
GVX_BADVARID = 0,
|
|
GVX_BADPLAYER,
|
|
GVX_BADSPRITE,
|
|
GVX_BADSECTOR,
|
|
GVX_BADWALL,
|
|
GVX_BADINDEX,
|
|
GVX_BADTILE,
|
|
GVX_BADPAL,
|
|
};
|
|
|
|
static const char *gvxerrs[] = {
|
|
"Gv_GetVarX(): invalid gamevar ID",
|
|
"Gv_GetVarX(): invalid player ID",
|
|
"Gv_GetVarX(): invalid sprite ID",
|
|
"Gv_GetVarX(): invalid sector ID",
|
|
"Gv_GetVarX(): invalid wall ID",
|
|
"Gv_GetVarX(): invalid array index",
|
|
"Gv_GetVarX(): invalid tile ID",
|
|
"Gv_GetVarX(): invalid pal ID",
|
|
};
|
|
|
|
int32_t __fastcall Gv_GetSpecialVarX(int nGameVar)
|
|
{
|
|
int nReturn = -1;
|
|
|
|
if (nGameVar & (MAXGAMEVARS << 2)) // array
|
|
{
|
|
int const nArrayIndex = Gv_GetVarX(*insptr++);
|
|
|
|
nGameVar &= (MAXGAMEVARS - 1); // ~((MAXGAMEVARS<<2)|(MAXGAMEVARS<<1));
|
|
|
|
int const nArraySize =
|
|
(aGameArrays[nGameVar].nFlags & GAMEARRAY_VARSIZE) ? Gv_GetVarX(aGameArrays[nGameVar].size) : aGameArrays[nGameVar].size;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= (unsigned) nArraySize))
|
|
{
|
|
CON_ERRPRINTF("%s %s[%d]\n", gvxerrs[GVX_BADINDEX], aGameArrays[nGameVar].szLabel, nArrayIndex);
|
|
return -1;
|
|
}
|
|
|
|
nReturn = Gv_GetGameArrayValue(nGameVar, nArrayIndex);
|
|
}
|
|
else if (nGameVar & (MAXGAMEVARS << 3)) // struct shortcut vars
|
|
{
|
|
int nArrayIndexVar = *insptr++;
|
|
int nArrayIndex = Gv_GetVarX(nArrayIndexVar);
|
|
|
|
switch ((nGameVar & (MAXGAMEVARS - 1)) - g_iStructVarIDs)
|
|
{
|
|
case STRUCT_SPRITE:
|
|
{
|
|
int const nLabel = *insptr++;
|
|
|
|
nArrayIndexVar = (EDUKE32_PREDICT_FALSE(ActorLabels[nLabel].flags & LABEL_HASPARM2)) ?
|
|
Gv_GetVarX(*insptr++) : 0;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXSPRITES))
|
|
{
|
|
nGameVar = nArrayIndex;
|
|
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADSPRITE], nGameVar);
|
|
return -1;
|
|
}
|
|
|
|
nReturn = VM_GetSprite(nArrayIndex, nLabel, nArrayIndexVar);
|
|
break;
|
|
}
|
|
case STRUCT_TSPR:
|
|
{
|
|
int const nLabel = *insptr++;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXSPRITES))
|
|
{
|
|
nGameVar = nArrayIndex;
|
|
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADSPRITE], nGameVar);
|
|
return -1;
|
|
}
|
|
|
|
nReturn = VM_GetTsprite(nArrayIndex, nLabel);
|
|
break;
|
|
}
|
|
case STRUCT_THISPROJECTILE:
|
|
{
|
|
int const nLabel = *insptr++;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXSPRITES))
|
|
{
|
|
nGameVar = nArrayIndex;
|
|
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADSPRITE], nGameVar);
|
|
return -1;
|
|
}
|
|
|
|
nReturn = VM_GetActiveProjectile(nArrayIndex, nLabel);
|
|
break;
|
|
}
|
|
|
|
case STRUCT_PROJECTILE:
|
|
{
|
|
int const nLabel = *insptr++;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXTILES))
|
|
{
|
|
nGameVar = nArrayIndex;
|
|
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADTILE], nGameVar);
|
|
return -1;
|
|
}
|
|
|
|
nReturn = VM_GetProjectile(nArrayIndex, nLabel);
|
|
break;
|
|
}
|
|
case STRUCT_TILEDATA:
|
|
{
|
|
int const nLabel = *insptr++;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXTILES))
|
|
{
|
|
nGameVar = nArrayIndex;
|
|
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADTILE], nGameVar);
|
|
return -1;
|
|
}
|
|
|
|
nReturn = VM_GetTileData(nArrayIndex, nLabel);
|
|
break;
|
|
}
|
|
|
|
case STRUCT_PALDATA:
|
|
{
|
|
int const nLabel = *insptr++;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXPALOOKUPS))
|
|
{
|
|
nGameVar = nArrayIndex;
|
|
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADPAL], nGameVar);
|
|
return -1;
|
|
}
|
|
|
|
nReturn = VM_GetPalData(nArrayIndex, nLabel);
|
|
break;
|
|
}
|
|
|
|
case STRUCT_PLAYER:
|
|
{
|
|
int const nLabel = *insptr++;
|
|
|
|
if (nArrayIndexVar == g_iThisActorID)
|
|
nArrayIndex = vm.g_p;
|
|
|
|
nArrayIndexVar = (EDUKE32_PREDICT_FALSE(PlayerLabels[nLabel].flags & LABEL_HASPARM2)) ?
|
|
Gv_GetVarX(*insptr++) : 0;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXPLAYERS))
|
|
{
|
|
nGameVar = nArrayIndex;
|
|
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADPLAYER], nGameVar);
|
|
return -1;
|
|
}
|
|
|
|
nReturn = VM_GetPlayer(nArrayIndex, nLabel, nArrayIndexVar);
|
|
break;
|
|
}
|
|
case STRUCT_INPUT:
|
|
{
|
|
int const nLabel = *insptr++;
|
|
|
|
if (nArrayIndexVar == g_iThisActorID)
|
|
nArrayIndex = vm.g_p;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXPLAYERS))
|
|
{
|
|
nGameVar = nArrayIndex;
|
|
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADPLAYER], nGameVar);
|
|
return -1;
|
|
}
|
|
|
|
nReturn = VM_GetPlayerInput(nArrayIndex, nLabel);
|
|
break;
|
|
}
|
|
|
|
case STRUCT_ACTORVAR:
|
|
case STRUCT_PLAYERVAR:
|
|
nReturn = Gv_GetVar(*insptr++, nArrayIndex, vm.g_p);
|
|
break;
|
|
|
|
case STRUCT_SECTOR:
|
|
if (nArrayIndexVar == g_iThisActorID)
|
|
nArrayIndex = sprite[vm.g_i].sectnum;
|
|
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXSECTORS))
|
|
{
|
|
nGameVar = nArrayIndex;
|
|
insptr++;
|
|
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADSECTOR], nGameVar);
|
|
return -1;
|
|
}
|
|
nReturn = VM_GetSector(nArrayIndex, *insptr++);
|
|
break;
|
|
|
|
case STRUCT_WALL:
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) nArrayIndex >= MAXWALLS))
|
|
{
|
|
nGameVar = nArrayIndex;
|
|
insptr++;
|
|
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADWALL], nGameVar);
|
|
return -1;
|
|
}
|
|
nReturn = VM_GetWall(nArrayIndex, *insptr++);
|
|
break;
|
|
|
|
case STRUCT_USERDEF:
|
|
nReturn = VM_GetUserdef(*insptr++);
|
|
break;
|
|
|
|
default: EDUKE32_UNREACHABLE_SECTION(return -1);
|
|
}
|
|
}
|
|
|
|
return nReturn;
|
|
}
|
|
|
|
int32_t __fastcall Gv_GetVarX(int nGameVar)
|
|
{
|
|
if (nGameVar == g_iThisActorID)
|
|
return vm.g_i;
|
|
|
|
if (nGameVar == MAXGAMEVARS)
|
|
return *insptr++;
|
|
|
|
int const nNegative = !!(nGameVar & (MAXGAMEVARS << 1));
|
|
int nReturn = -1;
|
|
|
|
if (EDUKE32_PREDICT_FALSE(nGameVar >= g_gameVarCount && nNegative == 0))
|
|
nReturn = Gv_GetSpecialVarX(nGameVar);
|
|
else
|
|
{
|
|
nGameVar &= MAXGAMEVARS-1;
|
|
|
|
int const nFlags = aGameVars[nGameVar].nFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK);
|
|
|
|
if (!nFlags) nReturn = aGameVars[nGameVar].nValue;
|
|
else if (nFlags == GAMEVAR_PERPLAYER)
|
|
{
|
|
if (EDUKE32_PREDICT_FALSE((unsigned) vm.g_p >= MAXPLAYERS))
|
|
goto perr;
|
|
nReturn = aGameVars[nGameVar].pValues[vm.g_p];
|
|
}
|
|
else if (nFlags == GAMEVAR_PERACTOR)
|
|
nReturn = aGameVars[nGameVar].pValues[vm.g_i];
|
|
else switch (nFlags)
|
|
{
|
|
case GAMEVAR_INTPTR: nReturn = (*((int32_t *)aGameVars[nGameVar].nValue)); break;
|
|
case GAMEVAR_SHORTPTR: nReturn = (*((int16_t *)aGameVars[nGameVar].nValue)); break;
|
|
case GAMEVAR_CHARPTR: nReturn = (*((uint8_t *)aGameVars[nGameVar].nValue)); break;
|
|
}
|
|
}
|
|
|
|
return (nReturn ^ -nNegative) + nNegative;
|
|
|
|
perr:
|
|
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADPLAYER], vm.g_p);
|
|
return -1;
|
|
}
|
|
|
|
void __fastcall Gv_GetManyVars(int const count, int32_t * const rv)
|
|
{
|
|
for (int j = 0; j < count; ++j)
|
|
{
|
|
int nGameVar = *insptr++;
|
|
|
|
if (nGameVar == g_iThisActorID)
|
|
{
|
|
rv[j] = vm.g_i;
|
|
continue;
|
|
}
|
|
|
|
if (nGameVar == MAXGAMEVARS)
|
|
{
|
|
rv[j] = *insptr++;
|
|
continue;
|
|
}
|
|
|
|
int const nNegative = !!(nGameVar & (MAXGAMEVARS << 1));
|
|
|
|
if (EDUKE32_PREDICT_FALSE(nGameVar >= g_gameVarCount && nNegative == 0))
|
|
{
|
|
rv[j] = Gv_GetSpecialVarX(nGameVar);
|
|
continue;
|
|
}
|
|
|
|
nGameVar &= MAXGAMEVARS - 1;
|
|
|
|
int const nFlags = aGameVars[nGameVar].nFlags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK);
|
|
int nValue = aGameVars[nGameVar].nValue;
|
|
|
|
if (nFlags == GAMEVAR_PERPLAYER)
|
|
{
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)vm.g_p >= MAXPLAYERS))
|
|
goto perr;
|
|
nValue = aGameVars[nGameVar].pValues[vm.g_p];
|
|
}
|
|
else if (nFlags == GAMEVAR_PERACTOR)
|
|
nValue = aGameVars[nGameVar].pValues[vm.g_i];
|
|
else
|
|
{
|
|
switch (nFlags)
|
|
{
|
|
case GAMEVAR_INTPTR: nValue = (*((int32_t *)aGameVars[nGameVar].nValue)); break;
|
|
case GAMEVAR_SHORTPTR: nValue = (*((int16_t *)aGameVars[nGameVar].nValue)); break;
|
|
case GAMEVAR_CHARPTR: nValue = (*((uint8_t *)aGameVars[nGameVar].nValue)); break;
|
|
}
|
|
}
|
|
|
|
rv[j] = (nValue ^ -nNegative) + nNegative;
|
|
continue;
|
|
|
|
perr:
|
|
CON_ERRPRINTF("%s %d\n", gvxerrs[GVX_BADPLAYER], vm.g_p);
|
|
}
|
|
}
|
|
|
|
void __fastcall Gv_SetVarX(int const nGameVar, int32_t const nValue)
|
|
{
|
|
int const nFlags = aGameVars[nGameVar].nFlags & (GAMEVAR_USER_MASK|GAMEVAR_PTR_MASK);
|
|
|
|
if (!nFlags) aGameVars[nGameVar].nValue = nValue;
|
|
else if (nFlags == GAMEVAR_PERPLAYER)
|
|
{
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)vm.g_p >= MAXPLAYERS)) goto badindex;
|
|
aGameVars[nGameVar].pValues[vm.g_p] = nValue;
|
|
}
|
|
else if (nFlags == GAMEVAR_PERACTOR)
|
|
{
|
|
if (EDUKE32_PREDICT_FALSE((unsigned)vm.g_i >= MAXSPRITES)) goto badindex;
|
|
aGameVars[nGameVar].pValues[vm.g_i] = nValue;
|
|
}
|
|
else switch (nFlags)
|
|
{
|
|
case GAMEVAR_INTPTR: *((int32_t *)aGameVars[nGameVar].nValue) = (int32_t)nValue; break;
|
|
case GAMEVAR_SHORTPTR: *((int16_t *)aGameVars[nGameVar].nValue) = (int16_t)nValue; break;
|
|
case GAMEVAR_CHARPTR: *((uint8_t *)aGameVars[nGameVar].nValue) = (uint8_t)nValue; break;
|
|
}
|
|
|
|
return;
|
|
|
|
badindex:
|
|
CON_ERRPRINTF("Gv_SetVar(): invalid index (%d) for gamevar %s\n",
|
|
aGameVars[nGameVar].nFlags & GAMEVAR_PERACTOR ? vm.g_i : vm.g_p,
|
|
aGameVars[nGameVar].szLabel);
|
|
}
|
|
|
|
int32_t Gv_GetVarByLabel(const char *szGameLabel, int32_t const nDefault, int const nSprite, int const nPlayer)
|
|
{
|
|
int const nGameVar = hash_find(&h_gamevars, szGameLabel);
|
|
return EDUKE32_PREDICT_FALSE(nGameVar < 0) ? nDefault : Gv_GetVar(nGameVar, nSprite, nPlayer);
|
|
}
|
|
|
|
static intptr_t *Gv_GetVarDataPtr(const char *szGameLabel)
|
|
{
|
|
int const nGameVar = hash_find(&h_gamevars, szGameLabel);
|
|
|
|
if (EDUKE32_PREDICT_FALSE(nGameVar < 0))
|
|
return NULL;
|
|
|
|
if (aGameVars[nGameVar].nFlags & (GAMEVAR_PERACTOR | GAMEVAR_PERPLAYER))
|
|
{
|
|
if (EDUKE32_PREDICT_FALSE(!aGameVars[nGameVar].pValues))
|
|
CON_ERRPRINTF("Gv_GetVarDataPtr(): INTERNAL ERROR: NULL array !!!\n");
|
|
return aGameVars[nGameVar].pValues;
|
|
}
|
|
|
|
return &(aGameVars[nGameVar].nValue);
|
|
}
|
|
#endif // !defined LUNATIC
|
|
|
|
void Gv_ResetSystemDefaults(void)
|
|
{
|
|
// call many times...
|
|
#if !defined LUNATIC
|
|
char aszBuf[64];
|
|
|
|
//AddLog("ResetWeaponDefaults");
|
|
|
|
for (int nWeapon = 0; nWeapon < MAX_WEAPONS; ++nWeapon)
|
|
{
|
|
for (int nPlayer = 0; nPlayer < MAXPLAYERS; ++nPlayer)
|
|
{
|
|
Bsprintf(aszBuf, "WEAPON%d_CLIP", nWeapon);
|
|
aplWeaponClip[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
Bsprintf(aszBuf, "WEAPON%d_RELOAD", nWeapon);
|
|
aplWeaponReload[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
Bsprintf(aszBuf, "WEAPON%d_FIREDELAY", nWeapon);
|
|
aplWeaponFireDelay[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
Bsprintf(aszBuf, "WEAPON%d_TOTALTIME", nWeapon);
|
|
aplWeaponTotalTime[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
Bsprintf(aszBuf, "WEAPON%d_HOLDDELAY", nWeapon);
|
|
aplWeaponHoldDelay[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
Bsprintf(aszBuf, "WEAPON%d_FLAGS", nWeapon);
|
|
aplWeaponFlags[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
Bsprintf(aszBuf, "WEAPON%d_SHOOTS", nWeapon);
|
|
aplWeaponShoots[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
if ((unsigned)aplWeaponShoots[nWeapon][nPlayer] >= MAXTILES)
|
|
aplWeaponShoots[nWeapon][nPlayer] = 0;
|
|
Bsprintf(aszBuf, "WEAPON%d_SPAWNTIME", nWeapon);
|
|
aplWeaponSpawnTime[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
Bsprintf(aszBuf, "WEAPON%d_SPAWN", nWeapon);
|
|
aplWeaponSpawn[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
Bsprintf(aszBuf, "WEAPON%d_SHOTSPERBURST", nWeapon);
|
|
aplWeaponShotsPerBurst[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
Bsprintf(aszBuf, "WEAPON%d_WORKSLIKE", nWeapon);
|
|
aplWeaponWorksLike[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
Bsprintf(aszBuf, "WEAPON%d_INITIALSOUND", nWeapon);
|
|
aplWeaponInitialSound[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
Bsprintf(aszBuf, "WEAPON%d_FIRESOUND", nWeapon);
|
|
aplWeaponFireSound[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
Bsprintf(aszBuf, "WEAPON%d_SOUND2TIME", nWeapon);
|
|
aplWeaponSound2Time[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
Bsprintf(aszBuf, "WEAPON%d_SOUND2SOUND", nWeapon);
|
|
aplWeaponSound2Sound[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
Bsprintf(aszBuf, "WEAPON%d_RELOADSOUND1", nWeapon);
|
|
aplWeaponReloadSound1[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
Bsprintf(aszBuf, "WEAPON%d_RELOADSOUND2", nWeapon);
|
|
aplWeaponReloadSound2[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
Bsprintf(aszBuf, "WEAPON%d_SELECTSOUND", nWeapon);
|
|
aplWeaponSelectSound[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
Bsprintf(aszBuf, "WEAPON%d_FLASHCOLOR", nWeapon);
|
|
aplWeaponFlashColor[nWeapon][nPlayer] = Gv_GetVarByLabel(aszBuf, 0, -1, nPlayer);
|
|
}
|
|
}
|
|
|
|
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_iStructVarIDs = Gv_GetVarIndex("sprite");
|
|
#endif
|
|
|
|
for (int nWeapon = 0; nWeapon <= MAXTILES - 1; nWeapon++)
|
|
if (g_tile[nWeapon].defproj)
|
|
*g_tile[nWeapon].proj = *g_tile[nWeapon].defproj;
|
|
|
|
//AddLog("EOF:ResetWeaponDefaults");
|
|
}
|
|
|
|
// Will set members that were overridden at CON translation time to 1.
|
|
// For example, if
|
|
// gamevar WEAPON1_SHOOTS 2200 GAMEVAR_PERPLAYER
|
|
// was specified at file scope, g_weaponOverridden[1].Shoots will be 1.
|
|
weapondata_t g_weaponOverridden[MAX_WEAPONS];
|
|
|
|
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__STATIC, INSERT_CLIP__STATIC, 0, 0
|
|
},
|
|
|
|
{
|
|
PISTOL_WEAPON, /*NAM_WW2GI?20:*/12, /*NAM_WW2GI?50:*/27, 2, 5, 0,
|
|
/*(NAM_WW2GI?WEAPON_HOLSTER_CLEARS_CLIP:0) |*/ WEAPON_RELOAD_TIMING,
|
|
SHOTSPARK1__STATIC, 2, SHELL__STATIC, 0, 0, PISTOL_FIRE__STATIC, 0, 0,
|
|
EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, INSERT_CLIP__STATIC, 255+(95<<8)
|
|
},
|
|
|
|
{
|
|
SHOTGUN_WEAPON, 0, 13, 4, 30, 0,
|
|
WEAPON_CHECKATRELOAD,
|
|
SHOTGUN__STATIC, 24, SHOTGUNSHELL__STATIC, 7, 0, SHOTGUN_FIRE__STATIC, 15, SHOTGUN_COCK__STATIC,
|
|
EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, SHOTGUN_COCK__STATIC, 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__STATIC, 0, 0,
|
|
EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, SELECT_WEAPON__STATIC, 255+(95<<8)
|
|
},
|
|
|
|
{
|
|
RPG_WEAPON, 0, 0, 4, 20, 0,
|
|
0,
|
|
RPG__STATIC, 0, 0, 0, 0, 0, 0, 0,
|
|
EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, SELECT_WEAPON__STATIC, 255+(95<<8)
|
|
},
|
|
|
|
{
|
|
HANDBOMB_WEAPON, 0, 30, 6, 19, 12,
|
|
WEAPON_THROWIT,
|
|
HEAVYHBOMB__STATIC, 0, 0, 0, 0, 0, 0,
|
|
0, EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, 0, 0
|
|
},
|
|
|
|
{
|
|
SHRINKER_WEAPON, 0, 0, 10, /*NAM_WW2GI?30:*/12, 0,
|
|
WEAPON_GLOWS,
|
|
SHRINKER__STATIC, 0, 0, 0, SHRINKER_FIRE__STATIC, 0, 0, 0,
|
|
EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, SELECT_WEAPON__STATIC, 176+(252<<8)+(120<<16)
|
|
},
|
|
|
|
{
|
|
DEVISTATOR_WEAPON, 0, 0, 3, 6, 5,
|
|
WEAPON_FIREEVERYOTHER | WEAPON_AMMOPERSHOT,
|
|
RPG__STATIC, 0, 0, 2, CAT_FIRE__STATIC, 0, 0, 0,
|
|
EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, SELECT_WEAPON__STATIC, 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__STATIC, INSERT_CLIP__STATIC, 0, 0
|
|
},
|
|
|
|
{
|
|
FREEZE_WEAPON, 0, 0, 3, 5, 0,
|
|
WEAPON_RESET,
|
|
FREEZEBLAST__STATIC, 0, 0, 0, CAT_FIRE__STATIC, CAT_FIRE__STATIC, 0, 0,
|
|
EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, SELECT_WEAPON__STATIC, 72+(88<<8)+(140<<16)
|
|
},
|
|
|
|
{
|
|
HANDREMOTE_WEAPON, 0, 10, 2, 10, 0,
|
|
WEAPON_BOMB_TRIGGER | WEAPON_NOVISIBLE,
|
|
0, 0, 0, 0, 0, 0, 0,
|
|
0, EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, 0, 0
|
|
},
|
|
|
|
{
|
|
GROW_WEAPON, 0, 0, 3, /*NAM_WW2GI?30:*/5, 0,
|
|
WEAPON_GLOWS,
|
|
GROWSPARK__STATIC, /*NAM_WW2GI?2:*/0, /*NAM_WW2GI?SHELL:*/0, 0, 0, /*NAM_WW2GI?0:*/EXPANDERSHOOT__STATIC, 0, 0,
|
|
EJECT_CLIP__STATIC, INSERT_CLIP__STATIC, SELECT_WEAPON__STATIC, 216+(52<<8)+(20<<16)
|
|
},
|
|
};
|
|
|
|
// KEEPINSYNC with what is contained above
|
|
// XXX: ugly
|
|
static int32_t G_StaticToDynamicTile(int32_t const 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;
|
|
}
|
|
}
|
|
|
|
static int32_t G_StaticToDynamicSound(int32_t const sound)
|
|
{
|
|
switch (sound)
|
|
{
|
|
case CAT_FIRE__STATIC: return CAT_FIRE;
|
|
case CHAINGUN_FIRE__STATIC: return CHAINGUN_FIRE;
|
|
case EJECT_CLIP__STATIC: return EJECT_CLIP;
|
|
case EXPANDERSHOOT__STATIC: return EXPANDERSHOOT;
|
|
case INSERT_CLIP__STATIC: return INSERT_CLIP;
|
|
case PISTOL_FIRE__STATIC: return PISTOL_FIRE;
|
|
case SELECT_WEAPON__STATIC: return SELECT_WEAPON;
|
|
case SHOTGUN_FIRE__STATIC: return SHOTGUN_FIRE;
|
|
case SHOTGUN_COCK__STATIC: return SHOTGUN_COCK;
|
|
case SHRINKER_FIRE__STATIC: return SHRINKER_FIRE;
|
|
default: return sound;
|
|
}
|
|
}
|
|
|
|
// Initialize WEAPONx_* gamevars. Since for Lunatic, they reside on the C side,
|
|
// they're set directly. In C-CON, a new CON variable is defined together with
|
|
// its initial value.
|
|
#ifdef LUNATIC
|
|
# define ADDWEAPONVAR(Weapidx, Membname) do { \
|
|
int32_t j; \
|
|
for (j=0; j<MAXPLAYERS; j++) \
|
|
g_playerWeapon[j][Weapidx].Membname = weapondefaults[Weapidx].Membname; \
|
|
} while (0)
|
|
#else
|
|
# define ADDWEAPONVAR(Weapidx, Membname) do { \
|
|
Bsprintf(aszBuf, "WEAPON%d_" #Membname, Weapidx); \
|
|
Bstrupr(aszBuf); \
|
|
Gv_NewVar(aszBuf, weapondefaults[Weapidx].Membname, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM); \
|
|
} while (0)
|
|
#endif
|
|
|
|
// After CON translation, get not-overridden members from weapondefaults[] back
|
|
// into the live arrays! (That is, g_playerWeapon[][] for Lunatic, WEAPONx_*
|
|
// gamevars on the CON side in C-CON.)
|
|
#ifdef LUNATIC
|
|
# define POSTADDWEAPONVAR(Weapidx, Membname) ADDWEAPONVAR(Weapidx, Membname)
|
|
#else
|
|
// NYI
|
|
# define POSTADDWEAPONVAR(Weapidx, Membname) do {} while (0)
|
|
#endif
|
|
|
|
// Finish a default weapon member after CON translation. If it was not
|
|
// overridden from CON itself (see example at g_weaponOverridden[]), we set
|
|
// both the weapondefaults[] entry (probably dead by now) and the live value.
|
|
#define FINISH_WEAPON_DEFAULT_X(What, i, Membname) do { \
|
|
if (!g_weaponOverridden[i].Membname) \
|
|
{ \
|
|
weapondefaults[i].Membname = G_StaticToDynamic##What(weapondefaults[i].Membname); \
|
|
POSTADDWEAPONVAR(i, Membname); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define FINISH_WEAPON_DEFAULT_TILE(i, Membname) FINISH_WEAPON_DEFAULT_X(Tile, i, Membname)
|
|
#define FINISH_WEAPON_DEFAULT_SOUND(i, Membname) FINISH_WEAPON_DEFAULT_X(Sound, i, Membname)
|
|
|
|
// Process the dynamic {tile,sound} mappings after CON has been translated.
|
|
// We cannot do this before, because the dynamic maps are not yet set up then.
|
|
void Gv_FinalizeWeaponDefaults(void)
|
|
{
|
|
for (int i=0; i<MAX_WEAPONS; i++)
|
|
{
|
|
FINISH_WEAPON_DEFAULT_TILE(i, Shoots);
|
|
FINISH_WEAPON_DEFAULT_TILE(i, Spawn);
|
|
|
|
FINISH_WEAPON_DEFAULT_SOUND(i, InitialSound);
|
|
FINISH_WEAPON_DEFAULT_SOUND(i, FireSound);
|
|
FINISH_WEAPON_DEFAULT_SOUND(i, ReloadSound1);
|
|
FINISH_WEAPON_DEFAULT_SOUND(i, Sound2Sound);
|
|
FINISH_WEAPON_DEFAULT_SOUND(i, ReloadSound2);
|
|
FINISH_WEAPON_DEFAULT_SOUND(i, SelectSound);
|
|
}
|
|
}
|
|
#undef FINISH_WEAPON_DEFAULT_SOUND
|
|
#undef FINISH_WEAPON_DEFAULT_TILE
|
|
#undef FINISH_WEAPON_DEFAULT_X
|
|
#undef POSTADDWEAPONVAR
|
|
|
|
#if !defined LUNATIC
|
|
static int32_t lastvisinc;
|
|
#endif
|
|
|
|
static void Gv_AddSystemVars(void)
|
|
{
|
|
// only call ONCE
|
|
#if !defined LUNATIC
|
|
char aszBuf[64];
|
|
#endif
|
|
|
|
if (NAM_WW2GI)
|
|
{
|
|
weapondefaults[PISTOL_WEAPON].Clip = 20;
|
|
weapondefaults[PISTOL_WEAPON].Reload = 50;
|
|
weapondefaults[PISTOL_WEAPON].Flags |= WEAPON_HOLSTER_CLEARS_CLIP;
|
|
|
|
weapondefaults[SHRINKER_WEAPON].TotalTime = 30;
|
|
|
|
weapondefaults[GROW_WEAPON].TotalTime = 30;
|
|
weapondefaults[GROW_WEAPON].SpawnTime = 2;
|
|
weapondefaults[GROW_WEAPON].Spawn = SHELL;
|
|
weapondefaults[GROW_WEAPON].FireSound = 0;
|
|
}
|
|
|
|
for (int i=0; i<MAX_WEAPONS; i++)
|
|
{
|
|
ADDWEAPONVAR(i, WorksLike);
|
|
ADDWEAPONVAR(i, Clip);
|
|
ADDWEAPONVAR(i, Reload);
|
|
ADDWEAPONVAR(i, FireDelay);
|
|
ADDWEAPONVAR(i, TotalTime);
|
|
ADDWEAPONVAR(i, HoldDelay);
|
|
ADDWEAPONVAR(i, Flags);
|
|
ADDWEAPONVAR(i, Shoots);
|
|
ADDWEAPONVAR(i, SpawnTime);
|
|
ADDWEAPONVAR(i, Spawn);
|
|
ADDWEAPONVAR(i, ShotsPerBurst);
|
|
ADDWEAPONVAR(i, InitialSound);
|
|
ADDWEAPONVAR(i, FireSound);
|
|
ADDWEAPONVAR(i, Sound2Time);
|
|
ADDWEAPONVAR(i, Sound2Sound);
|
|
ADDWEAPONVAR(i, ReloadSound1);
|
|
ADDWEAPONVAR(i, ReloadSound2);
|
|
ADDWEAPONVAR(i, SelectSound);
|
|
ADDWEAPONVAR(i, FlashColor);
|
|
}
|
|
#ifdef LUNATIC
|
|
for (int i=0; i<MAXPLAYERS; i++)
|
|
{
|
|
DukePlayer_t *ps = g_player[i].ps;
|
|
|
|
ps->pipebombControl = NAM_WW2GI ? PIPEBOMB_TIMER : PIPEBOMB_REMOTE;
|
|
ps->pipebombLifetime = NAM_GRENADE_LIFETIME;
|
|
ps->pipebombLifetimeVar = NAM_GRENADE_LIFETIME_VAR;
|
|
|
|
ps->tripbombControl = TRIPBOMB_TRIPWIRE;
|
|
ps->tripbombLifetime = NAM_GRENADE_LIFETIME;
|
|
ps->tripbombLifetimeVar = NAM_GRENADE_LIFETIME_VAR;
|
|
}
|
|
#else
|
|
Gv_NewVar("GRENADE_LIFETIME", NAM_GRENADE_LIFETIME, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM);
|
|
Gv_NewVar("GRENADE_LIFETIME_VAR", NAM_GRENADE_LIFETIME_VAR, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM);
|
|
|
|
Gv_NewVar("STICKYBOMB_LIFETIME", NAM_GRENADE_LIFETIME, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM);
|
|
Gv_NewVar("STICKYBOMB_LIFETIME_VAR", NAM_GRENADE_LIFETIME_VAR, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM);
|
|
|
|
Gv_NewVar("TRIPBOMB_CONTROL", TRIPBOMB_TRIPWIRE, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM);
|
|
Gv_NewVar("PIPEBOMB_CONTROL", NAM_WW2GI ? PIPEBOMB_TIMER : PIPEBOMB_REMOTE, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM);
|
|
|
|
Gv_NewVar("RESPAWN_MONSTERS", (intptr_t)&ud.respawn_monsters,GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("RESPAWN_ITEMS",(intptr_t)&ud.respawn_items, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("RESPAWN_INVENTORY",(intptr_t)&ud.respawn_inventory, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("MONSTERS_OFF",(intptr_t)&ud.monsters_off, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("MARKER",(intptr_t)&ud.marker, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("FFIRE",(intptr_t)&ud.ffire, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("LEVEL",(intptr_t)&ud.level_number, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
|
|
Gv_NewVar("VOLUME",(intptr_t)&ud.volume_number, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
|
|
|
|
Gv_NewVar("COOP",(intptr_t)&ud.coop, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("MULTIMODE",(intptr_t)&ud.multimode, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
|
|
Gv_NewVar("WEAPON", 0, GAMEVAR_PERPLAYER | GAMEVAR_READONLY | GAMEVAR_SYSTEM);
|
|
Gv_NewVar("WORKSLIKE", 0, GAMEVAR_PERPLAYER | GAMEVAR_READONLY | GAMEVAR_SYSTEM);
|
|
Gv_NewVar("RETURN", 0, GAMEVAR_SYSTEM);
|
|
Gv_NewVar("ZRANGE", 4, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM);
|
|
Gv_NewVar("ANGRANGE", 18, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM);
|
|
Gv_NewVar("AUTOAIMANGLE", 0, GAMEVAR_PERPLAYER | GAMEVAR_SYSTEM);
|
|
Gv_NewVar("LOTAG", 0, GAMEVAR_SYSTEM);
|
|
Gv_NewVar("HITAG", 0, GAMEVAR_SYSTEM);
|
|
Gv_NewVar("TEXTURE", 0, GAMEVAR_SYSTEM);
|
|
Gv_NewVar("THISACTOR", 0, GAMEVAR_READONLY | GAMEVAR_SYSTEM);
|
|
|
|
// special vars for struct access
|
|
// KEEPINSYNC gamedef.h: enum QuickStructureAccess_t
|
|
Gv_NewVar("sprite", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
|
|
Gv_NewVar("sector", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
|
|
Gv_NewVar("wall", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
|
|
Gv_NewVar("player", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
|
|
Gv_NewVar("actorvar", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
|
|
Gv_NewVar("playervar", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
|
|
Gv_NewVar("tspr", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
|
|
Gv_NewVar("projectile", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
|
|
Gv_NewVar("thisprojectile", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
|
|
Gv_NewVar("userdef", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
|
|
Gv_NewVar("input", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
|
|
Gv_NewVar("tiledata", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
|
|
Gv_NewVar("paldata", -1, GAMEVAR_READONLY | GAMEVAR_SYSTEM | GAMEVAR_SPECIAL);
|
|
|
|
Gv_NewVar("myconnectindex", (intptr_t)&myconnectindex, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
|
|
Gv_NewVar("screenpeek", (intptr_t)&screenpeek, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
|
|
Gv_NewVar("currentweapon",(intptr_t)&hudweap.cur, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
|
|
Gv_NewVar("gs",(intptr_t)&hudweap.shade, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
|
|
Gv_NewVar("looking_arc",(intptr_t)&hudweap.lookhoriz, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
|
|
Gv_NewVar("gun_pos",(intptr_t)&hudweap.gunposy, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
|
|
Gv_NewVar("weapon_xoffset",(intptr_t)&hudweap.gunposx, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
|
|
Gv_NewVar("weaponcount",(intptr_t)&hudweap.count, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
|
|
Gv_NewVar("looking_angSR1",(intptr_t)&hudweap.lookhalfang, GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
|
|
Gv_NewVar("xdim",(intptr_t)&xdim, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
|
|
Gv_NewVar("ydim",(intptr_t)&ydim, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
|
|
Gv_NewVar("windowx1",(intptr_t)&windowxy1.x, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
|
|
Gv_NewVar("windowx2",(intptr_t)&windowxy2.x, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
|
|
Gv_NewVar("windowy1",(intptr_t)&windowxy1.y, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
|
|
Gv_NewVar("windowy2",(intptr_t)&windowxy2.y, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
|
|
Gv_NewVar("totalclock",(intptr_t)&totalclock, GAMEVAR_INTPTR | GAMEVAR_SYSTEM | GAMEVAR_READONLY);
|
|
Gv_NewVar("lastvisinc",(intptr_t)&lastvisinc, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("numsectors",(intptr_t)&numsectors, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR | GAMEVAR_READONLY);
|
|
|
|
Gv_NewVar("current_menu",(intptr_t)&g_currentMenu, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
|
|
Gv_NewVar("numplayers",(intptr_t)&numplayers, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
|
|
Gv_NewVar("viewingrange",(intptr_t)&viewingrange, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
|
|
Gv_NewVar("yxaspect",(intptr_t)&yxaspect, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
|
|
Gv_NewVar("gravitationalconstant",(intptr_t)&g_spriteGravity, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("gametype_flags",(intptr_t)&GametypeFlags[ud.coop], GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("framerate",(intptr_t)&g_currentFrameRate, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
|
|
Gv_NewVar("CLIPMASK0", CLIPMASK0, GAMEVAR_SYSTEM|GAMEVAR_READONLY);
|
|
Gv_NewVar("CLIPMASK1", CLIPMASK1, GAMEVAR_SYSTEM|GAMEVAR_READONLY);
|
|
|
|
Gv_NewVar("camerax",(intptr_t)&ud.camerapos.x, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("cameray",(intptr_t)&ud.camerapos.y, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("cameraz",(intptr_t)&ud.camerapos.z, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("cameraang",(intptr_t)&ud.cameraang, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
|
|
Gv_NewVar("camerahoriz",(intptr_t)&ud.camerahoriz, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
|
|
Gv_NewVar("camerasect",(intptr_t)&ud.camerasect, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
|
|
Gv_NewVar("cameradist",(intptr_t)&g_cameraDistance, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("cameraclock",(intptr_t)&g_cameraClock, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
|
|
Gv_NewVar("myx",(intptr_t)&my.x, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("myy",(intptr_t)&my.y, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("myz",(intptr_t)&my.z, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("omyx",(intptr_t)&omy.x, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("omyy",(intptr_t)&omy.y, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("omyz",(intptr_t)&omy.z, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("myvelx",(intptr_t)&myvel.x, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("myvely",(intptr_t)&myvel.y, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
Gv_NewVar("myvelz",(intptr_t)&myvel.z, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
|
|
Gv_NewVar("myhoriz",(intptr_t)&myhoriz, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
|
|
Gv_NewVar("myhorizoff",(intptr_t)&myhorizoff, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
|
|
Gv_NewVar("omyhoriz",(intptr_t)&omyhoriz, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
|
|
Gv_NewVar("omyhorizoff",(intptr_t)&omyhorizoff, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
|
|
Gv_NewVar("myang",(intptr_t)&myang, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
|
|
Gv_NewVar("omyang",(intptr_t)&omyang, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
|
|
Gv_NewVar("mycursectnum",(intptr_t)&mycursectnum, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
|
|
Gv_NewVar("myjumpingcounter",(intptr_t)&myjumpingcounter, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR);
|
|
|
|
Gv_NewVar("myjumpingtoggle",(intptr_t)&myjumpingtoggle, GAMEVAR_SYSTEM | GAMEVAR_CHARPTR);
|
|
Gv_NewVar("myonground",(intptr_t)&myonground, GAMEVAR_SYSTEM | GAMEVAR_CHARPTR);
|
|
Gv_NewVar("myhardlanding",(intptr_t)&myhardlanding, GAMEVAR_SYSTEM | GAMEVAR_CHARPTR);
|
|
Gv_NewVar("myreturntocenter",(intptr_t)&myreturntocenter, GAMEVAR_SYSTEM | GAMEVAR_CHARPTR);
|
|
|
|
Gv_NewVar("display_mirror",(intptr_t)&display_mirror, GAMEVAR_SYSTEM | GAMEVAR_CHARPTR);
|
|
Gv_NewVar("randomseed",(intptr_t)&randomseed, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
|
|
Gv_NewVar("NUMWALLS",(intptr_t)&numwalls, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR | GAMEVAR_READONLY);
|
|
Gv_NewVar("NUMSECTORS",(intptr_t)&numsectors, GAMEVAR_SYSTEM | GAMEVAR_SHORTPTR | GAMEVAR_READONLY);
|
|
Gv_NewVar("Numsprites",(intptr_t)&Numsprites, GAMEVAR_SYSTEM | GAMEVAR_INTPTR | GAMEVAR_READONLY);
|
|
|
|
Gv_NewVar("lastsavepos",(intptr_t)&g_lastSaveSlot, GAMEVAR_SYSTEM | GAMEVAR_INTPTR);
|
|
# ifdef USE_OPENGL
|
|
Gv_NewVar("rendmode",(intptr_t)&rendmode, GAMEVAR_READONLY | GAMEVAR_INTPTR | GAMEVAR_SYSTEM);
|
|
# else
|
|
Gv_NewVar("rendmode", 0, GAMEVAR_READONLY | GAMEVAR_SYSTEM);
|
|
# endif
|
|
|
|
// SYSTEM_GAMEARRAY
|
|
Gv_NewArray("tilesizx", (void *)&tilesiz[0].x, MAXTILES, GAMEARRAY_STRIDE2|GAMEARRAY_READONLY|GAMEARRAY_OFINT);
|
|
Gv_NewArray("tilesizy", (void *)&tilesiz[0].y, MAXTILES, GAMEARRAY_STRIDE2|GAMEARRAY_READONLY|GAMEARRAY_OFINT);
|
|
#endif
|
|
}
|
|
|
|
#undef ADDWEAPONVAR
|
|
|
|
void Gv_Init(void)
|
|
{
|
|
#if !defined LUNATIC
|
|
// already initialized
|
|
if (aGameVars[0].nFlags)
|
|
return;
|
|
|
|
Gv_Clear();
|
|
#else
|
|
static int32_t inited=0;
|
|
if (inited)
|
|
return;
|
|
inited = 1;
|
|
#endif
|
|
|
|
// Set up weapon defaults, g_playerWeapon[][].
|
|
Gv_AddSystemVars();
|
|
#if !defined LUNATIC
|
|
Gv_InitWeaponPointers();
|
|
#endif
|
|
Gv_ResetSystemDefaults();
|
|
}
|
|
|
|
#if !defined LUNATIC
|
|
void Gv_InitWeaponPointers(void)
|
|
{
|
|
char aszBuf[64];
|
|
// called from game Init AND when level is loaded...
|
|
|
|
//AddLog("Gv_InitWeaponPointers");
|
|
|
|
for (int i=(MAX_WEAPONS-1); i>=0; i--)
|
|
{
|
|
Bsprintf(aszBuf,"WEAPON%d_CLIP",i);
|
|
aplWeaponClip[i]=Gv_GetVarDataPtr(aszBuf);
|
|
if (!aplWeaponClip[i])
|
|
{
|
|
initprintf("ERROR: NULL weapon! WTF?!\n");
|
|
// Bexit(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);
|
|
}
|
|
}
|
|
|
|
void Gv_RefreshPointers(void)
|
|
{
|
|
aGameVars[Gv_GetVarIndex("RESPAWN_MONSTERS")].nValue = (intptr_t)&ud.respawn_monsters;
|
|
aGameVars[Gv_GetVarIndex("RESPAWN_ITEMS")].nValue = (intptr_t)&ud.respawn_items;
|
|
aGameVars[Gv_GetVarIndex("RESPAWN_INVENTORY")].nValue = (intptr_t)&ud.respawn_inventory;
|
|
aGameVars[Gv_GetVarIndex("MONSTERS_OFF")].nValue = (intptr_t)&ud.monsters_off;
|
|
aGameVars[Gv_GetVarIndex("MARKER")].nValue = (intptr_t)&ud.marker;
|
|
aGameVars[Gv_GetVarIndex("FFIRE")].nValue = (intptr_t)&ud.ffire;
|
|
aGameVars[Gv_GetVarIndex("LEVEL")].nValue = (intptr_t)&ud.level_number;
|
|
aGameVars[Gv_GetVarIndex("VOLUME")].nValue = (intptr_t)&ud.volume_number;
|
|
|
|
aGameVars[Gv_GetVarIndex("COOP")].nValue = (intptr_t)&ud.coop;
|
|
aGameVars[Gv_GetVarIndex("MULTIMODE")].nValue = (intptr_t)&ud.multimode;
|
|
|
|
aGameVars[Gv_GetVarIndex("myconnectindex")].nValue = (intptr_t)&myconnectindex;
|
|
aGameVars[Gv_GetVarIndex("screenpeek")].nValue = (intptr_t)&screenpeek;
|
|
aGameVars[Gv_GetVarIndex("currentweapon")].nValue = (intptr_t)&hudweap.cur;
|
|
aGameVars[Gv_GetVarIndex("gs")].nValue = (intptr_t)&hudweap.shade;
|
|
aGameVars[Gv_GetVarIndex("looking_arc")].nValue = (intptr_t)&hudweap.lookhoriz;
|
|
aGameVars[Gv_GetVarIndex("gun_pos")].nValue = (intptr_t)&hudweap.gunposy;
|
|
aGameVars[Gv_GetVarIndex("weapon_xoffset")].nValue = (intptr_t)&hudweap.gunposx;
|
|
aGameVars[Gv_GetVarIndex("weaponcount")].nValue = (intptr_t)&hudweap.count;
|
|
aGameVars[Gv_GetVarIndex("looking_angSR1")].nValue = (intptr_t)&hudweap.lookhalfang;
|
|
aGameVars[Gv_GetVarIndex("xdim")].nValue = (intptr_t)&xdim;
|
|
aGameVars[Gv_GetVarIndex("ydim")].nValue = (intptr_t)&ydim;
|
|
aGameVars[Gv_GetVarIndex("windowx1")].nValue = (intptr_t)&windowxy1.x;
|
|
aGameVars[Gv_GetVarIndex("windowx2")].nValue = (intptr_t)&windowxy2.x;
|
|
aGameVars[Gv_GetVarIndex("windowy1")].nValue = (intptr_t)&windowxy1.y;
|
|
aGameVars[Gv_GetVarIndex("windowy2")].nValue = (intptr_t)&windowxy2.y;
|
|
aGameVars[Gv_GetVarIndex("totalclock")].nValue = (intptr_t)&totalclock;
|
|
aGameVars[Gv_GetVarIndex("lastvisinc")].nValue = (intptr_t)&lastvisinc;
|
|
aGameVars[Gv_GetVarIndex("numsectors")].nValue = (intptr_t)&numsectors;
|
|
aGameVars[Gv_GetVarIndex("numplayers")].nValue = (intptr_t)&numplayers;
|
|
aGameVars[Gv_GetVarIndex("current_menu")].nValue = (intptr_t)&g_currentMenu;
|
|
aGameVars[Gv_GetVarIndex("viewingrange")].nValue = (intptr_t)&viewingrange;
|
|
aGameVars[Gv_GetVarIndex("yxaspect")].nValue = (intptr_t)&yxaspect;
|
|
aGameVars[Gv_GetVarIndex("gravitationalconstant")].nValue = (intptr_t)&g_spriteGravity;
|
|
aGameVars[Gv_GetVarIndex("gametype_flags")].nValue = (intptr_t)&GametypeFlags[ud.coop];
|
|
aGameVars[Gv_GetVarIndex("framerate")].nValue = (intptr_t)&g_currentFrameRate;
|
|
|
|
aGameVars[Gv_GetVarIndex("camerax")].nValue = (intptr_t)&ud.camerapos.x;
|
|
aGameVars[Gv_GetVarIndex("cameray")].nValue = (intptr_t)&ud.camerapos.y;
|
|
aGameVars[Gv_GetVarIndex("cameraz")].nValue = (intptr_t)&ud.camerapos.z;
|
|
aGameVars[Gv_GetVarIndex("cameraang")].nValue = (intptr_t)&ud.cameraang;
|
|
aGameVars[Gv_GetVarIndex("camerahoriz")].nValue = (intptr_t)&ud.camerahoriz;
|
|
aGameVars[Gv_GetVarIndex("camerasect")].nValue = (intptr_t)&ud.camerasect;
|
|
aGameVars[Gv_GetVarIndex("cameradist")].nValue = (intptr_t)&g_cameraDistance;
|
|
aGameVars[Gv_GetVarIndex("cameraclock")].nValue = (intptr_t)&g_cameraClock;
|
|
|
|
aGameVars[Gv_GetVarIndex("myx")].nValue = (intptr_t)&my.x;
|
|
aGameVars[Gv_GetVarIndex("myy")].nValue = (intptr_t)&my.y;
|
|
aGameVars[Gv_GetVarIndex("myz")].nValue = (intptr_t)&my.z;
|
|
aGameVars[Gv_GetVarIndex("omyx")].nValue = (intptr_t)&omy.x;
|
|
aGameVars[Gv_GetVarIndex("omyy")].nValue = (intptr_t)&omy.y;
|
|
aGameVars[Gv_GetVarIndex("omyz")].nValue = (intptr_t)&omy.z;
|
|
aGameVars[Gv_GetVarIndex("myvelx")].nValue = (intptr_t)&myvel.x;
|
|
aGameVars[Gv_GetVarIndex("myvely")].nValue = (intptr_t)&myvel.y;
|
|
aGameVars[Gv_GetVarIndex("myvelz")].nValue = (intptr_t)&myvel.z;
|
|
|
|
aGameVars[Gv_GetVarIndex("myhoriz")].nValue = (intptr_t)&myhoriz;
|
|
aGameVars[Gv_GetVarIndex("myhorizoff")].nValue = (intptr_t)&myhorizoff;
|
|
aGameVars[Gv_GetVarIndex("omyhoriz")].nValue = (intptr_t)&omyhoriz;
|
|
aGameVars[Gv_GetVarIndex("omyhorizoff")].nValue = (intptr_t)&omyhorizoff;
|
|
aGameVars[Gv_GetVarIndex("myang")].nValue = (intptr_t)&myang;
|
|
aGameVars[Gv_GetVarIndex("omyang")].nValue = (intptr_t)&omyang;
|
|
aGameVars[Gv_GetVarIndex("mycursectnum")].nValue = (intptr_t)&mycursectnum;
|
|
aGameVars[Gv_GetVarIndex("myjumpingcounter")].nValue = (intptr_t)&myjumpingcounter;
|
|
|
|
aGameVars[Gv_GetVarIndex("myjumpingtoggle")].nValue = (intptr_t)&myjumpingtoggle;
|
|
aGameVars[Gv_GetVarIndex("myonground")].nValue = (intptr_t)&myonground;
|
|
aGameVars[Gv_GetVarIndex("myhardlanding")].nValue = (intptr_t)&myhardlanding;
|
|
aGameVars[Gv_GetVarIndex("myreturntocenter")].nValue = (intptr_t)&myreturntocenter;
|
|
|
|
aGameVars[Gv_GetVarIndex("display_mirror")].nValue = (intptr_t)&display_mirror;
|
|
aGameVars[Gv_GetVarIndex("randomseed")].nValue = (intptr_t)&randomseed;
|
|
|
|
aGameVars[Gv_GetVarIndex("NUMWALLS")].nValue = (intptr_t)&numwalls;
|
|
aGameVars[Gv_GetVarIndex("NUMSECTORS")].nValue = (intptr_t)&numsectors;
|
|
aGameVars[Gv_GetVarIndex("Numsprites")].nValue = (intptr_t)&Numsprites;
|
|
|
|
aGameVars[Gv_GetVarIndex("lastsavepos")].nValue = (intptr_t)&g_lastSaveSlot;
|
|
# ifdef USE_OPENGL
|
|
aGameVars[Gv_GetVarIndex("rendmode")].nValue = (intptr_t)&rendmode;
|
|
# endif
|
|
}
|
|
#endif
|