m32script: fix tilesizx[]/tilesizy[] access. Can also 'copy' from them.

git-svn-id: https://svn.eduke32.com/eduke32@4799 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2014-12-06 19:09:53 +00:00
parent 74d99fe2e1
commit 5e35448560
5 changed files with 55 additions and 20 deletions

View file

@ -139,6 +139,7 @@ enum GamearrayFlags_t {
GAMEARRAY_RESET = 0x00000008,
GAMEARRAY_VARSIZE = 0x00000020,
GAMEARRAY_STRIDE2 = 0x00000040,
};
typedef struct {

View file

@ -349,8 +349,8 @@ Directives
Run-time commands
^^^^^^^^^^^^^^^^^
*`activatecheat`*, *`qstrncat`*, *`qsubstr`*, *`clearmapstate`*, `save`,
`savenn`, *`lineintersect`*, *`rayintersect`*, *`sectorofwall`*.
*`activatecheat`*, *`clearmapstate`*, `save`, `savenn`, *`lineintersect`*,
*`rayintersect`*, *`sectorofwall`*.
Additionally, various multiplayer-related commands either unconditionally
return results as if no multiplayer game is in progress, or are non-functional

View file

@ -1126,18 +1126,23 @@ static void C_GetNextVarType(int32_t type)
}
else if (id<MAXGAMEARRAYS) // simple (non-local) gamearrays
{
if (!m32_script_expertmode && (type&GV_WRITABLE))
if (type & GV_WRITABLE)
{
const int32_t flags = aGameArrays[id].dwFlags;
const int32_t dwFlags = aGameArrays[id].dwFlags;
if (flags & GAMEARRAY_READONLY)
// NOTE: GAMEARRAY_STRIDE2 arrays cannot be written to
// regardless of whether we're in expert mode or not.
if (!m32_script_expertmode || (dwFlags & GAMEARRAY_STRIDE2))
{
C_ReportError(ERROR_ARRAYREADONLY);
g_numCompilerErrors++;
}
else if (flags & GAMEARRAY_WARN)
{
C_CUSTOMWARNING("writing to expert-mode array. Be sure to know what you're doing!");
if (dwFlags & GAMEARRAY_READONLY)
{
C_ReportError(ERROR_ARRAYREADONLY);
g_numCompilerErrors++;
}
else if (dwFlags & GAMEARRAY_WARN)
{
C_CUSTOMWARNING("writing to expert-mode array. Be sure to know what you're doing!");
}
}
}
}

View file

@ -549,33 +549,49 @@ skip_check:
if (aGameArrays[di].dwFlags & GAMEARRAY_READONLY)
M32_ERROR("Array %d is read-only!", di);
if (vm.flags&VMFLAG_ERROR)
continue;
const int32_t ssiz = Gv_GetArraySize(si);
const int32_t dsiz = Gv_GetArraySize(di);
if (sidx > ssiz || didx > dsiz)
if ((uint32_t)sidx >= (uint32_t)ssiz)
M32_ERROR("Invalid source index %d", sidx);
if ((uint32_t)didx >= (uint32_t)dsiz)
M32_ERROR("Invalid destination index %d", didx);
if (vm.flags&VMFLAG_ERROR)
continue;
if (numelts > ssiz-sidx)
numelts = ssiz-sidx;
if (numelts > dsiz-didx)
numelts = dsiz-didx;
switch (aGameArrays[si].dwFlags & GAMEARRAY_TYPE_MASK)
const gamearray_t *const sar = &aGameArrays[si];
gamearray_t *const dar = &aGameArrays[di];
switch (sar->dwFlags & GAMEARRAY_TYPE_MASK)
{
case 0:
case GAMEARRAY_OFINT:
Bmemcpy((int32_t *)aGameArrays[di].vals + didx, (int32_t *)aGameArrays[si].vals + sidx, numelts * sizeof(int32_t));
if (sar->dwFlags & GAMEARRAY_STRIDE2)
{
for (; numelts>0; numelts--, sidx += 2)
((int32_t *)dar->vals)[didx++] = ((int32_t *)sar->vals)[sidx];
}
else
{
Bmemcpy((int32_t *)dar->vals + didx, (int32_t *)sar->vals + sidx,
numelts * sizeof(int32_t));
}
break;
case GAMEARRAY_OFSHORT:
for (; numelts>0; numelts--)
((int32_t *)aGameArrays[di].vals)[didx++] = ((int16_t *)aGameArrays[si].vals)[sidx++];
((int32_t *)dar->vals)[didx++] = ((int16_t *)sar->vals)[sidx++];
break;
case GAMEARRAY_OFCHAR:
for (; numelts>0; numelts--)
((int32_t *)aGameArrays[di].vals)[didx++] = ((uint8_t *)aGameArrays[si].vals)[sidx++];
((int32_t *)dar->vals)[didx++] = ((uint8_t *)sar->vals)[sidx++];
break;
}
continue;

