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