Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor|libcommon: Use an object-oriented model for ACScript system …
…components Now uses a common, OO model for all ACScript system components, in "acs" namespace. Functionality is separated into Interpreter, Script and System components. Also fixed a couple of bugs that crept in during the custom episodes implementation, through misinterpretation of vanilla behavior due to a logic error in vanilla (which, subtly masked various bugs in the Hexen IWAD(s)...).
- Loading branch information
1 parent
63939ea
commit 11ef7e3
Showing
82 changed files
with
3,049 additions
and
2,723 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
/** @file interpreter.h Action Code Script (ACS) interpreter. | ||
* | ||
* @authors Copyright © 2003-2013 Jaakko Keränen <jaakko.keranen@iki.fi> | ||
* @authors Copyright © 2005-2015 Daniel Swanson <danij@dengine.net> | ||
* @authors Copyright © 1999 Activision | ||
* | ||
* @par License | ||
* GPL: http://www.gnu.org/licenses/gpl.html | ||
* | ||
* <small>This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by the | ||
* Free Software Foundation; either version 2 of the License, or (at your | ||
* option) any later version. This program is distributed in the hope that it | ||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty | ||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | ||
* Public License for more details. You should have received a copy of the GNU | ||
* General Public License along with this program; if not, write to the Free | ||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
* 02110-1301 USA</small> | ||
*/ | ||
|
||
#ifndef LIBCOMMON_ACS_INTERPRETER_H | ||
#define LIBCOMMON_ACS_INTERPRETER_H | ||
|
||
#if __cplusplus | ||
# include "acs/script.h" | ||
# include "mapstatereader.h" | ||
# include "mapstatewriter.h" | ||
#endif | ||
|
||
#define ACS_INTERPRETER_MAX_SCRIPT_ARGS 10 | ||
#define ACS_INTERPRETER_SCRIPT_STACK_DEPTH 32 | ||
|
||
#ifdef __cplusplus | ||
|
||
namespace acs { | ||
|
||
class System; | ||
|
||
/** | ||
* Action Code Script (ACS) interpreter (thinker). | ||
* | ||
* @ingroup playsim | ||
*/ | ||
struct Interpreter | ||
{ | ||
thinker_t thinker; | ||
struct mobj_s *activator; | ||
Line *line; | ||
int side; | ||
void *_script; | ||
int delayCount; | ||
struct Stack { // Local value stack. | ||
int values[ACS_INTERPRETER_SCRIPT_STACK_DEPTH]; | ||
int height; | ||
|
||
void push(int value); | ||
int pop(); | ||
int top() const; | ||
void drop(); | ||
} locals; | ||
int args[ACS_INTERPRETER_MAX_SCRIPT_ARGS]; | ||
int const *pcodePtr; | ||
|
||
acs::System &scriptSys() const; | ||
|
||
/** | ||
* Returns the Script data for the thinker. | ||
*/ | ||
acs::Script &script() const; | ||
|
||
void think(); | ||
|
||
/** | ||
* Deserialize the thinker from the currently open save file. | ||
*/ | ||
int read(MapStateReader *msr); | ||
|
||
/** | ||
* Serialize the thinker to the currently open save file. | ||
*/ | ||
void write(MapStateWriter *msw) const; | ||
|
||
/** | ||
* @param script Logical ACS script-state instance. | ||
* @param scriptArgs Args passed to the script. | ||
* @param delayCount Delay in tics to wait before interpretation begins. | ||
*/ | ||
static thinker_s *newThinker(acs::Script &script, acs::Script::Args const &scriptArgs, | ||
struct mobj_s *activator = nullptr, Line *line = nullptr, | ||
int side = 0, int delayCount = 0); | ||
}; | ||
|
||
} // namespace acs | ||
#endif // __cplusplus | ||
|
||
// C wrapper API --------------------------------------------------------------- | ||
|
||
// Opaque type for interpreter instances. | ||
struct acs_Interpreter; | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
void acs_Interpreter_Think(acs_Interpreter *interp); | ||
|
||
#ifdef __cplusplus | ||
} // extern "C" | ||
#endif | ||
|
||
#endif // LIBCOMMON_ACS_INTERPRETER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
/** @file script.h Action Code Script (ACS), script model. | ||
* | ||
* @authors Copyright © 2003-2013 Jaakko Keränen <jaakko.keranen@iki.fi> | ||
* @authors Copyright © 2005-2015 Daniel Swanson <danij@dengine.net> | ||
* @authors Copyright © 1999 Activision | ||
* | ||
* @par License | ||
* GPL: http://www.gnu.org/licenses/gpl.html | ||
* | ||
* <small>This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by the | ||
* Free Software Foundation; either version 2 of the License, or (at your | ||
* option) any later version. This program is distributed in the hope that it | ||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty | ||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | ||
* Public License for more details. You should have received a copy of the GNU | ||
* General Public License along with this program; if not, write to the Free | ||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
* 02110-1301 USA</small> | ||
*/ | ||
|
||
#ifndef LIBCOMMON_ACS_SCRIPT_H | ||
#define LIBCOMMON_ACS_SCRIPT_H | ||
|
||
#include "common.h" | ||
#include <array> | ||
#include <de/reader.h> | ||
#include <de/writer.h> | ||
#include <de/String> | ||
|
||
namespace acs { | ||
|
||
class System; | ||
|
||
/** | ||
* Models the high-level state of an Action Code Script (ACS). | ||
* | ||
* @ingroup playsim | ||
*/ | ||
class Script | ||
{ | ||
public: | ||
/** | ||
* Stores information about an ACS byte/p-code entry point. | ||
*/ | ||
struct EntryPoint | ||
{ | ||
int const *pcodePtr = nullptr; | ||
bool startWhenMapBegins = false; | ||
int scriptNumber = 0; | ||
int scriptArgCount = 0; | ||
}; | ||
|
||
/** | ||
* Script arguments. | ||
*/ | ||
class Args : public std::array<de::dbyte, 4> | ||
{ | ||
public: | ||
Args(); | ||
Args(de::dbyte const *cArr, de::dint length); | ||
}; | ||
|
||
/** | ||
* Logical script states. | ||
*/ | ||
enum State { | ||
Inactive, | ||
Running, | ||
Suspended, | ||
|
||
WaitingForSector, | ||
WaitingForPolyobj, | ||
WaitingForScript, | ||
|
||
Terminating | ||
}; | ||
static de::String stateAsText(State state); | ||
|
||
public: | ||
Script(); | ||
Script(EntryPoint const &ep); | ||
|
||
/** | ||
* Composes the human-friendly, styled, textual name of the object. | ||
*/ | ||
de::String describe() const; | ||
|
||
/** | ||
* Composes a human-friendly, styled, textual description of the script. | ||
*/ | ||
de::String description() const; | ||
|
||
/** | ||
* Start/resume script interpretation if inactive/suspended. | ||
* | ||
* If currently suspended the script is instructed to resume (deferred). | ||
* | ||
* Otherwise instantiate a new script Interpreter and add it to the list of | ||
* thinkers for the @em current map. | ||
* | ||
* @param args Script argument values. | ||
* @param activator Mobj activator, if any (can be @c nullptr). | ||
* @param line Line activator, if any (can be @c nullptr). | ||
* @param side Line side number. | ||
* @param delayTics Number of tics to wait before interpretation begins. | ||
* (Can be used to delay processing during map startup). | ||
* | ||
* @return @c true if started/resumed. | ||
*/ | ||
bool start(Args const &args, mobj_t *activator = nullptr, | ||
Line *line = nullptr, int side = 0, int delayTics = 0); | ||
|
||
/** | ||
* Instruct the script to self-suspend if running (deferred). | ||
* | ||
* @return @c true if marked for suspension. | ||
*/ | ||
bool suspend(); | ||
|
||
/** | ||
* Instruct the script to self-terminate if running (deferred). | ||
* | ||
* @return @c true if marked for termination. | ||
*/ | ||
bool terminate(); | ||
|
||
/** | ||
* Returns the current logical state of the script (FYI). | ||
*/ | ||
State state() const; | ||
|
||
bool isRunning() const; | ||
bool isSuspended() const; | ||
bool isWaiting() const; | ||
|
||
void waitForPolyobj(int tag); | ||
void waitForScript (int number); | ||
void waitForSector (int tag); | ||
|
||
void polyobjFinished(int tag); | ||
void sectorFinished (int tag); | ||
|
||
/** | ||
* Returns the entry point info for the script. | ||
*/ | ||
EntryPoint const &entryPoint() const; | ||
|
||
/** | ||
* Reconfigure the entry point info for the script. | ||
*/ | ||
void applyEntryPoint(EntryPoint const &epToCopy); | ||
|
||
void read(Reader *reader); | ||
void write(Writer *writer) const; | ||
|
||
public: /// @todo make private: | ||
|
||
/** | ||
* Resume @em this script if it is waiting on @a other (which has just terminated). | ||
* | ||
* @param other Script to be considered. | ||
*/ | ||
void resumeIfWaitingForScript(Script const &other); | ||
|
||
void setState(State newState); | ||
|
||
private: | ||
DENG2_PRIVATE(d) | ||
}; | ||
|
||
} // namespace acs | ||
|
||
#endif // LIBCOMMON_ACS_SCRIPT_H |
Oops, something went wrong.