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
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (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, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "common/file.h"
24 
25 #ifndef GLK_AGT_INTERP
26 #define GLK_AGT_INTERP
27 
28 namespace Glk {
29 namespace AGT {
30 
31 /* This file contains variables and data structures used
32 	by the interpreter but not read in from the gamefile.
33    For the rest of the data structures, see agility.h and
34 	agtdata.c */
35 
36 #ifndef global
37 #define uagt_defined_global
38 #define global extern
39 #endif
40 
41 /* -------------------------------------------------------------------- */
42 /* The following are debugging and diagnostic flags.                */
43 /* They are mainly intended for debugging the interpreter, but      */
44 /*  they could concievable be used for debugging games under the    */
45 /* interpreter                              */
46 /* -------------------------------------------------------------------- */
47 
48 global rbool stable_random;
49 /* --Force random numbers to be repeatable. */
50 
51 
52 global rbool DEBUG_MEM; /* prints out information on memory allocation */
53 
54 global rbool debug_parse; /* Prints out long parse diagnostic information
55 			 after the sentence has been parse but before
56 			 disambiguation */
57 global rbool DEBUG_EXEC_VERB; /* This prints out a line indicating each command
58 			 that exec_verb() is asked to run */
59 global rbool DEBUG_DISAMBIG; /* Print out dismabiguation debugging info */
60 global rbool DEBUG_SMSG;    /* Print out STANDARD message info */
61 
62 #define DEBUG_AGT_CMD flag[0]  /* This sends metacommand execution information
63 			to either the screen or debugfile, depending on
64 			whether DEBUG_OUT is true or false. */
65 
66 global rbool debug_disambig, debug_any;
67 /* These determine if metacommands are traced during disambiguation
68  or during the scanning of ANY commands */
69 
70 global rbool DEBUG_OUT; /* True if debugging output is redirected somewhere
71 			other than the screen */
72 global Common::DumpFile *debugfile; /* Where debugging output should be sent */
73 
74 #define def_DEBUG_MEM 1    /* parser.c */
75 
76 
77 /* -------------------------------------------------------------------- */
78 /* The following are AGT 'purity' flags; they turn off features of  */
79 /*   my interpreter that are not fully consistent with the original AGT.*/
80 /* More are defined in agility.h, and you should look there for general */
81 /*  notes                               */
82 /* -------------------------------------------------------------------- */
83 
84 /* The following are defined (and described) in agil.c */
85 extern rbool PURE_INPUT, PURE_TONE;
86 
87 #define PURE_WEAR 1  /* If this is cleared, then things taken off
88 			still stay in the player's inventory.
89 			The support for this isn't quite complete yet
90 			(there are one or two checks that need to be done
91 			but aren't) and so right now this should be 1. */
92 
93 global rbool PURE_DOT; /* Treats period as a letter-character and not
94 			  as punctuation. This should be set automatically
95 			  during initialization based on whether any words
96 			  in the dictionary have dots. */
97 
98 #define FORCE_PURE_DOT 0  /* This forces the period to be treated as a letter
99 				 even if there are no words in the dictionary
100 				 containing periods. The only reason to set
101 				 this was if you were concerned that knowledge
102 				 about the presence or absence of periods in the
103 				 dictionary would give puzzles away. */
104 
105 
106 
107 
108 #define MEM_MARGIN (16*1024) /* 16K should be enough (SOGGY, the largest AGT
109 				game, uses around 12K) */
110 #define PICT_SUPPORT 0  /* Graphics not supported */
111 #define TAB_SIZE 3     /* Number of spaces in a tab */
112 
113 
114 
115 
116 /* -------------------------------------------------------------------- */
117 /*  Variables and Flags related to Metaverbs                */
118 /* -------------------------------------------------------------------- */
119 
120 global rbool notify_flag, listexit_flag, menu_mode;
121 
122 global rbool cmd_saveable; /* set indicates that this command can be repeated
123 			 with AGAIN. */
124 global rbool can_undo;  /* Can we UNDO the last turn? */
125 
126 global uchar *restart_state, *undo_state; /* Store old game states for
127 					 RESTART and UNDO */
128 global char doing_restore; /* Have we been asked to RESTORE? */
129 
130 global rbool do_look;  /* True if we should print a room description */
131 global rbool do_autoverb; /* True if we should run the autoexec verb
132 			  for the current room */
133 
134 /* The following are used for scripting and logging */
135 global rbool script_on;
136 global genfile scriptfile;
137 global signed char logflag; /* 1=logging, 2=replaying, 0=neither, 3=both */
138 global int logdelay; /* -1=wait for keypress, >=0 is numerical delay */
139 global genfile log_in, log_out;
140 
141 global rbool fast_replay; /* If true, don't print MORE prompts. */
142 
143 global rbool sound_on; /* Manipulated by music_cmd; can be used by interface
144 			 to determine if a tone should be made */
145 
146 global integer *pictable; /* Used to decode picture numbers */
147 global fc_type hold_fc; /* Needed to print instructions on demand */
148 
149 global unsigned short compass_rose; /* Used to pass compass info to
150 					the os layer */
151 
152 
153 /* -------------------------------------------------------------------- */
154 /*  Game State                              */
155 /* -------------------------------------------------------------------- */
156 
157 global rbool quitflag, deadflag, winflag, endflag;
158 global rbool first_visit_flag, newlife_flag, room_firstdesc;
159 
160 global rbool start_of_turn; /* True if running the command on the first
161 				  noun in the list */
162 global rbool end_of_turn;  /* True if running command on last noun in
163 				  the list. */
164 
165 global rbool actor_in_scope; /* Used to determine if the actor was in
166 				   scope when the command was originally
167 				   given */
168 
169 global integer loc;   /* Player's location */
170 global integer player_contents, player_worn; /* Worn and carried objects*/
171 
172 global long totwt, totsize; /* Size and wt player is carrying around */
173 
174 global integer curr_lives; /* Number of lives left. */
175 
176 global long tscore, old_score; /* Total score */
177 global long objscore;  /* Portion of tscore that comes from the POINTS
178 			field of nouns and creatures. */
179 
180 global integer turncnt;  /* Number of turns that have passed */
181 global integer curr_time;   /* The time in the game; in the format
182 			   1243==12:43 */
183 
184 global rbool *flag; /* AGT Flags */
185 global short *agt_counter; /* AGT counters */
186 #ifdef AGT_16BIT
187 global short *agt_var; /*AGT variables */
188 #else
189 global long *agt_var;
190 #endif
191 
192 global long agt_number; /* The number entered by the player */
193 global rbool agt_answer; /* Did the player get the answer to the last question
194 			right? */
195 
196 global tline l_stat, r_stat;  /* Left and right parts of status line */
197 /* If r_stat is the empty string, l_stat should be
198 centered to create a Trinity-like status line */
199 
200 global rbool nomatch_aware;  /* Does the game use the nomatch extension
201 				   to the metacommand format?
202 				   (which allow <none> and ANY to be
203 				   distingused) */
204 
205 global rbool smart_look;  /* If true, then LOOK <object> will be converted
206 				to EXAMINE. This is set automatically in agil.c,
207 				based on whether the game file uses
208 				LOOK <object> in any of the metacommands; if it
209 				does, then smart_look is set to 0. */
210 
211 /* -------------------------------------------------------------------- */
212 /* Menu data structures                         */
213 /* -------------------------------------------------------------------- */
214 
215 #define MENU_WIDTH 50
216 typedef char menuentry[MENU_WIDTH];
217 
218 global int  vm_width; /* Width of widest element */
219 global menuentry *verbmenu;
220 
221 
222 
223 /* -------------------------------------------------------------------- */
224 /* Parser Data Structures                       */
225 /*  This also includes "parser-related" variables like dobj and iobj    */
226 /* -------------------------------------------------------------------- */
227 
228 /* This extracts the object number from a parse rec */
229 #define p_obj(objrec) ((objrec) ? (objrec)->obj : 0)
230 
231 /* The following data structures are used for disambiguation of nouns */
232 struct parse_rec {
233 	long num;     /* Numeric value of object; 0 if object doesn't have one */
234 	int obj;     /* Object number; negative values point into the dictionary */
235 	int info;    /* Disambiguation info */
236 	/* -1=last record; ignore obj field. */
237 	word noun, adj;  /* Used for printing out error messages */
238 	short score;   /* Disambiguation score */
239 }; /* Stores objects that have been found during parse */
240 
241 
242 /* In an ideal world, the following would all be local variables. */
243 /*   Unfortunately, they're used in too many different places for this
244 	 to be practical */
245 
246 global int vb;
247 global integer actor, dobj, iobj;
248 global parse_rec *actor_rec, *dobj_rec, *iobj_rec;
249 global word prep;
250 global parse_rec *curr_creat_rec;
251 /* Creature currently behaving in a hostile way:
252 used to fill in $c_name$ messages */
253 
254 global int disambig_score; /* Used to rank objects during disambiguation */
255 
256 #define DISAMBIG_SUCC 1000   /* Score given to an object that triggers a
257 				built-in verb or an action token */
258 
259 
260 #define MAXINPUT 200   /* Max number of words input */
261 
262 global word input[MAXINPUT];  /* 200 words of input should be enough */
263 global words in_text[MAXINPUT];
264 /* The corrospoinding strings, for error reporting purposes */
265 
266 global short ip, ep; /* input pointer and error pointer */
267 global short ap, vp, np, pp, op; /* Points to first word in actor, verb, noun,
268 			and object resp. */
269 
270 
271 
272 /* The following needs to be kept consistant with ext_voc[] in
273    agil.c */
274 typedef enum {wthe, wmy, wa, wan, wthen, wp, wsc, wand, wc, wits, wall, wundo, wlook, wg,
275 			  wpick, wgo, wexits, wtalk, wtake, wdoor, wagain, wbut, wexcept,
276 			  wscene, weverything, wlistexit, wlistexits, wclose,
277 			  wdverb, wdnoun, wdadjective, wdprep, wdobject, wdname,
278 			  wstep, w_any, weither, wboth, weveryone, weverybody,
279 			  whe, wshe, wit, wthey, whim, wher, wthem, wis, ware, woops,
280 			  wwas, wwere,
281 			  win, wout, winto, wat, wto, wacross, winside, wwith, wnear, wfor,
282 			  wof, wbehind, wbeside, won, woff, wunder, wfrom, wthrough,
283 			  wtoward, wtowards, wbetween, waround, wupon, wthru,
284 			  wby, wover, wup, wdown,
285 			  wabout
286 			 } wtype;
287 global word ext_code[wabout + 1]; /* Codes for the above */
288 global short last_he, last_she, last_it, last_they;
289 /* Used for pronoun support */
290 
291 
292 
293 /* -------------------------------------------------------------------- */
294 /* Noun List Data structures and constants              */
295 /* -------------------------------------------------------------------- */
296 
297 
298 /* The following are used in noun lists */
299 #define AND_MARK (-ext_code[wand])
300 #define ALL_MARK (-ext_code[wall])
301 
302 #define D_END  50    /* Marks end of disambiguation list */
303 #define D_AND  51    /* Used to seperate multiple objects during disambig */
304 #define D_NOUN 0   /* Noun match */
305 #define D_SYN 1    /* Adjective/synonym only match */
306 #define D_ADJ 2    /* Adj only match */
307 #define D_FLAG 3   /* Flag noun */
308 #define D_GLOBAL 4 /* Global noun */
309 #define D_PIX 5     /* PIX name */
310 #define D_PRO 6      /* Pronoun */
311 #define D_ALL  7     /* ALL, or a header to an ALL EXCEPT _ AND _ ... list */
312 #define D_INTERN 8     /* Internal nouns: DOOR, SCENE */
313 #define D_NUM  9    /* A number, value is in obj */
314 #define D_EITHER 10  /* EITHER or ANY, used only to resolve disambiguation */
315 
316 #define D_MARK 0x80   /* Used as a temporary marker, usually to indicate
317 			 this noun is being considered for elimination */
318 
319 
320 
321 /* -------------------------------------------------------------------- */
322 /* These are used for text boxes (quotes and the title)                 */
323 /* -------------------------------------------------------------------- */
324 #define TB_TTL 1   /* We're printing the title */
325 #define TB_BOLD 2   /* Print it bold */
326 #define TB_BORDER 4 /* Give it a border */
327 #define TB_CENTER 8  /* Center the text inside */
328 #define TB_NOCENT 16 /* Don't center the whole box */
329 
330 
331 /* -------------------------------------------------------------------- */
332 /* In AGIL.C                                */
333 /* -------------------------------------------------------------------- */
334 extern void print_instructions(fc_type fc);
335 extern void run_game(fc_type fc);
336 
337 /* -------------------------------------------------------------------- */
338 /* In PARSER.C                              */
339 /* -------------------------------------------------------------------- */
340 extern rbool parse(void);  /* Returns true unless there is ambiguity */
341 extern void menu_cmd(void);
342 
343 
344 /* -------------------------------------------------------------------- */
345 /* In EXEC.C                                */
346 /* -------------------------------------------------------------------- */
347 
348 /* Legal values for gen_sysmsg context; they indicate who is calling it */
349 #define MSG_PARSE 0   /* The parser */
350 #define MSG_MAIN 1    /* The main execution loop */
351 #define MSG_RUN  2   /* The routines that execute the player's commands */
352 #define MSG_DESC 3   /* Printing out description. */
353 
354 extern void gen_sysmsg(int msgid, const char *s, int context, const char *pword);
355 /* Prints either STANDARD message <msgid> or default msg <s>;
356    <context> determines what $$ substitutions are meaningful
357    <parseword> gives the $pword$ substitution for MSG_PARSE messages */
358 
359 extern void exec(parse_rec *actor, int vnum, parse_rec *lnoun,
360 				 word prep, parse_rec *iobj);
361 extern void set_statline(void);
362 extern void newroom(void);
363 extern void print_descr(descr_ptr dp, rbool nl);
364 extern void quote(int msgnum);
365 extern void print_score(void);
366 extern long read_number(void);
367 
368 
369 /* -------------------------------------------------------------------- */
370 /* In TOKEN.C                                   */
371 /* -------------------------------------------------------------------- */
372 extern void init_stack(void);  /* Set up expression stack */
373 extern void clear_stack(void);  /* Set stack back to empty state */
374 
375 /* -------------------------------------------------------------------- */
376 /* In OBJECT.C                              */
377 /* -------------------------------------------------------------------- */
378 extern rbool player_has(int item);
379 extern rbool visible(int item);
380 extern rbool genvisible(parse_rec *dobj);
381 extern int *get_nouns(void);  /* Returns list of in scope nouns */
382 extern void add_object(int loc, int item); /* Adds item to loc's contents list */
383 extern void tmpobj(parse_rec *objrec);
384 extern void compute_scope(void); /* Sets scope flags for all of the objects */
385 extern void compute_seen(void);  /* Determine HAS_SEEN flag for nouns and creatures */
386 
387 extern void init_creat_fix(void);
388 extern void free_creat_fix(void);
389 
390 /* -------------------------------------------------------------------  */
391 /* The following are intended as building blocks to construct macros    */
392 /*  to extract information about general objects, regardless of whether */
393 /*  they are nouns, creatures, or virtual nouns with no associated  */
394 /*  data structure.                             */
395 /* -------------------------------------------------------------------  */
396 /* nounattr(item,attr) -- returns 0 if not noun.
397    creatattr(item,attr) -- returns 0 if not creature
398    objattr(item,attr) -- Returns attribute for noun or creature, 0 otherwise
399    anyattr(item,attr) -- Returns attribute for noun, creature, or room,
400 							0 otherwise.
401 */
402 
403 #define creatattr2(item,attr,op3) (tcreat(item)? \
404 								   creature[(item)-first_creat].attr:\
405 								   (op3))
406 #define creatattr(item,attr) creatattr2(item,attr,0)
407 #define nounattr2(item,attr,alt) (tnoun(item)? \
408 								  noun[(item)-first_noun].attr:(alt))
409 #define nounattr(item,attr) nounattr2(item,attr,0)
410 #define objattr(item,attr) nounattr2(item,attr,creatattr(item,attr))
411 #define objattr2(item,attr,op3) nounattr2(item,attr,creatattr2(item,attr,op3))
412 #define roomattr2(item,attr,op3) (troom(item)?\
413 								  room[(item)-first_room].attr:(op3))
414 #define anyattr(item,attr) roomattr2(item,attr,objattr(item,attr))
415 
416 #define it_scratch(item) objattr(item,scratch)
417 #define it_loc(item) objattr2(item,location,\
418 							  (tdoor(item)) ? loc+first_room : 0)
419 
420 
421 /* -------------------------------------------------------------------- */
422 /* In RUNVERB.C                             */
423 /* -------------------------------------------------------------------- */
424 extern int check_obj(parse_rec *act, int verbid,
425 					 parse_rec *donum, word prep, parse_rec *ionum);
426 
427 
428 /* -------------------------------------------------------------------- */
429 /* In AGTDBG.C                              */
430 /* -------------------------------------------------------------------- */
431 extern void debug_cmd_out(int ip, integer op, int arg1, int arg2, int optype);
432 extern void debug_head(int);
433 extern void debug_newline(integer op, rbool first_nl);
434 
435 /* -------------------------------------------------------------------- */
436 /* In SAVEGAME.C                            */
437 /* -------------------------------------------------------------------- */
438 extern Common::Error savegame(Common::WriteStream *savefile);
439 extern Common::Error loadgame(Common::SeekableReadStream *loadfile);
440 extern void init_state_sys(void);  /* Must be called before either of the following */
441 extern uchar *getstate(uchar *gs);
442 /* Returns malloc'd block containing game state. */
443 extern void putstate(uchar *gs); /* Restores games state. */
444 extern void init_vals(void);  /* Compute dependent variables
445 			  such as totwt, totsize, etc. */
446 extern void restart_game(void);
447 
448 
449 /* -------------------------------------------------------------------- */
450 /* In OS_<whatever>.C                           */
451 /* -------------------------------------------------------------------- */
452 global volatile int screen_width, status_width;
453 global int screen_height;
454 global volatile int curr_x;
455 
456 extern void init_interface();
457 extern void start_interface(fc_type fc);
458 extern void close_interface(void);
459 extern char *agt_input(int in_type); /* read line, return malloc'd string */
460 extern char agt_getkey(rbool echo_char);
461 extern void agt_clrscr(void);
462 extern void agt_textcolor(int c);
463 extern void agt_delay(int n); /* n in seconds */
464 extern int agt_rand(int a, int b); /* Return random number from a to b, inclusive */
465 extern void agt_newline(void);
466 extern void agt_puts(const char *s); /* Output string */
467 extern void agt_statline(const char *s); /* Prints s out on status line */
468 extern void agt_tone(int hz, int ms);
469 extern void agt_makebox(int width, int height, unsigned long flags);
470 extern void agt_qnewline(void);
471 extern void agt_endbox(void);
472 extern genfile agt_globalfile(int fid); /* When fid=0, return global config file */
473 extern rbool agt_option(int optnum, char *optstr[], rbool setflag);
474 
475 /* These have stubs defined in interface.c that would ened to be
476 	commented out if you actually wanted to support these */
477 extern void fontcmd(int cmd, int font); /* fontlist[font] */
478 extern void pictcmd(int cmd, int pict); /* pictlist[pict] or pixlist[pict] */
479 extern int musiccmd(int cmd, int song); /* songlist[song] */
480 
481 
482 /* -------------------------------------------------------------------- */
483 /* In INTERFACE.C                           */
484 /* -------------------------------------------------------------------- */
485 /* init_interface() (in os_?????.c) is responsible for initializing these */
486 global rbool par_fill_on, center_on;
487 global rbool textbold;  /* Is the text currently bold? */
488 
489 extern void wait_return(void);
490 extern void agt_waitkey(void);
491 
492 extern void agt_center(rbool b); /* 1=turn on text centering, 0=turn off */
493 extern void agt_par(rbool b); /* 1=turn on "paragraph" mode, 0=turn off */
494 extern char *agt_readline(int in_type); /* Front end for agt_input */
495 extern char agt_getchar(void); /* Front end for some uses of agt_getkey */
496 extern void prompt_out(int);  /* 1=standard prompt, 2=question prompt */
497 extern genfile get_user_file(int ft); /* 0=script, 1=save, 2=restore */
498 extern void set_default_filenames(fc_type fc);
499 extern void script(uchar); /* 0=turn off, 1=turn on */
500 extern void logon(void);  /* Turn on logging */
501 extern int close_pfile(genfile f, int ft); /* ft is the same as for get_user_file */
502 extern void replay(int delay); /* REPLAY */
503 extern rbool yesno(const char *);
504 extern void textbox(char *(txt[]), int len, unsigned long flags);
505 extern void padout(int padleng); /* Outputs padleng spaces */
506 extern int agt_menu(const char *header, int size, int width, menuentry *menu);
507 extern fc_type new_game(void);
508 
509 extern void set_test_mode(fc_type fc);
510 /* This sets up scripting and replaying for testing mode */
511 
512 /* These are intended to be called by the os layer */
513 extern void print_statline(void);
514 
515 extern void agt_save(void);
516 extern void agt_restore(void);
517 extern void agt_restart(void);
518 extern void agt_quit(void);
519 extern void agt_newgame(fc_type fc);
520 
521 /* -------------------------------------------------------------------- */
522 /* Object manipulation macros                       */
523 /* -------------------------------------------------------------------- */
524 #define objloop(i) for(i=first_noun; i<=maxnoun || i<=maxcreat; \
525 					   (i<=maxnoun || i>=first_creat) ? (i++) : (i=first_creat) )
526 #define nounloop(i) for(i=0;i<=maxnoun-first_noun;i++)
527 #define creatloop(i) for(i=0;i<=maxcreat-first_creat;i++)
528 
529 #define tdoor(x) ((x)==-ext_code[wdoor])
530 
531 #ifdef uagt_defined_global
532 #undef global
533 #undef uagt_define_global
534 #endif
535 
536 } // End of namespace AGT
537 } // End of namespace Glk
538 
539 #endif
540