~ubuntu-branches/ubuntu/wily/gargoyle-free/wily-proposed

« back to all changes in this revision

Viewing changes to terps/advsys/advdbs.c

  • Committer: Bazaar Package Importer
  • Author(s): Sylvain Beucler
  • Date: 2009-09-11 20:09:43 UTC
  • Revision ID: james.westby@ubuntu.com-20090911200943-idgzoyupq6650zpn
Tags: upstream-2009-08-25
ImportĀ upstreamĀ versionĀ 2009-08-25

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* advdbs.c - adventure database access routines */
 
2
/*
 
3
        Copyright (c) 1986, by David Michael Betz
 
4
        All rights reserved
 
5
*/
 
6
 
 
7
#include "header.h"
 
8
#include "advint.h"
 
9
#include "advdbs.h"
 
10
#include <setjmp.h>
 
11
 
 
12
#define RMODE   0x8001
 
13
 
 
14
/* global variables */
 
15
int h_init;     /* initialization code */
 
16
int h_update;   /* update code */
 
17
int h_before;   /* before handler code */
 
18
int h_after;    /* after handler code */
 
19
int h_error;    /* error handling code */
 
20
strid_t datafd; /* data file descriptor */
 
21
 
 
22
/* external variables */
 
23
extern jmp_buf restart;
 
24
 
 
25
/* table base addresses */
 
26
char *wtable;   /* word table */
 
27
char *wtypes;   /* word type table */
 
28
int wcount;     /* number of words */
 
29
char *otable;   /* object table */
 
30
int ocount;     /* number of objects */
 
31
char *atable;   /* action table */
 
32
int acount;     /* number of actions */
 
33
char *vtable;   /* variable table */
 
34
int vcount;     /* number of variables */
 
35
char *data;     /* base of data tables */
 
36
char *base;     /* current base address */
 
37
char *dbase;    /* base of the data space */
 
38
char *cbase;    /* base of the code space */
 
39
glui32 length;  /* length of resident data structures */
 
40
 
 
41
/* data file header */
 
42
static char hdr[HDR_SIZE];
 
43
 
 
44
/* save parameters */
 
45
static long saveoff;    /* save data file offset */
 
46
static char *save;      /* save area base address */
 
47
static glui32 slen;     /* save area length */
 
48
 
 
49
/* db_init - read and decode the data file header */
 
50
void db_init(strid_t realfd)
 
