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