/*  uagt.h-- Header file for interpreter data structures     */
/* Copyright 1996,97    Robert Masenten                      */
/*                                                           */
/* This is part of the source for AGiliTy: the (Mostly) Universal  */
/*       AGT Interpreter                                           */

/* This file contains variables and data structures used  
    by the interpreter but not read in from the gamefile.
   For the rest of the data structures, see agtread.h and
    agtdata.c */

#ifndef global
#define uagt_defined_global
#define global extern
#endif

/* --------------------------------------------------------------------	*/
/* The following are debugging and diagnostic flags. 		       	*/
/* They are mainly intended for debugging the interpreter, but 		*/
/*  they could concievable be used for debugging games under the 	*/
/* interpreter 								*/
/* --------------------------------------------------------------------	*/

global bool DEBUG_MEM; /* prints out information on memory allocation */

global bool debug_parse; /* Prints out long parse diagnostic information
		     after the sentence has been parse but before
		     disambiguation */
global bool DEBUG_EXEC_VERB; /* This prints out a line indicating each command
			 that exec_verb() is asked to run */
global bool DEBUG_DISAMBIG; /* Print out dismabiguation debugging info */


#define DEBUG_AGT_CMD flag[0]  /* This sends metacommand execution information
			to either the screen or debugfile, depending on 
			whether DEBUG_OUT is true or false. */

global bool debug_disambig, debug_any; 
	/* These determine if metacommands are traced during disambiguation 
	 or during the scanning of ANY commands */

global bool DEBUG_OUT; /* True if debugging output is redirected somewhere
			other than the screen */
global FILE *debugfile; /* Where debugging output should be sent */


#define def_debug_parse 0  /* parser.c */
#define def_DEBUG_AGT_CMD 0   /* exec.c */
#define def_DEBUG_EXEC_VERB 0  /* exec.c */ 
#define def_DEBUG_MEM 1    /* parser.c */

/* --------------------------------------------------------------------	*/
/* The following are AGT 'purity' flags; they turn off features of 	*/
/*   my interpreter that are not fully consistent with the original AGT.*/
/* More are defined in agtread.h, and you should look there for general */
/*  notes 								*/
/* --------------------------------------------------------------------	*/

/* The following are defined (and described) in agil.c */
extern bool PURE_INPUT, PURE_TONE;

#define PURE_WEAR 1  /* If this is cleared, then things taken off
			still stay in the player's inventory.
			The support for this isn't quite complete yet
			(there are one or two checks that need to be done
			but aren't) and so right now this should be 1. */

global bool PURE_DOT; /* Treats period as a letter-character and not
		      as punctuation. This should be set automatically
		      during initialization based on whether any words
		      in the dictionary have dots. */

#define FORCE_PURE_DOT 0  /* This forces the period to be treated as a letter
			     even if there are no words in the dictionary
			     containing periods. The only reason to set
			     this was if you were concerned that knowledge
			     about the presence or absence of periods in the 
			     dictionary would give puzzles away. */




#define MEM_MARGIN (16*1024) /* 16K should be enough (SOGGY, the largest AGT
				game, uses around 12K) */
#define PICT_SUPPORT 0  /* Graphics not supported */
#define TAB_SIZE 3     /* Number of spaces in a tab */




/* --------------------------------------------------------------------	*/
/*  Variables and Flags related to Metaverbs 				*/
/* --------------------------------------------------------------------	*/

global bool notify_flag, listexit_flag, menu_mode;

global bool cmd_saveable; /* set indicates that this command can be repeated
		     with AGAIN. */
global bool can_undo;  /* Can we UNDO the last turn? */

global uchar *restart_state, *undo_state; /* Store old game states for 
				     RESTART and UNDO */
global char doing_restore; /* Have we been asked to RESTORE? */

global bool do_look;  /* True if we should print a room description */
global bool do_autoverb; /* True if we should run the autoexec verb 
			  for the current room */

