]> 4ch.mooo.com Git - 16.git/blob - src/lib/16_ca.c
bcexmm compiles again ^^
[16.git] / src / lib / 16_ca.c
1 /* Catacomb Apocalypse Source Code\r
2  * Copyright (C) 1993-2014 Flat Rock Software\r
3  *\r
4  * This program is free software; you can redistribute it and/or modify\r
5  * it under the terms of the GNU General Public License as published by\r
6  * the Free Software Foundation; either version 2 of the License, or\r
7  * (at your option) any later version.\r
8  *\r
9  * This program is distributed in the hope that it will be useful,\r
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
12  * GNU General Public License for more details.\r
13  *\r
14  * You should have received a copy of the GNU General Public License along\r
15  * with this program; if not, write to the Free Software Foundation, Inc.,\r
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
17  */\r
18 \r
19 // ID_CA.C\r
20 \r
21 /*\r
22 =============================================================================\r
23 \r
24 Id Software Caching Manager\r
25 ---------------------------\r
26 \r
27 Must be started BEFORE the memory manager, because it needs to get the headers\r
28 loaded into the data segment\r
29 \r
30 =============================================================================\r
31 */\r
32 \r
33 #include "src/lib/16_ca.h"\r
34 #pragma hdrstop\r
35 \r
36 #pragma warn -pro\r
37 #pragma warn -use\r
38 \r
39 //#define THREEBYTEGRSTARTS\r
40 \r
41 /*\r
42 =============================================================================\r
43 \r
44                                                  LOCAL CONSTANTS\r
45 \r
46 =============================================================================\r
47 */\r
48 \r
49 typedef struct\r
50 {\r
51   word bit0,bit1;       // 0-255 is a character, > is a pointer to a node\r
52 } huffnode;\r
53 \r
54 \r
55 /*typedef struct\r
56 {\r
57         unsigned        RLEWtag;\r
58         long            headeroffsets[100];\r
59         byte            tileinfo[];\r
60 } mapfiletype;*/\r
61 \r
62 \r
63 /*\r
64 =============================================================================\r
65 \r
66                                                  GLOBAL VARIABLES\r
67 \r
68 =============================================================================\r
69 */\r
70 \r
71 /*byte          _seg    *tinf;\r
72 int                     mapon;\r
73 \r
74 unsigned        _seg    *mapsegs[3];\r
75 maptype         _seg    *mapheaderseg[NUMMAPS];\r
76 byte            _seg    *audiosegs[NUMSNDCHUNKS];\r
77 void            _seg    *grsegs[NUMCHUNKS];\r
78 \r
79 byte            far     grneeded[NUMCHUNKS];*/\r
80 \r
81 void    (*drawcachebox)         (char *title, unsigned numcache);\r
82 void    (*updatecachebox)       (void);\r
83 void    (*finishcachebox)       (void);\r
84 \r
85 /*\r
86 =============================================================================\r
87 \r
88                                                  LOCAL VARIABLES\r
89 \r
90 =============================================================================\r
91 */\r
92 \r
93 /*extern        long    far     CGAhead;\r
94 extern  long    far     EGAhead;\r
95 extern  byte    CGAdict;\r
96 extern  byte    EGAdict;\r
97 extern  byte    far     maphead;\r
98 extern  byte    mapdict;\r
99 extern  byte    far     audiohead;\r
100 extern  byte    audiodict;\r
101 \r
102 \r
103 long            _seg *grstarts; // array of offsets in egagraph, -1 for sparse\r
104 long            _seg *audiostarts;      // array of offsets in audio / audiot\r
105 \r
106 #ifdef GRHEADERLINKED\r
107 huffnode        *grhuffman;\r
108 #else\r
109 huffnode        grhuffman[255];\r
110 #endif\r
111 \r
112 #ifdef AUDIOHEADERLINKED\r
113 huffnode        *audiohuffman;\r
114 #else\r
115 huffnode        audiohuffman[255];\r
116 #endif\r
117 \r
118 \r
119 int                     grhandle;               // handle to EGAGRAPH\r
120 int                     maphandle;              // handle to MAPTEMP / GAMEMAPS\r
121 int                     audiohandle;    // handle to AUDIOT / AUDIO\r
122 \r
123 long            chunkcomplen,chunkexplen;\r
124 \r
125 SDMode          oldsoundmode;\r
126 \r
127 \r
128 \r
129 void    CAL_DialogDraw (char *title,unsigned numcache);\r
130 void    CAL_DialogUpdate (void);\r
131 void    CAL_DialogFinish (void);*/\r
132 //void  CAL_CarmackExpand (unsigned far *source, unsigned far *dest,unsigned length);\r
133 \r
134 \r
135 /*++++#ifdef THREEBYTEGRSTARTS\r
136 #define FILEPOSSIZE     3\r
137 //#define       GRFILEPOS(c) (*(long far *)(((byte far *)grstarts)+(c)*3)&0xffffff)\r
138 long GRFILEPOS(int c)\r
139 {\r
140         long value;\r
141         int     offset;\r
142 \r
143         offset = c*3;\r
144 \r
145         value = *(long far *)(((byte far *)grstarts)+offset);\r
146 \r
147         value &= 0x00ffffffl;\r
148 \r
149         if (value == 0xffffffl)\r
150                 value = -1;\r
151 \r
152         return value;\r
153 };\r
154 #else\r
155 #define FILEPOSSIZE     4\r
156 #define GRFILEPOS(c) (grstarts[c])\r
157 #endif*/\r
158 \r
159 /*\r
160 =============================================================================\r
161 \r
162                                            LOW LEVEL ROUTINES\r
163 \r
164 =============================================================================\r
165 */\r
166 \r
167 /*\r
168 ============================\r
169 =\r
170 = CA_OpenDebug / CA_CloseDebug\r
171 =\r
172 = Opens a binary file with the handle "debughandle"\r
173 =\r
174 ============================\r
175 */\r
176 void CA_OpenDebug(global_game_variables_t *gvar)\r
177 {\r
178 #ifdef __BORLANDC__\r
179         unlink("debug.16b");\r
180         gvar->handle.debughandle = open("debug.16b", O_CREAT | O_WRONLY | O_TEXT);\r
181 #endif\r
182 #ifdef __WATCOMC__\r
183         unlink("debug.16w");\r
184         gvar->handle.debughandle = open("debug.16w", O_CREAT | O_WRONLY | O_TEXT);\r
185 #endif\r
186 }\r
187 \r
188 void CA_CloseDebug(global_game_variables_t *gvar)\r
189 {\r
190         close(gvar->handle.debughandle);\r
191 }\r
192 \r
193 \r
194 \r
195 /*\r
196 ============================\r
197 =\r
198 = CAL_GetGrChunkLength\r
199 =\r
200 = Gets the length of an explicit length chunk (not tiles)\r
201 = The file pointer is positioned so the compressed data can be read in next.\r
202 =\r
203 ============================\r
204 */\r
205 /*++++\r
206 void CAL_GetGrChunkLength (int chunk)\r
207 {\r
208         lseek(grhandle,GRFILEPOS(chunk),SEEK_SET);\r
209         read(grhandle,&chunkexplen,sizeof(chunkexplen));\r
210         chunkcomplen = GRFILEPOS(chunk+1)-GRFILEPOS(chunk)-4;\r
211 }*/\r
212 \r
213 \r
214 /*\r
215 ==========================\r
216 =\r
217 = CA_FarRead\r
218 =\r
219 = Read from a file to a far pointer\r
220 =\r
221 ==========================\r
222 */\r
223 \r
224 boolean CA_FarRead(int handle, byte huge *dest, dword length, mminfo_t *mm)\r
225 {\r
226         boolean flag;\r
227         //dword fat=0;\r
228         //word segm=0;\r
229         if(mm->EMSVer<0x40)\r
230         if(length>0xfffflu)\r
231         {\r
232                 printf("File is a fat bakapee\n");\r
233                 //segm=(length%0xfffflu)-1;\r
234                 //fat=segm*0xfffflu;\r
235                 //length-=fat;\r
236                 printf("CA_FarRead doesn't support 64K reads yet!\n");\r
237                 return 0;//TODO: EXPAND!!!\r
238         }\r
239 \r
240         //if(!fat&&!segm)\r
241         //{\r
242                 __asm {\r
243                         push    ds\r
244                         mov     bx,[handle]\r
245                         mov     cx,[WORD PTR length]\r
246                         mov     dx,[WORD PTR dest]\r
247                         mov     ds,[WORD PTR dest+2]\r
248                         mov     ah,0x3f                         // READ w/handle\r
249                         int     21h\r
250                         pop     ds\r
251                         jnc     good\r
252                         mov     errno,ax\r
253                         mov     flag,0\r
254                         jmp End\r
255 #ifdef __BORLANDC__\r
256                 }\r
257 #endif\r
258 good:\r
259 #ifdef __BORLANDC__\r
260                 __asm {\r
261 #endif\r
262                         cmp     ax,[WORD PTR length]\r
263                         je      done\r
264 //                      errno = EINVFMT;                        // user manager knows this is bad read\r
265                         mov     flag,0\r
266                         jmp End\r
267 #ifdef __BORLANDC__\r
268                 }\r
269 #endif\r
270 done:\r
271 #ifdef __BORLANDC__\r
272                 __asm {\r
273 #endif\r
274                         mov     flag,1\r
275 #ifdef __BORLANDC__\r
276                 }\r
277 #endif\r
278 End:\r
279 #ifdef __WATCOMC__\r
280                 }\r
281 #endif\r
282         return flag;\r
283 }\r
284 \r
285 \r
286 /*\r
287 ==========================\r
288 =\r
289 = CA_SegWrite\r
290 =\r
291 = Write from a file to a far pointer\r
292 =\r
293 ==========================\r
294 */\r
295 \r
296 boolean CA_FarWrite(int handle, byte huge *source, dword length, mminfo_t *mm)\r
297 {\r
298         boolean flag;\r
299         //dword fat=0;\r
300         //word segm=0;\r
301         if(mm->EMSVer<0x40)\r
302         if(length>0xfffflu)\r
303         {\r
304                 printf("File is a fat bakapee\n");\r
305                 //segm=(length%0xfffflu)-1;\r
306                 //fat=segm*0xfffflu;\r
307                 //length-=fat;\r
308                 printf("CA_FarRead doesn't support 64K reads yet!\n");\r
309                 return 0;\r
310         }\r
311 \r
312         //if(!fat&&!segm)\r
313         //{\r
314                 __asm {\r
315                         push    ds\r
316                         mov     bx,[handle]\r
317                         mov     cx,[WORD PTR length]\r
318                         mov     dx,[WORD PTR source]\r
319                         mov     ds,[WORD PTR source+2]\r
320                         mov     ah,0x40                 // WRITE w/handle\r
321                         int     21h\r
322                         pop     ds\r
323                         jnc     good\r
324                         mov     errno,ax\r
325                         mov flag,0\r
326                         jmp End\r
327 #ifdef __BORLANDC__\r
328                 }\r
329 #endif\r
330 good:\r
331 #ifdef __BORLANDC__\r
332                 __asm {\r
333 #endif\r
334                         cmp     ax,[WORD PTR length]\r
335                         je      done\r
336                         //errno = ENOMEM;                               // user manager knows this is bad write\r
337                         mov     flag,0\r
338                         jmp End\r
339 #ifdef __BORLANDC__\r
340                 }\r
341 #endif\r
342 done:\r
343 #ifdef __BORLANDC__\r
344                 __asm {\r
345 #endif\r
346                         mov     flag,1\r
347 #ifdef __BORLANDC__\r
348                 }\r
349 #endif\r
350 End:\r
351 #ifdef __WATCOMC__\r
352                 }\r
353 #endif\r
354         return flag;\r
355 }\r
356 \r
357 \r
358 /*\r
359 ==========================\r
360 =\r
361 = CA_ReadFile\r
362 =\r
363 = Reads a file into an allready allocated buffer\r
364 =\r
365 ==========================\r
366 */\r
367 \r
368 boolean CA_ReadFile(char *filename, memptr *ptr, mminfo_t *mm)\r
369 {\r
370         int handle;\r
371         sdword size;\r
372         //long size;\r
373 \r
374         if((handle = open(filename,O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
375                 return false;\r
376 \r
377         size = filelength(handle);\r
378         if(!CA_FarRead(handle,*ptr,size, mm))\r
379         {\r
380                 close (handle);\r
381                 return false;\r
382         }\r
383         close (handle);\r
384         return true;\r
385 }\r
386 \r
387 \r
388 /*\r
389 ==========================\r
390 =\r
391 = CA_WriteFile\r
392 =\r
393 = Writes a file from a memory buffer\r
394 =\r
395 ==========================\r
396 */\r
397 \r
398 boolean CA_WriteFile (char *filename, void far *ptr, long length, mminfo_t *mm)\r
399 {\r
400         int handle;\r
401         sdword size;\r
402         //long size;\r
403 \r
404         handle = open(filename,O_CREAT | O_BINARY | O_WRONLY,\r
405                                 S_IREAD | S_IWRITE | S_IFREG);\r
406 \r
407         if (handle == -1)\r
408                 return false;\r
409 \r
410         if (!CA_FarWrite (handle,ptr,length, mm))\r
411         {\r
412                 close(handle);\r
413                 return false;\r
414         }\r
415         close(handle);\r
416         return true;\r
417 }\r
418 \r
419 \r
420 \r
421 /*\r
422 ==========================\r
423 =\r
424 = CA_LoadFile\r
425 =\r
426 = Allocate space for and load a file\r
427 =\r
428 ==========================\r
429 */\r
430 \r
431 boolean CA_LoadFile(char *filename, memptr *ptr, mminfo_t *mm, mminfotype *mmi)\r
432 {\r
433         int handle;\r
434         sdword size;\r
435         //long size;\r
436 \r
437         if((handle = open(filename,O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
438                 return false;\r
439 \r
440         size = filelength (handle);\r
441         MM_GetPtr(ptr,size, mm, mmi);\r
442         if(!CA_FarRead(handle,*ptr,size, mm))\r
443         {\r
444                 close(handle);\r
445                 return false;\r
446         }\r
447         close(handle);\r
448         return true;\r
449 }\r
450 \r
451 /*\r
452 ============================================================================\r
453 \r
454                 COMPRESSION routines, see JHUFF.C for more\r
455 \r
456 ============================================================================\r
457 */\r
458 \r
459 \r
460 \r
461 /*\r
462 ===============\r
463 =\r
464 = CAL_OptimizeNodes\r
465 =\r
466 = Goes through a huffman table and changes the 256-511 node numbers to the\r
467 = actular address of the node.  Must be called before CAL_HuffExpand\r
468 =\r
469 ===============\r
470 */\r
471 \r
472 void CAL_OptimizeNodes(huffnode *table)\r
473 {\r
474   huffnode *node;\r
475   int i;\r
476 \r
477   node = table;\r
478 \r
479   for (i=0;i<255;i++)\r
480   {\r
481         if (node->bit0 >= 256)\r
482           node->bit0 = (unsigned)(table+(node->bit0-256));\r
483         if (node->bit1 >= 256)\r
484           node->bit1 = (unsigned)(table+(node->bit1-256));\r
485         node++;\r
486   }\r
487 }\r
488 \r
489 \r
490 \r
491 /*\r
492 ======================\r
493 =\r
494 = CAL_HuffExpand\r
495 =\r
496 = Length is the length of the EXPANDED data\r
497 =\r
498 ======================\r
499 */\r
500 \r
501 void CAL_HuffExpand (byte huge *source, byte huge *dest,\r
502   long length,huffnode *hufftable)\r
503 {\r
504 //  unsigned bit,byte,node,code;\r
505   unsigned sourceseg,sourceoff,destseg,destoff,endoff;\r
506   huffnode *headptr;\r
507 //  huffnode *nodeon;\r
508 \r
509   headptr = hufftable+254;      // head node is allways node 254\r
510 \r
511   source++;     // normalize\r
512   source--;\r
513   dest++;\r
514   dest--;\r
515 \r
516   sourceseg = FP_SEG(source);\r
517   sourceoff = FP_OFF(source);\r
518   destseg = FP_SEG(dest);\r
519   destoff = FP_OFF(dest);\r
520   endoff = destoff+length;\r
521 \r
522 //\r
523 // ds:si source\r
524 // es:di dest\r
525 // ss:bx node pointer\r
526 //\r
527 \r
528         if (length <0xfff0)\r
529         {\r
530 \r
531 //--------------------------\r
532 // expand less than 64k of data\r
533 //--------------------------\r
534 \r
535         __asm {\r
536 ////            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 (void)\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 #ifdef MAPHEADERLINKED\r
1106         if ((maphandle = open("GAMEMAPS."EXT,\r
1107                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1108                 Quit ("Can't open GAMEMAPS."EXT"!");\r
1109 #else\r
1110         if ((maphandle = open("MAPTEMP."EXT,\r
1111                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1112                 Quit ("Can't open MAPTEMP."EXT"!");\r
1113 #endif\r
1114 }*/\r
1115 \r
1116 //==========================================================================\r
1117 \r
1118 \r
1119 /*\r
1120 ======================\r
1121 =\r
1122 = CAL_SetupAudioFile\r
1123 =\r
1124 ======================\r
1125 */\r
1126 \r
1127 /*void CAL_SetupAudioFile (void)\r
1128 {\r
1129         int handle;\r
1130         long length;\r
1131 \r
1132 //\r
1133 // load maphead.ext (offsets and tileinfo for map file)\r
1134 //\r
1135 #ifndef AUDIOHEADERLINKED\r
1136         if ((handle = open("AUDIOHED."EXT,\r
1137                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1138                 Quit ("Can't open AUDIOHED."EXT"!");\r
1139         length = filelength(handle);\r
1140         MM_GetPtr (&(memptr)audiostarts,length);\r
1141         CA_FarRead(handle, (byte far *)audiostarts, length);\r
1142         close(handle);\r
1143 #else\r
1144         audiohuffman = (huffnode *)&audiodict;\r
1145         CAL_OptimizeNodes (audiohuffman);\r
1146         audiostarts = (long _seg *)FP_SEG(&audiohead);\r
1147 #endif\r
1148 \r
1149 //\r
1150 // open the data file\r
1151 //\r
1152 #ifndef AUDIOHEADERLINKED\r
1153         if ((audiohandle = open("AUDIOT."EXT,\r
1154                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1155                 Quit ("Can't open AUDIOT."EXT"!");\r
1156 #else\r
1157         if ((audiohandle = open("AUDIO."EXT,\r
1158                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1159                 Quit ("Can't open AUDIO."EXT"!");\r
1160 #endif\r
1161 }*/\r
1162 \r
1163 //==========================================================================\r
1164 \r
1165 \r
1166 /*\r
1167 ======================\r
1168 =\r
1169 = CA_Startup\r
1170 =\r
1171 = Open all files and load in headers\r
1172 =\r
1173 ======================\r
1174 */\r
1175 \r
1176 void CA_Startup(global_game_variables_t *gvar)\r
1177 {\r
1178 #ifdef PROFILE\r
1179 #ifdef __BORLANDC__\r
1180         unlink("profile.16b");\r
1181         gvar->handle.profilehandle = open("profile.16b", O_CREAT | O_WRONLY | O_TEXT);\r
1182 #endif\r
1183 #ifdef __WATCOMC__\r
1184         unlink("profile.16w");\r
1185         gvar->handle.profilehandle = open("profile.16w", O_CREAT | O_WRONLY | O_TEXT);\r
1186 #endif\r
1187 #endif//profile\r
1188 \r
1189 #ifdef __BORLANDC__\r
1190         unlink("meminfo.16b");\r
1191         gvar->handle.showmemhandle = open("meminfo.16b", O_CREAT | O_WRONLY | O_TEXT);\r
1192 #endif\r
1193 #ifdef __WATCOMC__\r
1194         unlink("meminfo.16w");\r
1195         gvar->handle.showmemhandle = open("meminfo.16w", O_CREAT | O_WRONLY | O_TEXT);\r
1196 #endif\r
1197 /*      CAL_SetupMapFile ();\r
1198         CAL_SetupGrFile ();\r
1199         CAL_SetupAudioFile ();*/\r
1200 /*++++\r
1201 // MDM begin - (GAMERS EDGE)\r
1202 //\r
1203         if(!FindFile("AUDIO."EXT,NULL,2))\r
1204                 Quit("CA_Startup(): Can't find audio files.");\r
1205 //\r
1206 // MDM end\r
1207 \r
1208 #ifndef NOAUDIO\r
1209         CAL_SetupAudioFile();\r
1210 #endif\r
1211 \r
1212 // MDM begin - (GAMERS EDGE)\r
1213 //\r
1214         if (!FindFile("GAMEMAPS."EXT,NULL,1))\r
1215                 Quit("CA_Startup(): Can't find level files.");\r
1216 //\r
1217 // MDM end\r
1218 \r
1219 #ifndef NOMAPS\r
1220         CAL_SetupMapFile ();\r
1221 #endif\r
1222 \r
1223 // MDM begin - (GAMERS EDGE)\r
1224 //\r
1225         if (!FindFile("EGAGRAPH."EXT,NULL,2))\r
1226                 Quit("CA_Startup(): Can't find graphics files.");\r
1227 //\r
1228 // MDM end\r
1229 \r
1230 #ifndef NOGRAPHICS\r
1231         CAL_SetupGrFile ();\r
1232 #endif*/\r
1233 \r
1234         gvar->ca.mapon = -1;\r
1235         gvar->ca.ca_levelbit = 1;\r
1236         gvar->ca.ca_levelnum = 0;\r
1237 \r
1238 /*      drawcachebox    = CAL_DialogDraw;\r
1239         updatecachebox  = CAL_DialogUpdate;\r
1240         finishcachebox  = CAL_DialogFinish;*/\r
1241 }\r
1242 \r
1243 //==========================================================================\r
1244 \r
1245 \r
1246 /*\r
1247 ======================\r
1248 =\r
1249 = CA_Shutdown\r
1250 =\r
1251 = Closes all files\r
1252 =\r
1253 ======================\r
1254 */\r
1255 \r
1256 void CA_Shutdown(global_game_variables_t *gvar)\r
1257 {\r
1258 #ifdef PROFILE\r
1259         close(gvar->handle.profilehandle);\r
1260 #endif\r
1261         close(gvar->handle.showmemhandle);\r
1262 /*++++\r
1263         close(maphandle);\r
1264         close(grhandle);\r
1265         close(audiohandle);*/\r
1266 }\r
1267 \r
1268 //===========================================================================\r
1269 \r
1270 /*\r
1271 ======================\r
1272 =\r
1273 = CA_CacheAudioChunk\r
1274 =\r
1275 ======================\r
1276 */\r
1277 /*++++\r
1278 void CA_CacheAudioChunk (int chunk)\r
1279 {\r
1280         long    pos,compressed;\r
1281 #ifdef AUDIOHEADERLINKED\r
1282         long    expanded;\r
1283         memptr  bigbufferseg;\r
1284         byte    far *source;\r
1285 #endif\r
1286 \r
1287         if (audiosegs[chunk])\r
1288         {\r
1289                 MM_SetPurge (&(memptr)audiosegs[chunk],0);\r
1290                 return;                                                 // allready in memory\r
1291         }\r
1292 \r
1293 // MDM begin - (GAMERS EDGE)\r
1294 //\r
1295         if (!FindFile("AUDIO."EXT,NULL,2))\r
1296                 Quit("CA_CacheAudioChunk(): Can't find audio files.");\r
1297 //\r
1298 // MDM end\r
1299 \r
1300 //\r
1301 // load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
1302 // a larger buffer\r
1303 //\r
1304         pos = audiostarts[chunk];\r
1305         compressed = audiostarts[chunk+1]-pos;\r
1306 \r
1307         lseek(audiohandle,pos,SEEK_SET);\r
1308 \r
1309 #ifndef AUDIOHEADERLINKED\r
1310 \r
1311         MM_GetPtr (&(memptr)audiosegs[chunk],compressed);\r
1312         if (mmerror)\r
1313                 return;\r
1314 \r
1315         CA_FarRead(audiohandle,audiosegs[chunk],compressed);\r
1316 \r
1317 #else\r
1318 \r
1319         if (compressed<=BUFFERSIZE)\r
1320         {\r
1321                 CA_FarRead(audiohandle,bufferseg,compressed);\r
1322                 source = bufferseg;\r
1323         }\r
1324         else\r
1325         {\r
1326                 MM_GetPtr(&bigbufferseg,compressed);\r
1327                 if (mmerror)\r
1328                         return;\r
1329                 MM_SetLock (&bigbufferseg,true);\r
1330                 CA_FarRead(audiohandle,bigbufferseg,compressed);\r
1331                 source = bigbufferseg;\r
1332         }\r
1333 \r
1334         expanded = *(long far *)source;\r
1335         source += 4;                    // skip over length\r
1336         MM_GetPtr (&(memptr)audiosegs[chunk],expanded);\r
1337         if (mmerror)\r
1338                 goto done;\r
1339         CAL_HuffExpand (source,audiosegs[chunk],expanded,audiohuffman);\r
1340 \r
1341 done:\r
1342         if (compressed>BUFFERSIZE)\r
1343                 MM_FreePtr(&bigbufferseg);\r
1344 #endif\r
1345 }*/\r
1346 \r
1347 //===========================================================================\r
1348 \r
1349 /*\r
1350 ======================\r
1351 =\r
1352 = CA_LoadAllSounds\r
1353 =\r
1354 = Purges all sounds, then loads all new ones (mode switch)\r
1355 =\r
1356 ======================\r
1357 */\r
1358 /*++++\r
1359 void CA_LoadAllSounds (void)\r
1360 {\r
1361         unsigned        start,i;\r
1362 \r
1363         switch (oldsoundmode)\r
1364         {\r
1365         case sdm_Off:\r
1366                 goto cachein;\r
1367         case sdm_PC:\r
1368                 start = STARTPCSOUNDS;\r
1369                 break;\r
1370         case sdm_AdLib:\r
1371                 start = STARTADLIBSOUNDS;\r
1372                 break;\r
1373         }\r
1374 \r
1375         for (i=0;i<NUMSOUNDS;i++,start++)\r
1376                 if (audiosegs[start])\r
1377                         MM_SetPurge (&(memptr)audiosegs[start],3);              // make purgable\r
1378 \r
1379 cachein:\r
1380 \r
1381         switch (SoundMode)\r
1382         {\r
1383         case sdm_Off:\r
1384                 return;\r
1385         case sdm_PC:\r
1386                 start = STARTPCSOUNDS;\r
1387                 break;\r
1388         case sdm_AdLib:\r
1389                 start = STARTADLIBSOUNDS;\r
1390                 break;\r
1391         }\r
1392 \r
1393         for (i=0;i<NUMSOUNDS;i++,start++)\r
1394                 CA_CacheAudioChunk (start);\r
1395 \r
1396         oldsoundmode = SoundMode;\r
1397 }*/\r
1398 \r
1399 //===========================================================================\r
1400 \r
1401 //++++#if GRMODE == EGAGR\r
1402 \r
1403 /*\r
1404 ======================\r
1405 =\r
1406 = CAL_ShiftSprite\r
1407 =\r
1408 = Make a shifted (one byte wider) copy of a sprite into another area\r
1409 =\r
1410 ======================\r
1411 */\r
1412 /*++++\r
1413 unsigned        static  sheight,swidth;\r
1414 boolean static dothemask;\r
1415 \r
1416 void CAL_ShiftSprite (unsigned segment,unsigned source,unsigned dest,\r
1417         unsigned width, unsigned height, unsigned pixshift, boolean domask)\r
1418 {\r
1419 \r
1420         sheight = height;               // because we are going to reassign bp\r
1421         swidth = width;\r
1422         dothemask = domask;\r
1423 \r
1424 asm     mov     ax,[segment]\r
1425 asm     mov     ds,ax           // source and dest are in same segment, and all local\r
1426 \r
1427 asm     mov     bx,[source]\r
1428 asm     mov     di,[dest]\r
1429 \r
1430 asm     mov     bp,[pixshift]\r
1431 asm     shl     bp,1\r
1432 asm     mov     bp,WORD PTR [shifttabletable+bp]        // bp holds pointer to shift table\r
1433 \r
1434 asm     cmp     [ss:dothemask],0\r
1435 asm     je              skipmask\r
1436 \r
1437 //\r
1438 // table shift the mask\r
1439 //\r
1440 asm     mov     dx,[ss:sheight]\r
1441 \r
1442 domaskrow:\r
1443 \r
1444 asm     mov     BYTE PTR [di],255       // 0xff first byte\r
1445 asm     mov     cx,ss:[swidth]\r
1446 \r
1447 domaskbyte:\r
1448 \r
1449 asm     mov     al,[bx]                         // source\r
1450 asm     not     al\r
1451 asm     inc     bx                                      // next source byte\r
1452 asm     xor     ah,ah\r
1453 asm     shl     ax,1\r
1454 asm     mov     si,ax\r
1455 asm     mov     ax,[bp+si]                      // table shift into two bytes\r
1456 asm     not     ax\r
1457 asm     and     [di],al                         // and with first byte\r
1458 asm     inc     di\r
1459 asm     mov     [di],ah                         // replace next byte\r
1460 \r
1461 asm     loop    domaskbyte\r
1462 \r
1463 asm     inc     di                                      // the last shifted byte has 1s in it\r
1464 asm     dec     dx\r
1465 asm     jnz     domaskrow\r
1466 \r
1467 skipmask:\r
1468 \r
1469 //\r
1470 // table shift the data\r
1471 //\r
1472 asm     mov     dx,ss:[sheight]\r
1473 asm     shl     dx,1\r
1474 asm     shl     dx,1                            // four planes of data\r
1475 \r
1476 dodatarow:\r
1477 \r
1478 asm     mov     BYTE PTR [di],0         // 0 first byte\r
1479 asm     mov     cx,ss:[swidth]\r
1480 \r
1481 dodatabyte:\r
1482 \r
1483 asm     mov     al,[bx]                         // source\r
1484 asm     inc     bx                                      // next source byte\r
1485 asm     xor     ah,ah\r
1486 asm     shl     ax,1\r
1487 asm     mov     si,ax\r
1488 asm     mov     ax,[bp+si]                      // table shift into two bytes\r
1489 asm     or      [di],al                         // or with first byte\r
1490 asm     inc     di\r
1491 asm     mov     [di],ah                         // replace next byte\r
1492 \r
1493 asm     loop    dodatabyte\r
1494 \r
1495 asm     inc     di                                      // the last shifted byte has 0s in it\r
1496 asm     dec     dx\r
1497 asm     jnz     dodatarow\r
1498 \r
1499 //\r
1500 // done\r
1501 //\r
1502 \r
1503 asm     mov     ax,ss                           // restore data segment\r
1504 asm     mov     ds,ax\r
1505 \r
1506 }\r
1507 \r
1508 #endif\r
1509 */\r
1510 //===========================================================================\r
1511 \r
1512 /*\r
1513 ======================\r
1514 =\r
1515 = CAL_CacheSprite\r
1516 =\r
1517 = Generate shifts and set up sprite structure for a given sprite\r
1518 =\r
1519 ======================\r
1520 */\r
1521 /*++++\r
1522 void CAL_CacheSprite (int chunk, byte far *compressed)\r
1523 {\r
1524         int i;\r
1525         unsigned shiftstarts[5];\r
1526         unsigned smallplane,bigplane,expanded;\r
1527         spritetabletype far *spr;\r
1528         spritetype _seg *dest;\r
1529 \r
1530 #if GRMODE == CGAGR\r
1531 //\r
1532 // CGA has no pel panning, so shifts are never needed\r
1533 //\r
1534         spr = &spritetable[chunk-STARTSPRITES];\r
1535         smallplane = spr->width*spr->height;\r
1536         MM_GetPtr (&grsegs[chunk],smallplane*2+MAXSHIFTS*6);\r
1537         if (mmerror)\r
1538                 return;\r
1539         dest = (spritetype _seg *)grsegs[chunk];\r
1540         dest->sourceoffset[0] = MAXSHIFTS*6;    // start data after 3 unsigned tables\r
1541         dest->planesize[0] = smallplane;\r
1542         dest->width[0] = spr->width;\r
1543 \r
1544 //\r
1545 // expand the unshifted shape\r
1546 //\r
1547         CAL_HuffExpand (compressed, &dest->data[0],smallplane*2,grhuffman);\r
1548 \r
1549 #endif\r
1550 \r
1551 \r
1552 #if GRMODE == EGAGR\r
1553 \r
1554 //\r
1555 // calculate sizes\r
1556 //\r
1557         spr = &spritetable[chunk-STARTSPRITES];\r
1558         smallplane = spr->width*spr->height;\r
1559         bigplane = (spr->width+1)*spr->height;\r
1560 \r
1561         shiftstarts[0] = MAXSHIFTS*6;   // start data after 3 unsigned tables\r
1562         shiftstarts[1] = shiftstarts[0] + smallplane*5; // 5 planes in a sprite\r
1563         shiftstarts[2] = shiftstarts[1] + bigplane*5;\r
1564         shiftstarts[3] = shiftstarts[2] + bigplane*5;\r
1565         shiftstarts[4] = shiftstarts[3] + bigplane*5;   // nothing ever put here\r
1566 \r
1567         expanded = shiftstarts[spr->shifts];\r
1568         MM_GetPtr (&grsegs[chunk],expanded);\r
1569         if (mmerror)\r
1570                 return;\r
1571         dest = (spritetype _seg *)grsegs[chunk];\r
1572 \r
1573 //\r
1574 // expand the unshifted shape\r
1575 //\r
1576         CAL_HuffExpand (compressed, &dest->data[0],smallplane*5,grhuffman);\r
1577 \r
1578 //\r
1579 // make the shifts!\r
1580 //\r
1581         switch (spr->shifts)\r
1582         {\r
1583         case    1:\r
1584                 for (i=0;i<4;i++)\r
1585                 {\r
1586                         dest->sourceoffset[i] = shiftstarts[0];\r
1587                         dest->planesize[i] = smallplane;\r
1588                         dest->width[i] = spr->width;\r
1589                 }\r
1590                 break;\r
1591 \r
1592         case    2:\r
1593                 for (i=0;i<2;i++)\r
1594                 {\r
1595                         dest->sourceoffset[i] = shiftstarts[0];\r
1596                         dest->planesize[i] = smallplane;\r
1597                         dest->width[i] = spr->width;\r
1598                 }\r
1599                 for (i=2;i<4;i++)\r
1600                 {\r
1601                         dest->sourceoffset[i] = shiftstarts[1];\r
1602                         dest->planesize[i] = bigplane;\r
1603                         dest->width[i] = spr->width+1;\r
1604                 }\r
1605                 CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
1606                         dest->sourceoffset[2],spr->width,spr->height,4,true);\r
1607                 break;\r
1608 \r
1609         case    4:\r
1610                 dest->sourceoffset[0] = shiftstarts[0];\r
1611                 dest->planesize[0] = smallplane;\r
1612                 dest->width[0] = spr->width;\r
1613 \r
1614                 dest->sourceoffset[1] = shiftstarts[1];\r
1615                 dest->planesize[1] = bigplane;\r
1616                 dest->width[1] = spr->width+1;\r
1617                 CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
1618                         dest->sourceoffset[1],spr->width,spr->height,2,true);\r
1619 \r
1620                 dest->sourceoffset[2] = shiftstarts[2];\r
1621                 dest->planesize[2] = bigplane;\r
1622                 dest->width[2] = spr->width+1;\r
1623                 CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
1624                         dest->sourceoffset[2],spr->width,spr->height,4,true);\r
1625 \r
1626                 dest->sourceoffset[3] = shiftstarts[3];\r
1627                 dest->planesize[3] = bigplane;\r
1628                 dest->width[3] = spr->width+1;\r
1629                 CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
1630                         dest->sourceoffset[3],spr->width,spr->height,6,true);\r
1631 \r
1632                 break;\r
1633 \r
1634         default:\r
1635                 Quit ("CAL_CacheSprite: Bad shifts number!");\r
1636         }\r
1637 \r
1638 #endif\r
1639 }*/\r
1640 \r
1641 //===========================================================================\r
1642 \r
1643 \r
1644 /*\r
1645 ======================\r
1646 =\r
1647 = CAL_ExpandGrChunk\r
1648 =\r
1649 = Does whatever is needed with a pointer to a compressed chunk\r
1650 =\r
1651 ======================\r
1652 */\r
1653 /*++++\r
1654 void CAL_ExpandGrChunk (int chunk, byte far *source)\r
1655 {\r
1656         long    expanded;\r
1657 \r
1658 \r
1659         if (chunk >= STARTTILE8 && chunk < STARTEXTERNS)\r
1660         {\r
1661         //\r
1662         // expanded sizes of tile8/16/32 are implicit\r
1663         //\r
1664 \r
1665 #if GRMODE == EGAGR\r
1666 #define BLOCK           32\r
1667 #define MASKBLOCK       40\r
1668 #endif\r
1669 \r
1670 #if GRMODE == CGAGR\r
1671 #define BLOCK           16\r
1672 #define MASKBLOCK       32\r
1673 #endif\r
1674 \r
1675                 if (chunk<STARTTILE8M)                  // tile 8s are all in one chunk!\r
1676                         expanded = BLOCK*NUMTILE8;\r
1677                 else if (chunk<STARTTILE16)\r
1678                         expanded = MASKBLOCK*NUMTILE8M;\r
1679                 else if (chunk<STARTTILE16M)    // all other tiles are one/chunk\r
1680                         expanded = BLOCK*4;\r
1681                 else if (chunk<STARTTILE32)\r
1682                         expanded = MASKBLOCK*4;\r
1683                 else if (chunk<STARTTILE32M)\r
1684                         expanded = BLOCK*16;\r
1685                 else\r
1686                         expanded = MASKBLOCK*16;\r
1687         }\r
1688         else\r
1689         {\r
1690         //\r
1691         // everything else has an explicit size longword\r
1692         //\r
1693                 expanded = *(long far *)source;\r
1694                 source += 4;                    // skip over length\r
1695         }\r
1696 \r
1697 //\r
1698 // allocate final space, decompress it, and free bigbuffer\r
1699 // Sprites need to have shifts made and various other junk\r
1700 //\r
1701         if (chunk>=STARTSPRITES && chunk< STARTTILE8)\r
1702                 CAL_CacheSprite(chunk,source);\r
1703         else\r
1704         {\r
1705                 MM_GetPtr (&grsegs[chunk],expanded);\r
1706                 if (mmerror)\r
1707                         return;\r
1708                 CAL_HuffExpand (source,grsegs[chunk],expanded,grhuffman);\r
1709         }\r
1710 }\r
1711 */\r
1712 \r
1713 /*\r
1714 ======================\r
1715 =\r
1716 = CAL_ReadGrChunk\r
1717 =\r
1718 = Gets a chunk off disk, optimizing reads to general buffer\r
1719 =\r
1720 ======================\r
1721 */\r
1722 /*++++\r
1723 void CAL_ReadGrChunk (int chunk)\r
1724 {\r
1725         long    pos,compressed;\r
1726         memptr  bigbufferseg;\r
1727         byte    far *source;\r
1728         int             next;\r
1729 \r
1730 //\r
1731 // load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
1732 // a larger buffer\r
1733 //\r
1734         pos = GRFILEPOS(chunk);\r
1735         if (pos<0)                                                      // $FFFFFFFF start is a sparse tile\r
1736           return;\r
1737 \r
1738         next = chunk +1;\r
1739         while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
1740                 next++;\r
1741 \r
1742         compressed = GRFILEPOS(next)-pos;\r
1743 \r
1744         lseek(grhandle,pos,SEEK_SET);\r
1745 \r
1746         if (compressed<=BUFFERSIZE)\r
1747         {\r
1748                 CA_FarRead(grhandle,bufferseg,compressed);\r
1749                 source = bufferseg;\r
1750         }\r
1751         else\r
1752         {\r
1753                 MM_GetPtr(&bigbufferseg,compressed);\r
1754                 if (mmerror)\r
1755                         return;\r
1756                 MM_SetLock (&bigbufferseg,true);\r
1757                 CA_FarRead(grhandle,bigbufferseg,compressed);\r
1758                 source = bigbufferseg;\r
1759         }\r
1760 \r
1761         CAL_ExpandGrChunk (chunk,source);\r
1762 \r
1763         if (compressed>BUFFERSIZE)\r
1764                 MM_FreePtr(&bigbufferseg);\r
1765 }\r
1766 */\r
1767 /*\r
1768 ======================\r
1769 =\r
1770 = CA_CacheGrChunk\r
1771 =\r
1772 = Makes sure a given chunk is in memory, loadiing it if needed\r
1773 =\r
1774 ======================\r
1775 */\r
1776 /*++++\r
1777 void CA_CacheGrChunk (int chunk)\r
1778 {\r
1779         long    pos,compressed;\r
1780         memptr  bigbufferseg;\r
1781         byte    far *source;\r
1782         int             next;\r
1783 \r
1784         gvar->video.grneeded[chunk] |= ca_levelbit;             // make sure it doesn't get removed\r
1785         if (grsegs[chunk])\r
1786         {\r
1787                 MM_SetPurge (&grsegs[chunk],0);\r
1788                 return;                                                 // allready in memory\r
1789         }\r
1790 \r
1791 // MDM begin - (GAMERS EDGE)\r
1792 //\r
1793         if (!FindFile("EGAGRAPH."EXT,NULL,2))\r
1794                 Quit("CA_CacheGrChunk(): Can't find graphics files.");\r
1795 //\r
1796 // MDM end\r
1797 \r
1798 //\r
1799 // load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
1800 // a larger buffer\r
1801 //\r
1802         pos = GRFILEPOS(chunk);\r
1803         if (pos<0)                                                      // $FFFFFFFF start is a sparse tile\r
1804           return;\r
1805 \r
1806         next = chunk +1;\r
1807         while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
1808                 next++;\r
1809 \r
1810         compressed = GRFILEPOS(next)-pos;\r
1811 \r
1812         lseek(grhandle,pos,SEEK_SET);\r
1813 \r
1814         if (compressed<=BUFFERSIZE)\r
1815         {\r
1816                 CA_FarRead(grhandle,bufferseg,compressed);\r
1817                 source = bufferseg;\r
1818         }\r
1819         else\r
1820         {\r
1821                 MM_GetPtr(&bigbufferseg,compressed);\r
1822                 MM_SetLock (&bigbufferseg,true);\r
1823                 CA_FarRead(grhandle,bigbufferseg,compressed);\r
1824                 source = bigbufferseg;\r
1825         }\r
1826 \r
1827         CAL_ExpandGrChunk (chunk,source);\r
1828 \r
1829         if (compressed>BUFFERSIZE)\r
1830                 MM_FreePtr(&bigbufferseg);\r
1831 }\r
1832 */\r
1833 \r
1834 \r
1835 //==========================================================================\r
1836 \r
1837 /*\r
1838 ======================\r
1839 =\r
1840 = CA_CacheMap\r
1841 =\r
1842 ======================\r
1843 */\r
1844 /*++++\r
1845 void CA_CacheMap (int mapnum)\r
1846 {\r
1847         long    pos,compressed;\r
1848         int             plane;\r
1849         memptr  *dest,bigbufferseg;\r
1850         unsigned        size;\r
1851         unsigned        far     *source;\r
1852 #ifdef MAPHEADERLINKED\r
1853         memptr  buffer2seg;\r
1854         long    expanded;\r
1855 #endif\r
1856 \r
1857 \r
1858 // MDM begin - (GAMERS EDGE)\r
1859 //\r
1860         if (!FindFile("GAMEMAPS."EXT,NULL,1))\r
1861                 Quit("CA_CacheMap(): Can't find level files.");\r
1862 //\r
1863 // MDM end\r
1864 \r
1865 \r
1866 //\r
1867 // free up memory from last map\r
1868 //\r
1869         if (mapon>-1 && mapheaderseg[mapon])\r
1870                 MM_SetPurge (&(memptr)mapheaderseg[mapon],3);\r
1871         for (plane=0;plane<MAPPLANES;plane++)\r
1872                 if (mapsegs[plane])\r
1873                         MM_FreePtr (&(memptr)mapsegs[plane]);\r
1874 \r
1875         mapon = mapnum;\r
1876 \r
1877 \r
1878 //\r
1879 // load map header\r
1880 // The header will be cached if it is still around\r
1881 //\r
1882         if (!mapheaderseg[mapnum])\r
1883         {\r
1884                 pos = ((mapfiletype     _seg *)tinf)->headeroffsets[mapnum];\r
1885                 if (pos<0)                                              // $FFFFFFFF start is a sparse map\r
1886                   Quit ("CA_CacheMap: Tried to load a non existent map!");\r
1887 \r
1888                 MM_GetPtr(&(memptr)mapheaderseg[mapnum],sizeof(maptype));\r
1889                 lseek(maphandle,pos,SEEK_SET);\r
1890                 CA_FarRead (maphandle,(memptr)mapheaderseg[mapnum],sizeof(maptype));\r
1891         }\r
1892         else\r
1893                 MM_SetPurge (&(memptr)mapheaderseg[mapnum],0);\r
1894 \r
1895 //\r
1896 // load the planes in\r
1897 // If a plane's pointer still exists it will be overwritten (levels are\r
1898 // allways reloaded, never cached)\r
1899 //\r
1900 \r
1901         size = mapheaderseg[mapnum]->width * mapheaderseg[mapnum]->height * 2;\r
1902 \r
1903         for (plane = 0; plane<MAPPLANES; plane++)\r
1904         {\r
1905                 pos = mapheaderseg[mapnum]->planestart[plane];\r
1906                 compressed = mapheaderseg[mapnum]->planelength[plane];\r
1907 \r
1908                 if (!compressed)\r
1909                         continue;               // the plane is not used in this game\r
1910 \r
1911                 dest = &(memptr)mapsegs[plane];\r
1912                 MM_GetPtr(dest,size);\r
1913 \r
1914                 lseek(maphandle,pos,SEEK_SET);\r
1915                 if (compressed<=BUFFERSIZE)\r
1916                         source = bufferseg;\r
1917                 else\r
1918                 {\r
1919                         MM_GetPtr(&bigbufferseg,compressed);\r
1920                         MM_SetLock (&bigbufferseg,true);\r
1921                         source = bigbufferseg;\r
1922                 }\r
1923 \r
1924                 CA_FarRead(maphandle,(byte far *)source,compressed);\r
1925 #ifdef MAPHEADERLINKED\r
1926                 //\r
1927                 // unhuffman, then unRLEW\r
1928                 // The huffman'd chunk has a two byte expanded length first\r
1929                 // The resulting RLEW chunk also does, even though it's not really\r
1930                 // needed\r
1931                 //\r
1932                 expanded = *source;\r
1933                 source++;\r
1934                 MM_GetPtr (&buffer2seg,expanded);\r
1935                 CAL_CarmackExpand (source, (unsigned far *)buffer2seg,expanded);\r
1936                 CA_RLEWexpand (((unsigned far *)buffer2seg)+1,*dest,size,\r
1937                 ((mapfiletype _seg *)tinf)->RLEWtag);\r
1938                 MM_FreePtr (&buffer2seg);\r
1939 \r
1940 #else\r
1941                 //\r
1942                 // unRLEW, skipping expanded length\r
1943                 //\r
1944                 CA_RLEWexpand (source+1, *dest,size,\r
1945                 ((mapfiletype _seg *)tinf)->RLEWtag);\r
1946 #endif\r
1947 \r
1948                 if (compressed>BUFFERSIZE)\r
1949                         MM_FreePtr(&bigbufferseg);\r
1950         }\r
1951 }*/\r
1952 \r
1953 //===========================================================================\r
1954 \r
1955 /*\r
1956 ======================\r
1957 =\r
1958 = CA_UpLevel\r
1959 =\r
1960 = Goes up a bit level in the needed lists and clears it out.\r
1961 = Everything is made purgable\r
1962 =\r
1963 ======================\r
1964 */\r
1965 /*++++\r
1966 void CA_UpLevel (void)\r
1967 {\r
1968         if (ca_levelnum==7)\r
1969                 Quit ("CA_UpLevel: Up past level 7!");\r
1970 \r
1971         ca_levelbit<<=1;\r
1972         ca_levelnum++;\r
1973 }*/\r
1974 \r
1975 //===========================================================================\r
1976 \r
1977 /*\r
1978 ======================\r
1979 =\r
1980 = CA_DownLevel\r
1981 =\r
1982 = Goes down a bit level in the needed lists and recaches\r
1983 = everything from the lower level\r
1984 =\r
1985 ======================\r
1986 */\r
1987 /*++\r
1988 void CA_DownLevel (void)\r
1989 {\r
1990         if (!ca_levelnum)\r
1991                 Quit ("CA_DownLevel: Down past level 0!");\r
1992         ca_levelbit>>=1;\r
1993         ca_levelnum--;\r
1994         CA_CacheMarks(NULL);\r
1995 }*/\r
1996 \r
1997 //===========================================================================\r
1998 \r
1999 /*\r
2000 ======================\r
2001 =\r
2002 = CA_ClearMarks\r
2003 =\r
2004 = Clears out all the marks at the current level\r
2005 =\r
2006 ======================\r
2007 */\r
2008 \r
2009 void CA_ClearMarks (global_game_variables_t *gvar)\r
2010 {\r
2011         int i;\r
2012 \r
2013         for (i=0;i<NUMCHUNKS;i++)\r
2014                 gvar->video.grneeded[i]&=~gvar->ca.ca_levelbit;\r
2015 }\r
2016 \r
2017 //===========================================================================\r
2018 \r
2019 /*\r
2020 ======================\r
2021 =\r
2022 = CA_ClearAllMarks\r
2023 =\r
2024 = Clears out all the marks on all the levels\r
2025 =\r
2026 ======================\r
2027 */\r
2028 \r
2029 void CA_ClearAllMarks (global_game_variables_t *gvar)\r
2030 {\r
2031         _fmemset (gvar->video.grneeded,0,sizeof(gvar->video.grneeded));\r
2032         gvar->ca.ca_levelbit = 1;\r
2033         gvar->ca.ca_levelnum = 0;\r
2034 }\r
2035 \r
2036 //===========================================================================\r
2037 \r
2038 /*\r
2039 ======================\r
2040 =\r
2041 = CA_FreeGraphics\r
2042 =\r
2043 ======================\r
2044 */\r
2045 /*++++\r
2046 void CA_SetGrPurge (void)\r
2047 {\r
2048         int i;\r
2049 \r
2050 //\r
2051 // free graphics\r
2052 //\r
2053         CA_ClearMarks ();\r
2054 \r
2055         for (i=0;i<NUMCHUNKS;i++)\r
2056                 if (grsegs[i])\r
2057                         MM_SetPurge (&(memptr)grsegs[i],3);\r
2058 }\r
2059 */\r
2060 \r
2061 /*\r
2062 ======================\r
2063 =\r
2064 = CA_SetAllPurge\r
2065 =\r
2066 = Make everything possible purgable\r
2067 =\r
2068 ======================\r
2069 */\r
2070 /*++++++++\r
2071 void CA_SetAllPurge (void)\r
2072 {\r
2073         int i;\r
2074 \r
2075         CA_ClearMarks ();\r
2076 \r
2077 //\r
2078 // free cursor sprite and background save\r
2079 //\r
2080         VW_FreeCursor ();\r
2081 \r
2082 //\r
2083 // free map headers and map planes\r
2084 //\r
2085         for (i=0;i<NUMMAPS;i++)\r
2086                 if (mapheaderseg[i])\r
2087                         MM_SetPurge (&(memptr)mapheaderseg[i],3);\r
2088 \r
2089         for (i=0;i<3;i++)\r
2090                 if (mapsegs[i])\r
2091                         MM_FreePtr (&(memptr)mapsegs[i]);\r
2092 \r
2093 //\r
2094 // free sounds\r
2095 //\r
2096         for (i=0;i<NUMSNDCHUNKS;i++)\r
2097                 if (audiosegs[i])\r
2098                         MM_SetPurge (&(memptr)audiosegs[i],3);\r
2099 \r
2100 //\r
2101 // free graphics\r
2102 //\r
2103         CA_SetGrPurge ();\r
2104 }*/\r
2105 \r
2106 \r
2107 //===========================================================================\r
2108 \r
2109 \r
2110 /*\r
2111 ======================\r
2112 =\r
2113 = CAL_DialogDraw\r
2114 =\r
2115 ======================\r
2116 */\r
2117 /*\r
2118 #define NUMBARS (17l*8)\r
2119 #define BARSTEP 8\r
2120 \r
2121 unsigned        thx,thy,lastx;\r
2122 long            barx,barstep;\r
2123 \r
2124 void    CAL_DialogDraw (char *title,unsigned numcache)\r
2125 {\r
2126         unsigned        homex,homey,x;\r
2127 \r
2128         barstep = (NUMBARS<<16)/numcache;\r
2129 \r
2130 //\r
2131 // draw dialog window (masked tiles 12 - 20 are window borders)\r
2132 //\r
2133         US_CenterWindow (20,8);\r
2134         homex = PrintX;\r
2135         homey = PrintY;\r
2136 \r
2137         US_CPrint ("Loading");\r
2138         fontcolor = F_SECONDCOLOR;\r
2139         US_CPrint (title);\r
2140         fontcolor = F_BLACK;\r
2141 \r
2142 //\r
2143 // draw thermometer bar\r
2144 //\r
2145         thx = homex + 8;\r
2146         thy = homey + 32;\r
2147         VWB_DrawTile8(thx,thy,0);               // CAT3D numbers\r
2148         VWB_DrawTile8(thx,thy+8,3);\r
2149         VWB_DrawTile8(thx,thy+16,6);\r
2150         VWB_DrawTile8(thx+17*8,thy,2);\r
2151         VWB_DrawTile8(thx+17*8,thy+8,5);\r
2152         VWB_DrawTile8(thx+17*8,thy+16,8);\r
2153         for (x=thx+8;x<thx+17*8;x+=8)\r
2154         {\r
2155                 VWB_DrawTile8(x,thy,1);\r
2156                 VWB_DrawTile8(x,thy+8,4);\r
2157                 VWB_DrawTile8(x,thy+16,7);\r
2158         }\r
2159 \r
2160         thx += 4;               // first line location\r
2161         thy += 5;\r
2162         barx = (long)thx<<16;\r
2163         lastx = thx;\r
2164 \r
2165         VW_UpdateScreen();\r
2166 }\r
2167 */\r
2168 \r
2169 /*\r
2170 ======================\r
2171 =\r
2172 = CAL_DialogUpdate\r
2173 =\r
2174 ======================\r
2175 */\r
2176 /*\r
2177 void    CAL_DialogUpdate (void)\r
2178 {\r
2179         unsigned        x,xh;\r
2180 \r
2181         barx+=barstep;\r
2182         xh = barx>>16;\r
2183         if (xh - lastx > BARSTEP)\r
2184         {\r
2185                 for (x=lastx;x<=xh;x++)\r
2186 #if GRMODE == EGAGR\r
2187                         VWB_Vlin (thy,thy+13,x,14);\r
2188 #endif\r
2189 #if GRMODE == CGAGR\r
2190                         VWB_Vlin (thy,thy+13,x,SECONDCOLOR);\r
2191 #endif\r
2192                 lastx = xh;\r
2193                 VW_UpdateScreen();\r
2194         }\r
2195 }*/\r
2196 \r
2197 /*\r
2198 ======================\r
2199 =\r
2200 = CAL_DialogFinish\r
2201 =\r
2202 ======================\r
2203 */\r
2204 /*\r
2205 void    CAL_DialogFinish (void)\r
2206 {\r
2207         unsigned        x,xh;\r
2208 \r
2209         xh = thx + NUMBARS;\r
2210         for (x=lastx;x<=xh;x++)\r
2211 #if GRMODE == EGAGR\r
2212                 VWB_Vlin (thy,thy+13,x,14);\r
2213 #endif\r
2214 #if GRMODE == CGAGR\r
2215                 VWB_Vlin (thy,thy+13,x,SECONDCOLOR);\r
2216 #endif\r
2217         VW_UpdateScreen();\r
2218 \r
2219 }*/\r
2220 \r
2221 //===========================================================================\r
2222 \r
2223 /*\r
2224 ======================\r
2225 =\r
2226 = CA_CacheMarks\r
2227 =\r
2228 ======================\r
2229 *//*\r
2230 #define MAXEMPTYREAD    1024\r
2231 \r
2232 void CA_CacheMarks (char *title)\r
2233 {\r
2234         boolean dialog;\r
2235         int     i,next,numcache;\r
2236         long    pos,endpos,nextpos,nextendpos,compressed;\r
2237         long    bufferstart,bufferend;  // file position of general buffer\r
2238         byte    far *source;\r
2239         memptr  bigbufferseg;\r
2240 \r
2241         dialog = (title!=NULL);\r
2242 \r
2243         numcache = 0;\r
2244 //\r
2245 // go through and make everything not needed purgable\r
2246 //\r
2247         for (i=0;i<NUMCHUNKS;i++)\r
2248                 if (gvar->video.grneeded[i]&ca_levelbit)\r
2249                 {\r
2250                         if (grsegs[i])                                  // its allready in memory, make\r
2251                                 MM_SetPurge(&grsegs[i],0);      // sure it stays there!\r
2252                         else\r
2253                                 numcache++;\r
2254                 }\r
2255                 else\r
2256                 {\r
2257                         if (grsegs[i])                                  // not needed, so make it purgeable\r
2258                                 MM_SetPurge(&grsegs[i],3);\r
2259                 }\r
2260 \r
2261         if (!numcache)                  // nothing to cache!\r
2262                 return;\r
2263 \r
2264 // MDM begin - (GAMERS EDGE)\r
2265 //\r
2266         if (!FindFile("EGAGRAPH."EXT,NULL,2))\r
2267                 Quit("CA_CacheMarks(): Can't find graphics files.");\r
2268 //\r
2269 // MDM end\r
2270 \r
2271         if (dialog)\r
2272         {\r
2273 #ifdef PROFILE\r
2274                 write(profilehandle,title,strlen(title));\r
2275                 write(profilehandle,"\n",1);\r
2276 #endif\r
2277                 if (drawcachebox)\r
2278                         drawcachebox(title,numcache);\r
2279         }\r
2280 \r
2281 //\r
2282 // go through and load in anything still needed\r
2283 //\r
2284         bufferstart = bufferend = 0;            // nothing good in buffer now\r
2285 \r
2286         for (i=0;i<NUMCHUNKS;i++)\r
2287                 if ( (gvar->video.grneeded[i]&ca_levelbit) && !grsegs[i])\r
2288                 {\r
2289 //\r
2290 // update thermometer\r
2291 //\r
2292                         if (dialog && updatecachebox)\r
2293                                 updatecachebox ();\r
2294 \r
2295                         pos = GRFILEPOS(i);\r
2296                         if (pos<0)\r
2297                                 continue;\r
2298 \r
2299                         next = i +1;\r
2300                         while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
2301                                 next++;\r
2302 \r
2303                         compressed = GRFILEPOS(next)-pos;\r
2304                         endpos = pos+compressed;\r
2305 \r
2306                         if (compressed<=BUFFERSIZE)\r
2307                         {\r
2308                                 if (bufferstart<=pos\r
2309                                 && bufferend>= endpos)\r
2310                                 {\r
2311                                 // data is allready in buffer\r
2312                                         source = (byte _seg *)bufferseg+(pos-bufferstart);\r
2313                                 }\r
2314                                 else\r
2315                                 {\r
2316                                 // load buffer with a new block from disk\r
2317                                 // try to get as many of the needed blocks in as possible\r
2318                                         while ( next < NUMCHUNKS )\r
2319                                         {\r
2320                                                 while (next < NUMCHUNKS &&\r
2321                                                 !(gvar->video.grneeded[next]&ca_levelbit && !grsegs[next]))\r
2322                                                         next++;\r
2323                                                 if (next == NUMCHUNKS)\r
2324                                                         continue;\r
2325 \r
2326                                                 nextpos = GRFILEPOS(next);\r
2327                                                 while (GRFILEPOS(++next) == -1) // skip past any sparse tiles\r
2328                                                         ;\r
2329                                                 nextendpos = GRFILEPOS(next);\r
2330                                                 if (nextpos - endpos <= MAXEMPTYREAD\r
2331                                                 && nextendpos-pos <= BUFFERSIZE)\r
2332                                                         endpos = nextendpos;\r
2333                                                 else\r
2334                                                         next = NUMCHUNKS;                       // read pos to posend\r
2335                                         }\r
2336 \r
2337                                         lseek(grhandle,pos,SEEK_SET);\r
2338                                         CA_FarRead(grhandle,bufferseg,endpos-pos);\r
2339                                         bufferstart = pos;\r
2340                                         bufferend = endpos;\r
2341                                         source = bufferseg;\r
2342                                 }\r
2343                         }\r
2344                         else\r
2345                         {\r
2346                         // big chunk, allocate temporary buffer\r
2347                                 MM_GetPtr(&bigbufferseg,compressed);\r
2348                                 if (mmerror)\r
2349                                         return;\r
2350                                 MM_SetLock (&bigbufferseg,true);\r
2351                                 lseek(grhandle,pos,SEEK_SET);\r
2352                                 CA_FarRead(grhandle,bigbufferseg,compressed);\r
2353                                 source = bigbufferseg;\r
2354                         }\r
2355 \r
2356                         CAL_ExpandGrChunk (i,source);\r
2357                         if (mmerror)\r
2358                                 return;\r
2359 \r
2360                         if (compressed>BUFFERSIZE)\r
2361                                 MM_FreePtr(&bigbufferseg);\r
2362 \r
2363                 }\r
2364 \r
2365 //\r
2366 // finish up any thermometer remnants\r
2367 //\r
2368                 if (dialog && finishcachebox)\r
2369                         finishcachebox();\r
2370 }*/\r