ScummVM API documentation
converse_interpret.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef NUVIE_CORE_CONVERSE_INTERPRET_H
23 #define NUVIE_CORE_CONVERSE_INTERPRET_H
24 
25 #include "ultima/nuvie/core/converse.h"
26 
27 namespace Ultima {
28 namespace Nuvie {
29 
30 /* Control and value opcodes for op() & evop() (U6) */
31 #define U6OP_GT 0x81
32 #define U6OP_GE 0x82
33 #define U6OP_LT 0x83
34 #define U6OP_LE 0x84
35 #define U6OP_NE 0x85
36 #define U6OP_EQ 0x86
37 #define U6OP_ADD 0x90
38 #define U6OP_SUB 0x91
39 #define U6OP_MUL 0x92
40 #define U6OP_DIV 0x93
41 #define U6OP_LOR 0x94
42 #define U6OP_LAND 0x95
43 #define U6OP_CANCARRY 0x9a
44 #define U6OP_WEIGHT 0x9b
45 #define U6OP_HORSED 0x9d
46 #define U6OP_HASOBJ 0x9f
47 #define U6OP_RAND 0xa0
48 #define U6OP_EVAL 0xa7
49 #define U6OP_FLAG 0xab
50 #define U6OP_VAR 0xb2
51 #define U6OP_SVAR 0xb3
52 #define U6OP_DATA 0xb4
53 #define U6OP_OBJCOUNT 0xbb
54 #define U6OP_INPARTY 0xc6
55 #define U6OP_OBJINPARTY 0xc7
56 #define U6OP_JOIN 0xca
57 #define U6OP_LEAVE 0xcc
58 #define U6OP_NPCNEARBY 0xd7
59 #define U6OP_WOUNDED 0xda
60 #define U6OP_POISONED 0xdc
61 #define U6OP_NPC 0xdd
62 #define U6OP_EXP 0xe0
63 #define U6OP_LVL 0xe1
64 #define U6OP_STR 0xe2
65 #define U6OP_INT 0xe3
66 #define U6OP_DEX 0xe4
67 
68 #define U6OP_HORSE 0x9c
69 #define U6OP_SLEEP 0x9e
70 #define U6OP_IF 0xa1
71 #define U6OP_ENDIF 0xa2
72 #define U6OP_ELSE 0xa3
73 #define U6OP_SETF 0xa4
74 #define U6OP_CLEARF 0xa5
75 #define U6OP_DECL 0xa6
76 #define U6OP_ASSIGN 0xa8
77 #define U6OP_JUMP 0xb0
78 #define U6OP_DPRINT 0xb5
79 #define U6OP_BYE 0xb6
80 #define U6OP_INDEXOF 0xb7
81 #define U6OP_NEW 0xb9
82 #define U6OP_DELETE 0xba
83 #define U6OP_INVENTORY 0xbe
84 #define U6OP_PORTRAIT 0xbf
85 #define U6OP_ADDKARMA 0xc4
86 #define U6OP_SUBKARMA 0xc5
87 #define U6OP_GIVE 0xc9
88 #define U6OP_WAIT 0xcb
89 #define U6OP_WORKTYPE 0xcd
90 #define U6OP_RESURRECT 0xd6
91 #define U6OP_SETNAME 0xd8
92 #define U6OP_HEAL 0xd9
93 #define U6OP_CURE 0xdb
94 #define U6OP_ENDANSWER 0xee
95 #define U6OP_KEYWORDS 0xef
96 #define U6OP_SLOOK 0xf1
97 #define U6OP_SCONVERSE 0xf2
98 #define U6OP_SPREFIX 0xf3
99 #define U6OP_ANSWER 0xf6
100 #define U6OP_ASK 0xf7
101 #define U6OP_ASKC 0xf8
102 #define U6OP_INPUTSTR 0xf9
103 #define U6OP_INPUT 0xfb
104 #define U6OP_INPUTNUM 0xfc
105 #define U6OP_SIDENT 0xff
106 
107 #define U6OP_ENDDATA 0xb8
108 
109 #define MDOP_MISC_ACTION 0xd1
110 
111 /* Script is executed as it is stepped through byte-by-byte, and can have
112  * text, data, and control codes. Flow is controlled by run-level stack.
113  */
115 protected:
116  Converse *converse; // to get data from container
117 
118  bool is_waiting; // return control to Converse, paused waiting for something
119  bool stopped; // conversation will end, after control returns to Converse
120  uint8 answer_mode; // should a response has been triggered by input?
121 #define ANSWER_NO 0 /* keywords don't match */
122 #define ANSWER_YES 1 /* keywords match */
123 #define ANSWER_DONE 2 /* already answered */
124 
125  // input values (from the script)
126  struct in_val_s {
127  converse_value v; // data
128  uint8 d; // data-size or 0x00
129  };
130  // ONE data item from a converse script db
131  struct converse_db_s {
132  uint8 type; // 0=s 1=i
133  char *s;
134  uint8 i;
135  };
136  // frame around blocks of code that may or may not execute
137  struct convi_frame_s {
138  uint32 start;
139  converse_value start_c; // enter on c
140  bool run; // run(true) or skip(false) instructions
141  converse_value break_c; // will toggle run setting
142  };
143 
144  Common::Array<struct in_val_s> in; // control values (input/instruction)
145  uint32 in_start;
146  Common::String text; // input text from script
147  Common::Array<Common::String> rstrings; // string value(s) returned by op
148  Common::String ystring; // modified by SETNAME, accessed with "$Y"
149  uint8 decl_v; // declared/initialized variable number
150  uint8 decl_t; // declared variable type: 0x00=none,0xb2=int,0xb3=string
152 
153  bool db_lvar;
154  converse_value db_loc;
155  converse_value db_offset;
156 
157 
158  const char *get_rstr(uint32 sn) const {
159  return ((sn < rstrings.size()) ? rstrings[sn].c_str() : "");
160  }
161  const Common::String &get_ystr() const {
162  return ystring;
163  }
164  void set_ystr(const char *s);
165  void set_rstr(uint32 sn, const char *s);
166  converse_value add_rstr(const char *s);
167 
168  void let(uint8 v, uint8 t) {
169  decl_v = v;
170  decl_t = t;
171  }
172  void let() {
173  decl_v = decl_t = 0x00;
174  }
175 
176  void enter(converse_value c);
177  void leave();
178  void leave_all() {
179  while (b_frame && !b_frame->empty()) leave();
180  }
181  struct convi_frame_s *top_frame() const {
182  return ((b_frame && !b_frame->empty()) ? b_frame->top() : nullptr);
183  }
184  void do_frame(converse_value c);
185 
186  void set_break(converse_value c) {
187  if (top_frame()) top_frame()->break_c = c;
188  }
189  converse_value get_break() const {
190  return (top_frame() ? top_frame()->break_c : 0x00);
191  }
192  void clear_break() {
193  set_break(0x00);
194  }
195  void set_run(bool r) {
196  if (top_frame()) top_frame()->run = r;
197  }
198  bool get_run() const {
199  return (top_frame() ? top_frame()->run : true);
200  }
201 
202 public:
203  ConverseInterpret(Converse *owner);
204  virtual ~ConverseInterpret();
205 
206  bool waiting() const {
207  return is_waiting;
208  }
209  void wait() {
210  is_waiting = true;
211  }
212  void unwait() {
213  is_waiting = false;
214  }
215  void stop() {
216  stopped = true;
217  wait();
218  }
219  bool end() {
220  return stopped;
221  }
222 
223  void step();
224 
225 protected:
226  /* collecting from script */
227  virtual void collect_input();
228  virtual struct in_val_s read_value();
229  void eval(uint32 vi = 0);
230 
231  void add_val(converse_value c, uint8 d = 0);
232  void add_text(unsigned char c = 0);
233 
234  /* manipulating collected input */
235  uint32 val_count() const {
236  return in.size();
237  }
238  converse_value get_val(uint32 vi);
239  uint8 get_val_size(uint32 vi);
240  converse_value pop_val();
241  uint8 pop_val_size();
242  const Common::String &get_text() const {
243  return text;
244  }
245  void flush() {
246  in.resize(0);
247  in_start = 0;
248  text.clear();
249  }
250 
251  /* operating on input */
252  void exec();
253  void do_ctrl();
254  void do_text();
255  Common::String get_formatted_text(const char *c_str);
256  converse_value pop_arg(Common::Stack<converse_typed_value> &vs);
258  virtual bool evop(Common::Stack<converse_typed_value> &i);
259  virtual bool op(Common::Stack<converse_typed_value> &i);
260 
261  virtual bool op_create_new(Common::Stack<converse_typed_value> &i);
262 
263  converse_value evop_eq(Common::Stack<converse_typed_value> &vs);
264 
265 public:
266  virtual uint8 npc_num(uint32 n);//uint8 npc_num(uint32 n){return((n!=0xeb)?n:converse->npc_num);}
267  bool check_keywords(Common::String keystr, Common::String instr);
268  bool var_input() const {
269  return decl_t != 0x00;
270  }
271  void assign_input(); // set declared variable to Converse input
272  struct converse_db_s *get_db(uint32 loc, uint32 i);
273  converse_value get_db_integer(uint32 loc, uint32 i);
274  void set_db_integer(uint32 loc, uint32 i, converse_value val);
275  char *get_db_string(uint32 loc, uint32 i);
276  converse_value find_db_string(uint32 loc, const char *dstring);
277 
278  /* value tests */
279  virtual bool is_print(converse_value check) const {
280  return (((check == 0x0a) || (check >= 0x20 && check <= 0x7a) || (check == 0x7e) || (check == 0x7b))); //added '~' 0x7e, '{' 0x7b for fm towns.
281  }
282  virtual bool is_ctrl(converse_value code) const {
283  return (((code >= 0xa1 || code == 0x9c || code == 0x9e) && !is_valop(code) && !is_datasize(code)));
284  }
285  virtual bool is_datasize(converse_value check) const {
286  return ((check == 0xd3 || check == 0xd2 || check == 0xd4));
287  }
288  virtual bool is_valop(converse_value check) const {
289  return (((check == 0x81) || (check == 0x82) || (check == 0x83)
290  || (check == 0x84) || (check == 0x85) || (check == 0x86)
291  || (check == 0x90) || (check == 0x91) || (check == 0x92)
292  || (check == 0x93) || (check == 0x94) || (check == 0x95)
293  || (check == 0x9a) || (check == 0x9b) || (check == 0x9d)
294  || (check == 0x9f) || (check == 0xa0) || (check == 0xa7)
295  || (check == 0xab) || (check == 0xb2) || (check == 0xb3)
296  || (check == 0xb4) || (check == 0xb7) || (check == 0xbb) || (check == 0xc6)
297  || (check == 0xc7) || (check == 0xca) || (check == 0xcc)
298  || (check == 0xd7) || (check == 0xda) || (check == 0xdc)
299  || (check == 0xdd) || (check == 0xe0) || (check == 0xe1)
300  || (check == 0xe2) || (check == 0xe3) || (check == 0xe4)));
301  }
302  const char *evop_str(converse_value op);
303  const char *op_str(converse_value op);
304 };
305 
306 
308 public:
309  U6ConverseInterpret(Converse *owner) : ConverseInterpret(owner) { }
310 // ~U6ConverseInterpret();
311 };
312 
314 public:
315  WOUConverseInterpret(Converse *owner) : ConverseInterpret(owner) { }
316 
317 protected:
318  bool op_create_new(Common::Stack<converse_typed_value> &i) override;
319 };
320 
322 public:
323  SETalkInterpret(Converse *owner) : ConverseInterpret(owner) { }
324 };
325 
326 
328 public:
329  MDTalkInterpret(Converse *owner) : WOUConverseInterpret(owner) { }
330 };
331 
332 } // End of namespace Nuvie
333 } // End of namespace Ultima
334 
335 #endif
Definition: converse.h:55
Definition: str.h:59
Definition: converse_interpret.h:137
Definition: converse_interpret.h:131
Definition: converse_interpret.h:313
Definition: array.h:52
Definition: detection.h:27
Definition: converse_interpret.h:126
Definition: converse_interpret.h:307
size_type size() const
Definition: array.h:316
void resize(size_type newSize)
Definition: array.h:412
Definition: stack.h:102
Definition: converse_interpret.h:114
Definition: converse_interpret.h:327
Definition: converse.h:79
Definition: converse_interpret.h:321