/* The following are used for scripting and logging */
global bool script_on;
global FILE *scriptfile;
global signed char logflag; /* 1=logging, 2=replaying, 0=neither, 3=both */
global int logdelay; /* -1=wait for keypress, >=0 is numerical delay */
global FILE *log_in, *log_out;

global bool sound_on; /* Manipulated by music_cmd; can be used by interface 
			 to determine if a tone should be made */

global integer *pictable; /* Used to decode picture numbers */
global char *hold_game_name; /* Needed to print instructions on demand */

global unsigned short compass_rose; /* Used to pass compass info to
					the os layer */


/* --------------------------------------------------------------------	*/
/*  Game State					 			*/  
/* --------------------------------------------------------------------	*/

global bool quitflag, deadflag, winflag, endflag;
global bool first_visit_flag, newlife_flag, room_firstdesc;

global bool start_of_turn; /* True if running the command on the first
			      noun in the list */

global bool actor_in_scope; /* Used to determine if the actor was in 
			       scope when the command was originally
			       given */

global integer loc;   /* Player's location */
global integer player_contents, player_worn; /* Worn and carried objects*/

global long totwt, totsize; /* Size and wt player is carrying around */

global integer curr_lives; /* Number of lives left. */

global long tscore, old_score; /* Total score */
global long objscore;  /* Portion of tscore that comes from the POINTS
			field of nouns and creatures. */

global integer turncnt;  /* Number of turns that have passed */
global integer curr_time;   /* The time in the game; in the format
			   1243==12:43 */

global bool FAR *flag; /* AGT Flags */
global short FAR *agt_counter; /* AGT counters */
#ifdef AGT_16BIT
global short FAR *agt_var; /*AGT variables */
#else 
global long FAR *agt_var;
#endif

global long agt_number; /* The number entered by the player */
global bool agt_answer; /* Did the player get the answer to the last question
		    right? */

global tline l_stat, r_stat;  /* Left and right parts of status line */
                /* If r_stat is the empty string, l_stat should be 
		   centered to create a Trinity-like status line */



/* --------------------------------------------------------------------	*/
/* Menu data structures 						*/ 
/* --------------------------------------------------------------------	*/

#define MENU_WIDTH 50
typedef char menuentry[MENU_WIDTH];

global int  vm_width; /* Width of widest element */
global menuentry *verbmenu;



/* --------------------------------------------------------------------	*/
/* Parser Data Structures 						*/
/*  This also includes "parser-related" variables like dobj and iobj    */
/* --------------------------------------------------------------------	*/

/* The following data structures are used for disambiguation of nouns */
typedef struct {
  long num;     /* Numeric value of object; 0 if object doesn't have one */
  int obj;     /* Object number; negative values point into the dictionary */
  int info;    /* Disambiguation info */
       /* -1=last record; ignore obj field. */
  word noun, adj;  /* Used for printing out error messages */
  short score;   /* Disambiguation score */
} parse_rec; /* Stores objects that have been found during parse */


global integer actor, vb, dobj, iobj;
global parse_rec *actor_rec, *dobj_rec, *iobj_rec;
global word prep;
global parse_rec *curr_creat_rec; 
                /* Creature currently behaving in a hostile way:
		   used to fill in $c_name$ messages */

global int disambig_score; /* Used to rank objects during disambiguation */

#define DISAMBIG_SUCC 1000   /* Score given to an object that triggers a
				built-in verb or an action token */


#define MAXINPUT 200   /* Max number of words input */

global word FAR input[MAXINPUT];  /* 200 words of input should be enough */
global words FAR in_text[MAXINPUT];
        /* The corrospoinding strings, for error reporting purposes */

global short ip,ep;  /* input pointer and error pointer */
global short ap,vp,np,pp,op; /* Points to first word in actor, verb, noun, 
			and object resp. */



/* The following needs to be kept consistant with ext_voc[] in
   agil.c */
