home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource4
/
251_01
/
advdbs.c
< prev
next >
Wrap
Text File
|
1987-10-29
|
11KB
|
485 lines
/* advdbs.c - adventure database access routines */
/*
Copyright (c) 1986, by David Michael Betz
All rights reserved
*/
#include "advint.h"
#include "advdbs.h"
#ifdef MAC
#include <fnctl.h>
#define RMODE (O_RDONLY|O_BINARY)
#else
#include <setjmp.h>
#define RMODE 0
#endif
/* global variables */
int h_init; /* initialization code */
int h_update; /* update code */
int h_before; /* before handler code */
int h_after; /* after handler code */
int h_error; /* error handling code */
int datafd; /* data file descriptor */
/* external variables */
extern jmp_buf restart;
/* external routines */
extern char *malloc();
/* table base addresses */
char *wtable; /* word table */
char *wtypes; /* word type table */
int wcount; /* number of words */
char *otable; /* object table */
int ocount; /* number of objects */
char *atable; /* action table */
int acount; /* number of actions */
char *vtable; /* variable table */
int vcount; /* number of variables */
char *data; /* base of data tables */
char *base; /* current base address */
char *dbase; /* base of the data space */
char *cbase; /* base of the code space */
int length; /* length of resident data structures */
/* data file header */
static char hdr[HDR_SIZE];
/* save parameters */
static long saveoff; /* save data file offset */
static char *save; /* save area base address */
static int slen; /* save area length */
/* db_init - read and decode the data file header */
db_init(name)
char *name;
{
int woff,ooff,aoff,voff,n;
char fname[50];
/* get the data file name */
strcpy(fname,name);
#ifndef MAC
strcat(fname,".dat");
#endif
/* open the data file */
if ((datafd = open(fname,RMODE)) == -1)
error("can't open data file");
/* read the header */
if (read(datafd,hdr,HDR_SIZE) != HDR_SIZE)
error("bad data file");
complement(hdr,HDR_SIZE);
base = hdr;
/* check the magic information */
if (strncmp(&hdr[HDR_MAGIC],"ADVSYS",6) != 0)
error("not an adventure data file");
/* check the version number */
if ((n = getword(HDR_VERSION)) < 101 || n > VERSION)
error("wrong version number");
/* decode the resident data length header field */
length = getword(HDR_LENGTH);
/* allocate space for the resident data structure */
if ((data = malloc(length)) == 0)
error("insufficient memory");
/* compute the offset to the data */
saveoff = (long)getword(HDR_DATBLK) * 512L;
/* read the resident data structure */
lseek(datafd,saveoff,0);
if (read(datafd,data,length) != length)
error("bad data file");
complement(data,length);
/* get the table base addresses */
wtable = data + (woff = getword(HDR_WTABLE));
wtypes = data + getword(HDR_WTYPES) - 1;
otable = data + (ooff = getword(HDR_OTABLE));
atable = data + (aoff = getword(HDR_ATABLE));
vtable = data + (voff = getword(HDR_VTABLE));
/* get the save data area */
saveoff += (long)getword(HDR_SAVE);
save = data + getword(HDR_SAVE);
slen = getword(HDR_SLEN);
/* get the base of the data and code spaces */
dbase = data + getword(HDR_DBASE);
cbase = data + getword(HDR_CBASE);
/* initialize the message routines */
msg_init(datafd,getword(HDR_MSGBLK));
/* get the code pointers */
h_init = getword(HDR_INIT);
h_update = getword(HDR_UPDATE);
h_before = getword(HDR_BEFORE);
h_after = getword(HDR_AFTER);
h_error = getword(HDR_ERROR);
/* get the table lengths */
base = data;
wcount = getword(woff);
ocount = getword(ooff);
acount = getword(aoff);
vcount = getword(voff);
/* setup the base of the resident data */
base = dbase;
/* set the object count */
setvalue(V_OCOUNT,ocount);
}
/* db_save - save the current database */
db_save(name)
char *name;
{
return (advsave(&hdr[HDR_ANAME],20,save,slen) ? T : NIL);
}
/* db_restore - restore a saved database */
int db_restore(name)
char *name;
{
return (advrestore(&hdr[HDR_ANAME],20,save,slen) ? T : NIL);
}
/* db_restart - restart the current game */
db_restart()
{
lseek(datafd,saveoff,0);
if (read(datafd,save,slen) != slen)
return (NIL);
complement(save,slen);
setvalue(V_OCOUNT,ocount);
longjmp(restart,1);
}
/* complement - complement a block of memory */
complement(adr,len)
char *adr; int len;
{
for (; len--; adr++)
*adr = ~(*adr + 30);
}
/* findword - find a word in the dictionary */
int findword(word)
char *word;
{
char sword[WRDSIZE+1];
int wrd,i;
/* shorten the word */
strncpy(sword,word,WRDSIZE); sword[WRDSIZE] = 0;
/* look up the word */
for (i = 1; i <= wcount; i++) {
wrd = getwloc(i);
if (strcmp(base+wrd+2,sword) == 0)
return (getword(wrd));
}
return (NIL);
}
/* wtype - return the type of a word */
int wtype(wrd)
int wrd;
{
return (wtypes[wrd]);
}
/* match - match an object against a name and list of adjectives */
int match(obj,noun,adjs)
int obj,noun,*adjs;
{
int *aptr;
if (!hasnoun(obj,noun))
return (FALSE);
for (aptr = adjs; *aptr != NIL; aptr++)
if (!hasadjective(obj,*aptr))
return (FALSE);
return (TRUE);
}
/* checkverb - check to see if this is a valid verb */
int checkverb(verbs)
int *verbs;
{
int act;
/* look up the action */
for (act = 1; act <= acount; act++)
if (hasverb(act,verbs))
return (act);
return (NIL);
}
/* findaction - find an action matching a description */
findaction(verbs,preposition,flag)
int *verbs,preposition,flag;
{
int act,mask;
/* look up the action */
for (act = 1; act <= acount; act++) {
if (preposition && !haspreposition(act,preposition))
continue;
if (!hasverb(act,verbs))
continue;
mask = ~getabyte(act,A_MASK);
if ((flag & mask) == (getabyte(act,A_FLAG) & mask))
return (act);
}
return (NIL);
}
/* getp - get the value of an object property */
int getp(obj,prop)
int obj,prop;
{
int p;
for (; obj; obj = getofield(obj,O_CLASS))
if (p = findprop(obj,prop))
return (getofield(obj,p));
return (NIL);
}
/* setp - set the value of an object property */
int setp(obj,prop,val)
int obj,prop,val;
{
int p;
for (; obj; obj = getofield(obj,O_CLASS))
if (p = findprop(obj,prop))
return (putofield(obj,p,val));
return (NIL);
}
/* findprop - find a property */
int findprop(obj,prop)
int obj,prop;
{
int n,i,p;
n = getofield(obj,O_NPROPERTIES);
for (i = p = 0; i < n; i++, p += 4)
if ((getofield(obj,O_PROPERTIES+p) & ~P_CLASS) == prop)
return (O_PROPERTIES+p+2);
return (NIL);
}
/* hasnoun - check to see if an object has a specified noun */
int hasnoun(obj,noun)
int obj,noun;
{
while (obj) {
if (inlist(getofield(obj,O_NOUNS),noun))
return (TRUE);
obj = getofield(obj,O_CLASS);
}
return (FALSE);
}
/* hasadjective - check to see if an object has a specified adjective */
int hasadjective(obj,adjective)
int obj,adjective;
{
while (obj) {
if (inlist(getofield(obj,O_ADJECTIVES),adjective))
return (TRUE);
obj = getofield(obj,O_CLASS);
}
return (FALSE);
}
/* hasverb - check to see if this action has this verb */
int hasverb(act,verbs)
int act,*verbs;
{
int link,word,*verb;
/* get the list of verbs */
link = getafield(act,A_VERBS);
/* look for this verb */
while (link != NIL) {
verb = verbs;
word = getword(link+L_DATA);
while (*verb != NIL && word != NIL) {
if (*verb != getword(word+L_DATA))
break;
verb++;
word = getword(word+L_NEXT);
}
if (*verb == NIL && word == NIL)
return (TRUE);
link = getword(link+L_NEXT);
}
return (FALSE);
}
/* haspreposition - check to see if an action has a specified preposition */
int haspreposition(act,preposition)
int act,preposition;
{
return (inlist(getafield(act,A_P