home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / sega / pvquant / quant / virt_mem.c < prev   
Encoding:
C/C++ Source or Header  |  1991-10-22  |  6.7 KB  |  232 lines

  1. /************************************************************************
  2.  *                                                                      *
  3.  *                  Copyright (c) 1991, Frank van der Hulst             *
  4.  *                          All Rights Reserved                         *
  5.  *                                                                      *
  6.  * Authors:                                                             *
  7.  *          FvdH - Frank van der Hulst (Wellington, NZ)                     *
  8.  *                                                                      *
  9.  * Versions:                                                            *
  10.  *      V1.1 910626 FvdH - QUANT released for DBW_RENDER                *
  11.  *      V1.2 911021 FvdH - QUANT released for PoV Ray                   *
  12.  *                                                                      *
  13.  ************************************************************************/
  14. /* virt_mem.c
  15.     "Virtual memory" for QUANT. On a PC, these routines open a disk file
  16.     for use as a virtual memory buffer for BOX structure items. The most
  17.     commonly used boxes are cached in memory. As much memory as is available
  18.     is utilised for this cache. In SCO Unix sufficient memory is simply
  19.     malloc'ed. The buffer can be up to 800K long, depending on how    many
  20.     colours are to be produced. */
  21.  
  22. #ifdef __TURBOC__
  23. #include <mem.h>
  24. #endif
  25.  
  26. #include "quant.h"
  27. #include "heckbert.h"
  28.  
  29. #ifdef __TURBOC__
  30. typedef struct {
  31.     int    num;
  32.     int    age;
  33.     int    in_use;
  34.     Box    box;
  35. } BOX_BUFF;
  36.  
  37. static FILE *box_file;
  38.  
  39. static BOX_BUFF **box_buff;
  40. #else
  41. static Box **box_buff;
  42. #endif
  43. static int num_buffs;
  44.  
  45. /* Get a box (from disk if necessary), and lock it in memory so that it
  46.     can't be swapped out again. Returns a pointer to where the box is
  47.     located in memory. */
  48.  
  49. Box *get_box(int n)
  50. {
  51. #ifdef __TURBOC__
  52. int i, oldest;
  53.     oldest = 0;
  54.     for (i = 0; i < num_buffs; i++) {
  55.         if (box_buff[i]->num == n) {
  56.             box_buff[i]->age--;
  57.             box_buff[i]->in_use = TRUE;
  58.             return &box_buff[i]->box;
  59.         } else {
  60.             if (box_buff[i]->in_use) continue;
  61.             if (box_buff[i]->age > box_buff[oldest]->age)        oldest = i;
  62.         }
  63.     }
  64.     if (box_buff[oldest]->in_use) {
  65.         printf("\nInsufficient virtual memory buffers.\n");
  66.         exit(1);
  67.     }
  68.     if (box_buff[oldest]->num != -1) {
  69.         if (fseek(box_file, (long) box_buff[oldest]->num * sizeof(Box), SEEK_SET) != 0) {
  70.             printf("\nError seeking BOX_FILE.TMP for write\n");
  71.             exit(1);
  72.         }
  73.         if (fwrite(&box_buff[oldest]->box, sizeof(Box), 1, box_file) != 1) {
  74.             printf("\nError writing BOX_FILE.TMP\n");
  75.             exit(1);
  76.         }
  77.     }
  78.     if (fseek(box_file, (long) n * sizeof(Box), SEEK_SET) != 0) {
  79.         printf("\nError seeking BOX_FILE.TMP for read\n");
  80.         exit(1);
  81.     }
  82.     if (fread(&box_buff[oldest]->box, sizeof(Box), 1, box_file) != 1) {
  83.         printf("\nError reading BOX_FILE.TMP\n");
  84.         exit(1);
  85.     }
  86.     box_buff[oldest]->num = n;
  87.     box_buff[oldest]->age = 0;
  88.     box_buff[oldest]->in_use = TRUE;
  89.     return &box_buff[oldest]->box;
  90. #else
  91.     return box_buff[n];
  92. #endif
  93. }
  94.  
  95. /* Get a box (from disk if necessary), and allow it to be swapped out again.
  96.     Returns a pointer to where the box is located in memory. */
  97.  
  98. Box *get_box_tmp(int n)
  99. {
  100. #ifdef __TURBOC__
  101. int i, oldest;
  102.  
  103.     oldest = 0;
  104.     for (i = 0; i < num_buffs; i++) {
  105.         if (box_buff[i]->num == n) {
  106.             box_buff[i]->age--;
  107.             return &box_buff[i]->box;
  108.         } else {
  109.             if (box_buff[i]->in_use) continue;
  110.             if (box_buff[i]->age > box_buff[oldest]->age)        oldest = i;
  111.         }
  112.     }
  113.     if (box_buff[oldest]->in_use) {
  114.         printf("\nInsufficient virtual memory buffers.\n");
  115.         exit(1);
  116.     }
  117.     if (box_buff[oldest]->num != -1) {
  118.         if (fseek(box_file, (long) box_buff[oldest]->num * sizeof(Box), SEEK_SET) != 0) {
  119.             printf("\nError seeking BOX_FILE.TMP for write\n");
  120.             exit(1);
  121.         }
  122.         if (fwrite(&box_buff[oldest]->box, sizeof(Box), 1, box_file) != 1) {
  123.             printf("\nError writing BOX_FILE.TMP\n");
  124.             exit(1);
  125.         }
  126.     }
  127.     if (fseek(box_file, (long) n * sizeof(Box), SEEK_SET) != 0) {
  128.         printf("\nError seeking BOX_FILE.TMP for read\n");
  129.         exit(1);
  130.     }
  131.     if (fread(&box_buff[oldest]->box, sizeof(Box), 1, box_file) != 1) {
  132.         printf("\nError reading BOX_FILE.TMP\n");
  133.         exit(1);
  134.     }
  135.     box_buff[oldest]->num = n;
  136.     box_buff[oldest]->age = 0;
  137.     return &box_buff[oldest]->box;
  138. #else
  139.     return box_buff[n];
  140. #endif
  141. }
  142.  
  143. /* Free a previously locked box so that it can be swapped out to disk. */
  144.  
  145. void free_box(int n)
  146. {
  147. #ifdef __TURBOC__
  148. int i;
  149.  
  150.     for (i = 0; i < num_buffs; i++) {
  151.         if (box_buff[i]->num == n) {
  152.             box_buff[i]->in_use = FALSE;
  153.             return;
  154.         }
  155.     }
  156. #endif
  157. }
  158.  
  159. /* Grab almost all of the remaining memory (up to the number of colours
  160.     being produced), leaving only a little for printf(), etc.
  161.  
  162.     At least 3 buffers must be available, since the program locks 2 and
  163.     then wants to load a third one to compare data.
  164.  
  165.     This routine clears box[0], which is assumed by function main() in
  166.     QUANT.C. It also writes 0's to the entire disk buffer. Initially, all
  167.     cache buffers are set to -1, unused.
  168. */
  169.  
  170. void open_box_file(int buffs_needed)
  171. {
  172. int i;
  173. #ifdef __TURBOC__
  174. unsigned long coreleft;
  175.  
  176.     coreleft = farcoreleft();
  177.     if (coreleft < 0x4000L + sizeof(BOX_BUFF) * 3) {
  178.         printf("Insufficient memory: %ld needed, %ld available\n",
  179.                     0x4000L + sizeof(BOX_BUFF) * 3, coreleft);
  180.         exit(1);
  181.     }
  182.     num_buffs = (int)((coreleft - 0x4000L) / sizeof(BOX_BUFF));
  183.     if (num_buffs > buffs_needed) num_buffs = buffs_needed;
  184.     CHECK_ALLOC(box_buff, BOX_BUFF *, num_buffs, "Box Buffer");
  185.     for (i = 0; i < num_buffs; i++)
  186.         CHECK_ALLOC(box_buff[i], BOX_BUFF, 1, "Box Buffer");
  187.     printf("%d virtual memory buffers allocated\n", num_buffs);
  188.     box_file = fopen("VIRT_MEM.TMP", "w+b");
  189.     if (box_file == NULL) {
  190.         printf("Couldn't open VIRT_MEM.TMP\n");
  191.         exit(1);
  192.     }
  193.     for (i = 0; i < num_buffs; i++) {
  194.         box_buff[i]->num    = -1;
  195.         box_buff[i]->age    = 0x7fff;
  196.         box_buff[i]->in_use = FALSE;
  197.     }
  198.  
  199.     printf("Clearing virtual memory disk buffer.\n");
  200.     memset(&box_buff[0]->box, 0, sizeof(Box));
  201.     for (i = 0; i < buffs_needed; i++) {
  202.         if (fwrite(&box_buff[0]->box, sizeof(Box), 1, box_file) != 1) {
  203.             printf("\nError writing VIRT_MEM.TMP\n");
  204.             exit(1);
  205.         }
  206.     }
  207. #else
  208.  
  209.     CHECK_ALLOC(box_buff, void *, buffs_needed, "Box buffer");
  210.     num_buffs = buffs_needed;
  211.     for (i = 0; i < buffs_needed; i++)
  212.         CHECK_ALLOC(box_buff[i], Box, 1, "Box buffer");
  213.     printf("%d box buffers allocated\n", buffs_needed);
  214.  
  215.     for (i = 0; i < buffs_needed; i++)
  216.         memset(box_buff[i], 0, sizeof(Box));
  217. #endif
  218. }
  219.  
  220. /* Release cache buffers, and delete the disk buffer file */
  221.  
  222. void close_box_file(void)
  223. {
  224. int i;
  225.     for (i = 0; i < num_buffs; i++)     free(box_buff[i]);
  226.     free(box_buff);
  227. #ifdef __TURBOC__
  228.     fclose(box_file);
  229.     unlink("VIRT_MEM.TMP");
  230. #endif
  231. }
  232.