]> 4ch.mooo.com Git - 16.git/blob - src/lib/16_ca.c
16_ca need to be used more
[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 far *dest, dword length, global_game_variables_t *gvar)\r
225 {\r
226         boolean flag=0;\r
227         //dword fat=0;\r
228         //word segm=0;\r
229         if(gvar->pm.emm.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 far *source, dword length, global_game_variables_t *gvar)\r
297 {\r
298         boolean flag=0;\r
299         //dword fat=0;\r
300         //word segm=0;\r
301         if(gvar->pm.emm.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, global_game_variables_t *gvar)\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, gvar))\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, global_game_variables_t *gvar)\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, gvar))\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, global_game_variables_t *gvar)\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, gvar);\r
442         if(!CA_FarRead(handle,*ptr,size, gvar))\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 far *source, byte far *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,[word ptr 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,[word ptr 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,[word ptr 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,[word ptr 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 = CA_RLEWcompress\r
794 =\r
795 ======================\r
796 */\r
797 \r
798 long CA_RLEWCompress (unsigned far *source, long length, unsigned far *dest,\r
799   unsigned rlewtag)\r
800 {\r
801   long complength;\r
802   unsigned value,count,i;\r
803   unsigned far *start,far *end;\r
804 \r
805   start = dest;\r
806 \r
807   end = source + (length+1)/2;\r
808 \r
809 //\r
810 // compress it\r
811 //\r
812   do\r
813   {\r
814         count = 1;\r
815         value = *source++;\r
816         while (*source == value && source<end)\r
817         {\r
818           count++;\r
819           source++;\r
820         }\r
821         if (count>3 || value == rlewtag)\r
822         {\r
823     //\r
824     // send a tag / count / value string\r
825     //\r
826       *dest++ = rlewtag;\r
827       *dest++ = count;\r
828       *dest++ = value;\r
829     }\r
830     else\r
831     {\r
832     //\r
833     // send word without compressing\r
834     //\r
835       for (i=1;i<=count;i++)\r
836         *dest++ = value;\r
837         }\r
838 \r
839   } while (source<end);\r
840 \r
841   complength = 2*(dest-start);\r
842   return complength;\r
843 }\r
844 \r
845 \r
846 /*\r
847 ======================\r
848 =\r
849 = CA_RLEWexpand\r
850 = length is EXPANDED length\r
851 =\r
852 ======================\r
853 */\r
854 \r
855 void CA_RLEWexpand (unsigned far *source, unsigned far *dest,long length,\r
856   unsigned rlewtag)\r
857 {\r
858 //  unsigned value,count,i;\r
859   unsigned far *end;\r
860   unsigned sourceseg,sourceoff,destseg,destoff,endseg,endoff;\r
861 \r
862 \r
863 //\r
864 // expand it\r
865 //\r
866 #if 0\r
867   do\r
868   {\r
869         value = *source++;\r
870         if (value != rlewtag)\r
871         //\r
872         // uncompressed\r
873         //\r
874           *dest++=value;\r
875         else\r
876         {\r
877         //\r
878         // compressed string\r
879         //\r
880           count = *source++;\r
881           value = *source++;\r
882           for (i=1;i<=count;i++)\r
883         *dest++ = value;\r
884         }\r
885   } while (dest<end);\r
886 #endif\r
887 \r
888   end = dest + (length)/2;\r
889   sourceseg = FP_SEG(source);\r
890   sourceoff = FP_OFF(source);\r
891   destseg = FP_SEG(dest);\r
892   destoff = FP_OFF(dest);\r
893   endseg = FP_SEG(end);\r
894   endoff = FP_OFF(end);\r
895 \r
896 \r
897 //\r
898 // ax = source value\r
899 // bx = tag value\r
900 // cx = repeat counts\r
901 // dx = scratch\r
902 //\r
903 // NOTE: A repeat count that produces 0xfff0 bytes can blow this!\r
904 //\r
905         __asm {\r
906                 mov     bx,rlewtag\r
907                 mov     si,sourceoff\r
908                 mov     di,destoff\r
909                 mov     es,destseg\r
910                 mov     ds,sourceseg\r
911 #ifdef __BORLANDC__\r
912         }\r
913 #endif\r
914 expand:\r
915 #ifdef __BORLANDC__\r
916         __asm {\r
917 #endif\r
918                 lodsw\r
919                 cmp     ax,bx\r
920                 je      repeat\r
921                 stosw\r
922                 jmp     next\r
923 #ifdef __BORLANDC__\r
924         }\r
925 #endif\r
926 repeat:\r
927 #ifdef __BORLANDC__\r
928         __asm {\r
929 #endif\r
930                 lodsw\r
931                 mov     cx,ax           // repeat count\r
932                 lodsw                   // repeat value\r
933                 rep stosw\r
934 #ifdef __BORLANDC__\r
935         }\r
936 #endif\r
937 next:\r
938 #ifdef __BORLANDC__\r
939         __asm {\r
940 #endif\r
941                 cmp     si,0x10         // normalize ds:si\r
942                 jb      sinorm\r
943                 mov     ax,si\r
944                 shr     ax,1\r
945                 shr     ax,1\r
946                 shr     ax,1\r
947                 shr     ax,1\r
948                 mov     dx,ds\r
949                 add     dx,ax\r
950                 mov     ds,dx\r
951                 and     si,0xf\r
952 #ifdef __BORLANDC__\r
953         }\r
954 #endif\r
955 sinorm:\r
956 #ifdef __BORLANDC__\r
957         __asm {\r
958 #endif\r
959                 cmp     di,0x10         // normalize es:di\r
960                 jb      dinorm\r
961                 mov     ax,di\r
962                 shr     ax,1\r
963                 shr     ax,1\r
964                 shr     ax,1\r
965                 shr     ax,1\r
966                 mov     dx,es\r
967                 add     dx,ax\r
968                 mov     es,dx\r
969                 and     di,0xf\r
970 #ifdef __BORLANDC__\r
971         }\r
972 #endif\r
973 dinorm:\r
974 #ifdef __BORLANDC__\r
975         __asm {\r
976 #endif\r
977                 cmp     di,ss:endoff\r
978                 jne     expand\r
979                 mov     ax,es\r
980                 cmp     ax,ss:endseg\r
981                 jb      expand\r
982 \r
983                 mov     ax,ss\r
984                 mov     ds,ax\r
985         }\r
986 }\r
987 \r
988 \r
989 /*\r
990 =============================================================================\r
991 \r
992                                          CACHE MANAGER ROUTINES\r
993 \r
994 =============================================================================\r
995 */\r
996 \r
997 /*\r
998 ======================\r
999 =\r
1000 = CAL_SetupGrFile\r
1001 =\r
1002 ======================\r
1003 */\r
1004 ////++++ enable!\r
1005 /*void CAL_SetupGrFile (void)\r
1006 {\r
1007         int handle;\r
1008         memptr compseg;\r
1009 \r
1010 #ifdef GRHEADERLINKED\r
1011 \r
1012 #if GRMODE == EGAGR\r
1013         grhuffman = (huffnode *)&EGAdict;\r
1014         grstarts = (long _seg *)FP_SEG(&EGAhead);\r
1015 #endif\r
1016 #if GRMODE == CGAGR\r
1017         grhuffman = (huffnode *)&CGAdict;\r
1018         grstarts = (long _seg *)FP_SEG(&CGAhead);\r
1019 #endif\r
1020 \r
1021         CAL_OptimizeNodes (grhuffman);\r
1022 \r
1023 #else\r
1024 \r
1025 //\r
1026 // load ???dict.ext (huffman dictionary for graphics files)\r
1027 //\r
1028 \r
1029         if ((handle = open(GREXT"DICT."EXT,\r
1030                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1031                 Quit (gvar, "Can't open "GREXT"DICT."EXT"!");\r
1032 \r
1033         read(handle, &grhuffman, sizeof(grhuffman));\r
1034         close(handle);\r
1035         CAL_OptimizeNodes (grhuffman);\r
1036 //\r
1037 // load the data offsets from ???head.ext\r
1038 //\r
1039         MM_GetPtr (&(memptr)grstarts,(NUMCHUNKS+1)*FILEPOSSIZE);\r
1040 \r
1041         if ((handle = open(GREXT"HEAD."EXT,\r
1042                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1043                 Quit (gvar, "Can't open "GREXT"HEAD."EXT"!");\r
1044 \r
1045         CA_FarRead(handle, (memptr)grstarts, (NUMCHUNKS+1)*FILEPOSSIZE);\r
1046 \r
1047         close(handle);\r
1048 \r
1049 \r
1050 #endif\r
1051 \r
1052 //\r
1053 // Open the graphics file, leaving it open until the game is finished\r
1054 //\r
1055         grhandle = open(GREXT"GRAPH."EXT, O_RDONLY | O_BINARY);\r
1056         if (grhandle == -1)\r
1057                 Quit (gvar, "Cannot open "GREXT"GRAPH."EXT"!");\r
1058 \r
1059 \r
1060 //\r
1061 // load the pic and sprite headers into the arrays in the data segment\r
1062 //\r
1063 #if NUMPICS>0\r
1064         MM_GetPtr(&(memptr)pictable,NUMPICS*sizeof(pictabletype));\r
1065         CAL_GetGrChunkLength(STRUCTPIC);                // position file pointer\r
1066         MM_GetPtr(&compseg,chunkcomplen);\r
1067         CA_FarRead (grhandle,compseg,chunkcomplen);\r
1068         CAL_HuffExpand (compseg, (byte far *)pictable,NUMPICS*sizeof(pictabletype),grhuffman);\r
1069         MM_FreePtr(&compseg);\r
1070 #endif\r
1071 \r
1072 #if NUMPICM>0\r
1073         MM_GetPtr(&(memptr)picmtable,NUMPICM*sizeof(pictabletype));\r
1074         CAL_GetGrChunkLength(STRUCTPICM);               // position file pointer\r
1075         MM_GetPtr(&compseg,chunkcomplen);\r
1076         CA_FarRead (grhandle,compseg,chunkcomplen);\r
1077         CAL_HuffExpand (compseg, (byte far *)picmtable,NUMPICS*sizeof(pictabletype),grhuffman);\r
1078         MM_FreePtr(&compseg);\r
1079 #endif\r
1080 \r
1081 #if NUMSPRITES>0\r
1082         MM_GetPtr(&(memptr)spritetable,NUMSPRITES*sizeof(spritetabletype));\r
1083         CAL_GetGrChunkLength(STRUCTSPRITE);     // position file pointer\r
1084         MM_GetPtr(&compseg,chunkcomplen);\r
1085         CA_FarRead (grhandle,compseg,chunkcomplen);\r
1086         CAL_HuffExpand (compseg, (byte far *)spritetable,NUMSPRITES*sizeof(spritetabletype),grhuffman);\r
1087         MM_FreePtr(&compseg);\r
1088 #endif\r
1089 \r
1090 }*/\r
1091 \r
1092 //==========================================================================\r
1093 \r
1094 \r
1095 /*\r
1096 ======================\r
1097 =\r
1098 = CAL_SetupMapFile\r
1099 =\r
1100 ======================\r
1101 */\r
1102 \r
1103 void CAL_SetupMapFile (global_game_variables_t *gvar)\r
1104 {\r
1105 /*      int handle;\r
1106         long length;\r
1107 \r
1108 //\r
1109 // load maphead.ext (offsets and tileinfo for map file)\r
1110 //\r
1111 #ifndef MAPHEADERLINKED\r
1112         if ((handle = open("MAPHEAD."EXT,\r
1113                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1114                 printf("Can't open MAPHEAD."EXT"!");\r
1115         length = filelength(handle);\r
1116         MM_GetPtr (&(memptr)tinf,length);\r
1117         CA_FarRead(handle, tinf, length);\r
1118         close(handle);\r
1119 //#else\r
1120 \r
1121         tinf = (byte _seg *)FP_SEG(&maphead);\r
1122 \r
1123 #endif*/\r
1124 \r
1125 //\r
1126 // open the data file\r
1127 //\r
1128 //TODO: multiple files\r
1129         if ((gvar->ca.file.maphandle[0] = open("data/test.map",\r
1130                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1131         {\r
1132                 printf("Can't open data/test.map!");\r
1133         }\r
1134 // #ifdef MAPHEADERLINKED\r
1135 //      if ((maphandle = open("GAMEMAPS."EXT,\r
1136 //               O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1137 //              Quit (gvar, "Can't open GAMEMAPS."EXT"!");\r
1138 // //#else\r
1139 //      if ((maphandle = open("MAPTEMP."EXT,\r
1140 //               O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1141 //              Quit (gvar, "Can't open MAPTEMP."EXT"!");\r
1142 // #endif\r
1143 }\r
1144 \r
1145 //==========================================================================\r
1146 \r
1147 \r
1148 /*\r
1149 ======================\r
1150 =\r
1151 = CAL_SetupAudioFile\r
1152 =\r
1153 ======================\r
1154 */\r
1155 \r
1156 /*void CAL_SetupAudioFile (void)\r
1157 {\r
1158         int handle;\r
1159         long length;\r
1160 \r
1161 //\r
1162 // load maphead.ext (offsets and tileinfo for map file)\r
1163 //\r
1164 #ifndef AUDIOHEADERLINKED\r
1165         if ((handle = open("AUDIOHED."EXT,\r
1166                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1167                 Quit (gvar, "Can't open AUDIOHED."EXT"!");\r
1168         length = filelength(handle);\r
1169         MM_GetPtr (&(memptr)audiostarts,length);\r
1170         CA_FarRead(handle, (byte far *)audiostarts, length);\r
1171         close(handle);\r
1172 #else\r
1173         audiohuffman = (huffnode *)&audiodict;\r
1174         CAL_OptimizeNodes (audiohuffman);\r
1175         audiostarts = (long _seg *)FP_SEG(&audiohead);\r
1176 #endif\r
1177 \r
1178 //\r
1179 // open the data file\r
1180 //\r
1181 #ifndef AUDIOHEADERLINKED\r
1182         if ((audiohandle = open("AUDIOT."EXT,\r
1183                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1184                 Quit (gvar, "Can't open AUDIOT."EXT"!");\r
1185 #else\r
1186         if ((audiohandle = open("AUDIO."EXT,\r
1187                  O_RDONLY | O_BINARY, S_IREAD)) == -1)\r
1188                 Quit (gvar, "Can't open AUDIO."EXT"!");\r
1189 #endif\r
1190 }*/\r
1191 \r
1192 //==========================================================================\r
1193 \r
1194 \r
1195 /*\r
1196 ======================\r
1197 =\r
1198 = CA_Startup\r
1199 =\r
1200 = Open all files and load in headers\r
1201 =\r
1202 ======================\r
1203 */\r
1204 \r
1205 void CA_Startup(global_game_variables_t *gvar)\r
1206 {\r
1207 #ifdef PROFILE\r
1208 #ifdef __BORLANDC__\r
1209         unlink("profile.16b");\r
1210         gvar->handle.profilehandle = open("profile.16b", O_CREAT | O_WRONLY | O_TEXT);\r
1211 #endif\r
1212 #ifdef __WATCOMC__\r
1213         unlink("profile.16w");\r
1214         gvar->handle.profilehandle = open("profile.16w", O_CREAT | O_WRONLY | O_TEXT);\r
1215 #endif\r
1216 #endif//profile\r
1217 \r
1218 #ifdef __BORLANDC__\r
1219         unlink("meminfo.16b");\r
1220         gvar->handle.showmemhandle = open("meminfo.16b", O_CREAT | O_WRONLY | O_TEXT);\r
1221 #endif\r
1222 #ifdef __WATCOMC__\r
1223         unlink("meminfo.16w");\r
1224         gvar->handle.showmemhandle = open("meminfo.16w", O_CREAT | O_WRONLY | O_TEXT);\r
1225 #endif\r
1226 /*\r
1227         CAL_SetupGrFile ();\r
1228         CAL_SetupAudioFile ();*/\r
1229         CAL_SetupMapFile (gvar);\r
1230 \r
1231         gvar->ca.camap.mapon = -1;\r
1232         gvar->ca.ca_levelbit = 1;\r
1233         gvar->ca.ca_levelnum = 0;\r
1234 \r
1235 /*      drawcachebox    = CAL_DialogDraw;\r
1236         updatecachebox  = CAL_DialogUpdate;\r
1237         finishcachebox  = CAL_DialogFinish;*/\r
1238 }\r
1239 \r
1240 //==========================================================================\r
1241 \r
1242 \r
1243 /*\r
1244 ======================\r
1245 =\r
1246 = CA_Shutdown\r
1247 =\r
1248 = Closes all files\r
1249 =\r
1250 ======================\r
1251 */\r
1252 \r
1253 void CA_Shutdown(global_game_variables_t *gvar)\r
1254 {\r
1255 #ifdef PROFILE\r
1256         close(gvar->handle.profilehandle);\r
1257 #endif\r
1258         close(gvar->handle.showmemhandle);\r
1259 \r
1260         close(*(gvar->ca.file.maphandle));\r
1261 /*++++\r
1262         close(grhandle);\r
1263         close(audiohandle);*/\r
1264 }\r
1265 \r
1266 //===========================================================================\r
1267 \r
1268 /*\r
1269 ======================\r
1270 =\r
1271 = CA_CacheAudioChunk\r
1272 =\r
1273 ======================\r
1274 */\r
1275 /*++++\r
1276 void CA_CacheAudioChunk (int chunk)\r
1277 {\r
1278         long    pos,compressed;\r
1279 #ifdef AUDIOHEADERLINKED\r
1280         long    expanded;\r
1281         memptr  bigbufferseg;\r
1282         byte    far *source;\r
1283 #endif\r
1284 \r
1285         if (audiosegs[chunk])\r
1286         {\r
1287                 MM_SetPurge (&(memptr)audiosegs[chunk],0);\r
1288                 return;                                                 // allready in memory\r
1289         }\r
1290 \r
1291 // MDM begin - (GAMERS EDGE)\r
1292 //\r
1293         if (!FindFile("AUDIO."EXT,NULL,2))\r
1294                 Quit (gvar, "CA_CacheAudioChunk(): Can't find audio files.");\r
1295 //\r
1296 // MDM end\r
1297 \r
1298 //\r
1299 // load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
1300 // a larger buffer\r
1301 //\r
1302         pos = audiostarts[chunk];\r
1303         compressed = audiostarts[chunk+1]-pos;\r
1304 \r
1305         lseek(audiohandle,pos,SEEK_SET);\r
1306 \r
1307 #ifndef AUDIOHEADERLINKED\r
1308 \r
1309         MM_GetPtr (&(memptr)audiosegs[chunk],compressed);\r
1310         if (mmerror)\r
1311                 return;\r
1312 \r
1313         CA_FarRead(audiohandle,audiosegs[chunk],compressed);\r
1314 \r
1315 #else\r
1316 \r
1317         if (compressed<=BUFFERSIZE)\r
1318         {\r
1319                 CA_FarRead(audiohandle,bufferseg,compressed);\r
1320                 source = bufferseg;\r
1321         }\r
1322         else\r
1323         {\r
1324                 MM_GetPtr(&bigbufferseg,compressed);\r
1325                 if (mmerror)\r
1326                         return;\r
1327                 MM_SetLock (&bigbufferseg,true);\r
1328                 CA_FarRead(audiohandle,bigbufferseg,compressed);\r
1329                 source = bigbufferseg;\r
1330         }\r
1331 \r
1332         expanded = *(long far *)source;\r
1333         source += 4;                    // skip over length\r
1334         MM_GetPtr (&(memptr)audiosegs[chunk],expanded);\r
1335         if (mmerror)\r
1336                 goto done;\r
1337         CAL_HuffExpand (source,audiosegs[chunk],expanded,audiohuffman);\r
1338 \r
1339 done:\r
1340         if (compressed>BUFFERSIZE)\r
1341                 MM_FreePtr(&bigbufferseg);\r
1342 #endif\r
1343 }*/\r
1344 \r
1345 //===========================================================================\r
1346 \r
1347 /*\r
1348 ======================\r
1349 =\r
1350 = CA_LoadAllSounds\r
1351 =\r
1352 = Purges all sounds, then loads all new ones (mode switch)\r
1353 =\r
1354 ======================\r
1355 */\r
1356 /*++++\r
1357 void CA_LoadAllSounds (void)\r
1358 {\r
1359         unsigned        start,i;\r
1360 \r
1361         switch (oldsoundmode)\r
1362         {\r
1363         case sdm_Off:\r
1364                 goto cachein;\r
1365         case sdm_PC:\r
1366                 start = STARTPCSOUNDS;\r
1367                 break;\r
1368         case sdm_AdLib:\r
1369                 start = STARTADLIBSOUNDS;\r
1370                 break;\r
1371         }\r
1372 \r
1373         for (i=0;i<NUMSOUNDS;i++,start++)\r
1374                 if (audiosegs[start])\r
1375                         MM_SetPurge (&(memptr)audiosegs[start],3);              // make purgable\r
1376 \r
1377 cachein:\r
1378 \r
1379         switch (SoundMode)\r
1380         {\r
1381         case sdm_Off:\r
1382                 return;\r
1383         case sdm_PC:\r
1384                 start = STARTPCSOUNDS;\r
1385                 break;\r
1386         case sdm_AdLib:\r
1387                 start = STARTADLIBSOUNDS;\r
1388                 break;\r
1389         }\r
1390 \r
1391         for (i=0;i<NUMSOUNDS;i++,start++)\r
1392                 CA_CacheAudioChunk (start);\r
1393 \r
1394         oldsoundmode = SoundMode;\r
1395 }*/\r
1396 \r
1397 //===========================================================================\r
1398 \r
1399 //++++#if GRMODE == EGAGR\r
1400 \r
1401 /*\r
1402 ======================\r
1403 =\r
1404 = CAL_ShiftSprite\r
1405 =\r
1406 = Make a shifted (one byte wider) copy of a sprite into another area\r
1407 =\r
1408 ======================\r
1409 */\r
1410 /*++++\r
1411 unsigned        static  sheight,swidth;\r
1412 boolean static dothemask;\r
1413 \r
1414 void CAL_ShiftSprite (unsigned segment,unsigned source,unsigned dest,\r
1415         unsigned width, unsigned height, unsigned pixshift, boolean domask)\r
1416 {\r
1417 \r
1418         sheight = height;               // because we are going to reassign bp\r
1419         swidth = width;\r
1420         dothemask = domask;\r
1421 \r
1422 asm     mov     ax,[segment]\r
1423 asm     mov     ds,ax           // source and dest are in same segment, and all local\r
1424 \r
1425 asm     mov     bx,[source]\r
1426 asm     mov     di,[dest]\r
1427 \r
1428 asm     mov     bp,[pixshift]\r
1429 asm     shl     bp,1\r
1430 asm     mov     bp,WORD PTR [shifttabletable+bp]        // bp holds pointer to shift table\r
1431 \r
1432 asm     cmp     [ss:dothemask],0\r
1433 asm     je              skipmask\r
1434 \r
1435 //\r
1436 // table shift the mask\r
1437 //\r
1438 asm     mov     dx,[ss:sheight]\r
1439 \r
1440 domaskrow:\r
1441 \r
1442 asm     mov     BYTE PTR [di],255       // 0xff first byte\r
1443 asm     mov     cx,ss:[swidth]\r
1444 \r
1445 domaskbyte:\r
1446 \r
1447 asm     mov     al,[bx]                         // source\r
1448 asm     not     al\r
1449 asm     inc     bx                                      // next source byte\r
1450 asm     xor     ah,ah\r
1451 asm     shl     ax,1\r
1452 asm     mov     si,ax\r
1453 asm     mov     ax,[bp+si]                      // table shift into two bytes\r
1454 asm     not     ax\r
1455 asm     and     [di],al                         // and with first byte\r
1456 asm     inc     di\r
1457 asm     mov     [di],ah                         // replace next byte\r
1458 \r
1459 asm     loop    domaskbyte\r
1460 \r
1461 asm     inc     di                                      // the last shifted byte has 1s in it\r
1462 asm     dec     dx\r
1463 asm     jnz     domaskrow\r
1464 \r
1465 skipmask:\r
1466 \r
1467 //\r
1468 // table shift the data\r
1469 //\r
1470 asm     mov     dx,ss:[sheight]\r
1471 asm     shl     dx,1\r
1472 asm     shl     dx,1                            // four planes of data\r
1473 \r
1474 dodatarow:\r
1475 \r
1476 asm     mov     BYTE PTR [di],0         // 0 first byte\r
1477 asm     mov     cx,ss:[swidth]\r
1478 \r
1479 dodatabyte:\r
1480 \r
1481 asm     mov     al,[bx]                         // source\r
1482 asm     inc     bx                                      // next source byte\r
1483 asm     xor     ah,ah\r
1484 asm     shl     ax,1\r
1485 asm     mov     si,ax\r
1486 asm     mov     ax,[bp+si]                      // table shift into two bytes\r
1487 asm     or      [di],al                         // or with first byte\r
1488 asm     inc     di\r
1489 asm     mov     [di],ah                         // replace next byte\r
1490 \r
1491 asm     loop    dodatabyte\r
1492 \r
1493 asm     inc     di                                      // the last shifted byte has 0s in it\r
1494 asm     dec     dx\r
1495 asm     jnz     dodatarow\r
1496 \r
1497 //\r
1498 // done\r
1499 //\r
1500 \r
1501 asm     mov     ax,ss                           // restore data segment\r
1502 asm     mov     ds,ax\r
1503 \r
1504 }\r
1505 \r
1506 #endif\r
1507 */\r
1508 //===========================================================================\r
1509 \r
1510 /*\r
1511 ======================\r
1512 =\r
1513 = CAL_CacheSprite\r
1514 =\r
1515 = Generate shifts and set up sprite structure for a given sprite\r
1516 =\r
1517 ======================\r
1518 */\r
1519 /*++++\r
1520 void CAL_CacheSprite (int chunk, byte far *compressed)\r
1521 {\r
1522         int i;\r
1523         unsigned shiftstarts[5];\r
1524         unsigned smallplane,bigplane,expanded;\r
1525         spritetabletype far *spr;\r
1526         spritetype _seg *dest;\r
1527 \r
1528 #if GRMODE == CGAGR\r
1529 //\r
1530 // CGA has no pel panning, so shifts are never needed\r
1531 //\r
1532         spr = &spritetable[chunk-STARTSPRITES];\r
1533         smallplane = spr->width*spr->height;\r
1534         MM_GetPtr (&grsegs[chunk],smallplane*2+MAXSHIFTS*6);\r
1535         if (mmerror)\r
1536                 return;\r
1537         dest = (spritetype _seg *)grsegs[chunk];\r
1538         dest->sourceoffset[0] = MAXSHIFTS*6;    // start data after 3 unsigned tables\r
1539         dest->planesize[0] = smallplane;\r
1540         dest->width[0] = spr->width;\r
1541 \r
1542 //\r
1543 // expand the unshifted shape\r
1544 //\r
1545         CAL_HuffExpand (compressed, &dest->data[0],smallplane*2,grhuffman);\r
1546 \r
1547 #endif\r
1548 \r
1549 \r
1550 #if GRMODE == EGAGR\r
1551 \r
1552 //\r
1553 // calculate sizes\r
1554 //\r
1555         spr = &spritetable[chunk-STARTSPRITES];\r
1556         smallplane = spr->width*spr->height;\r
1557         bigplane = (spr->width+1)*spr->height;\r
1558 \r
1559         shiftstarts[0] = MAXSHIFTS*6;   // start data after 3 unsigned tables\r
1560         shiftstarts[1] = shiftstarts[0] + smallplane*5; // 5 planes in a sprite\r
1561         shiftstarts[2] = shiftstarts[1] + bigplane*5;\r
1562         shiftstarts[3] = shiftstarts[2] + bigplane*5;\r
1563         shiftstarts[4] = shiftstarts[3] + bigplane*5;   // nothing ever put here\r
1564 \r
1565         expanded = shiftstarts[spr->shifts];\r
1566         MM_GetPtr (&grsegs[chunk],expanded);\r
1567         if (mmerror)\r
1568                 return;\r
1569         dest = (spritetype _seg *)grsegs[chunk];\r
1570 \r
1571 //\r
1572 // expand the unshifted shape\r
1573 //\r
1574         CAL_HuffExpand (compressed, &dest->data[0],smallplane*5,grhuffman);\r
1575 \r
1576 //\r
1577 // make the shifts!\r
1578 //\r
1579         switch (spr->shifts)\r
1580         {\r
1581         case    1:\r
1582                 for (i=0;i<4;i++)\r
1583                 {\r
1584                         dest->sourceoffset[i] = shiftstarts[0];\r
1585                         dest->planesize[i] = smallplane;\r
1586                         dest->width[i] = spr->width;\r
1587                 }\r
1588                 break;\r
1589 \r
1590         case    2:\r
1591                 for (i=0;i<2;i++)\r
1592                 {\r
1593                         dest->sourceoffset[i] = shiftstarts[0];\r
1594                         dest->planesize[i] = smallplane;\r
1595                         dest->width[i] = spr->width;\r
1596                 }\r
1597                 for (i=2;i<4;i++)\r
1598                 {\r
1599                         dest->sourceoffset[i] = shiftstarts[1];\r
1600                         dest->planesize[i] = bigplane;\r
1601                         dest->width[i] = spr->width+1;\r
1602                 }\r
1603                 CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
1604                         dest->sourceoffset[2],spr->width,spr->height,4,true);\r
1605                 break;\r
1606 \r
1607         case    4:\r
1608                 dest->sourceoffset[0] = shiftstarts[0];\r
1609                 dest->planesize[0] = smallplane;\r
1610                 dest->width[0] = spr->width;\r
1611 \r
1612                 dest->sourceoffset[1] = shiftstarts[1];\r
1613                 dest->planesize[1] = bigplane;\r
1614                 dest->width[1] = spr->width+1;\r
1615                 CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
1616                         dest->sourceoffset[1],spr->width,spr->height,2,true);\r
1617 \r
1618                 dest->sourceoffset[2] = shiftstarts[2];\r
1619                 dest->planesize[2] = bigplane;\r
1620                 dest->width[2] = spr->width+1;\r
1621                 CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
1622                         dest->sourceoffset[2],spr->width,spr->height,4,true);\r
1623 \r
1624                 dest->sourceoffset[3] = shiftstarts[3];\r
1625                 dest->planesize[3] = bigplane;\r
1626                 dest->width[3] = spr->width+1;\r
1627                 CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],\r
1628                         dest->sourceoffset[3],spr->width,spr->height,6,true);\r
1629 \r
1630                 break;\r
1631 \r
1632         default:\r
1633                 Quit (gvar, "CAL_CacheSprite: Bad shifts number!");\r
1634         }\r
1635 \r
1636 #endif\r
1637 }*/\r
1638 \r
1639 //===========================================================================\r
1640 \r
1641 \r
1642 /*\r
1643 ======================\r
1644 =\r
1645 = CAL_ExpandGrChunk\r
1646 =\r
1647 = Does whatever is needed with a pointer to a compressed chunk\r
1648 =\r
1649 ======================\r
1650 */\r
1651 /*++++\r
1652 void CAL_ExpandGrChunk (int chunk, byte far *source)\r
1653 {\r
1654         long    expanded;\r
1655 \r
1656 \r
1657         if (chunk >= STARTTILE8 && chunk < STARTEXTERNS)\r
1658         {\r
1659         //\r
1660         // expanded sizes of tile8/16/32 are implicit\r
1661         //\r
1662 \r
1663 #if GRMODE == EGAGR\r
1664 #define BLOCK           32\r
1665 #define MASKBLOCK       40\r
1666 #endif\r
1667 \r
1668 #if GRMODE == CGAGR\r
1669 #define BLOCK           16\r
1670 #define MASKBLOCK       32\r
1671 #endif\r
1672 \r
1673                 if (chunk<STARTTILE8M)                  // tile 8s are all in one chunk!\r
1674                         expanded = BLOCK*NUMTILE8;\r
1675                 else if (chunk<STARTTILE16)\r
1676                         expanded = MASKBLOCK*NUMTILE8M;\r
1677                 else if (chunk<STARTTILE16M)    // all other tiles are one/chunk\r
1678                         expanded = BLOCK*4;\r
1679                 else if (chunk<STARTTILE32)\r
1680                         expanded = MASKBLOCK*4;\r
1681                 else if (chunk<STARTTILE32M)\r
1682                         expanded = BLOCK*16;\r
1683                 else\r
1684                         expanded = MASKBLOCK*16;\r
1685         }\r
1686         else\r
1687         {\r
1688         //\r
1689         // everything else has an explicit size longword\r
1690         //\r
1691                 expanded = *(long far *)source;\r
1692                 source += 4;                    // skip over length\r
1693         }\r
1694 \r
1695 //\r
1696 // allocate final space, decompress it, and free bigbuffer\r
1697 // Sprites need to have shifts made and various other junk\r
1698 //\r
1699         if (chunk>=STARTSPRITES && chunk< STARTTILE8)\r
1700                 CAL_CacheSprite(chunk,source);\r
1701         else\r
1702         {\r
1703                 MM_GetPtr (&grsegs[chunk],expanded);\r
1704                 if (mmerror)\r
1705                         return;\r
1706                 CAL_HuffExpand (source,grsegs[chunk],expanded,grhuffman);\r
1707         }\r
1708 }\r
1709 */\r
1710 \r
1711 /*\r
1712 ======================\r
1713 =\r
1714 = CAL_ReadGrChunk\r
1715 =\r
1716 = Gets a chunk off disk, optimizing reads to general buffer\r
1717 =\r
1718 ======================\r
1719 */\r
1720 /*++++\r
1721 void CAL_ReadGrChunk (int chunk)\r
1722 {\r
1723         long    pos,compressed;\r
1724         memptr  bigbufferseg;\r
1725         byte    far *source;\r
1726         int             next;\r
1727 \r
1728 //\r
1729 // load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
1730 // a larger buffer\r
1731 //\r
1732         pos = GRFILEPOS(chunk);\r
1733         if (pos<0)                                                      // $FFFFFFFF start is a sparse tile\r
1734           return;\r
1735 \r
1736         next = chunk +1;\r
1737         while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
1738                 next++;\r
1739 \r
1740         compressed = GRFILEPOS(next)-pos;\r
1741 \r
1742         lseek(grhandle,pos,SEEK_SET);\r
1743 \r
1744         if (compressed<=BUFFERSIZE)\r
1745         {\r
1746                 CA_FarRead(grhandle,bufferseg,compressed);\r
1747                 source = bufferseg;\r
1748         }\r
1749         else\r
1750         {\r
1751                 MM_GetPtr(&bigbufferseg,compressed);\r
1752                 if (mmerror)\r
1753                         return;\r
1754                 MM_SetLock (&bigbufferseg,true);\r
1755                 CA_FarRead(grhandle,bigbufferseg,compressed);\r
1756                 source = bigbufferseg;\r
1757         }\r
1758 \r
1759         CAL_ExpandGrChunk (chunk,source);\r
1760 \r
1761         if (compressed>BUFFERSIZE)\r
1762                 MM_FreePtr(&bigbufferseg);\r
1763 }\r
1764 */\r
1765 /*\r
1766 ======================\r
1767 =\r
1768 = CA_CacheGrChunk\r
1769 =\r
1770 = Makes sure a given chunk is in memory, loadiing it if needed\r
1771 =\r
1772 ======================\r
1773 */\r
1774 /*++++\r
1775 void CA_CacheGrChunk (int chunk)\r
1776 {\r
1777         long    pos,compressed;\r
1778         memptr  bigbufferseg;\r
1779         byte    far *source;\r
1780         int             next;\r
1781 \r
1782         gvar->video.grneeded[chunk] |= ca_levelbit;             // make sure it doesn't get removed\r
1783         if (grsegs[chunk])\r
1784         {\r
1785                 MM_SetPurge (&grsegs[chunk],0);\r
1786                 return;                                                 // allready in memory\r
1787         }\r
1788 \r
1789 // MDM begin - (GAMERS EDGE)\r
1790 //\r
1791         if (!FindFile("EGAGRAPH."EXT,NULL,2))\r
1792                 Quit (gvar, "CA_CacheGrChunk(): Can't find graphics files.");\r
1793 //\r
1794 // MDM end\r
1795 \r
1796 //\r
1797 // load the chunk into a buffer, either the miscbuffer if it fits, or allocate\r
1798 // a larger buffer\r
1799 //\r
1800         pos = GRFILEPOS(chunk);\r
1801         if (pos<0)                                                      // $FFFFFFFF start is a sparse tile\r
1802           return;\r
1803 \r
1804         next = chunk +1;\r
1805         while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
1806                 next++;\r
1807 \r
1808         compressed = GRFILEPOS(next)-pos;\r
1809 \r
1810         lseek(grhandle,pos,SEEK_SET);\r
1811 \r
1812         if (compressed<=BUFFERSIZE)\r
1813         {\r
1814                 CA_FarRead(grhandle,bufferseg,compressed);\r
1815                 source = bufferseg;\r
1816         }\r
1817         else\r
1818         {\r
1819                 MM_GetPtr(&bigbufferseg,compressed);\r
1820                 MM_SetLock (&bigbufferseg,true);\r
1821                 CA_FarRead(grhandle,bigbufferseg,compressed);\r
1822                 source = bigbufferseg;\r
1823         }\r
1824 \r
1825         CAL_ExpandGrChunk (chunk,source);\r
1826 \r
1827         if (compressed>BUFFERSIZE)\r
1828                 MM_FreePtr(&bigbufferseg);\r
1829 }\r
1830 */\r
1831 \r
1832 \r
1833 //==========================================================================\r
1834 \r
1835 /*\r
1836 ======================\r
1837 =\r
1838 = CA_CacheMap\r
1839 =\r
1840 ======================\r
1841 */\r
1842 /*++++ segments!\r
1843 void CA_CacheMap (global_game_variables_t *gvar)\r
1844 {\r
1845         long    pos,compressed;\r
1846         int             plane;\r
1847         memptr  *dest,bigbufferseg;\r
1848         unsigned        size;\r
1849         unsigned        far     *source;\r
1850 #ifdef MAPHEADERLINKED\r
1851         memptr  buffer2seg;\r
1852         long    expanded;\r
1853 #endif\r
1854 \r
1855 \r
1856 //\r
1857 // free up memory from last map\r
1858 //\r
1859         if (gvar->ca.camap.mapon>-1 && gvar->ca.camap.mapheaderseg[gvar->ca.camap.mapon])\r
1860                 MM_SetPurge (((memptr)gvar->ca.camap.mapheaderseg[(gvar->ca.camap.mapon)]), 3, gvar);\r
1861         for (plane=0;plane<MAPPLANES;plane++)\r
1862                 if (gvar->ca.camap.mapsegs[plane])\r
1863                         MM_FreePtr ((memptr)gvar->ca.camap.mapsegs[plane], gvar);\r
1864 \r
1865         gvar->ca.camap.mapon = gvar->ca.camap.mapnum;\r
1866 \r
1867 \r
1868 //\r
1869 // load map header\r
1870 // The header will be cached if it is still around\r
1871 //\r
1872 //      if (!gvar->ca.camap.mapheaderseg[gvar->ca.camap.mapnum])\r
1873 //      {\r
1874 //              //pos = ((mapfiletype   _seg *)tinf)->headeroffsets[mapnum];\r
1875 //              //pos = ((_seg *)gvar->ca.camap.tinf)->headeroffsets[gvar->ca.camap.mapnum];\r
1876 //              pos = ((memptr)gvar->ca.camap.tinf)->headeroffsets[gvar->ca.camap.mapnum];\r
1877 //              if (pos<0)                                              // $FFFFFFFF start is a sparse map\r
1878 //                printf("CA_CacheMap: Tried to load a non existent map!");\r
1879 \r
1880 //              MM_GetPtr(&(memptr)gvar->ca.camapheaderseg[mapnum],sizeof(maptype));\r
1881 //              lseek(maphandle,pos,SEEK_SET);\r
1882 //              CA_FarRead (maphandle,(memptr)mapheaderseg[mapnum],sizeof(maptype));\r
1883 //      }\r
1884 //      else\r
1885 //              MM_SetPurge (&(memptr)mapheaderseg[mapnum], 0, &(gvar->mm));\r
1886 \r
1887 //\r
1888 // load the planes in\r
1889 // If a plane's pointer still exists it will be overwritten (levels are\r
1890 // allways reloaded, never cached)\r
1891 //\r
1892 \r
1893         size = mapheaderseg[mapnum]->width * mapheaderseg[mapnum]->height * 2;\r
1894 \r
1895         for (plane = 0; plane<MAPPLANES; plane++)\r
1896         {\r
1897                 //pos = mapheaderseg[mapnum]->planestart[plane];\r
1898                 //compressed = mapheaderseg[mapnum]->planelength[plane];\r
1899 \r
1900                 if (!compressed)\r
1901                         continue;               // the plane is not used in this game\r
1902 \r
1903                 dest = &(memptr)mapsegs[plane];\r
1904                 MM_GetPtr(dest,size);\r
1905 \r
1906                 lseek(maphandle,pos,SEEK_SET);\r
1907                 if (compressed<=BUFFERSIZE)\r
1908                         source = bufferseg;\r
1909                 else\r
1910                 {\r
1911                         MM_GetPtr(&bigbufferseg,compressed);\r
1912                         MM_SetLock (&bigbufferseg,true);\r
1913                         source = bigbufferseg;\r
1914                 }\r
1915 \r
1916                 CA_FarRead(maphandle,(byte far *)source,compressed);\r
1917 #ifdef MAPHEADERLINKED\r
1918                 //\r
1919                 // unhuffman, then unRLEW\r
1920                 // The huffman'd chunk has a two byte expanded length first\r
1921                 // The resulting RLEW chunk also does, even though it's not really\r
1922                 // needed\r
1923                 //\r
1924                 expanded = *source;\r
1925                 source++;\r
1926                 MM_GetPtr (&buffer2seg,expanded);\r
1927                 CAL_CarmackExpand (source, (unsigned far *)buffer2seg,expanded);\r
1928                 CA_RLEWexpand (((unsigned far *)buffer2seg)+1,*dest,size,\r
1929                 ((mapfiletype _seg *)tinf)->RLEWtag);\r
1930                 MM_FreePtr (&buffer2seg);\r
1931 \r
1932 #else\r
1933                 //\r
1934                 // unRLEW, skipping expanded length\r
1935                 //\r
1936                 CA_RLEWexpand (source+1, *dest,size,\r
1937                 ((mapfiletype _seg *)tinf)->RLEWtag);\r
1938 #endif\r
1939 \r
1940                 if (compressed>BUFFERSIZE)\r
1941                         MM_FreePtr(&bigbufferseg);\r
1942         }\r
1943 }//*/\r
1944 \r
1945 //===========================================================================\r
1946 \r
1947 /*\r
1948 ======================\r
1949 =\r
1950 = CA_UpLevel\r
1951 =\r
1952 = Goes up a bit level in the needed lists and clears it out.\r
1953 = Everything is made purgable\r
1954 =\r
1955 ======================\r
1956 */\r
1957 \r
1958 void CA_UpLevel (global_game_variables_t *gvar)\r
1959 {\r
1960         if (gvar->ca.ca_levelnum==7)\r
1961                 printf("CA_UpLevel: Up past level 7!");\r
1962 \r
1963         gvar->ca.ca_levelbit<<=1;\r
1964         gvar->ca.ca_levelnum++;\r
1965 }\r
1966 \r
1967 //===========================================================================\r
1968 \r
1969 /*\r
1970 ======================\r
1971 =\r
1972 = CA_DownLevel\r
1973 =\r
1974 = Goes down a bit level in the needed lists and recaches\r
1975 = everything from the lower level\r
1976 =\r
1977 ======================\r
1978 */\r
1979 \r
1980 void CA_DownLevel (global_game_variables_t *gvar)\r
1981 {\r
1982         if (!gvar->ca.ca_levelnum)\r
1983                 printf("CA_DownLevel: Down past level 0!");\r
1984         gvar->ca.ca_levelbit>>=1;\r
1985         gvar->ca.ca_levelnum--;\r
1986         ////++++++++++++++++++++++++++++++++++++++++++CA_CacheMarks(NULL);\r
1987 }\r
1988 \r
1989 //===========================================================================\r
1990 \r
1991 /*\r
1992 ======================\r
1993 =\r
1994 = CA_ClearMarks\r
1995 =\r
1996 = Clears out all the marks at the current level\r
1997 =\r
1998 ======================\r
1999 */\r
2000 \r
2001 void CA_ClearMarks (global_game_variables_t *gvar)\r
2002 {\r
2003         int i;\r
2004 \r
2005         for (i=0;i<NUMCHUNKS;i++)\r
2006                 gvar->video.grneeded[i]&=~gvar->ca.ca_levelbit;\r
2007 }\r
2008 \r
2009 //===========================================================================\r
2010 \r
2011 /*\r
2012 ======================\r
2013 =\r
2014 = CA_ClearAllMarks\r
2015 =\r
2016 = Clears out all the marks on all the levels\r
2017 =\r
2018 ======================\r
2019 */\r
2020 \r
2021 void CA_ClearAllMarks (global_game_variables_t *gvar)\r
2022 {\r
2023         _fmemset (gvar->video.grneeded,0,sizeof(gvar->video.grneeded));\r
2024         gvar->ca.ca_levelbit = 1;\r
2025         gvar->ca.ca_levelnum = 0;\r
2026 }\r
2027 \r
2028 //===========================================================================\r
2029 \r
2030 /*\r
2031 ======================\r
2032 =\r
2033 = CA_FreeGraphics\r
2034 =\r
2035 ======================\r
2036 */\r
2037 \r
2038 void CA_SetGrPurge (global_game_variables_t *gvar)\r
2039 {\r
2040         int i;\r
2041 \r
2042 //\r
2043 // free graphics\r
2044 //\r
2045         CA_ClearMarks (gvar);\r
2046 \r
2047         for (i=0;i<NUMCHUNKS;i++)\r
2048                 if (gvar->ca.grsegs[i])\r
2049                         MM_SetPurge (gvar->ca.grsegs[i],3, gvar);\r
2050 }\r
2051 \r
2052 \r
2053 /*\r
2054 ======================\r
2055 =\r
2056 = CA_SetAllPurge\r
2057 =\r
2058 = Make everything possible purgable\r
2059 =\r
2060 ======================\r
2061 */\r
2062 \r
2063 void CA_SetAllPurge (global_game_variables_t *gvar)\r
2064 {\r
2065         int i;\r
2066 \r
2067         CA_ClearMarks (gvar);\r
2068 \r
2069 //\r
2070 // free cursor sprite and background save\r
2071 //\r
2072         //VW_FreeCursor ();\r
2073 \r
2074 //\r
2075 // free map headers and map planes\r
2076 //\r
2077 //      for (i=0;i<NUMMAPS;i++)\r
2078 //              if (gvar->ca.camap.mapheaderseg[i])\r
2079 //                      MM_SetPurge (gvar->ca.camap.mapheaderseg[i],3, gvar);\r
2080 \r
2081         for (i=0;i<3;i++)\r
2082                 if (gvar->ca.mapsegs[i])\r
2083                         MM_FreePtr (gvar->ca.mapsegs[i], gvar);\r
2084 \r
2085 //\r
2086 // free sounds\r
2087 //\r
2088         for (i=0;i<NUMSNDCHUNKS;i++)\r
2089                 if (gvar->ca.audiosegs[i])\r
2090                         MM_SetPurge (gvar->ca.audiosegs[i],3, gvar);\r
2091 \r
2092 //\r
2093 // free graphics\r
2094 //\r
2095         CA_SetGrPurge (gvar);\r
2096 }\r
2097 \r
2098 \r
2099 //===========================================================================\r
2100 \r
2101 \r
2102 /*\r
2103 ======================\r
2104 =\r
2105 = CAL_DialogDraw\r
2106 =\r
2107 ======================\r
2108 */\r
2109 /*\r
2110 #define NUMBARS (17l*8)\r
2111 #define BARSTEP 8\r
2112 \r
2113 unsigned        thx,thy,lastx;\r
2114 long            barx,barstep;\r
2115 \r
2116 void    CAL_DialogDraw (char *title,unsigned numcache)\r
2117 {\r
2118         unsigned        homex,homey,x;\r
2119 \r
2120         barstep = (NUMBARS<<16)/numcache;\r
2121 \r
2122 //\r
2123 // draw dialog window (masked tiles 12 - 20 are window borders)\r
2124 //\r
2125         US_CenterWindow (20,8);\r
2126         homex = PrintX;\r
2127         homey = PrintY;\r
2128 \r
2129         US_CPrint ("Loading");\r
2130         fontcolor = F_SECONDCOLOR;\r
2131         US_CPrint (title);\r
2132         fontcolor = F_BLACK;\r
2133 \r
2134 //\r
2135 // draw thermometer bar\r
2136 //\r
2137         thx = homex + 8;\r
2138         thy = homey + 32;\r
2139         VWB_DrawTile8(thx,thy,0);               // CAT3D numbers\r
2140         VWB_DrawTile8(thx,thy+8,3);\r
2141         VWB_DrawTile8(thx,thy+16,6);\r
2142         VWB_DrawTile8(thx+17*8,thy,2);\r
2143         VWB_DrawTile8(thx+17*8,thy+8,5);\r
2144         VWB_DrawTile8(thx+17*8,thy+16,8);\r
2145         for (x=thx+8;x<thx+17*8;x+=8)\r
2146         {\r
2147                 VWB_DrawTile8(x,thy,1);\r
2148                 VWB_DrawTile8(x,thy+8,4);\r
2149                 VWB_DrawTile8(x,thy+16,7);\r
2150         }\r
2151 \r
2152         thx += 4;               // first line location\r
2153         thy += 5;\r
2154         barx = (long)thx<<16;\r
2155         lastx = thx;\r
2156 \r
2157         VW_UpdateScreen();\r
2158 }\r
2159 */\r
2160 \r
2161 /*\r
2162 ======================\r
2163 =\r
2164 = CAL_DialogUpdate\r
2165 =\r
2166 ======================\r
2167 */\r
2168 /*\r
2169 void    CAL_DialogUpdate (void)\r
2170 {\r
2171         unsigned        x,xh;\r
2172 \r
2173         barx+=barstep;\r
2174         xh = barx>>16;\r
2175         if (xh - lastx > BARSTEP)\r
2176         {\r
2177                 for (x=lastx;x<=xh;x++)\r
2178 #if GRMODE == EGAGR\r
2179                         VWB_Vlin (thy,thy+13,x,14);\r
2180 #endif\r
2181 #if GRMODE == CGAGR\r
2182                         VWB_Vlin (thy,thy+13,x,SECONDCOLOR);\r
2183 #endif\r
2184                 lastx = xh;\r
2185                 VW_UpdateScreen();\r
2186         }\r
2187 }*/\r
2188 \r
2189 /*\r
2190 ======================\r
2191 =\r
2192 = CAL_DialogFinish\r
2193 =\r
2194 ======================\r
2195 */\r
2196 /*\r
2197 void    CAL_DialogFinish (void)\r
2198 {\r
2199         unsigned        x,xh;\r
2200 \r
2201         xh = thx + NUMBARS;\r
2202         for (x=lastx;x<=xh;x++)\r
2203 #if GRMODE == EGAGR\r
2204                 VWB_Vlin (thy,thy+13,x,14);\r
2205 #endif\r
2206 #if GRMODE == CGAGR\r
2207                 VWB_Vlin (thy,thy+13,x,SECONDCOLOR);\r
2208 #endif\r
2209         VW_UpdateScreen();\r
2210 \r
2211 }*/\r
2212 \r
2213 //===========================================================================\r
2214 \r
2215 /*\r
2216 ======================\r
2217 =\r
2218 = CA_CacheMarks\r
2219 =\r
2220 ======================\r
2221 *//*\r
2222 #define MAXEMPTYREAD    1024\r
2223 \r
2224 void CA_CacheMarks (char *title)\r
2225 {\r
2226         boolean dialog;\r
2227         int     i,next,numcache;\r
2228         long    pos,endpos,nextpos,nextendpos,compressed;\r
2229         long    bufferstart,bufferend;  // file position of general buffer\r
2230         byte    far *source;\r
2231         memptr  bigbufferseg;\r
2232 \r
2233         dialog = (title!=NULL);\r
2234 \r
2235         numcache = 0;\r
2236 //\r
2237 // go through and make everything not needed purgable\r
2238 //\r
2239         for (i=0;i<NUMCHUNKS;i++)\r
2240                 if (gvar->video.grneeded[i]&ca_levelbit)\r
2241                 {\r
2242                         if (grsegs[i])                                  // its allready in memory, make\r
2243                                 MM_SetPurge(&grsegs[i],0);      // sure it stays there!\r
2244                         else\r
2245                                 numcache++;\r
2246                 }\r
2247                 else\r
2248                 {\r
2249                         if (grsegs[i])                                  // not needed, so make it purgeable\r
2250                                 MM_SetPurge(&grsegs[i],3);\r
2251                 }\r
2252 \r
2253         if (!numcache)                  // nothing to cache!\r
2254                 return;\r
2255 \r
2256 // MDM begin - (GAMERS EDGE)\r
2257 //\r
2258         if (!FindFile("EGAGRAPH."EXT,NULL,2))\r
2259                 Quit (gvar, "CA_CacheMarks(): Can't find graphics files.");\r
2260 //\r
2261 // MDM end\r
2262 \r
2263         if (dialog)\r
2264         {\r
2265 #ifdef PROFILE\r
2266                 write(profilehandle,title,strlen(title));\r
2267                 write(profilehandle,"\n",1);\r
2268 #endif\r
2269                 if (drawcachebox)\r
2270                         drawcachebox(title,numcache);\r
2271         }\r
2272 \r
2273 //\r
2274 // go through and load in anything still needed\r
2275 //\r
2276         bufferstart = bufferend = 0;            // nothing good in buffer now\r
2277 \r
2278         for (i=0;i<NUMCHUNKS;i++)\r
2279                 if ( (gvar->video.grneeded[i]&ca_levelbit) && !grsegs[i])\r
2280                 {\r
2281 //\r
2282 // update thermometer\r
2283 //\r
2284                         if (dialog && updatecachebox)\r
2285                                 updatecachebox ();\r
2286 \r
2287                         pos = GRFILEPOS(i);\r
2288                         if (pos<0)\r
2289                                 continue;\r
2290 \r
2291                         next = i +1;\r
2292                         while (GRFILEPOS(next) == -1)           // skip past any sparse tiles\r
2293                                 next++;\r
2294 \r
2295                         compressed = GRFILEPOS(next)-pos;\r
2296                         endpos = pos+compressed;\r
2297 \r
2298                         if (compressed<=BUFFERSIZE)\r
2299                         {\r
2300                                 if (bufferstart<=pos\r
2301                                 && bufferend>= endpos)\r
2302                                 {\r
2303                                 // data is allready in buffer\r
2304                                         source = (byte _seg *)bufferseg+(pos-bufferstart);\r
2305                                 }\r
2306                                 else\r
2307                                 {\r
2308                                 // load buffer with a new block from disk\r
2309                                 // try to get as many of the needed blocks in as possible\r
2310                                         while ( next < NUMCHUNKS )\r
2311                                         {\r
2312                                                 while (next < NUMCHUNKS &&\r
2313                                                 !(gvar->video.grneeded[next]&ca_levelbit && !grsegs[next]))\r
2314                                                         next++;\r
2315                                                 if (next == NUMCHUNKS)\r
2316                                                         continue;\r
2317 \r
2318                                                 nextpos = GRFILEPOS(next);\r
2319                                                 while (GRFILEPOS(++next) == -1) // skip past any sparse tiles\r
2320                                                         ;\r
2321                                                 nextendpos = GRFILEPOS(next);\r
2322                                                 if (nextpos - endpos <= MAXEMPTYREAD\r
2323                                                 && nextendpos-pos <= BUFFERSIZE)\r
2324                                                         endpos = nextendpos;\r
2325                                                 else\r
2326                                                         next = NUMCHUNKS;                       // read pos to posend\r
2327                                         }\r
2328 \r
2329                                         lseek(grhandle,pos,SEEK_SET);\r
2330                                         CA_FarRead(grhandle,bufferseg,endpos-pos);\r
2331                                         bufferstart = pos;\r
2332                                         bufferend = endpos;\r
2333                                         source = bufferseg;\r
2334                                 }\r
2335                         }\r
2336                         else\r
2337                         {\r
2338                         // big chunk, allocate temporary buffer\r
2339                                 MM_GetPtr(&bigbufferseg,compressed);\r
2340                                 if (mmerror)\r
2341                                         return;\r
2342                                 MM_SetLock (&bigbufferseg,true);\r
2343                                 lseek(grhandle,pos,SEEK_SET);\r
2344                                 CA_FarRead(grhandle,bigbufferseg,compressed);\r
2345                                 source = bigbufferseg;\r
2346                         }\r
2347 \r
2348                         CAL_ExpandGrChunk (i,source);\r
2349                         if (mmerror)\r
2350                                 return;\r
2351 \r
2352                         if (compressed>BUFFERSIZE)\r
2353                                 MM_FreePtr(&bigbufferseg);\r
2354 \r
2355                 }\r
2356 \r
2357 //\r
2358 // finish up any thermometer remnants\r
2359 //\r
2360                 if (dialog && finishcachebox)\r
2361                         finishcachebox();\r
2362 }*/\r