typedef enum{wthe,wmy,wa,wan,wthen,wp,wsc,wand,wc,wits,wall,wundo,
	       wpick,wgo,wexits,wtalk,wtake,wdoor,wagain,wbut,wexcept,
	       wscene,weverything,wlistexit,wlistexits,wclose,
	       wdverb,wdnoun,wdadjective,wdprep,wdobject,wdname,
	       wstep,
	       whe,wshe,wit,wthey,whim,wher,wthem,wis,ware,woops,
	       win,wout,winto,wat,wto,wacross,winside,wwith,wnear,wfor,
	       wof,wbehind,wbeside,won,woff,wunder,wfrom, wthrough,
	       wtoward, wtowards, wbetween, waround, wupon, wthru,
	       wby, wover, wup, wdown,
	       wabout} wtype;
global word ext_code[wabout+1];  /* Codes for the above */
global short last_he, last_she, last_it, last_they;
     /* Used for pronoun support */



/* --------------------------------------------------------------------	*/
/* Noun List Data structures and constants				*/
/* --------------------------------------------------------------------	*/


/* The following are used in noun lists */
#define END_MARK 0
#define AND_MARK (-ext_code[wand])
#define ALL_MARK (-ext_code[wall])

#define D_END  50    /* Marks end of disambiguation list */
#define D_AND  51    /* Used to seperate multiple objects during disambig */
#define D_NOUN 0   /* Noun match */
#define D_SYN 1    /* Adjective/synonym only match */
#define D_ADJ 2    /* Adj only match */
#define D_FLAG 3   /* Flag noun */
#define D_GLOBAL 4 /* Global noun */
#define D_PIX 5     /* PIX name */
#define D_PRO 6      /* Pronoun */
#define D_ALL  7     /* ALL, or a header to an ALL EXCEPT _ AND _ ... list */
#define D_INTERN 8     /* Internal nouns: DOOR, SCENE */
#define D_NUM  9    /* A number, value is in obj */

#define D_MARK 0x80   /* Used as a temporary marker, usually to indicate
			 this noun is being considered for elimination */



/* --------------------------------------------------------------------	*/
/* These are used for text boxes (quotes and the title)                 */
/* --------------------------------------------------------------------	*/
#define TB_TTL 1   /* We're printing the title */
#define TB_BOLD 2   /* Print it bold */
#define TB_BORDER 4 /* Give it a border */
#define TB_CENTER 8  /* Center the text inside */
#define TB_NOCENT 16 /* Don't center the whole box */



/* --------------------------------------------------------------------	*/
/* In AGIL.C 								*/
/* --------------------------------------------------------------------	*/
void print_instructions(char *game_name);
void run_game(char *gamename);

/* --------------------------------------------------------------------	*/
/* In PARSER.C 								*/
/* --------------------------------------------------------------------	*/
bool parse(void);  /* Returns true unless there is ambiguity */
void menu_cmd(void);


/* --------------------------------------------------------------------	*/
/* In EXEC.C 								*/
/* --------------------------------------------------------------------	*/
void exec(parse_rec *actor,int vnum, parse_rec *lnoun,
	  word prep, parse_rec *iobj);
void set_statline(void);
void newroom(void); 
void print_descr(descr_ptr dp,bool nl);
void quote(int msgnum);
void print_score(void);
void sysmsg(int msgid,char *s);
long read_number(void);


/* --------------------------------------------------------------------	*/
/* In OBJECT.C 								*/
/* --------------------------------------------------------------------	*/
bool player_has(int item);
bool visible(int item);
int *get_nouns(void);  /* Returns list of in scope nouns */
void add_object(int loc, int item); /* Adds item to loc's contents list */
void tmpobj(parse_rec *objrec); 
void compute_scope(void); /* Sets scope flags for all of the objects */

/* --------------------------------------------------------------------	*/
/* In RUNVERB.C 							*/
/* --------------------------------------------------------------------	*/
int check_obj(parse_rec *act, int verbid, 
	       parse_rec *donum, word prep, parse_rec *ionum);


/* --------------------------------------------------------------------	*/
/* In AGTDBG.C 								*/
/* --------------------------------------------------------------------	*/
void debug_cmd_out(int,int,int,int,int);
void debug_head(int);


