]> 4ch.mooo.com Git - 16.git/blob - src/lib/16_ca.c
vgacamm.exe fixed and vrstest works better~! wwwwwwwwwwwww
[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;*/   //moved to src/lib/typdefst.h\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 asm     mov     dx,[ss:bx+2]            // take bit1 path\r
559 asm     shl     cl,1                            // advance to next bit position\r
560 asm     jnc     sourceupshort\r
561 \r
562 newbyteshort:\r
563 asm     mov     ch,[si]                         // load next byte\r
564 asm     inc     si\r
565 asm     mov     cl,1                            // back to first bit\r
566 \r
567 sourceupshort:\r
568 asm     or      dh,dh                           // if dx<256 its a byte, else move node\r
569 asm     jz      storebyteshort\r
570 asm     mov     bx,dx                           // next node = (huffnode *)code\r
571 asm     jmp     expandshort\r
572 \r
573 storebyteshort:\r
574 asm     mov     [es:di],dl\r
575 asm     inc     di                                      // write a decopmpressed byte out\r
576 asm     mov     bx,[headptr]            // back to the head node for next bit\r
577 \r
578 asm     cmp     di,ax                           // done?\r
579 asm     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 asm mov bx,[headptr]\r
594 asm     mov     cl,1\r
595 \r
596 asm     mov     si,[sourceoff]\r
597 asm     mov     di,[destoff]\r
598 asm     mov     es,[destseg]\r
599 asm     mov     ds,[sourceseg]\r
600 \r
601 asm     lodsb                   // load first byte\r
602 \r
603 expand:\r
604 asm     test    al,cl           // bit set?\r
605 asm     jnz     bit1\r
606 asm     mov     dx,[ss:bx]      // take bit0 path from node\r
607 asm     jmp     gotcode\r
608 bit1:\r
609 asm     mov     dx,[ss:bx+2]    // take bit1 path\r
610 \r
611 gotcode:\r
612 asm     shl     cl,1            // advance to next bit position\r
613 asm     jnc     sourceup\r
614 asm     lodsb\r
615 asm     cmp     si,0x10         // normalize ds:si\r
616 asm     jb      sinorm\r
617 asm     mov     cx,ds\r
618 asm     inc     cx\r
619 asm     mov     ds,cx\r
620 asm     xor     si,si\r
621 sinorm:\r
622 asm     mov     cl,1            // back to first bit\r
623 \r
624 sourceup:\r
625 asm     or      dh,dh           // if dx<256 its a byte, else move node\r
626 asm     jz      storebyte\r
627 asm     mov     bx,dx           // next node = (huffnode *)code\r
628 asm     jmp     expand\r
629 \r
630 storebyte:\r
631 asm     mov     [es:di],dl\r
632 asm     inc     di              // write a decopmpressed byte out\r
633 asm     mov     bx,[headptr]    // back to the head node for next bit\r
634 \r
635 asm     cmp     di,0x10         // normalize es:di\r
636 asm     jb      dinorm\r
637 asm     mov     dx,es\r
638 asm     inc     dx\r
639 asm     mov     es,dx\r
640 asm     xor     di,di\r
641 dinorm:\r
642 \r
643 asm     sub     [WORD PTR ss:length],1\r
644 asm     jnc     expand\r
645 asm     dec     [WORD PTR ss:length+2]\r
646 asm     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\r
1129 //      unlink("debug0.16");\r
1130 //      gvar->handle.showmemhandle = open("debug0.16", O_CREAT | O_WRONLY | O_TEXT);\r
1131 /*++++\r
1132 // MDM begin - (GAMERS EDGE)\r
1133 //\r
1134         if(!FindFile("AUDIO."EXT,NULL,2))\r
1135                 Quit("CA_Startup(): Can't find audio files.");\r
1136 //\r
1137 // MDM end\r
1138 \r
1139 #ifndef NOAUDIO\r
1140         CAL_SetupAudioFile();\r
1141 #endif\r
1142 \r
1143 // MDM begin - (GAMERS EDGE)\r
1144 //\r
1145         if (!FindFile("GAMEMAPS."EXT,NULL,1))\r
1146                 Quit("CA_Startup(): Can't find level files.");\r
1147 //\r
1148 // MDM end\r
1149 \r
1150 #ifndef NOMAPS\r
1151         CAL_SetupMapFile ();\r
1152 #endif\r
1153 \r
1154 // MDM begin - (GAMERS EDGE)\r
1155 //\r
1156         if (!FindFile("EGAGRAPH."EXT,NULL,2))\r
1157                 Quit("CA_Startup(): Can't find graphics files.");\r
1158 //\r
1159 // MDM end\r
1160 \r
1161 #ifndef NOGRAPHICS\r
1162         CAL_SetupGrFile ();\r
1163 #endif\r
1164 \r
1165         mapon = -1;\r
1166         ca_levelbit = 1;\r
1167         ca_levelnum = 0;\r
1168 \r
1169         drawcachebox    = CAL_DialogDraw;\r
1170         updatecachebox  = CAL_DialogUpdate;\r
1171         finishcachebox  = CAL_DialogFinish;*/\r
1172 }\r
1173 \r
1174 //==========================================================================\r
1175 \r
1176 \r
1177 /*\r
1178 ======================\r
1179 =\r
1180 = CA_Shutdown\r
1181 =\r
1182 = Closes all files\r
1183 =\r
1184 ======================\r
1185 */\r
1186 \r
1187 void CA_Shutdown(global_game_variables_t *gvar)\r
1188 {\r
1189 #ifdef PROFILE\r
1190         close(gvar->handle.profilehandle);\r
1191 #endif\r
1192 //      close(gvar->handle.showmemhandle);\r
1193 /*++++\r
1194         close(maphandle);\r
1195         close(grhandle);\r
1196         close(audiohandle);*/\r
1197 }\r
1198 \r
1199 //===========================================================================\r
1200 \r
1201 /*\r
1202 ======================\r
1203 =\r
1204 = CA_CacheAudioChunk\r
1205 =\r
1206 ======================\r
1207 */\r
1208 /*++++\r
1209 void CA_CacheAudioChunk (int chunk)\r
1210 {\r
1211         long    pos,compressed;\r
1212 #ifdef AUDIOHEADERLINKED\r
1213         long    expanded;\r
1214         memptr  bigbufferseg;\r
1215         byte    far *source;\r
1216 #endif\r
1217 \r
1218         if (audiosegs[chunk])\r
1219         {\r
1220                 MM_SetPurge (&(memptr)audiosegs[chunk],0);\r
1221                 return;                                                 // allready in memory\r
1222         }\r
1223 \r
1224 // MDM begin - (GAMERS EDGE)\r
1225 //\r
1226         if (!FindFile("AUDIO."EXT,NULL,2))\r
1227                 Quit("CA_CacheAudioChunk(): Can't find audio files.");\r
1228 //\r
1229 // MDM end\r
1230 \r
1231 //\r
1232 // load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
1233 // a larger buffer\r
1234 //\r
1235         pos = audiostarts[chunk];\r
1236         compressed = audiostarts[chunk+1]-pos;\r
1237 \r
1238         lseek(audiohandle,pos,SEEK_SET);\r
1239 \r
1240 #ifndef AUDIOHEADERLINKED\r
1241 \r
1242         MM_GetPtr (&(memptr)audiosegs[chunk],compressed);\r
1243         if (mmerror)\r
1244                 return;\r
1245 \r
1246         CA_FarRead(audiohandle,audiosegs[chunk],compressed);\r
1247 \r
1248 #else\r
1249 \r
1250         if (compressed<=BUFFERSIZE)\r
1251         {\r
1252                 CA_FarRead(audiohandle,bufferseg,compressed);\r
1253                 source = bufferseg;\r
1254         }\r
1255         else\r
1256         {\r
1257                 MM_GetPtr(&bigbufferseg,compressed);\r
1258                 if (mmerror)\r
1259                         return;\r
1260                 MM_SetLock (&bigbufferseg,true);\r
1261                 CA_FarRead(audiohandle,bigbufferseg,compressed);\r
1262                 source = bigbufferseg;\r
1263         }\r
1264 \r
1265         expanded = *(long far *)source;\r
1266         source += 4;                    // skip over length\r
1267         MM_GetPtr (&(memptr)audiosegs[chunk],expanded);\r
1268         if (mmerror)\r
1269                 goto done;\r
1270         CAL_HuffExpand (source,audiosegs[chunk],expanded,audiohuffman);\r
1271 \r
1272 done:\r
1273         if (compressed>BUFFERSIZE)\r
1274                 MM_FreePtr(&bigbufferseg);\r
1275 #endif\r
1276 }*/\r
1277 \r
1278 //===========================================================================\r
1279 \r
1280 /*\r
1281 ======================\r
1282 =\r
1283 = CA_LoadAllSounds\r
1284 =\r
1285 = Purges all sounds, then loads all new ones (mode switch)\r
1286 =\r
1287 ======================\r
1288 */\r
1289 /*++++\r
1290 void CA_LoadAllSounds (void)\r
1291 {\r
1292         unsigned        start,i;\r
1293 \r
1294         switch (oldsoundmode)\r
1295         {\r
1296         case sdm_Off:\r
1297                 goto cachein;\r
1298         case sdm_PC:\r
1299                 start = STARTPCSOUNDS;\r
1300                 break;\r
1301         case sdm_AdLib:\r
1302                 start = STARTADLIBSOUNDS;\r
1303                 break;\r
1304         }\r
1305 \r
1306         for (i=0;i<NUMSOUNDS;i++,start++)\r
1307                 if (audiosegs[start])\r
1308                         MM_SetPurge (&(memptr)audiosegs[start],3);              // make purgable\r
1309 \r
1310 cachein:\r
1311 \r
1312         switch (SoundMode)\r
1313         {\r
1314         case sdm_Off:\r
1315                 return;\r
1316         case sdm_PC:\r
1317                 start = STARTPCSOUNDS;\r
1318                 break;\r
1319         case sdm_AdLib:\r
1320                 start = STARTADLIBSOUNDS;\r
1321                 break;\r
1322         }\r
1323 \r
1324         for (i=0;i<NUMSOUNDS;i++,start++)\r
1325                 CA_CacheAudioChunk (start);\r
1326 \r
1327         oldsoundmode = SoundMode;\r
1328 }*/\r
1329 \r
1330 //===========================================================================\r
1331 \r
1332 //++++#if GRMODE == EGAGR\r
1333 \r
1334 /*\r
1335 ======================\r
1336 =\r
1337 = CAL_ShiftSprite\r
1338 =\r
1339 = Make a shifted (one byte wider) copy of a sprite into another area\r
1340 =\r
1341 ======================\r
1342 */\r
1343 /*++++\r
1344 unsigned        static  sheight,swidth;\r
1345 boolean static dothemask;\r
1346 \r
1347 void CAL_ShiftSprite (unsigned segment,unsigned source,unsigned dest,\r
1348         unsigned width, unsigned height, unsigned pixshift, boolean domask)\r
1349 {\r
1350 \r
1351         sheight = height;               // because we are going to reassign bp\r
1352         swidth = width;\r
1353         dothemask = domask;\r
1354 \r
1355 asm     mov     ax,[segment]\r
1356 asm     mov     ds,ax           // source and dest are in same segment, and all local\r
1357 \r
1358 asm     mov     bx,[source]\r
1359 asm     mov     di,[dest]\r
1360 \r
1361 asm     mov     bp,[pixshift]\r
1362 asm     shl     bp,1\r
1363 asm     mov     bp,WORD PTR [shifttabletable+bp]        // bp holds pointer to shift table\r
1364 \r
1365 asm     cmp     [ss:dothemask],0\r
1366 asm     je              skipmask\r
1367 \r
1368 //\r
1369 // table shift the mask\r
1370 //\r
1371 asm     mov     dx,[ss:sheight]\r
1372 \r
1373 domaskrow:\r
1374 \r
1375 asm     mov     BYTE PTR [di],255       // 0xff first byte\r
1376 asm     mov     cx,ss:[swidth]\r
1377 \r
1378 domaskbyte:\r
1379 \r
1380 asm     mov     al,[bx]                         // source\r
1381 asm     not     al\r
1382 asm     inc     bx                                      // next source byte\r
1383 asm     xor     ah,ah\r
1384 asm     shl     ax,1\r
1385 asm     mov     si,ax\r
1386 asm     mov     ax,[bp+si]                      // table shift into two bytes\r
1387 asm     not     ax\r
1388 asm     and     [di],al                         // and with first byte\r
1389 asm     inc     di\r
1390 asm     mov     [di],ah                         // replace next byte\r
1391 \r
1392 asm     loop    domaskbyte\r
1393 \r
1394 asm     inc     di                                      // the last shifted byte has 1s in it\r
1395 asm     dec     dx\r
1396 asm     jnz     domaskrow\r
1397 \r
1398 skipmask:\r
1399 \r
1400 //\r
1401 // table shift the data\r
1402 //\r
1403 asm     mov     dx,ss:[sheight]\r
1404 asm     shl     dx,1\r
1405 asm     shl     dx,1                            // four planes of data\r
1406 \r
1407 dodatarow:\r
1408 \r
1409 asm     mov     BYTE PTR [di],0         // 0 first byte\r
1410 asm     mov     cx,ss:[swidth]\r
1411 \r
1412 dodatabyte:\r
1413 \r
1414 asm     mov     al,[bx]                         // source\r
1415 asm     inc     bx                                      // next source byte\r
1416 asm     xor     ah,ah\r
1417 asm     shl     ax,1\r
1418 asm     mov     si,ax\r
1419 asm     mov     ax,[bp+si]                      // table shift into two bytes\r
1420 asm     or      [di],al                         // or with first byte\r
1421 asm     inc     di\r
1422 asm     mov     [di],ah                         // replace next byte\r
1423 \r
1424 asm     loop    dodatabyte\r
1425 \r
1426 asm     inc     di                                      // the last shifted byte has 0s in it\r
1427 asm     dec     dx\r
1428 asm     jnz     dodatarow\r
1429 \r
1430 //\r
1431 // done\r
1432 //\r
1433 \r
1434 asm     mov     ax,ss                           // restore data segment\r
1435 asm     mov     ds,ax\r
1436 \r
1437 }\r
1438 \r
1439 #endif\r
1440 */\r
1441 //===========================================================================\r
1442 \r
1443 /*\r
1444 ======================\r
1445 =\r
1446 = CAL_CacheSprite\r
1447 =\r
1448 = Generate shifts and set up sprite structure for a given sprite\r
1449 =\r
1450 ======================\r
1451 */\r
1452 /*++++\r
1453 void CAL_CacheSprite (int chunk, byte far *compressed)\r
1454 {\r
1455         int i;\r
1456         unsigned shiftstarts[5];\r
1457         unsigned smallplane,bigplane,expanded;\r
1458         spritetabletype far *spr;\r
1459         spritetype _seg *dest;\r
1460 \r
1461 #if GRMODE == CGAGR\r
1462 //\r
1463 // CGA has no pel panning, so shifts are never needed\r
1464 //\r
1465         spr = &spritetable[chunk-STARTSPRITES];\r
1466         smallplane = spr->width*spr->height;\r
1467         MM_GetPtr (&grsegs[chunk],smallplane*2+MAXSHIFTS*6);\r
1468         if (mmerror)\r
1469                 return;\r
1470         dest = (spritetype _seg *)grsegs[chunk];\r
1471         dest->sourceoffset[0] = MAXSHIFTS*6;    // start data after 3 unsigned tables\r
1472         dest->planesize[0] = smallplane;\r
1473         dest->width[0] = spr->width;\r
1474 \r
1475 //\r
1476 // expand the unshifted shape\r
1477 //\r
1478         CAL_HuffExpand (compressed, &dest->data[0],smallplane*2,grhuffman);\r
1479 \r
1480 #endif\r
1481 \r
1482 \r
1483 #if GRMODE == EGAGR\r
1484 \r
1485 //\r
1486 // calculate sizes\r
1487 //\r
1488         spr = &spritetable[chunk-STARTSPRITES];\r
1489         smallplane = spr->width*spr->height;\r
1490         bigplane = (spr->width+1)*spr->height;\r
1491 \r
1492         shiftstarts[0] = MAXSHIFTS*6;   // start data after 3 unsigned tables\r
1493         shiftstarts[1] = shiftstarts[0] + smallplane*5; // 5 planes in a sprite\r
1494         shiftstarts[2] = shiftstarts[1] + bigplane*5;\r
1495         shiftstarts[3] = shiftstarts[2] + bigplane*5;\r
1496         shiftstarts[4] = shiftstarts[3] + bigplane*5;   // nothing ever put here\r
1497 \r
1498         expanded = shiftstarts[spr->shifts];\r
1499         MM_GetPtr (&grsegs[chunk],expanded);\r
1500         if (mmerror)\r
1501                 return;\r
1502         dest = (spritetype _seg *)grsegs[chunk];\r
1503 \r
1504 //\r
1505 // expand the unshifted shape\r
1506 //\r
1507         CAL_HuffExpand (compressed, &dest->data[0],smallplane*5,grhuffman);\r
1508 \r
1509 //\r
1510 // make the shifts!\r
1511 //\r
1512         switch (spr->shifts)\r
1513         {\r
1514         case    1:\r
1515                 for (i=0;i<4;i++)\r
1516                 {\r
1517                         dest->sourceoffset[i] = shiftstarts[0];\r
1518                         dest->planesize[i] = smallplane;\r
1519                         dest->width[i] = spr->width;\r
1520                 }\r
1521                 break;\r
1522 \r
1523         case    2:\r
1524                 for (i=0;i<2;i++)\r
1525                 {\r
1526                         dest->sourceoffset[i] = shiftstarts[0];\r
1527                         dest->planesize[i] = smallplane;\r
1528                         dest->width[i] = spr->width;\r
1529                 }\r
1530                 for (i=2;i<4;i++)\r
1531                 {\r
1532                         dest->sourceoffset[i] = shiftstarts[1];\r
1533                         dest->planesize[i] = bigplane;\r
1534                         dest->width[i] = spr->width+1;\r
1535                 }\r
1536                 CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
1537                         dest->sourceoffset[2],spr->width,spr->height,4,true);\r
1538                 break;\r
1539 \r
1540         case    4:\r
1541                 dest->sourceoffset[0] = shiftstarts[0];\r
1542                 dest->planesize[0] = smallplane;\r
1543                 dest->width[0] = spr->width;\r
1544 \r
1545                 dest->sourceoffset[1] = shiftstarts[1];\r
1546                 dest->planesize[1] = bigplane;\r
1547                 dest->width[1] = spr->width+1;\r
1548                 CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
1549                         dest->sourceoffset[1],spr->width,spr->height,2,true);\r
1550 \r
1551                 dest->sourceoffset[2] = shiftstarts[2];\r
1552                 dest->planesize[2] = bigplane;\r
1553                 dest->width[2] = spr->width+1;\r
1554                 CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
1555                         dest->sourceoffset[2],spr->width,spr->height,4,true);\r
1556 \r
1557                 dest->sourceoffset[3] = shiftstarts[3];\r
1558                 dest->planesize[3] = bigplane;\r
1559                 dest->width[3] = spr->width+1;\r
1560                 CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
1561                         dest->sourceoffset[3],spr->width,spr->height,6,true);\r
1562 \r
1563                 break;\r
1564 \r
1565         default:\r
1566                 Quit ("CAL_CacheSprite: Bad shifts number!");\r
1567         }\r
1568 \r
1569 #endif\r
1570 }*/\r
1571 \r
1572 //===========================================================================\r
1573 \r
1574 \r
1575 /*\r
1576 ======================\r
1577 =\r
1578 = CAL_ExpandGrChunk\r
1579 =\r
1580 = Does whatever is needed with a pointer to a compressed chunk\r
1581 =\r
1582 ======================\r
1583 */\r
1584 /*++++\r
1585 void CAL_ExpandGrChunk (int chunk, byte far *source)\r
1586 {\r
1587         long    expanded;\r
1588 \r
1589 \r
1590         if (chunk >= STARTTILE8 && chunk < STARTEXTERNS)\r
1591         {\r
1592         //\r
1593         // expanded sizes of tile8/16/32 are implicit\r
1594         //\r
1595 \r
1596 #if GRMODE == EGAGR\r
1597 #define BLOCK           32\r
1598 #define MASKBLOCK       40\r
1599 #endif\r
1600 \r
1601 #if GRMODE == CGAGR\r
1602 #define BLOCK           16\r
1603 #define MASKBLOCK       32\r
1604 #endif\r
1605 \r
1606                 if (chunk<STARTTILE8M)                  // tile 8s are all in one chunk!\r
1607                         expanded = BLOCK*NUMTILE8;\r
1608                 else if (chunk<STARTTILE16)\r
1609                         expanded = MASKBLOCK*NUMTILE8M;\r
1610                 else if (chunk<STARTTILE16M)    // all other tiles are one/chunk\r
1611                         expanded = BLOCK*4;\r
1612                 else if (chunk<STARTTILE32)\r
1613                         expanded = MASKBLOCK*4;\r
1614                 else if (chunk<STARTTILE32M)\r
1615                         expanded = BLOCK*16;\r
1616                 else\r
1617                         expanded = MASKBLOCK*16;\r
1618         }\r
1619         else\r
1620         {\r
1621         //\r
1622         // everything else has an explicit size longword\r
1623         //\r
1624                 expanded = *(long far *)source;\r
1625                 source += 4;                    // skip over length\r
1626         }\r
1627 \r
1628 //\r
1629 // allocate final space, decompress it, and free bigbuffer\r
1630 // Sprites need to have shifts made and various other junk\r
1631 //\r
1632         if (chunk>=STARTSPRITES && chunk< STARTTILE8)\r
1633                 CAL_CacheSprite(chunk,source);\r
1634         else\r
1635         {\r
1636                 MM_GetPtr (&grsegs[chunk],expanded);\r
1637                 if (mmerror)\r
1638                         return;\r
1639                 CAL_HuffExpand (source,grsegs[chunk],expanded,grhuffman);\r
1640         }\r
1641 }\r
1642 */\r
1643 \r
1644 /*\r
1645 ======================\r
1646 =\r
1647 = CAL_ReadGrChunk\r
1648 =\r
1649 = Gets a chunk off disk, optimizing reads to general buffer\r
1650 =\r
1651 ======================\r
1652 */\r
1653 /*++++\r
1654 void CAL_ReadGrChunk (int chunk)\r
1655 {\r
1656         long    pos,compressed;\r
1657         memptr  bigbufferseg;\r
1658         byte    far *source;\r
1659         int             next;\r
1660 \r
1661 //\r
1662 // load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
1663 // a larger buffer\r
1664 //\r
1665         pos = GRFILEPOS(chunk);\r
1666         if (pos<0)                                                      // $FFFFFFFF start is a sparse tile\r
1667           return;\r
1668 \r
1669         next = chunk +1;\r
1670         while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
1671                 next++;\r
1672 \r
1673         compressed = GRFILEPOS(next)-pos;\r
1674 \r
1675         lseek(grhandle,pos,SEEK_SET);\r
1676 \r
1677         if (compressed<=BUFFERSIZE)\r
1678         {\r
1679                 CA_FarRead(grhandle,bufferseg,compressed);\r
1680                 source = bufferseg;\r
1681         }\r
1682         else\r
1683         {\r
1684                 MM_GetPtr(&bigbufferseg,compressed);\r
1685                 if (mmerror)\r
1686                         return;\r
1687                 MM_SetLock (&bigbufferseg,true);\r
1688                 CA_FarRead(grhandle,bigbufferseg,compressed);\r
1689                 source = bigbufferseg;\r
1690         }\r
1691 \r
1692         CAL_ExpandGrChunk (chunk,source);\r
1693 \r
1694         if (compressed>BUFFERSIZE)\r
1695                 MM_FreePtr(&bigbufferseg);\r
1696 }\r
1697 */\r
1698 /*\r
1699 ======================\r
1700 =\r
1701 = CA_CacheGrChunk\r
1702 =\r
1703 = Makes sure a given chunk is in memory, loadiing it if needed\r
1704 =\r
1705 ======================\r
1706 */\r
1707 /*++++\r
1708 void CA_CacheGrChunk (int chunk)\r
1709 {\r
1710         long    pos,compressed;\r
1711         memptr  bigbufferseg;\r
1712         byte    far *source;\r
1713         int             next;\r
1714 \r
1715         gvar->video.grneeded[chunk] |= ca_levelbit;             // make sure it doesn't get removed\r
1716         if (grsegs[chunk])\r
1717         {\r
1718                 MM_SetPurge (&grsegs[chunk],0);\r
1719                 return;                                                 // allready in memory\r
1720         }\r
1721 \r
1722 // MDM begin - (GAMERS EDGE)\r
1723 //\r
1724         if (!FindFile("EGAGRAPH."EXT,NULL,2))\r
1725                 Quit("CA_CacheGrChunk(): Can't find graphics files.");\r
1726 //\r
1727 // MDM end\r
1728 \r
1729 //\r
1730 // load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
1731 // a larger buffer\r
1732 //\r
1733         pos = GRFILEPOS(chunk);\r
1734         if (pos<0)                                                      // $FFFFFFFF start is a sparse tile\r
1735           return;\r
1736 \r
1737         next = chunk +1;\r
1738         while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
1739                 next++;\r
1740 \r
1741         compressed = GRFILEPOS(next)-pos;\r
1742 \r
1743         lseek(grhandle,pos,SEEK_SET);\r
1744 \r
1745         if (compressed<=BUFFERSIZE)\r
1746         {\r
1747                 CA_FarRead(grhandle,bufferseg,compressed);\r
1748                 source = bufferseg;\r
1749         }\r
1750         else\r
1751         {\r
1752                 MM_GetPtr(&bigbufferseg,compressed);\r
1753                 MM_SetLock (&bigbufferseg,true);\r
1754                 CA_FarRead(grhandle,bigbufferseg,compressed);\r
1755                 source = bigbufferseg;\r
1756         }\r
1757 \r
1758         CAL_ExpandGrChunk (chunk,source);\r
1759 \r
1760         if (compressed>BUFFERSIZE)\r
1761                 MM_FreePtr(&bigbufferseg);\r
1762 }\r
1763 */\r
1764 \r
1765 \r
1766 //==========================================================================\r
1767 \r
1768 /*\r
1769 ======================\r
1770 =\r
1771 = CA_CacheMap\r
1772 =\r
1773 ======================\r
1774 */\r
1775 /*++++\r
1776 void CA_CacheMap (int mapnum)\r
1777 {\r
1778         long    pos,compressed;\r
1779         int             plane;\r
1780         memptr  *dest,bigbufferseg;\r
1781         unsigned        size;\r
1782         unsigned        far     *source;\r
1783 #ifdef MAPHEADERLINKED\r
1784         memptr  buffer2seg;\r
1785         long    expanded;\r
1786 #endif\r
1787 \r
1788 \r
1789 // MDM begin - (GAMERS EDGE)\r
1790 //\r
1791         if (!FindFile("GAMEMAPS."EXT,NULL,1))\r
1792                 Quit("CA_CacheMap(): Can't find level files.");\r
1793 //\r
1794 // MDM end\r
1795 \r
1796 \r
1797 //\r
1798 // free up memory from last map\r
1799 //\r
1800         if (mapon>-1 && mapheaderseg[mapon])\r
1801                 MM_SetPurge (&(memptr)mapheaderseg[mapon],3);\r
1802         for (plane=0;plane<MAPPLANES;plane++)\r
1803                 if (mapsegs[plane])\r
1804                         MM_FreePtr (&(memptr)mapsegs[plane]);\r
1805 \r
1806         mapon = mapnum;\r
1807 \r
1808 \r
1809 //\r
1810 // load map header\r
1811 // The header will be cached if it is still around\r
1812 //\r
1813         if (!mapheaderseg[mapnum])\r
1814         {\r
1815                 pos = ((mapfiletype     _seg *)tinf)->headeroffsets[mapnum];\r
1816                 if (pos<0)                                              // $FFFFFFFF start is a sparse map\r
1817                   Quit ("CA_CacheMap: Tried to load a non existent map!");\r
1818 \r
1819                 MM_GetPtr(&(memptr)mapheaderseg[mapnum],sizeof(maptype));\r
1820                 lseek(maphandle,pos,SEEK_SET);\r
1821                 CA_FarRead (maphandle,(memptr)mapheaderseg[mapnum],sizeof(maptype));\r
1822         }\r
1823         else\r
1824                 MM_SetPurge (&(memptr)mapheaderseg[mapnum],0);\r
1825 \r
1826 //\r
1827 // load the planes in\r
1828 // If a plane's pointer still exists it will be overwritten (levels are\r
1829 // allways reloaded, never cached)\r
1830 //\r
1831 \r
1832         size = mapheaderseg[mapnum]->width * mapheaderseg[mapnum]->height * 2;\r
1833 \r
1834         for (plane = 0; plane<MAPPLANES; plane++)\r
1835         {\r
1836                 pos = mapheaderseg[mapnum]->planestart[plane];\r
1837                 compressed = mapheaderseg[mapnum]->planelength[plane];\r
1838 \r
1839                 if (!compressed)\r
1840                         continue;               // the plane is not used in this game\r
1841 \r
1842                 dest = &(memptr)mapsegs[plane];\r
1843                 MM_GetPtr(dest,size);\r
1844 \r
1845                 lseek(maphandle,pos,SEEK_SET);\r
1846                 if (compressed<=BUFFERSIZE)\r
1847                         source = bufferseg;\r
1848                 else\r
1849                 {\r
1850                         MM_GetPtr(&bigbufferseg,compressed);\r
1851                         MM_SetLock (&bigbufferseg,true);\r
1852                         source = bigbufferseg;\r
1853                 }\r
1854 \r
1855                 CA_FarRead(maphandle,(byte far *)source,compressed);\r
1856 #ifdef MAPHEADERLINKED\r
1857                 //\r
1858                 // unhuffman, then unRLEW\r
1859                 // The huffman'd chunk has a two byte expanded length first\r
1860                 // The resulting RLEW chunk also does, even though it's not really\r
1861                 // needed\r
1862                 //\r
1863                 expanded = *source;\r
1864                 source++;\r
1865                 MM_GetPtr (&buffer2seg,expanded);\r
1866                 CAL_CarmackExpand (source, (unsigned far *)buffer2seg,expanded);\r
1867                 CA_RLEWexpand (((unsigned far *)buffer2seg)+1,*dest,size,\r
1868                 ((mapfiletype _seg *)tinf)->RLEWtag);\r
1869                 MM_FreePtr (&buffer2seg);\r
1870 \r
1871 #else\r
1872                 //\r
1873                 // unRLEW, skipping expanded length\r
1874                 //\r
1875                 CA_RLEWexpand (source+1, *dest,size,\r
1876                 ((mapfiletype _seg *)tinf)->RLEWtag);\r
1877 #endif\r
1878 \r
1879                 if (compressed>BUFFERSIZE)\r
1880                         MM_FreePtr(&bigbufferseg);\r
1881         }\r
1882 }*/\r
1883 \r
1884 //===========================================================================\r
1885 \r
1886 /*\r
1887 ======================\r
1888 =\r
1889 = CA_UpLevel\r
1890 =\r
1891 = Goes up a bit level in the needed lists and clears it out.\r
1892 = Everything is made purgable\r
1893 =\r
1894 ======================\r
1895 */\r
1896 /*++++\r
1897 void CA_UpLevel (void)\r
1898 {\r
1899         if (ca_levelnum==7)\r
1900                 Quit ("CA_UpLevel: Up past level 7!");\r
1901 \r
1902         ca_levelbit<<=1;\r
1903         ca_levelnum++;\r
1904 }*/\r
1905 \r
1906 //===========================================================================\r
1907 \r
1908 /*\r
1909 ======================\r
1910 =\r
1911 = CA_DownLevel\r
1912 =\r
1913 = Goes down a bit level in the needed lists and recaches\r
1914 = everything from the lower level\r
1915 =\r
1916 ======================\r
1917 */\r
1918 /*++\r
1919 void CA_DownLevel (void)\r
1920 {\r
1921         if (!ca_levelnum)\r
1922                 Quit ("CA_DownLevel: Down past level 0!");\r
1923         ca_levelbit>>=1;\r
1924         ca_levelnum--;\r
1925         CA_CacheMarks(NULL);\r
1926 }*/\r
1927 \r
1928 //===========================================================================\r
1929 \r
1930 /*\r
1931 ======================\r
1932 =\r
1933 = CA_ClearMarks\r
1934 =\r
1935 = Clears out all the marks at the current level\r
1936 =\r
1937 ======================\r
1938 */\r
1939 void CA_ClearMarks (global_game_variables_t *gvar)\r
1940 {\r
1941         int i;\r
1942 \r
1943         for (i=0;i<NUMCHUNKS;i++)\r
1944                 gvar->video.grneeded[i]&=~gvar->ca.ca_levelbit;\r
1945 }\r
1946 \r
1947 //===========================================================================\r
1948 \r
1949 /*\r
1950 ======================\r
1951 =\r
1952 = CA_ClearAllMarks\r
1953 =\r
1954 = Clears out all the marks on all the levels\r
1955 =\r
1956 ======================\r
1957 */\r
1958 void CA_ClearAllMarks (global_game_variables_t *gvar)\r
1959 {\r
1960         _fmemset (gvar->video.grneeded,0,sizeof(gvar->video.grneeded));\r
1961         gvar->ca.ca_levelbit = 1;\r
1962         gvar->ca.ca_levelnum = 0;\r
1963 }\r
1964 \r
1965 //===========================================================================\r
1966 \r
1967 /*\r
1968 ======================\r
1969 =\r
1970 = CA_FreeGraphics\r
1971 =\r
1972 ======================\r
1973 */\r
1974 /*++++\r
1975 void CA_SetGrPurge (void)\r
1976 {\r
1977         int i;\r
1978 \r
1979 //\r
1980 // free graphics\r
1981 //\r
1982         CA_ClearMarks ();\r
1983 \r
1984         for (i=0;i<NUMCHUNKS;i++)\r
1985                 if (grsegs[i])\r
1986                         MM_SetPurge (&(memptr)grsegs[i],3);\r
1987 }\r
1988 */\r
1989 \r
1990 /*\r
1991 ======================\r
1992 =\r
1993 = CA_SetAllPurge\r
1994 =\r
1995 = Make everything possible purgable\r
1996 =\r
1997 ======================\r
1998 */\r
1999 /*++++++++\r
2000 void CA_SetAllPurge (void)\r
2001 {\r
2002         int i;\r
2003 \r
2004         CA_ClearMarks ();\r
2005 \r
2006 //\r
2007 // free cursor sprite and background save\r
2008 //\r
2009         VW_FreeCursor ();\r
2010 \r
2011 //\r
2012 // free map headers and map planes\r
2013 //\r
2014         for (i=0;i<NUMMAPS;i++)\r
2015                 if (mapheaderseg[i])\r
2016                         MM_SetPurge (&(memptr)mapheaderseg[i],3);\r
2017 \r
2018         for (i=0;i<3;i++)\r
2019                 if (mapsegs[i])\r
2020                         MM_FreePtr (&(memptr)mapsegs[i]);\r
2021 \r
2022 //\r
2023 // free sounds\r
2024 //\r
2025         for (i=0;i<NUMSNDCHUNKS;i++)\r
2026                 if (audiosegs[i])\r
2027                         MM_SetPurge (&(memptr)audiosegs[i],3);\r
2028 \r
2029 //\r
2030 // free graphics\r
2031 //\r
2032         CA_FreeGraphics ();\r
2033 }\r
2034 \r
2035 \r
2036 void CA_SetGrPurge (void)\r
2037 {\r
2038         int i;\r
2039 \r
2040 //\r
2041 // free graphics\r
2042 //\r
2043         for (i=0;i<NUMCHUNKS;i++)\r
2044                 if (grsegs[i])\r
2045                         MM_SetPurge (&(memptr)grsegs[i],3);\r
2046 }*/\r
2047 \r
2048 \r
2049 //===========================================================================\r
2050 \r
2051 \r
2052 /*\r
2053 ======================\r
2054 =\r
2055 = CAL_DialogDraw\r
2056 =\r
2057 ======================\r
2058 */\r
2059 /*\r
2060 #define NUMBARS (17l*8)\r
2061 #define BARSTEP 8\r
2062 \r
2063 unsigned        thx,thy,lastx;\r
2064 long            barx,barstep;\r
2065 \r
2066 void    CAL_DialogDraw (char *title,unsigned numcache)\r
2067 {\r
2068         unsigned        homex,homey,x;\r
2069 \r
2070         barstep = (NUMBARS<<16)/numcache;\r
2071 \r
2072 //\r
2073 // draw dialog window (masked tiles 12 - 20 are window borders)\r
2074 //\r
2075         US_CenterWindow (20,8);\r
2076         homex = PrintX;\r
2077         homey = PrintY;\r
2078 \r
2079         US_CPrint ("Loading");\r
2080         fontcolor = F_SECONDCOLOR;\r
2081         US_CPrint (title);\r
2082         fontcolor = F_BLACK;\r
2083 \r
2084 //\r
2085 // draw thermometer bar\r
2086 //\r
2087         thx = homex + 8;\r
2088         thy = homey + 32;\r
2089         VWB_DrawTile8(thx,thy,0);               // CAT3D numbers\r
2090         VWB_DrawTile8(thx,thy+8,3);\r
2091         VWB_DrawTile8(thx,thy+16,6);\r
2092         VWB_DrawTile8(thx+17*8,thy,2);\r
2093         VWB_DrawTile8(thx+17*8,thy+8,5);\r
2094         VWB_DrawTile8(thx+17*8,thy+16,8);\r
2095         for (x=thx+8;x<thx+17*8;x+=8)\r
2096         {\r
2097                 VWB_DrawTile8(x,thy,1);\r
2098                 VWB_DrawTile8(x,thy+8,4);\r
2099                 VWB_DrawTile8(x,thy+16,7);\r
2100         }\r
2101 \r
2102         thx += 4;               // first line location\r
2103         thy += 5;\r
2104         barx = (long)thx<<16;\r
2105         lastx = thx;\r
2106 \r
2107         VW_UpdateScreen();\r
2108 }\r
2109 */\r
2110 \r
2111 /*\r
2112 ======================\r
2113 =\r
2114 = CAL_DialogUpdate\r
2115 =\r
2116 ======================\r
2117 */\r
2118 /*\r
2119 void    CAL_DialogUpdate (void)\r
2120 {\r
2121         unsigned        x,xh;\r
2122 \r
2123         barx+=barstep;\r
2124         xh = barx>>16;\r
2125         if (xh - lastx > BARSTEP)\r
2126         {\r
2127                 for (x=lastx;x<=xh;x++)\r
2128 #if GRMODE == EGAGR\r
2129                         VWB_Vlin (thy,thy+13,x,14);\r
2130 #endif\r
2131 #if GRMODE == CGAGR\r
2132                         VWB_Vlin (thy,thy+13,x,SECONDCOLOR);\r
2133 #endif\r
2134                 lastx = xh;\r
2135                 VW_UpdateScreen();\r
2136         }\r
2137 }*/\r
2138 \r
2139 /*\r
2140 ======================\r
2141 =\r
2142 = CAL_DialogFinish\r
2143 =\r
2144 ======================\r
2145 */\r
2146 /*\r
2147 void    CAL_DialogFinish (void)\r
2148 {\r
2149         unsigned        x,xh;\r
2150 \r
2151         xh = thx + NUMBARS;\r
2152         for (x=lastx;x<=xh;x++)\r
2153 #if GRMODE == EGAGR\r
2154                 VWB_Vlin (thy,thy+13,x,14);\r
2155 #endif\r
2156 #if GRMODE == CGAGR\r
2157                 VWB_Vlin (thy,thy+13,x,SECONDCOLOR);\r
2158 #endif\r
2159         VW_UpdateScreen();\r
2160 \r
2161 }*/\r
2162 \r
2163 //===========================================================================\r
2164 \r
2165 /*\r
2166 ======================\r
2167 =\r
2168 = CA_CacheMarks\r
2169 =\r
2170 ======================\r
2171 *//*\r
2172 #define MAXEMPTYREAD    1024\r
2173 \r
2174 void CA_CacheMarks (char *title)\r
2175 {\r
2176         boolean dialog;\r
2177         int     i,next,numcache;\r
2178         long    pos,endpos,nextpos,nextendpos,compressed;\r
2179         long    bufferstart,bufferend;  // file position of general buffer\r
2180         byte    far *source;\r
2181         memptr  bigbufferseg;\r
2182 \r
2183         dialog = (title!=NULL);\r
2184 \r
2185         numcache = 0;\r
2186 //\r
2187 // go through and make everything not needed purgable\r
2188 //\r
2189         for (i=0;i<NUMCHUNKS;i++)\r
2190                 if (gvar->video.grneeded[i]&ca_levelbit)\r
2191                 {\r
2192                         if (grsegs[i])                                  // its allready in memory, make\r
2193                                 MM_SetPurge(&grsegs[i],0);      // sure it stays there!\r
2194                         else\r
2195                                 numcache++;\r
2196                 }\r
2197                 else\r
2198                 {\r
2199                         if (grsegs[i])                                  // not needed, so make it purgeable\r
2200                                 MM_SetPurge(&grsegs[i],3);\r
2201                 }\r
2202 \r
2203         if (!numcache)                  // nothing to cache!\r
2204                 return;\r
2205 \r
2206 // MDM begin - (GAMERS EDGE)\r
2207 //\r
2208         if (!FindFile("EGAGRAPH."EXT,NULL,2))\r
2209                 Quit("CA_CacheMarks(): Can't find graphics files.");\r
2210 //\r
2211 // MDM end\r
2212 \r
2213         if (dialog)\r
2214         {\r
2215 #ifdef PROFILE\r
2216                 write(profilehandle,title,strlen(title));\r
2217                 write(profilehandle,"\n",1);\r
2218 #endif\r
2219                 if (drawcachebox)\r
2220                         drawcachebox(title,numcache);\r
2221         }\r
2222 \r
2223 //\r
2224 // go through and load in anything still needed\r
2225 //\r
2226         bufferstart = bufferend = 0;            // nothing good in buffer now\r
2227 \r
2228         for (i=0;i<NUMCHUNKS;i++)\r
2229                 if ( (gvar->video.grneeded[i]&ca_levelbit) && !grsegs[i])\r
2230                 {\r
2231 //\r
2232 // update thermometer\r
2233 //\r
2234                         if (dialog && updatecachebox)\r
2235                                 updatecachebox ();\r
2236 \r
2237                         pos = GRFILEPOS(i);\r
2238                         if (pos<0)\r
2239                                 continue;\r
2240 \r
2241                         next = i +1;\r
2242                         while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
2243                                 next++;\r
2244 \r
2245                         compressed = GRFILEPOS(next)-pos;\r
2246                         endpos = pos+compressed;\r
2247 \r
2248                         if (compressed<=BUFFERSIZE)\r
2249                         {\r
2250                                 if (bufferstart<=pos\r
2251                                 && bufferend>= endpos)\r
2252                                 {\r
2253                                 // data is allready in buffer\r
2254                                         source = (byte _seg *)bufferseg+(pos-bufferstart);\r
2255                                 }\r
2256                                 else\r
2257                                 {\r
2258                                 // load buffer with a new block from disk\r
2259                                 // try to get as many of the needed blocks in as possible\r
2260                                         while ( next < NUMCHUNKS )\r
2261                                         {\r
2262                                                 while (next < NUMCHUNKS &&\r
2263                                                 !(gvar->video.grneeded[next]&ca_levelbit && !grsegs[next]))\r
2264                                                         next++;\r
2265                                                 if (next == NUMCHUNKS)\r
2266                                                         continue;\r
2267 \r
2268                                                 nextpos = GRFILEPOS(next);\r
2269                                                 while (GRFILEPOS(++next) == -1) // skip past any sparse tiles\r
2270                                                         ;\r
2271                                                 nextendpos = GRFILEPOS(next);\r
2272                                                 if (nextpos - endpos <= MAXEMPTYREAD\r
2273                                                 && nextendpos-pos <= BUFFERSIZE)\r
2274                                                         endpos = nextendpos;\r
2275                                                 else\r
2276                                                         next = NUMCHUNKS;                       // read pos to posend\r
2277                                         }\r
2278 \r
2279                                         lseek(grhandle,pos,SEEK_SET);\r
2280                                         CA_FarRead(grhandle,bufferseg,endpos-pos);\r
2281                                         bufferstart = pos;\r
2282                                         bufferend = endpos;\r
2283                                         source = bufferseg;\r
2284                                 }\r
2285                         }\r
2286                         else\r
2287                         {\r
2288                         // big chunk, allocate temporary buffer\r
2289                                 MM_GetPtr(&bigbufferseg,compressed);\r
2290                                 if (mmerror)\r
2291                                         return;\r
2292                                 MM_SetLock (&bigbufferseg,true);\r
2293                                 lseek(grhandle,pos,SEEK_SET);\r
2294                                 CA_FarRead(grhandle,bigbufferseg,compressed);\r
2295                                 source = bigbufferseg;\r
2296                         }\r
2297 \r
2298                         CAL_ExpandGrChunk (i,source);\r
2299                         if (mmerror)\r
2300                                 return;\r
2301 \r
2302                         if (compressed>BUFFERSIZE)\r
2303                                 MM_FreePtr(&bigbufferseg);\r
2304 \r
2305                 }\r
2306 \r
2307 //\r
2308 // finish up any thermometer remnants\r
2309 //\r
2310                 if (dialog && finishcachebox)\r
2311                         finishcachebox();\r
2312 }*/\r