diff --git a/source/duke3d/src/gameexec.cpp b/source/duke3d/src/gameexec.cpp index ce5c17d70..9a37a2249 100644 --- a/source/duke3d/src/gameexec.cpp +++ b/source/duke3d/src/gameexec.cpp @@ -20,17 +20,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ //------------------------------------------------------------------------- -#include "compat.h" #include "colmatch.h" +#include "compat.h" #include "duke3d.h" -#include "scriplib.h" -#include "savegame.h" -#include "osdcmds.h" -#include "menus.h" -#include "input.h" #include "anim.h" +#include "input.h" +#include "menus.h" +#include "osdcmds.h" +#include "savegame.h" +#include "scriplib.h" #ifdef LUNATIC # include "lunatic_game.h" @@ -47,7 +47,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. vmstate_t vm; #if !defined LUNATIC -enum vmflags_t { +enum vmflags_t +{ VM_RETURN = 0x00000001, VM_KILL = 0x00000002, VM_NOEXECUTE = 0x00000004, @@ -75,7 +76,7 @@ int32_t g_structVarIDs = -1; uint32_t g_eventCalls[MAXEVENTS], g_actorCalls[MAXTILES]; double g_eventTotalMs[MAXEVENTS], g_actorTotalMs[MAXTILES], g_actorMinMs[MAXTILES], g_actorMaxMs[MAXTILES]; -GAMEEXEC_STATIC void VM_Execute(int loop); +GAMEEXEC_STATIC void VM_Execute(native_t loop); # include "gamestructures.cpp" #endif @@ -99,9 +100,8 @@ void VM_ScriptInfo(intptr_t const *ptr, int range) { initprintf("\n"); - for (intptr_t const *pScript = max(ptr - (range >> 1), apScript), - *p_end = min(ptr + (range >> 1), apScript + g_scriptSize); - pScript < p_end; pScript++) + for (intptr_t const *pScript = max(ptr - (range >> 1), apScript), *p_end = min(ptr + (range >> 1), apScript + g_scriptSize); pScript < p_end; + pScript++) { initprintf("%5d: %3d: ", (int32_t) (pScript - apScript), (int32_t) (pScript - ptr)); @@ -167,8 +167,7 @@ static void VM_DummySprite(void) vm.pData = &dummy.t_data[0]; } -static FORCE_INLINE int32_t VM_EventCommon_(int const eventNum, int const spriteNum, int const playerNum, - int const playerDist, int32_t returnValue) +static FORCE_INLINE int32_t VM_EventCommon_(int const eventNum, int const spriteNum, int const playerNum, int const playerDist, int32_t returnValue) { const double t = timerGetHiTicks(); @@ -269,9 +268,7 @@ static int32_t VM_CheckSquished(void) floorZ += ZOFFSET5; #endif - if (vm.pSprite->pal == 1 ? - (floorZ - ceilZ >= ZOFFSET5 || (pSector->lotag & 32768u)) : - (floorZ - ceilZ >= ZOFFSET4)) + if (vm.pSprite->pal == 1 ? (floorZ - ceilZ >= ZOFFSET5 || (pSector->lotag & 32768u)) : (floorZ - ceilZ >= ZOFFSET4)) return 0; P_DoQuote(QUOTE_SQUISHED, vm.pPlayer); @@ -349,10 +346,7 @@ int32_t A_GetFurthestAngle(int const spriteNum, int const angDiv) for (native_t j = pSprite->ang; j < (2048 + pSprite->ang); j += angIncs) { pSprite->z -= ZOFFSET3; - hitscan((const vec3_t *)pSprite, pSprite->sectnum, - sintable[(j+512)&2047], - sintable[j&2047], 0, - &hit, CLIPMASK1); + hitscan((const vec3_t *)pSprite, pSprite->sectnum, sintable[(j + 512) & 2047], sintable[j & 2047], 0, &hit, CLIPMASK1); pSprite->z += ZOFFSET3; int const hitDist = klabs(hit.pos.x-pSprite->x) + klabs(hit.pos.y-pSprite->y); @@ -381,8 +375,7 @@ int A_FurthestVisiblePoint(int const spriteNum, uspritetype * const ts, vec2_t * for (native_t j = ts->ang; j < (2048 + ts->ang); j += (angincs /*-(krand()&511)*/)) { ts->z -= ZOFFSET2; - hitscan((const vec3_t *)ts, ts->sectnum, sintable[(j + 512) & 2047], sintable[j & 2047], - 16384 - (krand() & 32767), &hit, CLIPMASK1); + hitscan((const vec3_t *)ts, ts->sectnum, sintable[(j + 512) & 2047], sintable[j & 2047], 16384 - (krand() & 32767), &hit, CLIPMASK1); ts->z += ZOFFSET2; if (hit.sect < 0) @@ -393,8 +386,7 @@ int A_FurthestVisiblePoint(int const spriteNum, uspritetype * const ts, vec2_t * if (d < da) { - if (cansee(hit.pos.x, hit.pos.y, hit.pos.z, hit.sect, - pnSprite->x, pnSprite->y, pnSprite->z - ZOFFSET2, pnSprite->sectnum)) + if (cansee(hit.pos.x, hit.pos.y, hit.pos.z, hit.sect, pnSprite->x, pnSprite->y, pnSprite->z - ZOFFSET2, pnSprite->sectnum)) { vect->x = hit.pos.x; vect->y = hit.pos.y; @@ -414,10 +406,7 @@ static void VM_GetZRange(int const spriteNum, int32_t * const ceilhit, int32_t * pSprite->cstat = 0; pSprite->z -= ZOFFSET; - getzrange((vec3_t *)pSprite, pSprite->sectnum, - &actor[spriteNum].ceilingz, ceilhit, - &actor[spriteNum].floorz, florhit, - wallDist, CLIPMASK0); + getzrange((vec3_t *)pSprite, pSprite->sectnum, &actor[spriteNum].ceilingz, ceilhit, &actor[spriteNum].floorz, florhit, wallDist, CLIPMASK0); pSprite->z += ZOFFSET; pSprite->cstat = ocstat; @@ -463,7 +452,8 @@ void A_Fall(int const spriteNum) else if (sector[pSprite->sectnum].lotag == ST_2_UNDERWATER || EDUKE32_PREDICT_FALSE(G_CheckForSpaceCeiling(pSprite->sectnum))) spriteGravity = g_spriteGravity/6; - if (pSprite->statnum == STAT_ACTOR || pSprite->statnum == STAT_PLAYER || pSprite->statnum == STAT_ZOMBIEACTOR || pSprite->statnum == STAT_STANDABLE) + if (pSprite->statnum == STAT_ACTOR || pSprite->statnum == STAT_PLAYER || pSprite->statnum == STAT_ZOMBIEACTOR + || pSprite->statnum == STAT_STANDABLE) { int32_t ceilhit, florhit; VM_GetZRange(spriteNum, &ceilhit, &florhit, 127); @@ -512,8 +502,10 @@ int32_t __fastcall G_GetAngleDelta(int32_t currAngle, int32_t newAngle) return newAngle-currAngle; } - if (newAngle > 1024) newAngle -= 2048; - if (currAngle > 1024) currAngle -= 2048; + if (newAngle > 1024) + newAngle -= 2048; + if (currAngle > 1024) + currAngle -= 2048; // OSD_Printf("G_GetAngleDelta() returning %d\n",na-a); return newAngle-currAngle; @@ -554,9 +546,9 @@ GAMEEXEC_STATIC void VM_AlterAng(int32_t const moveFlags) // NOTE: looks like 'owner' is set to target sprite ID... - vm.pSprite->owner - = (holoDukeSprite >= 0 && cansee(sprite[holoDukeSprite].x, sprite[holoDukeSprite].y, sprite[holoDukeSprite].z, - sprite[holoDukeSprite].sectnum, vm.pSprite->x, vm.pSprite->y, vm.pSprite->z, vm.pSprite->sectnum)) + vm.pSprite->owner = (holoDukeSprite >= 0 + && cansee(sprite[holoDukeSprite].x, sprite[holoDukeSprite].y, sprite[holoDukeSprite].z, sprite[holoDukeSprite].sectnum, + vm.pSprite->x, vm.pSprite->y, vm.pSprite->z, vm.pSprite->sectnum)) ? holoDukeSprite : vm.pPlayer->i; @@ -580,11 +572,14 @@ GAMEEXEC_STATIC void VM_AlterAng(int32_t const moveFlags) } else if (elapsedTics > 18 && elapsedTics < GAMETICSPERSEC) // choose { - if (klabs(angDiff>>2) < 128) vm.pSprite->ang = goalAng; - else vm.pSprite->ang += angDiff>>2; + if (klabs(angDiff >> 2) < 128) + vm.pSprite->ang = goalAng; + else + vm.pSprite->ang += angDiff >> 2; } } - else vm.pSprite->ang = goalAng; + else + vm.pSprite->ang = goalAng; } if (elapsedTics < 1) @@ -696,8 +691,7 @@ GAMEEXEC_STATIC void VM_Move(void) if (movflags&face_player_smart) { - vec2_t const vect = { vm.pPlayer->pos.x + (vm.pPlayer->vel.x / 768), - vm.pPlayer->pos.y + (vm.pPlayer->vel.y / 768) }; + vec2_t const vect = { vm.pPlayer->pos.x + (vm.pPlayer->vel.x / 768), vm.pPlayer->pos.y + (vm.pPlayer->vel.y / 768) }; VM_AddAngle(2, getangle(vect.x - vm.pSprite->x, vect.y - vm.pSprite->y)); } @@ -712,11 +706,15 @@ dead: intptr_t const * const moveptr = apScript + AC_MOVE_ID(vm.pData); - if (movflags&geth) vm.pSprite->xvel += ((moveptr[0])-vm.pSprite->xvel)>>1; - if (movflags&getv) vm.pSprite->zvel += ((moveptr[1]<<4)-vm.pSprite->zvel)>>1; + if (movflags & geth) + vm.pSprite->xvel += ((moveptr[0]) - vm.pSprite->xvel) >> 1; + if (movflags & getv) + vm.pSprite->zvel += ((moveptr[1] << 4) - vm.pSprite->zvel) >> 1; #else - if (movflags&geth) vm.pSprite->xvel += (vm.pActor->mv.hvel - vm.pSprite->xvel)>>1; - if (movflags&getv) vm.pSprite->zvel += (16*vm.pActor->mv.vvel - vm.pSprite->zvel)>>1; + if (movflags & geth) + vm.pSprite->xvel += (vm.pActor->mv.hvel - vm.pSprite->xvel) >> 1; + if (movflags & getv) + vm.pSprite->zvel += (16 * vm.pActor->mv.vvel - vm.pSprite->zvel) >> 1; #endif if (movflags&dodgebullet && !deadflag) @@ -834,8 +832,8 @@ dead: if (vm.pSprite->z < vm.pActor->ceilingz+ZOFFSET5) vm.pSprite->z = vm.pActor->ceilingz+ZOFFSET5; - vec3_t const vect = { (spriteXvel * (sintable[(angDiff + 512) & 2047])) >> 14, - (spriteXvel * (sintable[angDiff & 2047])) >> 14, vm.pSprite->zvel }; + vec3_t const vect + = { (spriteXvel * (sintable[(angDiff + 512) & 2047])) >> 14, (spriteXvel * (sintable[angDiff & 2047])) >> 14, vm.pSprite->zvel }; vm.pActor->movflag = A_MoveSprite(vm.spriteNum, &vect, (A_CheckSpriteFlags(vm.spriteNum, SFLAG_NOCLIP) ? 0 : CLIPMASK0)); } @@ -861,7 +859,8 @@ static void P_AddWeaponMaybeSwitch(DukePlayer_t * const ps, int const weaponNum) if (w == KNEE_WEAPON) w = FREEZE_WEAPON; - else w--; + else + w--; if (w == ps->curr_weapon) curr_wchoice = i; @@ -878,10 +877,7 @@ static void P_AddWeaponMaybeSwitch(DukePlayer_t * const ps, int const weaponNum) } #if defined LUNATIC -void P_AddWeaponMaybeSwitchI(int32_t snum, int32_t weap) -{ - P_AddWeaponMaybeSwitch(g_player[snum].ps, weap); -} +void P_AddWeaponMaybeSwitchI(int32_t snum, int32_t weap) { P_AddWeaponMaybeSwitch(g_player[snum].ps, weap); } #else static void P_AddWeaponAmmoCommon(DukePlayer_t * const pPlayer, int const weaponNum, int const nAmount) { @@ -954,21 +950,13 @@ static void VM_AddInventory(DukePlayer_t * const pPlayer, int const itemNum, int case GET_ACCESS: switch (vm.pSprite->pal) { - case 0: - pPlayer->got_access |= 1; - break; - case 21: - pPlayer->got_access |= 2; - break; - case 23: - pPlayer->got_access |= 4; - break; + case 0: pPlayer->got_access |= 1; break; + case 21: pPlayer->got_access |= 2; break; + case 23: pPlayer->got_access |= 4; break; } break; - default: - CON_ERRPRINTF("invalid inventory item %d\n", itemNum); - break; + default: CON_ERRPRINTF("invalid inventory item %d\n", itemNum); break; } } #endif @@ -1028,8 +1016,7 @@ static void VM_Fall(int const spriteNum, spritetype * const pSprite) int newZ = pSprite->z + pSprite->zvel; #ifdef YAX_ENABLE - if (yax_getbunch(pSprite->sectnum, YAX_FLOOR) >= 0 && - (sector[pSprite->sectnum].floorstat&512)==0) + if (yax_getbunch(pSprite->sectnum, YAX_FLOOR) >= 0 && (sector[pSprite->sectnum].floorstat & 512) == 0) setspritez(spriteNum, (vec3_t *)pSprite); else #endif @@ -1178,22 +1165,17 @@ static int G_StartTrackSlotWrap(int const volumeNum, int const levelNum) { if (EDUKE32_PREDICT_FALSE(G_StartTrackSlot(volumeNum, levelNum))) { - CON_ERRPRINTF("invalid level %d or null music for volume %d level %d\n", - levelNum, volumeNum, levelNum); + CON_ERRPRINTF("invalid level %d or null music for volume %d level %d\n", levelNum, volumeNum, levelNum); return 1; } return 0; } #else -int G_StartTrack(int const levelNum) -{ - return G_StartTrackSlot(ud.volume_number, levelNum); -} +int G_StartTrack(int const levelNum) { return G_StartTrackSlot(ud.volume_number, levelNum); } #endif -LUNATIC_EXTERN void G_ShowView(vec3_t vec, fix16_t a, fix16_t horiz, int32_t sect, - int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t unbiasedp) +LUNATIC_EXTERN void G_ShowView(vec3_t vec, fix16_t a, fix16_t horiz, int32_t sect, int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t unbiasedp) { if (g_screenCapture) return; @@ -1204,8 +1186,10 @@ LUNATIC_EXTERN void G_ShowView(vec3_t vec, fix16_t a, fix16_t horiz, int32_t sec return; } - if (x1 > x2) swaplong(&x1,&x2); - if (y1 > y2) swaplong(&y1,&y2); + if (x1 > x2) + swaplong(&x1, &x2); + if (y1 > y2) + swaplong(&y1, &y2); if (!unbiasedp) { @@ -1281,12 +1265,12 @@ void Screen_Play(void) } #if !defined LUNATIC -GAMEEXEC_STATIC void VM_Execute(int loop) +GAMEEXEC_STATIC void VM_Execute(native_t loop) { - int32_t tw = *insptr; - DukePlayer_t * const pPlayer = vm.pPlayer; + native_t tw = *insptr; + DukePlayer_t *const pPlayer = vm.pPlayer; - // jump directly into the loop, saving us from the checks during the first iteration + // jump directly into the loop, skipping branches during the first iteration goto skip_check; while (loop) @@ -1296,12 +1280,12 @@ GAMEEXEC_STATIC void VM_Execute(int loop) tw = *insptr; -skip_check: + skip_check: // Bsprintf(g_szBuf,"Parsing: %d",*insptr); // AddLog(g_szBuf); - g_errorLineNum = tw>>12; - g_tw = tw &= VM_INSTMASK; + g_errorLineNum = tw >> 12; + g_tw = tw &= VM_INSTMASK; if (tw == CON_LEFTBRACE) { @@ -1315,13 +1299,13 @@ skip_check: } else if (tw == CON_ELSE) { - insptr = (intptr_t *) *(insptr+1); + insptr = (intptr_t *)*(insptr + 1); continue; } else if (tw == CON_STATE) { - intptr_t const * const tempscrptr = insptr + 2; - insptr = (intptr_t *)*(insptr + 1); + intptr_t const *const tempscrptr = insptr + 2; + insptr = (intptr_t *)*(insptr + 1); VM_Execute(1); insptr = tempscrptr; continue; @@ -1329,4516 +1313,4474 @@ skip_check: switch (tw) { - case CON_IFVARE: - insptr++; - tw = Gv_GetVarX(*insptr++); - VM_CONDITIONAL(tw == *insptr); - continue; + case CON_RETURN: vm.flags |= VM_RETURN; fallthrough__; + case CON_ENDSWITCH: + case CON_ENDA: + case CON_BREAK: + case CON_ENDS: + case CON_ENDEVENT: return; - case CON_REDEFINEQUOTE: - insptr++; - { - int const strIndex = *insptr++; - int const XstrIndex = *insptr++; + case CON_JUMP: // this is used for event chaining + insptr++; + tw = Gv_GetVarX(*insptr++); + insptr = (intptr_t *)(tw + apScript); + continue; - if (EDUKE32_PREDICT_FALSE((apStrings[strIndex] == NULL || apXStrings[XstrIndex] == NULL))) + case CON_SETVARVAR: + insptr++; { - CON_ERRPRINTF("invalid source quote %d or destination quote %d\n", XstrIndex, strIndex); - break; + tw = *insptr++; + int const nValue = Gv_GetVarX(*insptr++); + + if ((aGameVars[tw].flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) == 0) + aGameVars[tw].global = nValue; + else + Gv_SetVarX(tw, nValue); } - Bstrcpy(apStrings[strIndex], apXStrings[XstrIndex]); continue; - } - case CON_GETTHISPROJECTILE: - insptr++; - { + case CON_ADDVARVAR: + insptr++; tw = *insptr++; - int const spriteNum = (tw != g_thisActorVarID) ? Gv_GetVarX(tw) : vm.spriteNum; - int const labelNum = *insptr++; - - Gv_SetVarX(*insptr++, VM_GetActiveProjectile(spriteNum, labelNum)); + Gv_AddVar(tw, Gv_GetVarX(*insptr++)); continue; - } - case CON_SETTHISPROJECTILE: - insptr++; - { + case CON_SUBVARVAR: + insptr++; tw = *insptr++; - int const spriteNum = (tw != g_thisActorVarID) ? Gv_GetVarX(tw) : vm.spriteNum; - int const labelNum = *insptr++; - - VM_SetActiveProjectile(spriteNum, labelNum, Gv_GetVarX(*insptr++)); + Gv_SubVar(tw, Gv_GetVarX(*insptr++)); continue; - } - case CON_IFRND: - VM_CONDITIONAL(rnd(*(++insptr))); - continue; + case CON_IFVARVARE: + insptr++; + tw = Gv_GetVarX(*insptr++); + tw = (tw == Gv_GetVarX(*insptr++)); + insptr--; + VM_CONDITIONAL(tw); + continue; - case CON_IFCANSHOOTTARGET: - { - if (vm.playerDist > 1024) - { - int16_t temphit; + case CON_IFVARVARN: + insptr++; + tw = Gv_GetVarX(*insptr++); + tw = (tw != Gv_GetVarX(*insptr++)); + insptr--; + VM_CONDITIONAL(tw); + continue; - if ((tw = A_CheckHitSprite(vm.spriteNum, &temphit)) == (1 << 30)) + case CON_MULVARVAR: + insptr++; + tw = *insptr++; + Gv_MulVar(tw, Gv_GetVarX(*insptr++)); + continue; + + case CON_DIVVARVAR: + insptr++; { - VM_CONDITIONAL(1); + tw = *insptr++; + + int const nValue = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE(!nValue)) + { + CON_CRITICALERRPRINTF("divide by zero!\n"); + continue; + } + + Gv_DivVar(tw, nValue); continue; } - int dist = 768; - int angDiff = 16; + case CON_IFVARE: + insptr++; + tw = Gv_GetVarX(*insptr++); + VM_CONDITIONAL(tw == *insptr); + continue; - if (A_CheckEnemySprite(vm.pSprite) && vm.pSprite->xrepeat > 56) + case CON_IFVARN: + insptr++; + tw = Gv_GetVarX(*insptr++); + VM_CONDITIONAL(tw != *insptr); + continue; + + case CON_ADDVAR: + insptr++; + Gv_AddVar(*insptr, *(insptr + 1)); + insptr += 2; + continue; + + case CON_SUBVAR: + insptr++; + Gv_SubVar(*insptr, *(insptr + 1)); + insptr += 2; + continue; + + case CON_SETVAR: + insptr++; + if ((aGameVars[*insptr].flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) == 0) + aGameVars[*insptr].global = *(insptr + 1); + else + Gv_SetVarX(*insptr, *(insptr + 1)); + insptr += 2; + continue; + + case CON_MULVAR: + insptr++; + Gv_MulVar(*insptr, *(insptr + 1)); + insptr += 2; + continue; + + case CON_DIVVAR: + insptr++; + if (EDUKE32_PREDICT_FALSE(*(insptr + 1) == 0)) { - dist = 3084; - angDiff = 48; + CON_CRITICALERRPRINTF("divide by zero!\n"); + insptr += 2; + continue; + } + Gv_DivVar(*insptr, *(insptr + 1)); + insptr += 2; + continue; + + case CON_IFVARVARG: + insptr++; + tw = Gv_GetVarX(*insptr++); + tw = (tw > Gv_GetVarX(*insptr++)); + insptr--; + VM_CONDITIONAL(tw); + continue; + + case CON_IFVARVARGE: + insptr++; + tw = Gv_GetVarX(*insptr++); + tw = (tw >= Gv_GetVarX(*insptr++)); + insptr--; + VM_CONDITIONAL(tw); + continue; + + case CON_IFVARVARL: + insptr++; + tw = Gv_GetVarX(*insptr++); + tw = (tw < Gv_GetVarX(*insptr++)); + insptr--; + VM_CONDITIONAL(tw); + continue; + + case CON_IFVARVARLE: + insptr++; + tw = Gv_GetVarX(*insptr++); + tw = (tw <= Gv_GetVarX(*insptr++)); + insptr--; + VM_CONDITIONAL(tw); + continue; + + case CON_IFVARVARA: + insptr++; + tw = Gv_GetVarX(*insptr++); + tw = ((uint32_t)tw > (uint32_t)Gv_GetVarX(*insptr++)); + insptr--; + VM_CONDITIONAL(tw); + continue; + + case CON_IFVARVARAE: + insptr++; + tw = Gv_GetVarX(*insptr++); + tw = ((uint32_t)tw >= (uint32_t)Gv_GetVarX(*insptr++)); + insptr--; + VM_CONDITIONAL(tw); + continue; + + case CON_IFVARVARB: + insptr++; + tw = Gv_GetVarX(*insptr++); + tw = ((uint32_t)tw < (uint32_t)Gv_GetVarX(*insptr++)); + insptr--; + VM_CONDITIONAL(tw); + continue; + + case CON_IFVARVARBE: + insptr++; + tw = Gv_GetVarX(*insptr++); + tw = ((uint32_t)tw <= (uint32_t)Gv_GetVarX(*insptr++)); + insptr--; + VM_CONDITIONAL(tw); + continue; + + case CON_IFVARVARAND: + insptr++; + tw = Gv_GetVarX(*insptr++); + tw &= Gv_GetVarX(*insptr++); + insptr--; + VM_CONDITIONAL(tw); + continue; + + case CON_IFVARVAROR: + insptr++; + tw = Gv_GetVarX(*insptr++); + tw |= Gv_GetVarX(*insptr++); + insptr--; + VM_CONDITIONAL(tw); + continue; + + case CON_IFVARVARXOR: + insptr++; + tw = Gv_GetVarX(*insptr++); + tw ^= Gv_GetVarX(*insptr++); + insptr--; + VM_CONDITIONAL(tw); + continue; + + case CON_IFVARAND: + insptr++; + tw = Gv_GetVarX(*insptr++); + VM_CONDITIONAL(tw & *insptr); + continue; + + case CON_IFVAROR: + insptr++; + tw = Gv_GetVarX(*insptr++); + VM_CONDITIONAL(tw | *insptr); + continue; + + case CON_IFVARXOR: + insptr++; + tw = Gv_GetVarX(*insptr++); + VM_CONDITIONAL(tw ^ *insptr); + continue; + + case CON_IFVAREITHER: + insptr++; + tw = Gv_GetVarX(*insptr++); + VM_CONDITIONAL(tw || *insptr); + continue; + + case CON_IFVARBOTH: + insptr++; + tw = Gv_GetVarX(*insptr++); + VM_CONDITIONAL(tw && *insptr); + continue; + + case CON_IFRND: VM_CONDITIONAL(rnd(*(++insptr))); continue; + + case CON_IFVARG: + insptr++; + tw = Gv_GetVarX(*insptr++); + VM_CONDITIONAL(tw > *insptr); + continue; + + case CON_IFVARGE: + insptr++; + tw = Gv_GetVarX(*insptr++); + VM_CONDITIONAL(tw >= *insptr); + continue; + + case CON_IFVARL: + insptr++; + tw = Gv_GetVarX(*insptr++); + VM_CONDITIONAL(tw < *insptr); + continue; + + case CON_IFVARLE: + insptr++; + tw = Gv_GetVarX(*insptr++); + VM_CONDITIONAL(tw <= *insptr); + continue; + + case CON_IFVARA: + insptr++; + tw = Gv_GetVarX(*insptr++); + VM_CONDITIONAL((uint32_t)tw > (uint32_t)*insptr); + continue; + + case CON_IFVARAE: + insptr++; + tw = Gv_GetVarX(*insptr++); + VM_CONDITIONAL((uint32_t)tw >= (uint32_t)*insptr); + continue; + + case CON_IFVARB: + insptr++; + tw = Gv_GetVarX(*insptr++); + VM_CONDITIONAL((uint32_t)tw < (uint32_t)*insptr); + continue; + + case CON_IFVARBE: + insptr++; + tw = Gv_GetVarX(*insptr++); + VM_CONDITIONAL((uint32_t)tw <= (uint32_t)*insptr); + continue; + + case CON_MODVAR: + insptr++; + if (EDUKE32_PREDICT_FALSE(*(insptr + 1) == 0)) + { + CON_CRITICALERRPRINTF("mod by zero!\n"); + insptr += 2; + continue; } -#define CHECK(x) \ - if (x >= 0 && sprite[x].picnum == vm.pSprite->picnum) \ - { \ - VM_CONDITIONAL(0); \ - continue; \ - } -#define CHECK2(x) \ - do \ - { \ - vm.pSprite->ang += x; \ - tw = A_CheckHitSprite(vm.spriteNum, &temphit); \ - vm.pSprite->ang -= x; \ - } while (0) + Gv_ModVar(*insptr, *(insptr + 1)); + insptr += 2; + continue; - if (tw > dist) + case CON_ANDVAR: + insptr++; + Gv_AndVar(*insptr, *(insptr + 1)); + insptr += 2; + continue; + + case CON_ORVAR: + insptr++; + Gv_OrVar(*insptr, *(insptr + 1)); + insptr += 2; + continue; + + case CON_XORVAR: + insptr++; + Gv_XorVar(*insptr, *(insptr + 1)); + insptr += 2; + continue; + + case CON_ANDVARVAR: + insptr++; + tw = *insptr++; + Gv_AndVar(tw, Gv_GetVarX(*insptr++)); + continue; + + case CON_XORVARVAR: + insptr++; + tw = *insptr++; + Gv_XorVar(tw, Gv_GetVarX(*insptr++)); + continue; + + case CON_ORVARVAR: + insptr++; + tw = *insptr++; + Gv_OrVar(tw, Gv_GetVarX(*insptr++)); + continue; + + case CON_SHIFTVARL: + insptr++; + Gv_ShiftVarL(*insptr, *(insptr + 1)); + insptr += 2; + continue; + + case CON_SHIFTVARR: + insptr++; + Gv_ShiftVarR(*insptr, *(insptr + 1)); + insptr += 2; + continue; + + case CON_SHIFTVARVARL: + insptr++; + tw = *insptr++; + Gv_ShiftVarL(tw, Gv_GetVarX(*insptr++)); + continue; + + case CON_SHIFTVARVARR: + insptr++; + tw = *insptr++; + Gv_ShiftVarR(tw, Gv_GetVarX(*insptr++)); + continue; + + case CON_MODVARVAR: + insptr++; { - CHECK(temphit); - CHECK2(angDiff); + tw = *insptr++; + + int const nValue = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE(!nValue)) + { + CON_CRITICALERRPRINTF("mod by zero!\n"); + continue; + } + + Gv_ModVar(tw, nValue); + continue; + } + + case CON_REDEFINEQUOTE: + insptr++; + { + int const strIndex = *insptr++; + int const XstrIndex = *insptr++; + + if (EDUKE32_PREDICT_FALSE((apStrings[strIndex] == NULL || apXStrings[XstrIndex] == NULL))) + { + CON_ERRPRINTF("invalid source quote %d or destination quote %d\n", XstrIndex, strIndex); + break; + } + Bstrcpy(apStrings[strIndex], apXStrings[XstrIndex]); + continue; + } + + case CON_GETTHISPROJECTILE: + insptr++; + { + tw = *insptr++; + int const spriteNum = (tw != g_thisActorVarID) ? Gv_GetVarX(tw) : vm.spriteNum; + int const labelNum = *insptr++; + + Gv_SetVarX(*insptr++, VM_GetActiveProjectile(spriteNum, labelNum)); + continue; + } + + case CON_SETTHISPROJECTILE: + insptr++; + { + tw = *insptr++; + int const spriteNum = (tw != g_thisActorVarID) ? Gv_GetVarX(tw) : vm.spriteNum; + int const labelNum = *insptr++; + + VM_SetActiveProjectile(spriteNum, labelNum, Gv_GetVarX(*insptr++)); + continue; + } + + case CON_IFCANSHOOTTARGET: + { + if (vm.playerDist > 1024) + { + int16_t temphit; + + if ((tw = A_CheckHitSprite(vm.spriteNum, &temphit)) == (1 << 30)) + { + VM_CONDITIONAL(1); + continue; + } + + int dist = 768; + int angDiff = 16; + + if (A_CheckEnemySprite(vm.pSprite) && vm.pSprite->xrepeat > 56) + { + dist = 3084; + angDiff = 48; + } + +#define CHECK(x) \ + if (x >= 0 && sprite[x].picnum == vm.pSprite->picnum) \ + { \ + VM_CONDITIONAL(0); \ + continue; \ + } +#define CHECK2(x) \ + do \ + { \ + vm.pSprite->ang += x; \ + tw = A_CheckHitSprite(vm.spriteNum, &temphit); \ + vm.pSprite->ang -= x; \ + } while (0) if (tw > dist) { CHECK(temphit); - CHECK2(-angDiff); + CHECK2(angDiff); - if (tw > 768) + if (tw > dist) { CHECK(temphit); - VM_CONDITIONAL(1); - continue; + CHECK2(-angDiff); + + if (tw > 768) + { + CHECK(temphit); + VM_CONDITIONAL(1); + continue; + } } } } + VM_CONDITIONAL(1); } - VM_CONDITIONAL(1); - } - continue; + continue; - case CON_IFCANSEETARGET: - tw = cansee(vm.pSprite->x, vm.pSprite->y, vm.pSprite->z-((krand()&41)<<8), - vm.pSprite->sectnum, pPlayer->pos.x, pPlayer->pos.y, - pPlayer->pos.z/*-((krand()&41)<<8)*/, sprite[pPlayer->i].sectnum); - VM_CONDITIONAL(tw); - if (tw) vm.pActor->timetosleep = SLEEPTIME; - continue; + case CON_IFCANSEETARGET: + tw = cansee(vm.pSprite->x, vm.pSprite->y, vm.pSprite->z - ((krand() & 41) << 8), vm.pSprite->sectnum, pPlayer->pos.x, pPlayer->pos.y, + pPlayer->pos.z /*-((krand()&41)<<8)*/, sprite[pPlayer->i].sectnum); + VM_CONDITIONAL(tw); + if (tw) + vm.pActor->timetosleep = SLEEPTIME; + continue; - case CON_IFACTORNOTSTAYPUT: - VM_CONDITIONAL(vm.pActor->actorstayput == -1); - continue; + case CON_IFACTORNOTSTAYPUT: VM_CONDITIONAL(vm.pActor->actorstayput == -1); continue; - case CON_IFCANSEE: - { - uspritetype *pSprite = (uspritetype *)&sprite[pPlayer->i]; - - // select sprite for monster to target - // if holoduke is on, let them target holoduke first. - // -#ifndef EDUKE32_STANDALONE - if (pPlayer->holoduke_on >= 0) + case CON_IFCANSEE: { - pSprite = (uspritetype *)&sprite[pPlayer->holoduke_on]; - tw = cansee(vm.pSprite->x,vm.pSprite->y,vm.pSprite->z-(krand()&(ZOFFSET5-1)),vm.pSprite->sectnum, - pSprite->x,pSprite->y,pSprite->z,pSprite->sectnum); + uspritetype *pSprite = (uspritetype *)&sprite[pPlayer->i]; + +// select sprite for monster to target +// if holoduke is on, let them target holoduke first. +// +#ifndef EDUKE32_STANDALONE + if (pPlayer->holoduke_on >= 0) + { + pSprite = (uspritetype *)&sprite[pPlayer->holoduke_on]; + tw = cansee(vm.pSprite->x, vm.pSprite->y, vm.pSprite->z - (krand() & (ZOFFSET5 - 1)), vm.pSprite->sectnum, pSprite->x, pSprite->y, + pSprite->z, pSprite->sectnum); + + if (tw == 0) + { + // they can't see player's holoduke + // check for player... + pSprite = (uspritetype *)&sprite[pPlayer->i]; + } + } +#endif + // can they see player, (or player's holoduke) + tw = cansee(vm.pSprite->x, vm.pSprite->y, vm.pSprite->z - (krand() & ((47 << 8))), vm.pSprite->sectnum, pSprite->x, pSprite->y, + pSprite->z - (24 << 8), pSprite->sectnum); if (tw == 0) { - // they can't see player's holoduke - // check for player... - pSprite = (uspritetype *)&sprite[pPlayer->i]; + // search around for target player + + // also modifies 'target' x&y if found.. + + tw = 1; + if (A_FurthestVisiblePoint(vm.spriteNum, pSprite, &vm.pActor->lastv) == -1) + tw = 0; } - } -#endif - // can they see player, (or player's holoduke) - tw = cansee(vm.pSprite->x,vm.pSprite->y,vm.pSprite->z-(krand()&((47<<8))),vm.pSprite->sectnum, - pSprite->x,pSprite->y,pSprite->z-(24<<8),pSprite->sectnum); - - if (tw == 0) - { - // search around for target player - - // also modifies 'target' x&y if found.. - - tw = 1; - if (A_FurthestVisiblePoint(vm.spriteNum,pSprite,&vm.pActor->lastv) == -1) - tw = 0; - } - else - { - // else, they did see it. - // save where we were looking... - vm.pActor->lastv.x = pSprite->x; - vm.pActor->lastv.y = pSprite->y; - } - - if (tw && (vm.pSprite->statnum == STAT_ACTOR || vm.pSprite->statnum == STAT_STANDABLE)) - vm.pActor->timetosleep = SLEEPTIME; - - VM_CONDITIONAL(tw); - continue; - } - - case CON_IFHITWEAPON: - VM_CONDITIONAL(A_IncurDamage(vm.spriteNum) >= 0); - continue; - - case CON_IFSQUISHED: - VM_CONDITIONAL(VM_CheckSquished()); - continue; - - case CON_IFDEAD: - VM_CONDITIONAL(vm.pSprite->extra <= 0); - continue; - - case CON_AI: - insptr++; - //Following changed to use pointersizes - AC_AI_ID(vm.pData) = *insptr++; // Ai - AC_ACTION_ID(vm.pData) = *(apScript + AC_AI_ID(vm.pData)); // Action - - // NOTE: "if" check added in r1155. It used to be a pointer though. - if (AC_AI_ID(vm.pData)) - AC_MOVE_ID(vm.pData) = *(apScript + AC_AI_ID(vm.pData) + 1); // move - - vm.pSprite->hitag = *(apScript + AC_AI_ID(vm.pData) + 2); // move flags - - AC_COUNT(vm.pData) = 0; - AC_ACTION_COUNT(vm.pData) = 0; - AC_CURFRAME(vm.pData) = 0; - - if (!A_CheckEnemySprite(vm.pSprite) || vm.pSprite->extra > 0) // hack - if (vm.pSprite->hitag&random_angle) - vm.pSprite->ang = krand()&2047; - continue; - - case CON_ACTION: - insptr++; - AC_ACTION_COUNT(vm.pData) = 0; - AC_CURFRAME(vm.pData) = 0; - AC_ACTION_ID(vm.pData) = *insptr++; - continue; - - case CON_IFPLAYERSL: - VM_CONDITIONAL(numplayers < *(++insptr)); - continue; - - case CON_IFPDISTL: - VM_CONDITIONAL(vm.playerDist < *(++insptr)); - if (vm.playerDist > MAXSLEEPDIST && vm.pActor->timetosleep == 0) - vm.pActor->timetosleep = SLEEPTIME; - continue; - - case CON_IFPDISTG: - VM_CONDITIONAL(vm.playerDist > *(++insptr)); - if (vm.playerDist > MAXSLEEPDIST && vm.pActor->timetosleep == 0) - vm.pActor->timetosleep = SLEEPTIME; - continue; - - case CON_ADDSTRENGTH: - insptr++; - vm.pSprite->extra += *insptr++; - continue; - - case CON_STRENGTH: - insptr++; - vm.pSprite->extra = *insptr++; - continue; - - case CON_IFGOTWEAPONCE: - insptr++; - - if ((g_gametypeFlags[ud.coop]&GAMETYPE_WEAPSTAY) && (g_netServer || ud.multimode > 1)) - { - if (*insptr == 0) + else { - int j = 0; - for (; j < pPlayer->weapreccnt; ++j) - if (pPlayer->weaprecs[j] == vm.pSprite->picnum) - break; - - VM_CONDITIONAL(j < pPlayer->weapreccnt && vm.pSprite->owner == vm.spriteNum); - continue; + // else, they did see it. + // save where we were looking... + vm.pActor->lastv.x = pSprite->x; + vm.pActor->lastv.y = pSprite->y; } - else if (pPlayer->weapreccnt < MAX_WEAPONS) - { - pPlayer->weaprecs[pPlayer->weapreccnt++] = vm.pSprite->picnum; - VM_CONDITIONAL(vm.pSprite->owner == vm.spriteNum); - continue; - } - } - VM_CONDITIONAL(0); - continue; - case CON_GETLASTPAL: - insptr++; - if (vm.pSprite->picnum == APLAYER) - vm.pSprite->pal = g_player[P_GetP(vm.pSprite)].ps->palookup; - else - { - if (vm.pSprite->pal == 1 && vm.pSprite->extra == 0) // hack for frozen - vm.pSprite->extra++; - vm.pSprite->pal = vm.pActor->tempang; - } - vm.pActor->tempang = 0; - continue; + if (tw && (vm.pSprite->statnum == STAT_ACTOR || vm.pSprite->statnum == STAT_STANDABLE)) + vm.pActor->timetosleep = SLEEPTIME; - case CON_TOSSWEAPON: - insptr++; - // NOTE: assumes that current actor is APLAYER - P_DropWeapon(P_GetP(vm.pSprite)); - continue; - - case CON_MIKESND: - insptr++; - if (EDUKE32_PREDICT_FALSE(((unsigned)vm.pSprite->yvel >= MAXSOUNDS))) - { - CON_ERRPRINTF("invalid sound %d\n", vm.pUSprite->yvel); - continue; - } - if (!S_CheckSoundPlaying(vm.spriteNum,vm.pSprite->yvel)) - A_PlaySound(vm.pSprite->yvel,vm.spriteNum); - continue; - - case CON_PKICK: - insptr++; - - if ((g_netServer || ud.multimode > 1) && vm.pSprite->picnum == APLAYER) - { - if (g_player[otherp].ps->quick_kick == 0) - g_player[otherp].ps->quick_kick = 14; - } - else if (vm.pSprite->picnum != APLAYER && pPlayer->quick_kick == 0) - pPlayer->quick_kick = 14; - continue; - - case CON_SIZETO: - insptr++; - - tw = (*insptr++ - vm.pSprite->xrepeat)<<1; - vm.pSprite->xrepeat += ksgn(tw); - - if ((vm.pSprite->picnum == APLAYER && vm.pSprite->yrepeat < 36) || *insptr < vm.pSprite->yrepeat || - ((vm.pSprite->yrepeat*(tilesiz[vm.pSprite->picnum].y+8))<<2) < (vm.pActor->floorz - vm.pActor->ceilingz)) - { - tw = ((*insptr)-vm.pSprite->yrepeat)<<1; - if (klabs(tw)) vm.pSprite->yrepeat += ksgn(tw); - } - - insptr++; - - continue; - - case CON_SIZEAT: - insptr++; - vm.pSprite->xrepeat = (uint8_t)*insptr++; - vm.pSprite->yrepeat = (uint8_t)*insptr++; - continue; - - case CON_SOUNDONCE: - if (EDUKE32_PREDICT_FALSE((unsigned)*(++insptr) >= MAXSOUNDS)) - { - CON_ERRPRINTF("invalid sound %d\n", (int32_t)*insptr++); + VM_CONDITIONAL(tw); continue; } - if (!S_CheckSoundPlaying(vm.spriteNum, *insptr++)) - A_PlaySound(*(insptr-1),vm.spriteNum); + case CON_IFHITWEAPON: VM_CONDITIONAL(A_IncurDamage(vm.spriteNum) >= 0); continue; - continue; + case CON_IFSQUISHED: VM_CONDITIONAL(VM_CheckSquished()); continue; - case CON_IFACTORSOUND: - insptr++; - { - int const spriteNum = Gv_GetVarX(*insptr++); - int const soundNum = Gv_GetVarX(*insptr++); + case CON_IFDEAD: VM_CONDITIONAL(vm.pSprite->extra <= 0); continue; - if (EDUKE32_PREDICT_FALSE((unsigned)soundNum >= MAXSOUNDS)) + case CON_AI: + insptr++; + // Following changed to use pointersizes + AC_AI_ID(vm.pData) = *insptr++; // Ai + AC_ACTION_ID(vm.pData) = *(apScript + AC_AI_ID(vm.pData)); // Action + + // NOTE: "if" check added in r1155. It used to be a pointer though. + if (AC_AI_ID(vm.pData)) + AC_MOVE_ID(vm.pData) = *(apScript + AC_AI_ID(vm.pData) + 1); // move + + vm.pSprite->hitag = *(apScript + AC_AI_ID(vm.pData) + 2); // move flags + + AC_COUNT(vm.pData) = 0; + AC_ACTION_COUNT(vm.pData) = 0; + AC_CURFRAME(vm.pData) = 0; + + if (!A_CheckEnemySprite(vm.pSprite) || vm.pSprite->extra > 0) // hack + if (vm.pSprite->hitag & random_angle) + vm.pSprite->ang = krand() & 2047; + continue; + + case CON_ACTION: + insptr++; + AC_ACTION_COUNT(vm.pData) = 0; + AC_CURFRAME(vm.pData) = 0; + AC_ACTION_ID(vm.pData) = *insptr++; + continue; + + case CON_IFPLAYERSL: VM_CONDITIONAL(numplayers < *(++insptr)); continue; + + case CON_IFPDISTL: + VM_CONDITIONAL(vm.playerDist < *(++insptr)); + if (vm.playerDist > MAXSLEEPDIST && vm.pActor->timetosleep == 0) + vm.pActor->timetosleep = SLEEPTIME; + continue; + + case CON_IFPDISTG: + VM_CONDITIONAL(vm.playerDist > *(++insptr)); + if (vm.playerDist > MAXSLEEPDIST && vm.pActor->timetosleep == 0) + vm.pActor->timetosleep = SLEEPTIME; + continue; + + case CON_ADDSTRENGTH: + insptr++; + vm.pSprite->extra += *insptr++; + continue; + + case CON_STRENGTH: + insptr++; + vm.pSprite->extra = *insptr++; + continue; + + case CON_IFGOTWEAPONCE: + insptr++; + + if ((g_gametypeFlags[ud.coop] & GAMETYPE_WEAPSTAY) && (g_netServer || ud.multimode > 1)) { - CON_ERRPRINTF("invalid sound %d\n", soundNum); + if (*insptr == 0) + { + int j = 0; + for (; j < pPlayer->weapreccnt; ++j) + if (pPlayer->weaprecs[j] == vm.pSprite->picnum) + break; + + VM_CONDITIONAL(j < pPlayer->weapreccnt && vm.pSprite->owner == vm.spriteNum); + continue; + } + else if (pPlayer->weapreccnt < MAX_WEAPONS) + { + pPlayer->weaprecs[pPlayer->weapreccnt++] = vm.pSprite->picnum; + VM_CONDITIONAL(vm.pSprite->owner == vm.spriteNum); + continue; + } + } + VM_CONDITIONAL(0); + continue; + + case CON_GETLASTPAL: + insptr++; + if (vm.pSprite->picnum == APLAYER) + vm.pSprite->pal = g_player[P_GetP(vm.pSprite)].ps->palookup; + else + { + if (vm.pSprite->pal == 1 && vm.pSprite->extra == 0) // hack for frozen + vm.pSprite->extra++; + vm.pSprite->pal = vm.pActor->tempang; + } + vm.pActor->tempang = 0; + continue; + + case CON_TOSSWEAPON: + insptr++; + // NOTE: assumes that current actor is APLAYER + P_DropWeapon(P_GetP(vm.pSprite)); + continue; + + case CON_MIKESND: + insptr++; + if (EDUKE32_PREDICT_FALSE(((unsigned)vm.pSprite->yvel >= MAXSOUNDS))) + { + CON_ERRPRINTF("invalid sound %d\n", vm.pUSprite->yvel); + continue; + } + if (!S_CheckSoundPlaying(vm.spriteNum, vm.pSprite->yvel)) + A_PlaySound(vm.pSprite->yvel, vm.spriteNum); + continue; + + case CON_PKICK: + insptr++; + + if ((g_netServer || ud.multimode > 1) && vm.pSprite->picnum == APLAYER) + { + if (g_player[otherp].ps->quick_kick == 0) + g_player[otherp].ps->quick_kick = 14; + } + else if (vm.pSprite->picnum != APLAYER && pPlayer->quick_kick == 0) + pPlayer->quick_kick = 14; + continue; + + case CON_SIZETO: + insptr++; + + tw = (*insptr++ - vm.pSprite->xrepeat) << 1; + vm.pSprite->xrepeat += ksgn(tw); + + if ((vm.pSprite->picnum == APLAYER && vm.pSprite->yrepeat < 36) || *insptr < vm.pSprite->yrepeat + || ((vm.pSprite->yrepeat * (tilesiz[vm.pSprite->picnum].y + 8)) << 2) < (vm.pActor->floorz - vm.pActor->ceilingz)) + { + tw = ((*insptr) - vm.pSprite->yrepeat) << 1; + if (klabs(tw)) + vm.pSprite->yrepeat += ksgn(tw); + } + + insptr++; + + continue; + + case CON_SIZEAT: + insptr++; + vm.pSprite->xrepeat = (uint8_t)*insptr++; + vm.pSprite->yrepeat = (uint8_t)*insptr++; + continue; + + case CON_SOUNDONCE: + if (EDUKE32_PREDICT_FALSE((unsigned)*(++insptr) >= MAXSOUNDS)) + { + CON_ERRPRINTF("invalid sound %d\n", (int32_t)*insptr++); + continue; + } + + if (!S_CheckSoundPlaying(vm.spriteNum, *insptr++)) + A_PlaySound(*(insptr - 1), vm.spriteNum); + + continue; + + case CON_IFACTORSOUND: + insptr++; + { + int const spriteNum = Gv_GetVarX(*insptr++); + int const soundNum = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)soundNum >= MAXSOUNDS)) + { + CON_ERRPRINTF("invalid sound %d\n", soundNum); + insptr++; + continue; + } + + insptr--; + VM_CONDITIONAL(A_CheckSoundPlaying(spriteNum, soundNum)); + } + continue; + + case CON_IFSOUND: + if (EDUKE32_PREDICT_FALSE((unsigned)*(++insptr) >= MAXSOUNDS)) + { + CON_ERRPRINTF("invalid sound %d\n", (int32_t)*insptr); insptr++; continue; } - - insptr--; - VM_CONDITIONAL(A_CheckSoundPlaying(spriteNum, soundNum)); - } - continue; - - case CON_IFSOUND: - if (EDUKE32_PREDICT_FALSE((unsigned)*(++insptr) >= MAXSOUNDS)) - { - CON_ERRPRINTF("invalid sound %d\n", (int32_t)*insptr); - insptr++; + VM_CONDITIONAL(S_CheckSoundPlaying(vm.spriteNum, *insptr)); + // VM_DoConditional(SoundOwner[*insptr][0].ow == vm.spriteNum); continue; - } - VM_CONDITIONAL(S_CheckSoundPlaying(vm.spriteNum,*insptr)); - // VM_DoConditional(SoundOwner[*insptr][0].ow == vm.spriteNum); - continue; - case CON_STOPSOUND: - if (EDUKE32_PREDICT_FALSE((unsigned)*(++insptr) >= MAXSOUNDS)) - { - CON_ERRPRINTF("invalid sound %d\n", (int32_t)*insptr); - insptr++; - continue; - } - if (S_CheckSoundPlaying(vm.spriteNum,*insptr)) - S_StopSound((int16_t)*insptr); - insptr++; - continue; - - case CON_STOPACTORSOUND: - insptr++; - { - int const spriteNum = Gv_GetVarX(*insptr++); - int const soundNum = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)soundNum >= MAXSOUNDS)) + case CON_STOPSOUND: + if (EDUKE32_PREDICT_FALSE((unsigned)*(++insptr) >= MAXSOUNDS)) { - CON_ERRPRINTF("invalid sound %d\n", soundNum); + CON_ERRPRINTF("invalid sound %d\n", (int32_t)*insptr); + insptr++; continue; } - - if (A_CheckSoundPlaying(spriteNum, soundNum)) - S_StopEnvSound(soundNum, spriteNum); - - continue; - } - - case CON_ACTORSOUND: - insptr++; - { - int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.spriteNum; - int const soundNum = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)soundNum >= MAXSOUNDS)) - { - CON_ERRPRINTF("invalid sound %d\n", soundNum); - continue; - } - - A_PlaySound(soundNum, spriteNum); - - continue; - } - - case CON_SETACTORSOUNDPITCH: - insptr++; - { - int const spriteNum = Gv_GetVarX(*insptr++); - int const soundNum = Gv_GetVarX(*insptr++); - int const newPitch = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)soundNum>=MAXSOUNDS)) - { - CON_ERRPRINTF("invalid sound %d\n", soundNum); - continue; - } - - S_ChangeSoundPitch(soundNum, spriteNum, newPitch); - - continue; - } - - case CON_GLOBALSOUND: - if (EDUKE32_PREDICT_FALSE((unsigned)*(++insptr) >= MAXSOUNDS)) - { - CON_ERRPRINTF("invalid sound %d\n", (int32_t)*insptr); + if (S_CheckSoundPlaying(vm.spriteNum, *insptr)) + S_StopSound((int16_t)*insptr); insptr++; continue; - } - if (vm.playerNum == screenpeek || (g_gametypeFlags[ud.coop]&GAMETYPE_COOPSOUND) -#ifdef SPLITSCREEN_MOD_HACKS - || (g_fakeMultiMode==2) -#endif - ) - A_PlaySound(*insptr,g_player[screenpeek].ps->i); - insptr++; - continue; - case CON_SOUND: - if (EDUKE32_PREDICT_FALSE((unsigned)*(++insptr) >= MAXSOUNDS)) - { - CON_ERRPRINTF("invalid sound %d\n", (int32_t)*insptr); + case CON_STOPACTORSOUND: insptr++; - continue; - } - A_PlaySound(*insptr++,vm.spriteNum); - continue; - - case CON_TIP: - insptr++; - pPlayer->tipincs = GAMETICSPERSEC; - continue; - - case CON_FALL: - insptr++; - VM_Fall(vm.spriteNum, vm.pSprite); - continue; - - case CON_RETURN: - vm.flags |= VM_RETURN; - case CON_ENDA: - case CON_BREAK: - case CON_ENDS: - return; - case CON_NULLOP: - insptr++; - continue; - - case CON_ADDAMMO: - insptr++; - { - int const weaponNum = *insptr++; - int const addAmount = *insptr++; - - VM_AddAmmo(pPlayer, weaponNum, addAmount); - - continue; - } - - case CON_MONEY: - insptr++; - A_SpawnMultiple(vm.spriteNum, MONEY, *insptr++); - continue; - - case CON_MAIL: - insptr++; - A_SpawnMultiple(vm.spriteNum, MAIL, *insptr++); - continue; - - case CON_SLEEPTIME: - insptr++; - vm.pActor->timetosleep = (int16_t)*insptr++; - continue; - - case CON_PAPER: - insptr++; - A_SpawnMultiple(vm.spriteNum, PAPER, *insptr++); - continue; - - case CON_ADDKILLS: - insptr++; - P_AddKills(pPlayer, *insptr++); - vm.pActor->actorstayput = -1; - continue; - - case CON_LOTSOFGLASS: - insptr++; - A_SpawnGlass(vm.spriteNum,*insptr++); - continue; - - case CON_SPAWNWALLGLASS: - insptr++; - { - int const wallNum = Gv_GetVarX(*insptr++); - int const numShards = Gv_GetVarX(*insptr++); - A_SpawnWallGlass(vm.spriteNum, wallNum, numShards); - } - continue; - - case CON_SPAWNWALLSTAINEDGLASS: - insptr++; - { - int const wallNum = Gv_GetVarX(*insptr++); - int const numShards = Gv_GetVarX(*insptr++); - A_SpawnRandomGlass(vm.spriteNum, wallNum, numShards); - } - continue; - - case CON_SPAWNCEILINGGLASS: - insptr++; - { - int const sectNum = Gv_GetVarX(*insptr++); - int const numShards = Gv_GetVarX(*insptr++); - A_SpawnCeilingGlass(vm.spriteNum, sectNum, numShards); - } - continue; - - case CON_KILLIT: - insptr++; - vm.flags |= VM_KILL; - return; - - case CON_ADDWEAPON: - insptr++; - { - int const weaponNum = *insptr++; - VM_AddWeapon(pPlayer, weaponNum, *insptr++); - continue; - } - - case CON_DEBUG: - insptr++; - buildprint(*insptr++, "\n"); - continue; - - case CON_ENDOFGAME: - case CON_ENDOFLEVEL: - insptr++; - pPlayer->timebeforeexit = *insptr++; - pPlayer->customexitsound = -1; - ud.eog = 1; - continue; - - case CON_ADDPHEALTH: - insptr++; - - { - if (pPlayer->newowner >= 0) - G_ClearCameraView(pPlayer); - - int newHealth = sprite[pPlayer->i].extra; - - if (vm.pSprite->picnum != ATOMICHEALTH) { - if (newHealth > pPlayer->max_player_health && *insptr > 0) + int const spriteNum = Gv_GetVarX(*insptr++); + int const soundNum = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)soundNum >= MAXSOUNDS)) { - insptr++; + CON_ERRPRINTF("invalid sound %d\n", soundNum); continue; } + + if (A_CheckSoundPlaying(spriteNum, soundNum)) + S_StopEnvSound(soundNum, spriteNum); + + continue; + } + + case CON_ACTORSOUND: + insptr++; + { + int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.spriteNum; + int const soundNum = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)soundNum >= MAXSOUNDS)) + { + CON_ERRPRINTF("invalid sound %d\n", soundNum); + continue; + } + + A_PlaySound(soundNum, spriteNum); + + continue; + } + + case CON_SETACTORSOUNDPITCH: + insptr++; + { + int const spriteNum = Gv_GetVarX(*insptr++); + int const soundNum = Gv_GetVarX(*insptr++); + int const newPitch = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)soundNum >= MAXSOUNDS)) + { + CON_ERRPRINTF("invalid sound %d\n", soundNum); + continue; + } + + S_ChangeSoundPitch(soundNum, spriteNum, newPitch); + + continue; + } + + case CON_GLOBALSOUND: + if (EDUKE32_PREDICT_FALSE((unsigned)*(++insptr) >= MAXSOUNDS)) + { + CON_ERRPRINTF("invalid sound %d\n", (int32_t)*insptr); + insptr++; + continue; + } + if (vm.playerNum == screenpeek || (g_gametypeFlags[ud.coop] & GAMETYPE_COOPSOUND) +#ifdef SPLITSCREEN_MOD_HACKS + || (g_fakeMultiMode == 2) +#endif + ) + A_PlaySound(*insptr, g_player[screenpeek].ps->i); + insptr++; + continue; + + case CON_SOUND: + if (EDUKE32_PREDICT_FALSE((unsigned)*(++insptr) >= MAXSOUNDS)) + { + CON_ERRPRINTF("invalid sound %d\n", (int32_t)*insptr); + insptr++; + continue; + } + A_PlaySound(*insptr++, vm.spriteNum); + continue; + + case CON_TIP: + insptr++; + pPlayer->tipincs = GAMETICSPERSEC; + continue; + + case CON_FALL: + insptr++; + VM_Fall(vm.spriteNum, vm.pSprite); + continue; + + case CON_NULLOP: insptr++; continue; + + case CON_ADDAMMO: + insptr++; + { + int const weaponNum = *insptr++; + int const addAmount = *insptr++; + + VM_AddAmmo(pPlayer, weaponNum, addAmount); + + continue; + } + + case CON_MONEY: + insptr++; + A_SpawnMultiple(vm.spriteNum, MONEY, *insptr++); + continue; + + case CON_MAIL: + insptr++; + A_SpawnMultiple(vm.spriteNum, MAIL, *insptr++); + continue; + + case CON_SLEEPTIME: + insptr++; + vm.pActor->timetosleep = (int16_t)*insptr++; + continue; + + case CON_PAPER: + insptr++; + A_SpawnMultiple(vm.spriteNum, PAPER, *insptr++); + continue; + + case CON_ADDKILLS: + insptr++; + P_AddKills(pPlayer, *insptr++); + vm.pActor->actorstayput = -1; + continue; + + case CON_LOTSOFGLASS: + insptr++; + A_SpawnGlass(vm.spriteNum, *insptr++); + continue; + + case CON_SPAWNWALLGLASS: + insptr++; + { + int const wallNum = Gv_GetVarX(*insptr++); + int const numShards = Gv_GetVarX(*insptr++); + A_SpawnWallGlass(vm.spriteNum, wallNum, numShards); + } + continue; + + case CON_SPAWNWALLSTAINEDGLASS: + insptr++; + { + int const wallNum = Gv_GetVarX(*insptr++); + int const numShards = Gv_GetVarX(*insptr++); + A_SpawnRandomGlass(vm.spriteNum, wallNum, numShards); + } + continue; + + case CON_SPAWNCEILINGGLASS: + insptr++; + { + int const sectNum = Gv_GetVarX(*insptr++); + int const numShards = Gv_GetVarX(*insptr++); + A_SpawnCeilingGlass(vm.spriteNum, sectNum, numShards); + } + continue; + + case CON_KILLIT: + insptr++; + vm.flags |= VM_KILL; + return; + + case CON_ADDWEAPON: + insptr++; + { + int const weaponNum = *insptr++; + VM_AddWeapon(pPlayer, weaponNum, *insptr++); + continue; + } + + case CON_DEBUG: + insptr++; + buildprint(*insptr++, "\n"); + continue; + + case CON_ENDOFGAME: + case CON_ENDOFLEVEL: + insptr++; + pPlayer->timebeforeexit = *insptr++; + pPlayer->customexitsound = -1; + ud.eog = 1; + continue; + + case CON_ADDPHEALTH: + insptr++; + + { + if (pPlayer->newowner >= 0) + G_ClearCameraView(pPlayer); + + int newHealth = sprite[pPlayer->i].extra; + + if (vm.pSprite->picnum != ATOMICHEALTH) + { + if (newHealth > pPlayer->max_player_health && *insptr > 0) + { + insptr++; + continue; + } + else + { + if (newHealth > 0) + newHealth += *insptr; + if (newHealth > pPlayer->max_player_health && *insptr > 0) + newHealth = pPlayer->max_player_health; + } + } else { if (newHealth > 0) newHealth += *insptr; - if (newHealth > pPlayer->max_player_health && *insptr > 0) - newHealth = pPlayer->max_player_health; + if (newHealth > (pPlayer->max_player_health << 1)) + newHealth = (pPlayer->max_player_health << 1); } - } - else - { - if (newHealth > 0) - newHealth += *insptr; - if (newHealth > (pPlayer->max_player_health<<1)) - newHealth = (pPlayer->max_player_health<<1); - } - if (newHealth < 0) newHealth = 0; + if (newHealth < 0) + newHealth = 0; - if (ud.god == 0) - { - if (*insptr > 0) + if (ud.god == 0) { - if ((newHealth - *insptr) < (pPlayer->max_player_health>>2) && - newHealth >= (pPlayer->max_player_health>>2)) - A_PlaySound(DUKE_GOTHEALTHATLOW,pPlayer->i); + if (*insptr > 0) + { + if ((newHealth - *insptr) < (pPlayer->max_player_health >> 2) && newHealth >= (pPlayer->max_player_health >> 2)) + A_PlaySound(DUKE_GOTHEALTHATLOW, pPlayer->i); - pPlayer->last_extra = newHealth; + pPlayer->last_extra = newHealth; + } + + sprite[pPlayer->i].extra = newHealth; + } + } + + insptr++; + continue; + + case CON_MOVE: + insptr++; + AC_COUNT(vm.pData) = 0; + AC_MOVE_ID(vm.pData) = *insptr++; + vm.pSprite->hitag = *insptr++; + if (A_CheckEnemySprite(vm.pSprite) && vm.pSprite->extra <= 0) // hack + continue; + if (vm.pSprite->hitag & random_angle) + vm.pSprite->ang = krand() & 2047; + continue; + + case CON_ADDWEAPONVAR: + insptr++; + { + int const weaponNum = Gv_GetVarX(*insptr++); + VM_AddWeapon(pPlayer, weaponNum, Gv_GetVarX(*insptr++)); + continue; + } + + case CON_SETASPECT: + insptr++; + { + int const xRange = Gv_GetVarX(*insptr++); + renderSetAspect(xRange, Gv_GetVarX(*insptr++)); + break; + } + + case CON_SSP: + insptr++; + { + int const spriteNum = Gv_GetVarX(*insptr++); + int const clipType = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES)) + { + CON_ERRPRINTF("invalid sprite %d\n", spriteNum); + break; + } + A_SetSprite(spriteNum, clipType); + break; + } + + case CON_ACTIVATEBYSECTOR: + insptr++; + { + int const sectNum = Gv_GetVarX(*insptr++); + int const spriteNum = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)sectNum >= (unsigned)numsectors)) + { + CON_ERRPRINTF("invalid sector %d\n", sectNum); + break; + } + G_ActivateBySector(sectNum, spriteNum); + break; + } + + case CON_OPERATESECTORS: + insptr++; + { + int const sectNum = Gv_GetVarX(*insptr++); + int const spriteNum = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)sectNum >= (unsigned)numsectors)) + { + CON_ERRPRINTF("invalid sector %d\n", sectNum); + break; + } + G_OperateSectors(sectNum, spriteNum); + break; + } + + case CON_OPERATEACTIVATORS: + insptr++; + { + int const nTag = Gv_GetVarX(*insptr++); + int const playerNum = (*insptr++ == g_thisActorVarID) ? vm.playerNum : Gv_GetVarX(*(insptr - 1)); + + if (EDUKE32_PREDICT_FALSE((unsigned)playerNum >= (unsigned)g_mostConcurrentPlayers)) + { + CON_ERRPRINTF("invalid player %d\n", playerNum); + break; + } + G_OperateActivators(nTag, playerNum); + break; + } + + + case CON_CANSEESPR: + insptr++; + { + int const nSprite1 = Gv_GetVarX(*insptr++); + int const nSprite2 = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)nSprite1 >= MAXSPRITES || (unsigned)nSprite2 >= MAXSPRITES)) + { + CON_ERRPRINTF("invalid sprite %d\n", (unsigned)nSprite1 >= MAXSPRITES ? nSprite1 : nSprite2); + insptr++; + continue; } - sprite[pPlayer->i].extra = newHealth; - } - } + int const nResult = cansee(sprite[nSprite1].x, sprite[nSprite1].y, sprite[nSprite1].z, sprite[nSprite1].sectnum, + sprite[nSprite2].x, sprite[nSprite2].y, sprite[nSprite2].z, sprite[nSprite2].sectnum); - insptr++; - continue; - - case CON_MOVE: - insptr++; - AC_COUNT(vm.pData) = 0; - AC_MOVE_ID(vm.pData) = *insptr++; - vm.pSprite->hitag = *insptr++; - if (A_CheckEnemySprite(vm.pSprite) && vm.pSprite->extra <= 0) // hack - continue; - if (vm.pSprite->hitag&random_angle) - vm.pSprite->ang = krand()&2047; - continue; - - case CON_ADDWEAPONVAR: - insptr++; - { - int const weaponNum = Gv_GetVarX(*insptr++); - VM_AddWeapon(pPlayer, weaponNum, Gv_GetVarX(*insptr++)); - continue; - } - - case CON_SETASPECT: - insptr++; - { - int const xRange = Gv_GetVarX(*insptr++); - renderSetAspect(xRange, Gv_GetVarX(*insptr++)); - break; - } - - case CON_SSP: - insptr++; - { - int const spriteNum = Gv_GetVarX(*insptr++); - int const clipType = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES)) - { - CON_ERRPRINTF("invalid sprite %d\n", spriteNum); - break; - } - A_SetSprite(spriteNum, clipType); - break; - } - - case CON_ACTIVATEBYSECTOR: - insptr++; - { - int const sectNum = Gv_GetVarX(*insptr++); - int const spriteNum = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)sectNum >= (unsigned)numsectors)) - { - CON_ERRPRINTF("invalid sector %d\n", sectNum); - break; - } - G_ActivateBySector(sectNum, spriteNum); - break; - } - - case CON_OPERATESECTORS: - insptr++; - { - int const sectNum = Gv_GetVarX(*insptr++); - int const spriteNum = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)sectNum >= (unsigned)numsectors)) - { - CON_ERRPRINTF("invalid sector %d\n", sectNum); - break; - } - G_OperateSectors(sectNum, spriteNum); - break; - } - - case CON_OPERATEACTIVATORS: - insptr++; - { - int const nTag = Gv_GetVarX(*insptr++); - int const playerNum = (*insptr++ == g_thisActorVarID) ? vm.playerNum : Gv_GetVarX(*(insptr-1)); - - if (EDUKE32_PREDICT_FALSE((unsigned)playerNum >= (unsigned)g_mostConcurrentPlayers)) - { - CON_ERRPRINTF("invalid player %d\n", playerNum); - break; - } - G_OperateActivators(nTag, playerNum); - break; - } - - - case CON_CANSEESPR: - insptr++; - { - int const nSprite1 = Gv_GetVarX(*insptr++); - int const nSprite2 = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)nSprite1 >= MAXSPRITES || (unsigned)nSprite2 >= MAXSPRITES)) - { - CON_ERRPRINTF("invalid sprite %d\n", (unsigned)nSprite1 >= MAXSPRITES ? nSprite1 : nSprite2); - insptr++; + Gv_SetVarX(*insptr++, nResult); continue; } - int const nResult = cansee(sprite[nSprite1].x, sprite[nSprite1].y, sprite[nSprite1].z, sprite[nSprite1].sectnum, - sprite[nSprite2].x, sprite[nSprite2].y, sprite[nSprite2].z, sprite[nSprite2].sectnum); - - Gv_SetVarX(*insptr++, nResult); + case CON_OPERATERESPAWNS: + insptr++; + G_OperateRespawns(Gv_GetVarX(*insptr++)); continue; - } - case CON_OPERATERESPAWNS: - insptr++; - G_OperateRespawns(Gv_GetVarX(*insptr++)); - continue; + case CON_OPERATEMASTERSWITCHES: + insptr++; + G_OperateMasterSwitches(Gv_GetVarX(*insptr++)); + continue; - case CON_OPERATEMASTERSWITCHES: - insptr++; - G_OperateMasterSwitches(Gv_GetVarX(*insptr++)); - continue; + case CON_CHECKACTIVATORMOTION: + insptr++; + aGameVars[g_returnVarID].global = G_CheckActivatorMotion(Gv_GetVarX(*insptr++)); + continue; - case CON_CHECKACTIVATORMOTION: - insptr++; - aGameVars[g_returnVarID].global = G_CheckActivatorMotion(Gv_GetVarX(*insptr++)); - continue; + case CON_INSERTSPRITEQ: + insptr++; + A_AddToDeleteQueue(vm.spriteNum); + continue; - case CON_INSERTSPRITEQ: - insptr++; - A_AddToDeleteQueue(vm.spriteNum); - continue; - - case CON_QSTRLEN: - insptr++; - { - int const gameVar = *insptr++; - int const quoteNum = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE(apStrings[quoteNum] == NULL)) + case CON_QSTRLEN: + insptr++; { - CON_ERRPRINTF("null quote %d\n", quoteNum); - Gv_SetVarX(gameVar, -1); + int const gameVar = *insptr++; + int const quoteNum = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE(apStrings[quoteNum] == NULL)) + { + CON_ERRPRINTF("null quote %d\n", quoteNum); + Gv_SetVarX(gameVar, -1); + continue; + } + + Gv_SetVarX(gameVar, Bstrlen(apStrings[quoteNum])); continue; } - Gv_SetVarX(gameVar, Bstrlen(apStrings[quoteNum])); - continue; - } - - case CON_QSTRDIM: - insptr++; - { - int const widthVar = *insptr++; - int const heightVar = *insptr++; - - struct { - int32_t tileNum; - vec3_t vect; - int32_t blockAngle, quoteNum, orientation; - vec2_t offset, between; - int32_t f; - vec2_t bound[2]; - } v; - Gv_FillWithVars(v); - - if (EDUKE32_PREDICT_FALSE(v.tileNum < 0 || v.tileNum + 127 >= MAXTILES)) - CON_ERRPRINTF("invalid base tilenum %d\n", v.tileNum); - else if (EDUKE32_PREDICT_FALSE((unsigned)v.quoteNum >= MAXQUOTES || apStrings[v.quoteNum] == NULL)) - CON_ERRPRINTF("invalid quote %d\n", v.quoteNum); - else + case CON_QSTRDIM: + insptr++; { - vec2_t dim = G_ScreenTextSize(v.tileNum, v.vect.x, v.vect.y, v.vect.z, v.blockAngle, apStrings[v.quoteNum], - 2 | v.orientation, v.offset.x, v.offset.y, v.between.x, v.between.y, v.f, - v.bound[0].x, v.bound[0].y, v.bound[1].x, v.bound[1].y); + int const widthVar = *insptr++; + int const heightVar = *insptr++; - Gv_SetVarX(widthVar, dim.x); - Gv_SetVarX(heightVar, dim.y); - } - continue; - } + struct + { + int32_t tileNum; + vec3_t vect; + int32_t blockAngle, quoteNum, orientation; + vec2_t offset, between; + int32_t f; + vec2_t bound[2]; + } v; + Gv_FillWithVars(v); - case CON_HEADSPRITESTAT: - insptr++; - { - int const gameVar = *insptr++; - int const statNum = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)statNum > MAXSTATUS)) - { - CON_ERRPRINTF("invalid status list %d\n", statNum); - continue; - } - - Gv_SetVarX(gameVar, headspritestat[statNum]); - continue; - } - - case CON_PREVSPRITESTAT: - insptr++; - { - int const gameVar = *insptr++; - int const spriteNum = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES)) - { - CON_ERRPRINTF("invalid sprite %d\n", spriteNum); - continue; - } - - Gv_SetVarX(gameVar, prevspritestat[spriteNum]); - continue; - } - - case CON_NEXTSPRITESTAT: - insptr++; - { - int const gameVar = *insptr++; - int const spriteNum = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES)) - { - CON_ERRPRINTF("invalid sprite %d\n", spriteNum); - continue; - } - - Gv_SetVarX(gameVar, nextspritestat[spriteNum]); - continue; - } - - case CON_HEADSPRITESECT: - insptr++; - { - int const gameVar = *insptr++; - int const sectNum = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)sectNum >= (unsigned)numsectors)) - { - CON_ERRPRINTF("invalid sector %d\n", sectNum); - continue; - } - - Gv_SetVarX(gameVar, headspritesect[sectNum]); - continue; - } - - case CON_PREVSPRITESECT: - insptr++; - { - int const gameVar = *insptr++; - int const spriteNum = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES)) - { - CON_ERRPRINTF("invalid sprite %d\n", spriteNum); - continue; - } - - Gv_SetVarX(gameVar, prevspritesect[spriteNum]); - continue; - } - - case CON_NEXTSPRITESECT: - insptr++; - { - int const gameVar = *insptr++; - int const spriteNum = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES)) - { - CON_ERRPRINTF("invalid sprite %d\n", spriteNum); - continue; - } - - Gv_SetVarX(gameVar, nextspritesect[spriteNum]); - continue; - } - - case CON_GETKEYNAME: - insptr++; - { - int const quoteIndex = Gv_GetVarX(*insptr++); - int const gameFunc = Gv_GetVarX(*insptr++); - int const funcPos = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)quoteIndex >= MAXQUOTES || apStrings[quoteIndex] == NULL)) - { - CON_ERRPRINTF("invalid quote %d\n", quoteIndex); - continue; - } - else if (EDUKE32_PREDICT_FALSE((unsigned)gameFunc >= NUMGAMEFUNCTIONS)) - { - CON_ERRPRINTF("invalid function %d\n", gameFunc); - continue; - } - else - { - if (funcPos < 2) - Bstrcpy(tempbuf, KB_ScanCodeToString(ud.config.KeyboardKeys[gameFunc][funcPos])); + if (EDUKE32_PREDICT_FALSE(v.tileNum < 0 || v.tileNum + 127 >= MAXTILES)) + CON_ERRPRINTF("invalid base tilenum %d\n", v.tileNum); + else if (EDUKE32_PREDICT_FALSE((unsigned)v.quoteNum >= MAXQUOTES || apStrings[v.quoteNum] == NULL)) + CON_ERRPRINTF("invalid quote %d\n", v.quoteNum); else { - Bstrcpy(tempbuf, KB_ScanCodeToString(ud.config.KeyboardKeys[gameFunc][0])); + vec2_t dim = G_ScreenTextSize(v.tileNum, v.vect.x, v.vect.y, v.vect.z, v.blockAngle, apStrings[v.quoteNum], 2 | v.orientation, + v.offset.x, v.offset.y, v.between.x, v.between.y, v.f, v.bound[0].x, v.bound[0].y, v.bound[1].x, + v.bound[1].y); - if (!*tempbuf) - Bstrcpy(tempbuf, KB_ScanCodeToString(ud.config.KeyboardKeys[gameFunc][1])); + Gv_SetVarX(widthVar, dim.x); + Gv_SetVarX(heightVar, dim.y); } - } - - if (*tempbuf) - Bstrcpy(apStrings[quoteIndex], tempbuf); - - continue; - } - - case CON_QSUBSTR: - insptr++; - { - struct { - int32_t outputQuote, inputQuote, quotePos, quoteLength; - } v; - Gv_FillWithVars(v); - - if (EDUKE32_PREDICT_FALSE((unsigned)v.outputQuote >= MAXQUOTES || apStrings[v.outputQuote] == NULL - || (unsigned)v.inputQuote >= MAXQUOTES || apStrings[v.inputQuote] == NULL)) - { - CON_ERRPRINTF("invalid quote %d\n", apStrings[v.outputQuote] ? v.inputQuote : v.outputQuote); continue; } - if (EDUKE32_PREDICT_FALSE((unsigned)v.quotePos >= MAXQUOTELEN)) - { - CON_ERRPRINTF("invalid position %d\n", v.quotePos); - continue; - } - - if (EDUKE32_PREDICT_FALSE(v.quoteLength < 0)) - { - CON_ERRPRINTF("invalid length %d\n", v.quoteLength); - continue; - } - - char * pOutput = apStrings[v.outputQuote]; - char const *pInput = apStrings[v.inputQuote]; - - while (*pInput && v.quotePos--) pInput++; - while ((*pOutput = *pInput) && v.quoteLength--) - { - pOutput++; - pInput++; - } - *pOutput = '\0'; - - continue; - } - - case CON_QSTRCMP: - insptr++; - { - int const quote1 = Gv_GetVarX(*insptr++); - int const quote2 = Gv_GetVarX(*insptr++); - int const gameVar = *insptr++; - - if (EDUKE32_PREDICT_FALSE(apStrings[quote1] == NULL || apStrings[quote2] == NULL)) - { - CON_ERRPRINTF("null quote %d\n", apStrings[quote1] ? quote2 : quote1); - Gv_SetVarX(gameVar, -2); - continue; - } - - Gv_SetVarX(gameVar, strcmp(apStrings[quote1], apStrings[quote2])); - continue; - } - - case CON_GETPNAME: - case CON_QSTRNCAT: - case CON_QSTRCAT: - case CON_QSTRCPY: - case CON_QGETSYSSTR: - insptr++; - { - int32_t i = Gv_GetVarX(*insptr++), j; - if (tw == CON_GETPNAME && *insptr == g_thisActorVarID) - { - j = vm.playerNum; - insptr++; - } - else j = Gv_GetVarX(*insptr++); - - switch (tw) - { - case CON_GETPNAME: - if (EDUKE32_PREDICT_FALSE((unsigned)i>=MAXQUOTES || apStrings[i] == NULL)) - { - CON_ERRPRINTF("invalid quote %d\n", i); - break; - } - if (g_player[j].user_name[0]) - Bstrcpy(apStrings[i],g_player[j].user_name); - else Bsprintf(apStrings[i],"%d",j); - break; - case CON_QGETSYSSTR: - if (EDUKE32_PREDICT_FALSE((unsigned)i>=MAXQUOTES || apStrings[i] == NULL)) - { - CON_ERRPRINTF("invalid quote %d\n", i); - break; - } - switch (j) - { - case STR_MAPNAME: - case STR_MAPFILENAME: - { - int32_t levelNum = ud.volume_number*MAXLEVELS + ud.level_number; - const char *pName; - - if (EDUKE32_PREDICT_FALSE((unsigned)levelNum >= ARRAY_SIZE(g_mapInfo))) - { - CON_ERRPRINTF("out of bounds map number (vol=%d, lev=%d)\n", - ud.volume_number, ud.level_number); - break; - } - - pName = j == STR_MAPNAME ? g_mapInfo[levelNum].name : g_mapInfo[levelNum].filename; - - if (EDUKE32_PREDICT_FALSE(pName == NULL)) - { - CON_ERRPRINTF("attempted access to %s of non-existent map (vol=%d, lev=%d)", - j==STR_MAPNAME ? "name" : "file name", - ud.volume_number, ud.level_number); - break; - } - - Bstrcpy(apStrings[i], j==STR_MAPNAME ? g_mapInfo[levelNum].name : g_mapInfo[levelNum].filename); - break; - } - case STR_PLAYERNAME: - if (EDUKE32_PREDICT_FALSE((unsigned)vm.playerNum >= (unsigned)g_mostConcurrentPlayers)) - { - CON_ERRPRINTF("invalid player %d\n", vm.playerNum); - break; - } - Bstrcpy(apStrings[i],g_player[vm.playerNum].user_name); - break; - case STR_VERSION: - Bsprintf(tempbuf,HEAD2 " %s",s_buildRev); - Bstrcpy(apStrings[i],tempbuf); - break; - case STR_GAMETYPE: - Bstrcpy(apStrings[i],g_gametypeNames[ud.coop]); - break; - case STR_VOLUMENAME: - if (EDUKE32_PREDICT_FALSE((unsigned)ud.volume_number >= MAXVOLUMES)) - { - CON_ERRPRINTF("invalid volume %d\n", ud.volume_number); - break; - } - Bstrcpy(apStrings[i],g_volumeNames[ud.volume_number]); - break; - case STR_YOURTIME: - Bstrcpy(apStrings[i],G_PrintYourTime()); - break; - case STR_PARTIME: - Bstrcpy(apStrings[i],G_PrintParTime()); - break; - case STR_DESIGNERTIME: - Bstrcpy(apStrings[i],G_PrintDesignerTime()); - break; - case STR_BESTTIME: - Bstrcpy(apStrings[i],G_PrintBestTime()); - break; - case STR_USERMAPFILENAME: - Bstrcpy(apStrings[i],boardfilename); - break; - default: - CON_ERRPRINTF("invalid string index %d or %d\n", i, j); - } - break; - case CON_QSTRCAT: - if (EDUKE32_PREDICT_FALSE(apStrings[i] == NULL || apStrings[j] == NULL)) goto nullquote; - Bstrncat(apStrings[i],apStrings[j],(MAXQUOTELEN-1)-Bstrlen(apStrings[i])); - break; - case CON_QSTRNCAT: - if (EDUKE32_PREDICT_FALSE(apStrings[i] == NULL || apStrings[j] == NULL)) goto nullquote; - Bstrncat(apStrings[i],apStrings[j],Gv_GetVarX(*insptr++)); - break; - case CON_QSTRCPY: - if (EDUKE32_PREDICT_FALSE(apStrings[i] == NULL || apStrings[j] == NULL)) goto nullquote; - if (i != j) - Bstrcpy(apStrings[i],apStrings[j]); - break; - default: -nullquote: - CON_ERRPRINTF("invalid quote %d\n", apStrings[i] ? j : i); - break; - } - continue; - } - - case CON_CHANGESPRITESECT: - insptr++; - { - int32_t const spriteNum = Gv_GetVarX(*insptr++); - int32_t sectNum = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES || (unsigned) sectNum >= MAXSECTORS)) - { - CON_ERRPRINTF("invalid parameters: %d, %d\n", spriteNum, sectNum); - continue; - } - - if (sprite[spriteNum].sectnum == sectNum) - continue; - - changespritesect(spriteNum, sectNum); - continue; - } - - case CON_CHANGESPRITESTAT: - insptr++; - { - int32_t const spriteNum = Gv_GetVarX(*insptr++); - int32_t statNum = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned) spriteNum >= MAXSPRITES || (unsigned) statNum >= MAXSECTORS)) - { - CON_ERRPRINTF("invalid parameters: %d, %d\n", spriteNum, statNum); - continue; - } - - if (sprite[spriteNum].statnum == statNum) - continue; - - /* initialize actor data when changing to an actor statnum because there's usually - garbage left over from being handled as a hard coded object */ - - if (sprite[spriteNum].statnum > STAT_ZOMBIEACTOR && (statNum == STAT_ACTOR || statNum == STAT_ZOMBIEACTOR)) - { - actor_t * const pActor = &actor[spriteNum]; - - Bmemset(&pActor->t_data, 0, sizeof pActor->t_data); - pActor->lastv.x = 0; - pActor->lastv.y = 0; - pActor->timetosleep = 0; - pActor->cgg = 0; - pActor->movflag = 0; - pActor->tempang = 0; - pActor->dispicnum = 0; - pActor->flags = 0; - sprite[spriteNum].hitag = 0; - - if (G_HaveActor(sprite[spriteNum].picnum)) - { - const intptr_t *actorptr = g_tile[sprite[spriteNum].picnum].execPtr; - // offsets - AC_ACTION_ID(pActor->t_data) = actorptr[1]; - AC_MOVE_ID(pActor->t_data) = actorptr[2]; - AC_MOVFLAGS(&sprite[spriteNum], &actor[spriteNum]) = actorptr[3]; // ai bits (movflags) - } - } - - changespritestat(spriteNum, statNum); - continue; - } - - case CON_STARTLEVEL: - insptr++; // skip command - { - // from 'level' cheat in game.c (about line 6250) - int const volumeNum = Gv_GetVarX(*insptr++); - int const levelNum = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)volumeNum >= MAXVOLUMES || (unsigned) levelNum >= MAXLEVELS)) - { - CON_ERRPRINTF("invalid parameters: %d, %d\n", volumeNum, levelNum); - continue; - } - - ud.m_volume_number = ud.volume_number = volumeNum; - ud.m_level_number = ud.level_number = levelNum; - //if (numplayers > 1 && g_netServer) - // Net_NewGame(volnume,levnume); - //else - { - g_player[myconnectindex].ps->gm |= MODE_EOL; - ud.display_bonus_screen = 0; - } // MODE_RESTART; - - continue; - } - - case CON_MYOSX: - case CON_MYOSPALX: - case CON_MYOS: - case CON_MYOSPAL: - insptr++; - { - struct { - vec2_t pos; - int32_t tilenum, shade, orientation; - } v; - Gv_FillWithVars(v); - - switch (tw) - { - case CON_MYOS: - VM_DrawTile(v.pos.x, v.pos.y, v.tilenum, v.shade, v.orientation); - break; - case CON_MYOSPAL: - VM_DrawTilePal(v.pos.x, v.pos.y, v.tilenum, v.shade, v.orientation, Gv_GetVarX(*insptr++)); - break; - case CON_MYOSX: - VM_DrawTileSmall(v.pos.x, v.pos.y, v.tilenum, v.shade, v.orientation); - break; - case CON_MYOSPALX: - VM_DrawTilePalSmall(v.pos.x, v.pos.y, v.tilenum, v.shade, v.orientation, Gv_GetVarX(*insptr++)); - break; - } - continue; - } - - case CON_SWITCH: - insptr++; - { - // command format: - // variable ID to check - // script offset to 'end' - // count of case statements - // script offset to default case (null if none) - // For each case: value, ptr to code - int32_t const lValue = Gv_GetVarX(*insptr++); - int32_t const lEnd = *insptr++; - int32_t const lCases = *insptr++; - - intptr_t const *const lpDefault = insptr++; - intptr_t const *const lpCases = insptr; - - int left = 0; - int right = lCases - 1; - - insptr += lCases << 1; - - do - { - int const lCheckCase = (left + right) >> 1; - - if (lpCases[lCheckCase << 1] > lValue) - right = lCheckCase - 1; - else if (lpCases[lCheckCase << 1] < lValue) - left = lCheckCase + 1; - else if (lpCases[lCheckCase << 1] == lValue) - { - // fake a 2-d Array - insptr = (intptr_t *)(lpCases[(lCheckCase << 1) + 1] + &apScript[0]); - VM_Execute(1); - goto matched; - } - - if (right - left < 0) - break; - } - while (1); - - if (*lpDefault) - { - insptr = (intptr_t *)(*lpDefault + &apScript[0]); - VM_Execute(1); - } - - matched: - insptr = (intptr_t *)(lEnd + (intptr_t)&apScript[0]); - - continue; - } - - case CON_ENDSWITCH: - insptr++; - case CON_ENDEVENT: - return; - - case CON_DISPLAYRAND: - insptr++; - Gv_SetVarX(*insptr++, system_15bit_rand()); - continue; - - case CON_DRAGPOINT: - insptr++; - { - int const wallNum = Gv_GetVarX(*insptr++); - vec2_t n; - Gv_FillWithVars(n); - - if (EDUKE32_PREDICT_FALSE((unsigned)wallNum >= (unsigned)numwalls)) - { - CON_ERRPRINTF("invalid wall %d\n", wallNum); - continue; - } - - dragpoint(wallNum, n.x, n.y, 0); - continue; - } - - case CON_LDIST: - case CON_DIST: - insptr++; - { - int const out = *insptr++; - vec2_t in; - Gv_FillWithVars(in); - - if (EDUKE32_PREDICT_FALSE((unsigned)in.x >= MAXSPRITES || (unsigned)in.y >= MAXSPRITES)) - { - CON_ERRPRINTF("invalid sprite %d, %d\n", in.x, in.y); - continue; - } - - Gv_SetVarX(out, (tw == CON_LDIST ? ldist : dist)(&sprite[in.x], &sprite[in.y])); - continue; - } - - case CON_GETANGLE: - case CON_GETINCANGLE: - insptr++; - { - int const out = *insptr++; - vec2_t in; - Gv_FillWithVars(in); - Gv_SetVarX(out, (tw == CON_GETANGLE ? getangle : G_GetAngleDelta)(in.x, in.y)); - continue; - } - - case CON_MULSCALE: - case CON_DIVSCALE: - insptr++; - { - int const out = *insptr++; - vec3_t in; - Gv_FillWithVars(in); - - if (tw == CON_MULSCALE) - Gv_SetVarX(out, mulscale(in.x, in.y, in.z)); - else - Gv_SetVarX(out, divscale(in.x, in.y, in.z)); - - continue; - } - - case CON_SCALEVAR: - insptr++; - { - int const out = *insptr++; - vec3_t in; - Gv_FillWithVars(in); - Gv_SetVarX(out, scale(in.x, in.y, in.z)); - continue; - } - - case CON_INITTIMER: - insptr++; - G_InitTimer(Gv_GetVarX(*insptr++)); - continue; - - case CON_NEXTSECTORNEIGHBORZ: - insptr++; - { - int32_t params[4]; - Gv_FillWithVars(params); - aGameVars[g_returnVarID].global = nextsectorneighborz(params[0], params[1], params[2], params[3]); - } - continue; - - case CON_MOVESECTOR: - insptr++; - A_MoveSector(Gv_GetVarX(*insptr++)); - continue; - - case CON_TIME: - insptr += 2; - continue; - - case CON_ESPAWNVAR: - case CON_EQSPAWNVAR: - case CON_QSPAWNVAR: - insptr++; - { - int const tileNum = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)vm.pSprite->sectnum >= (unsigned)numsectors)) - { - CON_ERRPRINTF("invalid sector %d\n", vm.pUSprite->sectnum); - continue; - } - - int const spriteNum = A_Spawn(vm.spriteNum, tileNum); - - switch (tw) - { - case CON_EQSPAWNVAR: - if (spriteNum != -1) - A_AddToDeleteQueue(spriteNum); - fallthrough__; - case CON_ESPAWNVAR: - aGameVars[g_returnVarID].global = spriteNum; - break; - case CON_QSPAWNVAR: - if (spriteNum != -1) - A_AddToDeleteQueue(spriteNum); - break; - } - continue; - } - - case CON_SHOOTVAR: - case CON_ESHOOTVAR: - insptr++; - { - int j = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)vm.pSprite->sectnum >= (unsigned)numsectors)) - { - CON_ERRPRINTF("invalid sector %d\n", vm.pUSprite->sectnum); - continue; - } - - j = A_Shoot(vm.spriteNum, j); - - if (tw == CON_ESHOOTVAR) - aGameVars[g_returnVarID].global = j; - - continue; - } - - case CON_EZSHOOTVAR: - case CON_ZSHOOTVAR: - insptr++; - { - int const zvel = (int16_t)Gv_GetVarX(*insptr++); - int j = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)vm.pSprite->sectnum >= (unsigned)numsectors)) - { - CON_ERRPRINTF("invalid sector %d\n", vm.pUSprite->sectnum); - continue; - } - - j = A_ShootWithZvel(vm.spriteNum, j, zvel); - - if (tw == CON_EZSHOOTVAR) - aGameVars[g_returnVarID].global = j; - - continue; - } - - case CON_CMENU: - insptr++; - Menu_Change(Gv_GetVarX(*insptr++)); - continue; - - case CON_SOUNDVAR: - case CON_STOPSOUNDVAR: - case CON_SOUNDONCEVAR: - case CON_GLOBALSOUNDVAR: - case CON_SCREENSOUND: - insptr++; - { - int const soundNum = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)soundNum>=MAXSOUNDS)) - { - CON_ERRPRINTF("invalid sound %d\n", soundNum); - continue; - } - - switch (tw) - { - case CON_SOUNDONCEVAR: // falls through to CON_SOUNDVAR - if (!S_CheckSoundPlaying(vm.spriteNum, soundNum)) - case CON_SOUNDVAR: - A_PlaySound((int16_t)soundNum, vm.spriteNum); - continue; - case CON_GLOBALSOUNDVAR: - A_PlaySound((int16_t)soundNum, g_player[screenpeek].ps->i); - continue; - case CON_STOPSOUNDVAR: - if (S_CheckSoundPlaying(vm.spriteNum, soundNum)) - S_StopSound((int16_t)soundNum); - continue; - case CON_SCREENSOUND: - A_PlaySound(soundNum, -1); - continue; - } - } - continue; - - case CON_STARTCUTSCENE: - case CON_IFCUTSCENE: - insptr++; - { - int const nQuote = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)nQuote >= MAXQUOTES || apStrings[nQuote] == NULL)) - { - CON_ERRPRINTF("invalid quote %d for anim!\n", nQuote); - continue; - } - - if (tw == CON_IFCUTSCENE) - { - insptr--; - VM_CONDITIONAL(g_animPtr == Anim_Find(apStrings[nQuote])); - continue; - } - - tw = pPlayer->palette; - I_ClearAllInput(); - Anim_Play(apStrings[nQuote]); - P_SetGamePalette(pPlayer, tw, 2 + 16); - continue; - } - - case CON_STARTSCREEN: - insptr++; - I_ClearAllInput(); - Screen_Play(); - continue; - - case CON_GUNIQHUDID: - insptr++; - { - tw = Gv_GetVarX(*insptr++); - if (EDUKE32_PREDICT_FALSE((unsigned)tw >= MAXUNIQHUDID - 1)) - CON_ERRPRINTF("invalid value %d\n", tw); - else - guniqhudid = tw; - - continue; - } - - case CON_SAVEGAMEVAR: - case CON_READGAMEVAR: - { - int32_t nValue = 0; - insptr++; - if (ud.config.scripthandle < 0) - { + case CON_HEADSPRITESTAT: insptr++; - continue; - } - switch (tw) - { - case CON_SAVEGAMEVAR: - nValue = Gv_GetVarX(*insptr); - SCRIPT_PutNumber(ud.config.scripthandle, "Gamevars", aGameVars[*insptr++].szLabel, nValue, FALSE, FALSE); - break; - case CON_READGAMEVAR: - SCRIPT_GetNumber(ud.config.scripthandle, "Gamevars", aGameVars[*insptr].szLabel, &nValue); - Gv_SetVarX(*insptr++, nValue); - break; - } - continue; - } - - case CON_SHOWVIEW: - case CON_SHOWVIEWUNBIASED: - case CON_SHOWVIEWQ16: - case CON_SHOWVIEWQ16UNBIASED: - insptr++; - { - struct { - vec3_t vec; - int32_t params[3]; - vec2_t scrn[2]; - } v; - Gv_FillWithVars(v); - - if (EDUKE32_PREDICT_FALSE(v.scrn[0].x < 0 || v.scrn[0].y < 0 || v.scrn[1].x >= 320 || v.scrn[1].y >= 200)) { - CON_ERRPRINTF("incorrect coordinates\n"); - continue; - } + int const gameVar = *insptr++; + int const statNum = Gv_GetVarX(*insptr++); - if (EDUKE32_PREDICT_FALSE((unsigned)v.params[2] >= (unsigned)numsectors)) - { - CON_ERRPRINTF("invalid sector %d\n", v.params[2]); - continue; - } - - if (tw != CON_SHOWVIEWQ16 && tw != CON_SHOWVIEWQ16UNBIASED) - { - v.params[0] <<= 16; - v.params[1] <<= 16; - } - - G_ShowView(v.vec, v.params[0], v.params[1], v.params[2], v.scrn[0].x, v.scrn[0].y, v.scrn[1].x, v.scrn[1].y, (tw != CON_SHOWVIEW && tw != CON_SHOWVIEWQ16)); - - continue; - } - - case CON_ROTATESPRITEA: - case CON_ROTATESPRITE16: - case CON_ROTATESPRITE: - insptr++; - { - struct { - vec3_t pos; - int32_t ang, tilenum, shade, pal, orientation; - } v; - Gv_FillWithVars(v); - - int32_t alpha = (tw == CON_ROTATESPRITEA) ? Gv_GetVarX(*insptr++) : 0; - - vec2_t bound[2]; - Gv_FillWithVars(bound); - - if (tw != CON_ROTATESPRITE16 && !(v.orientation&ROTATESPRITE_FULL16)) - { - v.pos.x <<= 16; - v.pos.y <<= 16; - } - - if (EDUKE32_PREDICT_FALSE((unsigned) v.tilenum >= MAXTILES)) - { - CON_ERRPRINTF("invalid tilenum %d\n", v.tilenum); - continue; - } - - int32_t blendidx = 0; - - NEG_ALPHA_TO_BLEND(alpha, blendidx, v.orientation); - - rotatesprite_(v.pos.x, v.pos.y, v.pos.z, v.ang, v.tilenum, v.shade, v.pal, 2 | (v.orientation & (ROTATESPRITE_MAX - 1)), - alpha, blendidx, bound[0].x, bound[0].y, bound[1].x, bound[1].y); - continue; - } - - case CON_GAMETEXT: - case CON_GAMETEXTZ: - insptr++; - { - struct { - int32_t tilenum; - vec2_t pos; - int32_t nQuote, shade, pal, orientation; - vec2_t bound[2]; - } v; - Gv_FillWithVars(v); - - int32_t const z = (tw == CON_GAMETEXTZ) ? Gv_GetVarX(*insptr++) : 65536; - - if (EDUKE32_PREDICT_FALSE(v.tilenum < 0 || v.tilenum + 127 >= MAXTILES)) - { - CON_ERRPRINTF("invalid base tilenum %d\n", v.tilenum); - continue; - } - - if (EDUKE32_PREDICT_FALSE((unsigned)v.nQuote >= MAXQUOTES || apStrings[v.nQuote] == NULL)) - { - CON_ERRPRINTF("invalid quote %d\n", v.nQuote); - continue; - } - - G_PrintGameText(v.tilenum, v.pos.x >> 1, v.pos.y, apStrings[v.nQuote], v.shade, v.pal, v.orientation & (ROTATESPRITE_MAX - 1), - v.bound[0].x, v.bound[0].y, v.bound[1].x, v.bound[1].y, z, 0); - continue; - } - - case CON_DIGITALNUMBER: - case CON_DIGITALNUMBERZ: - insptr++; - { - struct { - int32_t tilenum; - vec2_t pos; - int32_t nQuote, shade, pal, orientation; - vec2_t bound[2]; - } v; - Gv_FillWithVars(v); - - int32_t const nZoom = (tw == CON_DIGITALNUMBERZ) ? Gv_GetVarX(*insptr++) : 65536; - - // NOTE: '-' not taken into account, but we have rotatesprite() bound check now anyway - if (EDUKE32_PREDICT_FALSE(v.tilenum < 0 || v.tilenum+9 >= MAXTILES)) - { - CON_ERRPRINTF("invalid base tilenum %d\n", v.tilenum); - continue; - } - - G_DrawTXDigiNumZ(v.tilenum, v.pos.x, v.pos.y, v.nQuote, v.shade, v.pal, v.orientation & (ROTATESPRITE_MAX - 1), - v.bound[0].x, v.bound[0].y, v.bound[1].x, v.bound[1].y, nZoom); - continue; - } - - case CON_MINITEXT: - insptr++; - { - struct { - vec2_t pos; - int32_t nQuote, shade, pal; - } v; - Gv_FillWithVars(v); - - if (EDUKE32_PREDICT_FALSE((unsigned)v.nQuote >= MAXQUOTES || apStrings[v.nQuote] == NULL)) - { - CON_ERRPRINTF("invalid quote %d\n", v.nQuote); - continue; - } - - minitextshade(v.pos.x, v.pos.y, apStrings[v.nQuote], v.shade, v.pal, 2+8+16); - continue; - } - - case CON_SCREENTEXT: - insptr++; - { - struct { - int32_t tilenum; - vec3_t v; - int32_t blockangle, charangle, nQuote, shade, pal, orientation, alpha; - vec2_t spacing, between; - int32_t nFlags; - vec2_t bound[2]; - } v; - Gv_FillWithVars(v); - - if (EDUKE32_PREDICT_FALSE(v.tilenum < 0 || v.tilenum+127 >= MAXTILES)) - { - CON_ERRPRINTF("invalid base tilenum %d\n", v.tilenum); - continue; - } - - if (EDUKE32_PREDICT_FALSE((unsigned)v.nQuote >= MAXQUOTES || apStrings[v.nQuote] == NULL)) - { - CON_ERRPRINTF("invalid quote %d\n", v.nQuote); - continue; - } - - G_ScreenText(v.tilenum, v.v.x, v.v.y, v.v.z, v.blockangle, v.charangle, apStrings[v.nQuote], v.shade, v.pal, 2 | (v.orientation & (ROTATESPRITE_MAX - 1)), - v.alpha, v.spacing.x, v.spacing.y, v.between.x, v.between.y, v.nFlags, v.bound[0].x, v.bound[0].y, v.bound[1].x, v.bound[1].y); - continue; - } - - case CON_ANGOFF: - insptr++; - spriteext[vm.spriteNum].angoff=*insptr++; - continue; - - case CON_GETZRANGE: - insptr++; - { - struct { - vec3_t vect; - int32_t sectNum; - } v; - Gv_FillWithVars(v); - - int const ceilzvar = *insptr++; - int const ceilhitvar = *insptr++; - int const florzvar = *insptr++; - int const florhitvar = *insptr++; - - struct { - int32_t walldist, clipmask; - } v2; - Gv_FillWithVars(v2); - - if (EDUKE32_PREDICT_FALSE((unsigned)v.sectNum >= (unsigned)numsectors)) - { - CON_ERRPRINTF("invalid sector %d\n", v.sectNum); - continue; - } - - int32_t ceilz, ceilhit, florz, florhit; - - getzrange(&v.vect, v.sectNum, &ceilz, &ceilhit, &florz, &florhit, v2.walldist, v2.clipmask); - Gv_SetVarX(ceilzvar, ceilz); - Gv_SetVarX(ceilhitvar, ceilhit); - Gv_SetVarX(florzvar, florz); - Gv_SetVarX(florhitvar, florhit); - - continue; - } - - case CON_SECTSETINTERPOLATION: - case CON_SECTCLEARINTERPOLATION: - insptr++; - { - int const sectnum = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)sectnum >= (unsigned)numsectors)) - { - CON_ERRPRINTF("invalid sector %d\n", sectnum); - continue; - } - - if (tw==CON_SECTSETINTERPOLATION) - Sect_SetInterpolation(sectnum); - else - Sect_ClearInterpolation(sectnum); - - continue; - } - - case CON_CALCHYPOTENUSE: - insptr++; - { - int32_t returnVar = *insptr++; - vec2_t da; - Gv_FillWithVars(da); - int64_t const hypsq = (int64_t)da.x*da.x + (int64_t)da.y*da.y; - - Gv_SetVarX(returnVar, (hypsq > (int64_t) INT32_MAX) - ? (int32_t)sqrt((double)hypsq) - : ksqrt((uint32_t)hypsq)); - continue; - } - - case CON_LINEINTERSECT: - case CON_RAYINTERSECT: - insptr++; - { - struct { - vec3_t vec[2]; - vec2_t vec2[2]; - } v; - Gv_FillWithVars(v); - - int const intxvar = *insptr++; - int const intyvar = *insptr++; - int const intzvar = *insptr++; - int const retvar = *insptr++; - vec3_t in; - - int ret = ((tw == CON_LINEINTERSECT) ? lintersect : rayintersect)(v.vec[0].x, v.vec[0].y, v.vec[0].z, v.vec[1].x, - v.vec[1].y, v.vec[1].z, v.vec2[0].x, v.vec2[0].y, - v.vec2[1].x, v.vec2[1].y, &in.x, &in.y, &in.z); - - Gv_SetVarX(retvar, ret); - - if (ret) - { - Gv_SetVarX(intxvar, in.x); - Gv_SetVarX(intyvar, in.y); - Gv_SetVarX(intzvar, in.z); - } - - continue; - } - - case CON_CLIPMOVE: - case CON_CLIPMOVENOSLIDE: - insptr++; - { - typedef struct { - int32_t w, f, c; - } vec3dist_t; - - int const returnVar = *insptr++; - int const xReturn = *insptr++; - int const yReturn = *insptr++; - - insptr -= 2; - - typedef struct { - vec3_t vec3; - int32_t sectNum32; - vec2_t vec2; - vec3dist_t dist; - int32_t clipMask; - } clipmoveparams_t; - - int32_t const sectReturn = insptr[offsetof(clipmoveparams_t, sectNum32)/sizeof(int32_t)]; - - clipmoveparams_t v; - Gv_FillWithVars(v); - int16_t sectNum = v.sectNum32; - - if (EDUKE32_PREDICT_FALSE((unsigned)sectNum >= (unsigned)numsectors)) - { - CON_ERRPRINTF("invalid sector %d\n", sectNum); - Gv_SetVarX(returnVar, 0); - continue; - } - - Gv_SetVarX(returnVar, - clipmovex(&v.vec3, §Num, v.vec2.x, v.vec2.y, v.dist.w, v.dist.f, v.dist.c, v.clipMask, (tw == CON_CLIPMOVENOSLIDE))); - Gv_SetVarX(sectReturn, v.sectNum32); - Gv_SetVarX(xReturn, v.vec3.x); - Gv_SetVarX(yReturn, v.vec3.y); - - continue; - } - - case CON_HITSCAN: - insptr++; - { - struct { - vec3_t origin; - int32_t sectnum; - vec3_t vect; - } v; - Gv_FillWithVars(v); - - int const sectReturn = *insptr++; - int const wallReturn = *insptr++; - int const spriteReturn = *insptr++; - int const xReturn = *insptr++; - int const yReturn = *insptr++; - int const zReturn = *insptr++; - int const clipType = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)v.sectnum >= (unsigned)numsectors)) - { - CON_ERRPRINTF("invalid sector %d\n", v.sectnum); - continue; - } - - hitdata_t hit; - hitscan(&v.origin, v.sectnum, v.vect.x, v.vect.y, v.vect.z, &hit, clipType); - - Gv_SetVarX(sectReturn, hit.sect); - Gv_SetVarX(wallReturn, hit.wall); - Gv_SetVarX(spriteReturn, hit.sprite); - Gv_SetVarX(xReturn, hit.pos.x); - Gv_SetVarX(yReturn, hit.pos.y); - Gv_SetVarX(zReturn, hit.pos.z); - continue; - } - - case CON_CANSEE: - insptr++; - { - struct { - vec3_t vec1; - int32_t firstSector; - vec3_t vec2; - int32_t secondSector; - } v; - Gv_FillWithVars(v); - - int const returnVar = *insptr++; - - if (EDUKE32_PREDICT_FALSE((unsigned)v.firstSector >= (unsigned)numsectors || - (unsigned)v.secondSector >= (unsigned)numsectors)) - { - CON_ERRPRINTF("invalid sector %d\n", (unsigned)v.firstSector >= (unsigned)numsectors ? v.firstSector : v.secondSector); - Gv_SetVarX(returnVar, 0); - } - - Gv_SetVarX(returnVar, cansee(v.vec1.x, v.vec1.y, v.vec1.z, v.firstSector, v.vec2.x, v.vec2.y, v.vec2.z, v.secondSector)); - continue; - } - - case CON_ROTATEPOINT: - insptr++; - { - struct { - vec2_t point[2]; - int32_t angle; - } v; - Gv_FillWithVars(v); - - int const xReturn = *insptr++; - int const yReturn = *insptr++; - vec2_t result; - - rotatepoint(v.point[0], v.point[1], v.angle, &result); - - Gv_SetVarX(xReturn, result.x); - Gv_SetVarX(yReturn, result.y); - continue; - } - - case CON_NEARTAG: - insptr++; - { - // neartag(int32_t x, int32_t y, int32_t z, short sectnum, short ang, //Starting position & angle - // short *neartagsector, //Returns near sector if sector[].tag != 0 - // short *neartagwall, //Returns near wall if wall[].tag != 0 - // short *neartagsprite, //Returns near sprite if sprite[].tag != 0 - // int32_t *neartaghitdist, //Returns actual distance to object (scale: 1024=largest grid size) - // int32_t neartagrange, //Choose maximum distance to scan (scale: 1024=largest grid size) - // char tagsearch) //1-lotag only, 2-hitag only, 3-lotag&hitag - - struct { - vec3_t point; - int32_t sectNum, nAngle; - } v; - Gv_FillWithVars(v); - - int const sectReturn = *insptr++; - int const wallReturn = *insptr++; - int const spriteReturn = *insptr++; - int const distReturn = *insptr++; - - struct { - int32_t tagRange, tagSearch; - } v2; - Gv_FillWithVars(v2); - - if (EDUKE32_PREDICT_FALSE((unsigned)v.sectNum >= (unsigned)numsectors)) - { - CON_ERRPRINTF("Invalid sector %d\n", v.sectNum); - continue; - } - - int16_t neartagsector, neartagwall, neartagsprite; - int32_t neartaghitdist; - - neartag(v.point.x, v.point.y, v.point.z, v.sectNum, v.nAngle, &neartagsector, &neartagwall, &neartagsprite, - &neartaghitdist, v2.tagRange, v2.tagSearch, NULL); - - Gv_SetVarX(sectReturn, neartagsector); - Gv_SetVarX(wallReturn, neartagwall); - Gv_SetVarX(spriteReturn, neartagsprite); - Gv_SetVarX(distReturn, neartaghitdist); - continue; - } - - case CON_GETTIMEDATE: - insptr++; - { - int32_t values[8]; - G_GetTimeDate(values); - - for (native_t i = 0; i < 8; i++) - Gv_SetVarX(*insptr++, values[i]); - - continue; - } - - case CON_MOVESPRITE: - insptr++; - { - struct { - int32_t spriteNum; - vec3_t vect; - int32_t clipType; - } v; - Gv_FillWithVars(v); - - if (EDUKE32_PREDICT_FALSE((unsigned)v.spriteNum >= MAXSPRITES)) - { - CON_ERRPRINTF("invalid sprite %d\n", v.spriteNum); - insptr++; - continue; - } - - Gv_SetVarX(*insptr++, A_MoveSprite(v.spriteNum, &v.vect, v.clipType)); - continue; - } - - case CON_SETSPRITE: - insptr++; - { - struct { - int32_t spriteNum; - vec3_t vect; - } v; - Gv_FillWithVars(v); - - if (EDUKE32_PREDICT_FALSE((unsigned)v.spriteNum >= MAXSPRITES)) - { - CON_ERRPRINTF("invalid sprite %d\n", v.spriteNum); - continue; - } - setsprite(v.spriteNum, &v.vect); - continue; - } - - case CON_GETFLORZOFSLOPE: - case CON_GETCEILZOFSLOPE: - insptr++; - { - struct { - int32_t sectNum; - vec2_t vect; - } v; - Gv_FillWithVars(v); - - if (EDUKE32_PREDICT_FALSE((unsigned)v.sectNum >= (unsigned)numsectors)) - { - CON_ERRPRINTF("invalid sector %d\n", v.sectNum); - insptr++; - continue; - } - Gv_SetVarX(*insptr++, (tw == CON_GETFLORZOFSLOPE ? getflorzofslope : getceilzofslope)(v.sectNum, v.vect.x, v.vect.y)); - continue; - } - - case CON_UPDATESECTOR: - insptr++; - { - vec2_t vect = { 0, 0 }; - Gv_FillWithVars(vect); - - int const returnVar = *insptr++; - int16_t sectNum = sprite[vm.spriteNum].sectnum; - - updatesector(vect.x, vect.y, §Num); - Gv_SetVarX(returnVar, sectNum); - continue; - } - - case CON_UPDATESECTORZ: - insptr++; - { - vec3_t vect = { 0, 0, 0 }; - Gv_FillWithVars(vect); - - int const returnVar = *insptr++; - int16_t sectNum = sprite[vm.spriteNum].sectnum; - - updatesectorz(vect.x, vect.y, vect.z, §Num); - Gv_SetVarX(returnVar, sectNum); - continue; - } - - case CON_SPAWN: - insptr++; - if ((unsigned)vm.pSprite->sectnum >= MAXSECTORS) - { - CON_ERRPRINTF("invalid sector %d\n", vm.pUSprite->sectnum); - insptr++; - continue; - } - A_Spawn(vm.spriteNum,*insptr++); - continue; - - case CON_IFWASWEAPON: - case CON_IFSPAWNEDBY: - insptr++; - VM_CONDITIONAL(vm.pActor->picnum == *insptr); - continue; - - case CON_IFAI: - insptr++; - VM_CONDITIONAL(AC_AI_ID(vm.pData) == *insptr); - continue; - - case CON_IFACTION: - insptr++; - VM_CONDITIONAL(AC_ACTION_ID(vm.pData) == *insptr); - continue; - - case CON_IFACTIONCOUNT: - insptr++; - VM_CONDITIONAL(AC_ACTION_COUNT(vm.pData) >= *insptr); - continue; - - case CON_RESETACTIONCOUNT: - insptr++; - AC_ACTION_COUNT(vm.pData) = 0; - continue; - - case CON_DEBRIS: - insptr++; - { - int debrisTile = *insptr++; - - if ((unsigned)vm.pSprite->sectnum < MAXSECTORS) - for (native_t cnt = (*insptr) - 1; cnt >= 0; cnt--) + if (EDUKE32_PREDICT_FALSE((unsigned)statNum > MAXSTATUS)) { - int const tileOffset = (vm.pSprite->picnum == BLIMP && debrisTile == SCRAP1) ? 0 : (krand() % 3); - - int const spriteNum = - A_InsertSprite(vm.pSprite->sectnum, vm.pSprite->x + (krand() & 255) - 128, - vm.pSprite->y + (krand() & 255) - 128, vm.pSprite->z - (8 << 8) - (krand() & 8191), - debrisTile + tileOffset, vm.pSprite->shade, 32 + (krand() & 15), 32 + (krand() & 15), - krand() & 2047, (krand() & 127) + 32, -(krand() & 2047), vm.spriteNum, 5); - - sprite[spriteNum].yvel = - (vm.pSprite->picnum == BLIMP && debrisTile == SCRAP1) ? g_blimpSpawnItems[cnt % 14] : -1; - sprite[spriteNum].pal = vm.pSprite->pal; + CON_ERRPRINTF("invalid status list %d\n", statNum); + continue; } + + Gv_SetVarX(gameVar, headspritestat[statNum]); + continue; + } + + case CON_PREVSPRITESTAT: insptr++; - } - continue; - - case CON_COUNT: - insptr++; - AC_COUNT(vm.pData) = (int16_t) *insptr++; - continue; - - case CON_CSTATOR: - insptr++; - vm.pSprite->cstat |= (int16_t) *insptr++; - continue; - - case CON_CLIPDIST: - insptr++; - vm.pSprite->clipdist = (int16_t) *insptr++; - continue; - - case CON_CSTAT: - insptr++; - vm.pSprite->cstat = (int16_t) *insptr++; - continue; - - case CON_SAVENN: - case CON_SAVE: - insptr++; - { - int32_t const requestedSlot = *insptr++; - - if ((unsigned)requestedSlot >= 10) - continue; - - // check if we need to make a new file - if (strcmp(g_lastautosave.path, g_lastusersave.path) == 0 || - requestedSlot != g_lastAutoSaveArbitraryID) { - g_lastautosave.reset(); - } + int const gameVar = *insptr++; + int const spriteNum = Gv_GetVarX(*insptr++); - g_lastAutoSaveArbitraryID = requestedSlot; - - if (tw == CON_SAVE || g_lastautosave.name[0] == 0) - { - time_t timeStruct = time(NULL); - struct tm *pTime = localtime(&timeStruct); - - strftime(g_lastautosave.name, sizeof(g_lastautosave.name), - "%d %b %Y %I:%M%p", pTime); - } - - g_saveRequested = true; - - continue; - } - - case CON_QUAKE: - insptr++; - g_earthquakeTime = Gv_GetVarX(*insptr++); - A_PlaySound(EARTHQUAKE,g_player[screenpeek].ps->i); - continue; - - case CON_IFMOVE: - insptr++; - VM_CONDITIONAL(AC_MOVE_ID(vm.pData) == *insptr); - continue; - - case CON_RESETPLAYER: - insptr++; - vm.flags = VM_ResetPlayer(vm.playerNum, vm.flags, 0); - continue; - - case CON_RESETPLAYERFLAGS: - insptr++; - vm.flags = VM_ResetPlayer(vm.playerNum, vm.flags, Gv_GetVarX(*insptr++)); - continue; - - case CON_IFONWATER: - VM_CONDITIONAL(sector[vm.pSprite->sectnum].lotag == ST_1_ABOVE_WATER && - klabs(vm.pSprite->z - sector[vm.pSprite->sectnum].floorz) < ZOFFSET5); - continue; - - case CON_IFINWATER: - VM_CONDITIONAL(sector[vm.pSprite->sectnum].lotag == ST_2_UNDERWATER); - continue; - - case CON_IFCOUNT: - insptr++; - VM_CONDITIONAL(AC_COUNT(vm.pData) >= *insptr); - continue; - - case CON_IFACTOR: - insptr++; - VM_CONDITIONAL(vm.pSprite->picnum == *insptr); - continue; - - case CON_RESETCOUNT: - insptr++; - AC_COUNT(vm.pData) = 0; - continue; - - case CON_ADDINVENTORY: - insptr += 2; - - VM_AddInventory(pPlayer, *(insptr-1), *insptr); - - insptr++; - continue; - - case CON_HITRADIUSVAR: - insptr++; - { - int32_t params[5]; - Gv_FillWithVars(params); - A_RadiusDamage(vm.spriteNum, params[0], params[1], params[2], params[3], params[4]); - } - continue; - - case CON_HITRADIUS: - A_RadiusDamage(vm.spriteNum,*(insptr+1),*(insptr+2),*(insptr+3),*(insptr+4),*(insptr+5)); - insptr += 6; - continue; - - case CON_IFP: - { - int const moveFlags = *(++insptr); - int nResult = 0; - int const playerXVel = sprite[pPlayer->i].xvel; - int const syncBits = g_player[vm.playerNum].inputBits->bits; - - if (((moveFlags & pducking) && pPlayer->on_ground && TEST_SYNC_KEY(syncBits, SK_CROUCH)) || - ((moveFlags & pfalling) && pPlayer->jumping_counter == 0 && !pPlayer->on_ground && pPlayer->vel.z > 2048) || - ((moveFlags & pjumping) && pPlayer->jumping_counter > 348) || - ((moveFlags & pstanding) && playerXVel >= 0 && playerXVel < 8) || - ((moveFlags & pwalking) && playerXVel >= 8 && !TEST_SYNC_KEY(syncBits, SK_RUN)) || - ((moveFlags & prunning) && playerXVel >= 8 && TEST_SYNC_KEY(syncBits, SK_RUN)) || - ((moveFlags & phigher) && pPlayer->pos.z < (vm.pSprite->z - (48 << 8))) || - ((moveFlags & pwalkingback) && playerXVel <= -8 && !TEST_SYNC_KEY(syncBits, SK_RUN)) || - ((moveFlags & prunningback) && playerXVel <= -8 && TEST_SYNC_KEY(syncBits, SK_RUN)) || - ((moveFlags & pkicking) && (pPlayer->quick_kick > 0 || (PWEAPON(vm.playerNum, pPlayer->curr_weapon, WorksLike) == KNEE_WEAPON && - pPlayer->kickback_pic > 0))) || - ((moveFlags & pshrunk) && sprite[pPlayer->i].xrepeat < 32) || - ((moveFlags & pjetpack) && pPlayer->jetpack_on) || - ((moveFlags & ponsteroids) && pPlayer->inv_amount[GET_STEROIDS] > 0 && pPlayer->inv_amount[GET_STEROIDS] < 400) || - ((moveFlags & ponground) && pPlayer->on_ground) || - ((moveFlags & palive) && sprite[pPlayer->i].xrepeat > 32 && sprite[pPlayer->i].extra > 0 && pPlayer->timebeforeexit == 0) || - ((moveFlags & pdead) && sprite[pPlayer->i].extra <= 0)) - nResult = 1; - else if ((moveFlags & pfacing)) - { - nResult = - (vm.pSprite->picnum == APLAYER && (g_netServer || ud.multimode > 1)) - ? G_GetAngleDelta(fix16_to_int(g_player[otherp].ps->q16ang), getangle(pPlayer->pos.x - g_player[otherp].ps->pos.x, - pPlayer->pos.y - g_player[otherp].ps->pos.y)) - : G_GetAngleDelta(fix16_to_int(pPlayer->q16ang), getangle(vm.pSprite->x - pPlayer->pos.x, vm.pSprite->y - pPlayer->pos.y)); - - nResult = (nResult > -128 && nResult < 128); - } - VM_CONDITIONAL(nResult); - } - continue; - - case CON_IFSTRENGTH: - insptr++; - VM_CONDITIONAL(vm.pSprite->extra <= *insptr); - continue; - - case CON_GUTS: - A_DoGuts(vm.spriteNum,*(insptr+1),*(insptr+2)); - insptr += 3; - continue; - - case CON_WACKPLAYER: - insptr++; - P_ForceAngle(pPlayer); - continue; - - case CON_FLASH: - insptr++; - sprite[vm.spriteNum].shade = -127; - pPlayer->visibility = -127; - continue; - - case CON_SAVEMAPSTATE: - G_SaveMapState(); - insptr++; - continue; - - case CON_LOADMAPSTATE: - G_RestoreMapState(); - insptr++; - continue; - - case CON_CLEARMAPSTATE: - insptr++; - { - int const levelNum = Gv_GetVarX(*insptr++); - if (EDUKE32_PREDICT_FALSE((unsigned)levelNum >= MAXVOLUMES*MAXLEVELS)) - { - CON_ERRPRINTF("invalid map number %d\n", levelNum); - continue; - } - - G_FreeMapState(levelNum); - } - continue; - - case CON_STOPALLSOUNDS: - insptr++; - if (screenpeek == vm.playerNum) - FX_StopAllSounds(); - continue; - - case CON_STOPALLMUSIC: - insptr++; - S_StopMusic(); - continue; - - case CON_IFGAPZL: - insptr++; - VM_CONDITIONAL(((vm.pActor->floorz - vm.pActor->ceilingz) >> 8) < *insptr); - continue; - - case CON_IFHITSPACE: - VM_CONDITIONAL(TEST_SYNC_KEY(g_player[vm.playerNum].inputBits->bits, SK_OPEN)); - continue; - - case CON_IFOUTSIDE: - VM_CONDITIONAL(sector[vm.pSprite->sectnum].ceilingstat&1); - continue; - - case CON_IFMULTIPLAYER: - VM_CONDITIONAL((g_netServer || g_netClient || ud.multimode > 1)); - continue; - - case CON_IFCLIENT: - VM_CONDITIONAL(g_netClient != NULL); - continue; - - case CON_IFSERVER: - VM_CONDITIONAL(g_netServer != NULL); - continue; - - case CON_IFPLAYBACKON: - VM_CONDITIONAL(0); - continue; - - case CON_OPERATE: - insptr++; - if (sector[vm.pSprite->sectnum].lotag == 0) - { - int16_t foundSect, foundWall, foundSprite; - int32_t foundDist; - - neartag(vm.pSprite->x,vm.pSprite->y,vm.pSprite->z-ZOFFSET5,vm.pSprite->sectnum,vm.pSprite->ang, - &foundSect,&foundWall,&foundSprite,&foundDist, 768, 4+1, NULL); - - if (foundSect >= 0 && isanearoperator(sector[foundSect].lotag)) - if ((sector[foundSect].lotag&0xff) == ST_23_SWINGING_DOOR || sector[foundSect].floorz == sector[foundSect].ceilingz) - if ((sector[foundSect].lotag&(16384u|32768u)) == 0) - { - int32_t j; - - for (SPRITES_OF_SECT(foundSect, j)) - if (sprite[j].picnum == ACTIVATOR) - break; - - if (j == -1) - G_OperateSectors(foundSect,vm.spriteNum); - } - } - continue; - - case CON_IFINSPACE: - VM_CONDITIONAL(G_CheckForSpaceCeiling(vm.pSprite->sectnum)); - continue; - - case CON_SPRITEPAL: - insptr++; - if (vm.pSprite->picnum != APLAYER) - vm.pActor->tempang = vm.pSprite->pal; - vm.pSprite->pal = *insptr++; - continue; - - case CON_CACTOR: - insptr++; - vm.pSprite->picnum = *insptr++; - continue; - - case CON_IFBULLETNEAR: - VM_CONDITIONAL(A_Dodge(vm.pSprite) == 1); - continue; - - case CON_IFRESPAWN: - if (A_CheckEnemySprite(vm.pSprite)) VM_CONDITIONAL(ud.respawn_monsters) - else if (A_CheckInventorySprite(vm.pSprite)) VM_CONDITIONAL(ud.respawn_inventory) - else VM_CONDITIONAL(ud.respawn_items) - continue; - - case CON_IFFLOORDISTL: - insptr++; - VM_CONDITIONAL((vm.pActor->floorz - vm.pSprite->z) <= ((*insptr)<<8)); - continue; - - case CON_IFCEILINGDISTL: - insptr++; - VM_CONDITIONAL((vm.pSprite->z - vm.pActor->ceilingz) <= ((*insptr)<<8)); - continue; - - case CON_PALFROM: - insptr++; - if (EDUKE32_PREDICT_FALSE((unsigned)vm.playerNum >= (unsigned)g_mostConcurrentPlayers)) - { - CON_ERRPRINTF("invalid player %d\n", vm.playerNum); - insptr += 4; - } - else - { - palette_t const pal = { (uint8_t) * (insptr + 1), (uint8_t) * (insptr + 2), (uint8_t) * (insptr + 3), - (uint8_t) * (insptr) }; - insptr += 4; - P_PalFrom(pPlayer, pal.f, pal.r, pal.g, pal.b); - } - continue; - - case CON_SCREENPAL: - insptr++; - { - int32_t params[4]; - Gv_FillWithVars(params); - videoFadePalette(params[0], params[1], params[2], params[3]); - } - continue; - - case CON_SECTOROFWALL: - insptr++; - tw = *insptr++; - Gv_SetVarX(tw, sectorofwall(Gv_GetVarX(*insptr++))); - continue; - - case CON_QSPRINTF: - insptr++; - { - int const outputQuote = Gv_GetVarX(*insptr++); - int const inputQuote = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE(apStrings[inputQuote] == NULL || apStrings[outputQuote] == NULL)) - { - CON_ERRPRINTF("null quote %d\n", apStrings[inputQuote] ? outputQuote : inputQuote); - - while ((*insptr & VM_INSTMASK) != CON_NULLOP) - Gv_GetVarX(*insptr++); - - insptr++; // skip the NOP - continue; - } - - int32_t arg[32]; - int const quoteLen = Bstrlen(apStrings[inputQuote]); - int inputPos = 0; - char outBuf[MAXQUOTELEN]; - int outBufPos = 0; - int argIdx = 0; - - while ((*insptr & VM_INSTMASK) != CON_NULLOP && argIdx < 32) - arg[argIdx++] = Gv_GetVarX(*insptr++); - - int numArgs = argIdx; - - insptr++; // skip the NOP - - argIdx = 0; - - do - { - while (inputPos < quoteLen && outBufPos < MAXQUOTELEN && apStrings[inputQuote][inputPos] != '%') - outBuf[outBufPos++] = apStrings[inputQuote][inputPos++]; - - if (apStrings[inputQuote][inputPos] == '%') + if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES)) { - inputPos++; - switch (apStrings[inputQuote][inputPos]) + CON_ERRPRINTF("invalid sprite %d\n", spriteNum); + continue; + } + + Gv_SetVarX(gameVar, prevspritestat[spriteNum]); + continue; + } + + case CON_NEXTSPRITESTAT: + insptr++; + { + int const gameVar = *insptr++; + int const spriteNum = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES)) + { + CON_ERRPRINTF("invalid sprite %d\n", spriteNum); + continue; + } + + Gv_SetVarX(gameVar, nextspritestat[spriteNum]); + continue; + } + + case CON_HEADSPRITESECT: + insptr++; + { + int const gameVar = *insptr++; + int const sectNum = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)sectNum >= (unsigned)numsectors)) + { + CON_ERRPRINTF("invalid sector %d\n", sectNum); + continue; + } + + Gv_SetVarX(gameVar, headspritesect[sectNum]); + continue; + } + + case CON_PREVSPRITESECT: + insptr++; + { + int const gameVar = *insptr++; + int const spriteNum = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES)) + { + CON_ERRPRINTF("invalid sprite %d\n", spriteNum); + continue; + } + + Gv_SetVarX(gameVar, prevspritesect[spriteNum]); + continue; + } + + case CON_NEXTSPRITESECT: + insptr++; + { + int const gameVar = *insptr++; + int const spriteNum = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES)) + { + CON_ERRPRINTF("invalid sprite %d\n", spriteNum); + continue; + } + + Gv_SetVarX(gameVar, nextspritesect[spriteNum]); + continue; + } + + case CON_GETKEYNAME: + insptr++; + { + int const quoteIndex = Gv_GetVarX(*insptr++); + int const gameFunc = Gv_GetVarX(*insptr++); + int const funcPos = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)quoteIndex >= MAXQUOTES || apStrings[quoteIndex] == NULL)) + { + CON_ERRPRINTF("invalid quote %d\n", quoteIndex); + continue; + } + else if (EDUKE32_PREDICT_FALSE((unsigned)gameFunc >= NUMGAMEFUNCTIONS)) + { + CON_ERRPRINTF("invalid function %d\n", gameFunc); + continue; + } + else + { + if (funcPos < 2) + Bstrcpy(tempbuf, KB_ScanCodeToString(ud.config.KeyboardKeys[gameFunc][funcPos])); + else { - case 'l': - if (apStrings[inputQuote][inputPos+1] != 'd') + Bstrcpy(tempbuf, KB_ScanCodeToString(ud.config.KeyboardKeys[gameFunc][0])); + + if (!*tempbuf) + Bstrcpy(tempbuf, KB_ScanCodeToString(ud.config.KeyboardKeys[gameFunc][1])); + } + } + + if (*tempbuf) + Bstrcpy(apStrings[quoteIndex], tempbuf); + + continue; + } + + case CON_QSUBSTR: + insptr++; + { + struct + { + int32_t outputQuote, inputQuote, quotePos, quoteLength; + } v; + Gv_FillWithVars(v); + + if (EDUKE32_PREDICT_FALSE((unsigned)v.outputQuote >= MAXQUOTES || apStrings[v.outputQuote] == NULL + || (unsigned)v.inputQuote >= MAXQUOTES + || apStrings[v.inputQuote] == NULL)) + { + CON_ERRPRINTF("invalid quote %d\n", apStrings[v.outputQuote] ? v.inputQuote : v.outputQuote); + continue; + } + + if (EDUKE32_PREDICT_FALSE((unsigned)v.quotePos >= MAXQUOTELEN)) + { + CON_ERRPRINTF("invalid position %d\n", v.quotePos); + continue; + } + + if (EDUKE32_PREDICT_FALSE(v.quoteLength < 0)) + { + CON_ERRPRINTF("invalid length %d\n", v.quoteLength); + continue; + } + + char * pOutput = apStrings[v.outputQuote]; + char const *pInput = apStrings[v.inputQuote]; + + while (*pInput && v.quotePos--) + pInput++; + while ((*pOutput = *pInput) && v.quoteLength--) + { + pOutput++; + pInput++; + } + *pOutput = '\0'; + + continue; + } + + case CON_QSTRCMP: + insptr++; + { + int const quote1 = Gv_GetVarX(*insptr++); + int const quote2 = Gv_GetVarX(*insptr++); + int const gameVar = *insptr++; + + if (EDUKE32_PREDICT_FALSE(apStrings[quote1] == NULL || apStrings[quote2] == NULL)) + { + CON_ERRPRINTF("null quote %d\n", apStrings[quote1] ? quote2 : quote1); + Gv_SetVarX(gameVar, -2); + continue; + } + + Gv_SetVarX(gameVar, strcmp(apStrings[quote1], apStrings[quote2])); + continue; + } + + case CON_GETPNAME: + case CON_QSTRNCAT: + case CON_QSTRCAT: + case CON_QSTRCPY: + case CON_QGETSYSSTR: + insptr++; + { + int32_t i = Gv_GetVarX(*insptr++), j; + if (tw == CON_GETPNAME && *insptr == g_thisActorVarID) + { + j = vm.playerNum; + insptr++; + } + else + j = Gv_GetVarX(*insptr++); + + switch (tw) + { + case CON_GETPNAME: + if (EDUKE32_PREDICT_FALSE((unsigned)i >= MAXQUOTES || apStrings[i] == NULL)) { - // write the % and l - outBuf[outBufPos++] = apStrings[inputQuote][inputPos-1]; - outBuf[outBufPos++] = apStrings[inputQuote][inputPos++]; + CON_ERRPRINTF("invalid quote %d\n", i); break; } - inputPos++; - fallthrough__; - case 'd': - { - if (argIdx >= numArgs) - goto finish_qsprintf; - - char buf[16]; - Bsprintf(buf, "%d", arg[argIdx++]); - - int const bufLen = Bstrlen(buf); - Bmemcpy(&outBuf[outBufPos], buf, bufLen); - outBufPos += bufLen; - inputPos++; - } - break; - - case 's': - { - if (argIdx >= numArgs) - goto finish_qsprintf; - - int const argLen = Bstrlen(apStrings[arg[argIdx]]); - - Bmemcpy(&outBuf[outBufPos], apStrings[arg[argIdx]], argLen); - outBufPos += argLen; - argIdx++; - inputPos++; - } - break; - - default: - outBuf[outBufPos++] = apStrings[inputQuote][inputPos-1]; + if (g_player[j].user_name[0]) + Bstrcpy(apStrings[i], g_player[j].user_name); + else + Bsprintf(apStrings[i], "%d", j); break; + case CON_QGETSYSSTR: + if (EDUKE32_PREDICT_FALSE((unsigned)i >= MAXQUOTES || apStrings[i] == NULL)) + { + CON_ERRPRINTF("invalid quote %d\n", i); + break; + } + switch (j) + { + case STR_MAPNAME: + case STR_MAPFILENAME: + { + int32_t levelNum = ud.volume_number * MAXLEVELS + ud.level_number; + const char *pName; + + if (EDUKE32_PREDICT_FALSE((unsigned)levelNum >= ARRAY_SIZE(g_mapInfo))) + { + CON_ERRPRINTF("out of bounds map number (vol=%d, lev=%d)\n", ud.volume_number, ud.level_number); + break; + } + + pName = j == STR_MAPNAME ? g_mapInfo[levelNum].name : g_mapInfo[levelNum].filename; + + if (EDUKE32_PREDICT_FALSE(pName == NULL)) + { + CON_ERRPRINTF("attempted access to %s of non-existent map (vol=%d, lev=%d)", + j == STR_MAPNAME ? "name" : "file name", ud.volume_number, ud.level_number); + break; + } + + Bstrcpy(apStrings[i], j == STR_MAPNAME ? g_mapInfo[levelNum].name : g_mapInfo[levelNum].filename); + break; + } + case STR_PLAYERNAME: + if (EDUKE32_PREDICT_FALSE((unsigned)vm.playerNum >= (unsigned)g_mostConcurrentPlayers)) + { + CON_ERRPRINTF("invalid player %d\n", vm.playerNum); + break; + } + Bstrcpy(apStrings[i], g_player[vm.playerNum].user_name); + break; + case STR_VERSION: + Bsprintf(tempbuf, HEAD2 " %s", s_buildRev); + Bstrcpy(apStrings[i], tempbuf); + break; + case STR_GAMETYPE: Bstrcpy(apStrings[i], g_gametypeNames[ud.coop]); break; + case STR_VOLUMENAME: + if (EDUKE32_PREDICT_FALSE((unsigned)ud.volume_number >= MAXVOLUMES)) + { + CON_ERRPRINTF("invalid volume %d\n", ud.volume_number); + break; + } + Bstrcpy(apStrings[i], g_volumeNames[ud.volume_number]); + break; + case STR_YOURTIME: Bstrcpy(apStrings[i], G_PrintYourTime()); break; + case STR_PARTIME: Bstrcpy(apStrings[i], G_PrintParTime()); break; + case STR_DESIGNERTIME: Bstrcpy(apStrings[i], G_PrintDesignerTime()); break; + case STR_BESTTIME: Bstrcpy(apStrings[i], G_PrintBestTime()); break; + case STR_USERMAPFILENAME: Bstrcpy(apStrings[i], boardfilename); break; + default: CON_ERRPRINTF("invalid string index %d or %d\n", i, j); + } + break; + case CON_QSTRCAT: + if (EDUKE32_PREDICT_FALSE(apStrings[i] == NULL || apStrings[j] == NULL)) + goto nullquote; + Bstrncat(apStrings[i], apStrings[j], (MAXQUOTELEN - 1) - Bstrlen(apStrings[i])); + break; + case CON_QSTRNCAT: + if (EDUKE32_PREDICT_FALSE(apStrings[i] == NULL || apStrings[j] == NULL)) + goto nullquote; + Bstrncat(apStrings[i], apStrings[j], Gv_GetVarX(*insptr++)); + break; + case CON_QSTRCPY: + if (EDUKE32_PREDICT_FALSE(apStrings[i] == NULL || apStrings[j] == NULL)) + goto nullquote; + if (i != j) + Bstrcpy(apStrings[i], apStrings[j]); + break; + default: + nullquote: + CON_ERRPRINTF("invalid quote %d\n", apStrings[i] ? j : i); + break; + } + continue; + } + + case CON_CHANGESPRITESECT: + insptr++; + { + int32_t const spriteNum = Gv_GetVarX(*insptr++); + int32_t sectNum = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES || (unsigned)sectNum >= MAXSECTORS)) + { + CON_ERRPRINTF("invalid parameters: %d, %d\n", spriteNum, sectNum); + continue; + } + + if (sprite[spriteNum].sectnum == sectNum) + continue; + + changespritesect(spriteNum, sectNum); + continue; + } + + case CON_CHANGESPRITESTAT: + insptr++; + { + int32_t const spriteNum = Gv_GetVarX(*insptr++); + int32_t statNum = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)spriteNum >= MAXSPRITES || (unsigned)statNum >= MAXSECTORS)) + { + CON_ERRPRINTF("invalid parameters: %d, %d\n", spriteNum, statNum); + continue; + } + + if (sprite[spriteNum].statnum == statNum) + continue; + + /* initialize actor data when changing to an actor statnum because there's usually + garbage left over from being handled as a hard coded object */ + + if (sprite[spriteNum].statnum > STAT_ZOMBIEACTOR && (statNum == STAT_ACTOR || statNum == STAT_ZOMBIEACTOR)) + { + actor_t *const pActor = &actor[spriteNum]; + + Bmemset(&pActor->t_data, 0, sizeof pActor->t_data); + pActor->lastv.x = 0; + pActor->lastv.y = 0; + pActor->timetosleep = 0; + pActor->cgg = 0; + pActor->movflag = 0; + pActor->tempang = 0; + pActor->dispicnum = 0; + pActor->flags = 0; + sprite[spriteNum].hitag = 0; + + if (G_HaveActor(sprite[spriteNum].picnum)) + { + const intptr_t *actorptr = g_tile[sprite[spriteNum].picnum].execPtr; + // offsets + AC_ACTION_ID(pActor->t_data) = actorptr[1]; + AC_MOVE_ID(pActor->t_data) = actorptr[2]; + AC_MOVFLAGS(&sprite[spriteNum], &actor[spriteNum]) = actorptr[3]; // ai bits (movflags) } } + + changespritestat(spriteNum, statNum); + continue; + } + + case CON_STARTLEVEL: + insptr++; // skip command + { + // from 'level' cheat in game.c (about line 6250) + int const volumeNum = Gv_GetVarX(*insptr++); + int const levelNum = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)volumeNum >= MAXVOLUMES || (unsigned)levelNum >= MAXLEVELS)) + { + CON_ERRPRINTF("invalid parameters: %d, %d\n", volumeNum, levelNum); + continue; + } + + ud.m_volume_number = ud.volume_number = volumeNum; + ud.m_level_number = ud.level_number = levelNum; + // if (numplayers > 1 && g_netServer) + // Net_NewGame(volnume,levnume); + //else + { + g_player[myconnectindex].ps->gm |= MODE_EOL; + ud.display_bonus_screen = 0; + } // MODE_RESTART; + + continue; + } + + case CON_MYOSX: + case CON_MYOSPALX: + case CON_MYOS: + case CON_MYOSPAL: + insptr++; + { + struct + { + vec2_t pos; + int32_t tilenum, shade, orientation; + } v; + Gv_FillWithVars(v); + + switch (tw) + { + case CON_MYOS: VM_DrawTile(v.pos.x, v.pos.y, v.tilenum, v.shade, v.orientation); break; + case CON_MYOSPAL: VM_DrawTilePal(v.pos.x, v.pos.y, v.tilenum, v.shade, v.orientation, Gv_GetVarX(*insptr++)); break; + case CON_MYOSX: VM_DrawTileSmall(v.pos.x, v.pos.y, v.tilenum, v.shade, v.orientation); break; + case CON_MYOSPALX: VM_DrawTilePalSmall(v.pos.x, v.pos.y, v.tilenum, v.shade, v.orientation, Gv_GetVarX(*insptr++)); break; + } + continue; + } + + case CON_SWITCH: + insptr++; + { + // command format: + // variable ID to check + // script offset to 'end' + // count of case statements + // script offset to default case (null if none) + // For each case: value, ptr to code + int32_t const lValue = Gv_GetVarX(*insptr++); + int32_t const lEnd = *insptr++; + int32_t const lCases = *insptr++; + + intptr_t const *const lpDefault = insptr++; + intptr_t const *const lpCases = insptr; + + int left = 0; + int right = lCases - 1; + + insptr += lCases << 1; + + do + { + int const lCheckCase = (left + right) >> 1; + + if (lpCases[lCheckCase << 1] > lValue) + right = lCheckCase - 1; + else if (lpCases[lCheckCase << 1] < lValue) + left = lCheckCase + 1; + else if (lpCases[lCheckCase << 1] == lValue) + { + // fake a 2-d Array + insptr = (intptr_t *)(lpCases[(lCheckCase << 1) + 1] + &apScript[0]); + VM_Execute(1); + goto matched; + } + + if (right - left < 0) + break; + } while (1); + + if (*lpDefault) + { + insptr = (intptr_t *)(*lpDefault + &apScript[0]); + VM_Execute(1); + } + + matched: + insptr = (intptr_t *)(lEnd + (intptr_t)&apScript[0]); + + continue; + } + + case CON_DISPLAYRAND: + insptr++; + Gv_SetVarX(*insptr++, system_15bit_rand()); + continue; + + case CON_DRAGPOINT: + insptr++; + { + int const wallNum = Gv_GetVarX(*insptr++); + vec2_t n; + Gv_FillWithVars(n); + + if (EDUKE32_PREDICT_FALSE((unsigned)wallNum >= (unsigned)numwalls)) + { + CON_ERRPRINTF("invalid wall %d\n", wallNum); + continue; + } + + dragpoint(wallNum, n.x, n.y, 0); + continue; + } + + case CON_LDIST: + case CON_DIST: + insptr++; + { + int const out = *insptr++; + vec2_t in; + Gv_FillWithVars(in); + + if (EDUKE32_PREDICT_FALSE((unsigned)in.x >= MAXSPRITES || (unsigned)in.y >= MAXSPRITES)) + { + CON_ERRPRINTF("invalid sprite %d, %d\n", in.x, in.y); + continue; + } + + Gv_SetVarX(out, (tw == CON_LDIST ? ldist : dist)(&sprite[in.x], &sprite[in.y])); + continue; + } + + case CON_GETANGLE: + case CON_GETINCANGLE: + insptr++; + { + int const out = *insptr++; + vec2_t in; + Gv_FillWithVars(in); + Gv_SetVarX(out, (tw == CON_GETANGLE ? getangle : G_GetAngleDelta)(in.x, in.y)); + continue; + } + + case CON_MULSCALE: + case CON_DIVSCALE: + insptr++; + { + int const out = *insptr++; + vec3_t in; + Gv_FillWithVars(in); + + if (tw == CON_MULSCALE) + Gv_SetVarX(out, mulscale(in.x, in.y, in.z)); + else + Gv_SetVarX(out, divscale(in.x, in.y, in.z)); + + continue; + } + + case CON_SCALEVAR: + insptr++; + { + int const out = *insptr++; + vec3_t in; + Gv_FillWithVars(in); + Gv_SetVarX(out, scale(in.x, in.y, in.z)); + continue; + } + + case CON_INITTIMER: + insptr++; + G_InitTimer(Gv_GetVarX(*insptr++)); + continue; + + case CON_NEXTSECTORNEIGHBORZ: + insptr++; + { + int32_t params[4]; + Gv_FillWithVars(params); + aGameVars[g_returnVarID].global = nextsectorneighborz(params[0], params[1], params[2], params[3]); + } + continue; + + case CON_MOVESECTOR: + insptr++; + A_MoveSector(Gv_GetVarX(*insptr++)); + continue; + + case CON_TIME: insptr += 2; continue; + + case CON_ESPAWNVAR: + case CON_EQSPAWNVAR: + case CON_QSPAWNVAR: + insptr++; + { + int const tileNum = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)vm.pSprite->sectnum >= (unsigned)numsectors)) + { + CON_ERRPRINTF("invalid sector %d\n", vm.pUSprite->sectnum); + continue; + } + + int const spriteNum = A_Spawn(vm.spriteNum, tileNum); + + switch (tw) + { + case CON_EQSPAWNVAR: + if (spriteNum != -1) + A_AddToDeleteQueue(spriteNum); + fallthrough__; + case CON_ESPAWNVAR: aGameVars[g_returnVarID].global = spriteNum; break; + case CON_QSPAWNVAR: + if (spriteNum != -1) + A_AddToDeleteQueue(spriteNum); + break; + } + continue; + } + + case CON_SHOOTVAR: + case CON_ESHOOTVAR: + insptr++; + { + int j = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)vm.pSprite->sectnum >= (unsigned)numsectors)) + { + CON_ERRPRINTF("invalid sector %d\n", vm.pUSprite->sectnum); + continue; + } + + j = A_Shoot(vm.spriteNum, j); + + if (tw == CON_ESHOOTVAR) + aGameVars[g_returnVarID].global = j; + + continue; + } + + case CON_EZSHOOTVAR: + case CON_ZSHOOTVAR: + insptr++; + { + int const zvel = (int16_t)Gv_GetVarX(*insptr++); + int j = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)vm.pSprite->sectnum >= (unsigned)numsectors)) + { + CON_ERRPRINTF("invalid sector %d\n", vm.pUSprite->sectnum); + continue; + } + + j = A_ShootWithZvel(vm.spriteNum, j, zvel); + + if (tw == CON_EZSHOOTVAR) + aGameVars[g_returnVarID].global = j; + + continue; + } + + case CON_CMENU: + insptr++; + Menu_Change(Gv_GetVarX(*insptr++)); + continue; + + case CON_SOUNDVAR: + case CON_STOPSOUNDVAR: + case CON_SOUNDONCEVAR: + case CON_GLOBALSOUNDVAR: + case CON_SCREENSOUND: + insptr++; + { + int const soundNum = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)soundNum >= MAXSOUNDS)) + { + CON_ERRPRINTF("invalid sound %d\n", soundNum); + continue; + } + + switch (tw) + { + case CON_SOUNDONCEVAR: + if (!S_CheckSoundPlaying(vm.spriteNum, soundNum)) + { + fallthrough__; + case CON_SOUNDVAR: A_PlaySound((int16_t)soundNum, vm.spriteNum); + } + continue; + case CON_GLOBALSOUNDVAR: A_PlaySound((int16_t)soundNum, g_player[screenpeek].ps->i); continue; + case CON_STOPSOUNDVAR: + if (S_CheckSoundPlaying(vm.spriteNum, soundNum)) + S_StopSound((int16_t)soundNum); + continue; + case CON_SCREENSOUND: A_PlaySound(soundNum, -1); continue; + } + } + continue; + + case CON_STARTCUTSCENE: + case CON_IFCUTSCENE: + insptr++; + { + int const nQuote = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)nQuote >= MAXQUOTES || apStrings[nQuote] == NULL)) + { + CON_ERRPRINTF("invalid quote %d for anim!\n", nQuote); + continue; + } + + if (tw == CON_IFCUTSCENE) + { + insptr--; + VM_CONDITIONAL(g_animPtr == Anim_Find(apStrings[nQuote])); + continue; + } + + tw = pPlayer->palette; + I_ClearAllInput(); + Anim_Play(apStrings[nQuote]); + P_SetGamePalette(pPlayer, tw, 2 + 16); + continue; + } + + case CON_STARTSCREEN: + insptr++; + I_ClearAllInput(); + Screen_Play(); + continue; + + case CON_GUNIQHUDID: + insptr++; + { + tw = Gv_GetVarX(*insptr++); + if (EDUKE32_PREDICT_FALSE((unsigned)tw >= MAXUNIQHUDID - 1)) + CON_ERRPRINTF("invalid value %d\n", (int)tw); + else + guniqhudid = tw; + + continue; + } + + case CON_SAVEGAMEVAR: + case CON_READGAMEVAR: + { + int32_t nValue = 0; + insptr++; + if (ud.config.scripthandle < 0) + { + insptr++; + continue; + } + switch (tw) + { + case CON_SAVEGAMEVAR: + nValue = Gv_GetVarX(*insptr); + SCRIPT_PutNumber(ud.config.scripthandle, "Gamevars", aGameVars[*insptr++].szLabel, nValue, FALSE, FALSE); + break; + case CON_READGAMEVAR: + SCRIPT_GetNumber(ud.config.scripthandle, "Gamevars", aGameVars[*insptr].szLabel, &nValue); + Gv_SetVarX(*insptr++, nValue); + break; } - while (inputPos < quoteLen && outBufPos < MAXQUOTELEN); -finish_qsprintf: - outBuf[outBufPos] = '\0'; - Bstrncpyz(apStrings[outputQuote], outBuf, MAXQUOTELEN); continue; } - case CON_ADDLOG: - { - insptr++; - - initprintf(OSDTEXT_GREEN "CONLOG: L=%d\n",g_errorLineNum); - continue; - } - - case CON_ADDLOGVAR: - insptr++; - { - int32_t m=1; - char szBuf[256]; - int32_t lVarID = *insptr; - - if ((lVarID >= g_gameVarCount) || lVarID < 0) + case CON_SHOWVIEW: + case CON_SHOWVIEWUNBIASED: + case CON_SHOWVIEWQ16: + case CON_SHOWVIEWQ16UNBIASED: + insptr++; { - if (*insptr==MAXGAMEVARS) // addlogvar for a constant? Har. - insptr++; - // else if (*insptr > g_gameVarCount && (*insptr < (MAXGAMEVARS<<1)+MAXGAMEVARS+1+MAXGAMEARRAYS)) - else if (*insptr&(MAXGAMEVARS<<2)) + struct { - int32_t index; + vec3_t vec; + int32_t params[3]; + vec2_t scrn[2]; + } v; + Gv_FillWithVars(v); - lVarID ^= (MAXGAMEVARS<<2); + if (EDUKE32_PREDICT_FALSE(v.scrn[0].x < 0 || v.scrn[0].y < 0 || v.scrn[1].x >= 320 || v.scrn[1].y >= 200)) + { + CON_ERRPRINTF("incorrect coordinates\n"); + continue; + } - if (lVarID&(MAXGAMEVARS<<1)) + if (EDUKE32_PREDICT_FALSE((unsigned)v.params[2] >= (unsigned)numsectors)) + { + CON_ERRPRINTF("invalid sector %d\n", v.params[2]); + continue; + } + + if (tw != CON_SHOWVIEWQ16 && tw != CON_SHOWVIEWQ16UNBIASED) + { + v.params[0] <<= 16; + v.params[1] <<= 16; + } + + G_ShowView(v.vec, v.params[0], v.params[1], v.params[2], v.scrn[0].x, v.scrn[0].y, v.scrn[1].x, v.scrn[1].y, + (tw != CON_SHOWVIEW && tw != CON_SHOWVIEWQ16)); + + continue; + } + + case CON_ROTATESPRITEA: + case CON_ROTATESPRITE16: + case CON_ROTATESPRITE: + insptr++; + { + struct + { + vec3_t pos; + int32_t ang, tilenum, shade, pal, orientation; + } v; + Gv_FillWithVars(v); + + int32_t alpha = (tw == CON_ROTATESPRITEA) ? Gv_GetVarX(*insptr++) : 0; + + vec2_t bound[2]; + Gv_FillWithVars(bound); + + if (tw != CON_ROTATESPRITE16 && !(v.orientation & ROTATESPRITE_FULL16)) + { + v.pos.x <<= 16; + v.pos.y <<= 16; + } + + if (EDUKE32_PREDICT_FALSE((unsigned)v.tilenum >= MAXTILES)) + { + CON_ERRPRINTF("invalid tilenum %d\n", v.tilenum); + continue; + } + + int32_t blendidx = 0; + + NEG_ALPHA_TO_BLEND(alpha, blendidx, v.orientation); + + rotatesprite_(v.pos.x, v.pos.y, v.pos.z, v.ang, v.tilenum, v.shade, v.pal, 2 | (v.orientation & (ROTATESPRITE_MAX - 1)), alpha, + blendidx, bound[0].x, bound[0].y, bound[1].x, bound[1].y); + continue; + } + + case CON_GAMETEXT: + case CON_GAMETEXTZ: + insptr++; + { + struct + { + int32_t tilenum; + vec2_t pos; + int32_t nQuote, shade, pal, orientation; + vec2_t bound[2]; + } v; + Gv_FillWithVars(v); + + int32_t const z = (tw == CON_GAMETEXTZ) ? Gv_GetVarX(*insptr++) : 65536; + + if (EDUKE32_PREDICT_FALSE(v.tilenum < 0 || v.tilenum + 127 >= MAXTILES)) + { + CON_ERRPRINTF("invalid base tilenum %d\n", v.tilenum); + continue; + } + + if (EDUKE32_PREDICT_FALSE((unsigned)v.nQuote >= MAXQUOTES || apStrings[v.nQuote] == NULL)) + { + CON_ERRPRINTF("invalid quote %d\n", v.nQuote); + continue; + } + + G_PrintGameText(v.tilenum, v.pos.x >> 1, v.pos.y, apStrings[v.nQuote], v.shade, v.pal, v.orientation & (ROTATESPRITE_MAX - 1), + v.bound[0].x, v.bound[0].y, v.bound[1].x, v.bound[1].y, z, 0); + continue; + } + + case CON_DIGITALNUMBER: + case CON_DIGITALNUMBERZ: + insptr++; + { + struct + { + int32_t tilenum; + vec2_t pos; + int32_t nQuote, shade, pal, orientation; + vec2_t bound[2]; + } v; + Gv_FillWithVars(v); + + int32_t const nZoom = (tw == CON_DIGITALNUMBERZ) ? Gv_GetVarX(*insptr++) : 65536; + + // NOTE: '-' not taken into account, but we have rotatesprite() bound check now anyway + if (EDUKE32_PREDICT_FALSE(v.tilenum < 0 || v.tilenum + 9 >= MAXTILES)) + { + CON_ERRPRINTF("invalid base tilenum %d\n", v.tilenum); + continue; + } + + G_DrawTXDigiNumZ(v.tilenum, v.pos.x, v.pos.y, v.nQuote, v.shade, v.pal, v.orientation & (ROTATESPRITE_MAX - 1), v.bound[0].x, + v.bound[0].y, v.bound[1].x, v.bound[1].y, nZoom); + continue; + } + + case CON_MINITEXT: + insptr++; + { + struct + { + vec2_t pos; + int32_t nQuote, shade, pal; + } v; + Gv_FillWithVars(v); + + if (EDUKE32_PREDICT_FALSE((unsigned)v.nQuote >= MAXQUOTES || apStrings[v.nQuote] == NULL)) + { + CON_ERRPRINTF("invalid quote %d\n", v.nQuote); + continue; + } + + minitextshade(v.pos.x, v.pos.y, apStrings[v.nQuote], v.shade, v.pal, 2 + 8 + 16); + continue; + } + + case CON_SCREENTEXT: + insptr++; + { + struct + { + int32_t tilenum; + vec3_t v; + int32_t blockangle, charangle, nQuote, shade, pal, orientation, alpha; + vec2_t spacing, between; + int32_t nFlags; + vec2_t bound[2]; + } v; + Gv_FillWithVars(v); + + if (EDUKE32_PREDICT_FALSE(v.tilenum < 0 || v.tilenum + 127 >= MAXTILES)) + { + CON_ERRPRINTF("invalid base tilenum %d\n", v.tilenum); + continue; + } + + if (EDUKE32_PREDICT_FALSE((unsigned)v.nQuote >= MAXQUOTES || apStrings[v.nQuote] == NULL)) + { + CON_ERRPRINTF("invalid quote %d\n", v.nQuote); + continue; + } + + G_ScreenText(v.tilenum, v.v.x, v.v.y, v.v.z, v.blockangle, v.charangle, apStrings[v.nQuote], v.shade, v.pal, + 2 | (v.orientation & (ROTATESPRITE_MAX - 1)), v.alpha, v.spacing.x, v.spacing.y, v.between.x, v.between.y, v.nFlags, + v.bound[0].x, v.bound[0].y, v.bound[1].x, v.bound[1].y); + continue; + } + + case CON_ANGOFF: + insptr++; + spriteext[vm.spriteNum].angoff = *insptr++; + continue; + + case CON_GETZRANGE: + insptr++; + { + struct + { + vec3_t vect; + int32_t sectNum; + } v; + Gv_FillWithVars(v); + + int const ceilzvar = *insptr++; + int const ceilhitvar = *insptr++; + int const florzvar = *insptr++; + int const florhitvar = *insptr++; + + struct + { + int32_t walldist, clipmask; + } v2; + Gv_FillWithVars(v2); + + if (EDUKE32_PREDICT_FALSE((unsigned)v.sectNum >= (unsigned)numsectors)) + { + CON_ERRPRINTF("invalid sector %d\n", v.sectNum); + continue; + } + + int32_t ceilz, ceilhit, florz, florhit; + + getzrange(&v.vect, v.sectNum, &ceilz, &ceilhit, &florz, &florhit, v2.walldist, v2.clipmask); + Gv_SetVarX(ceilzvar, ceilz); + Gv_SetVarX(ceilhitvar, ceilhit); + Gv_SetVarX(florzvar, florz); + Gv_SetVarX(florhitvar, florhit); + + continue; + } + + case CON_SECTSETINTERPOLATION: + case CON_SECTCLEARINTERPOLATION: + insptr++; + { + int const sectnum = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)sectnum >= (unsigned)numsectors)) + { + CON_ERRPRINTF("invalid sector %d\n", sectnum); + continue; + } + + if (tw == CON_SECTSETINTERPOLATION) + Sect_SetInterpolation(sectnum); + else + Sect_ClearInterpolation(sectnum); + + continue; + } + + case CON_CALCHYPOTENUSE: + insptr++; + { + int32_t returnVar = *insptr++; + vec2_t da; + Gv_FillWithVars(da); + int64_t const hypsq = (int64_t)da.x * da.x + (int64_t)da.y * da.y; + + Gv_SetVarX(returnVar, (hypsq > (int64_t)INT32_MAX) ? (int32_t)sqrt((double)hypsq) : ksqrt((uint32_t)hypsq)); + continue; + } + + case CON_LINEINTERSECT: + case CON_RAYINTERSECT: + insptr++; + { + struct + { + vec3_t vec[2]; + vec2_t vec2[2]; + } v; + Gv_FillWithVars(v); + + int const intxvar = *insptr++; + int const intyvar = *insptr++; + int const intzvar = *insptr++; + int const retvar = *insptr++; + vec3_t in; + + int ret = ((tw == CON_LINEINTERSECT) ? lintersect : rayintersect)(v.vec[0].x, v.vec[0].y, v.vec[0].z, v.vec[1].x, v.vec[1].y, + v.vec[1].z, v.vec2[0].x, v.vec2[0].y, v.vec2[1].x, v.vec2[1].y, + &in.x, &in.y, &in.z); + + Gv_SetVarX(retvar, ret); + + if (ret) + { + Gv_SetVarX(intxvar, in.x); + Gv_SetVarX(intyvar, in.y); + Gv_SetVarX(intzvar, in.z); + } + + continue; + } + + case CON_CLIPMOVE: + case CON_CLIPMOVENOSLIDE: + insptr++; + { + typedef struct + { + int32_t w, f, c; + } vec3dist_t; + + int const returnVar = *insptr++; + int const xReturn = *insptr++; + int const yReturn = *insptr++; + + insptr -= 2; + + typedef struct + { + vec3_t vec3; + int32_t sectNum32; + vec2_t vec2; + vec3dist_t dist; + int32_t clipMask; + } clipmoveparams_t; + + int32_t const sectReturn = insptr[offsetof(clipmoveparams_t, sectNum32) / sizeof(int32_t)]; + + clipmoveparams_t v; + Gv_FillWithVars(v); + int16_t sectNum = v.sectNum32; + + if (EDUKE32_PREDICT_FALSE((unsigned)sectNum >= (unsigned)numsectors)) + { + CON_ERRPRINTF("invalid sector %d\n", sectNum); + Gv_SetVarX(returnVar, 0); + continue; + } + + Gv_SetVarX( + returnVar, + clipmovex(&v.vec3, §Num, v.vec2.x, v.vec2.y, v.dist.w, v.dist.f, v.dist.c, v.clipMask, (tw == CON_CLIPMOVENOSLIDE))); + Gv_SetVarX(sectReturn, v.sectNum32); + Gv_SetVarX(xReturn, v.vec3.x); + Gv_SetVarX(yReturn, v.vec3.y); + + continue; + } + + case CON_HITSCAN: + insptr++; + { + struct + { + vec3_t origin; + int32_t sectnum; + vec3_t vect; + } v; + Gv_FillWithVars(v); + + int const sectReturn = *insptr++; + int const wallReturn = *insptr++; + int const spriteReturn = *insptr++; + int const xReturn = *insptr++; + int const yReturn = *insptr++; + int const zReturn = *insptr++; + int const clipType = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)v.sectnum >= (unsigned)numsectors)) + { + CON_ERRPRINTF("invalid sector %d\n", v.sectnum); + continue; + } + + hitdata_t hit; + hitscan(&v.origin, v.sectnum, v.vect.x, v.vect.y, v.vect.z, &hit, clipType); + + Gv_SetVarX(sectReturn, hit.sect); + Gv_SetVarX(wallReturn, hit.wall); + Gv_SetVarX(spriteReturn, hit.sprite); + Gv_SetVarX(xReturn, hit.pos.x); + Gv_SetVarX(yReturn, hit.pos.y); + Gv_SetVarX(zReturn, hit.pos.z); + continue; + } + + case CON_CANSEE: + insptr++; + { + struct + { + vec3_t vec1; + int32_t firstSector; + vec3_t vec2; + int32_t secondSector; + } v; + Gv_FillWithVars(v); + + int const returnVar = *insptr++; + + if (EDUKE32_PREDICT_FALSE((unsigned)v.firstSector >= (unsigned)numsectors || (unsigned)v.secondSector >= (unsigned)numsectors)) + { + CON_ERRPRINTF("invalid sector %d\n", (unsigned)v.firstSector >= (unsigned)numsectors ? v.firstSector : v.secondSector); + Gv_SetVarX(returnVar, 0); + } + + Gv_SetVarX(returnVar, cansee(v.vec1.x, v.vec1.y, v.vec1.z, v.firstSector, v.vec2.x, v.vec2.y, v.vec2.z, v.secondSector)); + continue; + } + + case CON_ROTATEPOINT: + insptr++; + { + struct + { + vec2_t point[2]; + int32_t angle; + } v; + Gv_FillWithVars(v); + + int const xReturn = *insptr++; + int const yReturn = *insptr++; + vec2_t result; + + rotatepoint(v.point[0], v.point[1], v.angle, &result); + + Gv_SetVarX(xReturn, result.x); + Gv_SetVarX(yReturn, result.y); + continue; + } + + case CON_NEARTAG: + insptr++; + { + // neartag(int32_t x, int32_t y, int32_t z, short sectnum, short ang, //Starting position & angle + // short *neartagsector, //Returns near sector if sector[].tag != 0 + // short *neartagwall, //Returns near wall if wall[].tag != 0 + // short *neartagsprite, //Returns near sprite if sprite[].tag != 0 + // int32_t *neartaghitdist, //Returns actual distance to object (scale: 1024=largest grid size) + // int32_t neartagrange, //Choose maximum distance to scan (scale: 1024=largest grid size) + // char tagsearch) //1-lotag only, 2-hitag only, 3-lotag&hitag + + struct + { + vec3_t point; + int32_t sectNum, nAngle; + } v; + Gv_FillWithVars(v); + + int const sectReturn = *insptr++; + int const wallReturn = *insptr++; + int const spriteReturn = *insptr++; + int const distReturn = *insptr++; + + struct + { + int32_t tagRange, tagSearch; + } v2; + Gv_FillWithVars(v2); + + if (EDUKE32_PREDICT_FALSE((unsigned)v.sectNum >= (unsigned)numsectors)) + { + CON_ERRPRINTF("Invalid sector %d\n", v.sectNum); + continue; + } + + int16_t neartagsector, neartagwall, neartagsprite; + int32_t neartaghitdist; + + neartag(v.point.x, v.point.y, v.point.z, v.sectNum, v.nAngle, &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, + v2.tagRange, v2.tagSearch, NULL); + + Gv_SetVarX(sectReturn, neartagsector); + Gv_SetVarX(wallReturn, neartagwall); + Gv_SetVarX(spriteReturn, neartagsprite); + Gv_SetVarX(distReturn, neartaghitdist); + continue; + } + + case CON_GETTIMEDATE: + insptr++; + { + int32_t values[8]; + G_GetTimeDate(values); + + for (native_t i = 0; i < 8; i++) + Gv_SetVarX(*insptr++, values[i]); + + continue; + } + + case CON_MOVESPRITE: + insptr++; + { + struct + { + int32_t spriteNum; + vec3_t vect; + int32_t clipType; + } v; + Gv_FillWithVars(v); + + if (EDUKE32_PREDICT_FALSE((unsigned)v.spriteNum >= MAXSPRITES)) + { + CON_ERRPRINTF("invalid sprite %d\n", v.spriteNum); + insptr++; + continue; + } + + Gv_SetVarX(*insptr++, A_MoveSprite(v.spriteNum, &v.vect, v.clipType)); + continue; + } + + case CON_SETSPRITE: + insptr++; + { + struct + { + int32_t spriteNum; + vec3_t vect; + } v; + Gv_FillWithVars(v); + + if (EDUKE32_PREDICT_FALSE((unsigned)v.spriteNum >= MAXSPRITES)) + { + CON_ERRPRINTF("invalid sprite %d\n", v.spriteNum); + continue; + } + setsprite(v.spriteNum, &v.vect); + continue; + } + + case CON_GETFLORZOFSLOPE: + case CON_GETCEILZOFSLOPE: + insptr++; + { + struct + { + int32_t sectNum; + vec2_t vect; + } v; + Gv_FillWithVars(v); + + if (EDUKE32_PREDICT_FALSE((unsigned)v.sectNum >= (unsigned)numsectors)) + { + CON_ERRPRINTF("invalid sector %d\n", v.sectNum); + insptr++; + continue; + } + Gv_SetVarX(*insptr++, (tw == CON_GETFLORZOFSLOPE ? getflorzofslope : getceilzofslope)(v.sectNum, v.vect.x, v.vect.y)); + continue; + } + + case CON_UPDATESECTOR: + insptr++; + { + vec2_t vect = { 0, 0 }; + Gv_FillWithVars(vect); + + int const returnVar = *insptr++; + int16_t sectNum = sprite[vm.spriteNum].sectnum; + + updatesector(vect.x, vect.y, §Num); + Gv_SetVarX(returnVar, sectNum); + continue; + } + + case CON_UPDATESECTORZ: + insptr++; + { + vec3_t vect = { 0, 0, 0 }; + Gv_FillWithVars(vect); + + int const returnVar = *insptr++; + int16_t sectNum = sprite[vm.spriteNum].sectnum; + + updatesectorz(vect.x, vect.y, vect.z, §Num); + Gv_SetVarX(returnVar, sectNum); + continue; + } + + case CON_SPAWN: + insptr++; + if ((unsigned)vm.pSprite->sectnum >= MAXSECTORS) + { + CON_ERRPRINTF("invalid sector %d\n", vm.pUSprite->sectnum); + insptr++; + continue; + } + A_Spawn(vm.spriteNum, *insptr++); + continue; + + case CON_IFWASWEAPON: + case CON_IFSPAWNEDBY: + insptr++; + VM_CONDITIONAL(vm.pActor->picnum == *insptr); + continue; + + case CON_IFAI: + insptr++; + VM_CONDITIONAL(AC_AI_ID(vm.pData) == *insptr); + continue; + + case CON_IFACTION: + insptr++; + VM_CONDITIONAL(AC_ACTION_ID(vm.pData) == *insptr); + continue; + + case CON_IFACTIONCOUNT: + insptr++; + VM_CONDITIONAL(AC_ACTION_COUNT(vm.pData) >= *insptr); + continue; + + case CON_RESETACTIONCOUNT: + insptr++; + AC_ACTION_COUNT(vm.pData) = 0; + continue; + + case CON_DEBRIS: + insptr++; + { + int debrisTile = *insptr++; + + if ((unsigned)vm.pSprite->sectnum < MAXSECTORS) + for (native_t cnt = (*insptr) - 1; cnt >= 0; cnt--) + { + int const tileOffset = (vm.pSprite->picnum == BLIMP && debrisTile == SCRAP1) ? 0 : (krand() % 3); + + int const spriteNum = A_InsertSprite(vm.pSprite->sectnum, vm.pSprite->x + (krand() & 255) - 128, + vm.pSprite->y + (krand() & 255) - 128, vm.pSprite->z - (8 << 8) - (krand() & 8191), + debrisTile + tileOffset, vm.pSprite->shade, 32 + (krand() & 15), 32 + (krand() & 15), + krand() & 2047, (krand() & 127) + 32, -(krand() & 2047), vm.spriteNum, 5); + + sprite[spriteNum].yvel = (vm.pSprite->picnum == BLIMP && debrisTile == SCRAP1) ? g_blimpSpawnItems[cnt % 14] : -1; + sprite[spriteNum].pal = vm.pSprite->pal; + } + insptr++; + } + continue; + + case CON_COUNT: + insptr++; + AC_COUNT(vm.pData) = (int16_t)*insptr++; + continue; + + case CON_CSTATOR: + insptr++; + vm.pSprite->cstat |= (int16_t)*insptr++; + continue; + + case CON_CLIPDIST: + insptr++; + vm.pSprite->clipdist = (int16_t)*insptr++; + continue; + + case CON_CSTAT: + insptr++; + vm.pSprite->cstat = (int16_t)*insptr++; + continue; + + case CON_SAVENN: + case CON_SAVE: + insptr++; + { + int32_t const requestedSlot = *insptr++; + + if ((unsigned)requestedSlot >= 10) + continue; + + // check if we need to make a new file + if (strcmp(g_lastautosave.path, g_lastusersave.path) == 0 || requestedSlot != g_lastAutoSaveArbitraryID) + { + g_lastautosave.reset(); + } + + g_lastAutoSaveArbitraryID = requestedSlot; + + if (tw == CON_SAVE || g_lastautosave.name[0] == 0) + { + time_t timeStruct = time(NULL); + struct tm *pTime = localtime(&timeStruct); + + strftime(g_lastautosave.name, sizeof(g_lastautosave.name), "%d %b %Y %I:%M%p", pTime); + } + + g_saveRequested = true; + + continue; + } + + case CON_QUAKE: + insptr++; + g_earthquakeTime = Gv_GetVarX(*insptr++); + A_PlaySound(EARTHQUAKE, g_player[screenpeek].ps->i); + continue; + + case CON_IFMOVE: + insptr++; + VM_CONDITIONAL(AC_MOVE_ID(vm.pData) == *insptr); + continue; + + case CON_RESETPLAYER: + insptr++; + vm.flags = VM_ResetPlayer(vm.playerNum, vm.flags, 0); + continue; + + case CON_RESETPLAYERFLAGS: + insptr++; + vm.flags = VM_ResetPlayer(vm.playerNum, vm.flags, Gv_GetVarX(*insptr++)); + continue; + + case CON_IFONWATER: + VM_CONDITIONAL(sector[vm.pSprite->sectnum].lotag == ST_1_ABOVE_WATER + && klabs(vm.pSprite->z - sector[vm.pSprite->sectnum].floorz) < ZOFFSET5); + continue; + + case CON_IFINWATER: VM_CONDITIONAL(sector[vm.pSprite->sectnum].lotag == ST_2_UNDERWATER); continue; + + case CON_IFCOUNT: + insptr++; + VM_CONDITIONAL(AC_COUNT(vm.pData) >= *insptr); + continue; + + case CON_IFACTOR: + insptr++; + VM_CONDITIONAL(vm.pSprite->picnum == *insptr); + continue; + + case CON_RESETCOUNT: + insptr++; + AC_COUNT(vm.pData) = 0; + continue; + + case CON_ADDINVENTORY: + insptr += 2; + + VM_AddInventory(pPlayer, *(insptr - 1), *insptr); + + insptr++; + continue; + + case CON_HITRADIUSVAR: + insptr++; + { + int32_t params[5]; + Gv_FillWithVars(params); + A_RadiusDamage(vm.spriteNum, params[0], params[1], params[2], params[3], params[4]); + } + continue; + + case CON_HITRADIUS: + A_RadiusDamage(vm.spriteNum, *(insptr + 1), *(insptr + 2), *(insptr + 3), *(insptr + 4), *(insptr + 5)); + insptr += 6; + continue; + + case CON_IFP: + { + int const moveFlags = *(++insptr); + int nResult = 0; + int const playerXVel = sprite[pPlayer->i].xvel; + int const syncBits = g_player[vm.playerNum].inputBits->bits; + + if (((moveFlags & pducking) && pPlayer->on_ground && TEST_SYNC_KEY(syncBits, SK_CROUCH)) + || ((moveFlags & pfalling) && pPlayer->jumping_counter == 0 && !pPlayer->on_ground && pPlayer->vel.z > 2048) + || ((moveFlags & pjumping) && pPlayer->jumping_counter > 348) + || ((moveFlags & pstanding) && playerXVel >= 0 && playerXVel < 8) + || ((moveFlags & pwalking) && playerXVel >= 8 && !TEST_SYNC_KEY(syncBits, SK_RUN)) + || ((moveFlags & prunning) && playerXVel >= 8 && TEST_SYNC_KEY(syncBits, SK_RUN)) + || ((moveFlags & phigher) && pPlayer->pos.z < (vm.pSprite->z - (48 << 8))) + || ((moveFlags & pwalkingback) && playerXVel <= -8 && !TEST_SYNC_KEY(syncBits, SK_RUN)) + || ((moveFlags & prunningback) && playerXVel <= -8 && TEST_SYNC_KEY(syncBits, SK_RUN)) + || ((moveFlags & pkicking) + && (pPlayer->quick_kick > 0 + || (PWEAPON(vm.playerNum, pPlayer->curr_weapon, WorksLike) == KNEE_WEAPON && pPlayer->kickback_pic > 0))) + || ((moveFlags & pshrunk) && sprite[pPlayer->i].xrepeat < 32) + || ((moveFlags & pjetpack) && pPlayer->jetpack_on) + || ((moveFlags & ponsteroids) && pPlayer->inv_amount[GET_STEROIDS] > 0 && pPlayer->inv_amount[GET_STEROIDS] < 400) + || ((moveFlags & ponground) && pPlayer->on_ground) + || ((moveFlags & palive) && sprite[pPlayer->i].xrepeat > 32 && sprite[pPlayer->i].extra > 0 && pPlayer->timebeforeexit == 0) + || ((moveFlags & pdead) && sprite[pPlayer->i].extra <= 0)) + nResult = 1; + else if ((moveFlags & pfacing)) + { + nResult + = (vm.pSprite->picnum == APLAYER && (g_netServer || ud.multimode > 1)) + ? G_GetAngleDelta(fix16_to_int(g_player[otherp].ps->q16ang), + getangle(pPlayer->pos.x - g_player[otherp].ps->pos.x, pPlayer->pos.y - g_player[otherp].ps->pos.y)) + : G_GetAngleDelta(fix16_to_int(pPlayer->q16ang), getangle(vm.pSprite->x - pPlayer->pos.x, vm.pSprite->y - pPlayer->pos.y)); + + nResult = (nResult > -128 && nResult < 128); + } + VM_CONDITIONAL(nResult); + } + continue; + + case CON_IFSTRENGTH: + insptr++; + VM_CONDITIONAL(vm.pSprite->extra <= *insptr); + continue; + + case CON_GUTS: + A_DoGuts(vm.spriteNum, *(insptr + 1), *(insptr + 2)); + insptr += 3; + continue; + + case CON_WACKPLAYER: + insptr++; + P_ForceAngle(pPlayer); + continue; + + case CON_FLASH: + insptr++; + sprite[vm.spriteNum].shade = -127; + pPlayer->visibility = -127; + continue; + + case CON_SAVEMAPSTATE: + G_SaveMapState(); + insptr++; + continue; + + case CON_LOADMAPSTATE: + G_RestoreMapState(); + insptr++; + continue; + + case CON_CLEARMAPSTATE: + insptr++; + { + int const levelNum = Gv_GetVarX(*insptr++); + if (EDUKE32_PREDICT_FALSE((unsigned)levelNum >= MAXVOLUMES * MAXLEVELS)) + { + CON_ERRPRINTF("invalid map number %d\n", levelNum); + continue; + } + + G_FreeMapState(levelNum); + } + continue; + + case CON_STOPALLSOUNDS: + insptr++; + if (screenpeek == vm.playerNum) + FX_StopAllSounds(); + continue; + + case CON_STOPALLMUSIC: + insptr++; + S_StopMusic(); + continue; + + case CON_IFGAPZL: + insptr++; + VM_CONDITIONAL(((vm.pActor->floorz - vm.pActor->ceilingz) >> 8) < *insptr); + continue; + + case CON_IFHITSPACE: VM_CONDITIONAL(TEST_SYNC_KEY(g_player[vm.playerNum].inputBits->bits, SK_OPEN)); continue; + + case CON_IFOUTSIDE: VM_CONDITIONAL(sector[vm.pSprite->sectnum].ceilingstat & 1); continue; + + case CON_IFMULTIPLAYER: VM_CONDITIONAL((g_netServer || g_netClient || ud.multimode > 1)); continue; + + case CON_IFCLIENT: VM_CONDITIONAL(g_netClient != NULL); continue; + + case CON_IFSERVER: VM_CONDITIONAL(g_netServer != NULL); continue; + + case CON_IFPLAYBACKON: VM_CONDITIONAL(0); continue; + + case CON_OPERATE: + insptr++; + if (sector[vm.pSprite->sectnum].lotag == 0) + { + int16_t foundSect, foundWall, foundSprite; + int32_t foundDist; + + neartag(vm.pSprite->x, vm.pSprite->y, vm.pSprite->z - ZOFFSET5, vm.pSprite->sectnum, vm.pSprite->ang, &foundSect, &foundWall, + &foundSprite, &foundDist, 768, 4 + 1, NULL); + + if (foundSect >= 0 && isanearoperator(sector[foundSect].lotag)) + if ((sector[foundSect].lotag & 0xff) == ST_23_SWINGING_DOOR || sector[foundSect].floorz == sector[foundSect].ceilingz) + if ((sector[foundSect].lotag & (16384u | 32768u)) == 0) + { + int32_t j; + + for (SPRITES_OF_SECT(foundSect, j)) + if (sprite[j].picnum == ACTIVATOR) + break; + + if (j == -1) + G_OperateSectors(foundSect, vm.spriteNum); + } + } + continue; + + case CON_IFINSPACE: VM_CONDITIONAL(G_CheckForSpaceCeiling(vm.pSprite->sectnum)); continue; + + case CON_SPRITEPAL: + insptr++; + if (vm.pSprite->picnum != APLAYER) + vm.pActor->tempang = vm.pSprite->pal; + vm.pSprite->pal = *insptr++; + continue; + + case CON_CACTOR: + insptr++; + vm.pSprite->picnum = *insptr++; + continue; + + case CON_IFBULLETNEAR: VM_CONDITIONAL(A_Dodge(vm.pSprite) == 1); continue; + + case CON_IFRESPAWN: + if (A_CheckEnemySprite(vm.pSprite)) + VM_CONDITIONAL(ud.respawn_monsters) + else if (A_CheckInventorySprite(vm.pSprite)) + VM_CONDITIONAL(ud.respawn_inventory) + else + VM_CONDITIONAL(ud.respawn_items) + continue; + + case CON_IFFLOORDISTL: + insptr++; + VM_CONDITIONAL((vm.pActor->floorz - vm.pSprite->z) <= ((*insptr) << 8)); + continue; + + case CON_IFCEILINGDISTL: + insptr++; + VM_CONDITIONAL((vm.pSprite->z - vm.pActor->ceilingz) <= ((*insptr) << 8)); + continue; + + case CON_PALFROM: + insptr++; + if (EDUKE32_PREDICT_FALSE((unsigned)vm.playerNum >= (unsigned)g_mostConcurrentPlayers)) + { + CON_ERRPRINTF("invalid player %d\n", vm.playerNum); + insptr += 4; + } + else + { + palette_t const pal = { (uint8_t) * (insptr + 1), (uint8_t) * (insptr + 2), (uint8_t) * (insptr + 3), (uint8_t) * (insptr) }; + insptr += 4; + P_PalFrom(pPlayer, pal.f, pal.r, pal.g, pal.b); + } + continue; + + case CON_SCREENPAL: + insptr++; + { + int32_t params[4]; + Gv_FillWithVars(params); + videoFadePalette(params[0], params[1], params[2], params[3]); + } + continue; + + case CON_SECTOROFWALL: + insptr++; + tw = *insptr++; + Gv_SetVarX(tw, sectorofwall(Gv_GetVarX(*insptr++))); + continue; + + case CON_QSPRINTF: + insptr++; + { + int const outputQuote = Gv_GetVarX(*insptr++); + int const inputQuote = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE(apStrings[inputQuote] == NULL || apStrings[outputQuote] == NULL)) + { + CON_ERRPRINTF("null quote %d\n", apStrings[inputQuote] ? outputQuote : inputQuote); + + while ((*insptr & VM_INSTMASK) != CON_NULLOP) + Gv_GetVarX(*insptr++); + + insptr++; // skip the NOP + continue; + } + + int32_t arg[32]; + int const quoteLen = Bstrlen(apStrings[inputQuote]); + int inputPos = 0; + char outBuf[MAXQUOTELEN]; + int outBufPos = 0; + int argIdx = 0; + + while ((*insptr & VM_INSTMASK) != CON_NULLOP && argIdx < 32) + arg[argIdx++] = Gv_GetVarX(*insptr++); + + int numArgs = argIdx; + + insptr++; // skip the NOP + + argIdx = 0; + + do + { + while (inputPos < quoteLen && outBufPos < MAXQUOTELEN && apStrings[inputQuote][inputPos] != '%') + outBuf[outBufPos++] = apStrings[inputQuote][inputPos++]; + + if (apStrings[inputQuote][inputPos] == '%') + { + inputPos++; + switch (apStrings[inputQuote][inputPos]) + { + case 'l': + if (apStrings[inputQuote][inputPos + 1] != 'd') + { + // write the % and l + outBuf[outBufPos++] = apStrings[inputQuote][inputPos - 1]; + outBuf[outBufPos++] = apStrings[inputQuote][inputPos++]; + break; + } + inputPos++; + fallthrough__; + case 'd': + { + if (argIdx >= numArgs) + goto finish_qsprintf; + + char buf[16]; + Bsprintf(buf, "%d", arg[argIdx++]); + + int const bufLen = Bstrlen(buf); + Bmemcpy(&outBuf[outBufPos], buf, bufLen); + outBufPos += bufLen; + inputPos++; + } + break; + + case 's': + { + if (argIdx >= numArgs) + goto finish_qsprintf; + + int const argLen = Bstrlen(apStrings[arg[argIdx]]); + + Bmemcpy(&outBuf[outBufPos], apStrings[arg[argIdx]], argLen); + outBufPos += argLen; + argIdx++; + inputPos++; + } + break; + + default: outBuf[outBufPos++] = apStrings[inputQuote][inputPos - 1]; break; + } + } + } while (inputPos < quoteLen && outBufPos < MAXQUOTELEN); + finish_qsprintf: + outBuf[outBufPos] = '\0'; + Bstrncpyz(apStrings[outputQuote], outBuf, MAXQUOTELEN); + continue; + } + + case CON_ADDLOG: + { + insptr++; + + initprintf(OSDTEXT_GREEN "CONLOG: L=%d\n", g_errorLineNum); + continue; + } + + case CON_ADDLOGVAR: + insptr++; + { + int32_t m = 1; + char szBuf[256]; + int32_t lVarID = *insptr; + + if ((lVarID >= g_gameVarCount) || lVarID < 0) + { + if (*insptr == MAXGAMEVARS) // addlogvar for a constant? Har. + insptr++; + // else if (*insptr > g_gameVarCount && (*insptr < (MAXGAMEVARS<<1)+MAXGAMEVARS+1+MAXGAMEARRAYS)) + else if (*insptr & (MAXGAMEVARS << 2)) + { + int32_t index; + + lVarID ^= (MAXGAMEVARS << 2); + + if (lVarID & (MAXGAMEVARS << 1)) + { + m = -m; + lVarID ^= (MAXGAMEVARS << 1); + } + + insptr++; + + index = Gv_GetVarX(*insptr++); + if (EDUKE32_PREDICT_TRUE((unsigned)index < (unsigned)aGameArrays[lVarID].size)) + { + initprintf(OSDTEXT_GREEN "CONLOGVAR: L=%d %s[%d] =%d\n", g_errorLineNum, aGameArrays[lVarID].szLabel, index, + (int32_t)(m * Gv_GetArrayValue(lVarID, index))); + continue; + } + else + { + CON_ERRPRINTF("invalid array index\n"); + continue; + } + } + else if (*insptr & (MAXGAMEVARS << 3)) + { + // FIXME FIXME FIXME + if ((lVarID & (MAXGAMEVARS - 1)) == g_structVarIDs + STRUCT_ACTORVAR) + { + intptr_t const *oinsptr = insptr++; + int32_t index = Gv_GetVarX(*insptr++); + insptr = oinsptr; + if (EDUKE32_PREDICT_FALSE((unsigned)index >= MAXSPRITES - 1)) + { + CON_ERRPRINTF("invalid array index\n"); + Gv_GetVarX(*insptr++); + continue; + } + initprintf(OSDTEXT_GREEN "CONLOGVAR: L=%d %d %d\n", g_errorLineNum, index, Gv_GetVar(*insptr++, index, vm.playerNum)); + continue; + } + } + else if (EDUKE32_PREDICT_TRUE(*insptr & (MAXGAMEVARS << 1))) { m = -m; - lVarID ^= (MAXGAMEVARS<<1); - } - - insptr++; - - index=Gv_GetVarX(*insptr++); - if (EDUKE32_PREDICT_TRUE((unsigned)index < (unsigned)aGameArrays[lVarID].size)) - { - initprintf(OSDTEXT_GREEN "CONLOGVAR: L=%d %s[%d] =%d\n", g_errorLineNum, - aGameArrays[lVarID].szLabel, index, - (int32_t)(m*Gv_GetArrayValue(lVarID, index))); - continue; + lVarID ^= (MAXGAMEVARS << 1); } else { - CON_ERRPRINTF("invalid array index\n"); - continue; + // invalid varID + insptr++; + CON_ERRPRINTF("invalid variable\n"); + continue; // out of switch } } - else if (*insptr&(MAXGAMEVARS<<3)) + Bsprintf(tempbuf, "CONLOGVAR: L=%d %s ", g_errorLineNum, aGameVars[lVarID].szLabel); + + if (aGameVars[lVarID].flags & GAMEVAR_READONLY) { - // FIXME FIXME FIXME - if ((lVarID & (MAXGAMEVARS-1)) == g_structVarIDs + STRUCT_ACTORVAR) - { - intptr_t const *oinsptr = insptr++; - int32_t index = Gv_GetVarX(*insptr++); - insptr = oinsptr; - if (EDUKE32_PREDICT_FALSE((unsigned)index >= MAXSPRITES-1)) - { - CON_ERRPRINTF("invalid array index\n"); - Gv_GetVarX(*insptr++); - continue; - } - initprintf(OSDTEXT_GREEN "CONLOGVAR: L=%d %d %d\n",g_errorLineNum,index,Gv_GetVar(*insptr++,index,vm.playerNum)); - continue; - } + Bsprintf(szBuf, " (read-only)"); + Bstrcat(tempbuf, szBuf); } - else if (EDUKE32_PREDICT_TRUE(*insptr&(MAXGAMEVARS<<1))) + if (aGameVars[lVarID].flags & GAMEVAR_PERPLAYER) { - m = -m; - lVarID ^= (MAXGAMEVARS<<1); + Bsprintf(szBuf, " (Per Player. Player=%d)", vm.playerNum); + } + else if (aGameVars[lVarID].flags & GAMEVAR_PERACTOR) + { + Bsprintf(szBuf, " (Per Actor. Actor=%d)", vm.spriteNum); } else { - // invalid varID - insptr++; - CON_ERRPRINTF("invalid variable\n"); - continue; // out of switch + Bsprintf(szBuf, " (Global)"); } + Bstrcat(tempbuf, szBuf); + Bsprintf(szBuf, " =%d\n", Gv_GetVarX(lVarID) * m); + Bstrcat(tempbuf, szBuf); + initprintf(OSDTEXT_GREEN "%s", tempbuf); + insptr++; + continue; } - Bsprintf(tempbuf,"CONLOGVAR: L=%d %s ",g_errorLineNum, aGameVars[lVarID].szLabel); - if (aGameVars[lVarID].flags & GAMEVAR_READONLY) - { - Bsprintf(szBuf," (read-only)"); - Bstrcat(tempbuf,szBuf); - } - if (aGameVars[lVarID].flags & GAMEVAR_PERPLAYER) - { - Bsprintf(szBuf," (Per Player. Player=%d)",vm.playerNum); - } - else if (aGameVars[lVarID].flags & GAMEVAR_PERACTOR) - { - Bsprintf(szBuf," (Per Actor. Actor=%d)",vm.spriteNum); - } - else - { - Bsprintf(szBuf," (Global)"); - } - Bstrcat(tempbuf, szBuf); - Bsprintf(szBuf, " =%d\n", Gv_GetVarX(lVarID) * m); - Bstrcat(tempbuf, szBuf); - initprintf(OSDTEXT_GREEN "%s", tempbuf); + case CON_SETSECTOR: insptr++; - continue; - } - - case CON_SETSECTOR: - insptr++; - { - int const sectNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : sprite[vm.spriteNum].sectnum; - int const labelNum = *insptr++; - - VM_SetSector(sectNum, labelNum, Gv_GetVarX(*insptr++)); - continue; - } - - case CON_GETSECTOR: - insptr++; - { - int const sectNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : sprite[vm.spriteNum].sectnum; - int const labelNum = *insptr++; - - Gv_SetVarX(*insptr++, VM_GetSector(sectNum, labelNum)); - continue; - } - - case CON_SQRT: - insptr++; - { - // syntax sqrt - int const sqrtval = ksqrt((uint32_t)Gv_GetVarX(*insptr++)); - Gv_SetVarX(*insptr++, sqrtval); - continue; - } - - case CON_FINDNEARACTORVAR: - case CON_FINDNEARSPRITEVAR: - case CON_FINDNEARACTOR3DVAR: - case CON_FINDNEARSPRITE3DVAR: - insptr++; - { - // syntax findnearactorvar - // gets the sprite ID of the nearest actor within max dist - // that is of into - // -1 for none found - // - int const findPicnum = *insptr++; - int const maxDist = Gv_GetVarX(*insptr++); - int const returnVar = *insptr++; - - int foundSprite = -1; - int findStatnum = STAT_ACTOR; - int spriteNum; - - if (tw == CON_FINDNEARSPRITEVAR || tw == CON_FINDNEARSPRITE3DVAR) - findStatnum = MAXSTATUS-1; - - if (tw==CON_FINDNEARACTOR3DVAR || tw==CON_FINDNEARSPRITE3DVAR) { + int const sectNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : sprite[vm.spriteNum].sectnum; + int const labelNum = *insptr++; + + VM_SetSector(sectNum, labelNum, Gv_GetVarX(*insptr++)); + continue; + } + + case CON_GETSECTOR: + insptr++; + { + int const sectNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : sprite[vm.spriteNum].sectnum; + int const labelNum = *insptr++; + + Gv_SetVarX(*insptr++, VM_GetSector(sectNum, labelNum)); + continue; + } + + case CON_SQRT: + insptr++; + { + // syntax sqrt + int const sqrtval = ksqrt((uint32_t)Gv_GetVarX(*insptr++)); + Gv_SetVarX(*insptr++, sqrtval); + continue; + } + + case CON_FINDNEARACTORVAR: + case CON_FINDNEARSPRITEVAR: + case CON_FINDNEARACTOR3DVAR: + case CON_FINDNEARSPRITE3DVAR: + insptr++; + { + // syntax findnearactorvar + // gets the sprite ID of the nearest actor within max dist + // that is of into + // -1 for none found + // + int const findPicnum = *insptr++; + int const maxDist = Gv_GetVarX(*insptr++); + int const returnVar = *insptr++; + + int foundSprite = -1; + int findStatnum = STAT_ACTOR; + int spriteNum; + + if (tw == CON_FINDNEARSPRITEVAR || tw == CON_FINDNEARSPRITE3DVAR) + findStatnum = MAXSTATUS - 1; + + if (tw == CON_FINDNEARACTOR3DVAR || tw == CON_FINDNEARSPRITE3DVAR) + { + do + { + spriteNum = headspritestat[findStatnum]; // all sprites + + while (spriteNum >= 0) + { + if (sprite[spriteNum].picnum == findPicnum && spriteNum != vm.spriteNum + && dist(&sprite[vm.spriteNum], &sprite[spriteNum]) < maxDist) + { + foundSprite = spriteNum; + spriteNum = MAXSPRITES; + break; + } + spriteNum = nextspritestat[spriteNum]; + } + if (spriteNum == MAXSPRITES || tw == CON_FINDNEARACTOR3DVAR) + break; + } while (findStatnum--); + Gv_SetVarX(returnVar, foundSprite); + continue; + } + do { - spriteNum=headspritestat[findStatnum]; // all sprites + spriteNum = headspritestat[findStatnum]; // all sprites while (spriteNum >= 0) { - if (sprite[spriteNum].picnum == findPicnum && spriteNum != vm.spriteNum && dist(&sprite[vm.spriteNum], &sprite[spriteNum]) < maxDist) + if (sprite[spriteNum].picnum == findPicnum && spriteNum != vm.spriteNum + && ldist(&sprite[vm.spriteNum], &sprite[spriteNum]) < maxDist) { - foundSprite=spriteNum; - spriteNum = MAXSPRITES; + foundSprite = spriteNum; + spriteNum = MAXSPRITES; break; } spriteNum = nextspritestat[spriteNum]; } - if (spriteNum == MAXSPRITES || tw==CON_FINDNEARACTOR3DVAR) + + if (spriteNum == MAXSPRITES || tw == CON_FINDNEARACTORVAR) break; - } - while (findStatnum--); + } while (findStatnum--); Gv_SetVarX(returnVar, foundSprite); continue; } - do + case CON_FINDNEARACTORZVAR: + case CON_FINDNEARSPRITEZVAR: + insptr++; { - spriteNum=headspritestat[findStatnum]; // all sprites + // syntax findnearactorvar + // gets the sprite ID of the nearest actor within max dist + // that is of into + // -1 for none found + // + int const findPicnum = *insptr++; + int const maxDist = Gv_GetVarX(*insptr++); + int const maxZDist = Gv_GetVarX(*insptr++); + int const returnVar = *insptr++; - while (spriteNum >= 0) - { - if (sprite[spriteNum].picnum == findPicnum && spriteNum != vm.spriteNum && ldist(&sprite[vm.spriteNum], &sprite[spriteNum]) < maxDist) - { - foundSprite=spriteNum; - spriteNum = MAXSPRITES; - break; - } - spriteNum = nextspritestat[spriteNum]; - } + int foundSprite = -1; + int findStatnum = MAXSTATUS - 1; - if (spriteNum == MAXSPRITES || tw==CON_FINDNEARACTORVAR) - break; - } - while (findStatnum--); - Gv_SetVarX(returnVar, foundSprite); - continue; - } - - case CON_FINDNEARACTORZVAR: - case CON_FINDNEARSPRITEZVAR: - insptr++; - { - // syntax findnearactorvar - // gets the sprite ID of the nearest actor within max dist - // that is of into - // -1 for none found - // - int const findPicnum = *insptr++; - int const maxDist = Gv_GetVarX(*insptr++); - int const maxZDist = Gv_GetVarX(*insptr++); - int const returnVar = *insptr++; - - int foundSprite = -1; - int findStatnum = MAXSTATUS - 1; - - do - { - int spriteNum = headspritestat[tw == CON_FINDNEARACTORZVAR ? STAT_ACTOR : findStatnum]; // all sprites - - if (spriteNum == -1) - continue; do { - if (sprite[spriteNum].picnum == findPicnum && spriteNum != vm.spriteNum) + int spriteNum = headspritestat[tw == CON_FINDNEARACTORZVAR ? STAT_ACTOR : findStatnum]; // all sprites + + if (spriteNum == -1) + continue; + do { - if (ldist(&sprite[vm.spriteNum], &sprite[spriteNum]) < maxDist) + if (sprite[spriteNum].picnum == findPicnum && spriteNum != vm.spriteNum) { - if (klabs(sprite[vm.spriteNum].z-sprite[spriteNum].z) < maxZDist) + if (ldist(&sprite[vm.spriteNum], &sprite[spriteNum]) < maxDist) { - foundSprite = spriteNum; - spriteNum = MAXSPRITES; - break; + if (klabs(sprite[vm.spriteNum].z - sprite[spriteNum].z) < maxZDist) + { + foundSprite = spriteNum; + spriteNum = MAXSPRITES; + break; + } } } - } - spriteNum = nextspritestat[spriteNum]; - } - while (spriteNum>=0); + spriteNum = nextspritestat[spriteNum]; + } while (spriteNum >= 0); - if (tw==CON_FINDNEARACTORZVAR || spriteNum == MAXSPRITES) - break; - } - while (findStatnum--); - Gv_SetVarX(returnVar, foundSprite); - - continue; - } - - case CON_FINDPLAYER: - insptr++; - aGameVars[g_returnVarID].global = A_FindPlayer(&sprite[vm.spriteNum], &tw); - Gv_SetVarX(*insptr++, tw); - continue; - - case CON_FINDOTHERPLAYER: - insptr++; - aGameVars[g_returnVarID].global = P_FindOtherPlayer(vm.playerNum,&tw); - Gv_SetVarX(*insptr++, tw); - continue; - - case CON_SETPLAYER: - insptr++; - { - int const playerNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.playerNum; - int const labelNum = *insptr++; - int const lParm2 = (PlayerLabels[labelNum].flags & LABEL_HASPARM2) ? Gv_GetVarX(*insptr++) : 0; - - VM_SetPlayer(playerNum, labelNum, lParm2, Gv_GetVarX(*insptr++)); - continue; - } - - case CON_GETPLAYER: - insptr++; - { - int const playerNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.playerNum; - int const labelNum = *insptr++; - int const lParm2 = (PlayerLabels[labelNum].flags & LABEL_HASPARM2) ? Gv_GetVarX(*insptr++) : 0; - - Gv_SetVarX(*insptr++, VM_GetPlayer(playerNum, labelNum, lParm2)); - continue; - } - - case CON_GETINPUT: - insptr++; - { - int const playerNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.playerNum; - int const labelNum = *insptr++; - - Gv_SetVarX(*insptr++, VM_GetPlayerInput(playerNum, labelNum)); - continue; - } - - case CON_SETINPUT: - insptr++; - { - int const playerNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.playerNum; - int const labelNum = *insptr++; - - VM_SetPlayerInput(playerNum, labelNum, Gv_GetVarX(*insptr++)); - continue; - } - - case CON_GETUSERDEF: - insptr++; - { - int const labelNum = *insptr++; - int const lParm2 = (UserdefsLabels[labelNum].flags & LABEL_HASPARM2) ? Gv_GetVarX(*insptr++) : 0; - - Gv_SetVarX(*insptr++, VM_GetUserdef(labelNum, lParm2)); - continue; - } - - case CON_GETTILEDATA: - insptr++; - { - int const tileNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.pSprite->picnum; - int const labelNum = *insptr++; - - Gv_SetVarX(*insptr++, VM_GetTileData(tileNum, labelNum)); - continue; - } - - case CON_SETTILEDATA: - insptr++; - { - int const tileNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.pSprite->picnum; - int const labelNum = *insptr++; - - VM_SetTileData(tileNum, labelNum, Gv_GetVarX(*insptr++)); - continue; - } - - case CON_SETUSERDEF: - insptr++; - { - int const labelNum = *insptr++; - int const lParm2 = (UserdefsLabels[labelNum].flags & LABEL_HASPARM2) ? Gv_GetVarX(*insptr++) : 0; - - VM_SetUserdef(labelNum, lParm2, Gv_GetVarX(*insptr++)); - continue; - } - - case CON_GETPROJECTILE: - insptr++; - { - tw = Gv_GetVarX(*insptr++); - int const labelNum = *insptr++; - Gv_SetVarX(*insptr++, VM_GetProjectile(tw, labelNum)); - continue; - } - - case CON_SETPROJECTILE: - insptr++; - { - tw = Gv_GetVarX(*insptr++); - int const labelNum = *insptr++; - VM_SetProjectile(tw, labelNum, Gv_GetVarX(*insptr++)); - continue; - } - - case CON_SETWALL: - insptr++; - { - tw = *insptr++; - - int const wallNum = Gv_GetVarX(tw); - int const labelNum = *insptr++; - - VM_SetWall(wallNum, labelNum, Gv_GetVarX(*insptr++)); - continue; - } - - case CON_GETWALL: - insptr++; - { - tw = *insptr++; - - int const wallNum = Gv_GetVarX(tw); - int const labelNum = *insptr++; - - Gv_SetVarX(*insptr++, VM_GetWall(wallNum, labelNum)); - continue; - } - - case CON_SETACTORVAR: - case CON_GETACTORVAR: - insptr++; - { - int const lSprite = Gv_GetVarX(*insptr++); - int const lVar1 = *insptr++; - int const lVar2 = *insptr++; - - if (EDUKE32_PREDICT_FALSE((unsigned)lSprite >= MAXSPRITES)) - { - CON_ERRPRINTF("invalid sprite %d\n", lSprite); - - if (lVar1 == MAXGAMEVARS || lVar1 & ((MAXGAMEVARS << 2) | (MAXGAMEVARS << 3))) - insptr++; - - if (lVar2 == MAXGAMEVARS || lVar2 & ((MAXGAMEVARS << 2) | (MAXGAMEVARS << 3))) - insptr++; + if (tw == CON_FINDNEARACTORZVAR || spriteNum == MAXSPRITES) + break; + } while (findStatnum--); + Gv_SetVarX(returnVar, foundSprite); continue; } - if (tw == CON_SETACTORVAR) - Gv_SetVar(lVar1, Gv_GetVarX(lVar2), lSprite, vm.playerNum); - else - Gv_SetVarX(lVar2, Gv_GetVar(lVar1, lSprite, vm.playerNum)); - + case CON_FINDPLAYER: + { + int32_t tw; + insptr++; + aGameVars[g_returnVarID].global = A_FindPlayer(&sprite[vm.spriteNum], &tw); + Gv_SetVarX(*insptr++, tw); continue; } - case CON_SETPLAYERVAR: - case CON_GETPLAYERVAR: - insptr++; + case CON_FINDOTHERPLAYER: { - int const playerNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.playerNum; - int const lVar1 = *insptr++; - int const lVar2 = *insptr++; + int32_t tw; + insptr++; + aGameVars[g_returnVarID].global = P_FindOtherPlayer(vm.playerNum, &tw); + Gv_SetVarX(*insptr++, tw); + continue; + } + + case CON_SETPLAYER: + insptr++; + { + int const playerNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.playerNum; + int const labelNum = *insptr++; + int const lParm2 = (PlayerLabels[labelNum].flags & LABEL_HASPARM2) ? Gv_GetVarX(*insptr++) : 0; + + VM_SetPlayer(playerNum, labelNum, lParm2, Gv_GetVarX(*insptr++)); + continue; + } + + case CON_GETPLAYER: + insptr++; + { + int const playerNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.playerNum; + int const labelNum = *insptr++; + int const lParm2 = (PlayerLabels[labelNum].flags & LABEL_HASPARM2) ? Gv_GetVarX(*insptr++) : 0; + + Gv_SetVarX(*insptr++, VM_GetPlayer(playerNum, labelNum, lParm2)); + continue; + } + + case CON_GETINPUT: + insptr++; + { + int const playerNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.playerNum; + int const labelNum = *insptr++; + + Gv_SetVarX(*insptr++, VM_GetPlayerInput(playerNum, labelNum)); + continue; + } + + case CON_SETINPUT: + insptr++; + { + int const playerNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.playerNum; + int const labelNum = *insptr++; + + VM_SetPlayerInput(playerNum, labelNum, Gv_GetVarX(*insptr++)); + continue; + } + + case CON_GETUSERDEF: + insptr++; + { + int const labelNum = *insptr++; + int const lParm2 = (UserdefsLabels[labelNum].flags & LABEL_HASPARM2) ? Gv_GetVarX(*insptr++) : 0; + + Gv_SetVarX(*insptr++, VM_GetUserdef(labelNum, lParm2)); + continue; + } + + case CON_GETTILEDATA: + insptr++; + { + int const tileNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.pSprite->picnum; + int const labelNum = *insptr++; + + Gv_SetVarX(*insptr++, VM_GetTileData(tileNum, labelNum)); + continue; + } + + case CON_SETTILEDATA: + insptr++; + { + int const tileNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.pSprite->picnum; + int const labelNum = *insptr++; + + VM_SetTileData(tileNum, labelNum, Gv_GetVarX(*insptr++)); + continue; + } + + case CON_SETUSERDEF: + insptr++; + { + int const labelNum = *insptr++; + int const lParm2 = (UserdefsLabels[labelNum].flags & LABEL_HASPARM2) ? Gv_GetVarX(*insptr++) : 0; + + VM_SetUserdef(labelNum, lParm2, Gv_GetVarX(*insptr++)); + continue; + } + + case CON_GETPROJECTILE: + insptr++; + { + tw = Gv_GetVarX(*insptr++); + int const labelNum = *insptr++; + Gv_SetVarX(*insptr++, VM_GetProjectile(tw, labelNum)); + continue; + } + + case CON_SETPROJECTILE: + insptr++; + { + tw = Gv_GetVarX(*insptr++); + int const labelNum = *insptr++; + VM_SetProjectile(tw, labelNum, Gv_GetVarX(*insptr++)); + continue; + } + + case CON_SETWALL: + insptr++; + { + tw = *insptr++; + + int const wallNum = Gv_GetVarX(tw); + int const labelNum = *insptr++; + + VM_SetWall(wallNum, labelNum, Gv_GetVarX(*insptr++)); + continue; + } + + case CON_GETWALL: + insptr++; + { + tw = *insptr++; + + int const wallNum = Gv_GetVarX(tw); + int const labelNum = *insptr++; + + Gv_SetVarX(*insptr++, VM_GetWall(wallNum, labelNum)); + continue; + } + + case CON_SETACTORVAR: + case CON_GETACTORVAR: + insptr++; + { + int const lSprite = Gv_GetVarX(*insptr++); + int const lVar1 = *insptr++; + int const lVar2 = *insptr++; + + if (EDUKE32_PREDICT_FALSE((unsigned)lSprite >= MAXSPRITES)) + { + CON_ERRPRINTF("invalid sprite %d\n", lSprite); + + if (lVar1 == MAXGAMEVARS || lVar1 & ((MAXGAMEVARS << 2) | (MAXGAMEVARS << 3))) + insptr++; + + if (lVar2 == MAXGAMEVARS || lVar2 & ((MAXGAMEVARS << 2) | (MAXGAMEVARS << 3))) + insptr++; + + continue; + } + + if (tw == CON_SETACTORVAR) + Gv_SetVar(lVar1, Gv_GetVarX(lVar2), lSprite, vm.playerNum); + else + Gv_SetVarX(lVar2, Gv_GetVar(lVar1, lSprite, vm.playerNum)); + + continue; + } + + case CON_SETPLAYERVAR: + case CON_GETPLAYERVAR: + insptr++; + { + int const playerNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.playerNum; + int const lVar1 = *insptr++; + int const lVar2 = *insptr++; + + if (EDUKE32_PREDICT_FALSE((unsigned)playerNum >= (unsigned)g_mostConcurrentPlayers)) + { + CON_ERRPRINTF("invalid player %d\n", playerNum); + + if (lVar1 == MAXGAMEVARS || lVar1 & ((MAXGAMEVARS << 2) | (MAXGAMEVARS << 3))) + insptr++; + + if (lVar2 == MAXGAMEVARS || lVar2 & ((MAXGAMEVARS << 2) | (MAXGAMEVARS << 3))) + insptr++; + + continue; + } + + if (tw == CON_SETPLAYERVAR) + Gv_SetVar(lVar1, Gv_GetVarX(lVar2), vm.spriteNum, playerNum); + else + Gv_SetVarX(lVar2, Gv_GetVar(lVar1, vm.spriteNum, playerNum)); + + continue; + } + + case CON_SETACTOR: + insptr++; + { + int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.spriteNum; + int const labelNum = *insptr++; + int const lParm2 = (ActorLabels[labelNum].flags & LABEL_HASPARM2) ? Gv_GetVarX(*insptr++) : 0; + + VM_SetSprite(spriteNum, labelNum, lParm2, Gv_GetVarX(*insptr++)); + continue; + } + + case CON_GETACTOR: + insptr++; + { + int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.spriteNum; + int const labelNum = *insptr++; + int const lParm2 = (ActorLabels[labelNum].flags & LABEL_HASPARM2) ? Gv_GetVarX(*insptr++) : 0; + + Gv_SetVarX(*insptr++, VM_GetSprite(spriteNum, labelNum, lParm2)); + continue; + } + + case CON_SETTSPR: + insptr++; + { + int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.spriteNum; + int const labelNum = *insptr++; + + VM_SetTsprite(spriteNum, labelNum, Gv_GetVarX(*insptr++)); + continue; + } + + case CON_GETTSPR: + insptr++; + { + int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.spriteNum; + int const labelNum = *insptr++; + + Gv_SetVarX(*insptr++, VM_GetTsprite(spriteNum, labelNum)); + continue; + } + + case CON_GETANGLETOTARGET: + insptr++; + // vm.pActor->lastvx and lastvy are last known location of target. + Gv_SetVarX(*insptr++, getangle(vm.pActor->lastv.x - vm.pSprite->x, vm.pActor->lastv.y - vm.pSprite->y)); + continue; + + case CON_ANGOFFVAR: + insptr++; + spriteext[vm.spriteNum].angoff = Gv_GetVarX(*insptr++); + continue; + + case CON_LOCKPLAYER: + insptr++; + pPlayer->transporter_hold = Gv_GetVarX(*insptr++); + continue; + + case CON_CHECKAVAILWEAPON: + case CON_CHECKAVAILINVEN: + { + insptr++; + int const playerNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*insptr) : vm.playerNum; if (EDUKE32_PREDICT_FALSE((unsigned)playerNum >= (unsigned)g_mostConcurrentPlayers)) { - CON_ERRPRINTF("invalid player %d\n", playerNum); - - if (lVar1 == MAXGAMEVARS || lVar1 & ((MAXGAMEVARS << 2) | (MAXGAMEVARS << 3))) - insptr++; - - if (lVar2 == MAXGAMEVARS || lVar2 & ((MAXGAMEVARS << 2) | (MAXGAMEVARS << 3))) - insptr++; - + CON_ERRPRINTF("invalid player %d\n", (int)playerNum); continue; } - if (tw == CON_SETPLAYERVAR) - Gv_SetVar(lVar1, Gv_GetVarX(lVar2), vm.spriteNum, playerNum); + if (tw == CON_CHECKAVAILWEAPON) + P_CheckWeapon(g_player[playerNum].ps); else - Gv_SetVarX(lVar2, Gv_GetVar(lVar1, vm.spriteNum, playerNum)); + P_SelectNextInvItem(g_player[playerNum].ps); continue; } - case CON_SETACTOR: - insptr++; - { - int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.spriteNum; - int const labelNum = *insptr++; - int const lParm2 = (ActorLabels[labelNum].flags & LABEL_HASPARM2) ? Gv_GetVarX(*insptr++) : 0; - - VM_SetSprite(spriteNum, labelNum, lParm2, Gv_GetVarX(*insptr++)); + case CON_GETPLAYERANGLE: + insptr++; + Gv_SetVarX(*insptr++, fix16_to_int(pPlayer->q16ang)); continue; - } - case CON_GETACTOR: - insptr++; - { - int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.spriteNum; - int const labelNum = *insptr++; - int const lParm2 = (ActorLabels[labelNum].flags & LABEL_HASPARM2) ? Gv_GetVarX(*insptr++) : 0; - - Gv_SetVarX(*insptr++, VM_GetSprite(spriteNum, labelNum, lParm2)); + case CON_GETACTORANGLE: + insptr++; + Gv_SetVarX(*insptr++, vm.pSprite->ang); continue; - } - case CON_SETTSPR: - insptr++; - { - int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.spriteNum; - int const labelNum = *insptr++; - - VM_SetTsprite(spriteNum, labelNum, Gv_GetVarX(*insptr++)); + case CON_SETPLAYERANGLE: + insptr++; + pPlayer->q16ang = fix16_from_int(Gv_GetVarX(*insptr++) & 2047); continue; - } - case CON_GETTSPR: - insptr++; - { - int const spriteNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*(insptr - 1)) : vm.spriteNum; - int const labelNum = *insptr++; - - Gv_SetVarX(*insptr++, VM_GetTsprite(spriteNum, labelNum)); + case CON_SETACTORANGLE: + insptr++; + vm.pSprite->ang = Gv_GetVarX(*insptr++) & 2047; continue; - } - case CON_GETANGLETOTARGET: - insptr++; - // vm.pActor->lastvx and lastvy are last known location of target. - Gv_SetVarX(*insptr++, getangle(vm.pActor->lastv.x-vm.pSprite->x,vm.pActor->lastv.y-vm.pSprite->y)); - continue; - - case CON_ANGOFFVAR: - insptr++; - spriteext[vm.spriteNum].angoff = Gv_GetVarX(*insptr++); - continue; - - case CON_LOCKPLAYER: - insptr++; - pPlayer->transporter_hold = Gv_GetVarX(*insptr++); - continue; - - case CON_CHECKAVAILWEAPON: - case CON_CHECKAVAILINVEN: - { - insptr++; - int const playerNum = (*insptr++ != g_thisActorVarID) ? Gv_GetVarX(*insptr) : vm.playerNum; - - if (EDUKE32_PREDICT_FALSE((unsigned)playerNum >= (unsigned)g_mostConcurrentPlayers)) - { - CON_ERRPRINTF("invalid player %d\n", (int)playerNum); + case CON_KLABS: + if ((aGameVars[*(insptr + 1)].flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) == 0) + aGameVars[*(insptr + 1)].global = klabs(aGameVars[*(insptr + 1)].global); + else + Gv_SetVarX(*(insptr + 1), klabs(Gv_GetVarX(*(insptr + 1)))); + insptr += 2; continue; - } - if (tw == CON_CHECKAVAILWEAPON) - P_CheckWeapon(g_player[playerNum].ps); - else - P_SelectNextInvItem(g_player[playerNum].ps); - - continue; - } - - case CON_GETPLAYERANGLE: - insptr++; - Gv_SetVarX(*insptr++, fix16_to_int(pPlayer->q16ang)); - continue; - - case CON_GETACTORANGLE: - insptr++; - Gv_SetVarX(*insptr++, vm.pSprite->ang); - continue; - - case CON_SETPLAYERANGLE: - insptr++; - pPlayer->q16ang = fix16_from_int(Gv_GetVarX(*insptr++) & 2047); - continue; - - case CON_SETACTORANGLE: - insptr++; - vm.pSprite->ang = Gv_GetVarX(*insptr++) & 2047; - continue; - - case CON_SETVAR: - insptr++; - if ((aGameVars[*insptr].flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) == 0) - aGameVars[*insptr].global = *(insptr + 1); - else - Gv_SetVarX(*insptr, *(insptr + 1)); - insptr += 2; - continue; - - case CON_KLABS: - if ((aGameVars[*(insptr + 1)].flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) == 0) - aGameVars[*(insptr + 1)].global = klabs(aGameVars[*(insptr + 1)].global); - else - Gv_SetVarX(*(insptr + 1), klabs(Gv_GetVarX(*(insptr + 1)))); - insptr += 2; - continue; - - case CON_SETARRAY: - insptr++; - { - tw = *insptr++; - - int const arrayIndex = Gv_GetVarX(*insptr++); - int const newValue = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE((unsigned)tw >= (unsigned)g_gameArrayCount || - (unsigned)arrayIndex >= (unsigned)aGameArrays[tw].size)) + case CON_SETARRAY: + insptr++; { - OSD_Printf(OSD_ERROR "Gv_SetVar(): tried to set invalid array %d or index out of bounds from " - "sprite %d (%d), player %d\n", - tw, vm.spriteNum, TrackerCast(sprite[vm.spriteNum].picnum), vm.playerNum); - continue; - } + tw = *insptr++; - if (EDUKE32_PREDICT_FALSE(aGameArrays[tw].flags & GAMEARRAY_READONLY)) - { - OSD_Printf("Tried to set on read-only array `%s'", aGameArrays[tw].szLabel); - continue; - } + int const arrayIndex = Gv_GetVarX(*insptr++); + int const newValue = Gv_GetVarX(*insptr++); - switch (aGameArrays[tw].flags & GAMEARRAY_TYPE_MASK) - { - case 0: aGameArrays[tw].pValues[arrayIndex] = newValue; break; - case GAMEARRAY_INT16: ((int16_t *) aGameArrays[tw].pValues)[arrayIndex] = newValue; break; - case GAMEARRAY_INT8: ((int8_t *) aGameArrays[tw].pValues)[arrayIndex] = newValue; break; - case GAMEARRAY_UINT16: ((uint16_t *) aGameArrays[tw].pValues)[arrayIndex] = newValue; break; - case GAMEARRAY_UINT8: ((int8_t *) aGameArrays[tw].pValues)[arrayIndex] = newValue; break; - case GAMEARRAY_BITMAP: + if (EDUKE32_PREDICT_FALSE((unsigned)tw >= (unsigned)g_gameArrayCount || (unsigned)arrayIndex >= (unsigned)aGameArrays[tw].size)) { - uint32_t const mask = (1 << (arrayIndex & 7)); - uint8_t & value = ((uint8_t *)aGameArrays[tw].pValues)[arrayIndex >> 3]; - value = (value & ~mask) | (-!!newValue & mask); - break; - } - } - - continue; - } - - case CON_READARRAYFROMFILE: - insptr++; - { - int const arrayNum = *insptr++; - int const quoteFilename = *insptr++; - - if (EDUKE32_PREDICT_FALSE(apStrings[quoteFilename] == NULL)) - { - CON_ERRPRINTF("null quote %d\n", quoteFilename); - continue; - } - - int kFile = kopen4loadfrommod(apStrings[quoteFilename], 0); - - if (kFile < 0) - continue; - - size_t const filelength = kfilelength(kFile); - size_t const numElements = Gv_GetArrayCountFromFile(arrayNum, filelength); - - if (numElements > 0) - { - size_t const newBytes = Gv_GetArrayAllocSizeForCount(arrayNum, numElements); - size_t const readBytes = min(newBytes, filelength); - size_t const oldBytes = Gv_GetArrayAllocSize(arrayNum); - - intptr_t *& pValues = aGameArrays[arrayNum].pValues; - - if (newBytes != oldBytes) - { - Baligned_free(pValues); - pValues = (intptr_t *) Xaligned_alloc(ARRAY_ALIGNMENT, newBytes); + OSD_Printf(OSD_ERROR "Gv_SetVar(): tried to set invalid array %d or index out of bounds from " + "sprite %d (%d), player %d\n", + (int)tw, vm.spriteNum, TrackerCast(sprite[vm.spriteNum].picnum), vm.playerNum); + continue; } - aGameArrays[arrayNum].size = numElements; - - uintptr_t const flags = aGameArrays[arrayNum].flags; - - switch (flags & GAMEARRAY_SIZE_MASK) + if (EDUKE32_PREDICT_FALSE(aGameArrays[tw].flags & GAMEARRAY_READONLY)) { - case 0: + OSD_Printf("Tried to set on read-only array `%s'", aGameArrays[tw].szLabel); + continue; + } + + switch (aGameArrays[tw].flags & GAMEARRAY_TYPE_MASK) + { + case 0: aGameArrays[tw].pValues[arrayIndex] = newValue; break; + case GAMEARRAY_INT16: ((int16_t *)aGameArrays[tw].pValues)[arrayIndex] = newValue; break; + case GAMEARRAY_INT8: ((int8_t *)aGameArrays[tw].pValues)[arrayIndex] = newValue; break; + case GAMEARRAY_UINT16: ((uint16_t *)aGameArrays[tw].pValues)[arrayIndex] = newValue; break; + case GAMEARRAY_UINT8: ((int8_t *)aGameArrays[tw].pValues)[arrayIndex] = newValue; break; + case GAMEARRAY_BITMAP: + { + uint32_t const mask = (1 << (arrayIndex & 7)); + uint8_t & value = ((uint8_t *)aGameArrays[tw].pValues)[arrayIndex >> 3]; + value = (value & ~mask) | (-!!newValue & mask); + break; + } + } + + continue; + } + + case CON_READARRAYFROMFILE: + insptr++; + { + int const arrayNum = *insptr++; + int const quoteFilename = *insptr++; + + if (EDUKE32_PREDICT_FALSE(apStrings[quoteFilename] == NULL)) + { + CON_ERRPRINTF("null quote %d\n", quoteFilename); + continue; + } + + int kFile = kopen4loadfrommod(apStrings[quoteFilename], 0); + + if (kFile < 0) + continue; + + size_t const filelength = kfilelength(kFile); + size_t const numElements = Gv_GetArrayCountFromFile(arrayNum, filelength); + + if (numElements > 0) + { + size_t const newBytes = Gv_GetArrayAllocSizeForCount(arrayNum, numElements); + size_t const readBytes = min(newBytes, filelength); + size_t const oldBytes = Gv_GetArrayAllocSize(arrayNum); + + intptr_t *&pValues = aGameArrays[arrayNum].pValues; + + if (newBytes != oldBytes) + { + Baligned_free(pValues); + pValues = (intptr_t *)Xaligned_alloc(ARRAY_ALIGNMENT, newBytes); + } + + aGameArrays[arrayNum].size = numElements; + + uintptr_t const flags = aGameArrays[arrayNum].flags; + + switch (flags & GAMEARRAY_SIZE_MASK) + { + case 0: #ifdef BITNESS64 + { + void *const pArray = Xcalloc(1, newBytes); + + kread(kFile, pArray, readBytes); + + if (flags & GAMEARRAY_UNSIGNED) + { + for (unative_t i = 0; i < numElements; ++i) + pValues[i] = ((uint32_t *)pArray)[i]; + } + else + { + for (unative_t i = 0; i < numElements; ++i) + pValues[i] = ((int32_t *)pArray)[i]; + } + + Bfree(pArray); + break; + } +#endif + default: + memset((char *)pValues + readBytes, 0, newBytes - readBytes); + kread(kFile, pValues, readBytes); + break; + } + } + + kclose(kFile); + continue; + } + + case CON_WRITEARRAYTOFILE: + insptr++; + { + int const arrayNum = *insptr++; + int const quoteFilename = *insptr++; + + if (EDUKE32_PREDICT_FALSE(apStrings[quoteFilename] == NULL)) { - void * const pArray = Xcalloc(1, newBytes); + CON_ERRPRINTF("null quote %d\n", quoteFilename); + continue; + } - kread(kFile, pArray, readBytes); + char temp[BMAX_PATH]; - if (flags & GAMEARRAY_UNSIGNED) + if (EDUKE32_PREDICT_FALSE(G_ModDirSnprintf(temp, sizeof(temp), "%s", apStrings[quoteFilename]))) + { + CON_ERRPRINTF("file name too long\n"); + continue; + } + + FILE *const fil = Bfopen(temp, "wb"); + + if (EDUKE32_PREDICT_FALSE(fil == NULL)) + { + CON_ERRPRINTF("couldn't open file \"%s\"\n", temp); + continue; + } + + switch (aGameArrays[arrayNum].flags & GAMEARRAY_SIZE_MASK) + { + case 0: +#ifdef BITNESS64 { - for (unative_t i = 0; i < numElements; ++i) - pValues[i] = ((uint32_t *)pArray)[i]; - } - else - { - for (unative_t i = 0; i < numElements; ++i) - pValues[i] = ((int32_t *)pArray)[i]; + size_t const numElements = aGameArrays[arrayNum].size; + size_t const numDiskBytes = numElements * sizeof(int32_t); + int32_t *const pArray = (int32_t *)Xmalloc(numDiskBytes); + + for (unative_t k = 0; k < numElements; ++k) + pArray[k] = Gv_GetArrayValue(arrayNum, k); + + Bfwrite(pArray, 1, numDiskBytes, fil); + Bfree(pArray); + break; } +#endif + default: Bfwrite(aGameArrays[arrayNum].pValues, 1, Gv_GetArrayAllocSize(arrayNum), fil); break; + } + + Bfclose(fil); + + continue; + } + + case CON_GETARRAYSIZE: + insptr++; + tw = *insptr++; + Gv_SetVarX(*insptr++, (aGameArrays[tw].flags & GAMEARRAY_VARSIZE) ? Gv_GetVarX(aGameArrays[tw].size) : aGameArrays[tw].size); + continue; + + case CON_RESIZEARRAY: + insptr++; + { + tw = *insptr++; + + int const newSize = Gv_GetVarX(*insptr++); + int const oldSize = aGameArrays[tw].size; + + if (newSize >= 0 && newSize != oldSize) + { + // OSD_Printf(OSDTEXT_GREEN "CON_RESIZEARRAY: resizing array %s from %d to %d\n", + // aGameArrays[j].szLabel, aGameArrays[j].size, newSize); + + int const eltSize = Gv_GetArrayElementSize(tw); + intptr_t *const pArray = oldSize != 0 ? (intptr_t *)Xmalloc(eltSize * oldSize) : NULL; + + if (oldSize != 0) + Bmemcpy(pArray, aGameArrays[tw].pValues, eltSize * oldSize); + + Baligned_free(aGameArrays[tw].pValues); + + aGameArrays[tw].pValues = newSize != 0 ? (intptr_t *)Xaligned_alloc(ARRAY_ALIGNMENT, eltSize * newSize) : NULL; + aGameArrays[tw].size = newSize; + + if (oldSize != 0) + Bmemcpy(aGameArrays[tw].pValues, pArray, eltSize * min(oldSize, newSize)); + + if (newSize > oldSize) + Bmemset(&aGameArrays[tw].pValues[oldSize], 0, eltSize * (newSize - oldSize)); Bfree(pArray); - break; } -#endif - default: - memset((char *)pValues + readBytes, 0, newBytes - readBytes); - kread(kFile, pValues, readBytes); - break; + continue; + } + + case CON_COPY: + insptr++; + { + int const srcArray = *insptr++; + int srcArrayIndex = Gv_GetVarX(*insptr++); //, vm.spriteNum, vm.playerNum); + int const destArray = *insptr++; + int destArrayIndex = Gv_GetVarX(*insptr++); + int numElements = Gv_GetVarX(*insptr++); + + int const srcArraySize + = (aGameArrays[srcArray].flags & GAMEARRAY_VARSIZE) ? Gv_GetVarX(aGameArrays[srcArray].size) : aGameArrays[srcArray].size; + + int const destArraySize + = (aGameArrays[destArray].flags & GAMEARRAY_VARSIZE) ? Gv_GetVarX(aGameArrays[srcArray].size) : aGameArrays[destArray].size; + + if (EDUKE32_PREDICT_FALSE(srcArrayIndex > srcArraySize || destArrayIndex > destArraySize)) + continue; + + if ((srcArrayIndex + numElements) > srcArraySize) + numElements = srcArraySize - srcArrayIndex; + + if ((destArrayIndex + numElements) > destArraySize) + numElements = destArraySize - destArrayIndex; + + // Switch depending on the source array type. + + int const srcInc = 1 << (int)!!(EDUKE32_PREDICT_FALSE(aGameArrays[srcArray].flags & GAMEARRAY_STRIDE2)); + int const destInc = 1 << (int)!!(EDUKE32_PREDICT_FALSE(aGameArrays[destArray].flags & GAMEARRAY_STRIDE2)); + + // matching array types and no STRIDE2 flag + if ((aGameArrays[srcArray].flags & GAMEARRAY_SIZE_MASK) == (aGameArrays[destArray].flags & GAMEARRAY_SIZE_MASK) + && (srcInc & destInc) == 1) + { + Bmemcpy(aGameArrays[destArray].pValues + destArrayIndex, aGameArrays[srcArray].pValues + srcArrayIndex, + numElements * Gv_GetArrayElementSize(srcArray)); } - } + else + switch (aGameArrays[destArray].flags & GAMEARRAY_TYPE_MASK) + { + case 0: + for (; numElements > 0; --numElements) + aGameArrays[destArray].pValues[destArrayIndex += destInc] = Gv_GetArrayValue(srcArray, srcArrayIndex += srcInc); + break; + case GAMEARRAY_INT16: + for (; numElements > 0; --numElements) + ((int16_t *)aGameArrays[destArray].pValues)[destArrayIndex += destInc] + = Gv_GetArrayValue(srcArray, srcArrayIndex += srcInc); + break; + case GAMEARRAY_INT8: + for (; numElements > 0; --numElements) + ((int8_t *)aGameArrays[destArray].pValues)[destArrayIndex += destInc] + = Gv_GetArrayValue(srcArray, srcArrayIndex += srcInc); + break; + case GAMEARRAY_UINT16: + for (; numElements > 0; --numElements) + ((uint16_t *)aGameArrays[destArray].pValues)[destArrayIndex += destInc] + = Gv_GetArrayValue(srcArray, srcArrayIndex += srcInc); + break; + case GAMEARRAY_UINT8: + for (; numElements > 0; --numElements) + ((uint8_t *)aGameArrays[destArray].pValues)[destArrayIndex += destInc] + = Gv_GetArrayValue(srcArray, srcArrayIndex += srcInc); + break; + } - kclose(kFile); - continue; - } - - case CON_WRITEARRAYTOFILE: - insptr++; - { - int const arrayNum = *insptr++; - int const quoteFilename = *insptr++; - - if (EDUKE32_PREDICT_FALSE(apStrings[quoteFilename] == NULL)) - { - CON_ERRPRINTF("null quote %d\n", quoteFilename); continue; } - char temp[BMAX_PATH]; - - if (EDUKE32_PREDICT_FALSE(G_ModDirSnprintf(temp, sizeof(temp), "%s", apStrings[quoteFilename]))) - { - CON_ERRPRINTF("file name too long\n"); - continue; - } - - FILE *const fil = Bfopen(temp, "wb"); - - if (EDUKE32_PREDICT_FALSE(fil == NULL)) - { - CON_ERRPRINTF("couldn't open file \"%s\"\n", temp); - continue; - } - - switch (aGameArrays[arrayNum].flags & GAMEARRAY_SIZE_MASK) - { - case 0: -#ifdef BITNESS64 - { - size_t const numElements = aGameArrays[arrayNum].size; - size_t const numDiskBytes = numElements * sizeof(int32_t); - int32_t *const pArray = (int32_t *)Xmalloc(numDiskBytes); - - for (unative_t k = 0; k < numElements; ++k) - pArray[k] = Gv_GetArrayValue(arrayNum, k); - - Bfwrite(pArray, 1, numDiskBytes, fil); - Bfree(pArray); - break; - } -#endif - default: - Bfwrite(aGameArrays[arrayNum].pValues, 1, Gv_GetArrayAllocSize(arrayNum), fil); - break; - } - - Bfclose(fil); - - continue; - } - - case CON_GETARRAYSIZE: - insptr++; - tw = *insptr++; - Gv_SetVarX(*insptr++, (aGameArrays[tw].flags & GAMEARRAY_VARSIZE) ? Gv_GetVarX(aGameArrays[tw].size) - : aGameArrays[tw].size); - continue; - - case CON_RESIZEARRAY: - insptr++; - { - tw = *insptr++; - - int const newSize = Gv_GetVarX(*insptr++); - int const oldSize = aGameArrays[tw].size; - - if (newSize >= 0 && newSize != oldSize) - { -// OSD_Printf(OSDTEXT_GREEN "CON_RESIZEARRAY: resizing array %s from %d to %d\n", -// aGameArrays[j].szLabel, aGameArrays[j].size, newSize); - - int const eltSize = Gv_GetArrayElementSize(tw); - intptr_t * const pArray = oldSize != 0 ? (intptr_t *)Xmalloc(eltSize * oldSize) : NULL; - - if (oldSize != 0) - Bmemcpy(pArray, aGameArrays[tw].pValues, eltSize * oldSize); - - Baligned_free(aGameArrays[tw].pValues); - - aGameArrays[tw].pValues = newSize != 0 ? (intptr_t *)Xaligned_alloc(ARRAY_ALIGNMENT, eltSize * newSize) : NULL; - aGameArrays[tw].size = newSize; - - if (oldSize != 0) - Bmemcpy(aGameArrays[tw].pValues, pArray, eltSize * min(oldSize, newSize)); - - if (newSize > oldSize) - Bmemset(&aGameArrays[tw].pValues[oldSize], 0, eltSize * (newSize - oldSize)); - - Bfree(pArray); - } - continue; - } - - case CON_COPY: - insptr++; - { - int const srcArray = *insptr++; - int srcArrayIndex = Gv_GetVarX(*insptr++); //, vm.spriteNum, vm.playerNum); - int const destArray = *insptr++; - int destArrayIndex = Gv_GetVarX(*insptr++); - int numElements = Gv_GetVarX(*insptr++); - - int const srcArraySize = (aGameArrays[srcArray].flags & GAMEARRAY_VARSIZE) - ? Gv_GetVarX(aGameArrays[srcArray].size) - : aGameArrays[srcArray].size; - - int const destArraySize = (aGameArrays[destArray].flags & GAMEARRAY_VARSIZE) - ? Gv_GetVarX(aGameArrays[srcArray].size) - : aGameArrays[destArray].size; - - if (EDUKE32_PREDICT_FALSE(srcArrayIndex > srcArraySize || destArrayIndex > destArraySize)) - continue; - - if ((srcArrayIndex + numElements) > srcArraySize) - numElements = srcArraySize - srcArrayIndex; - - if ((destArrayIndex + numElements) > destArraySize) - numElements = destArraySize - destArrayIndex; - - // Switch depending on the source array type. - - int const srcInc = 1 << (int)!!(EDUKE32_PREDICT_FALSE(aGameArrays[srcArray].flags & GAMEARRAY_STRIDE2)); - int const destInc = 1 << (int)!!(EDUKE32_PREDICT_FALSE(aGameArrays[destArray].flags & GAMEARRAY_STRIDE2)); - - // matching array types and no STRIDE2 flag - if ((aGameArrays[srcArray].flags & GAMEARRAY_SIZE_MASK) == (aGameArrays[destArray].flags & GAMEARRAY_SIZE_MASK) && (srcInc & destInc) == 1) - { - Bmemcpy(aGameArrays[destArray].pValues + destArrayIndex, aGameArrays[srcArray].pValues + srcArrayIndex, - numElements * Gv_GetArrayElementSize(srcArray)); - } - else switch (aGameArrays[destArray].flags & GAMEARRAY_TYPE_MASK) - { - case 0: - for (; numElements > 0; --numElements) - aGameArrays[destArray].pValues[destArrayIndex += destInc] = Gv_GetArrayValue(srcArray, srcArrayIndex += srcInc); - break; - case GAMEARRAY_INT16: - for (; numElements > 0; --numElements) - ((int16_t *) aGameArrays[destArray].pValues)[destArrayIndex += destInc] = Gv_GetArrayValue(srcArray, srcArrayIndex += srcInc); - break; - case GAMEARRAY_INT8: - for (; numElements > 0; --numElements) - ((int8_t *) aGameArrays[destArray].pValues)[destArrayIndex += destInc] = Gv_GetArrayValue(srcArray, srcArrayIndex += srcInc); - break; - case GAMEARRAY_UINT16: - for (; numElements > 0; --numElements) - ((uint16_t *) aGameArrays[destArray].pValues)[destArrayIndex += destInc] = Gv_GetArrayValue(srcArray, srcArrayIndex += srcInc); - break; - case GAMEARRAY_UINT8: - for (; numElements > 0; --numElements) - ((uint8_t *) aGameArrays[destArray].pValues)[destArrayIndex += destInc] = Gv_GetArrayValue(srcArray, srcArrayIndex += srcInc); - break; - } - - continue; - } - - case CON_RANDVAR: - insptr++; - Gv_SetVarX(*insptr, mulscale16(krand(), *(insptr + 1) + 1)); - insptr += 2; - continue; - - case CON_DISPLAYRANDVAR: - insptr++; - Gv_SetVarX(*insptr, mulscale15(system_15bit_rand(), *(insptr + 1) + 1)); - insptr += 2; - continue; - - case CON_CLAMP: - insptr++; - { - tw = *insptr++; - int const min = Gv_GetVarX(*insptr++); - Gv_SetVarX(tw, clamp2(Gv_GetVarX(tw), min, Gv_GetVarX(*insptr++))); - } - continue; - - case CON_GETCLOSESTCOL: - insptr++; - { - tw = *insptr++; - int32_t const rgb = Gv_GetVarX(*insptr++); - Gv_SetVarX(tw, getclosestcol_lim(rgb & 0xFF, (rgb >> 8) & 0xFF, (rgb >> 16) & 0xFF, Gv_GetVarX(*insptr++))); - } - continue; - - case CON_DRAWLINE256: - insptr++; - { - struct { - vec2_t pos[2]; - int32_t index; - } v; - - Gv_FillWithVars(v); - - renderDrawLine(v.pos[0].x, v.pos[0].y, v.pos[1].x, v.pos[1].y, v.index); - } - continue; - - case CON_DRAWLINERGB: - insptr++; - { - struct { - vec2_t pos[2]; - int32_t index, rgb; - } v; - - Gv_FillWithVars(v); - - palette_t const p = { (uint8_t)(v.rgb & 0xFF), (uint8_t)((v.rgb >> 8) & 0xFF), (uint8_t)((v.rgb >> 16) & 0xFF), (uint8_t)v.index }; - - drawlinergb(v.pos[0].x, v.pos[0].y, v.pos[1].x, v.pos[1].y, p); - } - continue; - - case CON_INV: - if ((aGameVars[*(insptr + 1)].flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) == 0) - aGameVars[*(insptr + 1)].global = -aGameVars[*(insptr + 1)].global; - else - Gv_SetVarX(*(insptr + 1), -Gv_GetVarX(*(insptr + 1))); - insptr += 2; - continue; - - case CON_MULVAR: - insptr++; - Gv_MulVar(*insptr, *(insptr + 1)); - insptr += 2; - continue; - - case CON_DIVVAR: - insptr++; - if (EDUKE32_PREDICT_FALSE(*(insptr + 1) == 0)) - { - CON_CRITICALERRPRINTF("divide by zero!\n"); + case CON_RANDVAR: + insptr++; + Gv_SetVarX(*insptr, mulscale16(krand(), *(insptr + 1) + 1)); insptr += 2; continue; - } - Gv_DivVar(*insptr, *(insptr + 1)); - insptr += 2; - continue; - case CON_MODVAR: - insptr++; - if (EDUKE32_PREDICT_FALSE(*(insptr + 1) == 0)) - { - CON_CRITICALERRPRINTF("mod by zero!\n"); + case CON_DISPLAYRANDVAR: + insptr++; + Gv_SetVarX(*insptr, mulscale15(system_15bit_rand(), *(insptr + 1) + 1)); insptr += 2; continue; - } - Gv_ModVar(*insptr, *(insptr + 1)); - insptr += 2; - continue; + case CON_CLAMP: + insptr++; + { + tw = *insptr++; + int const min = Gv_GetVarX(*insptr++); + Gv_SetVarX(tw, clamp2(Gv_GetVarX(tw), min, Gv_GetVarX(*insptr++))); + } + continue; - case CON_ANDVAR: - insptr++; - Gv_AndVar(*insptr, *(insptr + 1)); - insptr += 2; - continue; + case CON_GETCLOSESTCOL: + insptr++; + { + tw = *insptr++; + int32_t const rgb = Gv_GetVarX(*insptr++); + Gv_SetVarX(tw, getclosestcol_lim(rgb & 0xFF, (rgb >> 8) & 0xFF, (rgb >> 16) & 0xFF, Gv_GetVarX(*insptr++))); + } + continue; - case CON_ORVAR: - insptr++; - Gv_OrVar(*insptr, *(insptr + 1)); - insptr += 2; - continue; + case CON_DRAWLINE256: + insptr++; + { + struct + { + vec2_t pos[2]; + int32_t index; + } v; - case CON_XORVAR: - insptr++; - Gv_XorVar(*insptr, *(insptr + 1)); - insptr += 2; - continue; + Gv_FillWithVars(v); - case CON_SETVARVAR: - insptr++; - { - tw = *insptr++; - int const nValue = Gv_GetVarX(*insptr++); + renderDrawLine(v.pos[0].x, v.pos[0].y, v.pos[1].x, v.pos[1].y, v.index); + } + continue; - if ((aGameVars[tw].flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) == 0) - aGameVars[tw].global = nValue; + case CON_DRAWLINERGB: + insptr++; + { + struct + { + vec2_t pos[2]; + int32_t index, rgb; + } v; + + Gv_FillWithVars(v); + + palette_t const p + = { (uint8_t)(v.rgb & 0xFF), (uint8_t)((v.rgb >> 8) & 0xFF), (uint8_t)((v.rgb >> 16) & 0xFF), (uint8_t)v.index }; + + drawlinergb(v.pos[0].x, v.pos[0].y, v.pos[1].x, v.pos[1].y, p); + } + continue; + + case CON_INV: + if ((aGameVars[*(insptr + 1)].flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) == 0) + aGameVars[*(insptr + 1)].global = -aGameVars[*(insptr + 1)].global; else - Gv_SetVarX(tw, nValue); - } - continue; + Gv_SetVarX(*(insptr + 1), -Gv_GetVarX(*(insptr + 1))); + insptr += 2; + continue; - case CON_RANDVARVAR: - insptr++; - tw = *insptr++; - Gv_SetVarX(tw, mulscale16(krand(), Gv_GetVarX(*insptr++) + 1)); - continue; - case CON_DISPLAYRANDVARVAR: - insptr++; - tw = *insptr++; - Gv_SetVarX(tw, mulscale15(system_15bit_rand(), Gv_GetVarX(*insptr++) + 1)); - continue; - - case CON_GMAXAMMO: - insptr++; - tw = Gv_GetVarX(*insptr++); - if (EDUKE32_PREDICT_FALSE((unsigned)tw >= MAX_WEAPONS)) - { - CON_ERRPRINTF("invalid weapon %d\n", tw); + case CON_RANDVARVAR: insptr++; + tw = *insptr++; + Gv_SetVarX(tw, mulscale16(krand(), Gv_GetVarX(*insptr++) + 1)); continue; - } - Gv_SetVarX(*insptr++, pPlayer->max_ammo_amount[tw]); - continue; - case CON_SMAXAMMO: - insptr++; - tw = Gv_GetVarX(*insptr++); - if (EDUKE32_PREDICT_FALSE((unsigned)tw >= MAX_WEAPONS)) - { - CON_ERRPRINTF("invalid weapon %d\n", tw); + case CON_DISPLAYRANDVARVAR: insptr++; - continue; - } - pPlayer->max_ammo_amount[tw] = Gv_GetVarX(*insptr++); - continue; - - case CON_MULVARVAR: - insptr++; - tw = *insptr++; - Gv_MulVar(tw, Gv_GetVarX(*insptr++)); - continue; - - case CON_DIVVARVAR: - insptr++; - { tw = *insptr++; + Gv_SetVarX(tw, mulscale15(system_15bit_rand(), Gv_GetVarX(*insptr++) + 1)); + continue; - int const nValue = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE(!nValue)) + case CON_GMAXAMMO: + insptr++; + tw = Gv_GetVarX(*insptr++); + if (EDUKE32_PREDICT_FALSE((unsigned)tw >= MAX_WEAPONS)) { - CON_CRITICALERRPRINTF("divide by zero!\n"); + CON_ERRPRINTF("invalid weapon %d\n", (int)tw); + insptr++; + continue; + } + Gv_SetVarX(*insptr++, pPlayer->max_ammo_amount[tw]); + continue; + + case CON_SMAXAMMO: + insptr++; + tw = Gv_GetVarX(*insptr++); + if (EDUKE32_PREDICT_FALSE((unsigned)tw >= MAX_WEAPONS)) + { + CON_ERRPRINTF("invalid weapon %d\n", (int)tw); + insptr++; + continue; + } + pPlayer->max_ammo_amount[tw] = Gv_GetVarX(*insptr++); + continue; + + + case CON_DIVR: // div round to nearest + insptr++; + { + tw = *insptr++; + + int const dividend = Gv_GetVarX(tw); + int const divisor = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE(!divisor)) + { + CON_CRITICALERRPRINTF("divide by zero!\n"); + continue; + } + + Gv_SetVarX(tw, tabledivide32((dividend - ksgn(dividend) * klabs(divisor / 2)), divisor)); continue; } - Gv_DivVar(tw, nValue); - continue; - } - - case CON_DIVR: // div round to nearest - insptr++; - { - tw = *insptr++; - - int const dividend = Gv_GetVarX(tw); - int const divisor = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE(!divisor)) + case CON_DIVRU: // div round away from zero + insptr++; { - CON_CRITICALERRPRINTF("divide by zero!\n"); + tw = *insptr++; + + int const dividend = Gv_GetVarX(tw); + int const divisor = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE(!divisor)) + { + CON_CRITICALERRPRINTF("divide by zero!\n"); + continue; + } + + Gv_SetVarX(tw, tabledivide32((dividend - ksgn(dividend) * klabs(divisor) + 1), divisor)); continue; } - Gv_SetVarX(tw, tabledivide32((dividend - ksgn(dividend) * klabs(divisor / 2)), divisor)); - continue; - } - - case CON_DIVRU: // div round away from zero - insptr++; - { + case CON_SIN: + insptr++; tw = *insptr++; + Gv_SetVarX(tw, sintable[Gv_GetVarX(*insptr++) & 2047]); + continue; - int const dividend = Gv_GetVarX(tw); - int const divisor = Gv_GetVarX(*insptr++); + case CON_COS: + insptr++; + tw = *insptr++; + Gv_SetVarX(tw, sintable[(Gv_GetVarX(*insptr++) + 512) & 2047]); + continue; - if (EDUKE32_PREDICT_FALSE(!divisor)) + + case CON_SPGETLOTAG: + insptr++; + aGameVars[g_lotagVarID].global = vm.pSprite->lotag; + continue; + + case CON_SPGETHITAG: + insptr++; + aGameVars[g_hitagVarID].global = vm.pSprite->hitag; + continue; + + case CON_SECTGETLOTAG: + insptr++; + aGameVars[g_lotagVarID].global = sector[vm.pSprite->sectnum].lotag; + continue; + + case CON_SECTGETHITAG: + insptr++; + aGameVars[g_hitagVarID].global = sector[vm.pSprite->sectnum].hitag; + continue; + + case CON_GETTEXTUREFLOOR: + insptr++; + aGameVars[g_textureVarID].global = sector[vm.pSprite->sectnum].floorpicnum; + continue; + + case CON_STARTTRACK: + insptr++; + G_StartTrackSlotWrap(ud.volume_number, *(insptr++)); + continue; + + case CON_STARTTRACKVAR: + insptr++; + G_StartTrackSlotWrap(ud.volume_number, Gv_GetVarX(*(insptr++))); + continue; + + case CON_STARTTRACKSLOT: + insptr++; { - CON_CRITICALERRPRINTF("divide by zero!\n"); + int const volumeNum = Gv_GetVarX(*(insptr++)); + int const levelNum = Gv_GetVarX(*(insptr++)); + G_StartTrackSlotWrap(volumeNum == -1 ? MAXVOLUMES : volumeNum, levelNum); + } + continue; + + case CON_SWAPTRACKSLOT: + insptr++; + { + int const volumeNum = Gv_GetVarX(*(insptr++)); + int const levelNum = Gv_GetVarX(*(insptr++)); + + if (volumeNum == ud.music_episode && levelNum == ud.music_level) + continue; + + // This is the best ASS can do right now. Better implementation pending. + int32_t position = S_GetMusicPosition(); + if (!G_StartTrackSlotWrap(volumeNum == -1 ? MAXVOLUMES : volumeNum, levelNum)) + S_SetMusicPosition(position); + } + continue; + + case CON_PRELOADTRACKSLOTFORSWAP: + // ASS can't even handle this command right now. + insptr++; + Gv_GetVarX(*(insptr++)); + Gv_GetVarX(*(insptr++)); + continue; + + case CON_SETMUSICPOSITION: + insptr++; + Gv_GetVarX(*(insptr++)); + continue; + case CON_GETMUSICPOSITION: insptr += 2; continue; + + case CON_ACTIVATECHEAT: + insptr++; + tw = Gv_GetVarX(*(insptr++)); + if (EDUKE32_PREDICT_FALSE(numplayers != 1 || !(g_player[myconnectindex].ps->gm & MODE_GAME))) + { + CON_ERRPRINTF("not in a single-player game.\n"); continue; } - - Gv_SetVarX(tw, tabledivide32((dividend - ksgn(dividend) * klabs(divisor) + 1), divisor)); + osdcmd_cheatsinfo_stat.cheatnum = tw; continue; - } - case CON_MODVARVAR: - insptr++; - { - tw = *insptr++; - - int const nValue = Gv_GetVarX(*insptr++); - - if (EDUKE32_PREDICT_FALSE(!nValue)) - { - CON_CRITICALERRPRINTF("mod by zero!\n"); - continue; - } - - Gv_ModVar(tw, nValue); + case CON_SETGAMEPALETTE: + insptr++; + P_SetGamePalette(pPlayer, Gv_GetVarX(*(insptr++)), 2 + 16); continue; - } - case CON_ANDVARVAR: - insptr++; - tw = *insptr++; - Gv_AndVar(tw, Gv_GetVarX(*insptr++)); - continue; - - case CON_XORVARVAR: - insptr++; - tw = *insptr++; - Gv_XorVar(tw, Gv_GetVarX(*insptr++)); - continue; - - case CON_ORVARVAR: - insptr++; - tw = *insptr++; - Gv_OrVar(tw, Gv_GetVarX(*insptr++)); - continue; - - case CON_SUBVAR: - insptr++; - Gv_SubVar(*insptr, *(insptr+1)); - insptr += 2; - continue; - - case CON_SUBVARVAR: - insptr++; - tw = *insptr++; - Gv_SubVar(tw, Gv_GetVarX(*insptr++)); - continue; - - case CON_ADDVAR: - insptr++; - Gv_AddVar(*insptr, *(insptr+1)); - insptr += 2; - continue; - - case CON_SHIFTVARL: - insptr++; - Gv_ShiftVarL(*insptr, *(insptr+1)); - insptr += 2; - continue; - - case CON_SHIFTVARR: - insptr++; - Gv_ShiftVarR(*insptr, *(insptr+1)); - insptr += 2; - continue; - - case CON_SHIFTVARVARL: - insptr++; - tw = *insptr++; - Gv_ShiftVarL(tw, Gv_GetVarX(*insptr++)); - continue; - - case CON_SHIFTVARVARR: - insptr++; - tw = *insptr++; - Gv_ShiftVarR(tw, Gv_GetVarX(*insptr++)); - continue; - - case CON_SIN: - insptr++; - tw = *insptr++; - Gv_SetVarX(tw, sintable[Gv_GetVarX(*insptr++)&2047]); - continue; - - case CON_COS: - insptr++; - tw = *insptr++; - Gv_SetVarX(tw, sintable[(Gv_GetVarX(*insptr++)+512)&2047]); - continue; - - case CON_ADDVARVAR: - insptr++; - tw = *insptr++; - Gv_AddVar(tw, Gv_GetVarX(*insptr++)); - continue; - - case CON_SPGETLOTAG: - insptr++; - aGameVars[g_lotagVarID].global = vm.pSprite->lotag; - continue; - - case CON_SPGETHITAG: - insptr++; - aGameVars[g_hitagVarID].global = vm.pSprite->hitag; - continue; - - case CON_SECTGETLOTAG: - insptr++; - aGameVars[g_lotagVarID].global = sector[vm.pSprite->sectnum].lotag; - continue; - - case CON_SECTGETHITAG: - insptr++; - aGameVars[g_hitagVarID].global = sector[vm.pSprite->sectnum].hitag; - continue; - - case CON_GETTEXTUREFLOOR: - insptr++; - aGameVars[g_textureVarID].global = sector[vm.pSprite->sectnum].floorpicnum; - continue; - - case CON_STARTTRACK: - insptr++; - G_StartTrackSlotWrap(ud.volume_number, *(insptr++)); - continue; - - case CON_STARTTRACKVAR: - insptr++; - G_StartTrackSlotWrap(ud.volume_number, Gv_GetVarX(*(insptr++))); - continue; - - case CON_STARTTRACKSLOT: - insptr++; - { - int const volumeNum = Gv_GetVarX(*(insptr++)); - int const levelNum = Gv_GetVarX(*(insptr++)); - G_StartTrackSlotWrap(volumeNum == -1 ? MAXVOLUMES : volumeNum, levelNum); - } - continue; - - case CON_SWAPTRACKSLOT: - insptr++; - { - int const volumeNum = Gv_GetVarX(*(insptr++)); - int const levelNum = Gv_GetVarX(*(insptr++)); - - if (volumeNum == ud.music_episode && levelNum == ud.music_level) - continue; - - // This is the best ASS can do right now. Better implementation pending. - int32_t position = S_GetMusicPosition(); - if (!G_StartTrackSlotWrap(volumeNum == -1 ? MAXVOLUMES : volumeNum, levelNum)) - S_SetMusicPosition(position); - } - continue; - - case CON_PRELOADTRACKSLOTFORSWAP: - // ASS can't even handle this command right now. - insptr++; - Gv_GetVarX(*(insptr++)); - Gv_GetVarX(*(insptr++)); - continue; - - case CON_SETMUSICPOSITION: - insptr++; - Gv_GetVarX(*(insptr++)); - continue; - case CON_GETMUSICPOSITION: - insptr += 2; - continue; - - case CON_ACTIVATECHEAT: - insptr++; - tw = Gv_GetVarX(*(insptr++)); - if (EDUKE32_PREDICT_FALSE(numplayers != 1 || !(g_player[myconnectindex].ps->gm & MODE_GAME))) - { - CON_ERRPRINTF("not in a single-player game.\n"); + case CON_GETTEXTURECEILING: + insptr++; + aGameVars[g_textureVarID].global = sector[vm.pSprite->sectnum].ceilingpicnum; continue; - } - osdcmd_cheatsinfo_stat.cheatnum = tw; - continue; - case CON_SETGAMEPALETTE: - insptr++; - P_SetGamePalette(pPlayer, Gv_GetVarX(*(insptr++)), 2+16); - continue; - - case CON_GETTEXTURECEILING: - insptr++; - aGameVars[g_textureVarID].global = sector[vm.pSprite->sectnum].ceilingpicnum; - continue; - - case CON_IFVARVARAND: - insptr++; - tw = Gv_GetVarX(*insptr++); - tw &= Gv_GetVarX(*insptr++); - insptr--; - VM_CONDITIONAL(tw); - continue; - - case CON_IFVARVAROR: - insptr++; - tw = Gv_GetVarX(*insptr++); - tw |= Gv_GetVarX(*insptr++); - insptr--; - VM_CONDITIONAL(tw); - continue; - - case CON_IFVARVARXOR: - insptr++; - tw = Gv_GetVarX(*insptr++); - tw ^= Gv_GetVarX(*insptr++); - insptr--; - VM_CONDITIONAL(tw); - continue; - - case CON_IFVARVAREITHER: - insptr++; - tw = Gv_GetVarX(*insptr++); - tw = (Gv_GetVarX(*insptr++) || tw); - insptr--; - VM_CONDITIONAL(tw); - continue; - - case CON_IFVARVARBOTH: - insptr++; - tw = Gv_GetVarX(*insptr++); - tw = (Gv_GetVarX(*insptr++) && tw); - insptr--; - VM_CONDITIONAL(tw); - continue; - - case CON_IFVARVARN: - insptr++; - tw = Gv_GetVarX(*insptr++); - tw = (tw != Gv_GetVarX(*insptr++)); - insptr--; - VM_CONDITIONAL(tw); - continue; - - case CON_IFVARVARE: - insptr++; - tw = Gv_GetVarX(*insptr++); - tw = (tw == Gv_GetVarX(*insptr++)); - insptr--; - VM_CONDITIONAL(tw); - continue; - - case CON_IFVARVARG: - insptr++; - tw = Gv_GetVarX(*insptr++); - tw = (tw > Gv_GetVarX(*insptr++)); - insptr--; - VM_CONDITIONAL(tw); - continue; - - case CON_IFVARVARGE: - insptr++; - tw = Gv_GetVarX(*insptr++); - tw = (tw >= Gv_GetVarX(*insptr++)); - insptr--; - VM_CONDITIONAL(tw); - continue; - - case CON_IFVARVARL: - insptr++; - tw = Gv_GetVarX(*insptr++); - tw = (tw < Gv_GetVarX(*insptr++)); - insptr--; - VM_CONDITIONAL(tw); - continue; - - case CON_IFVARVARLE: - insptr++; - tw = Gv_GetVarX(*insptr++); - tw = (tw <= Gv_GetVarX(*insptr++)); - insptr--; - VM_CONDITIONAL(tw); - continue; - - case CON_IFVARVARA: - insptr++; - tw = Gv_GetVarX(*insptr++); - tw = ((uint32_t)tw > (uint32_t)Gv_GetVarX(*insptr++)); - insptr--; - VM_CONDITIONAL(tw); - continue; - - case CON_IFVARVARAE: - insptr++; - tw = Gv_GetVarX(*insptr++); - tw = ((uint32_t)tw >= (uint32_t)Gv_GetVarX(*insptr++)); - insptr--; - VM_CONDITIONAL(tw); - continue; - - case CON_IFVARVARB: - insptr++; - tw = Gv_GetVarX(*insptr++); - tw = ((uint32_t)tw < (uint32_t)Gv_GetVarX(*insptr++)); - insptr--; - VM_CONDITIONAL(tw); - continue; - - case CON_IFVARVARBE: - insptr++; - tw = Gv_GetVarX(*insptr++); - tw = ((uint32_t)tw <= (uint32_t)Gv_GetVarX(*insptr++)); - insptr--; - VM_CONDITIONAL(tw); - continue; - - case CON_IFVARN: - insptr++; - tw = Gv_GetVarX(*insptr++); - VM_CONDITIONAL(tw != *insptr); - continue; - - case CON_WHILEVARN: - { - intptr_t const *const savedinsptr = insptr + 2; - do - { - insptr = savedinsptr; - tw = (Gv_GetVarX(*(insptr - 1)) != *insptr); - VM_CONDITIONAL(tw); - } - while (tw); - continue; - } - - case CON_WHILEVARL: - { - intptr_t const *const savedinsptr = insptr + 2; - do - { - insptr = savedinsptr; - tw = (Gv_GetVarX(*(insptr - 1)) < *insptr); - VM_CONDITIONAL(tw); - } while (tw); - continue; - } - - case CON_WHILEVARVARN: - { - intptr_t const *const savedinsptr = insptr + 2; - do - { - insptr = savedinsptr; - tw = Gv_GetVarX(*(insptr - 1)); - tw = (tw != Gv_GetVarX(*insptr++)); + case CON_IFVARVAREITHER: + insptr++; + tw = Gv_GetVarX(*insptr++); + tw = (Gv_GetVarX(*insptr++) || tw); insptr--; VM_CONDITIONAL(tw); - } - while (tw); - continue; - } + continue; - case CON_WHILEVARVARL: - { - intptr_t const *const savedinsptr = insptr + 2; - do - { - insptr = savedinsptr; - tw = Gv_GetVarX(*(insptr - 1)); - tw = (tw < Gv_GetVarX(*insptr++)); + case CON_IFVARVARBOTH: + insptr++; + tw = Gv_GetVarX(*insptr++); + tw = (Gv_GetVarX(*insptr++) && tw); insptr--; VM_CONDITIONAL(tw); - } while (tw); - continue; - } + continue; - case CON_FOR: // special-purpose iteration - insptr++; + case CON_WHILEVARN: { - int const returnVar = *insptr++; - int const iterType = *insptr++; - int const nIndex = iterType <= ITER_DRAWNSPRITES ? 0 : Gv_GetVarX(*insptr++); - - intptr_t const *const pEnd = insptr + *insptr; - intptr_t const *const pNext = ++insptr; - - switch (iterType) + intptr_t const *const savedinsptr = insptr + 2; + do { - case ITER_ALLSPRITES: - for (native_t jj=0; jj=0;) - { - int const kk=nextspritestat[jj]; - Gv_SetVarX(returnVar, jj); - insptr = pNext; - VM_Execute(0); - jj=kk; - } - } - break; - case ITER_ALLSPRITESBYSECT: - for (native_t sectNum=0; sectNum=0;) - { - int const kk=nextspritesect[jj]; - Gv_SetVarX(returnVar, jj); - insptr = pNext; - VM_Execute(0); - jj=kk; - } - } - break; - case ITER_ALLSECTORS: - for (native_t jj=0; jj= MAXSECTORS) goto badindex; - for (native_t jj=headspritesect[nIndex]; jj>=0;) - { - int const kk=nextspritesect[jj]; - Gv_SetVarX(returnVar, jj); - insptr = pNext; - VM_Execute(0); - jj=kk; - } - break; - case ITER_SPRITESOFSTATUS: - if ((unsigned) nIndex >= MAXSTATUS) goto badindex; - for (native_t jj=headspritestat[nIndex]; jj>=0;) - { - int const kk=nextspritestat[jj]; - Gv_SetVarX(returnVar, jj); - insptr = pNext; - VM_Execute(0); - jj=kk; - } - break; - case ITER_WALLSOFSECTOR: - if ((unsigned) nIndex >= MAXSECTORS) goto badindex; - for (native_t jj=sector[nIndex].wallptr, endwall=jj+sector[nIndex].wallnum-1; - jj<=endwall; jj++) - { - Gv_SetVarX(returnVar, jj); - insptr = pNext; - VM_Execute(0); - } - break; - case ITER_LOOPOFWALL: - if ((unsigned) nIndex >= (unsigned)numwalls) goto badindex; - { - int jj = nIndex; - do - { - Gv_SetVarX(returnVar, jj); - insptr = pNext; - VM_Execute(0); - jj = wall[jj].point2; - } while (jj != nIndex); - } - break; - case ITER_RANGE: - for (native_t jj=0; jj *insptr); - continue; - - case CON_IFVARGE: - insptr++; - tw = Gv_GetVarX(*insptr++); - VM_CONDITIONAL(tw >= *insptr); - continue; - - case CON_IFVARL: - insptr++; - tw = Gv_GetVarX(*insptr++); - VM_CONDITIONAL(tw < *insptr); - continue; - - case CON_IFVARLE: - insptr++; - tw = Gv_GetVarX(*insptr++); - VM_CONDITIONAL(tw <= *insptr); - continue; - - case CON_IFVARA: - insptr++; - tw = Gv_GetVarX(*insptr++); - VM_CONDITIONAL((uint32_t)tw > (uint32_t)*insptr); - continue; - - case CON_IFVARAE: - insptr++; - tw = Gv_GetVarX(*insptr++); - VM_CONDITIONAL((uint32_t)tw >= (uint32_t)*insptr); - continue; - - case CON_IFVARB: - insptr++; - tw = Gv_GetVarX(*insptr++); - VM_CONDITIONAL((uint32_t)tw < (uint32_t)*insptr); - continue; - - case CON_IFVARBE: - insptr++; - tw = Gv_GetVarX(*insptr++); - VM_CONDITIONAL((uint32_t)tw <= (uint32_t)*insptr); - continue; - - case CON_IFPHEALTHL: - insptr++; - VM_CONDITIONAL(sprite[pPlayer->i].extra < *insptr); - continue; - - case CON_IFPINVENTORY: - insptr++; - - switch (*insptr++) - { - case GET_STEROIDS: - case GET_SHIELD: - case GET_SCUBA: - case GET_HOLODUKE: - case GET_HEATS: - case GET_FIRSTAID: - case GET_BOOTS: - case GET_JETPACK: - tw = (pPlayer->inv_amount[*(insptr - 1)] != *insptr); - break; - - case GET_ACCESS: - switch (vm.pSprite->pal) - { - case 0: tw = (pPlayer->got_access & 1); break; - case 21: tw = (pPlayer->got_access & 2); break; - case 23: tw = (pPlayer->got_access & 4); break; - } - break; - default: tw = 0; CON_ERRPRINTF("invalid inventory item %d\n", (int32_t) * (insptr - 1)); + insptr = savedinsptr; + tw = (Gv_GetVarX(*(insptr - 1)) != *insptr); + VM_CONDITIONAL(tw); + } while (tw); + continue; } - VM_CONDITIONAL(tw); - continue; - - case CON_PSTOMP: - insptr++; - if (pPlayer->knee_incs == 0 && sprite[pPlayer->i].xrepeat >= 40) - if (cansee(vm.pSprite->x, vm.pSprite->y, vm.pSprite->z - ZOFFSET6, vm.pSprite->sectnum, pPlayer->pos.x, - pPlayer->pos.y, pPlayer->pos.z + ZOFFSET2, sprite[pPlayer->i].sectnum)) + case CON_WHILEVARL: + { + intptr_t const *const savedinsptr = insptr + 2; + do { - int numPlayers = g_mostConcurrentPlayers - 1; + insptr = savedinsptr; + tw = (Gv_GetVarX(*(insptr - 1)) < *insptr); + VM_CONDITIONAL(tw); + } while (tw); + continue; + } - for (; numPlayers >= 0; --numPlayers) + case CON_WHILEVARVARN: + { + intptr_t const *const savedinsptr = insptr + 2; + do + { + insptr = savedinsptr; + tw = Gv_GetVarX(*(insptr - 1)); + tw = (tw != Gv_GetVarX(*insptr++)); + insptr--; + VM_CONDITIONAL(tw); + } while (tw); + continue; + } + + case CON_WHILEVARVARL: + { + intptr_t const *const savedinsptr = insptr + 2; + do + { + insptr = savedinsptr; + tw = Gv_GetVarX(*(insptr - 1)); + tw = (tw < Gv_GetVarX(*insptr++)); + insptr--; + VM_CONDITIONAL(tw); + } while (tw); + continue; + } + + case CON_FOR: // special-purpose iteration + insptr++; + { + int const returnVar = *insptr++; + int const iterType = *insptr++; + int const nIndex = iterType <= ITER_DRAWNSPRITES ? 0 : Gv_GetVarX(*insptr++); + + intptr_t const *const pEnd = insptr + *insptr; + intptr_t const *const pNext = ++insptr; + + switch (iterType) { - if (g_player[numPlayers].ps->actorsqu == vm.spriteNum) + case ITER_ALLSPRITES: + for (native_t jj = 0; jj < MAXSPRITES; ++jj) + { + if (sprite[jj].statnum == MAXSTATUS) + continue; + + Gv_SetVarX(returnVar, jj); + insptr = pNext; + VM_Execute(0); + } break; - } + case ITER_ALLSPRITESBYSTAT: + for (native_t statNum = 0; statNum < MAXSTATUS; ++statNum) + { + for (native_t jj = headspritestat[statNum]; jj >= 0;) + { + int const kk = nextspritestat[jj]; + Gv_SetVarX(returnVar, jj); + insptr = pNext; + VM_Execute(0); + jj = kk; + } + } + break; + case ITER_ALLSPRITESBYSECT: + for (native_t sectNum = 0; sectNum < numsectors; ++sectNum) + { + for (native_t jj = headspritesect[sectNum]; jj >= 0;) + { + int const kk = nextspritesect[jj]; + Gv_SetVarX(returnVar, jj); + insptr = pNext; + VM_Execute(0); + jj = kk; + } + } + break; + case ITER_ALLSECTORS: + for (native_t jj = 0; jj < numsectors; ++jj) + { + Gv_SetVarX(returnVar, jj); + insptr = pNext; + VM_Execute(0); + } + break; + case ITER_ALLWALLS: + for (native_t jj = 0; jj < numwalls; ++jj) + { + Gv_SetVarX(returnVar, jj); + insptr = pNext; + VM_Execute(0); + } + break; + case ITER_ACTIVELIGHTS: +#ifdef POLYMER + for (native_t jj = 0; jj < PR_MAXLIGHTS; ++jj) + { + if (!prlights[jj].flags.active) + continue; - if (numPlayers == -1) - { - if (pPlayer->weapon_pos == 0) - pPlayer->weapon_pos = -1; + Gv_SetVarX(returnVar, jj); + insptr = pNext; + VM_Execute(0); + } +#endif + break; - pPlayer->actorsqu = vm.spriteNum; - pPlayer->knee_incs = 1; + case ITER_DRAWNSPRITES: + { + for (native_t ii = 0; ii < spritesortcnt; ii++) + { + Gv_SetVarX(returnVar, ii); + insptr = pNext; + VM_Execute(0); + } + break; + } + + case ITER_SPRITESOFSECTOR: + if ((unsigned)nIndex >= MAXSECTORS) + goto badindex; + for (native_t jj = headspritesect[nIndex]; jj >= 0;) + { + int const kk = nextspritesect[jj]; + Gv_SetVarX(returnVar, jj); + insptr = pNext; + VM_Execute(0); + jj = kk; + } + break; + case ITER_SPRITESOFSTATUS: + if ((unsigned)nIndex >= MAXSTATUS) + goto badindex; + for (native_t jj = headspritestat[nIndex]; jj >= 0;) + { + int const kk = nextspritestat[jj]; + Gv_SetVarX(returnVar, jj); + insptr = pNext; + VM_Execute(0); + jj = kk; + } + break; + case ITER_WALLSOFSECTOR: + if ((unsigned)nIndex >= MAXSECTORS) + goto badindex; + for (native_t jj = sector[nIndex].wallptr, endwall = jj + sector[nIndex].wallnum - 1; jj <= endwall; jj++) + { + Gv_SetVarX(returnVar, jj); + insptr = pNext; + VM_Execute(0); + } + break; + case ITER_LOOPOFWALL: + if ((unsigned)nIndex >= (unsigned)numwalls) + goto badindex; + { + int jj = nIndex; + do + { + Gv_SetVarX(returnVar, jj); + insptr = pNext; + VM_Execute(0); + jj = wall[jj].point2; + } while (jj != nIndex); + } + break; + case ITER_RANGE: + for (native_t jj = 0; jj < nIndex; jj++) + { + Gv_SetVarX(returnVar, jj); + insptr = pNext; + VM_Execute(0); + } + break; + default: + CON_ERRPRINTF("invalid iterator type %d", iterType); + continue; + badindex: + OSD_Printf(OSD_ERROR "Line %d, for %s: index %d out of range!\n", g_errorLineNum, iter_tokens[iterType].token, nIndex); + continue; } + insptr = pEnd; } - continue; + continue; - case CON_IFAWAYFROMWALL: - { - int16_t otherSectnum = vm.pSprite->sectnum; - tw = 0; + case CON_IFPHEALTHL: + insptr++; + VM_CONDITIONAL(sprite[pPlayer->i].extra < *insptr); + continue; + + case CON_IFPINVENTORY: + insptr++; + + switch (*insptr++) + { + case GET_STEROIDS: + case GET_SHIELD: + case GET_SCUBA: + case GET_HOLODUKE: + case GET_HEATS: + case GET_FIRSTAID: + case GET_BOOTS: + case GET_JETPACK: tw = (pPlayer->inv_amount[*(insptr - 1)] != *insptr); break; + + case GET_ACCESS: + switch (vm.pSprite->pal) + { + case 0: tw = (pPlayer->got_access & 1); break; + case 21: tw = (pPlayer->got_access & 2); break; + case 23: tw = (pPlayer->got_access & 4); break; + } + break; + default: tw = 0; CON_ERRPRINTF("invalid inventory item %d\n", (int32_t) * (insptr - 1)); + } + + VM_CONDITIONAL(tw); + continue; + + case CON_PSTOMP: + insptr++; + if (pPlayer->knee_incs == 0 && sprite[pPlayer->i].xrepeat >= 40) + if (cansee(vm.pSprite->x, vm.pSprite->y, vm.pSprite->z - ZOFFSET6, vm.pSprite->sectnum, pPlayer->pos.x, pPlayer->pos.y, + pPlayer->pos.z + ZOFFSET2, sprite[pPlayer->i].sectnum)) + { + int numPlayers = g_mostConcurrentPlayers - 1; + + for (; numPlayers >= 0; --numPlayers) + { + if (g_player[numPlayers].ps->actorsqu == vm.spriteNum) + break; + } + + if (numPlayers == -1) + { + if (pPlayer->weapon_pos == 0) + pPlayer->weapon_pos = -1; + + pPlayer->actorsqu = vm.spriteNum; + pPlayer->knee_incs = 1; + } + } + continue; + + case CON_IFAWAYFROMWALL: + { + int16_t otherSectnum = vm.pSprite->sectnum; + tw = 0; #define IFAWAYDIST 108 - updatesector(vm.pSprite->x + IFAWAYDIST, vm.pSprite->y + IFAWAYDIST, &otherSectnum); - if (otherSectnum == vm.pSprite->sectnum) - { - updatesector(vm.pSprite->x - IFAWAYDIST, vm.pSprite->y - IFAWAYDIST, &otherSectnum); + updatesector(vm.pSprite->x + IFAWAYDIST, vm.pSprite->y + IFAWAYDIST, &otherSectnum); if (otherSectnum == vm.pSprite->sectnum) { - updatesector(vm.pSprite->x + IFAWAYDIST, vm.pSprite->y - IFAWAYDIST, &otherSectnum); + updatesector(vm.pSprite->x - IFAWAYDIST, vm.pSprite->y - IFAWAYDIST, &otherSectnum); if (otherSectnum == vm.pSprite->sectnum) { - updatesector(vm.pSprite->x - IFAWAYDIST, vm.pSprite->y + IFAWAYDIST, &otherSectnum); + updatesector(vm.pSprite->x + IFAWAYDIST, vm.pSprite->y - IFAWAYDIST, &otherSectnum); if (otherSectnum == vm.pSprite->sectnum) - tw = 1; + { + updatesector(vm.pSprite->x - IFAWAYDIST, vm.pSprite->y + IFAWAYDIST, &otherSectnum); + if (otherSectnum == vm.pSprite->sectnum) + tw = 1; + } } } - } - VM_CONDITIONAL(tw); + VM_CONDITIONAL(tw); #undef IFAWAYDIST + } + continue; - } - continue; - - case CON_QUOTE: - insptr++; - - if (EDUKE32_PREDICT_FALSE((unsigned)(*insptr) >= MAXQUOTES) || apStrings[*insptr] == NULL) - { - CON_ERRPRINTF("invalid quote %d\n", (int32_t)(*insptr)); + case CON_QUOTE: insptr++; - continue; - } - if (EDUKE32_PREDICT_FALSE((unsigned)vm.playerNum >= MAXPLAYERS)) - { - CON_ERRPRINTF("invalid player %d\n", vm.playerNum); + if (EDUKE32_PREDICT_FALSE((unsigned)(*insptr) >= MAXQUOTES) || apStrings[*insptr] == NULL) + { + CON_ERRPRINTF("invalid quote %d\n", (int32_t)(*insptr)); + insptr++; + continue; + } + + if (EDUKE32_PREDICT_FALSE((unsigned)vm.playerNum >= MAXPLAYERS)) + { + CON_ERRPRINTF("invalid player %d\n", vm.playerNum); + insptr++; + continue; + } + + P_DoQuote(*(insptr++) | MAXQUOTES, pPlayer); + continue; + + case CON_USERQUOTE: insptr++; + tw = Gv_GetVarX(*insptr++); + + if (EDUKE32_PREDICT_FALSE((unsigned)tw >= MAXQUOTES || apStrings[tw] == NULL)) + { + CON_ERRPRINTF("invalid quote %d\n", (int)tw); + continue; + } + + G_AddUserQuote(apStrings[tw]); continue; - } - P_DoQuote(*(insptr++) | MAXQUOTES, pPlayer); - continue; + case CON_ECHO: + insptr++; + tw = Gv_GetVarX(*insptr++); - case CON_USERQUOTE: - insptr++; - tw = Gv_GetVarX(*insptr++); + if (EDUKE32_PREDICT_FALSE((unsigned)tw >= MAXQUOTES || apStrings[tw] == NULL)) + { + CON_ERRPRINTF("invalid quote %d\n", (int)tw); + continue; + } - if (EDUKE32_PREDICT_FALSE((unsigned)tw >= MAXQUOTES || apStrings[tw] == NULL)) - { - CON_ERRPRINTF("invalid quote %d\n", tw); + OSD_Printf("%s\n", apStrings[tw]); continue; - } - G_AddUserQuote(apStrings[tw]); - continue; + case CON_IFINOUTERSPACE: VM_CONDITIONAL(G_CheckForSpaceFloor(vm.pSprite->sectnum)); continue; - case CON_ECHO: - insptr++; - tw = Gv_GetVarX(*insptr++); + case CON_IFNOTMOVING: VM_CONDITIONAL((vm.pActor->movflag & 49152) > 16384); continue; - if (EDUKE32_PREDICT_FALSE((unsigned)tw >= MAXQUOTES || apStrings[tw] == NULL)) - { - CON_ERRPRINTF("invalid quote %d\n", tw); + case CON_RESPAWNHITAG: + insptr++; + switch (DYNAMICTILEMAP(vm.pSprite->picnum)) + { + case FEM1__STATIC: + case FEM2__STATIC: + case FEM3__STATIC: + case FEM4__STATIC: + case FEM5__STATIC: + case FEM6__STATIC: + case FEM7__STATIC: + case FEM8__STATIC: + case FEM9__STATIC: + case FEM10__STATIC: + case PODFEM1__STATIC: + case NAKED1__STATIC: + case STATUE__STATIC: + if (vm.pSprite->yvel) + G_OperateRespawns(vm.pSprite->yvel); + break; + default: + if (vm.pSprite->hitag >= 0) + G_OperateRespawns(vm.pSprite->hitag); + break; + } continue; - } - OSD_Printf("%s\n", apStrings[tw]); - continue; + case CON_IFSPRITEPAL: + insptr++; + VM_CONDITIONAL(vm.pSprite->pal == *insptr); + continue; - case CON_IFINOUTERSPACE: - VM_CONDITIONAL(G_CheckForSpaceFloor(vm.pSprite->sectnum)); - continue; + case CON_IFANGDIFFL: + insptr++; + tw = klabs(G_GetAngleDelta(fix16_to_int(pPlayer->q16ang), vm.pSprite->ang)); + VM_CONDITIONAL(tw <= *insptr); + continue; - case CON_IFNOTMOVING: - VM_CONDITIONAL((vm.pActor->movflag&49152) > 16384); - continue; + case CON_IFNOSOUNDS: VM_CONDITIONAL(!A_CheckAnySoundPlaying(vm.spriteNum)); continue; - case CON_RESPAWNHITAG: - insptr++; - switch (DYNAMICTILEMAP(vm.pSprite->picnum)) - { - case FEM1__STATIC: - case FEM2__STATIC: - case FEM3__STATIC: - case FEM4__STATIC: - case FEM5__STATIC: - case FEM6__STATIC: - case FEM7__STATIC: - case FEM8__STATIC: - case FEM9__STATIC: - case FEM10__STATIC: - case PODFEM1__STATIC: - case NAKED1__STATIC: - case STATUE__STATIC: - if (vm.pSprite->yvel) - G_OperateRespawns(vm.pSprite->yvel); - break; - default: - if (vm.pSprite->hitag >= 0) - G_OperateRespawns(vm.pSprite->hitag); - break; - } - continue; + case CON_SPRITEFLAGS: + insptr++; + vm.pActor->flags = Gv_GetVarX(*insptr++); + continue; - case CON_IFSPRITEPAL: - insptr++; - VM_CONDITIONAL(vm.pSprite->pal == *insptr); - continue; + case CON_GETTICKS: + insptr++; + Gv_SetVarX(*insptr++, timerGetTicks()); + continue; - case CON_IFANGDIFFL: - insptr++; - tw = klabs(G_GetAngleDelta(fix16_to_int(pPlayer->q16ang), vm.pSprite->ang)); - VM_CONDITIONAL(tw <= *insptr); - continue; + case CON_GETCURRADDRESS: + insptr++; + tw = *insptr++; + Gv_SetVarX(tw, (intptr_t)(insptr - apScript)); + continue; - case CON_IFNOSOUNDS: - VM_CONDITIONAL(!A_CheckAnySoundPlaying(vm.spriteNum)); - continue; - - case CON_SPRITEFLAGS: - insptr++; - vm.pActor->flags = Gv_GetVarX(*insptr++); - continue; - - case CON_GETTICKS: - insptr++; - Gv_SetVarX(*insptr++, timerGetTicks()); - continue; - - case CON_GETCURRADDRESS: - insptr++; - tw = *insptr++; - Gv_SetVarX(tw, (intptr_t)(insptr - apScript)); - continue; - - case CON_JUMP: // XXX XXX XXX - insptr++; - tw = Gv_GetVarX(*insptr++); - insptr = (intptr_t *)(tw + apScript); - continue; - - default: // you aren't supposed to be here! - VM_ScriptInfo(insptr, 64); - G_GameExit("An error has occurred in the " APPNAME " virtual machine.\n\n" - "If you are an end user, please e-mail the file " APPBASENAME ".log\n" - "along with links to any mods you're using to development@voidpoint.com.\n\n" - "If you are a developer, please attach all of your script files\n" - "along with instructions on how to reproduce this error.\n\n" - "Thank you!"); - break; + default: // you aren't supposed to be here! + VM_ScriptInfo(insptr, 64); + G_GameExit("An error has occurred in the " APPNAME " virtual machine.\n\n" + "If you are an end user, please e-mail the file " APPBASENAME ".log\n" + "along with links to any mods you're using to development@voidpoint.com.\n\n" + "If you are a developer, please attach all of your script files\n" + "along with instructions on how to reproduce this error.\n\n" + "Thank you!"); + break; } } } @@ -5911,9 +5853,8 @@ void VM_UpdateAnim(int spriteNum, int32_t *pData) // NORECURSE void A_Execute(int spriteNum, int playerNum, int playerDist) { - vmstate_t tempvm = { - spriteNum, playerNum, playerDist, 0, &sprite[spriteNum], &actor[spriteNum].t_data[0], g_player[playerNum].ps, &actor[spriteNum] - }; + vmstate_t tempvm + = { spriteNum, playerNum, playerDist, 0, &sprite[spriteNum], &actor[spriteNum].t_data[0], g_player[playerNum].ps, &actor[spriteNum] }; vm = tempvm; #ifdef LUNATIC @@ -6123,7 +6064,8 @@ void G_SaveMapState(void) #if !defined LUNATIC for (native_t i=g_gameVarCount-1; i>=0; i--) { - if (aGameVars[i].flags & GAMEVAR_NORESET) continue; + if (aGameVars[i].flags & GAMEVAR_NORESET) + continue; if (aGameVars[i].flags & GAMEVAR_PERPLAYER) { if (!save->vars[i]) @@ -6136,7 +6078,8 @@ void G_SaveMapState(void) save->vars[i] = (intptr_t *)Xaligned_alloc(ACTOR_VAR_ALIGNMENT, MAXSPRITES * sizeof(intptr_t)); Bmemcpy(&save->vars[i][0], aGameVars[i].pValues, sizeof(intptr_t) * MAXSPRITES); } - else save->vars[i] = (intptr_t *)aGameVars[i].global; + else + save->vars[i] = (intptr_t *)aGameVars[i].global; } for (native_t i=g_gameArrayCount-1; i>=0; i--) @@ -6254,18 +6197,22 @@ void G_RestoreMapState(void) #if !defined LUNATIC for (native_t i=g_gameVarCount-1; i>=0; i--) { - if (aGameVars[i].flags & GAMEVAR_NORESET) continue; + if (aGameVars[i].flags & GAMEVAR_NORESET) + continue; if (aGameVars[i].flags & GAMEVAR_PERPLAYER) { - if (!pSavedState->vars[i]) continue; + if (!pSavedState->vars[i]) + continue; Bmemcpy(aGameVars[i].pValues, pSavedState->vars[i], sizeof(intptr_t) * MAXPLAYERS); } else if (aGameVars[i].flags & GAMEVAR_PERACTOR) { - if (!pSavedState->vars[i]) continue; + if (!pSavedState->vars[i]) + continue; Bmemcpy(aGameVars[i].pValues, pSavedState->vars[i], sizeof(intptr_t) * MAXSPRITES); } - else aGameVars[i].global = (intptr_t)pSavedState->vars[i]; + else + aGameVars[i].global = (intptr_t)pSavedState->vars[i]; } for (native_t i=g_gameArrayCount-1; i>=0; i--) @@ -6317,13 +6264,9 @@ void G_RestoreMapState(void) for (native_t x=g_animWallCnt-1; x>=0; x--) switch (DYNAMICTILEMAP(wall[animwall[x].wallnum].picnum)) { - case FEMPIC1__STATIC: - wall[animwall[x].wallnum].picnum = BLANKSCREEN; - break; + case FEMPIC1__STATIC: wall[animwall[x].wallnum].picnum = BLANKSCREEN; break; case FEMPIC2__STATIC: - case FEMPIC3__STATIC: - wall[animwall[x].wallnum].picnum = SCREENBREAK6; - break; + case FEMPIC3__STATIC: wall[animwall[x].wallnum].picnum = SCREENBREAK6; break; } } #if 0 @@ -6347,15 +6290,9 @@ void G_RestoreMapState(void) } #ifdef LUNATIC -void VM_FallSprite(int32_t i) -{ - VM_Fall(i, &sprite[i]); -} +void VM_FallSprite(int32_t i) { VM_Fall(i, &sprite[i]); } -int32_t VM_ResetPlayer2(int32_t snum, int32_t flags) -{ - return VM_ResetPlayer(snum, 0, flags); -} +int32_t VM_ResetPlayer2(int32_t snum, int32_t flags) { return VM_ResetPlayer(snum, 0, flags); } int32_t VM_CheckSquished2(int32_t i, int32_t snum) { @@ -6369,8 +6306,7 @@ int32_t VM_CheckSquished2(int32_t i, int32_t snum) #endif // MYOS* CON commands. -LUNATIC_EXTERN void VM_DrawTileGeneric(int32_t x, int32_t y, int32_t zoom, int32_t tilenum, int32_t shade, - int32_t orientation, int32_t p) +LUNATIC_EXTERN void VM_DrawTileGeneric(int32_t x, int32_t y, int32_t zoom, int32_t tilenum, int32_t shade, int32_t orientation, int32_t p) { orientation &= (ROTATESPRITE_MAX-1);