1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191 |
- /* Catacomb Apocalypse Source Code
- * Copyright (C) 1993-2014 Flat Rock Software
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
- // ID_CA.C
- /*
- =============================================================================
- Id Software Caching Manager
- ---------------------------
- Must be started BEFORE the memory manager, because it needs to get the headers
- loaded into the data segment
- =============================================================================
- */
- #include "ID_HEADS.H"
- #pragma hdrstop
- #include "ID_STRS.H"
- #pragma warn -pro
- #pragma warn -use
- #define THREEBYTEGRSTARTS
- /*
- =============================================================================
- LOCAL CONSTANTS
- =============================================================================
- */
- typedef struct
- {
- unsigned bit0,bit1; // 0-255 is a character, > is a pointer to a node
- } huffnode;
- typedef struct
- {
- unsigned RLEWtag;
- long headeroffsets[100];
- byte tileinfo[];
- } mapfiletype;
- /*
- =============================================================================
- GLOBAL VARIABLES
- =============================================================================
- */
- byte _seg *tinf;
- int mapon;
- unsigned _seg *mapsegs[3];
- maptype _seg *mapheaderseg[NUMMAPS];
- byte _seg *audiosegs[NUMSNDCHUNKS];
- void _seg *grsegs[NUMCHUNKS];
- byte far grneeded[NUMCHUNKS];
- byte ca_levelbit,ca_levelnum;
- int profilehandle,debughandle;
- void (*drawcachebox) (char *title, unsigned numcache);
- void (*updatecachebox) (void);
- void (*finishcachebox) (void);
- /*
- =============================================================================
- LOCAL VARIABLES
- =============================================================================
- */
- extern long far CGAhead;
- extern long far EGAhead;
- extern byte CGAdict;
- extern byte EGAdict;
- extern byte far maphead;
- extern byte mapdict;
- extern byte far audiohead;
- extern byte audiodict;
- long _seg *grstarts; // array of offsets in egagraph, -1 for sparse
- long _seg *audiostarts; // array of offsets in audio / audiot
- #ifdef GRHEADERLINKED
- huffnode *grhuffman;
- #else
- huffnode grhuffman[255];
- #endif
- #ifdef AUDIOHEADERLINKED
- huffnode *audiohuffman;
- #else
- huffnode audiohuffman[255];
- #endif
- int grhandle; // handle to EGAGRAPH
- int maphandle; // handle to MAPTEMP / GAMEMAPS
- int audiohandle; // handle to AUDIOT / AUDIO
- long chunkcomplen,chunkexplen;
- SDMode oldsoundmode;
- void CAL_DialogDraw (char *title,unsigned numcache);
- void CAL_DialogUpdate (void);
- void CAL_DialogFinish (void);
- void CAL_CarmackExpand (unsigned far *source, unsigned far *dest,
- unsigned length);
- #ifdef THREEBYTEGRSTARTS
- #define FILEPOSSIZE 3
- //#define GRFILEPOS(c) (*(long far *)(((byte far *)grstarts)+(c)*3)&0xffffff)
- long GRFILEPOS(int c)
- {
- long value;
- int offset;
- offset = c*3;
- value = *(long far *)(((byte far *)grstarts)+offset);
- value &= 0x00ffffffl;
- if (value == 0xffffffl)
- value = -1;
- return value;
- };
- #else
- #define FILEPOSSIZE 4
- #define GRFILEPOS(c) (grstarts[c])
- #endif
- /*
- =============================================================================
- LOW LEVEL ROUTINES
- =============================================================================
- */
- /*
- ============================
- =
- = CA_OpenDebug / CA_CloseDebug
- =
- = Opens a binary file with the handle "debughandle"
- =
- ============================
- */
- void CA_OpenDebug (void)
- {
- unlink ("DEBUG.TXT");
- debughandle = open("DEBUG.TXT", O_CREAT | O_WRONLY | O_TEXT);
- }
- void CA_CloseDebug (void)
- {
- close (debughandle);
- }
- /*
- ============================
- =
- = CAL_GetGrChunkLength
- =
- = Gets the length of an explicit length chunk (not tiles)
- = The file pointer is positioned so the compressed data can be read in next.
- =
- ============================
- */
- void CAL_GetGrChunkLength (int chunk)
- {
- lseek(grhandle,GRFILEPOS(chunk),SEEK_SET);
- read(grhandle,&chunkexplen,sizeof(chunkexplen));
- chunkcomplen = GRFILEPOS(chunk+1)-GRFILEPOS(chunk)-4;
- }
- /*
- ==========================
- =
- = CA_FarRead
- =
- = Read from a file to a far pointer
- =
- ==========================
- */
- boolean CA_FarRead (int handle, byte far *dest, long length)
- {
- if (length>0xffffl)
- Quit ("CA_FarRead doesn't support 64K reads yet!");
- asm push ds
- asm mov bx,[handle]
- asm mov cx,[WORD PTR length]
- asm mov dx,[WORD PTR dest]
- asm mov ds,[WORD PTR dest+2]
- asm mov ah,0x3f // READ w/handle
- asm int 21h
- asm pop ds
- asm jnc good
- errno = _AX;
- return false;
- good:
- asm cmp ax,[WORD PTR length]
- asm je done
- errno = EINVFMT; // user manager knows this is bad read
- return false;
- done:
- return true;
- }
- /*
- ==========================
- =
- = CA_SegWrite
- =
- = Write from a file to a far pointer
- =
- ==========================
- */
- boolean CA_FarWrite (int handle, byte far *source, long length)
- {
- if (length>0xffffl)
- Quit ("CA_FarWrite doesn't support 64K reads yet!");
- asm push ds
- asm mov bx,[handle]
- asm mov cx,[WORD PTR length]
- asm mov dx,[WORD PTR source]
- asm mov ds,[WORD PTR source+2]
- asm mov ah,0x40 // WRITE w/handle
- asm int 21h
- asm pop ds
- asm jnc good
- errno = _AX;
- return false;
- good:
- asm cmp ax,[WORD PTR length]
- asm je done
- errno = ENOMEM; // user manager knows this is bad write
- return false;
- done:
- return true;
- }
- /*
- ==========================
- =
- = CA_ReadFile
- =
- = Reads a file into an allready allocated buffer
- =
- ==========================
- */
- boolean CA_ReadFile (char *filename, memptr *ptr)
- {
- int handle;
- long size;
- if ((handle = open(filename,O_RDONLY | O_BINARY, S_IREAD)) == -1)
- return false;
- size = filelength (handle);
- if (!CA_FarRead (handle,*ptr,size))
- {
- close (handle);
- return false;
- }
- close (handle);
- return true;
- }
- /*
- ==========================
- =
- = CA_LoadFile
- =
- = Allocate space for and load a file
- =
- ==========================
- */
- boolean CA_LoadFile (char *filename, memptr *ptr)
- {
- int handle;
- long size;
- if ((handle = open(filename,O_RDONLY | O_BINARY, S_IREAD)) == -1)
- return false;
- size = filelength (handle);
- MM_GetPtr (ptr,size);
- if (!CA_FarRead (handle,*ptr,size))
- {
- close (handle);
- return false;
- }
- close (handle);
- return true;
- }
- /*
- ============================================================================
- COMPRESSION routines, see JHUFF.C for more
- ============================================================================
- */
- /*
- ===============
- =
- = CAL_OptimizeNodes
- =
- = Goes through a huffman table and changes the 256-511 node numbers to the
- = actular address of the node. Must be called before CAL_HuffExpand
- =
- ===============
- */
- void CAL_OptimizeNodes (huffnode *table)
- {
- huffnode *node;
- int i;
- node = table;
- for (i=0;i<255;i++)
- {
- if (node->bit0 >= 256)
- node->bit0 = (unsigned)(table+(node->bit0-256));
- if (node->bit1 >= 256)
- node->bit1 = (unsigned)(table+(node->bit1-256));
- node++;
- }
- }
- /*
- ======================
- =
- = CAL_HuffExpand
- =
- = Length is the length of the EXPANDED data
- =
- ======================
- */
- void CAL_HuffExpand (byte huge *source, byte huge *dest,
- long length,huffnode *hufftable)
- {
- // unsigned bit,byte,node,code;
- unsigned sourceseg,sourceoff,destseg,destoff,endoff;
- huffnode *headptr;
- // huffnode *nodeon;
- headptr = hufftable+254; // head node is allways node 254
- source++; // normalize
- source--;
- dest++;
- dest--;
- sourceseg = FP_SEG(source);
- sourceoff = FP_OFF(source);
- destseg = FP_SEG(dest);
- destoff = FP_OFF(dest);
- endoff = destoff+length;
- //
- // ds:si source
- // es:di dest
- // ss:bx node pointer
- //
- if (length <0xfff0)
- {
- //--------------------------
- // expand less than 64k of data
- //--------------------------
- asm mov bx,[headptr]
- asm mov si,[sourceoff]
- asm mov di,[destoff]
- asm mov es,[destseg]
- asm mov ds,[sourceseg]
- asm mov ax,[endoff]
- asm mov ch,[si] // load first byte
- asm inc si
- asm mov cl,1
- expandshort:
- asm test ch,cl // bit set?
- asm jnz bit1short
- asm mov dx,[ss:bx] // take bit0 path from node
- asm shl cl,1 // advance to next bit position
- asm jc newbyteshort
- asm jnc sourceupshort
- bit1short:
- asm mov dx,[ss:bx+2] // take bit1 path
- asm shl cl,1 // advance to next bit position
- asm jnc sourceupshort
- newbyteshort:
- asm mov ch,[si] // load next byte
- asm inc si
- asm mov cl,1 // back to first bit
- sourceupshort:
- asm or dh,dh // if dx<256 its a byte, else move node
- asm jz storebyteshort
- asm mov bx,dx // next node = (huffnode *)code
- asm jmp expandshort
- storebyteshort:
- asm mov [es:di],dl
- asm inc di // write a decopmpressed byte out
- asm mov bx,[headptr] // back to the head node for next bit
- asm cmp di,ax // done?
- asm jne expandshort
- }
- else
- {
- //--------------------------
- // expand more than 64k of data
- //--------------------------
- length--;
- asm mov bx,[headptr]
- asm mov cl,1
- asm mov si,[sourceoff]
- asm mov di,[destoff]
- asm mov es,[destseg]
- asm mov ds,[sourceseg]
- asm lodsb // load first byte
- expand:
- asm test al,cl // bit set?
- asm jnz bit1
- asm mov dx,[ss:bx] // take bit0 path from node
- asm jmp gotcode
- bit1:
- asm mov dx,[ss:bx+2] // take bit1 path
- gotcode:
- asm shl cl,1 // advance to next bit position
- asm jnc sourceup
- asm lodsb
- asm cmp si,0x10 // normalize ds:si
- asm jb sinorm
- asm mov cx,ds
- asm inc cx
- asm mov ds,cx
- asm xor si,si
- sinorm:
- asm mov cl,1 // back to first bit
- sourceup:
- asm or dh,dh // if dx<256 its a byte, else move node
- asm jz storebyte
- asm mov bx,dx // next node = (huffnode *)code
- asm jmp expand
- storebyte:
- asm mov [es:di],dl
- asm inc di // write a decopmpressed byte out
- asm mov bx,[headptr] // back to the head node for next bit
- asm cmp di,0x10 // normalize es:di
- asm jb dinorm
- asm mov dx,es
- asm inc dx
- asm mov es,dx
- asm xor di,di
- dinorm:
- asm sub [WORD PTR ss:length],1
- asm jnc expand
- asm dec [WORD PTR ss:length+2]
- asm jns expand // when length = ffff ffff, done
- }
- asm mov ax,ss
- asm mov ds,ax
- }
- /*
- ======================
- =
- = CAL_CarmackExpand
- =
- = Length is the length of the EXPANDED data
- =
- ======================
- */
- #define NEARTAG 0xa7
- #define FARTAG 0xa8
- void CAL_CarmackExpand (unsigned far *source, unsigned far *dest, unsigned length)
- {
- unsigned ch,chhigh,count,offset;
- unsigned far *copyptr, far *inptr, far *outptr;
- length/=2;
- inptr = source;
- outptr = dest;
- while (length)
- {
- ch = *inptr++;
- chhigh = ch>>8;
- if (chhigh == NEARTAG)
- {
- count = ch&0xff;
- if (!count)
- { // have to insert a word containing the tag byte
- ch |= *((unsigned char far *)inptr)++;
- *outptr++ = ch;
- length--;
- }
- else
- {
- offset = *((unsigned char far *)inptr)++;
- copyptr = outptr - offset;
- length -= count;
- while (count--)
- *outptr++ = *copyptr++;
- }
- }
- else if (chhigh == FARTAG)
- {
- count = ch&0xff;
- if (!count)
- { // have to insert a word containing the tag byte
- ch |= *((unsigned char far *)inptr)++;
- *outptr++ = ch;
- length --;
- }
- else
- {
- offset = *inptr++;
- copyptr = dest + offset;
- length -= count;
- while (count--)
- *outptr++ = *copyptr++;
- }
- }
- else
- {
- *outptr++ = ch;
- length --;
- }
- }
- }
- /*
- ======================
- =
- = CA_RLEWcompress
- =
- ======================
- */
- long CA_RLEWCompress (unsigned huge *source, long length, unsigned huge *dest,
- unsigned rlewtag)
- {
- long complength;
- unsigned value,count,i;
- unsigned huge *start,huge *end;
- start = dest;
- end = source + (length+1)/2;
- //
- // compress it
- //
- do
- {
- count = 1;
- value = *source++;
- while (*source == value && source<end)
- {
- count++;
- source++;
- }
- if (count>3 || value == rlewtag)
- {
- //
- // send a tag / count / value string
- //
- *dest++ = rlewtag;
- *dest++ = count;
- *dest++ = value;
- }
- else
- {
- //
- // send word without compressing
- //
- for (i=1;i<=count;i++)
- *dest++ = value;
- }
- } while (source<end);
- complength = 2*(dest-start);
- return complength;
- }
- /*
- ======================
- =
- = CA_RLEWexpand
- = length is EXPANDED length
- =
- ======================
- */
- void CA_RLEWexpand (unsigned huge *source, unsigned huge *dest,long length,
- unsigned rlewtag)
- {
- // unsigned value,count,i;
- unsigned huge *end;
- unsigned sourceseg,sourceoff,destseg,destoff,endseg,endoff;
- //
- // expand it
- //
- #if 0
- do
- {
- value = *source++;
- if (value != rlewtag)
- //
- // uncompressed
- //
- *dest++=value;
- else
- {
- //
- // compressed string
- //
- count = *source++;
- value = *source++;
- for (i=1;i<=count;i++)
- *dest++ = value;
- }
- } while (dest<end);
- #endif
- end = dest + (length)/2;
- sourceseg = FP_SEG(source);
- sourceoff = FP_OFF(source);
- destseg = FP_SEG(dest);
- destoff = FP_OFF(dest);
- endseg = FP_SEG(end);
- endoff = FP_OFF(end);
- //
- // ax = source value
- // bx = tag value
- // cx = repeat counts
- // dx = scratch
- //
- // NOTE: A repeat count that produces 0xfff0 bytes can blow this!
- //
- asm mov bx,rlewtag
- asm mov si,sourceoff
- asm mov di,destoff
- asm mov es,destseg
- asm mov ds,sourceseg
- expand:
- asm lodsw
- asm cmp ax,bx
- asm je repeat
- asm stosw
- asm jmp next
- repeat:
- asm lodsw
- asm mov cx,ax // repeat count
- asm lodsw // repeat value
- asm rep stosw
- next:
- asm cmp si,0x10 // normalize ds:si
- asm jb sinorm
- asm mov ax,si
- asm shr ax,1
- asm shr ax,1
- asm shr ax,1
- asm shr ax,1
- asm mov dx,ds
- asm add dx,ax
- asm mov ds,dx
- asm and si,0xf
- sinorm:
- asm cmp di,0x10 // normalize es:di
- asm jb dinorm
- asm mov ax,di
- asm shr ax,1
- asm shr ax,1
- asm shr ax,1
- asm shr ax,1
- asm mov dx,es
- asm add dx,ax
- asm mov es,dx
- asm and di,0xf
- dinorm:
- asm cmp di,ss:endoff
- asm jne expand
- asm mov ax,es
- asm cmp ax,ss:endseg
- asm jb expand
- asm mov ax,ss
- asm mov ds,ax
- }
- /*
- =============================================================================
- CACHE MANAGER ROUTINES
- =============================================================================
- */
- /*
- ======================
- =
- = CAL_SetupGrFile
- =
- ======================
- */
- void CAL_SetupGrFile (void)
- {
- int handle;
- memptr compseg;
- #ifdef GRHEADERLINKED
- #if GRMODE == EGAGR
- grhuffman = (huffnode *)&EGAdict;
- grstarts = (long _seg *)FP_SEG(&EGAhead);
- #endif
- #if GRMODE == CGAGR
- grhuffman = (huffnode *)&CGAdict;
- grstarts = (long _seg *)FP_SEG(&CGAhead);
- #endif
- CAL_OptimizeNodes (grhuffman);
- #else
- //
- // load ???dict.ext (huffman dictionary for graphics files)
- //
- if ((handle = open(GREXT"DICT."EXT,
- O_RDONLY | O_BINARY, S_IREAD)) == -1)
- Quit ("Can't open "GREXT"DICT."EXT"!");
- read(handle, &grhuffman, sizeof(grhuffman));
- close(handle);
- CAL_OptimizeNodes (grhuffman);
- //
- // load the data offsets from ???head.ext
- //
- MM_GetPtr (&(memptr)grstarts,(NUMCHUNKS+1)*FILEPOSSIZE);
- if ((handle = open(GREXT"HEAD."EXT,
- O_RDONLY | O_BINARY, S_IREAD)) == -1)
- Quit ("Can't open "GREXT"HEAD."EXT"!");
- CA_FarRead(handle, (memptr)grstarts, (NUMCHUNKS+1)*FILEPOSSIZE);
- close(handle);
- #endif
- //
- // Open the graphics file, leaving it open until the game is finished
- //
- grhandle = open(GREXT"GRAPH."EXT, O_RDONLY | O_BINARY);
- if (grhandle == -1)
- Quit ("Cannot open "GREXT"GRAPH."EXT"!");
- //
- // load the pic and sprite headers into the arrays in the data segment
- //
- #if NUMPICS>0
- MM_GetPtr(&(memptr)pictable,NUMPICS*sizeof(pictabletype));
- CAL_GetGrChunkLength(STRUCTPIC); // position file pointer
- MM_GetPtr(&compseg,chunkcomplen);
- CA_FarRead (grhandle,compseg,chunkcomplen);
- CAL_HuffExpand (compseg, (byte huge *)pictable,NUMPICS*sizeof(pictabletype),grhuffman);
- MM_FreePtr(&compseg);
- #endif
- #if NUMPICM>0
- MM_GetPtr(&(memptr)picmtable,NUMPICM*sizeof(pictabletype));
- CAL_GetGrChunkLength(STRUCTPICM); // position file pointer
- MM_GetPtr(&compseg,chunkcomplen);
- CA_FarRead (grhandle,compseg,chunkcomplen);
- CAL_HuffExpand (compseg, (byte huge *)picmtable,NUMPICS*sizeof(pictabletype),grhuffman);
- MM_FreePtr(&compseg);
- #endif
- #if NUMSPRITES>0
- MM_GetPtr(&(memptr)spritetable,NUMSPRITES*sizeof(spritetabletype));
- CAL_GetGrChunkLength(STRUCTSPRITE); // position file pointer
- MM_GetPtr(&compseg,chunkcomplen);
- CA_FarRead (grhandle,compseg,chunkcomplen);
- CAL_HuffExpand (compseg, (byte huge *)spritetable,NUMSPRITES*sizeof(spritetabletype),grhuffman);
- MM_FreePtr(&compseg);
- #endif
- }
- //==========================================================================
- /*
- ======================
- =
- = CAL_SetupMapFile
- =
- ======================
- */
- void CAL_SetupMapFile (void)
- {
- int handle;
- long length;
- //
- // load maphead.ext (offsets and tileinfo for map file)
- //
- #ifndef MAPHEADERLINKED
- if ((handle = open("MAPHEAD."EXT,
- O_RDONLY | O_BINARY, S_IREAD)) == -1)
- Quit ("Can't open MAPHEAD."EXT"!");
- length = filelength(handle);
- MM_GetPtr (&(memptr)tinf,length);
- CA_FarRead(handle, tinf, length);
- close(handle);
- #else
- tinf = (byte _seg *)FP_SEG(&maphead);
- #endif
- //
- // open the data file
- //
- #ifdef MAPHEADERLINKED
- if ((maphandle = open("GAMEMAPS."EXT,
- O_RDONLY | O_BINARY, S_IREAD)) == -1)
- Quit ("Can't open GAMEMAPS."EXT"!");
- #else
- if ((maphandle = open("MAPTEMP."EXT,
- O_RDONLY | O_BINARY, S_IREAD)) == -1)
- Quit ("Can't open MAPTEMP."EXT"!");
- #endif
- }
- //==========================================================================
- /*
- ======================
- =
- = CAL_SetupAudioFile
- =
- ======================
- */
- void CAL_SetupAudioFile (void)
- {
- int handle;
- long length;
- //
- // load maphead.ext (offsets and tileinfo for map file)
- //
- #ifndef AUDIOHEADERLINKED
- if ((handle = open("AUDIOHED."EXT,
- O_RDONLY | O_BINARY, S_IREAD)) == -1)
- Quit ("Can't open AUDIOHED."EXT"!");
- length = filelength(handle);
- MM_GetPtr (&(memptr)audiostarts,length);
- CA_FarRead(handle, (byte far *)audiostarts, length);
- close(handle);
- #else
- audiohuffman = (huffnode *)&audiodict;
- CAL_OptimizeNodes (audiohuffman);
- audiostarts = (long _seg *)FP_SEG(&audiohead);
- #endif
- //
- // open the data file
- //
- #ifndef AUDIOHEADERLINKED
- if ((audiohandle = open("AUDIOT."EXT,
- O_RDONLY | O_BINARY, S_IREAD)) == -1)
- Quit ("Can't open AUDIOT."EXT"!");
- #else
- if ((audiohandle = open("AUDIO."EXT,
- O_RDONLY | O_BINARY, S_IREAD)) == -1)
- Quit ("Can't open AUDIO."EXT"!");
- #endif
- }
- //==========================================================================
- /*
- ======================
- =
- = CA_Startup
- =
- = Open all files and load in headers
- =
- ======================
- */
- void CA_Startup (void)
- {
- #ifdef PROFILE
- unlink ("PROFILE.TXT");
- profilehandle = open("PROFILE.TXT", O_CREAT | O_WRONLY | O_TEXT);
- #endif
- // MDM begin - (GAMERS EDGE)
- //
- if (!FindFile("AUDIO."EXT,NULL,2))
- Quit("CA_Startup(): Can't find audio files.");
- //
- // MDM end
- #ifndef NOAUDIO
- CAL_SetupAudioFile ();
- #endif
- // MDM begin - (GAMERS EDGE)
- //
- if (!FindFile("GAMEMAPS."EXT,NULL,1))
- Quit("CA_Startup(): Can't find level files.");
- //
- // MDM end
- #ifndef NOMAPS
- CAL_SetupMapFile ();
- #endif
- // MDM begin - (GAMERS EDGE)
- //
- if (!FindFile("EGAGRAPH."EXT,NULL,2))
- Quit("CA_Startup(): Can't find graphics files.");
- //
- // MDM end
- #ifndef NOGRAPHICS
- CAL_SetupGrFile ();
- #endif
- mapon = -1;
- ca_levelbit = 1;
- ca_levelnum = 0;
- drawcachebox = CAL_DialogDraw;
- updatecachebox = CAL_DialogUpdate;
- finishcachebox = CAL_DialogFinish;
- }
- //==========================================================================
- /*
- ======================
- =
- = CA_Shutdown
- =
- = Closes all files
- =
- ======================
- */
- void CA_Shutdown (void)
- {
- #ifdef PROFILE
- close (profilehandle);
- #endif
- close (maphandle);
- close (grhandle);
- close (audiohandle);
- }
- //===========================================================================
- /*
- ======================
- =
- = CA_CacheAudioChunk
- =
- ======================
- */
- void CA_CacheAudioChunk (int chunk)
- {
- long pos,compressed;
- #ifdef AUDIOHEADERLINKED
- long expanded;
- memptr bigbufferseg;
- byte far *source;
- #endif
- if (audiosegs[chunk])
- {
- MM_SetPurge (&(memptr)audiosegs[chunk],0);
- return; // allready in memory
- }
- // MDM begin - (GAMERS EDGE)
- //
- if (!FindFile("AUDIO."EXT,NULL,2))
- Quit("CA_CacheAudioChunk(): Can't find audio files.");
- //
- // MDM end
- //
- // load the chunk into a buffer, either the miscbuffer if it fits, or allocate
- // a larger buffer
- //
- pos = audiostarts[chunk];
- compressed = audiostarts[chunk+1]-pos;
- lseek(audiohandle,pos,SEEK_SET);
- #ifndef AUDIOHEADERLINKED
- MM_GetPtr (&(memptr)audiosegs[chunk],compressed);
- if (mmerror)
- return;
- CA_FarRead(audiohandle,audiosegs[chunk],compressed);
- #else
- if (compressed<=BUFFERSIZE)
- {
- CA_FarRead(audiohandle,bufferseg,compressed);
- source = bufferseg;
- }
- else
- {
- MM_GetPtr(&bigbufferseg,compressed);
- if (mmerror)
- return;
- MM_SetLock (&bigbufferseg,true);
- CA_FarRead(audiohandle,bigbufferseg,compressed);
- source = bigbufferseg;
- }
- expanded = *(long far *)source;
- source += 4; // skip over length
- MM_GetPtr (&(memptr)audiosegs[chunk],expanded);
- if (mmerror)
- goto done;
- CAL_HuffExpand (source,audiosegs[chunk],expanded,audiohuffman);
- done:
- if (compressed>BUFFERSIZE)
- MM_FreePtr(&bigbufferseg);
- #endif
- }
- //===========================================================================
- /*
- ======================
- =
- = CA_LoadAllSounds
- =
- = Purges all sounds, then loads all new ones (mode switch)
- =
- ======================
- */
- void CA_LoadAllSounds (void)
- {
- unsigned start,i;
- switch (oldsoundmode)
- {
- case sdm_Off:
- goto cachein;
- case sdm_PC:
- start = STARTPCSOUNDS;
- break;
- case sdm_AdLib:
- start = STARTADLIBSOUNDS;
- break;
- }
- for (i=0;i<NUMSOUNDS;i++,start++)
- if (audiosegs[start])
- MM_SetPurge (&(memptr)audiosegs[start],3); // make purgable
- cachein:
- switch (SoundMode)
- {
- case sdm_Off:
- return;
- case sdm_PC:
- start = STARTPCSOUNDS;
- break;
- case sdm_AdLib:
- start = STARTADLIBSOUNDS;
- break;
- }
- for (i=0;i<NUMSOUNDS;i++,start++)
- CA_CacheAudioChunk (start);
- oldsoundmode = SoundMode;
- }
- //===========================================================================
- #if GRMODE == EGAGR
- /*
- ======================
- =
- = CAL_ShiftSprite
- =
- = Make a shifted (one byte wider) copy of a sprite into another area
- =
- ======================
- */
- unsigned static sheight,swidth;
- boolean static dothemask;
- void CAL_ShiftSprite (unsigned segment,unsigned source,unsigned dest,
- unsigned width, unsigned height, unsigned pixshift, boolean domask)
- {
- sheight = height; // because we are going to reassign bp
- swidth = width;
- dothemask = domask;
- asm mov ax,[segment]
- asm mov ds,ax // source and dest are in same segment, and all local
- asm mov bx,[source]
- asm mov di,[dest]
- asm mov bp,[pixshift]
- asm shl bp,1
- asm mov bp,WORD PTR [shifttabletable+bp] // bp holds pointer to shift table
- asm cmp [ss:dothemask],0
- asm je skipmask
- //
- // table shift the mask
- //
- asm mov dx,[ss:sheight]
- domaskrow:
- asm mov BYTE PTR [di],255 // 0xff first byte
- asm mov cx,ss:[swidth]
- domaskbyte:
- asm mov al,[bx] // source
- asm not al
- asm inc bx // next source byte
- asm xor ah,ah
- asm shl ax,1
- asm mov si,ax
- asm mov ax,[bp+si] // table shift into two bytes
- asm not ax
- asm and [di],al // and with first byte
- asm inc di
- asm mov [di],ah // replace next byte
- asm loop domaskbyte
- asm inc di // the last shifted byte has 1s in it
- asm dec dx
- asm jnz domaskrow
- skipmask:
- //
- // table shift the data
- //
- asm mov dx,ss:[sheight]
- asm shl dx,1
- asm shl dx,1 // four planes of data
- dodatarow:
- asm mov BYTE PTR [di],0 // 0 first byte
- asm mov cx,ss:[swidth]
- dodatabyte:
- asm mov al,[bx] // source
- asm inc bx // next source byte
- asm xor ah,ah
- asm shl ax,1
- asm mov si,ax
- asm mov ax,[bp+si] // table shift into two bytes
- asm or [di],al // or with first byte
- asm inc di
- asm mov [di],ah // replace next byte
- asm loop dodatabyte
- asm inc di // the last shifted byte has 0s in it
- asm dec dx
- asm jnz dodatarow
- //
- // done
- //
- asm mov ax,ss // restore data segment
- asm mov ds,ax
- }
- #endif
- //===========================================================================
- /*
- ======================
- =
- = CAL_CacheSprite
- =
- = Generate shifts and set up sprite structure for a given sprite
- =
- ======================
- */
- void CAL_CacheSprite (int chunk, byte far *compressed)
- {
- int i;
- unsigned shiftstarts[5];
- unsigned smallplane,bigplane,expanded;
- spritetabletype far *spr;
- spritetype _seg *dest;
- #if GRMODE == CGAGR
- //
- // CGA has no pel panning, so shifts are never needed
- //
- spr = &spritetable[chunk-STARTSPRITES];
- smallplane = spr->width*spr->height;
- MM_GetPtr (&grsegs[chunk],smallplane*2+MAXSHIFTS*6);
- if (mmerror)
- return;
- dest = (spritetype _seg *)grsegs[chunk];
- dest->sourceoffset[0] = MAXSHIFTS*6; // start data after 3 unsigned tables
- dest->planesize[0] = smallplane;
- dest->width[0] = spr->width;
- //
- // expand the unshifted shape
- //
- CAL_HuffExpand (compressed, &dest->data[0],smallplane*2,grhuffman);
- #endif
- #if GRMODE == EGAGR
- //
- // calculate sizes
- //
- spr = &spritetable[chunk-STARTSPRITES];
- smallplane = spr->width*spr->height;
- bigplane = (spr->width+1)*spr->height;
- shiftstarts[0] = MAXSHIFTS*6; // start data after 3 unsigned tables
- shiftstarts[1] = shiftstarts[0] + smallplane*5; // 5 planes in a sprite
- shiftstarts[2] = shiftstarts[1] + bigplane*5;
- shiftstarts[3] = shiftstarts[2] + bigplane*5;
- shiftstarts[4] = shiftstarts[3] + bigplane*5; // nothing ever put here
- expanded = shiftstarts[spr->shifts];
- MM_GetPtr (&grsegs[chunk],expanded);
- if (mmerror)
- return;
- dest = (spritetype _seg *)grsegs[chunk];
- //
- // expand the unshifted shape
- //
- CAL_HuffExpand (compressed, &dest->data[0],smallplane*5,grhuffman);
- //
- // make the shifts!
- //
- switch (spr->shifts)
- {
- case 1:
- for (i=0;i<4;i++)
- {
- dest->sourceoffset[i] = shiftstarts[0];
- dest->planesize[i] = smallplane;
- dest->width[i] = spr->width;
- }
- break;
- case 2:
- for (i=0;i<2;i++)
- {
- dest->sourceoffset[i] = shiftstarts[0];
- dest->planesize[i] = smallplane;
- dest->width[i] = spr->width;
- }
- for (i=2;i<4;i++)
- {
- dest->sourceoffset[i] = shiftstarts[1];
- dest->planesize[i] = bigplane;
- dest->width[i] = spr->width+1;
- }
- CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],
- dest->sourceoffset[2],spr->width,spr->height,4,true);
- break;
- case 4:
- dest->sourceoffset[0] = shiftstarts[0];
- dest->planesize[0] = smallplane;
- dest->width[0] = spr->width;
- dest->sourceoffset[1] = shiftstarts[1];
- dest->planesize[1] = bigplane;
- dest->width[1] = spr->width+1;
- CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],
- dest->sourceoffset[1],spr->width,spr->height,2,true);
- dest->sourceoffset[2] = shiftstarts[2];
- dest->planesize[2] = bigplane;
- dest->width[2] = spr->width+1;
- CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],
- dest->sourceoffset[2],spr->width,spr->height,4,true);
- dest->sourceoffset[3] = shiftstarts[3];
- dest->planesize[3] = bigplane;
- dest->width[3] = spr->width+1;
- CAL_ShiftSprite ((unsigned)grsegs[chunk],dest->sourceoffset[0],
- dest->sourceoffset[3],spr->width,spr->height,6,true);
- break;
- default:
- Quit ("CAL_CacheSprite: Bad shifts number!");
- }
- #endif
- }
- //===========================================================================
- /*
- ======================
- =
- = CAL_ExpandGrChunk
- =
- = Does whatever is needed with a pointer to a compressed chunk
- =
- ======================
- */
- void CAL_ExpandGrChunk (int chunk, byte far *source)
- {
- long expanded;
- if (chunk >= STARTTILE8 && chunk < STARTEXTERNS)
- {
- //
- // expanded sizes of tile8/16/32 are implicit
- //
- #if GRMODE == EGAGR
- #define BLOCK 32
- #define MASKBLOCK 40
- #endif
- #if GRMODE == CGAGR
- #define BLOCK 16
- #define MASKBLOCK 32
- #endif
- if (chunk<STARTTILE8M) // tile 8s are all in one chunk!
- expanded = BLOCK*NUMTILE8;
- else if (chunk<STARTTILE16)
- expanded = MASKBLOCK*NUMTILE8M;
- else if (chunk<STARTTILE16M) // all other tiles are one/chunk
- expanded = BLOCK*4;
- else if (chunk<STARTTILE32)
- expanded = MASKBLOCK*4;
- else if (chunk<STARTTILE32M)
- expanded = BLOCK*16;
- else
- expanded = MASKBLOCK*16;
- }
- else
- {
- //
- // everything else has an explicit size longword
- //
- expanded = *(long far *)source;
- source += 4; // skip over length
- }
- //
- // allocate final space, decompress it, and free bigbuffer
- // Sprites need to have shifts made and various other junk
- //
- if (chunk>=STARTSPRITES && chunk< STARTTILE8)
- CAL_CacheSprite(chunk,source);
- else
- {
- MM_GetPtr (&grsegs[chunk],expanded);
- if (mmerror)
- return;
- CAL_HuffExpand (source,grsegs[chunk],expanded,grhuffman);
- }
- }
- /*
- ======================
- =
- = CAL_ReadGrChunk
- =
- = Gets a chunk off disk, optimizing reads to general buffer
- =
- ======================
- */
- void CAL_ReadGrChunk (int chunk)
- {
- long pos,compressed;
- memptr bigbufferseg;
- byte far *source;
- int next;
- //
- // load the chunk into a buffer, either the miscbuffer if it fits, or allocate
- // a larger buffer
- //
- pos = GRFILEPOS(chunk);
- if (pos<0) // $FFFFFFFF start is a sparse tile
- return;
- next = chunk +1;
- while (GRFILEPOS(next) == -1) // skip past any sparse tiles
- next++;
- compressed = GRFILEPOS(next)-pos;
- lseek(grhandle,pos,SEEK_SET);
- if (compressed<=BUFFERSIZE)
- {
- CA_FarRead(grhandle,bufferseg,compressed);
- source = bufferseg;
- }
- else
- {
- MM_GetPtr(&bigbufferseg,compressed);
- if (mmerror)
- return;
- MM_SetLock (&bigbufferseg,true);
- CA_FarRead(grhandle,bigbufferseg,compressed);
- source = bigbufferseg;
- }
- CAL_ExpandGrChunk (chunk,source);
- if (compressed>BUFFERSIZE)
- MM_FreePtr(&bigbufferseg);
- }
- /*
- ======================
- =
- = CA_CacheGrChunk
- =
- = Makes sure a given chunk is in memory, loadiing it if needed
- =
- ======================
- */
- void CA_CacheGrChunk (int chunk)
- {
- long pos,compressed;
- memptr bigbufferseg;
- byte far *source;
- int next;
- grneeded[chunk] |= ca_levelbit; // make sure it doesn't get removed
- if (grsegs[chunk])
- {
- MM_SetPurge (&grsegs[chunk],0);
- return; // allready in memory
- }
- // MDM begin - (GAMERS EDGE)
- //
- if (!FindFile("EGAGRAPH."EXT,NULL,2))
- Quit("CA_CacheGrChunk(): Can't find graphics files.");
- //
- // MDM end
- //
- // load the chunk into a buffer, either the miscbuffer if it fits, or allocate
- // a larger buffer
- //
- pos = GRFILEPOS(chunk);
- if (pos<0) // $FFFFFFFF start is a sparse tile
- return;
- next = chunk +1;
- while (GRFILEPOS(next) == -1) // skip past any sparse tiles
- next++;
- compressed = GRFILEPOS(next)-pos;
- lseek(grhandle,pos,SEEK_SET);
- if (compressed<=BUFFERSIZE)
- {
- CA_FarRead(grhandle,bufferseg,compressed);
- source = bufferseg;
- }
- else
- {
- MM_GetPtr(&bigbufferseg,compressed);
- MM_SetLock (&bigbufferseg,true);
- CA_FarRead(grhandle,bigbufferseg,compressed);
- source = bigbufferseg;
- }
- CAL_ExpandGrChunk (chunk,source);
- if (compressed>BUFFERSIZE)
- MM_FreePtr(&bigbufferseg);
- }
- //==========================================================================
- /*
- ======================
- =
- = CA_CacheMap
- =
- ======================
- */
- void CA_CacheMap (int mapnum)
- {
- long pos,compressed;
- int plane;
- memptr *dest,bigbufferseg;
- unsigned size;
- unsigned far *source;
- #ifdef MAPHEADERLINKED
- memptr buffer2seg;
- long expanded;
- #endif
- // MDM begin - (GAMERS EDGE)
- //
- if (!FindFile("GAMEMAPS."EXT,NULL,1))
- Quit("CA_CacheMap(): Can't find level files.");
- //
- // MDM end
- //
- // free up memory from last map
- //
- if (mapon>-1 && mapheaderseg[mapon])
- MM_SetPurge (&(memptr)mapheaderseg[mapon],3);
- for (plane=0;plane<MAPPLANES;plane++)
- if (mapsegs[plane])
- MM_FreePtr (&(memptr)mapsegs[plane]);
- mapon = mapnum;
- //
- // load map header
- // The header will be cached if it is still around
- //
- if (!mapheaderseg[mapnum])
- {
- pos = ((mapfiletype _seg *)tinf)->headeroffsets[mapnum];
- if (pos<0) // $FFFFFFFF start is a sparse map
- Quit ("CA_CacheMap: Tried to load a non existent map!");
- MM_GetPtr(&(memptr)mapheaderseg[mapnum],sizeof(maptype));
- lseek(maphandle,pos,SEEK_SET);
- CA_FarRead (maphandle,(memptr)mapheaderseg[mapnum],sizeof(maptype));
- }
- else
- MM_SetPurge (&(memptr)mapheaderseg[mapnum],0);
- //
- // load the planes in
- // If a plane's pointer still exists it will be overwritten (levels are
- // allways reloaded, never cached)
- //
- size = mapheaderseg[mapnum]->width * mapheaderseg[mapnum]->height * 2;
- for (plane = 0; plane<MAPPLANES; plane++)
- {
- pos = mapheaderseg[mapnum]->planestart[plane];
- compressed = mapheaderseg[mapnum]->planelength[plane];
- if (!compressed)
- continue; // the plane is not used in this game
- dest = &(memptr)mapsegs[plane];
- MM_GetPtr(dest,size);
- lseek(maphandle,pos,SEEK_SET);
- if (compressed<=BUFFERSIZE)
- source = bufferseg;
- else
- {
- MM_GetPtr(&bigbufferseg,compressed);
- MM_SetLock (&bigbufferseg,true);
- source = bigbufferseg;
- }
- CA_FarRead(maphandle,(byte far *)source,compressed);
- #ifdef MAPHEADERLINKED
- //
- // unhuffman, then unRLEW
- // The huffman'd chunk has a two byte expanded length first
- // The resulting RLEW chunk also does, even though it's not really
- // needed
- //
- expanded = *source;
- source++;
- MM_GetPtr (&buffer2seg,expanded);
- CAL_CarmackExpand (source, (unsigned far *)buffer2seg,expanded);
- CA_RLEWexpand (((unsigned far *)buffer2seg)+1,*dest,size,
- ((mapfiletype _seg *)tinf)->RLEWtag);
- MM_FreePtr (&buffer2seg);
- #else
- //
- // unRLEW, skipping expanded length
- //
- CA_RLEWexpand (source+1, *dest,size,
- ((mapfiletype _seg *)tinf)->RLEWtag);
- #endif
- if (compressed>BUFFERSIZE)
- MM_FreePtr(&bigbufferseg);
- }
- }
- //===========================================================================
- /*
- ======================
- =
- = CA_UpLevel
- =
- = Goes up a bit level in the needed lists and clears it out.
- = Everything is made purgable
- =
- ======================
- */
- void CA_UpLevel (void)
- {
- if (ca_levelnum==7)
- Quit ("CA_UpLevel: Up past level 7!");
- ca_levelbit<<=1;
- ca_levelnum++;
- }
- //===========================================================================
- /*
- ======================
- =
- = CA_DownLevel
- =
- = Goes down a bit level in the needed lists and recaches
- = everything from the lower level
- =
- ======================
- */
- void CA_DownLevel (void)
- {
- if (!ca_levelnum)
- Quit ("CA_DownLevel: Down past level 0!");
- ca_levelbit>>=1;
- ca_levelnum--;
- CA_CacheMarks(NULL);
- }
- //===========================================================================
- /*
- ======================
- =
- = CA_ClearMarks
- =
- = Clears out all the marks at the current level
- =
- ======================
- */
- void CA_ClearMarks (void)
- {
- int i;
- for (i=0;i<NUMCHUNKS;i++)
- grneeded[i]&=~ca_levelbit;
- }
- //===========================================================================
- /*
- ======================
- =
- = CA_ClearAllMarks
- =
- = Clears out all the marks on all the levels
- =
- ======================
- */
- void CA_ClearAllMarks (void)
- {
- _fmemset (grneeded,0,sizeof(grneeded));
- ca_levelbit = 1;
- ca_levelnum = 0;
- }
- //===========================================================================
- /*
- ======================
- =
- = CA_FreeGraphics
- =
- ======================
- */
- void CA_FreeGraphics (void)
- {
- int i;
- for (i=0;i<NUMCHUNKS;i++)
- if (grsegs[i])
- MM_SetPurge (&(memptr)grsegs[i],3);
- }
- /*
- ======================
- =
- = CA_SetAllPurge
- =
- = Make everything possible purgable
- =
- ======================
- */
- void CA_SetAllPurge (void)
- {
- int i;
- CA_ClearMarks ();
- //
- // free cursor sprite and background save
- //
- VW_FreeCursor ();
- //
- // free map headers and map planes
- //
- for (i=0;i<NUMMAPS;i++)
- if (mapheaderseg[i])
- MM_SetPurge (&(memptr)mapheaderseg[i],3);
- for (i=0;i<3;i++)
- if (mapsegs[i])
- MM_FreePtr (&(memptr)mapsegs[i]);
- //
- // free sounds
- //
- for (i=0;i<NUMSNDCHUNKS;i++)
- if (audiosegs[i])
- MM_SetPurge (&(memptr)audiosegs[i],3);
- //
- // free graphics
- //
- CA_FreeGraphics ();
- }
- void CA_SetGrPurge (void)
- {
- int i;
- //
- // free graphics
- //
- for (i=0;i<NUMCHUNKS;i++)
- if (grsegs[i])
- MM_SetPurge (&(memptr)grsegs[i],3);
- }
- //===========================================================================
- /*
- ======================
- =
- = CAL_DialogDraw
- =
- ======================
- */
- #define NUMBARS (17l*8)
- #define BARSTEP 8
- unsigned thx,thy,lastx;
- long barx,barstep;
- void CAL_DialogDraw (char *title,unsigned numcache)
- {
- unsigned homex,homey,x;
- barstep = (NUMBARS<<16)/numcache;
- //
- // draw dialog window (masked tiles 12 - 20 are window borders)
- //
- US_CenterWindow (20,8);
- homex = PrintX;
- homey = PrintY;
- US_CPrint ("Loading");
- fontcolor = F_SECONDCOLOR;
- US_CPrint (title);
- fontcolor = F_BLACK;
- //
- // draw thermometer bar
- //
- thx = homex + 8;
- thy = homey + 32;
- VWB_DrawTile8(thx,thy,0); // CAT3D numbers
- VWB_DrawTile8(thx,thy+8,3);
- VWB_DrawTile8(thx,thy+16,6);
- VWB_DrawTile8(thx+17*8,thy,2);
- VWB_DrawTile8(thx+17*8,thy+8,5);
- VWB_DrawTile8(thx+17*8,thy+16,8);
- for (x=thx+8;x<thx+17*8;x+=8)
- {
- VWB_DrawTile8(x,thy,1);
- VWB_DrawTile8(x,thy+8,4);
- VWB_DrawTile8(x,thy+16,7);
- }
- thx += 4; // first line location
- thy += 5;
- barx = (long)thx<<16;
- lastx = thx;
- VW_UpdateScreen();
- }
- /*
- ======================
- =
- = CAL_DialogUpdate
- =
- ======================
- */
- void CAL_DialogUpdate (void)
- {
- unsigned x,xh;
- barx+=barstep;
- xh = barx>>16;
- if (xh - lastx > BARSTEP)
- {
- for (x=lastx;x<=xh;x++)
- #if GRMODE == EGAGR
- VWB_Vlin (thy,thy+13,x,14);
- #endif
- #if GRMODE == CGAGR
- VWB_Vlin (thy,thy+13,x,SECONDCOLOR);
- #endif
- lastx = xh;
- VW_UpdateScreen();
- }
- }
- /*
- ======================
- =
- = CAL_DialogFinish
- =
- ======================
- */
- void CAL_DialogFinish (void)
- {
- unsigned x,xh;
- xh = thx + NUMBARS;
- for (x=lastx;x<=xh;x++)
- #if GRMODE == EGAGR
- VWB_Vlin (thy,thy+13,x,14);
- #endif
- #if GRMODE == CGAGR
- VWB_Vlin (thy,thy+13,x,SECONDCOLOR);
- #endif
- VW_UpdateScreen();
- }
- //===========================================================================
- /*
- ======================
- =
- = CA_CacheMarks
- =
- ======================
- */
- #define MAXEMPTYREAD 1024
- void CA_CacheMarks (char *title)
- {
- boolean dialog;
- int i,next,numcache;
- long pos,endpos,nextpos,nextendpos,compressed;
- long bufferstart,bufferend; // file position of general buffer
- byte far *source;
- memptr bigbufferseg;
- dialog = (title!=NULL);
- numcache = 0;
- //
- // go through and make everything not needed purgable
- //
- for (i=0;i<NUMCHUNKS;i++)
- if (grneeded[i]&ca_levelbit)
- {
- if (grsegs[i]) // its allready in memory, make
- MM_SetPurge(&grsegs[i],0); // sure it stays there!
- else
- numcache++;
- }
- else
- {
- if (grsegs[i]) // not needed, so make it purgeable
- MM_SetPurge(&grsegs[i],3);
- }
- if (!numcache) // nothing to cache!
- return;
- // MDM begin - (GAMERS EDGE)
- //
- if (!FindFile("EGAGRAPH."EXT,NULL,2))
- Quit("CA_CacheMarks(): Can't find graphics files.");
- //
- // MDM end
- if (dialog)
- {
- #ifdef PROFILE
- write(profilehandle,title,strlen(title));
- write(profilehandle,"\n",1);
- #endif
- if (drawcachebox)
- drawcachebox(title,numcache);
- }
- //
- // go through and load in anything still needed
- //
- bufferstart = bufferend = 0; // nothing good in buffer now
- for (i=0;i<NUMCHUNKS;i++)
- if ( (grneeded[i]&ca_levelbit) && !grsegs[i])
- {
- //
- // update thermometer
- //
- if (dialog && updatecachebox)
- updatecachebox ();
- pos = GRFILEPOS(i);
- if (pos<0)
- continue;
- next = i +1;
- while (GRFILEPOS(next) == -1) // skip past any sparse tiles
- next++;
- compressed = GRFILEPOS(next)-pos;
- endpos = pos+compressed;
- if (compressed<=BUFFERSIZE)
- {
- if (bufferstart<=pos
- && bufferend>= endpos)
- {
- // data is allready in buffer
- source = (byte _seg *)bufferseg+(pos-bufferstart);
- }
- else
- {
- // load buffer with a new block from disk
- // try to get as many of the needed blocks in as possible
- while ( next < NUMCHUNKS )
- {
- while (next < NUMCHUNKS &&
- !(grneeded[next]&ca_levelbit && !grsegs[next]))
- next++;
- if (next == NUMCHUNKS)
- continue;
- nextpos = GRFILEPOS(next);
- while (GRFILEPOS(++next) == -1) // skip past any sparse tiles
- ;
- nextendpos = GRFILEPOS(next);
- if (nextpos - endpos <= MAXEMPTYREAD
- && nextendpos-pos <= BUFFERSIZE)
- endpos = nextendpos;
- else
- next = NUMCHUNKS; // read pos to posend
- }
- lseek(grhandle,pos,SEEK_SET);
- CA_FarRead(grhandle,bufferseg,endpos-pos);
- bufferstart = pos;
- bufferend = endpos;
- source = bufferseg;
- }
- }
- else
- {
- // big chunk, allocate temporary buffer
- MM_GetPtr(&bigbufferseg,compressed);
- if (mmerror)
- return;
- MM_SetLock (&bigbufferseg,true);
- lseek(grhandle,pos,SEEK_SET);
- CA_FarRead(grhandle,bigbufferseg,compressed);
- source = bigbufferseg;
- }
- CAL_ExpandGrChunk (i,source);
- if (mmerror)
- return;
- if (compressed>BUFFERSIZE)
- MM_FreePtr(&bigbufferseg);
- }
- //
- // finish up any thermometer remnants
- //
- if (dialog && finishcachebox)
- finishcachebox();
- }
|