View file

@ -79,9 +79,16 @@ static void Gv_Clear(void)
return;
}
#define ASSERT_IMPLIES(x, y) Bassert(!(x) || (y))
int32_t Gv_NewArray(const char *pszLabel, void *arrayptr, int32_t asize, uint32_t dwFlags)
{
Bassert(!(dwFlags&GAMEARRAY_VARSIZE) || (dwFlags&GAMEARRAY_READONLY));
ASSERT_IMPLIES(dwFlags&GAMEARRAY_VARSIZE, dwFlags&GAMEARRAY_READONLY);
ASSERT_IMPLIES(dwFlags&GAMEARRAY_STRIDE2, dwFlags&GAMEARRAY_READONLY);
ASSERT_IMPLIES(dwFlags&GAMEARRAY_TYPE_MASK,
g_gameArrayCount==0 || (dwFlags&(GAMEARRAY_READONLY|GAMEARRAY_WARN)));
ASSERT_IMPLIES(dwFlags&GAMEARRAY_STRIDE2, dwFlags&GAMEARRAY_OFINT);
if (g_gameArrayCount >= MAXGAMEARRAYS)
{
@ -307,6 +314,9 @@ int32_t __fastcall Gv_GetVarX(register int32_t id)
return -1;
}
if (gar->dwFlags & GAMEARRAY_STRIDE2)
index <<= 1;
switch (gar->dwFlags & GAMEARRAY_TYPE_MASK)
{
case 0:
@ -406,6 +416,9 @@ void __fastcall Gv_SetVarX(register int32_t id, register int32_t lValue)
return;
}
// NOTE: GAMEARRAY_READONLY arrays can be modified in expert mode.
Bassert((gar->dwFlags & GAMEARRAY_STRIDE2) == 0);
switch (gar->dwFlags & GAMEARRAY_TYPE_MASK)
{
case 0:
@ -670,8 +683,8 @@ static void Gv_AddSystemVars(void)
Gv_NewArray("headsectbunchf", (void *)headsectbunch[1], YAX_MAXBUNCHES, GAMEARRAY_READONLY|GAMEARRAY_OFSHORT);
Gv_NewArray("nextsectbunchf", (void *)nextsectbunch[1], MAXSECTORS, GAMEARRAY_READONLY|GAMEARRAY_OFSHORT);
#endif
// Gv_NewArray("tilesizx", (void *)tilesizx, MAXTILES, GAMEARRAY_READONLY|GAMEARRAY_OFSHORT);
// Gv_NewArray("tilesizy", (void *)tilesizy, MAXTILES, GAMEARRAY_READONLY|GAMEARRAY_OFSHORT);
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);
// Gv_NewArray("picsiz", (void *)picsiz, MAXTILES, GAMEARRAY_READONLY|GAMEARRAY_OFCHAR);
Gv_NewArray("picanm", (void *)picanm, MAXTILES, GAMEARRAY_READONLY|GAMEARRAY_OFINT);