1 /** @file interpreter.h  Action Code Script (ACS) interpreter.
2  *
3  * @authors Copyright © 2003-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
4  * @authors Copyright © 2005-2015 Daniel Swanson <danij@dengine.net>
5  * @authors Copyright © 1999 Activision
6  *
7  * @par License
8  * GPL: http://www.gnu.org/licenses/gpl.html
9  *
10  * <small>This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by the
12  * Free Software Foundation; either version 2 of the License, or (at your
13  * option) any later version. This program is distributed in the hope that it
14  * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16  * Public License for more details. You should have received a copy of the GNU
17  * General Public License along with this program; if not, write to the Free
18  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19  * 02110-1301 USA</small>
20  */
21 
22 #ifndef LIBCOMMON_ACS_INTERPRETER_H
23 #define LIBCOMMON_ACS_INTERPRETER_H
24 
25 #if __cplusplus
26 #  include "acs/script.h"
27 #  include "mapstatereader.h"
28 #  include "mapstatewriter.h"
29 #endif
30 
31 #define ACS_INTERPRETER_MAX_SCRIPT_ARGS     10
32 #define ACS_INTERPRETER_SCRIPT_STACK_DEPTH  32
33 
34 #ifdef __cplusplus
35 
36 namespace acs {
37 
38 class System;
39 
40 /**
41  * Action Code Script (ACS) interpreter (thinker).
42  *
43  * @ingroup playsim
44  */
45 struct Interpreter
46 {
47     thinker_t thinker;
48     struct mobj_s *activator;
49     Line *line;
50     int side;
51     Script *_script;
52     int delayCount;
53     struct Stack { // Local value stack.
54         int values[ACS_INTERPRETER_SCRIPT_STACK_DEPTH];
55         int height;
56 
57         void push(int value);
58         int pop();
59         int top() const;
60         void drop();
61     } locals;
62     int args[ACS_INTERPRETER_MAX_SCRIPT_ARGS];
63     int const *pcodePtr;
64 
65     System &scriptSys() const;
66 
67     /**
68      * Returns the Script data for the thinker.
69      */
70     Script &script() const;
71 
72     void think();
73 
74     /**
75      * Deserialize the thinker using the given data reader @msr.
76      */
77     int read(MapStateReader *msr);
78 
79     /**
80      * Serialize the thinker using the given data writer @msw.
81      */
82     void write(MapStateWriter *msw) const;
83 
84     /**
85      * Constructs a new ACScript Interpreter and adds its thinker to the map.
86      *
87      * @param script      ACScript to interpret.
88      * @param scriptArgs  Script argument values.
89      * @param activator   Map object activator, if any (can be @c nullptr).
90      * @param delayCount  Number of tics to wait before interpretation begins.
91      *                    (Can be used to delay processing during map startup.)
92      */
93     static thinker_s *newThinker(Script &script, Script::Args const &scriptArgs,
94         struct mobj_s *activator = nullptr, Line *line = nullptr, int side = 0,
95         int delayCount = 0);
96 
97     static int currentScriptNumber;
98 };
99 
100 }  // namespace acs
101 #endif  // __cplusplus
102 
103 // C wrapper API ---------------------------------------------------------------
104 
105 // Opaque type for interpreter instances.
106 struct acs_Interpreter;
107 
108 #ifdef __cplusplus
109 extern "C" {
110 #endif
111 
112 void acs_Interpreter_Think(acs_Interpreter *interp);
113 
114 #ifdef __cplusplus
115 }  // extern "C"
116 #endif
117 
118 #endif  // LIBCOMMON_ACS_INTERPRETER_H
119