51
{
 
52
    int woff,ooff,aoff,voff,n;
 
53
 
 
54
    /* open the data file */
 
55
        datafd = realfd; // glk_stream_open_file(name, filemode_Read, 0);
 
56
    
 
57
        // if (datafd == NULL)
 
58
        //      error("can't open data file");
 
59
 
 
60
        /* read the header */
 
61
    if (glk_get_buffer_stream(datafd,hdr,HDR_SIZE) != HDR_SIZE)
 
62
                error("bad data file");
 
63
    
 
64
        complement(hdr,HDR_SIZE);
 
65
    base = hdr;
 
66
 
 
67
    /* check the magic information */
 
68
    if (strncmp(&hdr[HDR_MAGIC],"ADVSYS",6) != 0)
 
69
        error("not an adventure data file");
 
70
 
 
71
    /* check the version number */
 
72
    if ((n = getword(HDR_VERSION)) < 101 || n > VERSION)
 
73
        error("wrong version number");
 
74
 
 
75
    /* decode the resident data length header field */
 
76
    length = getword(HDR_LENGTH);
 
77
 
 
78
    /* allocate space for the resident data structure */
 
79
    if ((data = malloc(length)) == 0)
 
80
                error("insufficient memory");
 
81
 
 
82
    /* compute the offset to the data */
 
83
    saveoff = (long)getword(HDR_DATBLK) * 512L; 
 
84
 
 
85
    /* read the resident data structure */
 
86
    glk_stream_set_position(datafd,saveoff,seekmode_Start);
 
87
    if (glk_get_buffer_stream(datafd,data,length) != length)
 
88
                error("bad data file");
 
89
    complement(data,length);
 
90
 
 
91
    /* get the table base addresses */
 
92
    wtable = data + (woff = getword(HDR_WTABLE));
 
93
    wtypes = data + getword(HDR_WTYPES) - 1;
 
94
    otable = data + (ooff = getword(HDR_OTABLE));
 
95
    atable = data + (aoff = getword(HDR_ATABLE));
 
96
    vtable = data + (voff = getword(HDR_VTABLE));
 
97
 
 
98
    /* get the save data area */
 
99
    saveoff += (long)getword(HDR_SAVE);
 
100
    save = data + getword(HDR_SAVE);
 
101
    slen = getword(HDR_SLEN);
 
102
 
 
103
    /* get the base of the data and code spaces */
 
104
    dbase = data + getword(HDR_DBASE);
 
105
    cbase = data + getword(HDR_CBASE);
 
106
 
 
107
    /* initialize the message routines */
 
108
    msg_init(datafd,getword(HDR_MSGBLK));
 
109
 
 
110
    /* get the code pointers */
 
111
    h_init = getword(HDR_INIT);
 
112
    h_update = getword(HDR_UPDATE);
 
113
    h_before = getword(HDR_BEFORE);
 
114
    h_after = getword(HDR_AFTER);
 
115
    h_error = getword(HDR_ERROR);
 
116
 
 
117
    /* get the table lengths */
 
118
    base = data;
 
119
    wcount = getword(woff); 
 
120
    ocount = getword(ooff);
 
121
    acount = getword(aoff);
 
122
    vcount = getword(voff);
 
123
 
 
124
    /* setup the base of the resident data */
 
125
    base = dbase;
 
126
 
 
127
    /* set the object count */
 
128
    setvalue(V_OCOUNT,ocount);
 
129
 
 
130
        /* CHANGED FOR GLK */
 
131
 
 
132
#ifdef GARGLK
 
133
        garglk_set_story_name(&hdr[HDR_ANAME]);
 
134
#endif
 
135
 
 
136
#ifdef WINDOWS
 
137
        {
 
138
                int i;
 
139
                char *buf;
 
140
 
 
141
                i = strlen(&hdr[HDR_ANAME]);
 
142
                i += 1;
 
143
                i += strlen("GLK AdvSys - ");
 
144
 
 
145
                buf = malloc( sizeof(char) * i );
 
146
                wsprintf(buf, "GLK AdvSys - %s", &hdr[HDR_ANAME]);
 
147
                winglk_window_set_title(buf);
 
148
        }
 
149
#endif
 
150
}
 
151
 
 
152
/* db_save - save the current database */
 
153
int db_save()
 
154
{
 
155
    return (advsave(&hdr[HDR_ANAME],20,save,slen) ? T : NIL);
 
156
}
 
157
 
 
158
/* db_restore - restore a saved database */
 
159
int db_restore()
 
160
{
 
161
    return (advrestore(&hdr[HDR_ANAME],20,save,slen) ? T : NIL);
 
162
}
 
163
 
 
164
/* db_restart - restart the current game */
 
165
int db_restart()
 
166
{
 
167
    glk_stream_set_position(datafd,saveoff,seekmode_Start);
 
168
    if (glk_get_buffer_stream(datafd,save,slen) != slen)
 
169
                return (NIL);
 
170
    complement(save,slen);
 
171
    setvalue(V_OCOUNT,ocount);
 
172
    
 
173
        longjmp(restart,1);
 
174
}
 
175
 
 
176
/* complement - complement a block of memory */
 
177
void complement(char *adr,int len)
 
178
{
 
179
    for (; len--; adr++)
 
180
        *adr = ~(*adr + 30);
 
181
}
 
182
 
 
183
/* findword - find a word in the dictionary */
 
184
int findword(char *word)
 
185
{
 
186
    char sword[WRDSIZE+1];
 
187
    int wrd,i;
 
188
 
 
189
    /* shorten the word */
 
190
    strncpy(sword,word,WRDSIZE); sword[WRDSIZE] = 0;
 
191
 
 
192
    /* look up the word */
 
193
    for (i = 1; i <= wcount; i++) {
 
194
        wrd = getwloc(i);
 
195
        if (strcmp(base+wrd+2,sword) == 0)
 
196
            return (getword(wrd));
 
197
    }
 
198
    return (NIL);
 
199
}
 
200
 
 
201
/* wtype - return the type of a word */
 
202
int wtype(int wrd)
 
203
{
 
204
    return (wtypes[wrd]);
 
205
}
 
206
 
 
207
/* match - match an object against a name and list of adjectives */
 
208
int match(int obj,int noun,int *adjs)
 
