From 0df2cb80cf03d7259746834220d209b306a8c503 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 4 Sep 2008 23:15:36 +0000 Subject: Add GPLed Heretic/Hexen source. Subversion-branch: /branches/raven-branch Subversion-revision: 1195 --- src/hexen/p_acs.c | 1782 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1782 insertions(+) create mode 100644 src/hexen/p_acs.c (limited to 'src/hexen/p_acs.c') diff --git a/src/hexen/p_acs.c b/src/hexen/p_acs.c new file mode 100644 index 00000000..30909db8 --- /dev/null +++ b/src/hexen/p_acs.c @@ -0,0 +1,1782 @@ + +//************************************************************************** +//** +//** p_acs.c : Heretic 2 : Raven Software, Corp. +//** +//** $RCSfile: p_acs.c,v $ +//** $Revision: 1.31 $ +//** $Date: 95/10/09 16:25:17 $ +//** $Author: cjr $ +//** +//************************************************************************** + +// HEADER FILES ------------------------------------------------------------ + +#include "h2def.h" +#include "p_local.h" + +// MACROS ------------------------------------------------------------------ + +#define SCRIPT_CONTINUE 0 +#define SCRIPT_STOP 1 +#define SCRIPT_TERMINATE 2 +#define OPEN_SCRIPTS_BASE 1000 +#define PRINT_BUFFER_SIZE 256 +#define GAME_SINGLE_PLAYER 0 +#define GAME_NET_COOPERATIVE 1 +#define GAME_NET_DEATHMATCH 2 +#define TEXTURE_TOP 0 +#define TEXTURE_MIDDLE 1 +#define TEXTURE_BOTTOM 2 +#define S_DROP ACScript->stackPtr-- +#define S_POP ACScript->stack[--ACScript->stackPtr] +#define S_PUSH(x) ACScript->stack[ACScript->stackPtr++] = x + +// TYPES ------------------------------------------------------------------- + +typedef struct +{ + int marker; + int infoOffset; + int code; +} acsHeader_t; + +// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- + +// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- + +// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- + +static void StartOpenACS(int number, int infoIndex, int *address); +static void ScriptFinished(int number); +static boolean TagBusy(int tag); +static boolean AddToACSStore(int map, int number, byte *args); +static int GetACSIndex(int number); +static void Push(int value); +static int Pop(void); +static int Top(void); +static void Drop(void); + +static int CmdNOP(void); +static int CmdTerminate(void); +static int CmdSuspend(void); +static int CmdPushNumber(void); +static int CmdLSpec1(void); +static int CmdLSpec2(void); +static int CmdLSpec3(void); +static int CmdLSpec4(void); +static int CmdLSpec5(void); +static int CmdLSpec1Direct(void); +static int CmdLSpec2Direct(void); +static int CmdLSpec3Direct(void); +static int CmdLSpec4Direct(void); +static int CmdLSpec5Direct(void); +static int CmdAdd(void); +static int CmdSubtract(void); +static int CmdMultiply(void); +static int CmdDivide(void); +static int CmdModulus(void); +static int CmdEQ(void); +static int CmdNE(void); +static int CmdLT(void); +static int CmdGT(void); +static int CmdLE(void); +static int CmdGE(void); +static int CmdAssignScriptVar(void); +static int CmdAssignMapVar(void); +static int CmdAssignWorldVar(void); +static int CmdPushScriptVar(void); +static int CmdPushMapVar(void); +static int CmdPushWorldVar(void); +static int CmdAddScriptVar(void); +static int CmdAddMapVar(void); +static int CmdAddWorldVar(void); +static int CmdSubScriptVar(void); +static int CmdSubMapVar(void); +static int CmdSubWorldVar(void); +static int CmdMulScriptVar(void); +static int CmdMulMapVar(void); +static int CmdMulWorldVar(void); +static int CmdDivScriptVar(void); +static int CmdDivMapVar(void); +static int CmdDivWorldVar(void); +static int CmdModScriptVar(void); +static int CmdModMapVar(void); +static int CmdModWorldVar(void); +static int CmdIncScriptVar(void); +static int CmdIncMapVar(void); +static int CmdIncWorldVar(void); +static int CmdDecScriptVar(void); +static int CmdDecMapVar(void); +static int CmdDecWorldVar(void); +static int CmdGoto(void); +static int CmdIfGoto(void); +static int CmdDrop(void); +static int CmdDelay(void); +static int CmdDelayDirect(void); +static int CmdRandom(void); +static int CmdRandomDirect(void); +static int CmdThingCount(void); +static int CmdThingCountDirect(void); +static int CmdTagWait(void); +static int CmdTagWaitDirect(void); +static int CmdPolyWait(void); +static int CmdPolyWaitDirect(void); +static int CmdChangeFloor(void); +static int CmdChangeFloorDirect(void); +static int CmdChangeCeiling(void); +static int CmdChangeCeilingDirect(void); +static int CmdRestart(void); +static int CmdAndLogical(void); +static int CmdOrLogical(void); +static int CmdAndBitwise(void); +static int CmdOrBitwise(void); +static int CmdEorBitwise(void); +static int CmdNegateLogical(void); +static int CmdLShift(void); +static int CmdRShift(void); +static int CmdUnaryMinus(void); +static int CmdIfNotGoto(void); +static int CmdLineSide(void); +static int CmdScriptWait(void); +static int CmdScriptWaitDirect(void); +static int CmdClearLineSpecial(void); +static int CmdCaseGoto(void); +static int CmdBeginPrint(void); +static int CmdEndPrint(void); +static int CmdPrintString(void); +static int CmdPrintNumber(void); +static int CmdPrintCharacter(void); +static int CmdPlayerCount(void); +static int CmdGameType(void); +static int CmdGameSkill(void); +static int CmdTimer(void); +static int CmdSectorSound(void); +static int CmdAmbientSound(void); +static int CmdSoundSequence(void); +static int CmdSetLineTexture(void); +static int CmdSetLineBlocking(void); +static int CmdSetLineSpecial(void); +static int CmdThingSound(void); +static int CmdEndPrintBold(void); + +static void ThingCount(int type, int tid); + +// EXTERNAL DATA DECLARATIONS ---------------------------------------------- + +// PUBLIC DATA DEFINITIONS ------------------------------------------------- + +int ACScriptCount; +byte *ActionCodeBase; +acsInfo_t *ACSInfo; +int MapVars[MAX_ACS_MAP_VARS]; +int WorldVars[MAX_ACS_WORLD_VARS]; +acsstore_t ACSStore[MAX_ACS_STORE+1]; // +1 for termination marker + +// PRIVATE DATA DEFINITIONS ------------------------------------------------ + +static acs_t *ACScript; +static int *PCodePtr; +static byte SpecArgs[8]; +static int ACStringCount; +static char **ACStrings; +static char PrintBuffer[PRINT_BUFFER_SIZE]; +static acs_t *NewScript; + +static int (*PCodeCmds[])(void) = +{ + CmdNOP, + CmdTerminate, + CmdSuspend, + CmdPushNumber, + CmdLSpec1, + CmdLSpec2, + CmdLSpec3, + CmdLSpec4, + CmdLSpec5, + CmdLSpec1Direct, + CmdLSpec2Direct, + CmdLSpec3Direct, + CmdLSpec4Direct, + CmdLSpec5Direct, + CmdAdd, + CmdSubtract, + CmdMultiply, + CmdDivide, + CmdModulus, + CmdEQ, + CmdNE, + CmdLT, + CmdGT, + CmdLE, + CmdGE, + CmdAssignScriptVar, + CmdAssignMapVar, + CmdAssignWorldVar, + CmdPushScriptVar, + CmdPushMapVar, + CmdPushWorldVar, + CmdAddScriptVar, + CmdAddMapVar, + CmdAddWorldVar, + CmdSubScriptVar, + CmdSubMapVar, + CmdSubWorldVar, + CmdMulScriptVar, + CmdMulMapVar, + CmdMulWorldVar, + CmdDivScriptVar, + CmdDivMapVar, + CmdDivWorldVar, + CmdModScriptVar, + CmdModMapVar, + CmdModWorldVar, + CmdIncScriptVar, + CmdIncMapVar, + CmdIncWorldVar, + CmdDecScriptVar, + CmdDecMapVar, + CmdDecWorldVar, + CmdGoto, + CmdIfGoto, + CmdDrop, + CmdDelay, + CmdDelayDirect, + CmdRandom, + CmdRandomDirect, + CmdThingCount, + CmdThingCountDirect, + CmdTagWait, + CmdTagWaitDirect, + CmdPolyWait, + CmdPolyWaitDirect, + CmdChangeFloor, + CmdChangeFloorDirect, + CmdChangeCeiling, + CmdChangeCeilingDirect, + CmdRestart, + CmdAndLogical, + CmdOrLogical, + CmdAndBitwise, + CmdOrBitwise, + CmdEorBitwise, + CmdNegateLogical, + CmdLShift, + CmdRShift, + CmdUnaryMinus, + CmdIfNotGoto, + CmdLineSide, + CmdScriptWait, + CmdScriptWaitDirect, + CmdClearLineSpecial, + CmdCaseGoto, + CmdBeginPrint, + CmdEndPrint, + CmdPrintString, + CmdPrintNumber, + CmdPrintCharacter, + CmdPlayerCount, + CmdGameType, + CmdGameSkill, + CmdTimer, + CmdSectorSound, + CmdAmbientSound, + CmdSoundSequence, + CmdSetLineTexture, + CmdSetLineBlocking, + CmdSetLineSpecial, + CmdThingSound, + CmdEndPrintBold +}; + +// CODE -------------------------------------------------------------------- + +//========================================================================== +// +// P_LoadACScripts +// +//========================================================================== + +void P_LoadACScripts(int lump) +{ + int i; + int *buffer; + acsHeader_t *header; + acsInfo_t *info; + + header = W_CacheLumpNum(lump, PU_LEVEL); + ActionCodeBase = (byte *)header; + buffer = (int *)((byte *)header+header->infoOffset); + ACScriptCount = *buffer++; + if(ACScriptCount == 0) + { // Empty behavior lump + return; + } + ACSInfo = Z_Malloc(ACScriptCount*sizeof(acsInfo_t), PU_LEVEL, 0); + memset(ACSInfo, 0, ACScriptCount*sizeof(acsInfo_t)); + for(i = 0, info = ACSInfo; i < ACScriptCount; i++, info++) + { + info->number = *buffer++; + info->address = (int *)((byte *)ActionCodeBase+*buffer++); + info->argCount = *buffer++; + if(info->number >= OPEN_SCRIPTS_BASE) + { // Auto-activate + info->number -= OPEN_SCRIPTS_BASE; + StartOpenACS(info->number, i, info->address); + info->state = ASTE_RUNNING; + } + else + { + info->state = ASTE_INACTIVE; + } + } + ACStringCount = *buffer++; + ACStrings = (char **)buffer; + for(i = 0; i < ACStringCount; i++) + { + ACStrings[i] += (int)ActionCodeBase; + } + memset(MapVars, 0, sizeof(MapVars)); +} + +//========================================================================== +// +// StartOpenACS +// +//========================================================================== + +static void StartOpenACS(int number, int infoIndex, int *address) +{ + acs_t *script; + + script = Z_Malloc(sizeof(acs_t), PU_LEVSPEC, 0); + memset(script, 0, sizeof(acs_t)); + script->number = number; + + // World objects are allotted 1 second for initialization + script->delayCount = 35; + + script->infoIndex = infoIndex; + script->ip = address; + script->thinker.function = T_InterpretACS; + P_AddThinker(&script->thinker); +} + +//========================================================================== +// +// P_CheckACSStore +// +// Scans the ACS store and executes all scripts belonging to the current +// map. +// +//========================================================================== + +void P_CheckACSStore(void) +{ + acsstore_t *store; + + for(store = ACSStore; store->map != 0; store++) + { + if(store->map == gamemap) + { + P_StartACS(store->script, 0, store->args, NULL, NULL, 0); + if(NewScript) + { + NewScript->delayCount = 35; + } + store->map = -1; + } + } +} + +//========================================================================== +// +// P_StartACS +// +//========================================================================== + +static char ErrorMsg[128]; + +boolean P_StartACS(int number, int map, byte *args, mobj_t *activator, + line_t *line, int side) +{ + int i; + acs_t *script; + int infoIndex; + aste_t *statePtr; + + NewScript = NULL; + if(map && map != gamemap) + { // Add to the script store + return AddToACSStore(map, number, args); + } + infoIndex = GetACSIndex(number); + if(infoIndex == -1) + { // Script not found + //I_Error("P_StartACS: Unknown script number %d", number); + sprintf(ErrorMsg, "P_STARTACS ERROR: UNKNOWN SCRIPT %d", number); + P_SetMessage(&players[consoleplayer], ErrorMsg, true); + } + statePtr = &ACSInfo[infoIndex].state; + if(*statePtr == ASTE_SUSPENDED) + { // Resume a suspended script + *statePtr = ASTE_RUNNING; + return true; + } + if(*statePtr != ASTE_INACTIVE) + { // Script is already executing + return false; + } + script = Z_Malloc(sizeof(acs_t), PU_LEVSPEC, 0); + memset(script, 0, sizeof(acs_t)); + script->number = number; + script->infoIndex = infoIndex; + script->activator = activator; + script->line = line; + script->side = side; + script->ip = ACSInfo[infoIndex].address; + script->thinker.function = T_InterpretACS; + for(i = 0; i < ACSInfo[infoIndex].argCount; i++) + { + script->vars[i] = args[i]; + } + *statePtr = ASTE_RUNNING; + P_AddThinker(&script->thinker); + NewScript = script; + return true; +} + +//========================================================================== +// +// AddToACSStore +// +//========================================================================== + +static boolean AddToACSStore(int map, int number, byte *args) +{ + int i; + int index; + + index = -1; + for(i = 0; ACSStore[i].map != 0; i++) + { + if(ACSStore[i].script == number + && ACSStore[i].map == map) + { // Don't allow duplicates + return false; + } + if(index == -1 && ACSStore[i].map == -1) + { // Remember first empty slot + index = i; + } + } + if(index == -1) + { // Append required + if(i == MAX_ACS_STORE) + { + I_Error("AddToACSStore: MAX_ACS_STORE (%d) exceeded.", + MAX_ACS_STORE); + } + index = i; + ACSStore[index+1].map = 0; + } + ACSStore[index].map = map; + ACSStore[index].script = number; + *((int *)ACSStore[index].args) = *((int *)args); + return true; +} + +//========================================================================== +// +// P_StartLockedACS +// +//========================================================================== + + +boolean P_StartLockedACS(line_t *line, byte *args, mobj_t *mo, int side) +{ + int i; + int lock; + byte newArgs[5]; + char LockedBuffer[80]; + + extern char *TextKeyMessages[11]; + + lock = args[4]; + if(!mo->player) + { + return false; + } + if(lock) + { + if(!(mo->player->keys&(1<<(lock-1)))) + { + sprintf(LockedBuffer, "YOU NEED THE %s\n", + TextKeyMessages[lock-1]); + P_SetMessage(mo->player, LockedBuffer, true); + S_StartSound(mo, SFX_DOOR_LOCKED); + return false; + } + } + for(i = 0; i < 4; i++) + { + newArgs[i] = args[i]; + } + newArgs[4] = 0; + return P_StartACS(newArgs[0], newArgs[1], &newArgs[2], mo, + line, side); +} + +//========================================================================== +// +// P_TerminateACS +// +//========================================================================== + +boolean P_TerminateACS(int number, int map) +{ + int infoIndex; + + infoIndex = GetACSIndex(number); + if(infoIndex == -1) + { // Script not found + return false; + } + if(ACSInfo[infoIndex].state == ASTE_INACTIVE + || ACSInfo[infoIndex].state == ASTE_TERMINATING) + { // States that disallow termination + return false; + } + ACSInfo[infoIndex].state = ASTE_TERMINATING; + return true; +} + +//========================================================================== +// +// P_SuspendACS +// +//========================================================================== + +boolean P_SuspendACS(int number, int map) +{ + int infoIndex; + + infoIndex = GetACSIndex(number); + if(infoIndex == -1) + { // Script not found + return false; + } + if(ACSInfo[infoIndex].state == ASTE_INACTIVE + || ACSInfo[infoIndex].state == ASTE_SUSPENDED + || ACSInfo[infoIndex].state == ASTE_TERMINATING) + { // States that disallow suspension + return false; + } + ACSInfo[infoIndex].state = ASTE_SUSPENDED; + return true; +} + +//========================================================================== +// +// P_Init +// +//========================================================================== + +void P_ACSInitNewGame(void) +{ + memset(WorldVars, 0, sizeof(WorldVars)); + memset(ACSStore, 0, sizeof(ACSStore)); +} + +//========================================================================== +// +// T_InterpretACS +// +//========================================================================== + +void T_InterpretACS(acs_t *script) +{ + int cmd; + int action; + + if(ACSInfo[script->infoIndex].state == ASTE_TERMINATING) + { + ACSInfo[script->infoIndex].state = ASTE_INACTIVE; + ScriptFinished(ACScript->number); + P_RemoveThinker(&ACScript->thinker); + return; + } + if(ACSInfo[script->infoIndex].state != ASTE_RUNNING) + { + return; + } + if(script->delayCount) + { + script->delayCount--; + return; + } + ACScript = script; + PCodePtr = ACScript->ip; + do + { + cmd = *PCodePtr++; + action = PCodeCmds[cmd](); + } while(action == SCRIPT_CONTINUE); + ACScript->ip = PCodePtr; + if(action == SCRIPT_TERMINATE) + { + ACSInfo[script->infoIndex].state = ASTE_INACTIVE; + ScriptFinished(ACScript->number); + P_RemoveThinker(&ACScript->thinker); + } +} + +//========================================================================== +// +// P_TagFinished +// +//========================================================================== + +void P_TagFinished(int tag) +{ + int i; + + if(TagBusy(tag) == true) + { + return; + } + for(i = 0; i < ACScriptCount; i++) + { + if(ACSInfo[i].state == ASTE_WAITINGFORTAG + && ACSInfo[i].waitValue == tag) + { + ACSInfo[i].state = ASTE_RUNNING; + } + } +} + +//========================================================================== +// +// P_PolyobjFinished +// +//========================================================================== + +void P_PolyobjFinished(int po) +{ + int i; + + if(PO_Busy(po) == true) + { + return; + } + for(i = 0; i < ACScriptCount; i++) + { + if(ACSInfo[i].state == ASTE_WAITINGFORPOLY + && ACSInfo[i].waitValue == po) + { + ACSInfo[i].state = ASTE_RUNNING; + } + } +} + +//========================================================================== +// +// ScriptFinished +// +//========================================================================== + +static void ScriptFinished(int number) +{ + int i; + + for(i = 0; i < ACScriptCount; i++) + { + if(ACSInfo[i].state == ASTE_WAITINGFORSCRIPT + && ACSInfo[i].waitValue == number) + { + ACSInfo[i].state = ASTE_RUNNING; + } + } +} + +//========================================================================== +// +// TagBusy +// +//========================================================================== + +static boolean TagBusy(int tag) +{ + int sectorIndex; + + sectorIndex = -1; + while((sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0) + { + if(sectors[sectorIndex].specialdata) + { + return true; + } + } + return false; +} + +//========================================================================== +// +// GetACSIndex +// +// Returns the index of a script number. Returns -1 if the script number +// is not found. +// +//========================================================================== + +static int GetACSIndex(int number) +{ + int i; + + for(i = 0; i < ACScriptCount; i++) + { + if(ACSInfo[i].number == number) + { + return i; + } + } + return -1; +} + +//========================================================================== +// +// Push +// +//========================================================================== + +static void Push(int value) +{ + ACScript->stack[ACScript->stackPtr++] = value; +} + +//========================================================================== +// +// Pop +// +//========================================================================== + +static int Pop(void) +{ + return ACScript->stack[--ACScript->stackPtr]; +} + +//========================================================================== +// +// Top +// +//========================================================================== + +static int Top(void) +{ + return ACScript->stack[ACScript->stackPtr-1]; +} + +//========================================================================== +// +// Drop +// +//========================================================================== + +static void Drop(void) +{ + ACScript->stackPtr--; +} + +//========================================================================== +// +// P-Code Commands +// +//========================================================================== + +static int CmdNOP(void) +{ + return SCRIPT_CONTINUE; +} + +static int CmdTerminate(void) +{ + return SCRIPT_TERMINATE; +} + +static int CmdSuspend(void) +{ + ACSInfo[ACScript->infoIndex].state = ASTE_SUSPENDED; + return SCRIPT_STOP; +} + +static int CmdPushNumber(void) +{ + Push(*PCodePtr++); + return SCRIPT_CONTINUE; +} + +static int CmdLSpec1(void) +{ + int special; + + special = *PCodePtr++; + SpecArgs[0] = Pop(); + P_ExecuteLineSpecial(special, SpecArgs, ACScript->line, + ACScript->side, ACScript->activator); + return SCRIPT_CONTINUE; +} + +static int CmdLSpec2(void) +{ + int special; + + special = *PCodePtr++; + SpecArgs[1] = Pop(); + SpecArgs[0] = Pop(); + P_ExecuteLineSpecial(special, SpecArgs, ACScript->line, + ACScript->side, ACScript->activator); + return SCRIPT_CONTINUE; +} + +static int CmdLSpec3(void) +{ + int special; + + special = *PCodePtr++; + SpecArgs[2] = Pop(); + SpecArgs[1] = Pop(); + SpecArgs[0] = Pop(); + P_ExecuteLineSpecial(special, SpecArgs, ACScript->line, + ACScript->side, ACScript->activator); + return SCRIPT_CONTINUE; +} + +static int CmdLSpec4(void) +{ + int special; + + special = *PCodePtr++; + SpecArgs[3] = Pop(); + SpecArgs[2] = Pop(); + SpecArgs[1] = Pop(); + SpecArgs[0] = Pop(); + P_ExecuteLineSpecial(special, SpecArgs, ACScript->line, + ACScript->side, ACScript->activator); + return SCRIPT_CONTINUE; +} + +static int CmdLSpec5(void) +{ + int special; + + special = *PCodePtr++; + SpecArgs[4] = Pop(); + SpecArgs[3] = Pop(); + SpecArgs[2] = Pop(); + SpecArgs[1] = Pop(); + SpecArgs[0] = Pop(); + P_ExecuteLineSpecial(special, SpecArgs, ACScript->line, + ACScript->side, ACScript->activator); + return SCRIPT_CONTINUE; +} + +static int CmdLSpec1Direct(void) +{ + int special; + + special = *PCodePtr++; + SpecArgs[0] = *PCodePtr++; + P_ExecuteLineSpecial(special, SpecArgs, ACScript->line, + ACScript->side, ACScript->activator); + return SCRIPT_CONTINUE; +} + +static int CmdLSpec2Direct(void) +{ + int special; + + special = *PCodePtr++; + SpecArgs[0] = *PCodePtr++; + SpecArgs[1] = *PCodePtr++; + P_ExecuteLineSpecial(special, SpecArgs, ACScript->line, + ACScript->side, ACScript->activator); + return SCRIPT_CONTINUE; +} + +static int CmdLSpec3Direct(void) +{ + int special; + + special = *PCodePtr++; + SpecArgs[0] = *PCodePtr++; + SpecArgs[1] = *PCodePtr++; + SpecArgs[2] = *PCodePtr++; + P_ExecuteLineSpecial(special, SpecArgs, ACScript->line, + ACScript->side, ACScript->activator); + return SCRIPT_CONTINUE; +} + +static int CmdLSpec4Direct(void) +{ + int special; + + special = *PCodePtr++; + SpecArgs[0] = *PCodePtr++; + SpecArgs[1] = *PCodePtr++; + SpecArgs[2] = *PCodePtr++; + SpecArgs[3] = *PCodePtr++; + P_ExecuteLineSpecial(special, SpecArgs, ACScript->line, + ACScript->side, ACScript->activator); + return SCRIPT_CONTINUE; +} + +static int CmdLSpec5Direct(void) +{ + int special; + + special = *PCodePtr++; + SpecArgs[0] = *PCodePtr++; + SpecArgs[1] = *PCodePtr++; + SpecArgs[2] = *PCodePtr++; + SpecArgs[3] = *PCodePtr++; + SpecArgs[4] = *PCodePtr++; + P_ExecuteLineSpecial(special, SpecArgs, ACScript->line, + ACScript->side, ACScript->activator); + return SCRIPT_CONTINUE; +} + +static int CmdAdd(void) +{ + Push(Pop()+Pop()); + return SCRIPT_CONTINUE; +} + +static int CmdSubtract(void) +{ + int operand2; + + operand2 = Pop(); + Push(Pop()-operand2); + return SCRIPT_CONTINUE; +} + +static int CmdMultiply(void) +{ + Push(Pop()*Pop()); + return SCRIPT_CONTINUE; +} + +static int CmdDivide(void) +{ + int operand2; + + operand2 = Pop(); + Push(Pop()/operand2); + return SCRIPT_CONTINUE; +} + +static int CmdModulus(void) +{ + int operand2; + + operand2 = Pop(); + Push(Pop()%operand2); + return SCRIPT_CONTINUE; +} + +static int CmdEQ(void) +{ + Push(Pop() == Pop()); + return SCRIPT_CONTINUE; +} + +static int CmdNE(void) +{ + Push(Pop() != Pop()); + return SCRIPT_CONTINUE; +} + +static int CmdLT(void) +{ + int operand2; + + operand2 = Pop(); + Push(Pop() < operand2); + return SCRIPT_CONTINUE; +} + +static int CmdGT(void) +{ + int operand2; + + operand2 = Pop(); + Push(Pop() > operand2); + return SCRIPT_CONTINUE; +} + +static int CmdLE(void) +{ + int operand2; + + operand2 = Pop(); + Push(Pop() <= operand2); + return SCRIPT_CONTINUE; +} + +static int CmdGE(void) +{ + int operand2; + + operand2 = Pop(); + Push(Pop() >= operand2); + return SCRIPT_CONTINUE; +} + +static int CmdAssignScriptVar(void) +{ + ACScript->vars[*PCodePtr++] = Pop(); + return SCRIPT_CONTINUE; +} + +static int CmdAssignMapVar(void) +{ + MapVars[*PCodePtr++] = Pop(); + return SCRIPT_CONTINUE; +} + +static int CmdAssignWorldVar(void) +{ + WorldVars[*PCodePtr++] = Pop(); + return SCRIPT_CONTINUE; +} + +static int CmdPushScriptVar(void) +{ + Push(ACScript->vars[*PCodePtr++]); + return SCRIPT_CONTINUE; +} + +static int CmdPushMapVar(void) +{ + Push(MapVars[*PCodePtr++]); + return SCRIPT_CONTINUE; +} + +static int CmdPushWorldVar(void) +{ + Push(WorldVars[*PCodePtr++]); + return SCRIPT_CONTINUE; +} + +static int CmdAddScriptVar(void) +{ + ACScript->vars[*PCodePtr++] += Pop(); + return SCRIPT_CONTINUE; +} + +static int CmdAddMapVar(void) +{ + MapVars[*PCodePtr++] += Pop(); + return SCRIPT_CONTINUE; +} + +static int CmdAddWorldVar(void) +{ + WorldVars[*PCodePtr++] += Pop(); + return SCRIPT_CONTINUE; +} + +static int CmdSubScriptVar(void) +{ + ACScript->vars[*PCodePtr++] -= Pop(); + return SCRIPT_CONTINUE; +} + +static int CmdSubMapVar(void) +{ + MapVars[*PCodePtr++] -= Pop(); + return SCRIPT_CONTINUE; +} + +static int CmdSubWorldVar(void) +{ + WorldVars[*PCodePtr++] -= Pop(); + return SCRIPT_CONTINUE; +} + +static int CmdMulScriptVar(void) +{ + ACScript->vars[*PCodePtr++] *= Pop(); + return SCRIPT_CONTINUE; +} + +static int CmdMulMapVar(void) +{ + MapVars[*PCodePtr++] *= Pop(); + return SCRIPT_CONTINUE; +} + +static int CmdMulWorldVar(void) +{ + WorldVars[*PCodePtr++] *= Pop(); + return SCRIPT_CONTINUE; +} + +static int CmdDivScriptVar(void) +{ + ACScript->vars[*PCodePtr++] /= Pop(); + return SCRIPT_CONTINUE; +} + +static int CmdDivMapVar(void) +{ + MapVars[*PCodePtr++] /= Pop(); + return SCRIPT_CONTINUE; +} + +static int CmdDivWorldVar(void) +{ + WorldVars[*PCodePtr++] /= Pop(); + return SCRIPT_CONTINUE; +} + +static int CmdModScriptVar(void) +{ + ACScript->vars[*PCodePtr++] %= Pop(); + return SCRIPT_CONTINUE; +} + +static int CmdModMapVar(void) +{ + MapVars[*PCodePtr++] %= Pop(); + return SCRIPT_CONTINUE; +} + +static int CmdModWorldVar(void) +{ + WorldVars[*PCodePtr++] %= Pop(); + return SCRIPT_CONTINUE; +} + +static int CmdIncScriptVar(void) +{ + ACScript->vars[*PCodePtr++]++; + return SCRIPT_CONTINUE; +} + +static int CmdIncMapVar(void) +{ + MapVars[*PCodePtr++]++; + return SCRIPT_CONTINUE; +} + +static int CmdIncWorldVar(void) +{ + WorldVars[*PCodePtr++]++; + return SCRIPT_CONTINUE; +} + +static int CmdDecScriptVar(void) +{ + ACScript->vars[*PCodePtr++]--; + return SCRIPT_CONTINUE; +} + +static int CmdDecMapVar(void) +{ + MapVars[*PCodePtr++]--; + return SCRIPT_CONTINUE; +} + +static int CmdDecWorldVar(void) +{ + WorldVars[*PCodePtr++]--; + return SCRIPT_CONTINUE; +} + +static int CmdGoto(void) +{ + PCodePtr = (int *)(ActionCodeBase+*PCodePtr); + return SCRIPT_CONTINUE; +} + +static int CmdIfGoto(void) +{ + if(Pop()) + { + PCodePtr = (int *)(ActionCodeBase+*PCodePtr); + } + else + { + PCodePtr++; + } + return SCRIPT_CONTINUE; +} + +static int CmdDrop(void) +{ + Drop(); + return SCRIPT_CONTINUE; +} + +static int CmdDelay(void) +{ + ACScript->delayCount = Pop(); + return SCRIPT_STOP; +} + +static int CmdDelayDirect(void) +{ + ACScript->delayCount = *PCodePtr++; + return SCRIPT_STOP; +} + +static int CmdRandom(void) +{ + int low; + int high; + + high = Pop(); + low = Pop(); + Push(low+(P_Random()%(high-low+1))); + return SCRIPT_CONTINUE; +} + +static int CmdRandomDirect(void) +{ + int low; + int high; + + low = *PCodePtr++; + high = *PCodePtr++; + Push(low+(P_Random()%(high-low+1))); + return SCRIPT_CONTINUE; +} + +static int CmdThingCount(void) +{ + int tid; + + tid = Pop(); + ThingCount(Pop(), tid); + return SCRIPT_CONTINUE; +} + +static int CmdThingCountDirect(void) +{ + int type; + + type = *PCodePtr++; + ThingCount(type, *PCodePtr++); + return SCRIPT_CONTINUE; +} + +static void ThingCount(int type, int tid) +{ + int count; + int searcher; + mobj_t *mobj; + mobjtype_t moType; + thinker_t *think; + + if(!(type+tid)) + { // Nothing to count + return; + } + moType = TranslateThingType[type]; + count = 0; + searcher = -1; + if(tid) + { // Count TID things + while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL) + { + if(type == 0) + { // Just count TIDs + count++; + } + else if(moType == mobj->type) + { + if(mobj->flags&MF_COUNTKILL && mobj->health <= 0) + { // Don't count dead monsters + continue; + } + count++; + } + } + } + else + { // Count only types + for(think = thinkercap.next; think != &thinkercap; + think = think->next) + { + if(think->function != P_MobjThinker) + { // Not a mobj thinker + continue; + } + mobj = (mobj_t *)think; + if(mobj->type != moType) + { // Doesn't match + continue; + } + if(mobj->flags&MF_COUNTKILL && mobj->health <= 0) + { // Don't count dead monsters + continue; + } + count++; + } + } + Push(count); +} + +static int CmdTagWait(void) +{ + ACSInfo[ACScript->infoIndex].waitValue = Pop(); + ACSInfo[ACScript->infoIndex].state = ASTE_WAITINGFORTAG; + return SCRIPT_STOP; +} + +static int CmdTagWaitDirect(void) +{ + ACSInfo[ACScript->infoIndex].waitValue = *PCodePtr++; + ACSInfo[ACScript->infoIndex].state = ASTE_WAITINGFORTAG; + return SCRIPT_STOP; +} + +static int CmdPolyWait(void) +{ + ACSInfo[ACScript->infoIndex].waitValue = Pop(); + ACSInfo[ACScript->infoIndex].state = ASTE_WAITINGFORPOLY; + return SCRIPT_STOP; +} + +static int CmdPolyWaitDirect(void) +{ + ACSInfo[ACScript->infoIndex].waitValue = *PCodePtr++; + ACSInfo[ACScript->infoIndex].state = ASTE_WAITINGFORPOLY; + return SCRIPT_STOP; +} + +static int CmdChangeFloor(void) +{ + int tag; + int flat; + int sectorIndex; + + flat = R_FlatNumForName(ACStrings[Pop()]); + tag = Pop(); + sectorIndex = -1; + while((sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0) + { + sectors[sectorIndex].floorpic = flat; + } + return SCRIPT_CONTINUE; +} + +static int CmdChangeFloorDirect(void) +{ + int tag; + int flat; + int sectorIndex; + + tag = *PCodePtr++; + flat = R_FlatNumForName(ACStrings[*PCodePtr++]); + sectorIndex = -1; + while((sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0) + { + sectors[sectorIndex].floorpic = flat; + } + return SCRIPT_CONTINUE; +} + +static int CmdChangeCeiling(void) +{ + int tag; + int flat; + int sectorIndex; + + flat = R_FlatNumForName(ACStrings[Pop()]); + tag = Pop(); + sectorIndex = -1; + while((sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0) + { + sectors[sectorIndex].ceilingpic = flat; + } + return SCRIPT_CONTINUE; +} + +static int CmdChangeCeilingDirect(void) +{ + int tag; + int flat; + int sectorIndex; + + tag = *PCodePtr++; + flat = R_FlatNumForName(ACStrings[*PCodePtr++]); + sectorIndex = -1; + while((sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0) + { + sectors[sectorIndex].ceilingpic = flat; + } + return SCRIPT_CONTINUE; +} + +static int CmdRestart(void) +{ + PCodePtr = ACSInfo[ACScript->infoIndex].address; + return SCRIPT_CONTINUE; +} + +static int CmdAndLogical(void) +{ + Push(Pop() && Pop()); + return SCRIPT_CONTINUE; +} + +static int CmdOrLogical(void) +{ + Push(Pop() || Pop()); + return SCRIPT_CONTINUE; +} + +static int CmdAndBitwise(void) +{ + Push(Pop()&Pop()); + return SCRIPT_CONTINUE; +} + +static int CmdOrBitwise(void) +{ + Push(Pop()|Pop()); + return SCRIPT_CONTINUE; +} + +static int CmdEorBitwise(void) +{ + Push(Pop()^Pop()); + return SCRIPT_CONTINUE; +} + +static int CmdNegateLogical(void) +{ + Push(!Pop()); + return SCRIPT_CONTINUE; +} + +static int CmdLShift(void) +{ + int operand2; + + operand2 = Pop(); + Push(Pop()<>operand2); + return SCRIPT_CONTINUE; +} + +static int CmdUnaryMinus(void) +{ + Push(-Pop()); + return SCRIPT_CONTINUE; +} + +static int CmdIfNotGoto(void) +{ + if(Pop()) + { + PCodePtr++; + } + else + { + PCodePtr = (int *)(ActionCodeBase+*PCodePtr); + } + return SCRIPT_CONTINUE; +} + +static int CmdLineSide(void) +{ + Push(ACScript->side); + return SCRIPT_CONTINUE; +} + +static int CmdScriptWait(void) +{ + ACSInfo[ACScript->infoIndex].waitValue = Pop(); + ACSInfo[ACScript->infoIndex].state = ASTE_WAITINGFORSCRIPT; + return SCRIPT_STOP; +} + +static int CmdScriptWaitDirect(void) +{ + ACSInfo[ACScript->infoIndex].waitValue = *PCodePtr++; + ACSInfo[ACScript->infoIndex].state = ASTE_WAITINGFORSCRIPT; + return SCRIPT_STOP; +} + +static int CmdClearLineSpecial(void) +{ + if(ACScript->line) + { + ACScript->line->special = 0; + } + return SCRIPT_CONTINUE; +} + +static int CmdCaseGoto(void) +{ + if(Top() == *PCodePtr++) + { + PCodePtr = (int *)(ActionCodeBase+*PCodePtr); + Drop(); + } + else + { + PCodePtr++; + } + return SCRIPT_CONTINUE; +} + +static int CmdBeginPrint(void) +{ + *PrintBuffer = 0; + return SCRIPT_CONTINUE; +} + +static int CmdEndPrint(void) +{ + player_t *player; + + if(ACScript->activator && ACScript->activator->player) + { + player = ACScript->activator->player; + } + else + { + player = &players[consoleplayer]; + } + P_SetMessage(player, PrintBuffer, true); + return SCRIPT_CONTINUE; +} + +static int CmdEndPrintBold(void) +{ + int i; + + for(i = 0; i < MAXPLAYERS; i++) + { + if(playeringame[i]) + { + P_SetYellowMessage(&players[i], PrintBuffer, true); + } + } + return SCRIPT_CONTINUE; +} + +static int CmdPrintString(void) +{ + strcat(PrintBuffer, ACStrings[Pop()]); + return SCRIPT_CONTINUE; +} + +static int CmdPrintNumber(void) +{ + char tempStr[16]; + + sprintf(tempStr, "%d", Pop()); + strcat(PrintBuffer, tempStr); + return SCRIPT_CONTINUE; +} + +static int CmdPrintCharacter(void) +{ + char *bufferEnd; + + bufferEnd = PrintBuffer+strlen(PrintBuffer); + *bufferEnd++ = Pop(); + *bufferEnd = 0; + return SCRIPT_CONTINUE; +} + +static int CmdPlayerCount(void) +{ + int i; + int count; + + count = 0; + for(i = 0; i < MAXPLAYERS; i++) + { + count += playeringame[i]; + } + Push(count); + return SCRIPT_CONTINUE; +} + +static int CmdGameType(void) +{ + int gametype; + + if(netgame == false) + { + gametype = GAME_SINGLE_PLAYER; + } + else if(deathmatch) + { + gametype = GAME_NET_DEATHMATCH; + } + else + { + gametype = GAME_NET_COOPERATIVE; + } + Push(gametype); + return SCRIPT_CONTINUE; +} + +static int CmdGameSkill(void) +{ + Push(gameskill); + return SCRIPT_CONTINUE; +} + +static int CmdTimer(void) +{ + Push(leveltime); + return SCRIPT_CONTINUE; +} + +static int CmdSectorSound(void) +{ + int volume; + mobj_t *mobj; + + mobj = NULL; + if(ACScript->line) + { + mobj = (mobj_t *)&ACScript->line->frontsector->soundorg; + } + volume = Pop(); + S_StartSoundAtVolume(mobj, S_GetSoundID(ACStrings[Pop()]), volume); + return SCRIPT_CONTINUE; +} + +static int CmdThingSound(void) +{ + int tid; + int sound; + int volume; + mobj_t *mobj; + int searcher; + + volume = Pop(); + sound = S_GetSoundID(ACStrings[Pop()]); + tid = Pop(); + searcher = -1; + while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL) + { + S_StartSoundAtVolume(mobj, sound, volume); + } + return SCRIPT_CONTINUE; +} + +static int CmdAmbientSound(void) +{ + int volume; + + volume = Pop(); + S_StartSoundAtVolume(NULL, S_GetSoundID(ACStrings[Pop()]), volume); + return SCRIPT_CONTINUE; +} + +static int CmdSoundSequence(void) +{ + mobj_t *mobj; + + mobj = NULL; + if(ACScript->line) + { + mobj = (mobj_t *)&ACScript->line->frontsector->soundorg; + } + SN_StartSequenceName(mobj, ACStrings[Pop()]); + return SCRIPT_CONTINUE; +} + +static int CmdSetLineTexture(void) +{ + line_t *line; + int lineTag; + int side; + int position; + int texture; + int searcher; + + texture = R_TextureNumForName(ACStrings[Pop()]); + position = Pop(); + side = Pop(); + lineTag = Pop(); + searcher = -1; + while((line = P_FindLine(lineTag, &searcher)) != NULL) + { + if(position == TEXTURE_MIDDLE) + { + sides[line->sidenum[side]].midtexture = texture; + } + else if(position == TEXTURE_BOTTOM) + { + sides[line->sidenum[side]].bottomtexture = texture; + } + else + { // TEXTURE_TOP + sides[line->sidenum[side]].toptexture = texture; + } + } + return SCRIPT_CONTINUE; +} + +static int CmdSetLineBlocking(void) +{ + line_t *line; + int lineTag; + boolean blocking; + int searcher; + + blocking = Pop() ? ML_BLOCKING : 0; + lineTag = Pop(); + searcher = -1; + while((line = P_FindLine(lineTag, &searcher)) != NULL) + { + line->flags = (line->flags&~ML_BLOCKING)|blocking; + } + return SCRIPT_CONTINUE; +} + +static int CmdSetLineSpecial(void) +{ + line_t *line; + int lineTag; + int special, arg1, arg2, arg3, arg4, arg5; + int searcher; + + arg5 = Pop(); + arg4 = Pop(); + arg3 = Pop(); + arg2 = Pop(); + arg1 = Pop(); + special = Pop(); + lineTag = Pop(); + searcher = -1; + while((line = P_FindLine(lineTag, &searcher)) != NULL) + { + line->special = special; + line->arg1 = arg1; + line->arg2 = arg2; + line->arg3 = arg3; + line->arg4 = arg4; + line->arg5 = arg5; + } + return SCRIPT_CONTINUE; +} -- cgit v1.2.3