1 #ifndef _TSC_H
2 #define _TSC_H
3 
4 #include "object.h"
5 
6 #include <map>
7 #include <string>
8 #include <vector>
9 
10 #define NUM_SCRIPT_PAGES 4
11 // TSC running script instance; there is only ever one running at once
12 // but I generalized it as if there might be more just for good style.
13 struct ScriptInstance
14 {
15   const uint8_t *program; // compiled script code
16   uint32_t ip;            // instruction pointer
17   bool running;
18 
19   int scriptno; // script # of active script
20   int pageno;   // ScriptPage/namespace # script is in
21 
22   int delaytimer; // time left on a <WAI delay
23 
24   // used with <NOD
25   bool waitforkey;
26   bool lastjump, lastfire;
27   int nod_delay;
28 
29   int ynj_jump; // if != -1, a Yes/No choice is up, and this is the event # to jump to if they pick No.
30 
31   bool wait_standing; // if 1 pauses script until player touches ground
32 };
33 
34 struct ScriptPage
35 {
36   // a variable-length array of pointers to compiled script code
37   // for each script in the page; their indexes in this array
38   // correspond to their script numbers.
39   std::map<uint16_t, std::vector<uint8_t>> scripts;
40 
ClearScriptPage41   void Clear()
42   {
43     scripts.clear();
44   }
45 };
46 
47 class TSC
48 {
49 
50 public:
51   // script "pages", like namespaces, for the different tsc files
52   enum class ScriptPages : signed
53   {
54     SP_NULL        = -1, // head.tsc common scripts
55     SP_HEAD        = 0,  // head.tsc common scripts
56     SP_MAP         = 1,  // map scripts
57     SP_ARMSITEM    = 2,  // inventory screen
58     SP_STAGESELECT = 3   // scripts for Arthur's House teleporter
59   };
60 
61   TSC();
62   ~TSC();
63 
64   bool StartScript(int scriptno, ScriptPages pageno = ScriptPages::SP_MAP);
65   void StopScript(ScriptInstance *s);
66   bool JumpScript(int newscriptno, ScriptPages pageno = ScriptPages::SP_NULL);
67 
68   void Clear();
69   bool Init(void);
70   void Close(void);
71   bool Load(const std::string &fname, ScriptPages pageno);
72   std::string Decrypt(const std::string &fname, int *fsize_out);
73   bool Compile(const char *buf, int bufsize, ScriptPages pageno);
74   void RunScripts(void);
75   void StopScripts(void);
76   int GetCurrentScript(void);
77   ScriptInstance *GetCurrentScriptInstance();
78   const uint8_t *FindScriptData(int scriptno, ScriptPages pageno, ScriptPages *page_out);
79   void ExecScript(ScriptInstance *s);
80 
81 private:
82   ScriptInstance _curscript;
83   int _lastammoinc = 0;
84   ScriptPage _script_pages[NUM_SCRIPT_PAGES];
85   bool should_set_tao; // text-at-once flag
86 
87   static void _NPCDo(int id2, int p1, int p2, void (*action_function)(Object *o, int p1, int p2));
88   static void _DoANP(Object *o, int p1, int p2);
89   static void _DoCNP(Object *o, int p1, int p2);
90   static void _DoDNP(Object *o, int p1, int p2);
91 };
92 
93 std::string _DescribeCSDir(int csdir);
94 void _SetCSDir(Object *o, int csdir);
95 void _SetPDir(int d);
96 
97 // globally-accessible scripts in head.tsc
98 #define SCRIPT_NULL 0
99 #define SCRIPT_EMPTY 1             // displays a textbox that says "Empty."
100 #define SCRIPT_SAVE 16             // save-game script
101 #define SCRIPT_REFILL 17           // health refill script
102 #define SCRIPT_REST 19             // "Do you want to rest?"
103 #define SCRIPT_MISSILE_LAUNCHER 30 // spiel about missile launcher when you first get it
104 #define SCRIPT_DIED 40             // "You have died. Would you like to retry?"
105 #define SCRIPT_DROWNED 41          // "You have drowned. Would you like to retry?"
106 #define SCRIPT_NEVERSEENAGAIN 42   // "You were never seen again. Would you like to retry?"
107 
108 #define OP_AEPLUS 0   // 0, 0,
109 #define OP_AMPLUS 1   // 2, 0,
110 #define OP_AMMINUS 2  // 1, 0,
111 #define OP_AMJ 3      // 2, 0,
112 #define OP_ANP 4      // 3, 0,
113 #define OP_BOA 5      // 1, 0,
114 #define OP_BSL 6      // 1, 0,
115 #define OP_CAT 7      // 0, 0,
116 #define OP_CIL 8      // 0, 0,
117 #define OP_CLO 9      // 0, 0,
118 #define OP_CLR 10     // 0, 0,
119 #define OP_CMP 11     // 3, 0,
120 #define OP_CMU 12     // 1, 0,
121 #define OP_CNP 13     // 3, 0,
122 #define OP_CPS 14     // 0, 0,
123 #define OP_CRE 15     // 0, 0,
124 #define OP_CSS 16     // 0, 0,
125 #define OP_DNA 17     // 1, 0,
126 #define OP_DNP 18     // 1, 0,
127 #define OP_ECJ 19     // 2, 0,
128 #define OP_END 20     // 0, 0,
129 #define OP_EQPLUS 21  // 1, 0,
130 #define OP_EQMINUS 22 // 1, 0,
131 #define OP_ESC 23     // 0, 0,
132 #define OP_EVE 24     // 1, 0,
133 #define OP_FAC 25     // 1, 0,
134 #define OP_FAI 26     // 1, 0,
135 #define OP_FAO 27     // 1, 0,
136 #define OP_FLPLUS 28  // 1, 0,
137 #define OP_FLMINUS 29 // 1, 0,
138 #define OP_FLA 30     // 0, 0,
139 #define OP_FLJ 31     // 2, 0,
140 #define OP_FMU 32     // 0, 0,
141 #define OP_FOB 33     // 2, 0,
142 #define OP_FOM 34     // 1, 0,
143 #define OP_FON 35     // 2, 0,
144 #define OP_FRE 36     // 0, 0,
145 #define OP_GIT 37     // 1, 0,
146 #define OP_HMC 38     // 0, 0,
147 #define OP_INI 39     // 0, 0,
148 #define OP_INP 40     // 3, 0,
149 #define OP_ITPLUS 41  // 1, 0,
150 #define OP_ITMINUS 42 // 1, 0,
151 #define OP_ITJ 43     // 2, 0,
152 #define OP_KEY 44     // 0, 0,
153 #define OP_LDP 45     // 0, 0,
154 #define OP_LIPLUS 46  // 1, 0,
155 #define OP_MLPLUS 47  // 1, 0,
156 #define OP_MLP 48     // 0, 0,
157 #define OP_MM0 49     // 0, 0,
158 #define OP_MNA 50     // 0, 0,
159 #define OP_MNP 51     // 4, 0,
160 #define OP_MOV 52     // 2, 0,
161 #define OP_MPPLUS 53  // 1, 0,
162 #define OP_MPJ 54     // 1, 0,
163 #define OP_MS2 55     // 0, 0,
164 #define OP_MS3 56     // 0, 0,
165 #define OP_MSG 57     // 0, 0,
166 #define OP_MYB 58     // 1, 0,
167 #define OP_MYD 59     // 1, 0,
168 #define OP_NCJ 60     // 2, 0,
169 #define OP_NOD 61     // 0, 0,
170 #define OP_NUM 62     // 1, 0,
171 #define OP_PRI 63     // 0, 0,
172 #define OP_PSPLUS 64  // 2, 0,
173 #define OP_QUA 65     // 1, 0,
174 #define OP_RMU 66     // 0, 0,
175 #define OP_SAT 67     // 0, 0,
176 #define OP_SIL 68     // 1, 0,
177 #define OP_SKPLUS 69  // 1, 0,
178 #define OP_SKMINUS 70 // 1, 0,
179 #define OP_SKJ 71     // 2, 0,
180 #define OP_SLP 72     // 0, 0,
181 #define OP_SMC 73     // 0, 0,
182 #define OP_SMP 74     // 2, 0,
183 #define OP_SNP 75     // 4, 0,
184 #define OP_SOU 76     // 1, 0,
185 #define OP_SPS 77     // 0, 0,
186 #define OP_SSS 78     // 1, 0,
187 #define OP_STC 79     // 0, 0,
188 #define OP_SVP 80     // 0, 0,
189 #define OP_TAM 81     // 3, 0,
190 #define OP_TRA 82     // 4, 0,
191 #define OP_TUR 83     // 0, 0,
192 #define OP_UNI 84     // 1, 0,
193 #define OP_UNJ 85     // 1, 0,
194 #define OP_WAI 86     // 1, 0,
195 #define OP_WAS 87     // 0, 0,
196 #define OP_XX1 88     // 1, 0,
197 #define OP_YNJ 89     // 1, 0,
198 #define OP_ZAM 90     // 0, 0
199 #define OP_ACH 91     // 0, 0
200 
201 #define OP_COUNT 92
202 
203 #define OP_TEXT 0xfa // mine, denotes start of text
204 
205 #endif
206