/* --------------------------------------------------------------------	*/
/* In SAVEGAME.C 							*/
/* --------------------------------------------------------------------	*/
void savegame(void);
bool loadgame(void);
void init_state_sys(void);  /* Must be called before either of the following */
uchar *getstate(uchar *gs); 
    /* Returns malloc'd block containing game state. */
void putstate(uchar *gs); /* Restores games state. */
void init_vals(void);  /* Compute dependent variables
			  such as totwt, totsize, etc. */
void restart_game(void);


/* --------------------------------------------------------------------	*/
/* In OS_<whatever>.C 							*/
/* --------------------------------------------------------------------	*/
global volatile int screen_width, status_width;
global int screen_height;
global volatile int curr_x;  

void init_interface(char *gamename,int argc,char *argv[]);
void start_interface(void);
void close_interface(void);
char *agt_input(int in_type); /* read line, return malloc'd string */ 
char agt_getkey(bool echo_char); 
void agt_clrscr(void);
void agt_textcolor(int c);
void agt_delay(int n); /* n in seconds */
int agt_rand(int a,int b); /* Return random number from a to b, inclusive */
void agt_newline(void); 
void agt_puts(const char *s); /* Output string */
void agt_statline(const char *s); /* Prints s out on status line */
void agt_tone(int hz,int ms);  
void agt_makebox(int width,int height,unsigned long flags);
void agt_qnewline(void);
void agt_endbox(void);
FILE *agt_globalfile(int fid); /* When fid=0, return global config file */
bool agt_option(int optnum,char *optstr[],bool setflag);

/* These have stubs defined in interface.c that would ened to be
	commented out if you actually wanted to support these */
void fontcmd(int cmd,int font); /* fontlist[font] */
void pictcmd(int cmd,int pict); /* pictlist[pict] or pixlist[pict] */
int musiccmd(int cmd,int song); /* songlist[song] */


/* --------------------------------------------------------------------	*/
/* In INTERFACE.C 							*/
/* --------------------------------------------------------------------	*/
/* init_interface() (in os_?????.c) is responsible for initializing these */
global bool par_fill_on, center_on;
global bool textbold;  /* Is the text currently bold? */

void wait_return(void);
void agt_center(bool b); /* 1=turn on text centering, 0=turn off */
void agt_par(bool b); /* 1=turn on "paragraph" mode, 0=turn off */
char *agt_readline(int in_type); /* Front end for agt_input */
char agt_getchar(void); /* Front end for some uses of agt_getkey */
void prompt_out(int);  /* 1=standard prompt, 2=question prompt */
FILE *get_user_file(int ft); /* 0=script, 1=save, 2=restore */
void script(uchar); /* 0=turn off, 1=turn on */
void logon(void);  /* Turn on logging */
void replay(int delay); /* REPLAY */
bool yesno(const char*);
void textbox(char *(txt[]),int len,unsigned long flags);
void padout(int padleng); /* Outputs padleng spaces */
int agt_menu(char *header,int size,int width,menuentry *menu);
char *new_game(void); 

/* These are intended to be called by the os layer */
void print_statline(void); 

void agt_save(void);
void agt_restore(void);
void agt_restart(void);
void agt_quit(void);
void agt_newgame(char *gamename);

/* --------------------------------------------------------------------	*/
/* Object manipulation macros 						*/
/* --------------------------------------------------------------------	*/
#define objloop(i) for(i=first_noun; i<=maxnoun || i<=maxcreat; \
	       (i<=maxnoun || i>=first_creat) ? (i++) : (i=first_creat) ) 
#define nounloop(i) for(i=0;i<=maxnoun-first_noun;i++)
#define creatloop(i) for(i=0;i<=maxcreat-first_creat;i++)

#define troom(x) ((x)>=first_room && (x)<=maxroom) 
#define tnoun(x) ((x)>=first_noun && (x)<=maxnoun)
#define tcreat(x) ((x)>=first_creat && (x)<=maxcreat)
#define tdoor(x)  ((x)==-ext_code[wdoor])

#ifdef uagt_defined_global
#undef global
#undef uagt_define_global
#endif