209
{
 
210
    int *aptr;
 
211
 
 
212
    if (!hasnoun(obj,noun))
 
213
        return (FALSE);
 
214
    for (aptr = adjs; *aptr != NIL; aptr++)
 
215
        if (!hasadjective(obj,*aptr))
 
216
            return (FALSE);
 
217
    return (TRUE);
 
218
}
 
219
 
 
220
/* checkverb - check to see if this is a valid verb */
 
221
int checkverb(int *verbs)
 
222
{
 
223
    int act;
 
224
 
 
225
    /* look up the action */
 
226
    for (act = 1; act <= acount; act++)
 
227
        if (hasverb(act,verbs))
 
228
            return (act);
 
229
    return (NIL);
 
230
}
 
231
 
 
232
/* findaction - find an action matching a description */
 
233
int findaction(int *verbs,int preposition,int flag)
 
234
{
 
235
    int act,mask;
 
236
 
 
237
    /* look up the action */
 
238
    for (act = 1; act <= acount; act++) {
 
239
        if (preposition && !haspreposition(act,preposition))
 
240
            continue;
 
241
        if (!hasverb(act,verbs))
 
242
            continue;
 
243
        mask = ~getabyte(act,A_MASK);
 
244
        if ((flag & mask) == (getabyte(act,A_FLAG) & mask))
 
245
            return (act);
 
246
    }
 
247
    return (NIL);
 
248
}
 
249
 
 
250
/* getp - get the value of an object property */
 
251
int getp(int obj,int prop)
 
252
{
 
253
    int p;
 
254
 
 
255
    for (; obj; obj = getofield(obj,O_CLASS))
 
256
        if (p = findprop(obj,prop))
 
257
            return (getofield(obj,p));
 
258
    return (NIL);
 
259
}
 
260
 
 
261
/* setp - set the value of an object property */
 
262
int setp(int obj,int prop,int val)
 
263
{
 
264
    int p;
 
265
 
 
266
    for (; obj; obj = getofield(obj,O_CLASS))
 
267
        if (p = findprop(obj,prop))
 
268
            return (putofield(obj,p,val));
 
269
    return (NIL);
 
270
}
 
271
 
 
272
/* findprop - find a property */
 
273
int findprop(int obj,int prop)
 
274
{
 
275
    int n,i,p;
 
276
 
 
277
    n = getofield(obj,O_NPROPERTIES);
 
278
    for (i = p = 0; i < n; i++, p += 4)
 
279
        if ((getofield(obj,O_PROPERTIES+p) & ~P_CLASS) == prop)
 
280
            return (O_PROPERTIES+p+2);
 
281
    return (NIL);
 
282
}
 
283
 
 
284
/* hasnoun - check to see if an object has a specified noun */
 
285
int hasnoun(int obj,int noun)
 
286
{
 
287
    while (obj) {
 
288
        if (inlist(getofield(obj,O_NOUNS),noun))
 
289
            return (TRUE);
 
290
        obj = getofield(obj,O_CLASS);
 
291
    }
 
292
    return (FALSE);
 
293
}
 
294
 
 
295
/* hasadjective - check to see if an object has a specified adjective */
 
296
int hasadjective(int obj,int adjective)
 
297
{
 
298
    while (obj) {
 
299
        if (inlist(getofield(obj,O_ADJECTIVES),adjective))
 
300
            return (TRUE);
 
301
        obj = getofield(obj,O_CLASS);
 
302
    }
 
303
    return (FALSE);
 
304
}
 
305
 
 
306
/* hasverb - check to see if this action has this verb */
 
307
int hasverb(int act,int *verbs)
 
308
{
 
309
    int link,word,*verb;
 
310
 
 
311
    /* get the list of verbs */
 
312
    link = getafield(act,A_VERBS);
 
313
 
 
314
    /* look for this verb */
 
315
    while (link != NIL) {
 
316
        verb = verbs;
 
317
        word = getword(link+L_DATA);
 
318
        while (*verb != NIL && word != NIL) {
 
319
            if (*verb != getword(word+L_DATA))
 
320
                break;
 
321
            verb++;
 
322
            word = getword(word+L_NEXT);
 
323
        }
 
324
        if (*verb == NIL && word == NIL)
 
325
            return (TRUE);
 
326
        link = getword(link+L_NEXT);
 
327
    }
 
328
    return (FALSE);
 
329
}
 
330
 
 
331
/* haspreposition - check to see if an action has a specified preposition */
 
