Navigation Menu

Skip to content

Commit

Permalink
ACS|Hexen: Translate ACS script numbers when loading new bytecode
Browse files Browse the repository at this point in the history
  • Loading branch information
danij-deng committed Jan 27, 2014
1 parent aa6bb8e commit eb14c98
Showing 1 changed file with 47 additions and 32 deletions.
79 changes: 47 additions & 32 deletions doomsday/plugins/hexen/src/acscript.cpp
Expand Up @@ -94,6 +94,11 @@ struct BytecodeHeader
*/
struct BytecodeScriptInfo
{
enum Flag {
Open = 0x1
};

int flags;
int number;
int const *address;
int argCount;
Expand All @@ -105,7 +110,7 @@ struct BytecodeScriptInfo
};

/**
* Action-Code Script Interpreter (ACS).
* Action-Code Script (ACS) bytecode interpreter.
*/
class Interpreter
{
Expand All @@ -123,6 +128,8 @@ class Interpreter
*/
void loadBytecode(lumpnum_t lump)
{
#define OPEN_SCRIPTS_BASE 1000

DENG_ASSERT(!IS_CLIENT);

size_t const lumpLength = (lump >= 0? W_LumpLength(lump) : 0);
Expand Down Expand Up @@ -155,8 +162,7 @@ class Interpreter
return;
}

_scriptInfo = (BytecodeScriptInfo *) Z_Malloc(_scriptCount * sizeof(BytecodeScriptInfo), PU_MAP, 0);
memset(_scriptInfo, 0, _scriptCount * sizeof(BytecodeScriptInfo));
_scriptInfo = (BytecodeScriptInfo *) Z_Calloc(_scriptCount * sizeof(BytecodeScriptInfo), PU_MAP, 0);

BytecodeScriptInfo *info = _scriptInfo;
for(int i = 0; i < _scriptCount; ++i, info++)
Expand All @@ -165,6 +171,12 @@ class Interpreter
info->address = (int const *)(_pcode + LONG(*buffer++));
info->argCount = LONG(*buffer++);
info->state = Inactive;

if(info->number >= OPEN_SCRIPTS_BASE)
{
info->flags |= BytecodeScriptInfo::Open;
info->number -= OPEN_SCRIPTS_BASE;
}
}

_stringCount = LONG(*buffer++);
Expand All @@ -173,6 +185,8 @@ class Interpreter
{
_strings[i] = (char const *)(_pcode + LONG(*buffer++));
}

#undef OPEN_SCRIPTS_BASE
}

/**
Expand All @@ -188,22 +202,17 @@ class Interpreter
*/
void startOpenScripts()
{
#define OPEN_SCRIPTS_BASE 1000

// Each is allotted 1 second for initialization.
for(int i = 0; i < _scriptCount; ++i)
{
BytecodeScriptInfo &info = _scriptInfo[i];

if(info.number >= OPEN_SCRIPTS_BASE)
if(info.flags & BytecodeScriptInfo::Open)
{
info.number -= OPEN_SCRIPTS_BASE;
newACScript(info, TICSPERSEC);
info.state = Running;
}
}

#undef OPEN_SCRIPTS_BASE
}

/**
Expand Down Expand Up @@ -263,8 +272,7 @@ class Interpreter
*/
BytecodeScriptInfo &scriptInfo(int scriptNumber)
{
DENG_ASSERT(scriptNumber >= 0 && scriptNumber < _scriptCount);
return _scriptInfo[scriptNumber];
return _scriptInfo[scriptInfoIndex(scriptNumber)];
}

inline BytecodeScriptInfo *scriptInfoPtr(int scriptNumber) {
Expand Down Expand Up @@ -301,7 +309,7 @@ class Interpreter
if(!script) return;

// This script has now finished.
scriptInfo(script->infoIndex).state = Inactive;
scriptInfoByIndex(script->infoIndex).state = Inactive;

// Notify any scripts which are waiting for this script to finish.
for(int i = 0; i < _scriptCount; ++i)
Expand All @@ -316,6 +324,13 @@ class Interpreter
Thinker_Remove(&script->thinker);
}

public: /// @todo make private:
BytecodeScriptInfo &scriptInfoByIndex(int index)
{
DENG_ASSERT(index >= 0 && index < _scriptCount);
return _scriptInfo[index];
}

