Skip to content

Commit

Permalink
Hexen|ACScriptInterpreter: Moved remaining ACS interpretation logic i…
Browse files Browse the repository at this point in the history
…nto ACScriptInterpreter

Todo: Cleanup
  • Loading branch information
danij-deng committed Jan 27, 2014
1 parent 0be5024 commit be84246
Show file tree
Hide file tree
Showing 2 changed files with 543 additions and 476 deletions.
145 changes: 133 additions & 12 deletions doomsday/plugins/hexen/include/acscript.h
Expand Up @@ -45,10 +45,6 @@ void P_InitACScript(void);

void P_LoadACScripts(lumpnum_t lump);

/**
* @param map Map number on which the script is being started on.
* @c 0 = Current map. Otherwise 1-based index of the map to start on (deferred).
*/
dd_bool P_StartACScript(int number, uint map, byte *args, mobj_t *activator, Line *line, int side);

dd_bool P_TerminateACScript(int number, uint map);
Expand All @@ -59,10 +55,6 @@ void P_ACScriptTagFinished(int tag);

void P_ACScriptPolyobjFinished(int tag);

/**
* To be called when the current map changes to activate any deferred scripts which
* should now begin/resume.
*/
void P_ACScriptRunDeferredTasks(uint map/*Uri const *map*/);

void P_WriteGlobalACScriptData(void);
Expand All @@ -73,10 +65,8 @@ void P_ReadMapACScriptData(void);

#ifdef __cplusplus
} // extern "C"
#endif

#ifdef __cplusplus
class Interpreter;
class ACScriptInterpreter;
#endif

/**
Expand All @@ -96,7 +86,7 @@ typedef struct acscript_s {
int const *pcodePtr;

#ifdef __cplusplus
Interpreter &interpreter() const;
ACScriptInterpreter &interpreter() const;

void push(int value);
int pop();
Expand All @@ -123,6 +113,137 @@ int ACScript_Read(ACScript *script, int mapVersion);

#ifdef __cplusplus
} // extern "C"

struct BytecodeScriptInfo;

/**
* Action-Code Script (ACS) bytecode interpreter.
*/
class ACScriptInterpreter
{
public:
int mapVars[MAX_ACS_MAP_VARS];
int worldVars[MAX_ACS_WORLD_VARS];

ACScriptInterpreter();

/**
* Load new ACS bytecode from the specified @a lump.
*/
void loadBytecode(lumpnum_t lump);

/**
* Returns the total number of script entrypoints in the loaded bytecode.
*/
int scriptCount() const;

/**
* Start all scripts flagged to begin immediately "on open".
*/
void startOpenScripts();

/**
* Start/resume the specified script.
*
* @param map Map number on which the script is to be started.
* @c 0 = Current map. Otherwise 1-based index of the map to start on (deferred).
*
* @return @c true iff a script was newly started (or deferred).
*/
bool startScript(int scriptNumber, uint map, byte *args, mobj_t *activator = 0,
Line *line = 0, int side = 0);

bool suspendScript(int scriptNumber, uint map);

bool terminateScript(int scriptNumber, uint map);

void tagFinished(int tag);
void polyobjFinished(int tag);

/**
* Returns @c true iff @a scriptNumber is a known entrypoint.
*/
bool hasScriptEntrypoint(int scriptNumber);

/**
* Lookup the info structure for the specified @a scriptNumber (entrypoint).
*/
BytecodeScriptInfo &scriptInfo(int scriptNumber);

inline BytecodeScriptInfo *scriptInfoPtr(int scriptNumber) {
return hasScriptEntrypoint(scriptNumber)? &scriptInfo(scriptNumber) : 0;
}

/**
* Provides readonly access to a string constant from the loaded bytecode.
*/
Str const *string(int stringNumber) const;

/**
* Provides readonly access to the loaded bytecode.
*/
byte const *bytecode() const;

void clearDeferredTasks();

/**
* To be called when the current map changes to activate any deferred scripts
* which should now begin/resume.
*/
void runDeferredTasks(uint map/*Uri const *mapUri*/);

/**
* To be called when the specified @a script is to be formally terminated.
* All other scripts waiting on this are notified.
*
* @param script The script to be formally terminated. Note that the script
* is considered free'd after calling this and pointers to it
* should be considered invalid.
*/
void scriptFinished(ACScript *script);

void writeWorldScriptData();
void readWorldScriptData(int saveVersion);

void writeMapScriptData();
void readMapScriptData();

public: /// @todo make private:
BytecodeScriptInfo &scriptInfoByIndex(int index);

BytecodeScriptInfo &scriptInfoFor(ACScript *script);

private:
/**
* Returns the logical index of a @a scriptNumber; otherwise @c -1.
*/
int scriptInfoIndex(int scriptNumber);

ACScript *newACScript(BytecodeScriptInfo &info, byte const *args, int delayCount = 0);

/**
* A deferred task is enqueued when a script is started on a map not currently loaded.
*/
struct DeferredTask
{
uint map; ///< Target map.
int scriptNumber; ///< On the target map.
byte args[4];
};

bool newDeferredTask(uint map, int scriptNumber, byte const *args);

byte const *_pcode; ///< Start of the loaded bytecode.

int _scriptCount; ///< Number of script entrypoints.
BytecodeScriptInfo *_scriptInfo;

int _stringCount;
Str *_strings;

int _deferredTasksSize;
DeferredTask *_deferredTasks;
};
#endif

#endif // LIBHEXEN_PLAY_ACS_H

0 comments on commit be84246

Please sign in to comment.