M32Script cleanup. Fixes at least one non-minor and one minor bug.

git-svn-id: https://svn.eduke32.com/eduke32@4798 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2014-12-06 19:09:50 +00:00
parent 5e574436e2
commit 74d99fe2e1
4 changed files with 148 additions and 125 deletions

View file

@ -46,7 +46,7 @@ extern void VM_ScriptInfo(void);
extern void VM_Disasm(ofstype beg, int32_t size); extern void VM_Disasm(ofstype beg, int32_t size);
extern int32_t Gv_NewVar(const char *pszLabel, intptr_t lValue, uint32_t dwFlags); extern int32_t Gv_NewVar(const char *pszLabel, intptr_t lValue, uint32_t dwFlags);
extern int32_t Gv_NewArray(const char *pszLabel, void *arrayptr, intptr_t asize, uint32_t dwFlags); extern int32_t Gv_NewArray(const char *pszLabel, void *arrayptr, int32_t asize, uint32_t dwFlags);
extern void Gv_Init(void); extern void Gv_Init(void);
extern int32_t __fastcall Gv_GetVarX(register int32_t id); extern int32_t __fastcall Gv_GetVarX(register int32_t id);
@ -124,7 +124,7 @@ enum GamevarFlags_t {
}; };
enum GamearrayFlags_t { enum GamearrayFlags_t {
MAXGAMEARRAYS = (MAXGAMEVARS>>2), // must be lower than MAXGAMEVARS MAXGAMEARRAYS = (MAXGAMEVARS>>2), // must be strictly smaller than MAXGAMEVARS
MAXARRAYLABEL = MAXVARLABEL, MAXARRAYLABEL = MAXVARLABEL,
GAMEARRAY_READONLY = 0x00001000, GAMEARRAY_READONLY = 0x00001000,
@ -136,9 +136,9 @@ enum GamearrayFlags_t {
GAMEARRAY_OFINT = 0x00000004, GAMEARRAY_OFINT = 0x00000004,
GAMEARRAY_TYPE_MASK = GAMEARRAY_OFCHAR|GAMEARRAY_OFSHORT|GAMEARRAY_OFINT, GAMEARRAY_TYPE_MASK = GAMEARRAY_OFCHAR|GAMEARRAY_OFSHORT|GAMEARRAY_OFINT,
GAMEARRAY_VARSIZE = 0x00000020,
GAMEARRAY_RESET = 0x00000008, GAMEARRAY_RESET = 0x00000008,
GAMEARRAY_VARSIZE = 0x00000020,
}; };
typedef struct { typedef struct {
@ -235,17 +235,21 @@ extern int32_t mousyplc;
// uncomment if variable-length arrays are available // uncomment if variable-length arrays are available
//#define M32_LOCALS_VARARRAY //#define M32_LOCALS_VARARRAY
// uncomment if alloca() is available
//#define M32_LOCALS_ALLOCA
// if neither is there, use a constant number of them // if neither is there, use a constant number of them
#define M32_LOCALS_FIXEDNUM 64 #define M32_LOCALS_FIXEDNUM 64
#if defined M32_LOCALS_VARARRAY || defined M32_LOCALS_ALLOCA #if defined M32_LOCALS_VARARRAY
# define M32_MAX_LOCALS MAXGAMEVARS # define M32_MAX_LOCALS MAXGAMEVARS
#else #else
# define M32_MAX_LOCALS M32_LOCALS_FIXEDNUM # define M32_MAX_LOCALS M32_LOCALS_FIXEDNUM
#endif #endif
static inline int32_t Gv_GetArraySize(int32_t id)
{
if (aGameArrays[id].dwFlags & GAMEARRAY_VARSIZE)
return Gv_GetVarN(aGameArrays[id].size);
return aGameArrays[id].size;
}
#endif #endif

View file

@ -1128,7 +1128,7 @@ static void C_GetNextVarType(int32_t type)
{ {
if (!m32_script_expertmode && (type&GV_WRITABLE)) if (!m32_script_expertmode && (type&GV_WRITABLE))
{ {
int32_t flags = aGameArrays[id].dwFlags; const int32_t flags = aGameArrays[id].dwFlags;
if (flags & GAMEARRAY_READONLY) if (flags & GAMEARRAY_READONLY)
{ {
@ -1978,11 +1978,8 @@ static int32_t C_ParseCommand(void)
} }
if (aGameArrays[i].dwFlags & GAMEARRAY_TYPE_MASK) if (aGameArrays[i].dwFlags & GAMEARRAY_TYPE_MASK)
{
C_CUSTOMERROR("Array for %s must be user-defined.", C_CUSTOMERROR("Array for %s must be user-defined.",
tw==CON_SORT?"sorting":"collecting sectors"); tw==CON_SORT?"sorting":"collecting sectors");
g_numCompilerErrors++;
}
} }
else else
{ {
@ -2543,7 +2540,8 @@ repeatcase:
C_GetNextValue(LABEL_DEFINE); C_GetNextValue(LABEL_DEFINE);
{ {
int32_t asize = *(g_scriptPtr-1); const int32_t asize = *(g_scriptPtr-1);
if (cs.currentStateIdx < 0 && cs.currentEvent < 0) if (cs.currentStateIdx < 0 && cs.currentEvent < 0)
Gv_NewArray(tlabel, NULL, asize, GAMEARRAY_NORMAL); Gv_NewArray(tlabel, NULL, asize, GAMEARRAY_NORMAL);
else // local array else // local array

View file

@ -138,13 +138,11 @@ void VM_OnEvent(register int32_t iEventID, register int32_t iActor)
} }
{ {
instype *oinsptr=insptr; instype *const oinsptr=insptr;
vmstate_t vm_backup; vmstate_t vm_backup;
void *olocalvars = aGameArrays[M32_LOCAL_ARRAY_ID].vals; void *const olocalvars = aGameArrays[M32_LOCAL_ARRAY_ID].vals;
#ifdef M32_LOCALS_VARARRAY #ifdef M32_LOCALS_VARARRAY
int32_t localvars[aEventNumLocals[iEventID]]; int32_t localvars[aEventNumLocals[iEventID]];
#elif defined M32_LOCALS_ALLOCA
int32_t *localvars = alloca(aEventNumLocals[iEventID] * sizeof(int32_t));
#else #else
int32_t localvars[M32_LOCALS_FIXEDNUM]; int32_t localvars[M32_LOCALS_FIXEDNUM];
#endif #endif
@ -300,6 +298,14 @@ static char *GetMaybeInlineQuote(int32_t quotei)
return quotetext; return quotetext;
} }
static int CheckArray(int aidx)
{
if (!(aidx >= 0 && aidx < g_gameArrayCount))
M32_ERROR("Invalid array %d!", aidx);
return (vm.flags&VMFLAG_ERROR);
}
int32_t VM_Execute(int32_t once) int32_t VM_Execute(int32_t once)
{ {
register int32_t tw = *insptr; register int32_t tw = *insptr;
@ -330,13 +336,11 @@ skip_check:
case CON_STATE: case CON_STATE:
{ {
instype *tempscrptr = insptr+2; instype *const tempscrptr = insptr+2;
int32_t stateidx = *(insptr+1), o_g_st = vm.g_st, oret=vm.flags&VMFLAG_RETURN; const int32_t stateidx = *(insptr+1), o_g_st = vm.g_st, oret=vm.flags&VMFLAG_RETURN;
void *olocalvars = aGameArrays[M32_LOCAL_ARRAY_ID].vals; void *const olocalvars = aGameArrays[M32_LOCAL_ARRAY_ID].vals;
#ifdef M32_LOCALS_VARARRAY #ifdef M32_LOCALS_VARARRAY
int32_t localvars[statesinfo[stateidx].numlocals]; int32_t localvars[statesinfo[stateidx].numlocals];
#elif defined M32_LOCALS_ALLOCA
int32_t *localvars = alloca(statesinfo[stateidx].numlocals * sizeof(int32_t));
#else #else
int32_t localvars[M32_LOCALS_FIXEDNUM]; int32_t localvars[M32_LOCALS_FIXEDNUM];
#endif #endif
@ -475,47 +479,54 @@ skip_check:
case CON_SETARRAY: case CON_SETARRAY:
insptr++; insptr++;
{ {
int32_t j=*insptr++; const int32_t j=*insptr++;
int32_t index = Gv_GetVarX(*insptr++); const int32_t index = Gv_GetVarX(*insptr++);
int32_t value = Gv_GetVarX(*insptr++); const int32_t value = Gv_GetVarX(*insptr++);
CheckArray(j);
if (j<0 || j >= g_gameArrayCount)
{
M32_ERROR("Tried to set invalid array ID (%d)", j);
}
if (aGameArrays[j].dwFlags & GAMEARRAY_READONLY) if (aGameArrays[j].dwFlags & GAMEARRAY_READONLY)
{
M32_ERROR("Tried to set on read-only array `%s'", aGameArrays[j].szLabel); M32_ERROR("Tried to set on read-only array `%s'", aGameArrays[j].szLabel);
}
if (index >= aGameArrays[j].size || index < 0) if (!(index >= 0 && index < aGameArrays[j].size))
{
M32_ERROR("Array index %d out of bounds", index); M32_ERROR("Array index %d out of bounds", index);
}
if (vm.flags&VMFLAG_ERROR) continue; if (vm.flags&VMFLAG_ERROR)
((int32_t *)aGameArrays[j].vals)[index]=value; // REM: other array types not implemented, since they're read-only continue;
// NOTE: Other array types not implemented, since they're read-only.
((int32_t *)aGameArrays[j].vals)[index] = value;
continue; continue;
} }
case CON_GETARRAYSIZE: case CON_GETARRAYSIZE:
insptr++; insptr++;
{ {
int32_t j=*insptr++; const int32_t j=*insptr++;
Gv_SetVarX(*insptr++, (aGameArrays[j].dwFlags&GAMEARRAY_VARSIZE) ?
Gv_GetVarN(aGameArrays[j].size) : aGameArrays[j].size); if (CheckArray(j))
continue;
Gv_SetVarX(*insptr++, Gv_GetArraySize(j));
} }
continue; continue;
case CON_RESIZEARRAY: case CON_RESIZEARRAY:
insptr++; insptr++;
{ {
int32_t j=*insptr++; const int32_t j=*insptr++;
int32_t asize = Gv_GetVarX(*insptr++); const int32_t asize = Gv_GetVarX(*insptr++);
if (asize<=0 || asize>65536) CheckArray(j);
{
if (aGameArrays[j].dwFlags & GAMEARRAY_READONLY)
M32_ERROR("Tried to resize read-only array `%s'", aGameArrays[j].szLabel);
if (!(asize >= 1 && asize <= 65536))
M32_ERROR("Invalid array size %d (must be between 1 and 65536)", asize); M32_ERROR("Invalid array size %d (must be between 1 and 65536)", asize);
if (vm.flags&VMFLAG_ERROR)
continue; continue;
}
// OSD_Printf(OSDTEXT_GREEN "CON_RESIZEARRAY: resizing array %s from %d to %d\n", aGameArrays[j].szLabel, aGameArrays[j].size, asize); // OSD_Printf(OSDTEXT_GREEN "CON_RESIZEARRAY: resizing array %s from %d to %d\n", aGameArrays[j].szLabel, aGameArrays[j].size, asize);
aGameArrays[j].vals = Xrealloc(aGameArrays[j].vals, sizeof(int32_t) * asize); aGameArrays[j].vals = Xrealloc(aGameArrays[j].vals, sizeof(int32_t) * asize);
@ -527,34 +538,30 @@ skip_check:
case CON_COPY: case CON_COPY:
insptr++; insptr++;
{ {
int32_t si=*insptr++, ssiz; const int32_t si=*insptr++;
int32_t sidx = Gv_GetVarX(*insptr++); //, vm.g_i, vm.g_p); int32_t sidx = Gv_GetVarX(*insptr++);
int32_t di=*insptr++, dsiz; const int32_t di=*insptr++;
int32_t didx = Gv_GetVarX(*insptr++); int32_t didx = Gv_GetVarX(*insptr++);
int32_t numelts = Gv_GetVarX(*insptr++); int32_t numelts = Gv_GetVarX(*insptr++);
if (si<0 || si>=g_gameArrayCount) CheckArray(si);
{ CheckArray(di);
M32_ERROR("Invalid array %d!", si);
}
if (di<0 || di>=g_gameArrayCount)
{
M32_ERROR("Invalid array %d!", di);
}
if (aGameArrays[di].dwFlags & GAMEARRAY_READONLY) if (aGameArrays[di].dwFlags & GAMEARRAY_READONLY)
{
M32_ERROR("Array %d is read-only!", di); M32_ERROR("Array %d is read-only!", di);
}
if (vm.flags&VMFLAG_ERROR) continue;
ssiz = (aGameArrays[si].dwFlags&GAMEARRAY_VARSIZE) ? if (vm.flags&VMFLAG_ERROR)
Gv_GetVarN(aGameArrays[si].size) : aGameArrays[si].size; continue;
dsiz = (aGameArrays[di].dwFlags&GAMEARRAY_VARSIZE) ?
Gv_GetVarN(aGameArrays[si].size) : aGameArrays[di].size;
if (sidx > ssiz || didx > dsiz) continue; const int32_t ssiz = Gv_GetArraySize(si);
if ((sidx+numelts) > ssiz) numelts = ssiz-sidx; const int32_t dsiz = Gv_GetArraySize(di);
if ((didx+numelts) > dsiz) numelts = dsiz-didx;
if (sidx > ssiz || didx > dsiz)
continue;
if (numelts > ssiz-sidx)
numelts = ssiz-sidx;
if (numelts > dsiz-didx)
numelts = dsiz-didx;
switch (aGameArrays[si].dwFlags & GAMEARRAY_TYPE_MASK) switch (aGameArrays[si].dwFlags & GAMEARRAY_TYPE_MASK)
{ {
@ -1142,14 +1149,23 @@ skip_check:
case CON_COLLECTSECTORS: case CON_COLLECTSECTORS:
insptr++; insptr++;
{ {
int32_t aridx=*insptr++, startsectnum=Gv_GetVarX(*insptr++); const int32_t aridx=*insptr++, startsectnum=Gv_GetVarX(*insptr++);
int32_t numsectsVar=*insptr++, state=*insptr++; const int32_t numsectsVar=*insptr++, state=*insptr++;
int32_t o_g_st=vm.g_st, arsize = aGameArrays[aridx].size; if (CheckArray(aridx))
instype *end=insptr; continue;
gamearray_t *const gar = &aGameArrays[aridx];
Bassert((gar->dwFlags & (GAMEARRAY_READONLY|GAMEARRAY_VARSIZE)) == 0);
const int32_t o_g_st=vm.g_st, arsize = gar->size;
instype *const end=insptr;
int32_t sectcnt, numsects=0; int32_t sectcnt, numsects=0;
int16_t *sectlist = (int16_t *)aGameArrays[aridx].vals; // actually an int32_t array
int32_t *sectlist32 = (int32_t *)sectlist; // XXX: relies on -fno-strict-aliasing
int16_t *const sectlist = (int16_t *)gar->vals; // actually an int32_t array
int32_t *const sectlist32 = (int32_t *)sectlist;
int32_t j, startwall, endwall, ns; int32_t j, startwall, endwall, ns;
static uint8_t sectbitmap[MAXSECTORS>>3]; static uint8_t sectbitmap[MAXSECTORS>>3];
@ -1194,26 +1210,35 @@ skip_check:
case CON_SORT: case CON_SORT:
insptr++; insptr++;
{ {
int32_t aridx=*insptr++, count=Gv_GetVarX(*insptr++), state=*insptr++; const int32_t aridx=*insptr++, count=Gv_GetVarX(*insptr++), state=*insptr++;
int32_t o_g_st=vm.g_st; const int32_t o_g_st = vm.g_st;
instype *end=insptr; instype *const end = insptr;
if (count<=0) continue; if (CheckArray(aridx))
if (count > aGameArrays[aridx].size) continue;
if (count <= 0)
continue;
gamearray_t *const gar = &aGameArrays[aridx];
Bassert((gar->dwFlags & (GAMEARRAY_READONLY|GAMEARRAY_VARSIZE)) == 0);
if (count > gar->size)
{ {
M32_ERROR("Count of elements to sort (%d) exceeds array size (%d)!", count,aGameArrays[aridx].size); M32_ERROR("Count of elements to sort (%d) exceeds array size (%d)!",
count, gar->size);
continue; continue;
} }
if (state < 0) if (state < 0)
{ {
qsort(aGameArrays[aridx].vals, count, sizeof(int32_t), X_DoSortDefault); qsort(gar->vals, count, sizeof(int32_t), X_DoSortDefault);
} }
else else
{ {
x_sortingstateptr = script + statesinfo[state].ofs; x_sortingstateptr = script + statesinfo[state].ofs;
vm.g_st = 1+MAXEVENTS+state; vm.g_st = 1+MAXEVENTS+state;
qsort(aGameArrays[aridx].vals, count, sizeof(int32_t), X_DoSort); qsort(gar->vals, count, sizeof(int32_t), X_DoSort);
vm.g_st = o_g_st; vm.g_st = o_g_st;
insptr = end; insptr = end;
} }

View file

@ -57,18 +57,18 @@ static void Gv_Clear(void)
if (i >= MAXGAMEARRAYS) if (i >= MAXGAMEARRAYS)
continue; continue;
if (aGameArrays[i].szLabel) gamearray_t *const gar = &aGameArrays[i];
Bfree(aGameArrays[i].szLabel);
aGameArrays[i].szLabel = NULL; Bfree(gar->szLabel);
gar->szLabel = NULL;
if ((aGameArrays[i].dwFlags & GAMEARRAY_NORMAL) && aGameArrays[i].vals) if ((gar->dwFlags & GAMEARRAY_NORMAL) && gar->vals)
{ {
Bfree(aGameArrays[i].vals); Bfree(gar->vals);
aGameArrays[i].vals=NULL; gar->vals = NULL;
} }
aGameArrays[i].dwFlags |= GAMEARRAY_RESET; gar->dwFlags |= GAMEARRAY_RESET;
} }
g_gameVarCount = g_gameArrayCount = 0; g_gameVarCount = g_gameArrayCount = 0;
@ -79,9 +79,9 @@ static void Gv_Clear(void)
return; return;
} }
int32_t Gv_NewArray(const char *pszLabel, void *arrayptr, intptr_t asize, uint32_t dwFlags) int32_t Gv_NewArray(const char *pszLabel, void *arrayptr, int32_t asize, uint32_t dwFlags)
{ {
int32_t i; Bassert(!(dwFlags&GAMEARRAY_VARSIZE) || (dwFlags&GAMEARRAY_READONLY));
if (g_gameArrayCount >= MAXGAMEARRAYS) if (g_gameArrayCount >= MAXGAMEARRAYS)
{ {
@ -95,15 +95,15 @@ int32_t Gv_NewArray(const char *pszLabel, void *arrayptr, intptr_t asize, uint32
return 0; return 0;
} }
i = hash_find(&h_arrays, pszLabel); const int32_t i = hash_find(&h_arrays, pszLabel);
if (i>=0 && !(aGameArrays[i].dwFlags & GAMEARRAY_RESET)) if (i>=0 && !(aGameArrays[i].dwFlags & GAMEARRAY_RESET))
{ {
// found it it's a duplicate in error // found it it's a duplicate in error
if (aGameArrays[i].dwFlags&GAMEARRAY_TYPE_MASK) if (aGameArrays[i].dwFlags&GAMEARRAY_TYPE_MASK)
{
C_CUSTOMWARNING("ignored redefining system array `%s'.", pszLabel); C_CUSTOMWARNING("ignored redefining system array `%s'.", pszLabel);
}
// C_ReportError(WARNING_DUPLICATEDEFINITION); // C_ReportError(WARNING_DUPLICATEDEFINITION);
return 0; return 0;
} }
@ -112,27 +112,28 @@ int32_t Gv_NewArray(const char *pszLabel, void *arrayptr, intptr_t asize, uint32
{ {
// the dummy array with index 0 sets the size to 0 so that accidental accesses as array // the dummy array with index 0 sets the size to 0 so that accidental accesses as array
// will complain. // will complain.
C_CUSTOMERROR("invalid array size %d. Must be between 1 and 65536", (int32_t)asize); C_CUSTOMERROR("invalid array size %d. Must be between 1 and 65536", asize);
return 0; return 0;
} }
i = g_gameArrayCount; gamearray_t *const gar = &aGameArrays[g_gameArrayCount];
if (aGameArrays[i].szLabel == NULL) if (gar->szLabel == NULL)
aGameArrays[i].szLabel = (char *)Xcalloc(MAXARRAYLABEL, sizeof(char)); gar->szLabel = (char *)Xcalloc(MAXARRAYLABEL, sizeof(char));
if (aGameArrays[i].szLabel != pszLabel) if (gar->szLabel != pszLabel)
Bstrcpy(aGameArrays[i].szLabel, pszLabel); Bstrcpy(gar->szLabel, pszLabel);
if (!(dwFlags & GAMEARRAY_TYPE_MASK)) if (!(dwFlags & GAMEARRAY_TYPE_MASK))
aGameArrays[i].vals = (int32_t *)Xcalloc(asize, sizeof(int32_t)); gar->vals = (int32_t *)Xcalloc(asize, sizeof(int32_t));
else else
aGameArrays[i].vals = arrayptr; gar->vals = arrayptr;
aGameArrays[i].size = asize; gar->size = asize;
aGameArrays[i].dwFlags = dwFlags & ~GAMEARRAY_RESET; gar->dwFlags = dwFlags & ~GAMEARRAY_RESET;
hash_add(&h_arrays, gar->szLabel, g_gameArrayCount, 1);
g_gameArrayCount++; g_gameArrayCount++;
hash_add(&h_arrays, aGameArrays[i].szLabel, i, 1);
return 1; return 1;
} }
@ -290,7 +291,6 @@ int32_t __fastcall Gv_GetVarX(register int32_t id)
case M32_FLAG_ARRAY: case M32_FLAG_ARRAY:
{ {
register int32_t index; register int32_t index;
int32_t siz;
index = (int32_t)((id>>16)&0xffff); index = (int32_t)((id>>16)&0xffff);
if (!(id&M32_FLAG_CONSTANTINDEX)) if (!(id&M32_FLAG_CONSTANTINDEX))
@ -298,26 +298,24 @@ int32_t __fastcall Gv_GetVarX(register int32_t id)
id &= (MAXGAMEARRAYS-1); id &= (MAXGAMEARRAYS-1);
if (aGameArrays[id].dwFlags & GAMEARRAY_VARSIZE) const int32_t siz = Gv_GetArraySize(id);
siz = Gv_GetVarN(aGameArrays[id].size); const gamearray_t *const gar = &aGameArrays[id];
else
siz = aGameArrays[id].size;
if (index < 0 || index >= siz) if (index < 0 || index >= siz)
{ {
M32_ERROR("Gv_GetVarX(): invalid array index (%s[%d])", aGameArrays[id].szLabel, index); M32_ERROR("Gv_GetVarX(): invalid array index (%s[%d])", gar->szLabel, index);
return -1; return -1;
} }
switch (aGameArrays[id].dwFlags & GAMEARRAY_TYPE_MASK) switch (gar->dwFlags & GAMEARRAY_TYPE_MASK)
{ {
case 0: case 0:
case GAMEARRAY_OFINT: case GAMEARRAY_OFINT:
return (((int32_t *)aGameArrays[id].vals)[index] ^ -negateResult) + negateResult; return (((int32_t *)gar->vals)[index] ^ -negateResult) + negateResult;
case GAMEARRAY_OFSHORT: case GAMEARRAY_OFSHORT:
return (((int16_t *)aGameArrays[id].vals)[index] ^ -negateResult) + negateResult; return (((int16_t *)gar->vals)[index] ^ -negateResult) + negateResult;
case GAMEARRAY_OFCHAR: case GAMEARRAY_OFCHAR:
return (((uint8_t *)aGameArrays[id].vals)[index] ^ -negateResult) + negateResult; return (((uint8_t *)gar->vals)[index] ^ -negateResult) + negateResult;
default: default:
M32_ERROR("Gv_GetVarX() (array): WTF??"); M32_ERROR("Gv_GetVarX() (array): WTF??");
return -1; return -1;
@ -392,7 +390,6 @@ void __fastcall Gv_SetVarX(register int32_t id, register int32_t lValue)
case M32_FLAG_ARRAY: case M32_FLAG_ARRAY:
{ {
register int32_t index; register int32_t index;
int32_t siz;
index = (id>>16)&0xffff; index = (id>>16)&0xffff;
if (!(id&M32_FLAG_CONSTANTINDEX)) if (!(id&M32_FLAG_CONSTANTINDEX))
@ -400,27 +397,26 @@ void __fastcall Gv_SetVarX(register int32_t id, register int32_t lValue)
id &= (MAXGAMEARRAYS-1); id &= (MAXGAMEARRAYS-1);
if (aGameArrays[id].dwFlags & GAMEARRAY_VARSIZE) const int32_t siz = Gv_GetArraySize(id);
siz = Gv_GetVarN(aGameArrays[id].size); gamearray_t *const gar = &aGameArrays[id];
else siz = aGameArrays[id].size;
if (index < 0 || index >= siz) if (index < 0 || index >= siz)
{ {
M32_ERROR("Gv_SetVarX(): invalid array index %s[%d], size=%d", aGameArrays[id].szLabel, index, siz); M32_ERROR("Gv_SetVarX(): invalid array index %s[%d], size=%d", gar->szLabel, index, siz);
return; return;
} }
switch (aGameArrays[id].dwFlags & GAMEARRAY_TYPE_MASK) switch (gar->dwFlags & GAMEARRAY_TYPE_MASK)
{ {
case 0: case 0:
case GAMEARRAY_OFINT: case GAMEARRAY_OFINT:
((int32_t *)aGameArrays[id].vals)[index] = lValue; ((int32_t *)gar->vals)[index] = lValue;
return; return;
case GAMEARRAY_OFSHORT: case GAMEARRAY_OFSHORT:
((int16_t *)aGameArrays[id].vals)[index] = (int16_t)lValue; ((int16_t *)gar->vals)[index] = (int16_t)lValue;
return; return;
case GAMEARRAY_OFCHAR: case GAMEARRAY_OFCHAR:
((uint8_t *)aGameArrays[id].vals)[index] = (uint8_t)lValue; ((uint8_t *)gar->vals)[index] = (uint8_t)lValue;
return; return;
default: default:
M32_ERROR("Gv_SetVarX() (array): WTF??"); M32_ERROR("Gv_SetVarX() (array): WTF??");