DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T a

⟦0607978d0⟧ TextFile

    Length: 10575 (0x294f)
    Types: TextFile
    Names: »advdbs.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/General/Advsys/advdbs.c« 

TextFile

/* 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_PREPOSITIONS),preposition));
}

/* inlist - check to see if a word is an element of a list */
int inlist(link,word)
  int link,word;
{
    while (link != NIL) {
	if (word == getword(link+L_DATA))
	    return (TRUE);
	link = getword(link+L_NEXT);
    }
    return (FALSE);
}

/* getofield - get a field from an object */
int getofield(obj,off)
  int obj,off;
{
    return (getword(getoloc(obj)+off));
}

/* putofield - put a field into an object */
int putofield(obj,off,val)
  int obj,off,val;
{
    return (putword(getoloc(obj)+off,val));
}

/* getafield - get a field from an action */
int getafield(act,off)
  int act,off;
{
    return (getword(getaloc(act)+off));
}

/* getabyte - get a byte field from an action */
int getabyte(act,off)
  int act,off;
{
    return (getbyte(getaloc(act)+off));
}

/* getoloc - get an object from the object table */
int getoloc(n)
  int n;
{
    if (n < 1 || n > ocount)
	nerror("object number out of range: %d",n);
    return (getdword(otable+n+n));
}

/* getaloc - get an action from the action table */
int getaloc(n)
  int n;
{
    if (n < 1 || n > acount)
	nerror("action number out of range: %d",n);
    return (getdword(atable+n+n));
}

/* getvalue - get the value of a variable from the variable table */
int getvalue(n)
  int n;
{
    if (n < 1 || n > vcount)
	nerror("variable number out of range: %d",n);
    return (getdword(vtable+n+n));
}

/* setvalue - set the value of a variable in the variable table */
int setvalue(n,v)
  int n,v;
{
    if (n < 1 || n > vcount)
	nerror("variable number out of range: %d",n);
    return (putdword(vtable+n+n,v));
}

/* getwloc - get a word from the word table */
int getwloc(n)
  int n;
{
    if (n < 1 || n > wcount)
	nerror("word number out of range: %d",n);
    return (getdword(wtable+n+n));
}

/* getword - get a word from the data array */
int getword(n)
  int n;
{
    return (getdword(base+n));
}

/* putword - put a word into the data array */
int putword(n,w)
  int n,w;
{
    return (putdword(base+n,w));
}

/* getbyte - get a byte from the data array */
int getbyte(n)
  int n;
{
    return (*(base+n) & 0xFF);
}

/* getcbyte - get a code byte */
int getcbyte(n)
  int n;
{
    return (*(cbase+n) & 0xFF);
}

/* getcword - get a code word */
int getcword(n)
  int n;
{
    return (getdword(cbase+n));
}

/* getdword - get a word from the data array */
int getdword(p)
  char *p;
{
    return (((*p & 0xFF) | (*(p+1) << 8))&0xFFFF);
}

/* putdword - put a word into the data array */
int putdword(p,w)
  char *p; int w;
{
    *p = w; *(p+1) = w >> 8;
    return (w);
}

/* nerror - handle errors with numeric arguments */
nerror(fmt,n)
  char *fmt; int n;
{
    char buf[100];
    sprintf(buf,fmt,n);
    error(buf);
}