private:
/**
* Returns the logical index of a @a scriptNumber; otherwise @c -1.
Expand Down Expand Up @@ -690,7 +705,7 @@ void P_ACScriptTagFinished(int tag)

for(int i = 0; i < interp.scriptCount(); ++i)
{
BytecodeScriptInfo &info = interp.scriptInfo(i);
BytecodeScriptInfo &info = interp.scriptInfoByIndex(i);
if(info.state == WaitingForTag && info.waitValue == tag)
{
info.state = Running;
Expand All @@ -704,7 +719,7 @@ void P_ACScriptPolyobjFinished(int tag)

for(int i = 0; i < interp.scriptCount(); ++i)
{
BytecodeScriptInfo &info = interp.scriptInfo(i);
BytecodeScriptInfo &info = interp.scriptInfoByIndex(i);
if(info.state == WaitingForPolyobj && info.waitValue == tag)
{
info.state = Running;
Expand Down Expand Up @@ -763,7 +778,7 @@ static ACS_COMMAND(Terminate)

static ACS_COMMAND(Suspend)
{
interp.scriptInfo(activeScript->infoIndex).state = Suspended;
interp.scriptInfoByIndex(activeScript->infoIndex).state = Suspended;
return Stop;
}

Expand Down Expand Up @@ -1268,29 +1283,29 @@ static void thingCount(int type, int tid)

static ACS_COMMAND(TagWait)
{
interp.scriptInfo(activeScript->infoIndex).waitValue = pop();
interp.scriptInfo(activeScript->infoIndex).state = WaitingForTag;
interp.scriptInfoByIndex(activeScript->infoIndex).waitValue = pop();
interp.scriptInfoByIndex(activeScript->infoIndex).state = WaitingForTag;
return Stop;
}

static ACS_COMMAND(TagWaitDirect)
{
interp.scriptInfo(activeScript->infoIndex).waitValue = LONG(*PCodePtr++);
interp.scriptInfo(activeScript->infoIndex).state = WaitingForTag;
interp.scriptInfoByIndex(activeScript->infoIndex).waitValue = LONG(*PCodePtr++);
interp.scriptInfoByIndex(activeScript->infoIndex).state = WaitingForTag;
return Stop;
}

static ACS_COMMAND(PolyWait)
{
interp.scriptInfo(activeScript->infoIndex).waitValue = pop();
interp.scriptInfo(activeScript->infoIndex).state = WaitingForPolyobj;
interp.scriptInfoByIndex(activeScript->infoIndex).waitValue = pop();
interp.scriptInfoByIndex(activeScript->infoIndex).state = WaitingForPolyobj;
return Stop;
}

static ACS_COMMAND(PolyWaitDirect)
{
interp.scriptInfo(activeScript->infoIndex).waitValue = LONG(*PCodePtr++);
interp.scriptInfo(activeScript->infoIndex).state = WaitingForPolyobj;
interp.scriptInfoByIndex(activeScript->infoIndex).waitValue = LONG(*PCodePtr++);
interp.scriptInfoByIndex(activeScript->infoIndex).state = WaitingForPolyobj;
return Stop;
}

Expand Down Expand Up @@ -1411,7 +1426,7 @@ static ACS_COMMAND(ChangeCeilingDirect)

static ACS_COMMAND(Restart)
{
PCodePtr = interp.scriptInfo(activeScript->infoIndex).address;
PCodePtr = interp.scriptInfoByIndex(activeScript->infoIndex).address;
return Continue;
}

Expand Down Expand Up @@ -1492,15 +1507,15 @@ static ACS_COMMAND(LineSide)

static ACS_COMMAND(ScriptWait)
{
interp.scriptInfo(activeScript->infoIndex).waitValue = pop();
interp.scriptInfo(activeScript->infoIndex).state = WaitingForScript;
interp.scriptInfoByIndex(activeScript->infoIndex).waitValue = pop();
interp.scriptInfoByIndex(activeScript->infoIndex).state = WaitingForScript;
return Stop;
}

static ACS_COMMAND(ScriptWaitDirect)
{
interp.scriptInfo(activeScript->infoIndex).waitValue = LONG(*PCodePtr++);
interp.scriptInfo(activeScript->infoIndex).state = WaitingForScript;
interp.scriptInfoByIndex(activeScript->infoIndex).waitValue = LONG(*PCodePtr++);
interp.scriptInfoByIndex(activeScript->infoIndex).state = WaitingForScript;
return Stop;
}

Expand Down Expand Up @@ -1918,7 +1933,7 @@ void P_WriteMapACScriptData()

for(int i = 0; i < interp.scriptCount(); ++i)
{
BytecodeScriptInfo &info = interp.scriptInfo(i);
BytecodeScriptInfo &info = interp.scriptInfoByIndex(i);
SV_WriteShort(info.state);
SV_WriteShort(info.waitValue);
}
Expand All @@ -1935,7 +1950,7 @@ void P_ReadMapACScriptData()

for(int i = 0; i < interp.scriptCount(); ++i)
{
BytecodeScriptInfo &info = interp.scriptInfo(i);
BytecodeScriptInfo &info = interp.scriptInfoByIndex(i);

info.state = (ACScriptState) SV_ReadShort();
info.waitValue = SV_ReadShort();
Expand All @@ -1951,7 +1966,7 @@ void ACScript_Thinker(ACScript *script)
{
DENG_ASSERT(script != 0);

BytecodeScriptInfo &info = interp.scriptInfo(script->infoIndex);
BytecodeScriptInfo &info = interp.scriptInfoByIndex(script->infoIndex);
if(info.state == Terminating)
{
interp.scriptFinished(script);
Expand Down Expand Up @@ -2103,7 +2118,7 @@ D_CMD(ScriptInfo)

for(int i = 0; i < interp.scriptCount(); ++i)
{
BytecodeScriptInfo &info = interp.scriptInfo(i);
BytecodeScriptInfo &info = interp.scriptInfoByIndex(i);

if(whichOne != -1 && whichOne != info.number)
continue;
Expand Down

0 comments on commit eb14c98

Please sign in to comment.