332
int haspreposition(int act, int preposition)
 
333
{
 
334
    return (inlist(getafield(act,A_PREPOSITIONS),preposition));
 
335
}
 
336
 
 
337
/* inlist - check to see if a word is an element of a list */
 
338
int inlist(int link, int word)
 
339
{
 
340
    while (link != NIL) {
 
341
        if (word == getword(link+L_DATA))
 
342
            return (TRUE);
 
343
        link = getword(link+L_NEXT);
 
344
    }
 
345
    return (FALSE);
 
346
}
 
347
 
 
348
/* getofield - get a field from an object */
 
349
int getofield(int obj, int off)
 
350
{
 
351
    return (getword(getoloc(obj)+off));
 
352
}
 
353
 
 
354
/* putofield - put a field into an object */
 
355
int putofield(int obj,int off,int val)
 
356
{
 
357
    return (putword(getoloc(obj)+off,val));
 
358
}
 
359
 
 
360
/* getafield - get a field from an action */
 
361
int getafield(int act,int off)
 
362
{
 
363
    return (getword(getaloc(act)+off));
 
364
}
 
365
 
 
366
/* getabyte - get a byte field from an action */
 
367
int getabyte(int act,int off)
 
368
{
 
369
    return (getbyte(getaloc(act)+off));
 
370
}
 
371
 
 
372
/* getoloc - get an object from the object table */
 
373
int getoloc(int n)
 
374
{
 
375
    if (n < 1 || n > ocount)
 
376
        nerror("object number out of range: %d",n);
 
377
    return (getdword(otable+n+n));
 
378
}
 
379
 
 
380
/* getaloc - get an action from the action table */
 
381
int getaloc(int n)
 
382
{
 
383
    if (n < 1 || n > acount)
 
384
        nerror("action number out of range: %d",n);
 
385
    return (getdword(atable+n+n));
 
386
}
 
387
 
 
388
/* getvalue - get the value of a variable from the variable table */
 
389
int getvalue(int n)
 
390
{
 
391
    if (n < 1 || n > vcount)
 
392
        nerror("variable number out of range: %d",n);
 
393
    return (getdword(vtable+n+n));
 
394
}
 
395
 
 
396
/* setvalue - set the value of a variable in the variable table */
 
397
int setvalue(n,v)
 
398
  int n,v;
 
399
{
 
400
    if (n < 1 || n > vcount)
 
401
        nerror("variable number out of range: %d",n);
 
402
    return (putdword(vtable+n+n,v));
 
403
}
 
404
 
 
405
/* getwloc - get a word from the word table */
 
406
int getwloc(int n)
 
407
{
 
408
    if (n < 1 || n > wcount)
 
409
        nerror("word number out of range: %d",n);
 
410
    return (getdword(wtable+n+n));
 
411
}
 
412
 
 
413
/* getword - get a word from the data array */
 
414
int getword(int n)
 
415
{
 
416
    return (getdword(base+n));
 
417
}
 
418
 
 
419
/* putword - put a word into the data array */
 
420
int putword(int n,int w)
 
421
{
 
422
    return (putdword(base+n,w));
 
423
}
 
424
 
 
425
/* getbyte - get a byte from the data array */
 
426
int getbyte(int n)
 
427
{
 
428
    return (*(base+n) & 0xFF);
 
429
}
 
430
 
 
431
/* getcbyte - get a code byte */
 
432
int getcbyte(int n)
 
433
{
 
434
    return (*(cbase+n) & 0xFF);
 
435
}
 
436
 
 
437
/* getcword - get a code word */
 
438
int getcword(int n)
 
439
{
 
440
    return (getdword(cbase+n));
 
441
}
 
442
 
 
443
/* getdword - get a word from the data array */
 
444
int getdword(char *p)
 
445
{
 
446
    return (((*p & 0xFF) | (*(p+1) << 8))&0xFFFF);
 
447
}
 
448
 
 
449
/* putdword - put a word into the data array */
 
450
int putdword(char *p,int w)
 
451
{
 
452
    *p = w; *(p+1) = w >> 8;
 
453
    return (w);
 
454
}
 
455
 
 
456
/* nerror - handle errors with numeric arguments */
 
457
void nerror(char *fmt,int n)
 
458
{
 
459
    char buf[100];
 
460
    sprintf(buf,fmt,n);
 
461
    error(buf);
 
462
}