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