-
Notifications
You must be signed in to change notification settings - Fork 5
/
advmsg.c
110 lines (92 loc) · 2.48 KB
/
advmsg.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/* advmsg.c - adventure interpreter message routines */
/*
Copyright (c) 1993, by David Michael Betz
All rights reserved
*/
#include <stdio.h>
#include <stdlib.h>
#include "advint.h"
/* cache size */
#define CSIZE 8
/* message block cache */
static char *mbuffer[CSIZE]; /* message text block cache buffers */
static int mblock[CSIZE]; /* message text block cache block numbers */
static int mnext[CSIZE]; /* next most recently used block */
static int mhead,mtail; /* head and tail of lru list */
/* message file variables */
static int mbase; /* message base block */
static FILE *mfp; /* message file pointer */
/* current message variables */
static int mblk; /* current block */
static char *mbuf; /* current buffer */
static int moff; /* current buffer offset */
/* msg_init - initialize the message routines */
void msg_init(FILE *fp,int base)
{
char *p;
int i;
/* remember the message file descriptor and base */
mbase = base;
mfp = fp;
/* initialize the cache */
if ((p = malloc(CSIZE * 512)) == NULL)
error("insufficient memory");
for (i = 0; i < CSIZE; i++) {
mbuffer[i] = p; p += 512;
mblock[i] = -1;
mnext[i] = i+1;
}
mhead = 0; mtail = CSIZE-1; mnext[mtail] = -1;
}
/* msg_open - open a message */
void msg_open(unsigned int msg)
{
/* save the current message block */
mblk = msg >> 7;
/* make sure the first block is in a buffer */
get_block(mblk);
/* setup the initial offset into the block */
moff = (msg & 0x7F) << 2;
}
/* msg_byte - get a byte from a message */
int msg_byte(void)
{
/* check for end of block and get next block */
if (moff >= 512) {
get_block(++mblk);
moff = 0;
}
/* return the next message byte */
return (decode(mbuf[moff++]));
}
/* decode - decode a character */
int decode(int ch)
{
return ((ch + 30) & 0xFF);
}
/* get_block - get a block of message text */
void get_block(unsigned int blk)
{
int last=0,n;
long loff;
/* first check the cache */
for (n = mhead; n != -1; last = n, n = mnext[n])
if (blk == mblock[n]) {
if (n != mhead) {
if ((mnext[last] = mnext[n]) == -1)
mtail = last;
mnext[n] = mhead;
mhead = n;
}
mbuf = mbuffer[n];
return;
}
/* overwrite the least recently used buffer */
mblock[mtail] = blk;
loff = ((long) mbase + (long) blk) << 9;
fseek(mfp,loff,SEEK_SET);
if (fread(mbuffer[mtail],1,512,mfp) != 512)
error("error reading message text");
/* get the block */
get_block(blk);
}