]> 4ch.mooo.com Git - 16.git/blob - src/lib/16_ca.c
^^ yay! i polished exmmtest and the memory reporter
[16.git] / src / lib / 16_ca.c
1 /* Catacomb Apocalypse Source Code\r
2  * Copyright (C) 1993-2014 Flat Rock Software\r
3  *\r
4  * This program is free software; you can redistribute it and/or modify\r
5  * it under the terms of the GNU General Public License as published by\r
6  * the Free Software Foundation; either version 2 of the License, or\r
7  * (at your option) any later version.\r
8  *\r
9  * This program is distributed in the hope that it will be useful,\r
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
12  * GNU General Public License for more details.\r
13  *\r
14  * You should have received a copy of the GNU General Public License along\r
15  * with this program; if not, write to the Free Software Foundation, Inc.,\r
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
17  */\r
18 \r
19 // ID_CA.C\r
20 \r
21 /*\r
22 =============================================================================\r
23 \r
24 Id Software Caching Manager\r
25 ---------------------------\r
26 \r
27 Must be started BEFORE the memory manager, because it needs to get the headers\r
28 loaded into the data segment\r
29 \r
30 =============================================================================\r
31 */\r
32 \r
33 #include "src/lib/16_ca.h"\r
34 #pragma hdrstop\r
35 \r
36 #pragma warn -pro\r
37 #pragma warn -use\r
38 \r
39 //#define THREEBYTEGRSTARTS\r
40 \r
41 /*\r
42 =============================================================================\r
43 \r
44                                                  LOCAL CONSTANTS\r
45 \r
46 =============================================================================\r
47 */\r
48 \r
49 typedef struct\r
50 {\r
51   word bit0,bit1;       // 0-255 is a character, > is a pointer to a node\r
52 } huffnode;\r
53 \r
54 \r
55 /*typedef struct\r
56 {\r
57         unsigned        RLEWtag;\r
58         long            headeroffsets[100];\r
59         byte            tileinfo[];\r
60 } mapfiletype;*/\r
61 \r
62 \r
63 /*\r
64 =============================================================================\r
65 \r
66                                                  GLOBAL VARIABLES\r
67 \r
68 =============================================================================\r
69 */\r
70 \r
71 /*byte          _seg    *tinf;\r
72 int                     mapon;\r
73 \r
74 unsigned        _seg    *mapsegs[3];\r
75 maptype         _seg    *mapheaderseg[NUMMAPS];\r
76 byte            _seg    *audiosegs[NUMSNDCHUNKS];\r
77 void            _seg    *grsegs[NUMCHUNKS];\r
78 \r
79 byte            far     grneeded[NUMCHUNKS];*/\r
80 \r
81 void    (*drawcachebox)         (char *title, unsigned numcache);\r
82 void    (*updatecachebox)       (void);\r
83 void    (*finishcachebox)       (void);\r
84 \r
85 /*\r
86 =============================================================================\r
87 \r
88                                                  LOCAL VARIABLES\r
89 \r
90 =============================================================================\r
91 */\r
92 \r
93 /*extern        long    far     CGAhead;\r
94 extern  long    far     EGAhead;\r
95 extern  byte    CGAdict;\r
96 extern  byte    EGAdict;\r
97 extern  byte    far     maphead;\r
98 extern  byte    mapdict;\r
99 extern  byte    far     audiohead;\r
100 extern  byte    audiodict;\r
101 \r
102 \r
103 long            _seg *grstarts; // array of offsets in egagraph, -1 for sparse\r
104 long            _seg *audiostarts;      // array of offsets in audio / audiot\r
105 \r
106 #ifdef GRHEADERLINKED\r
107 huffnode        *grhuffman;\r
108 #else\r
109 huffnode        grhuffman[255];\r
110 #endif\r
111 \r
112 #ifdef AUDIOHEADERLINKED\r
113 huffnode        *audiohuffman;\r
114 #else\r
115 huffnode        audiohuffman[255];\r
116 #endif\r
117 \r
118 \r
119 int                     grhandle;               // handle to EGAGRAPH\r
120 int                     maphandle;              // handle to MAPTEMP / GAMEMAPS\r
121 int                     audiohandle;    // handle to AUDIOT / AUDIO\r
122 \r
123 long            chunkcomplen,chunkexplen;\r
124 \r
125 SDMode          oldsoundmode;\r
126 \r
127 \r
128 \r
129 void    CAL_DialogDraw (char *title,unsigned numcache);\r
130 void    CAL_DialogUpdate (void);\r
131 void    CAL_DialogFinish (void);*/\r
132 //void  CAL_CarmackExpand (unsigned far *source, unsigned far *dest,unsigned length);\r
133 \r
134 \r
135 /*++++#ifdef THREEBYTEGRSTARTS\r
136 #define FILEPOSSIZE     3\r
137 //#define       GRFILEPOS(c) (*(long far *)(((byte far *)grstarts)+(c)*3)&0xffffff)\r
138 long GRFILEPOS(int c)\r
139 {\r
140         long value;\r
141         int     offset;\r
142 \r
143         offset = c*3;\r
144 \r
145         value = *(long far *)(((byte far *)grstarts)+offset);\r
146 \r
147         value &= 0x00ffffffl;\r
148 \r
149         if (value == 0xffffffl)\r
150                 value = -1;\r
151 \r
152         return value;\r
153 };\r
154 #else\r
155 #define FILEPOSSIZE     4\r
156 #define GRFILEPOS(c) (grstarts[c])\r
157 #endif*/\r
158 \r
159 /*\r
160 =============================================================================\r
161 \r
162                                            LOW LEVEL ROUTINES\r
163 \r
164 =============================================================================\r
165 */\r
166 \r
167 /*\r
168 ============================\r
169 =\r
170 = CA_OpenDebug / CA_CloseDebug\r
171 =\r
172 = Opens a binary file with the handle "debughandle"\r
173 =\r
174 ============================\r
175 */\r
176 void CA_OpenDebug(global_game_variables_t *gvar)\r
177 {\r
178 #ifdef __BORLANDC__\r
179         unlink("debug.16b");\r
180         gvar->handle.debughandle = open("debug.16b", O_CREAT | O_WRONLY | O_TEXT);\r
181 #endif\r
182 #ifdef __WATCOMC__\r
183         unlink("debug.16w");\r
184         gvar->handle.debughandle = open("debug.16w", O_CREAT | O_WRONLY | O_TEXT);\r
185 #endif\r
186 }\r
187 \r
188 void CA_CloseDebug(global_game_variables_t *gvar)\r
189 {\r
190         close(gvar->handle.debughandle);\r
191 }\r
192 \r
193 \r
194 \r
195 /*\r
196 ============================\r
197 =\r
198 = CAL_GetGrChunkLength\r
199 =\r
200 = Gets the length of an explicit length chunk (not tiles)\r
201 = The file pointer is positioned so the compressed data can be read in next.\r
202 =\r
203 ============================\r
204 */\r
205 /*++++\r
206 void CAL_GetGrChunkLength (int chunk)\r
207 {\r
208         lseek(grhandle,GRFILEPOS(chunk),SEEK_SET);\r
209         read(grhandle,&chunkexplen,sizeof(chunkexplen));\r
210         chunkcomplen = GRFILEPOS(chunk+1)-GRFILEPOS(chunk)-4;\r
211 }*/\r
212 \r
213 \r
214 /*\r
215 ==========================\r
216 =\r
217 = CA_FarRead\r
218 =\r
219 = Read from a file to a far pointer\r
220 =\r
221 ==========================\r
222 */\r
223 \r
224 boolean CA_FarRead(int handle, byte huge *dest, dword length, mminfo_t *mm)\r
225 {\r
226         boolean flag;\r
227         //dword fat=0;\r
228         //word segm=0;\r
229         if(mm->EMSVer<0x40)\r
230         if(length>0xfffflu)\r
231         {\r
232                 printf("File is a fat bakapee\n");\r
233                 //segm=(length%0xfffflu)-1;\r
234                 //fat=segm*0xfffflu;\r
235                 //length-=fat;\r
236                 printf("CA_FarRead doesn't support 64K reads yet!\n");\r
237                 return 0;//TODO: EXPAND!!!\r
238         }\r
239 \r
240         //if(!fat&&!segm)\r
241         //{\r
242                 __asm {\r
243                         push    ds\r
244                         mov     bx,[handle]\r
245                         mov     cx,[WORD PTR length]\r
246                         mov     dx,[WORD PTR dest]\r
247                         mov     ds,[WORD PTR dest+2]\r
248                         mov     ah,0x3f                         // READ w/handle\r
249                         int     21h\r
250                         pop     ds\r
251                         jnc     good\r
252                         mov     errno,ax\r
253                         mov     flag,0\r
254                         jmp End\r
255 #ifdef __BORLANDC__\r
256                 }\r
257 #endif\r
258 good:\r
259 #ifdef __BORLANDC__\r
260                 __asm {\r
261 #endif\r
262                         cmp     ax,[WORD PTR length]\r
263                         je      done\r
264 //                      errno = EINVFMT;                        // user manager knows this is bad read\r
265                         mov     flag,0\r
266                         jmp End\r
267 #ifdef __BORLANDC__\r
268                 }\r
269 #endif\r
270 done:\r
271 #ifdef __BORLANDC__\r
272                 __asm {\r
273 #endif\r
274                         mov     flag,1\r
275 #ifdef __BORLANDC__\r
276                 }\r
277 #endif\r
278 End:\r
279 #ifdef __WATCOMC__\r
280                 }\r
281 #endif\r
282         return flag;\r
283 }\r
284 \r
285 \r
286 /*\r
287 ==========================\r
288 =\r
289 = CA_SegWrite\r
290 =\r
291 = Write from a file to a far pointer\r
292 =\r
293 ==========================\r
294 */\r
295 \r
296 boolean CA_FarWrite(int handle, byte huge *source, dword length, mminfo_t *mm)\r
297 {\r
298         boolean flag;\r
299         //dword fat=0;\r
300         //word segm=0;\r
301         if(mm->EMSVer<0x40)\r
302         if(length>0xfffflu)\r
303         {\r
304                 printf("File is a fat bakapee\n");\r
305                 //segm=(length%0xfffflu)-1;\r
306                 //fat=segm*0xfffflu;\r
307                 //length-=fat;\r
308                 printf("CA_FarRead doesn't support 64K reads yet!\n");\r
309                 return 0;\r
310         }\r
311 \r
312         //if(!fat&&!segm)\r
313         //{\r
314                 __asm {\r
315                         push    ds\r
316                         mov     bx,[handle]\r
317                         mov     cx,[WORD PTR length]\r
318                         mov     dx,[WORD PTR source]\r
319                         mov     ds,[WORD PTR source+2]\r
320                         mov     ah,0x40                 // WRITE w/handle\r
321                         int     21h\r
322                         pop     ds\r
323                         jnc     good\r
324                         mov     errno,ax\r
325                         mov flag,0\r
326                         jmp End\r
327 #ifdef __BORLANDC__\r
328                 }\r
329 #endif\r
330 good:\r
331 #ifdef __BORLANDC__\r
332                 __asm {\r
333 #endif\r
334                         cmp     ax,[WORD PTR length]\r
335                         je      done\r
336                         //errno = ENOMEM;                               // user manager knows this is bad write\r
337                         mov     flag,0\r
338                         jmp End\r
339 #ifdef __BORLANDC__\r
340                 }\r
341 #endif\r
342 done:\r
343 #ifdef __BORLANDC__\r
344                 __asm {\r
345 #endif\r
346                         mov     flag,1\r
347 #ifdef __BORLANDC__\r
348                 }\r
349 #endif\r
350 End:\r
351 #ifdef __WATCOMC__\r
352                 }\r
353 #endif\r
354         return flag;\r
355 }\r
356 \r
357 \r
358 /*\r
359 ==========================\r
360 =\r
361 = CA_ReadFile\r
362 =\r
363 = Reads a file into an allready allocated buffer\r
364 =\r
365 ==========================\r
366 */\r
367 \r
368 boolean CA_ReadFile(char *filename, memptr *ptr, mminfo_t *mm)\r
369 {\r
370         int handle;\r
371         sdword size;\r
372         //long size;\r
373 \r
374         if((handle = open(filename,O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
375                 return false;\r
376 \r
377         size = filelength(handle);\r
378         if(!CA_FarRead(handle,*ptr,size, mm))\r
379         {\r
380                 close (handle);\r
381                 return false;\r
382         }\r
383         close (handle);\r
384         return true;\r
385 }\r
386 \r
387 \r
388 /*\r
389 ==========================\r
390 =\r
391 = CA_WriteFile\r
392 =\r
393 = Writes a file from a memory buffer\r
394 =\r
395 ==========================\r
396 */\r
397 \r
398 boolean CA_WriteFile (char *filename, void far *ptr, long length, mminfo_t *mm)\r
399 {\r
400         int handle;\r
401         sdword size;\r
402         //long size;\r
403 \r
404         handle = open(filename,O_CREAT | O_BINARY | O_WRONLY,\r
405                                 S_IREAD | S_IWRITE | S_IFREG);\r
406 \r
407         if (handle == -1)\r
408                 return false;\r
409 \r
410         if (!CA_FarWrite (handle,ptr,length, mm))\r
411         {\r
412                 close(handle);\r
413                 return false;\r
414         }\r
415         close(handle);\r
416         return true;\r
417 }\r
418 \r
419 \r
420 \r
421 /*\r
422 ==========================\r
423 =\r
424 = CA_LoadFile\r
425 =\r
426 = Allocate space for and load a file\r
427 =\r
428 ==========================\r
429 */\r
430 \r
431 boolean CA_LoadFile(char *filename, memptr *ptr, mminfo_t *mm, mminfotype *mmi)\r
432 {\r
433         int handle;\r
434         sdword size;\r
435         //long size;\r
436 \r
437         if((handle = open(filename,O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
438                 return false;\r
439 \r
440         size = filelength (handle);\r
441         MM_GetPtr(ptr,size, mm, mmi);\r
442         if(!CA_FarRead(handle,*ptr,size, mm))\r
443         {\r
444                 close(handle);\r
445                 return false;\r
446         }\r
447         close(handle);\r
448         return true;\r
449 }\r
450 \r
451 /*\r
452 ============================================================================\r
453 \r
454                 COMPRESSION routines, see JHUFF.C for more\r
455 \r
456 ============================================================================\r
457 */\r
458 \r
459 \r
460 \r
461 /*\r
462 ===============\r
463 =\r
464 = CAL_OptimizeNodes\r
465 =\r
466 = Goes through a huffman table and changes the 256-511 node numbers to the\r
467 = actular address of the node.  Must be called before CAL_HuffExpand\r
468 =\r
469 ===============\r
470 */\r
471 \r
472 void CAL_OptimizeNodes(huffnode *table)\r
473 {\r
474   huffnode *node;\r
475   int i;\r
476 \r
477   node = table;\r
478 \r
479   for (i=0;i<255;i++)\r
480   {\r
481         if (node->bit0 >= 256)\r
482           node->bit0 = (unsigned)(table+(node->bit0-256));\r
483         if (node->bit1 >= 256)\r
484           node->bit1 = (unsigned)(table+(node->bit1-256));\r
485         node++;\r
486   }\r
487 }\r
488 \r
489 \r
490 \r
491 /*\r
492 ======================\r
493 =\r
494 = CAL_HuffExpand\r
495 =\r
496 = Length is the length of the EXPANDED data\r
497 =\r
498 ======================\r
499 */\r
500 \r
501 void CAL_HuffExpand (byte huge *source, byte huge *dest,\r
502   long length,huffnode *hufftable)\r
503 {\r
504 //  unsigned bit,byte,node,code;\r
505   unsigned sourceseg,sourceoff,destseg,destoff,endoff;\r
506   huffnode *headptr;\r
507 //  huffnode *nodeon;\r
508 \r
509   headptr = hufftable+254;      // head node is allways node 254\r
510 \r
511   source++;     // normalize\r
512   source--;\r
513   dest++;\r
514   dest--;\r
515 \r
516   sourceseg = FP_SEG(source);\r
517   sourceoff = FP_OFF(source);\r
518   destseg = FP_SEG(dest);\r
519   destoff = FP_OFF(dest);\r
520   endoff = destoff+length;\r
521 \r
522 //\r
523 // ds:si source\r
524 // es:di dest\r
525 // ss:bx node pointer\r
526 //\r
527 \r
528         if (length <0xfff0)\r
529         {\r
530 \r
531 //--------------------------\r
532 // expand less than 64k of data\r
533 //--------------------------\r
534 \r
535         __asm\r
536         {\r
537 ;;;;;           mov     bx,[headptr]\r
538 \r
539                 mov     si,[sourceoff]\r
540                 mov     di,[destoff]\r
541                 mov     es,[destseg]\r
542                 mov     ds,[sourceseg]\r
543                 mov     ax,[endoff]\r
544 \r
545                 mov     ch,[si]                         // load first byte\r
546                 inc     si\r
547                 mov     cl,1\r
548 \r
549 expandshort:\r
550                 test    ch,cl                   // bit set?\r
551                 jnz     bit1short\r
552                 mov     dx,[ss:bx]                      // take bit0 path from node\r
553                 shl     cl,1                            // advance to next bit position\r
554                 jc      newbyteshort\r
555                 jnc     sourceupshort\r
556 \r
557 bit1short:\r
558                 mov     dx,[ss:bx+2]            // take bit1 path\r
559                 shl     cl,1                            // advance to next bit position\r
560                 jnc     sourceupshort\r
561 \r
562 newbyteshort:\r
563                 mov     ch,[si]                         // load next byte\r
564                 inc     si\r
565                 mov     cl,1                            // back to first bit\r
566 \r
567 sourceupshort:\r
568                 or      dh,dh                           // if dx<256 its a byte, else move node\r
569                 jz      storebyteshort\r
570                 mov     bx,dx                           // next node = (huffnode *)code\r
571                 jmp     expandshort\r
572 \r
573 storebyteshort:\r
574                 mov     [es:di],dl\r
575                 inc     di                                      // write a decopmpressed byte out\r
576 ;;;;            mov     bx,[headptr]            // back to the head node for next bit\r
577 \r
578                 cmp     di,ax                           // done?\r
579                 jne     expandshort\r
580         }\r
581         }\r
582         else\r
583         {\r
584 \r
585 //--------------------------\r
586 // expand more than 64k of data\r
587 //--------------------------\r
588 \r
589   length--;\r
590 \r
591         __asm\r
592         {\r
593 ;;;;            mov     bx,[headptr]\r
594                 mov     cl,1\r
595 \r
596                 mov     si,[sourceoff]\r
597                 mov     di,[destoff]\r
598                 mov     es,[destseg]\r
599                 mov     ds,[sourceseg]\r
600 \r
601                 lodsb                   // load first byte\r
602 \r
603 expand:\r
604                 test    al,cl           // bit set?\r
605                 jnz     bit1\r
606                 mov     dx,[ss:bx]      // take bit0 path from node\r
607                 jmp     gotcode\r
608 bit1:\r
609                 mov     dx,[ss:bx+2]    // take bit1 path\r
610 \r
611 gotcode:\r
612                 shl     cl,1            // advance to next bit position\r
613                 jnc     sourceup\r
614                 lodsb\r
615                 cmp     si,0x10         // normalize ds:si\r
616                 jb      sinorm\r
617                 mov     cx,ds\r
618                 inc     cx\r
619                 mov     ds,cx\r
620                 xor     si,si\r
621 sinorm:\r
622                 mov     cl,1            // back to first bit\r
623 \r
624 sourceup:\r
625                 or      dh,dh           // if dx<256 its a byte, else move node\r
626                 jz      storebyte\r
627                 mov     bx,dx           // next node = (huffnode *)code\r
628                 jmp     expand\r
629 \r
630 storebyte:\r
631                 mov     [es:di],dl\r
632                 inc     di              // write a decopmpressed byte out\r
633 ;;;;            mov     bx,[headptr]    // back to the head node for next bit\r
634 \r
635                 cmp     di,0x10         // normalize es:di\r
636                 jb      dinorm\r
637                 mov     dx,es\r
638                 inc     dx\r
639                 mov     es,dx\r
640                 xor     di,di\r
641 dinorm:\r
642 \r
643                 sub     [WORD PTR ss:length],1\r
644                 jnc     expand\r
645                 dec     [WORD PTR ss:length+2]\r
646                 jns     expand          // when length = ffff ffff, done\r
647         }\r
648         }\r
649 \r
650         __asm\r
651         {\r
652                 mov     ax,ss\r
653                 mov     ds,ax\r
654         }\r
655 \r
656 }\r
657 \r
658 \r
659 /*\r
660 ======================\r
661 =\r
662 = CAL_CarmackExpand\r
663 =\r
664 = Length is the length of the EXPANDED data\r
665 =\r
666 ======================\r
667 */\r
668 /*++++\r
669 #define NEARTAG 0xa7\r
670 #define FARTAG  0xa8\r
671 \r
672 void CAL_CarmackExpand (unsigned far *source, unsigned far *dest, unsigned length)\r
673 {\r
674         unsigned        ch,chhigh,count,offset;\r
675         unsigned        far *copyptr, far *inptr, far *outptr;\r
676 \r
677         length/=2;\r
678 \r
679         inptr = source;\r
680         outptr = dest;\r
681 \r
682         while (length)\r
683         {\r
684                 ch = *inptr++;\r
685                 chhigh = ch>>8;\r
686                 if (chhigh == NEARTAG)\r
687                 {\r
688                         count = ch&0xff;\r
689                         if (!count)\r
690                         {                               // have to insert a word containing the tag byte\r
691                                 ch |= *((unsigned char far *)inptr)++;\r
692                                 *outptr++ = ch;\r
693                                 length--;\r
694                         }\r
695                         else\r
696                         {\r
697                                 offset = *((unsigned char far *)inptr)++;\r
698                                 copyptr = outptr - offset;\r
699                                 length -= count;\r
700                                 while (count--)\r
701                                         *outptr++ = *copyptr++;\r
702                         }\r
703                 }\r
704                 else if (chhigh == FARTAG)\r
705                 {\r
706                         count = ch&0xff;\r
707                         if (!count)\r
708                         {                               // have to insert a word containing the tag byte\r
709                                 ch |= *((unsigned char far *)inptr)++;\r
710                                 *outptr++ = ch;\r
711                                 length --;\r
712                         }\r
713                         else\r
714                         {\r
715                                 offset = *inptr++;\r
716                                 copyptr = dest + offset;\r
717                                 length -= count;\r
718                                 while (count--)\r
719                                         *outptr++ = *copyptr++;\r
720                         }\r
721                 }\r
722                 else\r
723                 {\r
724                         *outptr++ = ch;\r
725                         length --;\r
726                 }\r
727         }\r
728 }\r
729 */\r
730 \r
731 \r
732 /*\r
733 ======================\r
734 =\r
735 = CA_RLEWcompress\r
736 =\r
737 ======================\r
738 */\r
739 /*++++\r
740 long CA_RLEWCompress (unsigned huge *source, long length, unsigned huge *dest,\r
741   unsigned rlewtag)\r
742 {\r
743   long complength;\r
744   unsigned value,count,i;\r
745   unsigned huge *start,huge *end;\r
746 \r
747   start = dest;\r
748 \r
749   end = source + (length+1)/2;\r
750 \r
751 //\r
752 // compress it\r
753 //\r
754   do\r
755   {\r
756         count = 1;\r
757         value = *source++;\r
758         while (*source == value && source<end)\r
759         {\r
760           count++;\r
761           source++;\r
762         }\r
763         if (count>3 || value == rlewtag)\r
764         {\r
765     //\r
766     // send a tag / count / value string\r
767     //\r
768       *dest++ = rlewtag;\r
769       *dest++ = count;\r
770       *dest++ = value;\r
771     }\r
772     else\r
773     {\r
774     //\r
775     // send word without compressing\r
776     //\r
777       for (i=1;i<=count;i++)\r
778         *dest++ = value;\r
779         }\r
780 \r
781   } while (source<end);\r
782 \r
783   complength = 2*(dest-start);\r
784   return complength;\r
785 }\r
786 */\r
787 \r
788 /*\r
789 ======================\r
790 =\r
791 = CA_RLEWexpand\r
792 = length is EXPANDED length\r
793 =\r
794 ======================\r
795 */\r
796 /*++++\r
797 void CA_RLEWexpand (unsigned huge *source, unsigned huge *dest,long length,\r
798   unsigned rlewtag)\r
799 {\r
800 //  unsigned value,count,i;\r
801   unsigned huge *end;\r
802   unsigned sourceseg,sourceoff,destseg,destoff,endseg,endoff;\r
803 \r
804 \r
805 //\r
806 // expand it\r
807 //\r
808 #if 0\r
809   do\r
810   {\r
811         value = *source++;\r
812         if (value != rlewtag)\r
813         //\r
814         // uncompressed\r
815         //\r
816           *dest++=value;\r
817         else\r
818         {\r
819         //\r
820         // compressed string\r
821         //\r
822           count = *source++;\r
823           value = *source++;\r
824           for (i=1;i<=count;i++)\r
825         *dest++ = value;\r
826         }\r
827   } while (dest<end);\r
828 #endif\r
829 \r
830   end = dest + (length)/2;\r
831   sourceseg = FP_SEG(source);\r
832   sourceoff = FP_OFF(source);\r
833   destseg = FP_SEG(dest);\r
834   destoff = FP_OFF(dest);\r
835   endseg = FP_SEG(end);\r
836   endoff = FP_OFF(end);\r
837 \r
838 \r
839 //\r
840 // ax = source value\r
841 // bx = tag value\r
842 // cx = repeat counts\r
843 // dx = scratch\r
844 //\r
845 // NOTE: A repeat count that produces 0xfff0 bytes can blow this!\r
846 //\r
847 \r
848 asm     mov     bx,rlewtag\r
849 asm     mov     si,sourceoff\r
850 asm     mov     di,destoff\r
851 asm     mov     es,destseg\r
852 asm     mov     ds,sourceseg\r
853 \r
854 expand:\r
855 asm     lodsw\r
856 asm     cmp     ax,bx\r
857 asm     je      repeat\r
858 asm     stosw\r
859 asm     jmp     next\r
860 \r
861 repeat:\r
862 asm     lodsw\r
863 asm     mov     cx,ax           // repeat count\r
864 asm     lodsw                   // repeat value\r
865 asm     rep stosw\r
866 \r
867 next:\r
868 \r
869 asm     cmp     si,0x10         // normalize ds:si\r
870 asm     jb      sinorm\r
871 asm     mov     ax,si\r
872 asm     shr     ax,1\r
873 asm     shr     ax,1\r
874 asm     shr     ax,1\r
875 asm     shr     ax,1\r
876 asm     mov     dx,ds\r
877 asm     add     dx,ax\r
878 asm     mov     ds,dx\r
879 asm     and     si,0xf\r
880 sinorm:\r
881 asm     cmp     di,0x10         // normalize es:di\r
882 asm     jb      dinorm\r
883 asm     mov     ax,di\r
884 asm     shr     ax,1\r
885 asm     shr     ax,1\r
886 asm     shr     ax,1\r
887 asm     shr     ax,1\r
888 asm     mov     dx,es\r
889 asm     add     dx,ax\r
890 asm     mov     es,dx\r
891 asm     and     di,0xf\r
892 dinorm:\r
893 \r
894 asm     cmp     di,ss:endoff\r
895 asm     jne     expand\r
896 asm     mov     ax,es\r
897 asm     cmp     ax,ss:endseg\r
898 asm     jb      expand\r
899 \r
900 asm     mov     ax,ss\r
901 asm     mov     ds,ax\r
902 \r
903 }\r
904 */\r
905 \r
906 \r
907 /*\r
908 =============================================================================\r
909 \r
910                                          CACHE MANAGER ROUTINES\r
911 \r
912 =============================================================================\r
913 */\r
914 \r
915 /*\r
916 ======================\r
917 =\r
918 = CAL_SetupGrFile\r
919 =\r
920 ======================\r
921 */\r
922 ////++++ enable!\r
923 /*void CAL_SetupGrFile (void)\r
924 {\r
925         int handle;\r
926         memptr compseg;\r
927 \r
928 #ifdef GRHEADERLINKED\r
929 \r
930 #if GRMODE == EGAGR\r
931         grhuffman = (huffnode *)&EGAdict;\r
932         grstarts = (long _seg *)FP_SEG(&EGAhead);\r
933 #endif\r
934 #if GRMODE == CGAGR\r
935         grhuffman = (huffnode *)&CGAdict;\r
936         grstarts = (long _seg *)FP_SEG(&CGAhead);\r
937 #endif\r
938 \r
939         CAL_OptimizeNodes (grhuffman);\r
940 \r
941 #else\r
942 \r
943 //\r
944 // load ???dict.ext (huffman dictionary for graphics files)\r
945 //\r
946 \r
947         if ((handle = open(GREXT"DICT."EXT,\r
948                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
949                 Quit ("Can't open "GREXT"DICT."EXT"!");\r
950 \r
951         read(handle, &grhuffman, sizeof(grhuffman));\r
952         close(handle);\r
953         CAL_OptimizeNodes (grhuffman);\r
954 //\r
955 // load the data offsets from ???head.ext\r
956 //\r
957         MM_GetPtr (&(memptr)grstarts,(NUMCHUNKS+1)*FILEPOSSIZE);\r
958 \r
959         if ((handle = open(GREXT"HEAD."EXT,\r
960                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
961                 Quit ("Can't open "GREXT"HEAD."EXT"!");\r
962 \r
963         CA_FarRead(handle, (memptr)grstarts, (NUMCHUNKS+1)*FILEPOSSIZE);\r
964 \r
965         close(handle);\r
966 \r
967 \r
968 #endif\r
969 \r
970 //\r
971 // Open the graphics file, leaving it open until the game is finished\r
972 //\r
973         grhandle = open(GREXT"GRAPH."EXT, O_RDONLY | O_BINARY);\r
974         if (grhandle == -1)\r
975                 Quit ("Cannot open "GREXT"GRAPH."EXT"!");\r
976 \r
977 \r
978 //\r
979 // load the pic and sprite headers into the arrays in the data segment\r
980 //\r
981 #if NUMPICS>0\r
982         MM_GetPtr(&(memptr)pictable,NUMPICS*sizeof(pictabletype));\r
983         CAL_GetGrChunkLength(STRUCTPIC);                // position file pointer\r
984         MM_GetPtr(&compseg,chunkcomplen);\r
985         CA_FarRead (grhandle,compseg,chunkcomplen);\r
986         CAL_HuffExpand (compseg, (byte huge *)pictable,NUMPICS*sizeof(pictabletype),grhuffman);\r
987         MM_FreePtr(&compseg);\r
988 #endif\r
989 \r
990 #if NUMPICM>0\r
991         MM_GetPtr(&(memptr)picmtable,NUMPICM*sizeof(pictabletype));\r
992         CAL_GetGrChunkLength(STRUCTPICM);               // position file pointer\r
993         MM_GetPtr(&compseg,chunkcomplen);\r
994         CA_FarRead (grhandle,compseg,chunkcomplen);\r
995         CAL_HuffExpand (compseg, (byte huge *)picmtable,NUMPICS*sizeof(pictabletype),grhuffman);\r
996         MM_FreePtr(&compseg);\r
997 #endif\r
998 \r
999 #if NUMSPRITES>0\r
1000         MM_GetPtr(&(memptr)spritetable,NUMSPRITES*sizeof(spritetabletype));\r
1001         CAL_GetGrChunkLength(STRUCTSPRITE);     // position file pointer\r
1002         MM_GetPtr(&compseg,chunkcomplen);\r
1003         CA_FarRead (grhandle,compseg,chunkcomplen);\r
1004         CAL_HuffExpand (compseg, (byte huge *)spritetable,NUMSPRITES*sizeof(spritetabletype),grhuffman);\r
1005         MM_FreePtr(&compseg);\r
1006 #endif\r
1007 \r
1008 }*/\r
1009 \r
1010 //==========================================================================\r
1011 \r
1012 \r
1013 /*\r
1014 ======================\r
1015 =\r
1016 = CAL_SetupMapFile\r
1017 =\r
1018 ======================\r
1019 */\r
1020 \r
1021 /*void CAL_SetupMapFile (void)\r
1022 {\r
1023         int handle;\r
1024         long length;\r
1025 \r
1026 //\r
1027 // load maphead.ext (offsets and tileinfo for map file)\r
1028 //\r
1029 #ifndef MAPHEADERLINKED\r
1030         if ((handle = open("MAPHEAD."EXT,\r
1031                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1032                 Quit ("Can't open MAPHEAD."EXT"!");\r
1033         length = filelength(handle);\r
1034         MM_GetPtr (&(memptr)tinf,length);\r
1035         CA_FarRead(handle, tinf, length);\r
1036         close(handle);\r
1037 #else\r
1038 \r
1039         tinf = (byte _seg *)FP_SEG(&maphead);\r
1040 \r
1041 #endif\r
1042 \r
1043 //\r
1044 // open the data file\r
1045 //\r
1046 #ifdef MAPHEADERLINKED\r
1047         if ((maphandle = open("GAMEMAPS."EXT,\r
1048                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1049                 Quit ("Can't open GAMEMAPS."EXT"!");\r
1050 #else\r
1051         if ((maphandle = open("MAPTEMP."EXT,\r
1052                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1053                 Quit ("Can't open MAPTEMP."EXT"!");\r
1054 #endif\r
1055 }*/\r
1056 \r
1057 //==========================================================================\r
1058 \r
1059 \r
1060 /*\r
1061 ======================\r
1062 =\r
1063 = CAL_SetupAudioFile\r
1064 =\r
1065 ======================\r
1066 */\r
1067 \r
1068 /*void CAL_SetupAudioFile (void)\r
1069 {\r
1070         int handle;\r
1071         long length;\r
1072 \r
1073 //\r
1074 // load maphead.ext (offsets and tileinfo for map file)\r
1075 //\r
1076 #ifndef AUDIOHEADERLINKED\r
1077         if ((handle = open("AUDIOHED."EXT,\r
1078                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1079                 Quit ("Can't open AUDIOHED."EXT"!");\r
1080         length = filelength(handle);\r
1081         MM_GetPtr (&(memptr)audiostarts,length);\r
1082         CA_FarRead(handle, (byte far *)audiostarts, length);\r
1083         close(handle);\r
1084 #else\r
1085         audiohuffman = (huffnode *)&audiodict;\r
1086         CAL_OptimizeNodes (audiohuffman);\r
1087         audiostarts = (long _seg *)FP_SEG(&audiohead);\r
1088 #endif\r
1089 \r
1090 //\r
1091 // open the data file\r
1092 //\r
1093 #ifndef AUDIOHEADERLINKED\r
1094         if ((audiohandle = open("AUDIOT."EXT,\r
1095                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1096                 Quit ("Can't open AUDIOT."EXT"!");\r
1097 #else\r
1098         if ((audiohandle = open("AUDIO."EXT,\r
1099                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1100                 Quit ("Can't open AUDIO."EXT"!");\r
1101 #endif\r
1102 }*/\r
1103 \r
1104 //==========================================================================\r
1105 \r
1106 \r
1107 /*\r
1108 ======================\r
1109 =\r
1110 = CA_Startup\r
1111 =\r
1112 = Open all files and load in headers\r
1113 =\r
1114 ======================\r
1115 */\r
1116 \r
1117 void CA_Startup(global_game_variables_t *gvar)\r
1118 {\r
1119 #ifdef PROFILE\r
1120 #ifdef __BORLANDC__\r
1121         unlink("profile.16b");\r
1122         gvar->handle.profilehandle = open("profile.16b", O_CREAT | O_WRONLY | O_TEXT);\r
1123 #endif\r
1124 #ifdef __WATCOMC__\r
1125         unlink("profile.16w");\r
1126         gvar->handle.profilehandle = open("profile.16w", O_CREAT | O_WRONLY | O_TEXT);\r
1127 #endif\r
1128 #endif//profile\r
1129 \r
1130 #ifdef __BORLANDC__\r
1131         unlink("meminfo.16b");\r
1132         gvar->handle.showmemhandle = open("meminfo.16b", O_CREAT | O_WRONLY | O_TEXT);\r
1133 #endif\r
1134 #ifdef __WATCOMC__\r
1135         unlink("meminfo.16w");\r
1136         gvar->handle.showmemhandle = open("meminfo.16w", O_CREAT | O_WRONLY | O_TEXT);\r
1137 #endif\r
1138 /*      CAL_SetupMapFile ();\r
1139         CAL_SetupGrFile ();\r
1140         CAL_SetupAudioFile ();*/\r
1141 /*++++\r
1142 // MDM begin - (GAMERS EDGE)\r
1143 //\r
1144         if(!FindFile("AUDIO."EXT,NULL,2))\r
1145                 Quit("CA_Startup(): Can't find audio files.");\r
1146 //\r
1147 // MDM end\r
1148 \r
1149 #ifndef NOAUDIO\r
1150         CAL_SetupAudioFile();\r
1151 #endif\r
1152 \r
1153 // MDM begin - (GAMERS EDGE)\r
1154 //\r
1155         if (!FindFile("GAMEMAPS."EXT,NULL,1))\r
1156                 Quit("CA_Startup(): Can't find level files.");\r
1157 //\r
1158 // MDM end\r
1159 \r
1160 #ifndef NOMAPS\r
1161         CAL_SetupMapFile ();\r
1162 #endif\r
1163 \r
1164 // MDM begin - (GAMERS EDGE)\r
1165 //\r
1166         if (!FindFile("EGAGRAPH."EXT,NULL,2))\r
1167                 Quit("CA_Startup(): Can't find graphics files.");\r
1168 //\r
1169 // MDM end\r
1170 \r
1171 #ifndef NOGRAPHICS\r
1172         CAL_SetupGrFile ();\r
1173 #endif*/\r
1174 \r
1175         gvar->ca.mapon = -1;\r
1176         gvar->ca.ca_levelbit = 1;\r
1177         gvar->ca.ca_levelnum = 0;\r
1178 \r
1179 /*      drawcachebox    = CAL_DialogDraw;\r
1180         updatecachebox  = CAL_DialogUpdate;\r
1181         finishcachebox  = CAL_DialogFinish;*/\r
1182 }\r
1183 \r
1184 //==========================================================================\r
1185 \r
1186 \r
1187 /*\r
1188 ======================\r
1189 =\r
1190 = CA_Shutdown\r
1191 =\r
1192 = Closes all files\r
1193 =\r
1194 ======================\r
1195 */\r
1196 \r
1197 void CA_Shutdown(global_game_variables_t *gvar)\r
1198 {\r
1199 #ifdef PROFILE\r
1200         close(gvar->handle.profilehandle);\r
1201 #endif\r
1202         close(gvar->handle.showmemhandle);\r
1203 /*++++\r
1204         close(maphandle);\r
1205         close(grhandle);\r
1206         close(audiohandle);*/\r
1207 }\r
1208 \r
1209 //===========================================================================\r
1210 \r
1211 /*\r
1212 ======================\r
1213 =\r
1214 = CA_CacheAudioChunk\r
1215 =\r
1216 ======================\r
1217 */\r
1218 /*++++\r
1219 void CA_CacheAudioChunk (int chunk)\r
1220 {\r
1221         long    pos,compressed;\r
1222 #ifdef AUDIOHEADERLINKED\r
1223         long    expanded;\r
1224         memptr  bigbufferseg;\r
1225         byte    far *source;\r
1226 #endif\r
1227 \r
1228         if (audiosegs[chunk])\r
1229         {\r
1230                 MM_SetPurge (&(memptr)audiosegs[chunk],0);\r
1231                 return;                                                 // allready in memory\r
1232         }\r
1233 \r
1234 // MDM begin - (GAMERS EDGE)\r
1235 //\r
1236         if (!FindFile("AUDIO."EXT,NULL,2))\r
1237                 Quit("CA_CacheAudioChunk(): Can't find audio files.");\r
1238 //\r
1239 // MDM end\r
1240 \r
1241 //\r
1242 // load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
1243 // a larger buffer\r
1244 //\r
1245         pos = audiostarts[chunk];\r
1246         compressed = audiostarts[chunk+1]-pos;\r
1247 \r
1248         lseek(audiohandle,pos,SEEK_SET);\r
1249 \r
1250 #ifndef AUDIOHEADERLINKED\r
1251 \r
1252         MM_GetPtr (&(memptr)audiosegs[chunk],compressed);\r
1253         if (mmerror)\r
1254                 return;\r
1255 \r
1256         CA_FarRead(audiohandle,audiosegs[chunk],compressed);\r
1257 \r
1258 #else\r
1259 \r
1260         if (compressed<=BUFFERSIZE)\r
1261         {\r
1262                 CA_FarRead(audiohandle,bufferseg,compressed);\r
1263                 source = bufferseg;\r
1264         }\r
1265         else\r
1266         {\r
1267                 MM_GetPtr(&bigbufferseg,compressed);\r
1268                 if (mmerror)\r
1269                         return;\r
1270                 MM_SetLock (&bigbufferseg,true);\r
1271                 CA_FarRead(audiohandle,bigbufferseg,compressed);\r
1272                 source = bigbufferseg;\r
1273         }\r
1274 \r
1275         expanded = *(long far *)source;\r
1276         source += 4;                    // skip over length\r
1277         MM_GetPtr (&(memptr)audiosegs[chunk],expanded);\r
1278         if (mmerror)\r
1279                 goto done;\r
1280         CAL_HuffExpand (source,audiosegs[chunk],expanded,audiohuffman);\r
1281 \r
1282 done:\r
1283         if (compressed>BUFFERSIZE)\r
1284                 MM_FreePtr(&bigbufferseg);\r
1285 #endif\r
1286 }*/\r
1287 \r
1288 //===========================================================================\r
1289 \r
1290 /*\r
1291 ======================\r
1292 =\r
1293 = CA_LoadAllSounds\r
1294 =\r
1295 = Purges all sounds, then loads all new ones (mode switch)\r
1296 =\r
1297 ======================\r
1298 */\r
1299 /*++++\r
1300 void CA_LoadAllSounds (void)\r
1301 {\r
1302         unsigned        start,i;\r
1303 \r
1304         switch (oldsoundmode)\r
1305         {\r
1306         case sdm_Off:\r
1307                 goto cachein;\r
1308         case sdm_PC:\r
1309                 start = STARTPCSOUNDS;\r
1310                 break;\r
1311         case sdm_AdLib:\r
1312                 start = STARTADLIBSOUNDS;\r
1313                 break;\r
1314         }\r
1315 \r
1316         for (i=0;i<NUMSOUNDS;i++,start++)\r
1317                 if (audiosegs[start])\r
1318                         MM_SetPurge (&(memptr)audiosegs[start],3);              // make purgable\r
1319 \r
1320 cachein:\r
1321 \r
1322         switch (SoundMode)\r
1323         {\r
1324         case sdm_Off:\r
1325                 return;\r
1326         case sdm_PC:\r
1327                 start = STARTPCSOUNDS;\r
1328                 break;\r
1329         case sdm_AdLib:\r
1330                 start = STARTADLIBSOUNDS;\r
1331                 break;\r
1332         }\r
1333 \r
1334         for (i=0;i<NUMSOUNDS;i++,start++)\r
1335                 CA_CacheAudioChunk (start);\r
1336 \r
1337         oldsoundmode = SoundMode;\r
1338 }*/\r
1339 \r
1340 //===========================================================================\r
1341 \r
1342 //++++#if GRMODE == EGAGR\r
1343 \r
1344 /*\r
1345 ======================\r
1346 =\r
1347 = CAL_ShiftSprite\r
1348 =\r
1349 = Make a shifted (one byte wider) copy of a sprite into another area\r
1350 =\r
1351 ======================\r
1352 */\r
1353 /*++++\r
1354 unsigned        static  sheight,swidth;\r
1355 boolean static dothemask;\r
1356 \r
1357 void CAL_ShiftSprite (unsigned segment,unsigned source,unsigned dest,\r
1358         unsigned width, unsigned height, unsigned pixshift, boolean domask)\r
1359 {\r
1360 \r
1361         sheight = height;               // because we are going to reassign bp\r
1362         swidth = width;\r
1363         dothemask = domask;\r
1364 \r
1365 asm     mov     ax,[segment]\r
1366 asm     mov     ds,ax           // source and dest are in same segment, and all local\r
1367 \r
1368 asm     mov     bx,[source]\r
1369 asm     mov     di,[dest]\r
1370 \r
1371 asm     mov     bp,[pixshift]\r
1372 asm     shl     bp,1\r
1373 asm     mov     bp,WORD PTR [shifttabletable+bp]        // bp holds pointer to shift table\r
1374 \r
1375 asm     cmp     [ss:dothemask],0\r
1376 asm     je              skipmask\r
1377 \r
1378 //\r
1379 // table shift the mask\r
1380 //\r
1381 asm     mov     dx,[ss:sheight]\r
1382 \r
1383 domaskrow:\r
1384 \r
1385 asm     mov     BYTE PTR [di],255       // 0xff first byte\r
1386 asm     mov     cx,ss:[swidth]\r
1387 \r
1388 domaskbyte:\r
1389 \r
1390 asm     mov     al,[bx]                         // source\r
1391 asm     not     al\r
1392 asm     inc     bx                                      // next source byte\r
1393 asm     xor     ah,ah\r
1394 asm     shl     ax,1\r
1395 asm     mov     si,ax\r
1396 asm     mov     ax,[bp+si]                      // table shift into two bytes\r
1397 asm     not     ax\r
1398 asm     and     [di],al                         // and with first byte\r
1399 asm     inc     di\r
1400 asm     mov     [di],ah                         // replace next byte\r
1401 \r
1402 asm     loop    domaskbyte\r
1403 \r
1404 asm     inc     di                                      // the last shifted byte has 1s in it\r
1405 asm     dec     dx\r
1406 asm     jnz     domaskrow\r
1407 \r
1408 skipmask:\r
1409 \r
1410 //\r
1411 // table shift the data\r
1412 //\r
1413 asm     mov     dx,ss:[sheight]\r
1414 asm     shl     dx,1\r
1415 asm     shl     dx,1                            // four planes of data\r
1416 \r
1417 dodatarow:\r
1418 \r
1419 asm     mov     BYTE PTR [di],0         // 0 first byte\r
1420 asm     mov     cx,ss:[swidth]\r
1421 \r
1422 dodatabyte:\r
1423 \r
1424 asm     mov     al,[bx]                         // source\r
1425 asm     inc     bx                                      // next source byte\r
1426 asm     xor     ah,ah\r
1427 asm     shl     ax,1\r
1428 asm     mov     si,ax\r
1429 asm     mov     ax,[bp+si]                      // table shift into two bytes\r
1430 asm     or      [di],al                         // or with first byte\r
1431 asm     inc     di\r
1432 asm     mov     [di],ah                         // replace next byte\r
1433 \r
1434 asm     loop    dodatabyte\r
1435 \r
1436 asm     inc     di                                      // the last shifted byte has 0s in it\r
1437 asm     dec     dx\r
1438 asm     jnz     dodatarow\r
1439 \r
1440 //\r
1441 // done\r
1442 //\r
1443 \r
1444 asm     mov     ax,ss                           // restore data segment\r
1445 asm     mov     ds,ax\r
1446 \r
1447 }\r
1448 \r
1449 #endif\r
1450 */\r
1451 //===========================================================================\r
1452 \r
1453 /*\r
1454 ======================\r
1455 =\r
1456 = CAL_CacheSprite\r
1457 =\r
1458 = Generate shifts and set up sprite structure for a given sprite\r
1459 =\r
1460 ======================\r
1461 */\r
1462 /*++++\r
1463 void CAL_CacheSprite (int chunk, byte far *compressed)\r
1464 {\r
1465         int i;\r
1466         unsigned shiftstarts[5];\r
1467         unsigned smallplane,bigplane,expanded;\r
1468         spritetabletype far *spr;\r
1469         spritetype _seg *dest;\r
1470 \r
1471 #if GRMODE == CGAGR\r
1472 //\r
1473 // CGA has no pel panning, so shifts are never needed\r
1474 //\r
1475         spr = &spritetable[chunk-STARTSPRITES];\r
1476         smallplane = spr->width*spr->height;\r
1477         MM_GetPtr (&grsegs[chunk],smallplane*2+MAXSHIFTS*6);\r
1478         if (mmerror)\r
1479                 return;\r
1480         dest = (spritetype _seg *)grsegs[chunk];\r
1481         dest->sourceoffset[0] = MAXSHIFTS*6;    // start data after 3 unsigned tables\r
1482         dest->planesize[0] = smallplane;\r
1483         dest->width[0] = spr->width;\r
1484 \r
1485 //\r
1486 // expand the unshifted shape\r
1487 //\r
1488         CAL_HuffExpand (compressed, &dest->data[0],smallplane*2,grhuffman);\r
1489 \r
1490 #endif\r
1491 \r
1492 \r
1493 #if GRMODE == EGAGR\r
1494 \r
1495 //\r
1496 // calculate sizes\r
1497 //\r
1498         spr = &spritetable[chunk-STARTSPRITES];\r
1499         smallplane = spr->width*spr->height;\r
1500         bigplane = (spr->width+1)*spr->height;\r
1501 \r
1502         shiftstarts[0] = MAXSHIFTS*6;   // start data after 3 unsigned tables\r
1503         shiftstarts[1] = shiftstarts[0] + smallplane*5; // 5 planes in a sprite\r
1504         shiftstarts[2] = shiftstarts[1] + bigplane*5;\r
1505         shiftstarts[3] = shiftstarts[2] + bigplane*5;\r
1506         shiftstarts[4] = shiftstarts[3] + bigplane*5;   // nothing ever put here\r
1507 \r
1508         expanded = shiftstarts[spr->shifts];\r
1509         MM_GetPtr (&grsegs[chunk],expanded);\r
1510         if (mmerror)\r
1511                 return;\r
1512         dest = (spritetype _seg *)grsegs[chunk];\r
1513 \r
1514 //\r
1515 // expand the unshifted shape\r
1516 //\r
1517         CAL_HuffExpand (compressed, &dest->data[0],smallplane*5,grhuffman);\r
1518 \r
1519 //\r
1520 // make the shifts!\r
1521 //\r
1522         switch (spr->shifts)\r
1523         {\r
1524         case    1:\r
1525                 for (i=0;i<4;i++)\r
1526                 {\r
1527                         dest->sourceoffset[i] = shiftstarts[0];\r
1528                         dest->planesize[i] = smallplane;\r
1529                         dest->width[i] = spr->width;\r
1530                 }\r
1531                 break;\r
1532 \r
1533         case    2:\r
1534                 for (i=0;i<2;i++)\r
1535                 {\r
1536                         dest->sourceoffset[i] = shiftstarts[0];\r
1537                         dest->planesize[i] = smallplane;\r
1538                         dest->width[i] = spr->width;\r
1539                 }\r
1540                 for (i=2;i<4;i++)\r
1541                 {\r
1542                         dest->sourceoffset[i] = shiftstarts[1];\r
1543                         dest->planesize[i] = bigplane;\r
1544                         dest->width[i] = spr->width+1;\r
1545                 }\r
1546                 CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
1547                         dest->sourceoffset[2],spr->width,spr->height,4,true);\r
1548                 break;\r
1549 \r
1550         case    4:\r
1551                 dest->sourceoffset[0] = shiftstarts[0];\r
1552                 dest->planesize[0] = smallplane;\r
1553                 dest->width[0] = spr->width;\r
1554 \r
1555                 dest->sourceoffset[1] = shiftstarts[1];\r
1556                 dest->planesize[1] = bigplane;\r
1557                 dest->width[1] = spr->width+1;\r
1558                 CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
1559                         dest->sourceoffset[1],spr->width,spr->height,2,true);\r
1560 \r
1561                 dest->sourceoffset[2] = shiftstarts[2];\r
1562                 dest->planesize[2] = bigplane;\r
1563                 dest->width[2] = spr->width+1;\r
1564                 CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
1565                         dest->sourceoffset[2],spr->width,spr->height,4,true);\r
1566 \r
1567                 dest->sourceoffset[3] = shiftstarts[3];\r
1568                 dest->planesize[3] = bigplane;\r
1569                 dest->width[3] = spr->width+1;\r
1570                 CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
1571                         dest->sourceoffset[3],spr->width,spr->height,6,true);\r
1572 \r
1573                 break;\r
1574 \r
1575         default:\r
1576                 Quit ("CAL_CacheSprite: Bad shifts number!");\r
1577         }\r
1578 \r
1579 #endif\r
1580 }*/\r
1581 \r
1582 //===========================================================================\r
1583 \r
1584 \r
1585 /*\r
1586 ======================\r
1587 =\r
1588 = CAL_ExpandGrChunk\r
1589 =\r
1590 = Does whatever is needed with a pointer to a compressed chunk\r
1591 =\r
1592 ======================\r
1593 */\r
1594 /*++++\r
1595 void CAL_ExpandGrChunk (int chunk, byte far *source)\r
1596 {\r
1597         long    expanded;\r
1598 \r
1599 \r
1600         if (chunk >= STARTTILE8 && chunk < STARTEXTERNS)\r
1601         {\r
1602         //\r
1603         // expanded sizes of tile8/16/32 are implicit\r
1604         //\r
1605 \r
1606 #if GRMODE == EGAGR\r
1607 #define BLOCK           32\r
1608 #define MASKBLOCK       40\r
1609 #endif\r
1610 \r
1611 #if GRMODE == CGAGR\r
1612 #define BLOCK           16\r
1613 #define MASKBLOCK       32\r
1614 #endif\r
1615 \r
1616                 if (chunk<STARTTILE8M)                  // tile 8s are all in one chunk!\r
1617                         expanded = BLOCK*NUMTILE8;\r
1618                 else if (chunk<STARTTILE16)\r
1619                         expanded = MASKBLOCK*NUMTILE8M;\r
1620                 else if (chunk<STARTTILE16M)    // all other tiles are one/chunk\r
1621                         expanded = BLOCK*4;\r
1622                 else if (chunk<STARTTILE32)\r
1623                         expanded = MASKBLOCK*4;\r
1624                 else if (chunk<STARTTILE32M)\r
1625                         expanded = BLOCK*16;\r
1626                 else\r
1627                         expanded = MASKBLOCK*16;\r
1628         }\r
1629         else\r
1630         {\r
1631         //\r
1632         // everything else has an explicit size longword\r
1633         //\r
1634                 expanded = *(long far *)source;\r
1635                 source += 4;                    // skip over length\r
1636         }\r
1637 \r
1638 //\r
1639 // allocate final space, decompress it, and free bigbuffer\r
1640 // Sprites need to have shifts made and various other junk\r
1641 //\r
1642         if (chunk>=STARTSPRITES && chunk< STARTTILE8)\r
1643                 CAL_CacheSprite(chunk,source);\r
1644         else\r
1645         {\r
1646                 MM_GetPtr (&grsegs[chunk],expanded);\r
1647                 if (mmerror)\r
1648                         return;\r
1649                 CAL_HuffExpand (source,grsegs[chunk],expanded,grhuffman);\r
1650         }\r
1651 }\r
1652 */\r
1653 \r
1654 /*\r
1655 ======================\r
1656 =\r
1657 = CAL_ReadGrChunk\r
1658 =\r
1659 = Gets a chunk off disk, optimizing reads to general buffer\r
1660 =\r
1661 ======================\r
1662 */\r
1663 /*++++\r
1664 void CAL_ReadGrChunk (int chunk)\r
1665 {\r
1666         long    pos,compressed;\r
1667         memptr  bigbufferseg;\r
1668         byte    far *source;\r
1669         int             next;\r
1670 \r
1671 //\r
1672 // load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
1673 // a larger buffer\r
1674 //\r
1675         pos = GRFILEPOS(chunk);\r
1676         if (pos<0)                                                      // $FFFFFFFF start is a sparse tile\r
1677           return;\r
1678 \r
1679         next = chunk +1;\r
1680         while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
1681                 next++;\r
1682 \r
1683         compressed = GRFILEPOS(next)-pos;\r
1684 \r
1685         lseek(grhandle,pos,SEEK_SET);\r
1686 \r
1687         if (compressed<=BUFFERSIZE)\r
1688         {\r
1689                 CA_FarRead(grhandle,bufferseg,compressed);\r
1690                 source = bufferseg;\r
1691         }\r
1692         else\r
1693         {\r
1694                 MM_GetPtr(&bigbufferseg,compressed);\r
1695                 if (mmerror)\r
1696                         return;\r
1697                 MM_SetLock (&bigbufferseg,true);\r
1698                 CA_FarRead(grhandle,bigbufferseg,compressed);\r
1699                 source = bigbufferseg;\r
1700         }\r
1701 \r
1702         CAL_ExpandGrChunk (chunk,source);\r
1703 \r
1704         if (compressed>BUFFERSIZE)\r
1705                 MM_FreePtr(&bigbufferseg);\r
1706 }\r
1707 */\r
1708 /*\r
1709 ======================\r
1710 =\r
1711 = CA_CacheGrChunk\r
1712 =\r
1713 = Makes sure a given chunk is in memory, loadiing it if needed\r
1714 =\r
1715 ======================\r
1716 */\r
1717 /*++++\r
1718 void CA_CacheGrChunk (int chunk)\r
1719 {\r
1720         long    pos,compressed;\r
1721         memptr  bigbufferseg;\r
1722         byte    far *source;\r
1723         int             next;\r
1724 \r
1725         gvar->video.grneeded[chunk] |= ca_levelbit;             // make sure it doesn't get removed\r
1726         if (grsegs[chunk])\r
1727         {\r
1728                 MM_SetPurge (&grsegs[chunk],0);\r
1729                 return;                                                 // allready in memory\r
1730         }\r
1731 \r
1732 // MDM begin - (GAMERS EDGE)\r
1733 //\r
1734         if (!FindFile("EGAGRAPH."EXT,NULL,2))\r
1735                 Quit("CA_CacheGrChunk(): Can't find graphics files.");\r
1736 //\r
1737 // MDM end\r
1738 \r
1739 //\r
1740 // load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
1741 // a larger buffer\r
1742 //\r
1743         pos = GRFILEPOS(chunk);\r
1744         if (pos<0)                                                      // $FFFFFFFF start is a sparse tile\r
1745           return;\r
1746 \r
1747         next = chunk +1;\r
1748         while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
1749                 next++;\r
1750 \r
1751         compressed = GRFILEPOS(next)-pos;\r
1752 \r
1753         lseek(grhandle,pos,SEEK_SET);\r
1754 \r
1755         if (compressed<=BUFFERSIZE)\r
1756         {\r
1757                 CA_FarRead(grhandle,bufferseg,compressed);\r
1758                 source = bufferseg;\r
1759         }\r
1760         else\r
1761         {\r
1762                 MM_GetPtr(&bigbufferseg,compressed);\r
1763                 MM_SetLock (&bigbufferseg,true);\r
1764                 CA_FarRead(grhandle,bigbufferseg,compressed);\r
1765                 source = bigbufferseg;\r
1766         }\r
1767 \r
1768         CAL_ExpandGrChunk (chunk,source);\r
1769 \r
1770         if (compressed>BUFFERSIZE)\r
1771                 MM_FreePtr(&bigbufferseg);\r
1772 }\r
1773 */\r
1774 \r
1775 \r
1776 //==========================================================================\r
1777 \r
1778 /*\r
1779 ======================\r
1780 =\r
1781 = CA_CacheMap\r
1782 =\r
1783 ======================\r
1784 */\r
1785 /*++++\r
1786 void CA_CacheMap (int mapnum)\r
1787 {\r
1788         long    pos,compressed;\r
1789         int             plane;\r
1790         memptr  *dest,bigbufferseg;\r
1791         unsigned        size;\r
1792         unsigned        far     *source;\r
1793 #ifdef MAPHEADERLINKED\r
1794         memptr  buffer2seg;\r
1795         long    expanded;\r
1796 #endif\r
1797 \r
1798 \r
1799 // MDM begin - (GAMERS EDGE)\r
1800 //\r
1801         if (!FindFile("GAMEMAPS."EXT,NULL,1))\r
1802                 Quit("CA_CacheMap(): Can't find level files.");\r
1803 //\r
1804 // MDM end\r
1805 \r
1806 \r
1807 //\r
1808 // free up memory from last map\r
1809 //\r
1810         if (mapon>-1 && mapheaderseg[mapon])\r
1811                 MM_SetPurge (&(memptr)mapheaderseg[mapon],3);\r
1812         for (plane=0;plane<MAPPLANES;plane++)\r
1813                 if (mapsegs[plane])\r
1814                         MM_FreePtr (&(memptr)mapsegs[plane]);\r
1815 \r
1816         mapon = mapnum;\r
1817 \r
1818 \r
1819 //\r
1820 // load map header\r
1821 // The header will be cached if it is still around\r
1822 //\r
1823         if (!mapheaderseg[mapnum])\r
1824         {\r
1825                 pos = ((mapfiletype     _seg *)tinf)->headeroffsets[mapnum];\r
1826                 if (pos<0)                                              // $FFFFFFFF start is a sparse map\r
1827                   Quit ("CA_CacheMap: Tried to load a non existent map!");\r
1828 \r
1829                 MM_GetPtr(&(memptr)mapheaderseg[mapnum],sizeof(maptype));\r
1830                 lseek(maphandle,pos,SEEK_SET);\r
1831                 CA_FarRead (maphandle,(memptr)mapheaderseg[mapnum],sizeof(maptype));\r
1832         }\r
1833         else\r
1834                 MM_SetPurge (&(memptr)mapheaderseg[mapnum],0);\r
1835 \r
1836 //\r
1837 // load the planes in\r
1838 // If a plane's pointer still exists it will be overwritten (levels are\r
1839 // allways reloaded, never cached)\r
1840 //\r
1841 \r
1842         size = mapheaderseg[mapnum]->width * mapheaderseg[mapnum]->height * 2;\r
1843 \r
1844         for (plane = 0; plane<MAPPLANES; plane++)\r
1845         {\r
1846                 pos = mapheaderseg[mapnum]->planestart[plane];\r
1847                 compressed = mapheaderseg[mapnum]->planelength[plane];\r
1848 \r
1849                 if (!compressed)\r
1850                         continue;               // the plane is not used in this game\r
1851 \r
1852                 dest = &(memptr)mapsegs[plane];\r
1853                 MM_GetPtr(dest,size);\r
1854 \r
1855                 lseek(maphandle,pos,SEEK_SET);\r
1856                 if (compressed<=BUFFERSIZE)\r
1857                         source = bufferseg;\r
1858                 else\r
1859                 {\r
1860                         MM_GetPtr(&bigbufferseg,compressed);\r
1861                         MM_SetLock (&bigbufferseg,true);\r
1862                         source = bigbufferseg;\r
1863                 }\r
1864 \r
1865                 CA_FarRead(maphandle,(byte far *)source,compressed);\r
1866 #ifdef MAPHEADERLINKED\r
1867                 //\r
1868                 // unhuffman, then unRLEW\r
1869                 // The huffman'd chunk has a two byte expanded length first\r
1870                 // The resulting RLEW chunk also does, even though it's not really\r
1871                 // needed\r
1872                 //\r
1873                 expanded = *source;\r
1874                 source++;\r
1875                 MM_GetPtr (&buffer2seg,expanded);\r
1876                 CAL_CarmackExpand (source, (unsigned far *)buffer2seg,expanded);\r
1877                 CA_RLEWexpand (((unsigned far *)buffer2seg)+1,*dest,size,\r
1878                 ((mapfiletype _seg *)tinf)->RLEWtag);\r
1879                 MM_FreePtr (&buffer2seg);\r
1880 \r
1881 #else\r
1882                 //\r
1883                 // unRLEW, skipping expanded length\r
1884                 //\r
1885                 CA_RLEWexpand (source+1, *dest,size,\r
1886                 ((mapfiletype _seg *)tinf)->RLEWtag);\r
1887 #endif\r
1888 \r
1889                 if (compressed>BUFFERSIZE)\r
1890                         MM_FreePtr(&bigbufferseg);\r
1891         }\r
1892 }*/\r
1893 \r
1894 //===========================================================================\r
1895 \r
1896 /*\r
1897 ======================\r
1898 =\r
1899 = CA_UpLevel\r
1900 =\r
1901 = Goes up a bit level in the needed lists and clears it out.\r
1902 = Everything is made purgable\r
1903 =\r
1904 ======================\r
1905 */\r
1906 /*++++\r
1907 void CA_UpLevel (void)\r
1908 {\r
1909         if (ca_levelnum==7)\r
1910                 Quit ("CA_UpLevel: Up past level 7!");\r
1911 \r
1912         ca_levelbit<<=1;\r
1913         ca_levelnum++;\r
1914 }*/\r
1915 \r
1916 //===========================================================================\r
1917 \r
1918 /*\r
1919 ======================\r
1920 =\r
1921 = CA_DownLevel\r
1922 =\r
1923 = Goes down a bit level in the needed lists and recaches\r
1924 = everything from the lower level\r
1925 =\r
1926 ======================\r
1927 */\r
1928 /*++\r
1929 void CA_DownLevel (void)\r
1930 {\r
1931         if (!ca_levelnum)\r
1932                 Quit ("CA_DownLevel: Down past level 0!");\r
1933         ca_levelbit>>=1;\r
1934         ca_levelnum--;\r
1935         CA_CacheMarks(NULL);\r
1936 }*/\r
1937 \r
1938 //===========================================================================\r
1939 \r
1940 /*\r
1941 ======================\r
1942 =\r
1943 = CA_ClearMarks\r
1944 =\r
1945 = Clears out all the marks at the current level\r
1946 =\r
1947 ======================\r
1948 */\r
1949 \r
1950 void CA_ClearMarks (global_game_variables_t *gvar)\r
1951 {\r
1952         int i;\r
1953 \r
1954         for (i=0;i<NUMCHUNKS;i++)\r
1955                 gvar->video.grneeded[i]&=~gvar->ca.ca_levelbit;\r
1956 }\r
1957 \r
1958 //===========================================================================\r
1959 \r
1960 /*\r
1961 ======================\r
1962 =\r
1963 = CA_ClearAllMarks\r
1964 =\r
1965 = Clears out all the marks on all the levels\r
1966 =\r
1967 ======================\r
1968 */\r
1969 \r
1970 void CA_ClearAllMarks (global_game_variables_t *gvar)\r
1971 {\r
1972         _fmemset (gvar->video.grneeded,0,sizeof(gvar->video.grneeded));\r
1973         gvar->ca.ca_levelbit = 1;\r
1974         gvar->ca.ca_levelnum = 0;\r
1975 }\r
1976 \r
1977 //===========================================================================\r
1978 \r
1979 /*\r
1980 ======================\r
1981 =\r
1982 = CA_FreeGraphics\r
1983 =\r
1984 ======================\r
1985 */\r
1986 /*++++\r
1987 void CA_SetGrPurge (void)\r
1988 {\r
1989         int i;\r
1990 \r
1991 //\r
1992 // free graphics\r
1993 //\r
1994         CA_ClearMarks ();\r
1995 \r
1996         for (i=0;i<NUMCHUNKS;i++)\r
1997                 if (grsegs[i])\r
1998                         MM_SetPurge (&(memptr)grsegs[i],3);\r
1999 }\r
2000 */\r
2001 \r
2002 /*\r
2003 ======================\r
2004 =\r
2005 = CA_SetAllPurge\r
2006 =\r
2007 = Make everything possible purgable\r
2008 =\r
2009 ======================\r
2010 */\r
2011 /*++++++++\r
2012 void CA_SetAllPurge (void)\r
2013 {\r
2014         int i;\r
2015 \r
2016         CA_ClearMarks ();\r
2017 \r
2018 //\r
2019 // free cursor sprite and background save\r
2020 //\r
2021         VW_FreeCursor ();\r
2022 \r
2023 //\r
2024 // free map headers and map planes\r
2025 //\r
2026         for (i=0;i<NUMMAPS;i++)\r
2027                 if (mapheaderseg[i])\r
2028                         MM_SetPurge (&(memptr)mapheaderseg[i],3);\r
2029 \r
2030         for (i=0;i<3;i++)\r
2031                 if (mapsegs[i])\r
2032                         MM_FreePtr (&(memptr)mapsegs[i]);\r
2033 \r
2034 //\r
2035 // free sounds\r
2036 //\r
2037         for (i=0;i<NUMSNDCHUNKS;i++)\r
2038                 if (audiosegs[i])\r
2039                         MM_SetPurge (&(memptr)audiosegs[i],3);\r
2040 \r
2041 //\r
2042 // free graphics\r
2043 //\r
2044         CA_SetGrPurge ();\r
2045 }*/\r
2046 \r
2047 \r
2048 //===========================================================================\r
2049 \r
2050 \r
2051 /*\r
2052 ======================\r
2053 =\r
2054 = CAL_DialogDraw\r
2055 =\r
2056 ======================\r
2057 */\r
2058 /*\r
2059 #define NUMBARS (17l*8)\r
2060 #define BARSTEP 8\r
2061 \r
2062 unsigned        thx,thy,lastx;\r
2063 long            barx,barstep;\r
2064 \r
2065 void    CAL_DialogDraw (char *title,unsigned numcache)\r
2066 {\r
2067         unsigned        homex,homey,x;\r
2068 \r
2069         barstep = (NUMBARS<<16)/numcache;\r
2070 \r
2071 //\r
2072 // draw dialog window (masked tiles 12 - 20 are window borders)\r
2073 //\r
2074         US_CenterWindow (20,8);\r
2075         homex = PrintX;\r
2076         homey = PrintY;\r
2077 \r
2078         US_CPrint ("Loading");\r
2079         fontcolor = F_SECONDCOLOR;\r
2080         US_CPrint (title);\r
2081         fontcolor = F_BLACK;\r
2082 \r
2083 //\r
2084 // draw thermometer bar\r
2085 //\r
2086         thx = homex + 8;\r
2087         thy = homey + 32;\r
2088         VWB_DrawTile8(thx,thy,0);               // CAT3D numbers\r
2089         VWB_DrawTile8(thx,thy+8,3);\r
2090         VWB_DrawTile8(thx,thy+16,6);\r
2091         VWB_DrawTile8(thx+17*8,thy,2);\r
2092         VWB_DrawTile8(thx+17*8,thy+8,5);\r
2093         VWB_DrawTile8(thx+17*8,thy+16,8);\r
2094         for (x=thx+8;x<thx+17*8;x+=8)\r
2095         {\r
2096                 VWB_DrawTile8(x,thy,1);\r
2097                 VWB_DrawTile8(x,thy+8,4);\r
2098                 VWB_DrawTile8(x,thy+16,7);\r
2099         }\r
2100 \r
2101         thx += 4;               // first line location\r
2102         thy += 5;\r
2103         barx = (long)thx<<16;\r
2104         lastx = thx;\r
2105 \r
2106         VW_UpdateScreen();\r
2107 }\r
2108 */\r
2109 \r
2110 /*\r
2111 ======================\r
2112 =\r
2113 = CAL_DialogUpdate\r
2114 =\r
2115 ======================\r
2116 */\r
2117 /*\r
2118 void    CAL_DialogUpdate (void)\r
2119 {\r
2120         unsigned        x,xh;\r
2121 \r
2122         barx+=barstep;\r
2123         xh = barx>>16;\r
2124         if (xh - lastx > BARSTEP)\r
2125         {\r
2126                 for (x=lastx;x<=xh;x++)\r
2127 #if GRMODE == EGAGR\r
2128                         VWB_Vlin (thy,thy+13,x,14);\r
2129 #endif\r
2130 #if GRMODE == CGAGR\r
2131                         VWB_Vlin (thy,thy+13,x,SECONDCOLOR);\r
2132 #endif\r
2133                 lastx = xh;\r
2134                 VW_UpdateScreen();\r
2135         }\r
2136 }*/\r
2137 \r
2138 /*\r
2139 ======================\r
2140 =\r
2141 = CAL_DialogFinish\r
2142 =\r
2143 ======================\r
2144 */\r
2145 /*\r
2146 void    CAL_DialogFinish (void)\r
2147 {\r
2148         unsigned        x,xh;\r
2149 \r
2150         xh = thx + NUMBARS;\r
2151         for (x=lastx;x<=xh;x++)\r
2152 #if GRMODE == EGAGR\r
2153                 VWB_Vlin (thy,thy+13,x,14);\r
2154 #endif\r
2155 #if GRMODE == CGAGR\r
2156                 VWB_Vlin (thy,thy+13,x,SECONDCOLOR);\r
2157 #endif\r
2158         VW_UpdateScreen();\r
2159 \r
2160 }*/\r
2161 \r
2162 //===========================================================================\r
2163 \r
2164 /*\r
2165 ======================\r
2166 =\r
2167 = CA_CacheMarks\r
2168 =\r
2169 ======================\r
2170 *//*\r
2171 #define MAXEMPTYREAD    1024\r
2172 \r
2173 void CA_CacheMarks (char *title)\r
2174 {\r
2175         boolean dialog;\r
2176         int     i,next,numcache;\r
2177         long    pos,endpos,nextpos,nextendpos,compressed;\r
2178         long    bufferstart,bufferend;  // file position of general buffer\r
2179         byte    far *source;\r
2180         memptr  bigbufferseg;\r
2181 \r
2182         dialog = (title!=NULL);\r
2183 \r
2184         numcache = 0;\r
2185 //\r
2186 // go through and make everything not needed purgable\r
2187 //\r
2188         for (i=0;i<NUMCHUNKS;i++)\r
2189                 if (gvar->video.grneeded[i]&ca_levelbit)\r
2190                 {\r
2191                         if (grsegs[i])                                  // its allready in memory, make\r
2192                                 MM_SetPurge(&grsegs[i],0);      // sure it stays there!\r
2193                         else\r
2194                                 numcache++;\r
2195                 }\r
2196                 else\r
2197                 {\r
2198                         if (grsegs[i])                                  // not needed, so make it purgeable\r
2199                                 MM_SetPurge(&grsegs[i],3);\r
2200                 }\r
2201 \r
2202         if (!numcache)                  // nothing to cache!\r
2203                 return;\r
2204 \r
2205 // MDM begin - (GAMERS EDGE)\r
2206 //\r
2207         if (!FindFile("EGAGRAPH."EXT,NULL,2))\r
2208                 Quit("CA_CacheMarks(): Can't find graphics files.");\r
2209 //\r
2210 // MDM end\r
2211 \r
2212         if (dialog)\r
2213         {\r
2214 #ifdef PROFILE\r
2215                 write(profilehandle,title,strlen(title));\r
2216                 write(profilehandle,"\n",1);\r
2217 #endif\r
2218                 if (drawcachebox)\r
2219                         drawcachebox(title,numcache);\r
2220         }\r
2221 \r
2222 //\r
2223 // go through and load in anything still needed\r
2224 //\r
2225         bufferstart = bufferend = 0;            // nothing good in buffer now\r
2226 \r
2227         for (i=0;i<NUMCHUNKS;i++)\r
2228                 if ( (gvar->video.grneeded[i]&ca_levelbit) && !grsegs[i])\r
2229                 {\r
2230 //\r
2231 // update thermometer\r
2232 //\r
2233                         if (dialog && updatecachebox)\r
2234                                 updatecachebox ();\r
2235 \r
2236                         pos = GRFILEPOS(i);\r
2237                         if (pos<0)\r
2238                                 continue;\r
2239 \r
2240                         next = i +1;\r
2241                         while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
2242                                 next++;\r
2243 \r
2244                         compressed = GRFILEPOS(next)-pos;\r
2245                         endpos = pos+compressed;\r
2246 \r
2247                         if (compressed<=BUFFERSIZE)\r
2248                         {\r
2249                                 if (bufferstart<=pos\r
2250                                 && bufferend>= endpos)\r
2251                                 {\r
2252                                 // data is allready in buffer\r
2253                                         source = (byte _seg *)bufferseg+(pos-bufferstart);\r
2254                                 }\r
2255                                 else\r
2256                                 {\r
2257                                 // load buffer with a new block from disk\r
2258                                 // try to get as many of the needed blocks in as possible\r
2259                                         while ( next < NUMCHUNKS )\r
2260                                         {\r
2261                                                 while (next < NUMCHUNKS &&\r
2262                                                 !(gvar->video.grneeded[next]&ca_levelbit && !grsegs[next]))\r
2263                                                         next++;\r
2264                                                 if (next == NUMCHUNKS)\r
2265                                                         continue;\r
2266 \r
2267                                                 nextpos = GRFILEPOS(next);\r
2268                                                 while (GRFILEPOS(++next) == -1) // skip past any sparse tiles\r
2269                                                         ;\r
2270                                                 nextendpos = GRFILEPOS(next);\r
2271                                                 if (nextpos - endpos <= MAXEMPTYREAD\r
2272                                                 && nextendpos-pos <= BUFFERSIZE)\r
2273                                                         endpos = nextendpos;\r
2274                                                 else\r
2275                                                         next = NUMCHUNKS;                       // read pos to posend\r
2276                                         }\r
2277 \r
2278                                         lseek(grhandle,pos,SEEK_SET);\r
2279                                         CA_FarRead(grhandle,bufferseg,endpos-pos);\r
2280                                         bufferstart = pos;\r
2281                                         bufferend = endpos;\r
2282                                         source = bufferseg;\r
2283                                 }\r
2284                         }\r
2285                         else\r
2286                         {\r
2287                         // big chunk, allocate temporary buffer\r
2288                                 MM_GetPtr(&bigbufferseg,compressed);\r
2289                                 if (mmerror)\r
2290                                         return;\r
2291                                 MM_SetLock (&bigbufferseg,true);\r
2292                                 lseek(grhandle,pos,SEEK_SET);\r
2293                                 CA_FarRead(grhandle,bigbufferseg,compressed);\r
2294                                 source = bigbufferseg;\r
2295                         }\r
2296 \r
2297                         CAL_ExpandGrChunk (i,source);\r
2298                         if (mmerror)\r
2299                                 return;\r
2300 \r
2301                         if (compressed>BUFFERSIZE)\r
2302                                 MM_FreePtr(&bigbufferseg);\r
2303 \r
2304                 }\r
2305 \r
2306 //\r
2307 // finish up any thermometer remnants\r
2308 //\r
2309                 if (dialog && finishcachebox)\r
2310                         finishcachebox();\r
2311 }*/\r