home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource4 / 251_01 / advmsg.c < prev    next >
Text File  |  1987-10-29  |  3KB  |  117 lines

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