]> 4ch.mooo.com Git - 16.git/commitdiff
16_ca needs huge amounts of work and I should remember what needs to be done soon...
authorsparky4 <sparky4@cock.li>
Sat, 13 May 2017 19:41:36 +0000 (14:41 -0500)
committersparky4 <sparky4@cock.li>
Sat, 13 May 2017 19:41:36 +0000 (14:41 -0500)
src/lib/16_ca.c
src/lib/16_map.c
src/lib/16_rf.c
src/lib/16_rf.h
src/lib/16_t.h
src/lib/16_tdef.h
src/lib/id_ca.c [new file with mode: 0755]
src/maptest.c

index 1d9b7f0be2b3b5b35fb18e77953ad1e841a622d7..ce406dd50ebf6b08b481bc2a209e67e6a6fab370 100755 (executable)
@@ -1088,23 +1088,23 @@ void CAL_SetupGrFile (global_game_variables_t *gvar)
        CAL_GetGrChunkLength(STRUCTPIC,gvar);           // position file pointer\r
        printf("CAL_SetupGrFile:\n");\r
        printf("        gvar->ca.chunkcomplen size is %lu\n", gvar->ca.chunkcomplen);\r
-       MM_GetPtr(&compseg,gvar->ca.chunkcomplen,gvar);\r
-       IN_Ack(gvar);\r
+       MM_GetPtr(MEMPTRANDPERCONV compseg,gvar->ca.chunkcomplen,gvar);                                                         IN_Ack(gvar);\r
        CA_FarRead (gvar->ca.file.grhandle,compseg,gvar->ca.chunkcomplen,gvar);\r
        CAL_HuffExpand (compseg, (byte far *)gvar->video.pictable,NUMPICS*sizeof(pictabletype),gvar->ca.grhuffman);\r
-       MM_FreePtr(&compseg,gvar);\r
+       MM_FreePtr(MEMPTRANDPERCONV compseg,gvar);\r
 #endif\r
 \r
-#if NUMPICM>0\r
+#if 0\r
+       //NUMPICM>0\r
        MM_GetPtr(MEMPTRCONV picmtable,NUMPICM*sizeof(pictabletype));\r
        CAL_GetGrChunkLength(STRUCTPICM);               // position file pointer\r
        MM_GetPtr(&compseg,gvar->ca.chunkcomplen);\r
        CA_FarRead (gvar->ca.file.grhandle,compseg,gvar->ca.chunkcomplen);\r
        CAL_HuffExpand (compseg, (byte far *)picmtable,NUMPICS*sizeof(pictabletype),gvar->ca.grhuffman);\r
        MM_FreePtr(&compseg);\r
-#endif\r
+//#endif\r
 \r
-#if NUMSPRITES>0\r
+//#if NUMSPRITES>0\r
        MM_GetPtr(MEMPTRCONV spritetable,NUMSPRITES*sizeof(spritetabletype));\r
        CAL_GetGrChunkLength(STRUCTSPRITE);     // position file pointer\r
        MM_GetPtr(&compseg,gvar->ca.chunkcomplen);\r
index 88110d5e2a50f099704feda6236aeb690216e4a9..ad846e81b10bae5149e44ea7effc21606343781a 100755 (executable)
@@ -216,7 +216,6 @@ int newloadmap(char *mn, map_t *map) {
 //======\r
 \r
 \r
-#define MAPBUFINLM (gvar->ca.mapsegs[0])\r
 int CA_loadmap(char *mn, map_t *map, global_game_variables_t *gvar)\r
 {\r
        jsmn_parser p;\r
@@ -230,18 +229,18 @@ int CA_loadmap(char *mn, map_t *map, global_game_variables_t *gvar)
        jsmn_init(&p);\r
 \r
        file_s = filesize(fh);\r
-       CA_LoadFile(mn, (memptr *)&MAPBUFINLM, gvar);\r
-       tokcount = jsmn_parse(&p, (char const *)MAPBUFINLM, file_s, NULL, 0);\r
+       CA_LoadFile(mn, MEMPTRCONV MAPSEGINLM, gvar);\r
+       tokcount = jsmn_parse(&p, (char const *)MAPSEGINLM, file_s, NULL, 0);\r
        tok = malloc(tokcount*sizeof(jsmntok_t));//TODO: USE MM_ CA_ AND PM_\r
 //     printf("Allocated %d tokens", tokcount);\r
        jsmn_init(&p);\r
-       if((status = jsmn_parse(&p, (char const *)MAPBUFINLM, file_s, tok, tokcount)) < 0)\r
+       if((status = jsmn_parse(&p, (char const *)MAPSEGINLM, file_s, tok, tokcount)) < 0)\r
        {\r
                printf("Error: %d\n", status);\r
                return status;\r
        }\r
        else if(status != tokcount) { printf("Warning: used %d tok\n", status);}\r
-       extract_map((char const *)MAPBUFINLM, tok, tokcount, map);\r
+       extract_map((char const *)MAPSEGINLM, tok, tokcount, map);\r
 \r
        free(tok);      //TODO: USE MM_ CA_ AND PM_\r
        fclose(fh);     //TODO: USE MM_ CA_ AND PM_\r
index bc0afca6164f6c0165f50478650e1ca7b6d98c77..86f40456532ee01fe1185806ee259882ce1b3b16 100755 (executable)
@@ -919,7 +919,8 @@ void RFL_CalcOriginStuff (long x, long y)
        gvar->video.ofs.pan.panx = (originxglobal>>G_P_SHIFT) & 15;\r
        gvar->video.ofs.pan.pansx = gvar->video.ofs.pan.panx & 8;\r
        gvar->video.ofs.pan.pany = gvar->video.ofs.pan.pansy = (originyglobal>>G_P_SHIFT) & 15;\r
-       gvar->video.ofs.pan.panadjust = gvar->video.ofs.pan.panx/8 + gvar->video.ofs.ylookup[gvar->video.ofs.pan.pany];\r
+//     gvar->video.ofs.pan.panadjust = gvar->video.ofs.pan.panx/8 + gvar->video.ofs.ylookup[gvar->video.ofs.pan.pany];\r
+       gvar->video.ofs.pan.panadjust = gvar->video.ofs.pan.panx/8 + (gvar->video.ofs.pan.pany*gvar->video.page[0].stridew);\r
 /*#endif\r
 \r
 #if GRMODE == CGAGR\r
@@ -1368,7 +1369,7 @@ void RFL_BoundNewOrigin (unsigned orgx,unsigned orgy)
 \r
 void RF_ClearBlock (int        x, int y, int width, int height)\r
 {\r
-       eraseblocktype block;\r
+//     eraseblocktype block;\r
 \r
 #if GRMODE == EGAGR\r
        block.screenx = x/8+originxscreen;\r
@@ -1429,7 +1430,7 @@ void RF_RedrawBlock (int x, int y, int width, int height)
 \r
 void RF_CalcTics (void)\r
 {\r
-       long    newtime,oldtimecount;\r
+       long    newtime;//,oldtimecount;\r
        word TimeCount = *clockw;\r
 \r
 //\r
@@ -2678,7 +2679,8 @@ void RFL_EraseBlocks (void)
        //\r
        // erase the block by copying from the master screen\r
        //\r
-               pos = gvar->video.ofs.ylookup[block->screeny]+block->screenx;\r
+//----         pos = gvar->video.ofs.ylookup[block->screeny]+block->screenx;\r
+               pos = (block->screeny*gvar->video.page[0].stridew)+block->screenx;\r
                block->width = (block->width + (pos&1) + 1)& ~1;\r
                pos &= ~1;                              // make sure a word copy gets used\r
 //++++         VW_ScreenToScreen (masterofs+pos,bufferofs+pos,\r
index e70fb104b1db0a4fc6283e86c5ef517a4f7bccdd..fe16b89cb74914bff277928eecbd10072d46ac89 100755 (executable)
 #define MSPEED      (INTILE+NUMTILE16M)\r
 #define        CGAGR   1\r
 #define        EGAGR   2\r
-#define        MAXSHIFTS       1\r
+//#define      MAXSHIFTS       1\r
 #define        TILEWIDTH       TILEWH\r
 typedef enum {NOcard,MDAcard,CGAcard,EGAcard,MCGAcard,VGAcard,\r
                  HGCcard=0x80,HGCPcard,HICcard} cardtype;\r
 typedef enum {CGAgr,EGAgr,VGAgr} grtype;\r
-typedef struct\r
+/*typedef struct\r
 {\r
   int  width,\r
        height,\r
@@ -101,7 +101,7 @@ typedef     struct
        unsigned        planesize[MAXSHIFTS];\r
        unsigned        width[MAXSHIFTS];\r
        byte            data[];\r
-} spritetype;          // the memptr for each sprite points to this\r
+} spritetype;          // the memptr for each sprite points to this*/\r
 //\r
 \r
 //===========================================================================\r
index ff73865751b57b0a984f94756819344b50a5bd76..db1871f7f5d05d14f860eab9b45e45d7636c7abc 100755 (executable)
@@ -49,19 +49,16 @@ typedef     enum    {ichi,ni,san,yon,go,roku,shichi,hachi,kyu,ju,juichi,juni,jusan,juyo
 /*typedef unsigned memseg;\r
 \r
 memptr should be replaced by memseg in code.\r
-\r
 on usage where you need pointer convert memseg type (segment) to far pointer by\r
 MK_FP(segment value, 0)*/\r
-#ifdef __WATCOMC__\r
+       #ifdef __WATCOMC__\r
 //typedef void __based( void ) * memptr;       ////old //----typedef void __based(__self) * memptr;\r
 //typedef unsigned short _seg; // it will contains segment value (as Borland _seg)\r
 #define _seg __based( void )\r
-// #define __SEGA __segment\r
-#endif\r
-#ifdef __BORLANDC__\r
+       #endif\r
+       #ifdef __BORLANDC__\r
 #define _memavl()               coreleft()\r
-// #define __SEGA _seg\r
-#endif\r
+       #endif\r
 \r
 typedef void _seg * memptr;\r
 \r
index c1f2db84fe02b398a24c789f8355b46af9587892..b3fc892d87a81b609eb8e4d4d6e0d0d1c222cec7 100755 (executable)
@@ -694,6 +694,10 @@ typedef struct
 #define GFILENAME      DATADIR"vgagraph."\r
 \r
 \r
+#define MAPSEGBUF      mapsegs\r
+#define MAPSEGPTR      MAPSEGBUF[0]\r
+#define MAPSEGINLM     (gvar->ca.MAPSEGPTR)\r
+\r
 typedef struct\r
 {\r
   word bit0,bit1;      // 0-255 is a character, > is a pointer to a node\r
diff --git a/src/lib/id_ca.c b/src/lib/id_ca.c
new file mode 100755 (executable)
index 0000000..0cf682e
--- /dev/null
@@ -0,0 +1,1914 @@
+// ID_CA.C\r
+\r
+// this has been customized for WOLF\r
+\r
+/*\r
+=============================================================================\r
+\r
+Id Software Caching Manager\r
+---------------------------\r
+\r
+Must be started BEFORE the memory manager, because it needs to get the headers\r
+loaded into the data segment\r
+\r
+=============================================================================\r
+*/\r
+\r
+#include "ID_HEADS.H"\r
+#pragma hdrstop\r
+\r
+#pragma warn -pro\r
+#pragma warn -use\r
+\r
+#define THREEBYTEGRSTARTS\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                LOCAL CONSTANTS\r
+\r
+=============================================================================\r
+*/\r
+\r
+typedef struct\r
+{\r
+  unsigned bit0,bit1;  // 0-255 is a character, > is a pointer to a node\r
+} huffnode;\r
+\r
+\r
+typedef struct\r
+{\r
+       unsigned        RLEWtag;\r
+       long            headeroffsets[100];\r
+       byte            tileinfo[];\r
+} mapfiletype;\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                GLOBAL VARIABLES\r
+\r
+=============================================================================\r
+*/\r
+\r
+byte _seg      *tinf;\r
+int                    mapon;\r
+\r
+unsigned       _seg    *mapsegs[MAPPLANES];\r
+maptype                _seg    *mapheaderseg[NUMMAPS];\r
+byte _seg      *audiosegs[NUMSNDCHUNKS];\r
+void           _seg    *grsegs[NUMCHUNKS];\r
+\r
+byte           far     grneeded[NUMCHUNKS];\r
+byte           ca_levelbit,ca_levelnum;\r
+\r
+int                    profilehandle,debughandle;\r
+\r
+char           audioname[13]="AUDIO.";\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                                LOCAL VARIABLES\r
+\r
+=============================================================================\r
+*/\r
+\r
+extern long    far     CGAhead;\r
+extern long    far     EGAhead;\r
+extern byte    CGAdict;\r
+extern byte    EGAdict;\r
+extern byte    far     maphead;\r
+extern byte    mapdict;\r
+extern byte    far     audiohead;\r
+extern byte    audiodict;\r
+\r
+\r
+char extension[5],     // Need a string, not constant to change cache files\r
+     gheadname[10]=GREXT"HEAD.",\r
+     gfilename[10]=GREXT"GRAPH.",\r
+     gdictname[10]=GREXT"DICT.",\r
+     mheadname[10]="MAPHEAD.",\r
+     mfilename[10]="MAPTEMP.",\r
+     aheadname[10]="AUDIOHED.",\r
+     afilename[10]="AUDIOT.";\r
+\r
+void CA_CannotOpen(char *string);\r
+\r
+long           _seg *grstarts; // array of offsets in egagraph, -1 for sparse\r
+long           _seg *audiostarts;      // array of offsets in audio / audiot\r
+\r
+#ifdef GRHEADERLINKED\r
+huffnode       *grhuffman;\r
+#else\r
+huffnode       grhuffman[255];\r
+#endif\r
+\r
+#ifdef AUDIOHEADERLINKED\r
+huffnode       *audiohuffman;\r
+#else\r
+huffnode       audiohuffman[255];\r
+#endif\r
+\r
+\r
+int                    grhandle;               // handle to EGAGRAPH\r
+int                    maphandle;              // handle to MAPTEMP / GAMEMAPS\r
+int                    audiohandle;    // handle to AUDIOT / AUDIO\r
+\r
+long           chunkcomplen,chunkexplen;\r
+\r
+SDMode         oldsoundmode;\r
+\r
+\r
+\r
+void   CAL_CarmackExpand (unsigned far *source, unsigned far *dest,\r
+               unsigned length);\r
+\r
+\r
+#ifdef THREEBYTEGRSTARTS\r
+#define FILEPOSSIZE    3\r
+//#define      GRFILEPOS(c) (*(long far *)(((byte far *)grstarts)+(c)*3)&0xffffff)\r
+long GRFILEPOS(int c)\r
+{\r
+       long value;\r
+       int     offset;\r
+\r
+       offset = c*3;\r
+\r
+       value = *(long far *)(((byte far *)grstarts)+offset);\r
+\r
+       value &= 0x00ffffffl;\r
+\r
+       if (value == 0xffffffl)\r
+               value = -1;\r
+\r
+       return value;\r
+};\r
+#else\r
+#define FILEPOSSIZE    4\r
+#define        GRFILEPOS(c) (grstarts[c])\r
+#endif\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                          LOW LEVEL ROUTINES\r
+\r
+=============================================================================\r
+*/\r
+\r
+/*\r
+============================\r
+=\r
+= CA_OpenDebug / CA_CloseDebug\r
+=\r
+= Opens a binary file with the handle "debughandle"\r
+=\r
+============================\r
+*/\r
+\r
+void CA_OpenDebug (void)\r
+{\r
+       unlink ("DEBUG.TXT");\r
+       debughandle = open("DEBUG.TXT", O_CREAT | O_WRONLY | O_TEXT);\r
+}\r
+\r
+void CA_CloseDebug (void)\r
+{\r
+       close (debughandle);\r
+}\r
+\r
+\r
+\r
+/*\r
+============================\r
+=\r
+= CAL_GetGrChunkLength\r
+=\r
+= Gets the length of an explicit length chunk (not tiles)\r
+= The file pointer is positioned so the compressed data can be read in next.\r
+=\r
+============================\r
+*/\r
+\r
+void CAL_GetGrChunkLength (int chunk)\r
+{\r
+       lseek(grhandle,GRFILEPOS(chunk),SEEK_SET);\r
+       read(grhandle,&chunkexplen,sizeof(chunkexplen));\r
+       chunkcomplen = GRFILEPOS(chunk+1)-GRFILEPOS(chunk)-4;\r
+}\r
+\r
+\r
+/*\r
+==========================\r
+=\r
+= CA_FarRead\r
+=\r
+= Read from a file to a far pointer\r
+=\r
+==========================\r
+*/\r
+\r
+boolean CA_FarRead (int handle, byte far *dest, long length)\r
+{\r
+       boolean flag=false;\r
+       if (length>0xffffl)\r
+               Quit ("CA_FarRead doesn't support 64K reads yet!");\r
+\r
+       __asm {\r
+               push    ds\r
+               mov     bx,[handle]\r
+               mov     cx,[WORD PTR length]\r
+               mov     dx,[WORD PTR dest]\r
+               mov     ds,[WORD PTR dest+2]\r
+               mov     ah,0x3f                         // READ w/handle\r
+               int     21h\r
+               pop     ds\r
+               jnc     good\r
+               mov     errno,ax\r
+               mov     flag,0\r
+               jmp End\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+good:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               cmp     ax,[WORD PTR length]\r
+               je      done\r
+//             errno = EINVFMT;                        // user manager knows this is bad read\r
+               mov     flag,0\r
+               jmp End\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+done:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               mov     flag,1\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+End:\r
+#ifdef __WATCOMC__\r
+       }\r
+#endif\r
+       return flag;\r
+}\r
+\r
+\r
+/*\r
+==========================\r
+=\r
+= CA_SegWrite\r
+=\r
+= Write from a file to a far pointer\r
+=\r
+==========================\r
+*/\r
+\r
+boolean CA_FarWrite (int handle, byte far *source, long length)\r
+{\r
+       boolean flag=false;\r
+       if (length>0xffffl)\r
+               Quit ("CA_FarWrite doesn't support 64K reads yet!");\r
+\r
+       __asm {\r
+               push    ds\r
+               mov     bx,[handle]\r
+               mov     cx,[WORD PTR length]\r
+               mov     dx,[WORD PTR source]\r
+               mov     ds,[WORD PTR source+2]\r
+               mov     ah,0x40                 // WRITE w/handle\r
+               int     21h\r
+               pop     ds\r
+               jnc     good\r
+               mov     errno,ax\r
+               mov flag,0\r
+               jmp End\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+good:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               cmp     ax,[WORD PTR length]\r
+               je      done\r
+//             errno = ENOMEM;                         // user manager knows this is bad write\r
+               mov     flag,0\r
+               jmp End\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+done:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               mov     flag,1\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+End:\r
+#ifdef __WATCOMC__\r
+       }\r
+#endif\r
+       return flag;\r
+}\r
+\r
+\r
+/*\r
+==========================\r
+=\r
+= CA_ReadFile\r
+=\r
+= Reads a file into an allready allocated buffer\r
+=\r
+==========================\r
+*/\r
+\r
+boolean CA_ReadFile (char *filename, memptr *ptr)\r
+{\r
+       int handle;\r
+       long size;\r
+\r
+       if ((handle = open(filename,O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
+               return false;\r
+\r
+       size = filelength (handle);\r
+       if (!CA_FarRead (handle,*ptr,size))\r
+       {\r
+               close (handle);\r
+               return false;\r
+       }\r
+       close (handle);\r
+       return true;\r
+}\r
+\r
+\r
+/*\r
+==========================\r
+=\r
+= CA_WriteFile\r
+=\r
+= Writes a file from a memory buffer\r
+=\r
+==========================\r
+*/\r
+\r
+boolean CA_WriteFile (char *filename, void far *ptr, long length)\r
+{\r
+       int handle;\r
+       long size;\r
+\r
+       handle = open(filename,O_CREAT | O_BINARY | O_WRONLY,\r
+                               S_IREAD | S_IWRITE | S_IFREG);\r
+\r
+       if (handle == -1)\r
+               return false;\r
+\r
+       if (!CA_FarWrite (handle,ptr,length))\r
+       {\r
+               close (handle);\r
+               return false;\r
+       }\r
+       close (handle);\r
+       return true;\r
+}\r
+\r
+\r
+\r
+/*\r
+==========================\r
+=\r
+= CA_LoadFile\r
+=\r
+= Allocate space for and load a file\r
+=\r
+==========================\r
+*/\r
+\r
+boolean CA_LoadFile (char *filename, memptr *ptr)\r
+{\r
+       int handle;\r
+       long size;\r
+\r
+       if ((handle = open(filename,O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
+               return false;\r
+\r
+       size = filelength (handle);\r
+       MM_GetPtr (ptr,size);\r
+       if (!CA_FarRead (handle,*ptr,size))\r
+       {\r
+               close (handle);\r
+               return false;\r
+       }\r
+       close (handle);\r
+       return true;\r
+}\r
+\r
+/*\r
+============================================================================\r
+\r
+               COMPRESSION routines, see JHUFF.C for more\r
+\r
+============================================================================\r
+*/\r
+\r
+\r
+\r
+/*\r
+===============\r
+=\r
+= CAL_OptimizeNodes\r
+=\r
+= Goes through a huffman table and changes the 256-511 node numbers to the\r
+= actular address of the node.  Must be called before CAL_HuffExpand\r
+=\r
+===============\r
+*/\r
+\r
+void CAL_OptimizeNodes (huffnode *table)\r
+{\r
+  huffnode *node;\r
+  int i;\r
+\r
+  node = table;\r
+\r
+  for (i=0;i<255;i++)\r
+  {\r
+       if (node->bit0 >= 256)\r
+         node->bit0 = (unsigned)(table+(node->bit0-256));\r
+       if (node->bit1 >= 256)\r
+         node->bit1 = (unsigned)(table+(node->bit1-256));\r
+       node++;\r
+  }\r
+}\r
+\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= CAL_HuffExpand\r
+=\r
+= Length is the length of the EXPANDED data\r
+= If screenhack, the data is decompressed in four planes directly\r
+= to the screen\r
+=\r
+======================\r
+*/\r
+\r
+void CAL_HuffExpand (byte huge *source, byte huge *dest,\r
+  long length,huffnode *hufftable, boolean screenhack)\r
+{\r
+//  unsigned bit,byte,node,code;\r
+  unsigned sourceseg,sourceoff,destseg,destoff,endoff;\r
+  huffnode *headptr;\r
+  byte         mapmask;\r
+//  huffnode *nodeon;\r
+\r
+  headptr = hufftable+254;     // head node is allways node 254\r
+\r
+  source++;    // normalize\r
+  source--;\r
+  dest++;\r
+  dest--;\r
+\r
+  if (screenhack)\r
+  {\r
+       mapmask = 1;\r
+asm    mov     dx,SC_INDEX\r
+asm    mov     ax,SC_MAPMASK + 256\r
+asm    out     dx,ax\r
+       length >>= 2;\r
+  }\r
+\r
+  sourceseg = FP_SEG(source);\r
+  sourceoff = FP_OFF(source);\r
+  destseg = FP_SEG(dest);\r
+  destoff = FP_OFF(dest);\r
+  endoff = destoff+length;\r
+\r
+//\r
+// ds:si source\r
+// es:di dest\r
+// ss:bx node pointer\r
+//\r
+\r
+       if (length <0xfff0)\r
+       {\r
+\r
+//--------------------------\r
+// expand less than 64k of data\r
+//--------------------------\r
+\r
+       __asm {\r
+               mov     bx,[word ptr headptr]\r
+\r
+               mov     si,[sourceoff]\r
+               mov     di,[destoff]\r
+               mov     es,[destseg]\r
+               mov     ds,[sourceseg]\r
+               mov     ax,[endoff]\r
+\r
+               mov     ch,[si]                         // load first byte\r
+               inc     si\r
+               mov     cl,1\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+expandshort:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               test    ch,cl                   // bit set?\r
+               jnz     bit1short\r
+               mov     dx,[ss:bx]                      // take bit0 path from node\r
+               shl     cl,1                            // advance to next bit position\r
+               jc      newbyteshort\r
+               jnc     sourceupshort\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+bit1short:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               mov     dx,[ss:bx+2]            // take bit1 path\r
+               shl     cl,1                            // advance to next bit position\r
+               jnc     sourceupshort\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+newbyteshort:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               mov     ch,[si]                         // load next byte\r
+               inc     si\r
+               mov     cl,1                            // back to first bit\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+sourceupshort:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               or      dh,dh                           // if dx<256 its a byte, else move node\r
+               jz      storebyteshort\r
+               mov     bx,dx                           // next node = (huffnode *)code\r
+               jmp     expandshort\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+storebyteshort:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               mov     [es:di],dl\r
+               inc     di                                      // write a decopmpressed byte out\r
+               mov     bx,[word ptr headptr]           // back to the head node for next bit\r
+\r
+               cmp     di,ax                           // done?\r
+               jne     expandshort\r
+//\r
+// perform screenhack if needed\r
+//\r
+               test    [screenhack],1\r
+               jz      notscreen\r
+               shl     [mapmask],1\r
+               mov     ah,[mapmask]\r
+               cmp     ah,16\r
+               je      notscreen                       // all four planes done\r
+               mov     dx,SC_INDEX\r
+               mov     al,SC_MAPMASK\r
+               out     dx,ax\r
+               mov     di,[destoff]\r
+               mov     ax,[endoff]\r
+               jmp     expandshort\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+notscreen:\r
+#ifdef __WATCOMC__\r
+       }\r
+#endif\r
+       }\r
+       else\r
+       {\r
+\r
+//--------------------------\r
+// expand more than 64k of data\r
+//--------------------------\r
+\r
+  length--;\r
+\r
+       __asm {\r
+               mov     bx,[word ptr headptr]\r
+               mov     cl,1\r
+\r
+               mov     si,[sourceoff]\r
+               mov     di,[destoff]\r
+               mov     es,[destseg]\r
+               mov     ds,[sourceseg]\r
+\r
+               lodsb                   // load first byte\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+expand:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               test    al,cl           // bit set?\r
+               jnz     bit1\r
+               mov     dx,[ss:bx]      // take bit0 path from node\r
+               jmp     gotcode\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+bit1:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               mov     dx,[ss:bx+2]    // take bit1 path\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+gotcode:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               shl     cl,1            // advance to next bit position\r
+               jnc     sourceup\r
+               lodsb\r
+               cmp     si,0x10         // normalize ds:si\r
+               jb      sinorm\r
+               mov     cx,ds\r
+               inc     cx\r
+               mov     ds,cx\r
+               xor     si,si\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+sinorm:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               mov     cl,1            // back to first bit\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+sourceup:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               or      dh,dh           // if dx<256 its a byte, else move node\r
+               jz      storebyte\r
+               mov     bx,dx           // next node = (huffnode *)code\r
+               jmp     expand\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+storebyte:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               mov     [es:di],dl\r
+               inc     di              // write a decopmpressed byte out\r
+               mov     bx,[word ptr headptr]   // back to the head node for next bit\r
+\r
+               cmp     di,0x10         // normalize es:di\r
+               jb      dinorm\r
+               mov     dx,es\r
+               inc     dx\r
+               mov     es,dx\r
+               xor     di,di\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+dinorm:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               sub     [WORD PTR ss:length],1\r
+               jnc     expand\r
+               dec     [WORD PTR ss:length+2]\r
+               jns     expand          // when length = ffff ffff, done\r
+       }\r
+       }\r
+\r
+       __asm {\r
+               mov     ax,ss\r
+               mov     ds,ax\r
+       }\r
+\r
+}\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= CAL_CarmackExpand\r
+=\r
+= Length is the length of the EXPANDED data\r
+=\r
+======================\r
+*/\r
+\r
+#define NEARTAG        0xa7\r
+#define FARTAG 0xa8\r
+\r
+void CAL_CarmackExpand (unsigned far *source, unsigned far *dest, unsigned length)\r
+{\r
+       unsigned        ch,chhigh,count,offset;\r
+       unsigned        far *copyptr, far *inptr, far *outptr;\r
+\r
+       length/=2;\r
+\r
+       inptr = source;\r
+       outptr = dest;\r
+\r
+       while (length)\r
+       {\r
+               ch = *inptr++;\r
+               chhigh = ch>>8;\r
+               if (chhigh == NEARTAG)\r
+               {\r
+                       count = ch&0xff;\r
+                       if (!count)\r
+                       {                               // have to insert a word containing the tag byte\r
+                               ch |= *(BYTEFARPTRCONV inptr)++;\r
+                               *outptr++ = ch;\r
+                               length--;\r
+                       }\r
+                       else\r
+                       {\r
+                               offset = *(BYTEFARPTRCONV inptr)++;\r
+                               copyptr = outptr - offset;\r
+                               length -= count;\r
+                               while (count--)\r
+                                       *outptr++ = *copyptr++;\r
+                       }\r
+               }\r
+               else if (chhigh == FARTAG)\r
+               {\r
+                       count = ch&0xff;\r
+                       if (!count)\r
+                       {                               // have to insert a word containing the tag byte\r
+                               ch |= *(BYTEFARPTRCONV inptr)++;\r
+                               *outptr++ = ch;\r
+                               length --;\r
+                       }\r
+                       else\r
+                       {\r
+                               offset = *inptr++;\r
+                               copyptr = dest + offset;\r
+                               length -= count;\r
+                               while (count--)\r
+                                       *outptr++ = *copyptr++;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       *outptr++ = ch;\r
+                       length --;\r
+               }\r
+       }\r
+}\r
+\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= CA_RLEWcompress\r
+=\r
+======================\r
+*/\r
+\r
+long CA_RLEWCompress (unsigned huge *source, long length, unsigned huge *dest,\r
+  unsigned rlewtag)\r
+{\r
+  long complength;\r
+  unsigned value,count,i;\r
+  unsigned huge *start,huge *end;\r
+\r
+  start = dest;\r
+\r
+  end = source + (length+1)/2;\r
+\r
+//\r
+// compress it\r
+//\r
+  do\r
+  {\r
+       count = 1;\r
+       value = *source++;\r
+       while (*source == value && source<end)\r
+       {\r
+         count++;\r
+         source++;\r
+       }\r
+       if (count>3 || value == rlewtag)\r
+       {\r
+    //\r
+    // send a tag / count / value string\r
+    //\r
+      *dest++ = rlewtag;\r
+      *dest++ = count;\r
+      *dest++ = value;\r
+    }\r
+    else\r
+    {\r
+    //\r
+    // send word without compressing\r
+    //\r
+      for (i=1;i<=count;i++)\r
+       *dest++ = value;\r
+       }\r
+\r
+  } while (source<end);\r
+\r
+  complength = 2*(dest-start);\r
+  return complength;\r
+}\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= CA_RLEWexpand\r
+= length is EXPANDED length\r
+=\r
+======================\r
+*/\r
+\r
+void CA_RLEWexpand (unsigned huge *source, unsigned huge *dest,long length,\r
+  unsigned rlewtag)\r
+{\r
+//  unsigned value,count,i;\r
+  unsigned huge *end;\r
+  unsigned sourceseg,sourceoff,destseg,destoff,endseg,endoff;\r
+\r
+\r
+//\r
+// expand it\r
+//\r
+#if 0\r
+  do\r
+  {\r
+       value = *source++;\r
+       if (value != rlewtag)\r
+       //\r
+       // uncompressed\r
+       //\r
+         *dest++=value;\r
+       else\r
+       {\r
+       //\r
+       // compressed string\r
+       //\r
+         count = *source++;\r
+         value = *source++;\r
+         for (i=1;i<=count;i++)\r
+       *dest++ = value;\r
+       }\r
+  } while (dest<end);\r
+#endif\r
+\r
+  end = dest + (length)/2;\r
+  sourceseg = FP_SEG(source);\r
+  sourceoff = FP_OFF(source);\r
+  destseg = FP_SEG(dest);\r
+  destoff = FP_OFF(dest);\r
+  endseg = FP_SEG(end);\r
+  endoff = FP_OFF(end);\r
+\r
+\r
+//\r
+// ax = source value\r
+// bx = tag value\r
+// cx = repeat counts\r
+// dx = scratch\r
+//\r
+// NOTE: A repeat count that produces 0xfff0 bytes can blow this!\r
+//\r
+\r
+       __asm {\r
+               mov     bx,rlewtag\r
+               mov     si,sourceoff\r
+               mov     di,destoff\r
+               mov     es,destseg\r
+               mov     ds,sourceseg\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+expand:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               lodsw\r
+               cmp     ax,bx\r
+               je      repeat\r
+               stosw\r
+               jmp     next\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+repeat:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               lodsw\r
+               mov     cx,ax           // repeat count\r
+               lodsw                   // repeat value\r
+               rep stosw\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+next:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               cmp     si,0x10         // normalize ds:si\r
+               jb      sinorm\r
+               mov     ax,si\r
+               shr     ax,1\r
+               shr     ax,1\r
+               shr     ax,1\r
+               shr     ax,1\r
+               mov     dx,ds\r
+               add     dx,ax\r
+               mov     ds,dx\r
+               and     si,0xf\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+sinorm:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               cmp     di,0x10         // normalize es:di\r
+               jb      dinorm\r
+               mov     ax,di\r
+               shr     ax,1\r
+               shr     ax,1\r
+               shr     ax,1\r
+               shr     ax,1\r
+               mov     dx,es\r
+               add     dx,ax\r
+               mov     es,dx\r
+               and     di,0xf\r
+#ifdef __BORLANDC__\r
+       }\r
+#endif\r
+dinorm:\r
+#ifdef __BORLANDC__\r
+       __asm {\r
+#endif\r
+               cmp     di,ss:endoff\r
+               jne     expand\r
+               mov     ax,es\r
+               cmp     ax,ss:endseg\r
+               jb      expand\r
+\r
+               mov     ax,ss\r
+               mov     ds,ax\r
+       }\r
+\r
+}\r
+\r
+\r
+\r
+/*\r
+=============================================================================\r
+\r
+                                        CACHE MANAGER ROUTINES\r
+\r
+=============================================================================\r
+*/\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= CAL_SetupGrFile\r
+=\r
+======================\r
+*/\r
+\r
+void CAL_SetupGrFile (void)\r
+{\r
+       char fname[13];\r
+       int handle;\r
+       memptr compseg;\r
+\r
+#ifdef GRHEADERLINKED\r
+\r
+       grhuffman = (huffnode *)&EGAdict;\r
+       grstarts = (long _seg *)FP_SEG(&EGAhead);\r
+\r
+       CAL_OptimizeNodes (grhuffman);\r
+\r
+#else\r
+\r
+//\r
+// load ???dict.ext (huffman dictionary for graphics files)\r
+//\r
+\r
+       strcpy(fname,gdictname);\r
+       strcat(fname,extension);\r
+\r
+       if ((handle = open(fname,\r
+                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
+               CA_CannotOpen(fname);\r
+\r
+       read(handle, &grhuffman, sizeof(grhuffman));\r
+       close(handle);\r
+       CAL_OptimizeNodes (grhuffman);\r
+//\r
+// load the data offsets from ???head.ext\r
+//\r
+       MM_GetPtr (MEMPTRCONV grstarts,(NUMCHUNKS+1)*FILEPOSSIZE);\r
+\r
+       strcpy(fname,gheadname);\r
+       strcat(fname,extension);\r
+\r
+       if ((handle = open(fname,\r
+                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
+               CA_CannotOpen(fname);\r
+\r
+       CA_FarRead(handle, (memptr)grstarts, (NUMCHUNKS+1)*FILEPOSSIZE);\r
+\r
+       close(handle);\r
+\r
+\r
+#endif\r
+\r
+//\r
+// Open the graphics file, leaving it open until the game is finished\r
+//\r
+       strcpy(fname,gfilename);\r
+       strcat(fname,extension);\r
+\r
+       grhandle = open(fname, O_RDONLY | O_BINARY);\r
+       if (grhandle == -1)\r
+               CA_CannotOpen(fname);\r
+\r
+\r
+//\r
+// load the pic and sprite headers into the arrays in the data segment\r
+//\r
+       MM_GetPtr(MEMPTRCONV pictable,NUMPICS*sizeof(pictabletype));\r
+       CAL_GetGrChunkLength(STRUCTPIC);                // position file pointer\r
+       printf("CAL_SetupGrFile:\n");\r
+       printf("        chunkcomplen size is %lu\n", chunkcomplen);\r
+       MM_GetPtr(MEMPTRANDPERCONV compseg,chunkcomplen);\r
+       CA_FarRead (grhandle,compseg,chunkcomplen);\r
+       CAL_HuffExpand (compseg, (byte huge *)pictable,NUMPICS*sizeof(pictabletype),grhuffman,false);\r
+       MM_FreePtr(MEMPTRANDPERCONV compseg);\r
+}\r
+\r
+//==========================================================================\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= CAL_SetupMapFile\r
+=\r
+======================\r
+*/\r
+\r
+void CAL_SetupMapFile (void)\r
+{\r
+       int     i;\r
+       int handle;\r
+       long length,pos;\r
+       char fname[13];\r
+\r
+//\r
+// load maphead.ext (offsets and tileinfo for map file)\r
+//\r
+#ifndef MAPHEADERLINKED\r
+       strcpy(fname,mheadname);\r
+       strcat(fname,extension);\r
+\r
+       if ((handle = open(fname,\r
+                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
+               CA_CannotOpen(fname);\r
+\r
+       length = filelength(handle);\r
+       MM_GetPtr (MEMPTRCONV tinf,length);\r
+       CA_FarRead(handle, tinf, length);\r
+       close(handle);\r
+#else\r
+\r
+       tinf = (byte _seg *)FP_SEG(&maphead);\r
+\r
+#endif\r
+\r
+//\r
+// open the data file\r
+//\r
+#ifdef CARMACIZED\r
+       strcpy(fname,"GAMEMAPS.");\r
+       strcat(fname,extension);\r
+\r
+       if ((maphandle = open(fname,\r
+                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
+               CA_CannotOpen(fname);\r
+#else\r
+       strcpy(fname,mfilename);\r
+       strcat(fname,extension);\r
+\r
+       if ((maphandle = open(fname,\r
+                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
+               CA_CannotOpen(fname);\r
+#endif\r
+\r
+//\r
+// load all map header\r
+//\r
+       for (i=0;i<NUMMAPS;i++)\r
+       {\r
+               pos = ((mapfiletype     _seg *)tinf)->headeroffsets[i];\r
+               if (pos<0)                                              // $FFFFFFFF start is a sparse map\r
+                       continue;\r
+\r
+               MM_GetPtr(MEMPTRCONV mapheaderseg[i],sizeof(maptype));\r
+               MM_SetLock(MEMPTRCONV mapheaderseg[i],true);\r
+               lseek(maphandle,pos,SEEK_SET);\r
+               CA_FarRead (maphandle,(memptr)mapheaderseg[i],sizeof(maptype));\r
+       }\r
+\r
+//\r
+// allocate space for 3 64*64 planes\r
+//\r
+       for (i=0;i<MAPPLANES;i++)\r
+       {\r
+               MM_GetPtr (MEMPTRCONV mapsegs[i],64*64*2);\r
+               MM_SetLock (MEMPTRCONV mapsegs[i],true);\r
+       }\r
+}\r
+\r
+\r
+//==========================================================================\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= CAL_SetupAudioFile\r
+=\r
+======================\r
+*/\r
+\r
+void CAL_SetupAudioFile (void)\r
+{\r
+       int handle;\r
+       long length;\r
+       char fname[13];\r
+\r
+//\r
+// load maphead.ext (offsets and tileinfo for map file)\r
+//\r
+#ifndef AUDIOHEADERLINKED\r
+       strcpy(fname,aheadname);\r
+       strcat(fname,extension);\r
+\r
+       if ((handle = open(fname,\r
+                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
+               CA_CannotOpen(fname);\r
+\r
+       length = filelength(handle);\r
+       MM_GetPtr (MEMPTRCONV audiostarts,length);\r
+       CA_FarRead(handle, (byte far *)audiostarts, length);\r
+       close(handle);\r
+#else\r
+       audiohuffman = (huffnode *)&audiodict;\r
+       CAL_OptimizeNodes (audiohuffman);\r
+       audiostarts = (long _seg *)FP_SEG(&audiohead);\r
+#endif\r
+\r
+//\r
+// open the data file\r
+//\r
+#ifndef AUDIOHEADERLINKED\r
+       strcpy(fname,afilename);\r
+       strcat(fname,extension);\r
+\r
+       if ((audiohandle = open(fname,\r
+                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
+               CA_CannotOpen(fname);\r
+#else\r
+       if ((audiohandle = open("AUDIO."EXTENSION,\r
+                O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
+               Quit ("Can't open AUDIO."EXTENSION"!");\r
+#endif\r
+}\r
+\r
+//==========================================================================\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= CA_Startup\r
+=\r
+= Open all files and load in headers\r
+=\r
+======================\r
+*/\r
+\r
+void CA_Startup (void)\r
+{\r
+#ifdef PROFILE\r
+       unlink ("PROFILE.TXT");\r
+       profilehandle = open("PROFILE.TXT", O_CREAT | O_WRONLY | O_TEXT);\r
+#endif\r
+\r
+       CAL_SetupMapFile ();\r
+       CAL_SetupGrFile ();\r
+       CAL_SetupAudioFile ();\r
+\r
+       mapon = -1;\r
+       ca_levelbit = 1;\r
+       ca_levelnum = 0;\r
+\r
+}\r
+\r
+//==========================================================================\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= CA_Shutdown\r
+=\r
+= Closes all files\r
+=\r
+======================\r
+*/\r
+\r
+void CA_Shutdown (void)\r
+{\r
+#ifdef PROFILE\r
+       close (profilehandle);\r
+#endif\r
+\r
+       close (maphandle);\r
+       close (grhandle);\r
+       close (audiohandle);\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+======================\r
+=\r
+= CA_CacheAudioChunk\r
+=\r
+======================\r
+*/\r
+\r
+void CA_CacheAudioChunk (int chunk)\r
+{\r
+       long    pos,compressed;\r
+#ifdef AUDIOHEADERLINKED\r
+       long    expanded;\r
+       memptr  bigbufferseg;\r
+       byte    far *source;\r
+#endif\r
+\r
+       if (audiosegs[chunk])\r
+       {\r
+               MM_SetPurge (MEMPTRCONV audiosegs[chunk],0);\r
+               return;                                                 // allready in memory\r
+       }\r
+\r
+//\r
+// load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
+// a larger buffer\r
+//\r
+       pos = audiostarts[chunk];\r
+       compressed = audiostarts[chunk+1]-pos;\r
+\r
+       lseek(audiohandle,pos,SEEK_SET);\r
+\r
+#ifndef AUDIOHEADERLINKED\r
+\r
+       MM_GetPtr (MEMPTRCONV audiosegs[chunk],compressed);\r
+       if (mmerror)\r
+               return;\r
+\r
+       CA_FarRead(audiohandle,audiosegs[chunk],compressed);\r
+\r
+#else\r
+\r
+       if (compressed<=BUFFERSIZE)\r
+       {\r
+               CA_FarRead(audiohandle,bufferseg,compressed);\r
+               source = bufferseg;\r
+       }\r
+       else\r
+       {\r
+               MM_GetPtr(MEMPTRANDPERCONV bigbufferseg,compressed);\r
+               if (mmerror)\r
+                       return;\r
+               MM_SetLock (MEMPTRANDPERCONV bigbufferseg,true);\r
+               CA_FarRead(audiohandle,bigbufferseg,compressed);\r
+               source = bigbufferseg;\r
+       }\r
+\r
+       expanded = *(long far *)source;\r
+       source += 4;                    // skip over length\r
+       MM_GetPtr (MEMPTRCONV audiosegs[chunk],expanded);\r
+       if (mmerror)\r
+               goto done;\r
+       CAL_HuffExpand (source,audiosegs[chunk],expanded,audiohuffman,false);\r
+\r
+done:\r
+       if (compressed>BUFFERSIZE)\r
+               MM_FreePtr(MEMPTRANDPERCONV bigbufferseg);\r
+#endif\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+======================\r
+=\r
+= CA_LoadAllSounds\r
+=\r
+= Purges all sounds, then loads all new ones (mode switch)\r
+=\r
+======================\r
+*/\r
+\r
+void CA_LoadAllSounds (void)\r
+{\r
+       unsigned        start,i;\r
+\r
+       switch (oldsoundmode)\r
+       {\r
+       case sdm_Off:\r
+               goto cachein;\r
+       case sdm_PC:\r
+               start = STARTPCSOUNDS;\r
+               break;\r
+       case sdm_AdLib:\r
+               start = STARTADLIBSOUNDS;\r
+               break;\r
+       }\r
+\r
+       for (i=0;i<NUMSOUNDS;i++,start++)\r
+               if (audiosegs[start])\r
+                       MM_SetPurge (MEMPTRCONV audiosegs[start],3);            // make purgable\r
+\r
+cachein:\r
+\r
+       switch (SoundMode)\r
+       {\r
+       case sdm_Off:\r
+               return;\r
+       case sdm_PC:\r
+               start = STARTPCSOUNDS;\r
+               break;\r
+       case sdm_AdLib:\r
+               start = STARTADLIBSOUNDS;\r
+               break;\r
+       }\r
+\r
+       for (i=0;i<NUMSOUNDS;i++,start++)\r
+               CA_CacheAudioChunk (start);\r
+\r
+       oldsoundmode = SoundMode;\r
+}\r
+\r
+//===========================================================================\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= CAL_ExpandGrChunk\r
+=\r
+= Does whatever is needed with a pointer to a compressed chunk\r
+=\r
+======================\r
+*/\r
+\r
+void CAL_ExpandGrChunk (int chunk, byte far *source)\r
+{\r
+       long    expanded;\r
+\r
+\r
+       if (chunk >= STARTTILE8 && chunk < STARTEXTERNS)\r
+       {\r
+       //\r
+       // expanded sizes of tile8/16/32 are implicit\r
+       //\r
+\r
+#define BLOCK          64\r
+#define MASKBLOCK      128\r
+\r
+               if (chunk<STARTTILE8M)                  // tile 8s are all in one chunk!\r
+                       expanded = BLOCK*NUMTILE8;\r
+               else if (chunk<STARTTILE16)\r
+                       expanded = MASKBLOCK*NUMTILE8M;\r
+               else if (chunk<STARTTILE16M)    // all other tiles are one/chunk\r
+                       expanded = BLOCK*4;\r
+               else if (chunk<STARTTILE32)\r
+                       expanded = MASKBLOCK*4;\r
+               else if (chunk<STARTTILE32M)\r
+                       expanded = BLOCK*16;\r
+               else\r
+                       expanded = MASKBLOCK*16;\r
+       }\r
+       else\r
+       {\r
+       //\r
+       // everything else has an explicit size longword\r
+       //\r
+               expanded = *(long far *)source;\r
+               source += 4;                    // skip over length\r
+       }\r
+\r
+//\r
+// allocate final space, decompress it, and free bigbuffer\r
+// Sprites need to have shifts made and various other junk\r
+//\r
+       MM_GetPtr (&grsegs[chunk],expanded);\r
+       if (mmerror)\r
+               return;\r
+       CAL_HuffExpand (source,grsegs[chunk],expanded,grhuffman,false);\r
+}\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= CA_CacheGrChunk\r
+=\r
+= Makes sure a given chunk is in memory, loadiing it if needed\r
+=\r
+======================\r
+*/\r
+\r
+void CA_CacheGrChunk (int chunk)\r
+{\r
+       long    pos,compressed;\r
+       memptr  bigbufferseg;\r
+       byte    far *source;\r
+       int             next;\r
+\r
+       grneeded[chunk] |= ca_levelbit;         // make sure it doesn't get removed\r
+       if (grsegs[chunk])\r
+       {\r
+               MM_SetPurge (&grsegs[chunk],0);\r
+               return;                                                 // allready in memory\r
+       }\r
+\r
+//\r
+// load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
+// a larger buffer\r
+//\r
+       pos = GRFILEPOS(chunk);\r
+       if (pos<0)                                                      // $FFFFFFFF start is a sparse tile\r
+         return;\r
+\r
+       next = chunk +1;\r
+       while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
+               next++;\r
+\r
+       compressed = GRFILEPOS(next)-pos;\r
+\r
+       lseek(grhandle,pos,SEEK_SET);\r
+\r
+       if (compressed<=BUFFERSIZE)\r
+       {\r
+               CA_FarRead(grhandle,bufferseg,compressed);\r
+               source = bufferseg;\r
+       }\r
+       else\r
+       {\r
+               MM_GetPtr(MEMPTRANDPERCONV bigbufferseg,compressed);\r
+               MM_SetLock (MEMPTRANDPERCONV bigbufferseg,true);\r
+               CA_FarRead(grhandle,bigbufferseg,compressed);\r
+               source = bigbufferseg;\r
+       }\r
+\r
+       CAL_ExpandGrChunk (chunk,source);\r
+\r
+       if (compressed>BUFFERSIZE)\r
+               MM_FreePtr(MEMPTRANDPERCONV bigbufferseg);\r
+}\r
+\r
+\r
+\r
+//==========================================================================\r
+\r
+/*\r
+======================\r
+=\r
+= CA_CacheScreen\r
+=\r
+= Decompresses a chunk from disk straight onto the screen\r
+=\r
+======================\r
+*/\r
+\r
+void CA_CacheScreen (int chunk)\r
+{\r
+       long    pos,compressed,expanded;\r
+       memptr  bigbufferseg;\r
+       byte    far *source;\r
+       int             next;\r
+\r
+//\r
+// load the chunk into a buffer\r
+//\r
+       pos = GRFILEPOS(chunk);\r
+       next = chunk +1;\r
+       while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
+               next++;\r
+       compressed = GRFILEPOS(next)-pos;\r
+\r
+       lseek(grhandle,pos,SEEK_SET);\r
+\r
+       MM_GetPtr(MEMPTRANDPERCONV bigbufferseg,compressed);\r
+       MM_SetLock (MEMPTRANDPERCONV bigbufferseg,true);\r
+       CA_FarRead(grhandle,bigbufferseg,compressed);\r
+       source = bigbufferseg;\r
+\r
+       expanded = *(long far *)source;\r
+       source += 4;                    // skip over length\r
+\r
+//\r
+// allocate final space, decompress it, and free bigbuffer\r
+// Sprites need to have shifts made and various other junk\r
+//\r
+       CAL_HuffExpand (source,MK_FP(SCREENSEG,bufferofs),expanded,grhuffman,true);\r
+       VW_MarkUpdateBlock (0,0,319,199);\r
+       MM_FreePtr(MEMPTRANDPERCONV bigbufferseg);\r
+}\r
+\r
+//==========================================================================\r
+\r
+/*\r
+======================\r
+=\r
+= CA_CacheMap\r
+=\r
+= WOLF: This is specialized for a 64*64 map size\r
+=\r
+======================\r
+*/\r
+\r
+void CA_CacheMap (int mapnum)\r
+{\r
+       long    pos,compressed;\r
+       int             plane;\r
+       memptr  *dest,bigbufferseg;\r
+       unsigned        size;\r
+       unsigned        far     *source;\r
+#ifdef CARMACIZED\r
+       memptr  buffer2seg;\r
+       long    expanded;\r
+#endif\r
+\r
+       mapon = mapnum;\r
+\r
+//\r
+// load the planes into the allready allocated buffers\r
+//\r
+       size = 64*64*2;\r
+\r
+       for (plane = 0; plane<MAPPLANES; plane++)\r
+       {\r
+               pos = mapheaderseg[mapnum]->planestart[plane];\r
+               compressed = mapheaderseg[mapnum]->planelength[plane];\r
+\r
+               dest = MEMPTRCONV mapsegs[plane];\r
+\r
+               lseek(maphandle,pos,SEEK_SET);\r
+               if (compressed<=BUFFERSIZE)\r
+                       source = bufferseg;\r
+               else\r
+               {\r
+                       MM_GetPtr(MEMPTRANDPERCONV bigbufferseg,compressed);\r
+                       MM_SetLock (MEMPTRANDPERCONV bigbufferseg,true);\r
+                       source = bigbufferseg;\r
+               }\r
+\r
+               CA_FarRead(maphandle,(byte far *)source,compressed);\r
+#ifdef CARMACIZED\r
+               //\r
+               // unhuffman, then unRLEW\r
+               // The huffman'd chunk has a two byte expanded length first\r
+               // The resulting RLEW chunk also does, even though it's not really\r
+               // needed\r
+               //\r
+               expanded = *source;\r
+               source++;\r
+               MM_GetPtr (MEMPTRANDPERCONV buffer2seg,expanded);\r
+               CAL_CarmackExpand (source, (unsigned far *)buffer2seg,expanded);\r
+               CA_RLEWexpand (((unsigned far *)buffer2seg)+1,*dest,size,\r
+               ((mapfiletype _seg *)tinf)->RLEWtag);\r
+               MM_FreePtr (MEMPTRANDPERCONV buffer2seg);\r
+\r
+#else\r
+               //\r
+               // unRLEW, skipping expanded length\r
+               //\r
+               CA_RLEWexpand (source+1, *dest,size,\r
+               ((mapfiletype _seg *)tinf)->RLEWtag);\r
+#endif\r
+\r
+               if (compressed>BUFFERSIZE)\r
+                       MM_FreePtr(MEMPTRANDPERCONV bigbufferseg);\r
+       }\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+======================\r
+=\r
+= CA_UpLevel\r
+=\r
+= Goes up a bit level in the needed lists and clears it out.\r
+= Everything is made purgable\r
+=\r
+======================\r
+*/\r
+\r
+void CA_UpLevel (void)\r
+{\r
+       int     i;\r
+\r
+       if (ca_levelnum==7)\r
+               Quit ("CA_UpLevel: Up past level 7!");\r
+\r
+       for (i=0;i<NUMCHUNKS;i++)\r
+               if (grsegs[i])\r
+                       MM_SetPurge (MEMPTRCONV grsegs[i],3);\r
+       ca_levelbit<<=1;\r
+       ca_levelnum++;\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+======================\r
+=\r
+= CA_DownLevel\r
+=\r
+= Goes down a bit level in the needed lists and recaches\r
+= everything from the lower level\r
+=\r
+======================\r
+*/\r
+\r
+void CA_DownLevel (void)\r
+{\r
+       if (!ca_levelnum)\r
+               Quit ("CA_DownLevel: Down past level 0!");\r
+       ca_levelbit>>=1;\r
+       ca_levelnum--;\r
+       CA_CacheMarks();\r
+}\r
+\r
+//===========================================================================\r
+\r
+/*\r
+======================\r
+=\r
+= CA_ClearMarks\r
+=\r
+= Clears out all the marks at the current level\r
+=\r
+======================\r
+*/\r
+\r
+void CA_ClearMarks (void)\r
+{\r
+       int i;\r
+\r
+       for (i=0;i<NUMCHUNKS;i++)\r
+               grneeded[i]&=~ca_levelbit;\r
+}\r
+\r
+\r
+//===========================================================================\r
+\r
+/*\r
+======================\r
+=\r
+= CA_ClearAllMarks\r
+=\r
+= Clears out all the marks on all the levels\r
+=\r
+======================\r
+*/\r
+\r
+void CA_ClearAllMarks (void)\r
+{\r
+       _fmemset (grneeded,0,sizeof(grneeded));\r
+       ca_levelbit = 1;\r
+       ca_levelnum = 0;\r
+}\r
+\r
+\r
+//===========================================================================\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= CA_FreeGraphics\r
+=\r
+======================\r
+*/\r
+\r
+\r
+void CA_SetGrPurge (void)\r
+{\r
+       int i;\r
+\r
+//\r
+// free graphics\r
+//\r
+       CA_ClearMarks ();\r
+\r
+       for (i=0;i<NUMCHUNKS;i++)\r
+               if (grsegs[i])\r
+                       MM_SetPurge (MEMPTRCONV grsegs[i],3);\r
+}\r
+\r
+\r
+\r
+/*\r
+======================\r
+=\r
+= CA_SetAllPurge\r
+=\r
+= Make everything possible purgable\r
+=\r
+======================\r
+*/\r
+\r
+void CA_SetAllPurge (void)\r
+{\r
+       int i;\r
+\r
+\r
+//\r
+// free sounds\r
+//\r
+       for (i=0;i<NUMSNDCHUNKS;i++)\r
+               if (audiosegs[i])\r
+                       MM_SetPurge (MEMPTRCONV audiosegs[i],3);\r
+\r
+//\r
+// free graphics\r
+//\r
+       CA_SetGrPurge ();\r
+}\r
+\r
+\r
+//===========================================================================\r
+\r
+/*\r
+======================\r
+=\r
+= CA_CacheMarks\r
+=\r
+======================\r
+*/\r
+#define MAXEMPTYREAD   1024\r
+\r
+void CA_CacheMarks (void)\r
+{\r
+       int     i,next,numcache;\r
+       long    pos,endpos,nextpos,nextendpos,compressed;\r
+       long    bufferstart,bufferend;  // file position of general buffer\r
+       byte    far *source;\r
+       memptr  bigbufferseg;\r
+\r
+       numcache = 0;\r
+//\r
+// go through and make everything not needed purgable\r
+//\r
+       for (i=0;i<NUMCHUNKS;i++)\r
+               if (grneeded[i]&ca_levelbit)\r
+               {\r
+                       if (grsegs[i])                                  // its allready in memory, make\r
+                               MM_SetPurge(&grsegs[i],0);      // sure it stays there!\r
+                       else\r
+                               numcache++;\r
+               }\r
+               else\r
+               {\r
+                       if (grsegs[i])                                  // not needed, so make it purgeable\r
+                               MM_SetPurge(&grsegs[i],3);\r
+               }\r
+\r
+       if (!numcache)                  // nothing to cache!\r
+               return;\r
+\r
+\r
+//\r
+// go through and load in anything still needed\r
+//\r
+       bufferstart = bufferend = 0;            // nothing good in buffer now\r
+\r
+       for (i=0;i<NUMCHUNKS;i++)\r
+               if ( (grneeded[i]&ca_levelbit) && !grsegs[i])\r
+               {\r
+                       pos = GRFILEPOS(i);\r
+                       if (pos<0)\r
+                               continue;\r
+\r
+                       next = i +1;\r
+                       while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
+                               next++;\r
+\r
+                       compressed = GRFILEPOS(next)-pos;\r
+                       endpos = pos+compressed;\r
+\r
+                       if (compressed<=BUFFERSIZE)\r
+                       {\r
+                               if (bufferstart<=pos\r
+                               && bufferend>= endpos)\r
+                               {\r
+                               // data is allready in buffer\r
+                                       source = (byte _seg *)bufferseg+(pos-bufferstart);\r
+                               }\r
+                               else\r
+                               {\r
+                               // load buffer with a new block from disk\r
+                               // try to get as many of the needed blocks in as possible\r
+                                       while ( next < NUMCHUNKS )\r
+                                       {\r
+                                               while (next < NUMCHUNKS &&\r
+                                               !(grneeded[next]&ca_levelbit && !grsegs[next]))\r
+                                                       next++;\r
+                                               if (next == NUMCHUNKS)\r
+                                                       continue;\r
+\r
+                                               nextpos = GRFILEPOS(next);\r
+                                               while (GRFILEPOS(++next) == -1) // skip past any sparse tiles\r
+                                                       ;\r
+                                               nextendpos = GRFILEPOS(next);\r
+                                               if (nextpos - endpos <= MAXEMPTYREAD\r
+                                               && nextendpos-pos <= BUFFERSIZE)\r
+                                                       endpos = nextendpos;\r
+                                               else\r
+                                                       next = NUMCHUNKS;                       // read pos to posend\r
+                                       }\r
+\r
+                                       lseek(grhandle,pos,SEEK_SET);\r
+                                       CA_FarRead(grhandle,bufferseg,endpos-pos);\r
+                                       bufferstart = pos;\r
+                                       bufferend = endpos;\r
+                                       source = bufferseg;\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                       // big chunk, allocate temporary buffer\r
+                               MM_GetPtr(MEMPTRANDPERCONV bigbufferseg,compressed);\r
+                               if (mmerror)\r
+                                       return;\r
+                               MM_SetLock (MEMPTRANDPERCONV bigbufferseg,true);\r
+                               lseek(grhandle,pos,SEEK_SET);\r
+                               CA_FarRead(grhandle,bigbufferseg,compressed);\r
+                               source = bigbufferseg;\r
+                       }\r
+\r
+                       CAL_ExpandGrChunk (i,source);\r
+                       if (mmerror)\r
+                               return;\r
+\r
+                       if (compressed>BUFFERSIZE)\r
+                               MM_FreePtr(MEMPTRANDPERCONV bigbufferseg);\r
+\r
+               }\r
+}\r
+\r
+void CA_CannotOpen(char *string)\r
+{\r
+ char str[30];\r
+\r
+ strcpy(str,"Can't open ");\r
+ strcat(str,string);\r
+ strcat(str,"!\n");\r
+ Quit (str);\r
+}\r
index 143a5f4de2f0ffa2221c911899cb9f3c7299b2ac..33c5dcc7152a6e3d5e949734248388ecdd1c4908 100755 (executable)
@@ -23,7 +23,7 @@
 #include <malloc.h>\r
 \r
 #define DUMP\r
-#define DUMP_MAP\r
+//#define DUMP_MAP\r
 \r
 void\r
 main(int argc, char *argv[])\r
@@ -48,7 +48,7 @@ main(int argc, char *argv[])
 \r
        fprintf(stderr, fmt, _memavl());\r
        fprintf(stderr, fmt0, _memmax());\r
-       fprintf(stderr, "Size of map var = %u\n", _msize(&(gvar.ca.mapsegs)));\r
+       fprintf(stderr, "Size of map var = %u\n", _msize(&(gvar.ca.MAPSEGPTR)));\r
 \r
        CA_loadmap("data/test.map", &map, &gvar);\r
 #ifdef DUMP\r
@@ -72,7 +72,7 @@ main(int argc, char *argv[])
                getch();\r
        }\r
 #else\r
-       //fprintf(stderr, "contents of the buffer\n[\n%s\n]\n", (gvar.ca.mapsegs));\r
+       fprintf(stderr, "contents of the buffer\n[\n%s\n]\n", (gvar.ca.MAPSEGPTR));\r
 #endif\r
        /*fprintf(stdout, "&main()=%Fp\n", *argv[0]);\r
        fprintf(stdout, "&map==%Fp\n", &map);\r
@@ -82,7 +82,7 @@ main(int argc, char *argv[])
        fprintf(stdout, "&map.data==%Fp\n", map.data);*/\r
 #endif\r
        //fprintf(stderr, "here comes dat boi!\n"); getch(); fprintf(stderr, "%s", datboi);\r
-       MM_FreePtr((memptr *)&(gvar.ca.mapsegs), &gvar);\r
+       MM_FreePtr(MEMPTRCONV (gvar.ca.MAPSEGPTR), &gvar);\r
        PM_Shutdown(&gvar);\r
        CA_Shutdown(&gvar);\r
        MM_Shutdown(&gvar);\r