mirror of
https://github.com/ZDoom/raze-gles.git
synced 2025-01-11 18:50:46 +00:00
Port system gamearray access from M32Script to CON. Expose tilesizx and tilesizy.
Also, fix deficient logic in Gv_Free and Gv_Clear (both M32 and CON) so that gamevar and gamearray erasure results are (closer to) correct, and so that the game does not crash when system arrays are accessed from CON because they all have been nulled. git-svn-id: https://svn.eduke32.com/eduke32@3274 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
a2f585fcfb
commit
6f2fa332dd
7 changed files with 162 additions and 42 deletions
|
@ -133,7 +133,7 @@ enum GamearrayFlags_t {
|
|||
GAMEARRAY_READONLY = 0x00001000,
|
||||
GAMEARRAY_WARN = 0x00002000,
|
||||
|
||||
GAMEARRAY_NORMAL = 0,
|
||||
GAMEARRAY_NORMAL = 0x00004000,
|
||||
GAMEARRAY_OFCHAR = 0x00000001,
|
||||
GAMEARRAY_OFSHORT = 0x00000002,
|
||||
GAMEARRAY_OFINT = 0x00000004,
|
||||
|
|
|
@ -2337,7 +2337,7 @@ static int32_t C_ParseCommand(int32_t loop)
|
|||
}
|
||||
|
||||
C_GetNextValue(LABEL_DEFINE);
|
||||
Gv_NewArray(label+(g_numLabels<<6),*(g_scriptPtr-1));
|
||||
Gv_NewArray(label+(g_numLabels<<6),NULL,*(g_scriptPtr-1), GAMEARRAY_NORMAL);
|
||||
|
||||
g_scriptPtr -= 2; // no need to save in script...
|
||||
continue;
|
||||
|
@ -3863,6 +3863,13 @@ static int32_t C_ParseCommand(int32_t loop)
|
|||
{
|
||||
bitptr[(g_scriptPtr-script)>>3] &= ~(BITPTR_POINTER<<((g_scriptPtr-script)&7));
|
||||
*g_scriptPtr++=i;
|
||||
|
||||
if (aGameArrays[i].dwFlags & GAMEARRAY_READONLY)
|
||||
{
|
||||
C_ReportError(ERROR_ARRAYREADONLY);
|
||||
g_numCompilerErrors++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3894,16 +3901,24 @@ static int32_t C_ParseCommand(int32_t loop)
|
|||
case CON_RESIZEARRAY:
|
||||
C_GetNextLabelName();
|
||||
i=GetADefID(label+(g_numLabels<<6));
|
||||
if (i < 0)
|
||||
if (i >= 0)
|
||||
{
|
||||
bitptr[(g_scriptPtr-script)>>3] &= ~(BITPTR_POINTER<<((g_scriptPtr-script)&7));
|
||||
*g_scriptPtr++ = i;
|
||||
if (tw==CON_RESIZEARRAY && (aGameArrays[i].dwFlags & GAMEARRAY_TYPE_MASK))
|
||||
{
|
||||
C_ReportError(-1);
|
||||
initprintf("can't resize system array `%s'.", label+(g_numLabels<<6));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_numCompilerErrors++;
|
||||
C_ReportError(ERROR_NOTAGAMEARRAY);
|
||||
return 1;
|
||||
}
|
||||
|
||||
bitptr[(g_scriptPtr-script)>>3] &= ~(BITPTR_POINTER<<((g_scriptPtr-script)&7));
|
||||
*g_scriptPtr++=i;
|
||||
|
||||
C_SkipComments();
|
||||
C_GetNextVarType(tw==CON_GETARRAYSIZE ? GAMEVAR_READONLY : 0);
|
||||
continue;
|
||||
|
@ -6031,10 +6046,10 @@ void C_Compile(const char *filenam)
|
|||
initprintf("Script compiled in %dms, %ld*%db, version %s\n", getticks() - startcompiletime,
|
||||
(unsigned long)(g_scriptPtr-script), (int32_t)sizeof(intptr_t), (g_scriptVersion == 14?"1.4+":"1.3D"));
|
||||
|
||||
initprintf("%d/%d labels, %d/%d variables\n", g_numLabels,
|
||||
initprintf("%d/%d labels, %d/%d variables, %d/%d arrays\n", g_numLabels,
|
||||
(int32_t)min((MAXSECTORS * sizeof(sectortype)/sizeof(int32_t)),
|
||||
MAXSPRITES * sizeof(spritetype)/(1<<6)),
|
||||
g_gameVarCount, MAXGAMEVARS);
|
||||
g_gameVarCount, MAXGAMEVARS, g_gameArrayCount, MAXGAMEARRAYS);
|
||||
|
||||
for (i=MAXQUOTES-1; i>=0; i--)
|
||||
if (ScriptQuotes[i])
|
||||
|
@ -6220,6 +6235,9 @@ void C_ReportError(int32_t iError)
|
|||
case ERROR_VARREADONLY:
|
||||
initprintf("%s:%d: error: variable `%s' is read-only.\n",g_szScriptFileName,g_lineNumber,label+(g_numLabels<<6));
|
||||
break;
|
||||
case ERROR_ARRAYREADONLY:
|
||||
initprintf("%s:%d: error: array `%s' is read-only.\n",g_szScriptFileName,g_lineNumber,label+(g_numLabels<<6));
|
||||
break;
|
||||
case ERROR_VARTYPEMISMATCH:
|
||||
initprintf("%s:%d: error: variable `%s' is of the wrong type.\n",g_szScriptFileName,g_lineNumber,label+(g_numLabels<<6));
|
||||
break;
|
||||
|
|
|
@ -155,6 +155,7 @@ enum ScriptError_t
|
|||
ERROR_SYMBOLNOTRECOGNIZED,
|
||||
ERROR_SYNTAXERROR,
|
||||
ERROR_VARREADONLY,
|
||||
ERROR_ARRAYREADONLY,
|
||||
ERROR_VARTYPEMISMATCH,
|
||||
WARNING_BADGAMEVAR,
|
||||
WARNING_DUPLICATECASE,
|
||||
|
|
|
@ -4196,6 +4196,11 @@ nullquote:
|
|||
j,vm.g_i,TrackerCast(sprite[vm.g_i].picnum),vm.g_p);
|
||||
continue;
|
||||
}
|
||||
if (aGameArrays[j].dwFlags & GAMEARRAY_READONLY)
|
||||
{
|
||||
OSD_Printf("Tried to set on read-only array `%s'", aGameArrays[j].szLabel);
|
||||
continue;
|
||||
}
|
||||
aGameArrays[j].plValues[index]=value;
|
||||
continue;
|
||||
}
|
||||
|
@ -4265,7 +4270,8 @@ nullquote:
|
|||
insptr++;
|
||||
{
|
||||
int32_t j=*insptr++;
|
||||
Gv_SetVarX(*insptr++,aGameArrays[j].size);
|
||||
Gv_SetVarX(*insptr++, (aGameArrays[j].dwFlags&GAMEARRAY_VARSIZE) ?
|
||||
Gv_GetVarX(aGameArrays[j].size) : aGameArrays[j].size);
|
||||
}
|
||||
continue;
|
||||
|
||||
|
@ -4287,16 +4293,53 @@ nullquote:
|
|||
case CON_COPY:
|
||||
insptr++;
|
||||
{
|
||||
int32_t j=*insptr++;
|
||||
int32_t index = Gv_GetVarX(*insptr++);
|
||||
int32_t j1=*insptr++;
|
||||
int32_t index1 = Gv_GetVarX(*insptr++);
|
||||
int32_t value = Gv_GetVarX(*insptr++);
|
||||
int32_t si=*insptr++, ssiz = 0;
|
||||
int32_t sidx = Gv_GetVarX(*insptr++); //, vm.g_i, vm.g_p);
|
||||
int32_t di=*insptr++, dsiz = 0;
|
||||
int32_t didx = Gv_GetVarX(*insptr++);
|
||||
int32_t numelts = Gv_GetVarX(*insptr++);
|
||||
|
||||
if (index > aGameArrays[j].size || index1 > aGameArrays[j1].size) continue;
|
||||
if ((index+value)>aGameArrays[j].size) value=aGameArrays[j].size-index;
|
||||
if ((index1+value)>aGameArrays[j1].size) value=aGameArrays[j1].size-index1;
|
||||
Bmemcpy(aGameArrays[j1].plValues+index1, aGameArrays[j].plValues+index, value * sizeof(intptr_t));
|
||||
if (si<0 || si>=g_gameArrayCount)
|
||||
{
|
||||
CON_ERRPRINTF("Invalid array %d!", si);
|
||||
dsiz = 1;
|
||||
}
|
||||
if (di<0 || di>=g_gameArrayCount)
|
||||
{
|
||||
CON_ERRPRINTF("Invalid array %d!", di);
|
||||
dsiz = 1;
|
||||
}
|
||||
if (aGameArrays[di].dwFlags & GAMEARRAY_READONLY)
|
||||
{
|
||||
CON_ERRPRINTF("Array %d is read-only!", di);
|
||||
dsiz = 1;
|
||||
}
|
||||
if (dsiz) continue; // dirty replacement for VMFLAG_ERROR
|
||||
|
||||
ssiz = (aGameArrays[si].dwFlags&GAMEARRAY_VARSIZE) ?
|
||||
Gv_GetVarX(aGameArrays[si].size) : aGameArrays[si].size;
|
||||
dsiz = (aGameArrays[di].dwFlags&GAMEARRAY_VARSIZE) ?
|
||||
Gv_GetVarX(aGameArrays[si].size) : aGameArrays[di].size;
|
||||
|
||||
if (sidx > ssiz || didx > dsiz) continue;
|
||||
if ((sidx+numelts) > ssiz) numelts = ssiz-sidx;
|
||||
if ((didx+numelts) > dsiz) numelts = dsiz-didx;
|
||||
|
||||
switch (aGameArrays[si].dwFlags & GAMEARRAY_TYPE_MASK)
|
||||
{
|
||||
case 0:
|
||||
case GAMEARRAY_OFINT:
|
||||
Bmemcpy((int32_t *)aGameArrays[di].plValues + didx, (int32_t *)aGameArrays[si].plValues + sidx, numelts * sizeof(int32_t));
|
||||
break;
|
||||
case GAMEARRAY_OFSHORT:
|
||||
for (; numelts>0; numelts--)
|
||||
((int32_t *)aGameArrays[di].plValues)[didx++] = ((int16_t *)aGameArrays[si].plValues)[sidx++];
|
||||
break;
|
||||
case GAMEARRAY_OFCHAR:
|
||||
for (; numelts>0; numelts--)
|
||||
((int32_t *)aGameArrays[di].plValues)[didx++] = ((uint8_t *)aGameArrays[si].plValues)[sidx++];
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,11 +52,13 @@ static void Gv_Free(void) /* called from Gv_ReadSave() and Gv_ResetVars() */
|
|||
if (i >= MAXGAMEARRAYS)
|
||||
continue;
|
||||
|
||||
if (aGameArrays[i].plValues)
|
||||
if ((aGameArrays[i].dwFlags & GAMEARRAY_NORMAL) && aGameArrays[i].plValues)
|
||||
{
|
||||
Bfree(aGameArrays[i].plValues);
|
||||
aGameArrays[i].plValues=NULL;
|
||||
}
|
||||
|
||||
aGameArrays[i].plValues=NULL;
|
||||
aGameArrays[i].bReset=1;
|
||||
aGameArrays[i].dwFlags |= GAMEARRAY_RESET;
|
||||
}
|
||||
g_gameVarCount=g_gameArrayCount=0;
|
||||
hash_init(&h_gamevars);
|
||||
|
@ -76,7 +78,6 @@ static void Gv_Clear(void)
|
|||
if (aGameVars[i].szLabel)
|
||||
Bfree(aGameVars[i].szLabel);
|
||||
aGameVars[i].szLabel=NULL;
|
||||
aGameVars[i].dwFlags=0;
|
||||
|
||||
if ((aGameVars[i].dwFlags & GAMEVAR_USER_MASK) && aGameVars[i].val.plValues)
|
||||
{
|
||||
|
@ -91,10 +92,12 @@ static void Gv_Clear(void)
|
|||
Bfree(aGameArrays[i].szLabel);
|
||||
aGameArrays[i].szLabel=NULL;
|
||||
|
||||
if (aGameArrays[i].plValues)
|
||||
if ((aGameArrays[i].dwFlags & GAMEARRAY_NORMAL) && aGameArrays[i].plValues)
|
||||
{
|
||||
Bfree(aGameArrays[i].plValues);
|
||||
aGameArrays[i].plValues=NULL;
|
||||
aGameArrays[i].bReset=1;
|
||||
aGameArrays[i].plValues=NULL;
|
||||
}
|
||||
aGameArrays[i].dwFlags |= GAMEARRAY_RESET;
|
||||
}
|
||||
g_gameVarCount=g_gameArrayCount=0;
|
||||
hash_init(&h_gamevars);
|
||||
|
@ -379,12 +382,12 @@ void Gv_ResetVars(void) /* this is called during a new game and nowhere else */
|
|||
|
||||
for (i=0; i<MAXGAMEARRAYS; i++)
|
||||
{
|
||||
if (aGameArrays[i].szLabel != NULL && aGameArrays[i].bReset)
|
||||
Gv_NewArray(aGameArrays[i].szLabel,aGameArrays[i].size);
|
||||
if (aGameArrays[i].szLabel != NULL && (aGameArrays[i].dwFlags & GAMEARRAY_RESET))
|
||||
Gv_NewArray(aGameArrays[i].szLabel,aGameArrays[i].plValues,aGameArrays[i].size,aGameArrays[i].dwFlags);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t Gv_NewArray(const char *pszLabel, int32_t asize)
|
||||
int32_t Gv_NewArray(const char *pszLabel, void *arrayptr, intptr_t asize, uint32_t dwFlags)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
|
@ -404,11 +407,20 @@ int32_t Gv_NewArray(const char *pszLabel, int32_t asize)
|
|||
return 0;
|
||||
}
|
||||
i = hash_find(&h_arrays,pszLabel);
|
||||
if (i >=0 && !aGameArrays[i].bReset)
|
||||
if (i >=0 && !(aGameArrays[i].dwFlags & GAMEARRAY_RESET))
|
||||
{
|
||||
// found it it's a duplicate in error
|
||||
|
||||
g_numCompilerWarnings++;
|
||||
C_ReportError(WARNING_DUPLICATEDEFINITION);
|
||||
|
||||
if (aGameArrays[i].dwFlags&GAMEARRAY_TYPE_MASK)
|
||||
{
|
||||
C_ReportError(-1);
|
||||
initprintf("ignored redefining system array `%s'.", pszLabel);
|
||||
}
|
||||
else
|
||||
C_ReportError(WARNING_DUPLICATEDEFINITION);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -418,9 +430,15 @@ int32_t Gv_NewArray(const char *pszLabel, int32_t asize)
|
|||
aGameArrays[i].szLabel=(char *)Bcalloc(MAXVARLABEL,sizeof(uint8_t));
|
||||
if (aGameArrays[i].szLabel != pszLabel)
|
||||
Bstrcpy(aGameArrays[i].szLabel,pszLabel);
|
||||
aGameArrays[i].plValues=(intptr_t *)Bcalloc(asize,GAR_ELTSZ);
|
||||
|
||||
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].bReset=0;
|
||||
aGameArrays[i].dwFlags = dwFlags & ~GAMEARRAY_RESET;
|
||||
|
||||
g_gameArrayCount++;
|
||||
hash_add(&h_arrays, aGameArrays[i].szLabel, i, 1);
|
||||
return 1;
|
||||
|
@ -753,16 +771,33 @@ int32_t __fastcall Gv_GetVarX(register int32_t id)
|
|||
if (id&(MAXGAMEVARS<<2)) // array
|
||||
{
|
||||
register int32_t index=Gv_GetVarX(*insptr++);
|
||||
int32_t siz;
|
||||
|
||||
id &= (MAXGAMEVARS-1);// ~((MAXGAMEVARS<<2)|(MAXGAMEVARS<<1));
|
||||
|
||||
if ((unsigned)index >= (unsigned)aGameArrays[id].size)
|
||||
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;
|
||||
}
|
||||
|
||||
return ((aGameArrays[id].plValues[index] ^ -negateResult) + negateResult);
|
||||
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
|
||||
|
@ -878,8 +913,12 @@ 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_GetVar(): WTF?\n");
|
||||
CON_ERRPRINTF("Gv_GetVarX(): WTF?\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -1624,6 +1663,12 @@ static void Gv_AddSystemVars(void)
|
|||
#else
|
||||
Gv_NewVar("rendmode", 0, GAMEVAR_READONLY | GAMEVAR_SYSTEM);
|
||||
#endif
|
||||
|
||||
// must be first!
|
||||
Gv_NewArray(".LOCALS_BASE", NULL, 0, GAMEARRAY_OFINT);
|
||||
|
||||
Gv_NewArray("tilesizx", (void *)tilesizx, MAXTILES, GAMEARRAY_READONLY|GAMEARRAY_OFSHORT);
|
||||
Gv_NewArray("tilesizy", (void *)tilesizy, MAXTILES, GAMEARRAY_READONLY|GAMEARRAY_OFSHORT);
|
||||
}
|
||||
|
||||
void Gv_Init(void)
|
||||
|
|
|
@ -52,8 +52,20 @@ enum GamevarFlags_t {
|
|||
#define MAXARRAYLABEL MAXVARLABEL
|
||||
|
||||
enum GamearrayFlags_t {
|
||||
GAMEARRAY_NORMAL = 0,
|
||||
GAMEARRAY_NORESET = 0x00000001,
|
||||
|
||||
GAMEARRAY_READONLY = 0x00001000,
|
||||
GAMEARRAY_WARN = 0x00002000,
|
||||
|
||||
GAMEARRAY_NORMAL = 0x00004000,
|
||||
GAMEARRAY_OFCHAR = 0x00000001,
|
||||
GAMEARRAY_OFSHORT = 0x00000002,
|
||||
GAMEARRAY_OFINT = 0x00000004,
|
||||
GAMEARRAY_TYPE_MASK = GAMEARRAY_OFCHAR|GAMEARRAY_OFSHORT|GAMEARRAY_OFINT,
|
||||
|
||||
GAMEARRAY_VARSIZE = 0x00000020,
|
||||
|
||||
GAMEARRAY_RESET = 0x00000008,
|
||||
/// GAMEARRAY_NORESET = 0x00000001,
|
||||
};
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
@ -71,7 +83,7 @@ typedef struct {
|
|||
char *szLabel;
|
||||
intptr_t *plValues; // array of values
|
||||
intptr_t size;
|
||||
intptr_t bReset;
|
||||
intptr_t dwFlags;
|
||||
} gamearray_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
|
@ -85,7 +97,7 @@ extern int32_t g_gameArrayCount;
|
|||
int32_t __fastcall Gv_GetVar(register int32_t id,register int32_t iActor,register int32_t iPlayer);
|
||||
int32_t __fastcall Gv_GetVarX(register int32_t id);
|
||||
int32_t Gv_GetVarByLabel(const char *szGameLabel,int32_t lDefault,int32_t iActor,int32_t iPlayer);
|
||||
int32_t Gv_NewArray(const char *pszLabel,int32_t asize);
|
||||
int32_t Gv_NewArray(const char *pszLabel,void *arrayptr,intptr_t asize,uint32_t dwFlags);
|
||||
int32_t Gv_NewVar(const char *pszLabel,intptr_t lValue,uint32_t dwFlags);
|
||||
int32_t Gv_ReadSave(int32_t fil,int32_t newbehav);
|
||||
void __fastcall A_ResetVars(register int32_t iActor);
|
||||
|
|
|
@ -44,7 +44,6 @@ static void Gv_Clear(void)
|
|||
Bfree(aGameVars[i].szLabel);
|
||||
|
||||
aGameVars[i].szLabel = NULL;
|
||||
aGameVars[i].dwFlags = 0;
|
||||
|
||||
if ((aGameVars[i].dwFlags & GAMEVAR_USER_MASK) && aGameVars[i].val.plValues)
|
||||
{
|
||||
|
@ -63,10 +62,12 @@ static void Gv_Clear(void)
|
|||
|
||||
aGameArrays[i].szLabel = NULL;
|
||||
|
||||
if (aGameArrays[i].vals)
|
||||
if ((aGameArrays[i].dwFlags & GAMEARRAY_NORMAL) && aGameArrays[i].vals)
|
||||
{
|
||||
Bfree(aGameArrays[i].vals);
|
||||
aGameArrays[i].vals=NULL;
|
||||
}
|
||||
|
||||
aGameArrays[i].vals = NULL;
|
||||
aGameArrays[i].dwFlags |= GAMEARRAY_RESET;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue