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