From 5e3544856083bafa7b8cceb7f3eddcd781b40d31 Mon Sep 17 00:00:00 2001 From: helixhorned Date: Sat, 6 Dec 2014 19:09:53 +0000 Subject: [PATCH] m32script: fix tilesizx[]/tilesizy[] access. Can also 'copy' from them. git-svn-id: https://svn.eduke32.com/eduke32@4799 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/build/include/m32script.h | 1 + .../eduke32/source/lunatic/doc/lunacon.txt | 4 +-- polymer/eduke32/source/m32def.c | 23 +++++++++------ polymer/eduke32/source/m32exec.c | 28 +++++++++++++++---- polymer/eduke32/source/m32vars.c | 19 +++++++++++-- 5 files changed, 55 insertions(+), 20 deletions(-) diff --git a/polymer/eduke32/build/include/m32script.h b/polymer/eduke32/build/include/m32script.h index 5f1fb1022..aa2731b93 100644 --- a/polymer/eduke32/build/include/m32script.h +++ b/polymer/eduke32/build/include/m32script.h @@ -139,6 +139,7 @@ enum GamearrayFlags_t { GAMEARRAY_RESET = 0x00000008, GAMEARRAY_VARSIZE = 0x00000020, + GAMEARRAY_STRIDE2 = 0x00000040, }; typedef struct { diff --git a/polymer/eduke32/source/lunatic/doc/lunacon.txt b/polymer/eduke32/source/lunatic/doc/lunacon.txt index 395b9dc43..e4d6c2f07 100644 --- a/polymer/eduke32/source/lunatic/doc/lunacon.txt +++ b/polymer/eduke32/source/lunatic/doc/lunacon.txt @@ -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 diff --git a/polymer/eduke32/source/m32def.c b/polymer/eduke32/source/m32def.c index 88f1fcdba..489b4b6ee 100644 --- a/polymer/eduke32/source/m32def.c +++ b/polymer/eduke32/source/m32def.c @@ -1126,18 +1126,23 @@ static void C_GetNextVarType(int32_t type) } else if (id 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; diff --git a/polymer/eduke32/source/m32vars.c b/polymer/eduke32/source/m32vars.c index fac263870..a0b04abaa 100644 --- a/polymer/eduke32/source/m32vars.c +++ b/polymer/eduke32/source/m32vars.c @@ -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);