From: sparky4 Date: Fri, 27 Oct 2023 00:37:56 +0000 (-0500) Subject: ted5 added X-Git-Url: http://4ch.mooo.com/gitweb/?p=16.git;a=commitdiff_plain;h=4c15d088479b9b6c4a8b298a9db585bc11582321 ted5 added --- diff --git a/16/ted5/BACKUP.BAT b/16/ted5/BACKUP.BAT new file mode 100755 index 00000000..1651dea9 --- /dev/null +++ b/16/ted5/BACKUP.BAT @@ -0,0 +1,6 @@ +copy *.c backup +copy *.h backup +copy *.asm backup +copy *.prj backup +copy *.dsk backup +copy _*.obj backup diff --git a/16/ted5/CHARSE.LBM b/16/ted5/CHARSE.LBM new file mode 100755 index 00000000..25e4f26a Binary files /dev/null and b/16/ted5/CHARSE.LBM differ diff --git a/16/ted5/EGAHEAD.TED b/16/ted5/EGAHEAD.TED new file mode 100755 index 00000000..053a72c4 Binary files /dev/null and b/16/ted5/EGAHEAD.TED differ diff --git a/16/ted5/EGALATCH.TED b/16/ted5/EGALATCH.TED new file mode 100755 index 00000000..a01c32fe Binary files /dev/null and b/16/ted5/EGALATCH.TED differ diff --git a/16/ted5/GRAB.BAT b/16/ted5/GRAB.BAT new file mode 100755 index 00000000..47dc78e7 --- /dev/null +++ b/16/ted5/GRAB.BAT @@ -0,0 +1,2 @@ +fgrab /ega ted.nsc +copy egalatch.ted _tedchar.ega diff --git a/16/ted5/GRAPHTED.H b/16/ted5/GRAPHTED.H new file mode 100755 index 00000000..4ea25acb --- /dev/null +++ b/16/ted5/GRAPHTED.H @@ -0,0 +1,12 @@ +////////////////////////////////////// +// +// Graphics DEFINE file for .TED +// FGRAB-ed on Thu Aug 08 17:33:46 1991 +// +////////////////////////////////////// + + + +// +// Thank you for using FGRAB! +// diff --git a/16/ted5/INFO.TXT b/16/ted5/INFO.TXT new file mode 100755 index 00000000..d7d9e4b9 --- /dev/null +++ b/16/ted5/INFO.TXT @@ -0,0 +1,97 @@ +TED 5.0 Features +--------------------------------------------------------------------------- + +__ Handles all current tile types with ease of expansion for future sizes. + Current sizes are: 8x8,16x16,32x32. Only one tile size is permitted per + map set. + +__ Handles any amount of tiles that will fit in EMS memory. If EMS is not + present, you can't use TED 5.0! + +__ Handles masked and non-masked tiles. + +__ Each map has 3 planes: background tiles, foreground tiles, and extra + info. The extra info plane will blit icons for values 0-63 (?), higher + values will be printed as hex. Planes will be selected upon project + creation. + +__ Must have ability to turn on/off each individual plane so all planes + can be on or off at once. + +__ Video modes supported will be CGA 320x200, EGA 320x200/640x480/800x600, + VGA 320x200 256-color. + +__ Map Morph feature will allow user to select a block area and make snap- + shots of it, modify the area, make another snapshot, etc. until the + morph process is completed. Full editing capabilities will include: + DELETE FRAME, INSERT FRAME, MAKE SNAPSHOT. + +__ TileInfo feature will allow user to edit tile attributes. Editing capa- + bilities will include: ADD, DELETE, CHANGE NAME. + +__ TED editing feature will include: + + __ Flood Fill + __ Block Fill + __ Copy Block (from tile maps as well) with SparseTile handling + __ Paste (with floating corners) + __ Draw + __ Line + +__ Other features: + + __ Info Bar (on/off) + __ Tile Search + __ Map Info + __ ScrollKeys (SHIFT for full screen moves) + __ Right-Button tile-pickup + __ Map Resizing (with Edge Selection) + __ X,Y coords in Hex & Dec + __ All numeric input will support HEX,DEC,BIN + +__ Map files will be saved as either MAPTEMP.ext for the RLEW-only + (development) version, or GAMEMAPS.ext for the HUFF/RLEW version. + +__ Dialogs will be implemented. + +__ Project selection. + +__ Map selection by name! + +__ Create ApplePreferred or ILBM Map dumps + + + + + +Map Header Struct +------------------------------------------------------------------- +size what description +------------------------------------------------------------------- +unsigned HeaderSize size of the entire map header +unsigned MapType how many planes the map has. If there + are 3, you have back/foreground & info. + If there are 2, you have back & info, If + there is 1, you have background. +unsigned TileSize size of tiles map is made for + (1=8,2=16,3=32) +long TileInfoOff offset to TILEINFO data +long TileInfoMOff offset to MASKED TILEINFO data +unsigned RLEWtag RLEW tag byte +unsigned Dictionary offset to Huff dictionary. 0 if RLEW only. +unsigned DataOffsets offset to MapOffset list +... +long MapOffsets offsets to Maps in map file + + + +Map Structure +------------------------------------------------------------------- +size what description +------------------------------------------------------------------- +long Plane 0 offset to plane 0 +long Plane 1 offset to plane 1 (0 if none) +long Plane 2 offset to plane 2 (0 if none) +char Name Map name (16 chars) +... +unsigned MapData all map data is in WORDs \ No newline at end of file diff --git a/16/ted5/JHUFF.C b/16/ted5/JHUFF.C new file mode 100755 index 00000000..37414658 --- /dev/null +++ b/16/ted5/JHUFF.C @@ -0,0 +1,1287 @@ +#include "ted5.h" +#pragma hdrstop + +long inlength,outlength; + +long counts[256]; + +unsigned huffbits[256]; +unsigned long huffstring[256]; + +huffnode nodearray[256]; // 256 nodes is worst case + +void CountBytes (unsigned char huge *start, long length); +void Huffmanize (void); +void OptimizeNodes (huffnode *table); +long HuffCompress (unsigned char huge *source, long length, + unsigned char huge *dest); +void HuffExpand (unsigned char huge *source, unsigned char huge *dest, + long length,huffnode *hufftable); +void RLEWExpand (unsigned huge *source, unsigned huge *dest,long length, + unsigned rlewtag); +long RLEWCompress (unsigned huge *source, long length, unsigned huge *dest, + unsigned rlewtag); + +/* +============================================================================= + + COMPRESSION SUBS + +============================================================================= +*/ + + +/* +====================== += += CountBytes += += Adds the bytes in the pointed to area to the counts array += If this is the first segment, make sure counts is zerod += +====================== +*/ + +void CountBytes (unsigned char huge *start, long length) +{ + long i; + + while (length--) + counts[*start++]++; +} + +/* +======================= += += FindLeast += += Returns the byte with the lowest counts value += +======================= +*/ + +int FindLeast (void) +{ + int i,least; + long low = 0x7fffffff; + + for (i=0;i<256;i++) + if (counts[i]24 && counts[bit0]) + { + puts("Error: Huffman bit string went over 32 bits!"); + exit(1); + } + } + else + TraceNode (bit0-256,numbits,bitstring); + + if (bit1 <256) + { + huffbits[bit1]=numbits; + huffstring[bit1]=bitstring+ (1ul<<(numbits-1)); // add a one in front + if (huffbits[bit1]>24 && counts[bit1]) + { + puts("Error: Huffman bit string went over 32 bits!"); + exit(1); + } + } + else + TraceNode (bit1-256,numbits,bitstring+(1ul<<(numbits-1))); +} + +/* +======================= += += Huffmanize += += Takes the counts array and builds a huffman tree at += nodearray, then builds a codeing table. += +======================= +*/ + +void Huffmanize (void) +{ + +// +// codes are either bytes if <256 or nodearray numbers+256 if >=256 +// + unsigned value[256],code0,code1; +// +// probablilities are the number of times the code is hit or $ffffffff if +// it is allready part of a higher node +// + unsigned long prob[256],low,workprob; + + int i,worknode,bitlength; + unsigned long bitstring; + + +// +// all possible leaves start out as bytes +// + for (i=0;i<256;i++) + { + value[i]=i; + prob[i]=counts[i]; + } + +// +// start selecting the lowest probable leaves for the ends of the tree +// + + worknode = 0; + while (1) // break out of when all codes have been used + { + // + // find the two lowest probability codes + // + + code0=0xffff; + low = 0x7ffffffff; + for (i=0;i<256;i++) + if (prob[i]bit0 >= 256) + node->bit0 = (unsigned)(table+(node->bit0-256)); + if (node->bit1 >= 256) + node->bit1 = (unsigned)(table+(node->bit1-256)); + node++; + } +} + +/*========================================================================*/ + +#if 0 +/* +====================== += += HuffCompress += += The file must be counted with CountBytes and then Huffmanized first += +====================== +*/ + +long HuffCompress (unsigned char huge *source, long length, + unsigned char huge *dest) +{ + long outlength; + unsigned long string; + unsigned biton,bits; + unsigned char byte; + + outlength = biton = 0; + + *(long huge *)dest=0; // so bits can be or'd on + + while (length--) + { + byte = *source++; + bits = huffbits[byte]; + string = huffstring[byte] << biton; + *(long huge *)(dest+1)=0; // so bits can be or'd on + *(long huge *)dest |= string; + biton += bits; // advance this many bits + dest+= biton/8; + biton&=7; // stay under 8 shifts + outlength+=bits; + } + + return (outlength+7)/8; +} +#endif + + +/*========================================================================*/ + +/* +====================== += += HuffExpand += +====================== +*/ + +void HuffExpand (unsigned char huge *source, unsigned char huge *dest, + long length,huffnode *hufftable) + +{ + unsigned bit,byte,node,code; + unsigned sourceseg,sourceoff,destseg,destoff,endoff; + huffnode *nodeon,*headptr; + + 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 + +} + + +//----------------- replaced by John C. ------------------------------------ +#if 0 +{ + unsigned bit,byte,node,code; + unsigned sourceseg,sourceoff,destseg,destoff,endseg,endoff; + huffnode *nodeon,*headptr; + + nodeon = headptr = hufftable+254; // head node is allways node 254 + + bit = 1; + byte = *source++; + + while (length) + { + if (byte&bit) + code = nodeon->bit1; + else + code = nodeon->bit0; + + bit<<=1; + if (bit==256) + { + bit=1; + byte = *source++; + } + + if (code<256) + { + *dest++=code; + nodeon=headptr; + length--; + } + else + nodeon = (huffnode *)code; + } + + +#if 0 + + source++; // normalize + source--; + dest++; + dest--; + + sourceseg = FP_SEG(source); + sourceoff = FP_OFF(source); + destseg = FP_SEG(dest); + destoff = FP_OFF(dest); + + length--; +// +// al = source byte +// cl = bit in source (1,2,4,8,...) +// dx = code +// +// ds:si source +// es:di dest +// ss:bx node pointer +// + +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 + +#endif + +} +#endif +//--------------------------------------------------------------------------- + +/*========================================================================*/ + +/* +====================== += += RLEWcompress += +====================== +*/ + +long 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 && source3 || 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 (source3 || value == rlebtag) + { + // + // send a tag / count / value string + // + *dest++ = rlebtag; + *dest++ = count; + *dest++ = value; + } + else + { + // + // send byte without compressing + // + for (i=1;i<=count;i++) + *dest++ = value; + } + + } while (source length) + maxstring = length; + if (maxstring > 255) + maxstring = 255; + + string = 1; + while (*(inscan+string) == *(inptr+string) && string= beststring) + { + beststring = string; + bestscan = inscan; + } + } + + if (beststring > 1 && inptr-bestscan <= 255) + { + // near string + *outptr++ = beststring + (NEARTAG*256); + *((unsigned char far *)outptr)++ = inptr-bestscan; + outlength += 3; + nearrepeats++; + inptr += beststring; + length -= beststring; + } + else if (beststring > 2) + { + // far string + *outptr++ = beststring + (FARTAG*256); + *outptr++ = bestscan-instart; + outlength += 4; + farrepeats++; + inptr += beststring; + length -= beststring; + } + else // no compression + { + chhigh = ch>>8; + if (chhigh == NEARTAG || chhigh == FARTAG) + { + // special case of encountering a + // tag word in the data stream + // send a length of 0, and follow it with the real low byte + *outptr++ = ch & 0xff00; + *((unsigned char far *)outptr)++ = ch&0xff; + outlength += 3; + dups++; + } + else + { + *outptr++ = ch; + outlength += 2; + } + inptr++; + length--; + newwords++; + } + + if (!--count) + { + static char cc[2]="-"; + cc[0]^='+'^'-'; + print(cc); + sx--; + + count = 10; + + if (keydown[1]) + { + while(keydown[1]); + return 0; + } + } + if (length<0) + Quit ("Length < 0!"); + } while (length); + #if 0 + printf ("%u near patterns\n",nearrepeats); + printf ("%u far patterns\n",farrepeats); + printf ("%u new words\n",newwords); + printf ("%u dups\n\n",dups); + #endif + return outlength; +} +#else + + + +/* +================== += += CarmackCompress += += Compress a string of words += +================== +*/ + +#define NEARTAG 0xa7 +#define FARTAG 0xa8 + +long CarmackCompress (unsigned far *source,long length, + unsigned far *dest) +{ + unsigned wch,chhigh; + unsigned inptrx; + unsigned far *instart, far *inptr, far *inscan, + far *stopscan, far *outptr; + unsigned far *bestscan, beststring; + unsigned dist,maxstring,string,outlength; + unsigned nearrepeats,farrepeats; + unsigned dups,count; + unsigned newwords; + +// +// this compression method produces a stream of words +// If the words high byte is NEARTAG or FARTAG, the low byte is a word +// copy count from the a position specified by either the next byte +// or the next word, respectively. A copy count of 0 means to insert the +// next byte as the low byte of the tag into the output +// + + +// +// set up +// + instart = inptr = bestscan = source; + outptr = dest; + + outlength = 0; + length = (length+1)/2; + + nearrepeats = farrepeats = dups = 0; + count = 10; + newwords = 0; +// +// compress +// + do + { + wch = *inptr; + inptrx = FP_OFF(inptr)+2; // convienient for cmpsw + +// +// scan from start for patterns that match current data +// +//================ + +// +// ax: +// bx: beststring +// cx: repeat counts +// dx: holding spot for inscan repeat count +// si: inptr +// di: inscan +// +asm xor bx,bx // beststring = 0 + +asm les di,[instart] // start looking for an identical string + // at the start of uncompressed text +asm mov ax,es +asm mov ds,ax // both DS and ES point to uncompressed data + +asm mov cx,WORD PTR [inptr] +asm sub cx,di +asm shr cx,1 // cx = words between inscan and inptr + +search: +asm mov ax,[wch] // current uncompressed word +asm repne scasw // search from DI for up to CX words for a + // first char match +asm jcxz done // no more to search + +asm mov dx,cx // save off remaining repeat count + // the number in CX is the remaining words + // to search for a long pattern +asm mov si,[inptrx] // SI is the current source data + // DI is the match in previously compressed + // data +asm mov ax,di // save off DI so we can back up after scan +asm repe cmpsw // decrement CX for each additional match +asm jne ended +asm dec cx // the search ended because of CX, not bad match +ended: +asm mov di,ax // back to original spot +asm mov ax,dx +asm sub ax,cx // AX is the total number of matching words +asm cmp ax,bx // more chars than beststring? +asm jb next +asm mov bx,ax +asm mov WORD PTR [bestscan],di // bestscan is start of the best match+2 + +next: +asm mov cx,dx // restore the remaining count +asm jmp search + +done: +asm mov ax,ss +asm mov ds,ax +asm mov [beststring],bx // save out the register variable +asm dec bx +asm sub WORD PTR [bestscan],2 // scasw incremented past start +//================ + + if (beststring>length) + beststring = length; + + if (beststring > 1 && inptr-bestscan <= 255) + { + // near string + *outptr++ = beststring + (NEARTAG*256); + *((unsigned char far *)outptr)++ = inptr-bestscan; + outlength += 3; + nearrepeats++; + inptr += beststring; + length -= beststring; + } + else if (beststring > 2) + { + // far string + *outptr++ = beststring + (FARTAG*256); + *outptr++ = bestscan-instart; + outlength += 4; + farrepeats++; + inptr += beststring; + length -= beststring; + } + else // no compression + { + chhigh = wch>>8; + if (chhigh == NEARTAG || chhigh == FARTAG) + { + // special case of encountering a + // tag word in the data stream + // send a length of 0, and follow it with the real low byte + *outptr++ = wch & 0xff00; + *((unsigned char far *)outptr)++ = wch&0xff; + outlength += 3; + dups++; + } + else + { + *outptr++ = wch; + outlength += 2; + } + inptr++; + length--; + newwords++; + } + + if (!--count) + { + static char cc[2]="-"; + cc[0]^='+'^'-'; + print(cc); + sx--; + + count = 10; + + if (keydown[1]) + { + while(keydown[1]); + return 0; + } + } + } while (length); +#if 0 + printf ("\r%u near patterns\n",nearrepeats); + printf ("%u far patterns\n",farrepeats); + printf ("%u new words\n",newwords); + printf ("%u dups\n\n",dups); +#endif + return outlength; +} +#endif + + diff --git a/16/ted5/JHUFF.H b/16/ted5/JHUFF.H new file mode 100755 index 00000000..0d4536c3 --- /dev/null +++ b/16/ted5/JHUFF.H @@ -0,0 +1,26 @@ +typedef struct +{ + unsigned bit0,bit1; // 0-255 is a character, > is a pointer to a node +} huffnode; + +extern long counts[256]; +extern huffnode nodearray[256]; + + +void CountBytes (unsigned char huge *start, long length); +void Huffmanize (void); +void OptimizeNodes (huffnode *table); +long HuffCompress (unsigned char huge *source, long length, + unsigned char huge *dest); +void HuffExpand (unsigned char huge *source, unsigned char huge *dest, + long length,huffnode *hufftable); +void RLEWExpand (unsigned huge *source, unsigned huge *dest,long length, + unsigned rlewtag); +long RLEWCompress (unsigned huge *source, long length, unsigned huge *dest, + unsigned rlewtag); +void RLEBExpand (unsigned char huge *source, unsigned char huge *dest, + long length, unsigned char rlebtag); +long RLEBCompress (unsigned char huge *source, long length, + unsigned char huge *dest, unsigned char rlebtag); +long CarmackCompress (unsigned far *source,long length, + unsigned far *dest); diff --git a/16/ted5/LIB.C b/16/ted5/LIB.C new file mode 100755 index 00000000..e5a06fd9 --- /dev/null +++ b/16/ted5/LIB.C @@ -0,0 +1,1011 @@ +#include "ted5.h" +#pragma hdrstop + +extern char far TEDCHAR,far VGAPAL; + +void Quit(char *string); +void drawchar(int x,int y,int chr); +void centerwindow (int width, int height); + +int win_xl,win_yl,win_xh,win_yh; +int screencenterx = 19,screencentery = 11; +unsigned char keydown[256]; +unsigned leftedge,yshift,xormask,MouseStatus,sx,sy; +void interrupt (*oldint9) ()=NULL; +enum {false,true} boolean; +memptr CGAfont,VGAfont; +unsigned doubled[256]; +// +// Special vars to handle EGA3 mouse mode +// +int EGA3mx,EGA3my; + + +//////////////////////////////////////////////////////////////////// +// +// Return a file's length +// +//////////////////////////////////////////////////////////////////// +long filelen(char *filename) +{ + long size; + int handle; + + if ((handle=open(filename,O_BINARY))==-1) + return 0; + + size=filelength(handle); + close(handle); + return size; +} + +//////////////////////////////////////////////////////////////////// +// +// WaitVBL +// +//////////////////////////////////////////////////////////////////// +void WaitVBL(int times) +{ +asm mov cx,times +asm mov dx,crtcaddr +asm add dx,6 + +waitvbl1: +asm in al,dx +asm test al,00001000b //;look for vbl +asm jnz waitvbl1 + +waitvbl2: +asm in al,dx +asm test al,00001000b //;look for vbl +asm jz waitvbl2 + +asm loop waitvbl1 +} + + +//////////////////////////////////////////////////////////////////// +// +// Int9ISR +// Called for every keypress. Keeps track of which keys are down, and passes +// the key on to DOS after clearing the dos buffer (max 1 char in buffer). +// +//////////////////////////////////////////////////////////////////// +void interrupt Int9ISR () +{ + int key = inportb (0x60); /* get the key pressed */ + + if (key>127) + keydown [key-128] = false; /* break scan code */ + else + { + keydown [key] = true; /* make scan code */ + poke (0x40,0x1c,peek(0x40,0x1a)); /* clear the bios key buffer */ + } +asm { + push ax + push bx + push cx + push dx + push si + push di + push bp + } + oldint9 (); /* give it to DOS */ +asm { + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + } + outport (0x20,0x20); /* tell the int manager we got it */ +} + + +//////////////////////////////////////////////////////////////////// +// +// SetupKBD +// Clears the keydown array and installs the INT 9 ISR if it isn't already +// hooked up. +// +//////////////////////////////////////////////////////////////////// +void SetupKBD () +{ + void far *vect = getvect (9); + int i; + + for (i=0;i<128;i++) /* clear our key down table */ + keydown[i]= false; + + poke (0x40,0x1c,peek(0x40,0x1a)); /* clear the bios key buffer */ + + if ( &Int9ISR != vect ) /* is our handler allready set up? */ + { + oldint9 = vect; + setvect (9,Int9ISR); + } +} + + +//////////////////////////////////////////////////////////////////// +// +// ShutdownKBD +// Sets the int 9 vector back to oldint 9 +// +//////////////////////////////////////////////////////////////////// +void ShutdownKBD () +{ + if (oldint9 != NULL) + setvect (9,oldint9); +} + + +//////////////////////////////////////////////////////////////////// +// +// clearkeys +// Clears out the bios buffer and zeros out the keydown array +// +//////////////////////////////////////////////////////////////////// +void clearkeys (void) +{ + int i; + while (bioskey (1)) + bioskey(0); + + for (i=0;i<128;i++) + keydown [i]=0; +} + + +//////////////////////////////////////////////////////////////////// +// +// Mouse Routines +// +//////////////////////////////////////////////////////////////////// +int MouseInit(void) +{ + union REGS regs; + unsigned char far *vector; + + if ((vector=MK_FP(peek(0,0x33*4+2),peek(0,0x33*4)))==NULL) return 0; + + if (*vector == 207) + return MouseStatus = 0; + + _AX=0; + geninterrupt(0x33); + EGA3mx=800/2; + EGA3my=600/2; + + // + // Set CGA mouse cursor (normal one sucks) + // + if (videomode==CGA) + { + static unsigned CGAcursor[]= + { + 0x0fff,0x03ff,0x00ff,0x003f,0x000f,0x0003,0x0000,0x000f,0x0c03,0x3c03, + 0xff03,0xffff,0xffff,0xffff,0xffff,0xffff, + + 0xf000,0xcc00,0xc300,0xc0c0,0xc030,0xc00c,0xc03f,0xcc30,0xf30c,0xc30c, + 0x00fc,0x0000,0x0000,0x0000,0x0000,0x0000 + }; + + _BX=0; + _CX=0; + _DX=FP_OFF(CGAcursor); + _ES=_DS; + _AX=9; + geninterrupt(0x33); + } + + return MouseStatus = 1; +} + + +void MouseOrigin(int x,int y) +{ + if (!MouseStatus) return; + + _CX=x; + _DX=y; + _AX=4; + geninterrupt(0x33); +} + + +void MouseLimits(int xmin,int xmax,int ymin,int ymax) +{ + if (!MouseStatus) return; + + _CX=xmin; + _DX=xmax; + _AX=7; + geninterrupt(0x33); + _CX=ymin; + _DX=ymax; + _AX=8; + geninterrupt(0x33); +} + + +void MouseHide(void) +{ + if (!MouseStatus) return; + + _AX=2; + geninterrupt(0x33); +} + + + +void MouseShow(void) +{ + if (!MouseStatus) return; + + _AX=1; + geninterrupt(0x33); +} + + + +int MouseButton(void) +{ + union REGS regs; + + if (!MouseStatus) return 0; + + regs.x.ax=3; + int86(0x33,®s,®s); + return(regs.x.bx); +} + + + +void MouseCoords(int *x,int *y) +{ + union REGS regs; + + if (!MouseStatus) + return; + + regs.x.ax=3; + int86(0x33,®s,®s); + *x=regs.x.cx; + *y=regs.x.dx; + + *x/=2; + if (videomode==EGA2) + *x*=2; +} + +///////////////////////// +// +// print +// Prints a string at sx,sy. No clipping!!! +// +///////////////////////// + +void print (const char *str) +{ + char ch; + + while ((ch=*str++) != 0) + if (ch == '\n') + { + sy++; + sx=leftedge; + } + else if (ch == '\r') + sx=leftedge; + else + drawchar (sx++,sy,ch); +} +void fprint (const char huge *str) +{ + char ch; + + while ((ch=*str++) != 0) + if (ch == '\n') + { + sy++; + sx=leftedge; + } + else if (ch == '\r') + sx=leftedge; + else + drawchar (sx++,sy,ch); +} + +//////////////////////////////////////////////////////////////////// +// +// print hex byte +// +//////////////////////////////////////////////////////////////////// +void printhexb(unsigned char value) +{ + int loop; + char hexstr[16]="0123456789ABCDEF",str[2]=""; + + for (loop=0;loop<2;loop++) + { + str[0]=hexstr[(value>>(1-loop)*4)&15]; + print(str); + } +} + +//////////////////////////////////////////////////////////////////// +// +// print hex +// +//////////////////////////////////////////////////////////////////// +void printhex(unsigned value) +{ + print("$"); + printhexb(value>>8); + printhexb(value&0xff); +} + + +//////////////////////////////////////////////////////////////////// +// +// print int +// +//////////////////////////////////////////////////////////////////// +void printint(unsigned value) +{ + char temp[10]; + + ultoa((unsigned long)value,temp,10); + print(temp); +} + + +//////////////////////////////////////////////////////////////////// +// +// print bin +// +//////////////////////////////////////////////////////////////////// +void printbin(unsigned value) +{ + int loop; + + print("%"); + for (loop=0;loop<16;loop++) + if ((value>>15-loop)&1) print("1"); else print("0"); +} + + +//////////////////////////////////////////////////////////////////// +// +// input unsigned +// +//////////////////////////////////////////////////////////////////// +unsigned inputint(int numchars) +{ + char string[18]="",digit,hexstr[16]="0123456789ABCDEF"; + unsigned value,loop,loop1; + + if (!input(string,numchars)) + return ESCOUT; + + if (string[0]=='$') + { + int digits; + + digits=strlen(string)-2; + if (digits<0) return 0; + + for (value=0,loop1=0;loop1<=digits;loop1++) + { + digit=toupper(string[loop1+1]); + for (loop=0;loop<16;loop++) + if (digit==hexstr[loop]) + { + value|=(loop<<(digits-loop1)*4); + break; + } + } + } + else if (string[0]=='%') + { + int digits; + + digits=strlen(string)-2; + if (digits<0) return 0; + + for (value=0,loop1=0;loop1<=digits;loop1++) + { + if (string[loop1+1]<'0' || string[loop1+1]>'1') return 0; + value|=(string[loop1+1]-'0')<<(digits-loop1); + } + } + else value=atoi(string); + return value; +} + + +//////////////////////////////////////////////////////////////////// +// +// line input routine +// +//////////////////////////////////////////////////////////////////// +int input(char *string,int max) +{ + char key; + int count=0,loop; + + do { + key=get()&0xff; + if ((key==127 || key==8)&&count>0) + { + count--; + drawchar(sx,sy,' '); + sx--; + } + + if (key>=' ' && key<='z' && count>(7-k))&1]; + } + // + // Now, change video modes! + // + switch(vid) + { + case TEXT: _AX=3; break; + case CGA: + screencenterx=19; + screencentery=11; + scrnbot=199; + scrnrgt=319; + _AX=4; + break; + case EGA1: + screencenterx=19; + screencentery=11; + scrnbot=199; + scrnrgt=319; + _AX=0x0d; + break; + case EGA2: + screencenterx=39; + screencentery=29; + scrnbot=479; + scrnrgt=638; + _AX=0x12; + break; + case VGA: + _AX=0x13; + screencenterx=19; + screencentery=11; + scrnbot=199; + scrnrgt=319; + } + geninterrupt(0x10); + videomode=vid; + + // + // Set CGA mouse cursor (normal one sucks) + // + if (vid==CGA) + { + static unsigned CGAcursor[]= + { + 0x0fff,0x03ff,0x00ff,0x003f,0x000f,0x0003,0x0000,0x000f,0x0c03,0x3c03, + 0xff03,0xffff,0xffff,0xffff,0xffff,0xffff, + + 0xf000,0xcc00,0xc300,0xc0c0,0xc030,0xc00c,0xc03f,0xcc30,0xf30c,0xc30c, + 0x00fc,0x0000,0x0000,0x0000,0x0000,0x0000 + }; + + _BX=0; + _CX=0; + _DX=FP_OFF(CGAcursor); + _ES=_DS; + _AX=9; + geninterrupt(0x33); + } + else + // + // Move EGA font into LATCH memory! + // + if (vid==EGA1 || vid==EGA2) + { + unsigned i,s=FP_SEG(&TEDCHAR),o=FP_OFF(&TEDCHAR); + + outport(GCindex,GCmode); + for (i=0;i<4;i++) + { + outport(SCindex,SCmapmask | (1< 2) + expwinh (width-2,height); + + WaitVBL (1); + centerwindow (width,height); +} + +void expwinv (int width, int height) +{ + if (height >2) + expwinv (width,height-2); + + WaitVBL (1); + centerwindow (width,height); +} +void expwin (int width, int height) +{ + if (width > 2) + { + if (height >2) + expwin (width-2,height-2); + else + expwinh (width-2,height); + } + else + if (height >2) + expwinv (width,height-2); + + WaitVBL (1); + centerwindow (width,height); +} + + +//////////////////////////////////////////////////////////// +// +// Save a *LARGE* file from a FAR buffer! +// by John Romero (C) 1990 Gamer's Edge +// +//////////////////////////////////////////////////////////// +void SaveFile(char *filename,char huge *buffer,long offset,long size) +{ + unsigned int handle,buf1,buf2,offlo,offhi,sizelo,sizehi; + + buf1=FP_OFF(buffer); + buf2=FP_SEG(buffer); + offlo=offset&0xffff; + offhi=offset>>16; + sizelo=size&0xffff; + sizehi=size>>16; + +asm mov ax,offlo +asm or ax,offhi +asm jz CREATEIT + +asm mov dx,filename +asm mov ax,3d02h // OPEN w/handle (read only) +asm int 21h +asm jnc L0 + + return; + +L0: + +asm mov handle,ax + +asm mov bx,handle +asm mov dx,offlo +asm mov cx,offhi +asm mov ax,4200h +asm int 21h // SEEK (to file offset) +asm jc out + +asm jmp DOSAVE + +CREATEIT: + +asm mov dx,filename +asm mov ax,3c00h // CREATE w/handle (read only) +asm xor cx,cx +asm int 21h +asm jc out + +asm mov handle,ax + +DOSAVE: + +asm cmp WORD PTR sizehi,0 // larger than 1 segment? +asm je L2 + +L1: + +asm push ds +asm mov bx,handle +asm mov cx,8000h +asm mov dx,buf1 +asm mov ax,buf2 +asm mov ds,ax +asm mov ah,40h // WRITE w/handle +asm int 21h +asm pop ds + +asm add WORD PTR buf2,800h // bump ptr up 1/2 segment +asm sub WORD PTR sizelo,8000h // done yet? +asm sbb WORD PTR sizehi,0 +asm cmp WORD PTR sizehi,0 +asm ja L1 +asm cmp WORD PTR sizelo,8000h +asm jae L1 + +L2: + +asm push ds +asm mov bx,handle +asm mov cx,sizelo +asm mov dx,buf1 +asm mov ax,buf2 +asm mov ds,ax +asm mov ah,40h // WRITE w/handle +asm int 21h +asm pop ds + +out: + +asm mov bx,handle // CLOSE w/handle +asm mov ah,3eh +asm int 21h + +} + +//////////////////////////////////////////////////////////// +// +// Load a *LARGE* file into a FAR buffer! +// by John Romero (C) 1990 Gamer's Edge +// +//////////////////////////////////////////////////////////// +unsigned long LoadFile(char *filename,char huge *buffer,long offset,long size) +{ + unsigned handle,flength1=0,flength2=0,buf1,buf2,len1,len2, + rsize1,rsize2,roffset1,roffset2; + + rsize1=size&0xffff; + rsize2=size>>16; + roffset1=offset&0xffff; + roffset2=offset>>16; + buf1=FP_OFF(buffer); + buf2=FP_SEG(buffer); + +asm mov dx,filename +asm mov ax,3d00h // OPEN w/handle (read only) +asm int 21h +asm jnc L_0 + + return 0; + +L_0: + +asm mov handle,ax +asm mov bx,ax +asm xor cx,cx +asm xor dx,dx +asm mov ax,4202h +asm int 21h // SEEK (find file length) +asm jc out + +asm mov flength1,ax +asm mov len1,ax +asm mov flength2,dx +asm mov len2,dx + +asm mov ax,rsize1 // was a size specified? +asm or ax,rsize1 +asm jz LOADALL + +asm mov ax,rsize1 // only load size requested +asm mov len1,ax +asm mov ax,rsize2 +asm mov len2,ax + +LOADALL: + +asm mov bx,handle +asm mov dx,roffset1 +asm mov cx,roffset2 +asm mov ax,4200h +asm int 21h // SEEK (to file offset) +asm jc out + +asm cmp WORD PTR len2,0 // MULTI-SEGMENTAL? +asm je L_2 + +L_1: + +asm push ds +asm mov bx,handle +asm mov cx,8000h // read 32K chunks +asm mov dx,buf1 +asm mov ax,buf2 +asm mov ds,ax +asm mov ah,3fh // READ w/handle +asm int 21h +asm pop ds +asm jc out + +asm add WORD PTR buf2,800h +asm sub WORD PTR len1,8000h +asm sbb WORD PTR len2,0 +asm cmp WORD PTR len2,0 +asm ja L_1 +asm cmp WORD PTR len1,8000h +asm jae L_1 + +L_2: + +asm push ds +asm mov bx,handle +asm mov cx,len1 +asm mov dx,buf1 +asm mov ax,buf2 +asm mov ds,ax +asm mov ah,3fh // READ w/handle +asm int 21h +asm pop ds +asm jmp exit + +out: + +asm mov WORD PTR flength2,0 +asm mov WORD PTR flength1,0 + +exit: + +asm mov bx,handle // CLOSE w/handle +asm mov ah,3eh +asm int 21h + + return (flength2*0x10000+flength1); + +} + + +//////////////////////////////////////////////////////////// +// +// Allocate memory and load file in +// +//////////////////////////////////////////////////////////// +void LoadIn(char *filename,void _seg **baseptr) +{ + char errstr[80]; + int handle; + long len; + + if ((handle=open(filename,O_BINARY))==-1) + { + strcpy(errstr,"Error loading file "); + strcat(errstr,filename); + Quit(errstr); + } + + len=filelength(handle); + close(handle); + MMAllocate((memptr *)baseptr,len); + LoadFile(filename,MK_FP(*baseptr,0),0,0); +} + + diff --git a/16/ted5/LIB.H b/16/ted5/LIB.H new file mode 100755 index 00000000..4075871c --- /dev/null +++ b/16/ted5/LIB.H @@ -0,0 +1,42 @@ +typedef enum {CGA,EGA1,EGA2,VGA,TEXT} video; +#define ESCOUT 0xdeaf + +void Quit(char *string); +void WaitVBL(int times); +int input(char *string,int max); +void SetupKBD (); +void ShutdownKBD (); +void clearkeys (void); +int MouseInit(void); +void MouseHide(void); +void MouseShow(void); +int MouseButton(void); +void MouseCoords(int *x,int *y); +void printhex(unsigned value); +void printbin(unsigned value); +unsigned inputint(int numchars); +int input(char *string,int max); +void print (const char *str); +void fprint (const char huge *str); +void printhexb(unsigned char value); +void printint(unsigned value); +void bar (int xl, int yl, int xh, int yh, int ch); +int get(void); +void drawwindow (int xl, int yl, int xh, int yh); +void erasewindow (void); +void centerwindow (int width, int height); +void expwin (int width, int height); +void expwinh (int width, int height); +void expwinv (int width, int height); +void SaveFile(char *filename,char huge *buffer, long size,long offset); +unsigned long LoadFile(char *filename,char huge *buffer,long offset,long size); +void LoadIn(char *filename,void _seg **baseptr); + +void MouseOrigin(int x,int y); +void MouseLimits(int xmin,int xmax,int ymin,int ymax); + +extern int win_xl,win_yl,win_xh,win_yh,screencenterx,screencentery; +extern unsigned char keydown[256]; +extern unsigned sx,sy,xormask,MouseStatus,leftedge; + +long filelen(char *filename); \ No newline at end of file diff --git a/16/ted5/LIB_A.ASM b/16/ted5/LIB_A.ASM new file mode 100755 index 00000000..1ce1de92 --- /dev/null +++ b/16/ted5/LIB_A.ASM @@ -0,0 +1,259 @@ +;==================================================== +; +; Library ASM code +; +;==================================================== + IDEAL + P386N + MODEL medium,C + +extrn xormask:WORD,yshift:WORD,CGAfont:WORD,VGAfont:WORD + + DATASEG + +SCindex = 3c4h +SCmapmask = 2 +GCindex = 3CEh +GCreadmap = 4 +GCmode = 5 + +a = 0 +LABEL CGAlookup WORD +PUBLIC CGAlookup + REPT 100 + dw a,a XOR 2000h +a = a+80 + ENDM + +a = 0 +LABEL EGA1lookup WORD +PUBLIC EGA1lookup + REPT 200 + dw a +a = a+40 + ENDM + +a = 0 +LABEL EGA2lookup WORD +PUBLIC EGA2lookup + REPT 480 + dw a +a = a+80 + ENDM + +a = 0 +LABEL VGAlookup WORD +PUBLIC VGAlookup + REPT 200 + dw a +a = a+320 + ENDM + + + CODESEG + +;==================================================== +; +; Draw CGA chars +; +;==================================================== +PROC CGAcharout +PUBLIC CGAcharout +ARG x:WORD,y:WORD,chr:BYTE +USES si,di,ds + mov bx,[y] + shl bx,1 + shl bx,1 + shl bx,1 + shl bx,1 + mov di,[CGAlookup+bx] + mov ax,[x] + shl ax,1 + add di,ax + + mov al,[chr] + xor ah,ah + shl ax,1 + shl ax,1 + shl ax,1 + shl ax,1 + mov si,ax + + mov ax,0b800h + mov es,ax + mov ds,[CGAfont] + cld + cmp [ss:xormask],0 + ja @@1 + + REPT 4 + movsw + add di,2000h-2 + movsw + sub di,2000h-78 + ENDM + jmp @@exit +@@1: + REPT 4 + lodsw + xor ax,0ffffh + stosw + add di,2000h-2 + lodsw + xor ax,0ffffh + stosw + sub di,2000h-78 + ENDM +@@exit: + ret +ENDP + +;==================================================== +; +; Draw EGA chars +; +;==================================================== +PROC EGAcharout +PUBLIC EGAcharout +ARG x:WORD,y:WORD,chr:BYTE,video:WORD +USES si,di,ds,bp + + mov dx,GCindex + mov ax,GCmode + out dx,ax + + mov bx,[y] + shl bx,1 + shl bx,1 + shl bx,1 + add bx,[yshift] + shl bx,1 + + cmp [video],1 + jne @@0 + mov cx,39 + mov di,[EGA1lookup+bx] + jmp @@1 +@@0: + mov cx,79 + mov di,[EGA2lookup+bx] +@@1: + add di,[x] + + mov ax,0a000h + mov es,ax + mov ds,ax + + mov si,0f000h + mov al,[chr] + xor ah,ah + shl ax,1 + shl ax,1 + shl ax,1 + add si,ax + + cld + cmp [ss:xormask],0 + ja @@2 + + mov dx,GCindex + mov ax,GCmode OR 100h + out dx,ax + mov dx,SCindex + mov ax,SCmapmask OR 0f00h + out dx,ax + + REPT 8 + movsb + add di,cx + ENDM + jmp @@exit + +@@2: +ga = 100h +gb = 0 + mov bp,si + mov bx,di + REPT 4 + mov dx,SCindex + mov ax,SCmapmask OR ga + out dx,ax + mov dx,GCindex + mov ax,GCreadmap OR gb + out dx,ax + REPT 8 + lodsb + xor al,0ffh + stosb + add di,cx + ENDM + mov di,bx + mov si,bp +ga = ga*2 +gb = gb+100h + ENDM +@@exit: + mov dx,GCindex + mov ax,GCmode + out dx,ax + ret +ENDP + +;==================================================== +; +; Draw VGA chars +; +;==================================================== +PROC VGAcharout +PUBLIC VGAcharout +ARG x:WORD,y:WORD,chr:BYTE +USES si,di,ds + + mov bx,[y] + shl bx,1 + shl bx,1 + shl bx,1 + add bx,[yshift] + shl bx,1 + mov di,[VGAlookup+bx] + + mov ax,[x] + shl ax,1 + shl ax,1 + shl ax,1 + add di,ax + + mov ah,[chr] + xor al,al + shr ax,1 + shr ax,1 ;[chr]*64! + mov si,ax + + mov ax,0a000h + mov es,ax + mov ds,[VGAfont] + + cmp [ss:xormask],0 + ja @@1 + + REPT 8 + REPT 4 + movsw + ENDM + add di,320-8 + ENDM + jmp @@exit +@@1: + REPT 8 + REPT 4 + lodsw + xor ax,0ffffh + stosw + ENDM + add di,320-8 + ENDM +@@exit: + ret +ENDP + +END diff --git a/16/ted5/MAPTEMP b/16/ted5/MAPTEMP new file mode 100755 index 00000000..48f87ccd Binary files /dev/null and b/16/ted5/MAPTEMP differ diff --git a/16/ted5/MAPTHEAD b/16/ted5/MAPTHEAD new file mode 100755 index 00000000..dee1d891 Binary files /dev/null and b/16/ted5/MAPTHEAD differ diff --git a/16/ted5/MEMMGR.C b/16/ted5/MEMMGR.C new file mode 100755 index 00000000..d13240f7 --- /dev/null +++ b/16/ted5/MEMMGR.C @@ -0,0 +1,781 @@ +#include "ted5.h" +#pragma hdrstop + +#define EMSINT 0x67 + +#define SPACEFREE 0x2000 // how much mem to leave alone in farheap +#define EXTRASTACKSIZE 0x2000 +#define MAXBLOCKS 1000 +#define LOCKBIT 0x8000 // if set in attributes, block cannot be moved +#define PURGEBITS 3 // 0-3 level, 0= unpurgable, 3= purge first + +#define BASEATTRIBUTES 0 // unlocked, non purgable + +unsigned totalmem; // total paragraphs available with 64k EMS +int EMSpresent,XMSpresent; + + +long TTLMainMem; + +void far *farheap; +void *nearheap; + +int numblocks; +struct { + unsigned start; // in paragraphs + unsigned length; + unsigned attributes; + memptr *useptr; + } blocks[MAXBLOCKS],tempblock; + +//========================================================================== + +// +// local prototypes +// +void CheckForEMS (void); +int FindBlock (memptr *ptr); +void RemoveBlock (int block); +void InsertBlock (int block); + + +// +// public prototypes +// + +void MMStartup (void); +void MMShutdown (void); +void MMMapEMS (void); +void MMGetPtr (memptr *baseptr,unsigned size); +void MMFreePtr (memptr *baseptr); +void MMSetPurge (memptr *baseptr, int purge); +void MMSortMem (void); +void MMBlockDump (void); +unsigned MMUnusedMemory (void); +unsigned MMTotalFree (void); + +//========================================================================== + + +// +// CheckForEMS +// +// Routine from p36 of Extending DOS +// +void CheckForEMS (void) +{ + char emmname[9] = "EMMXXXX0"; + +asm mov dx,OFFSET emmname +asm mov ax,0x3d00 +asm int 0x21 // try to open EMMXXXX0 device +asm jc error + +asm mov bx,ax +asm mov ax,0x4400 + +asm int 0x21 // get device info +asm jc error + +asm and dx,0x80 +asm jz error + +asm mov ax,0x4407 + +asm int 0x21 // get status +asm jc error +asm or al,al +asm jz error + +asm mov ah,0x3e +asm int 0x21 // close handle +asm jc error + +// +// EMS is good +// + + + return; + +error: +// +// EMS is bad +// + EMSpresent = 0; + +} + +//========================================================================== + + +// +// FindBlock +// +int FindBlock (memptr *ptr) +{ + int i; + for (i=1;i=MAXBLOCKS) + Quit ("Memory manager error: Too many blocks!"); +} + + + +// check numblocksdest) + { +asm cld + while (paragraphs>0xfff) + { + MoveParaBase (source,dest,0xfff*8); + source += 0xfff*8; + dest += 0xfff*8; + paragraphs -= 0xfff; + } + MoveParaBase (source,dest,paragraphs*8); + } + else + { +asm std + source+=paragraphs; + dest+=paragraphs; + while (paragraphs>0xfff) + { + source-=0xfff; + dest-=0xfff; + MoveParaBaseUp (source,dest,0xfff*8); + paragraphs -= 0xfff; + } + source-=paragraphs; + dest-=paragraphs; + MoveParaBaseUp (source,dest,paragraphs*8); +asm cld + } +} + + +/* +====================== += += MMSortMem += += Sorts all non locked blocks so lower purge levels are lower in memory += and all free space is at the top += +====================== +*/ + +int keyblock; + +// +// PushUp +// +// Pushes the block (purgeable) as high in memory as possible +// must be BELOW keyblock +// If it can't fit above keyblock it will be freed +// +void PushUp (int move) +{ + unsigned source,dest,size; + int i; + + size = blocks[move].length; + source = blocks[move].start; + + for (i=numblocks-1;i>keyblock;i--) + { + // + // if the block can fit under this block, move it + // + dest = blocks[i].start - size; + if (blocks[i-1].start+blocks[i-1].length <= dest) + { + // + // make a copy of block 'move' under block 'i' + // + InsertBlock (i-1); + blocks[i] = blocks[move]; + blocks[i].start = dest; + *(blocks[i].useptr) = (void _seg *)dest; // modify the pointer to the new spot + MoveParas (source,dest,size); + break; + } + } + + // + // erase original position + // + RemoveBlock (move); + keyblock--; // because a block below it was removed +} + + +// +// PushDown +// +// Push keyblock (unpurgable) as low in memory as possible +// +void PushDown (void) +{ + unsigned source,dest,size,end,lowblock,checkblock,i; + + size = blocks[keyblock].length; + source = blocks[keyblock].start; + +// +// find the lowest space it can be moved into +// + for (lowblock = 0;lowblocklowblock+1;i--) + blocks[i]=blocks[i-1]; + blocks[lowblock+1] = tempblock; + } + +//MMBlockDump(); // DEBUG + } + return; + + nofit:; // keep looking... + + } +} + + +// +// MMSortMem +// + +void MMSortMem (void) +{ + unsigned i,source,dest; + + keyblock = 0; + + do + { + keyblock++; + + // + // non-purgable, unlocked blocks will be pushed low in memory + // + if ( !(blocks[keyblock].attributes & PURGEBITS) && + !(blocks[keyblock].attributes & LOCKBIT) ) + PushDown (); + + } while (keyblock0;i--) + { + // + // push all purgable blocks as high as possible + // Currently they are NOT moved around locked blocks! + // + if ( blocks[i].attributes & PURGEBITS ) + { + source= blocks[i].start; + dest= blocks[i+1].start-blocks[i].length; + if (source!=dest) + { + MoveParas (source,dest,blocks[i].length); + blocks[i].start = dest; + *(blocks[i].useptr) = (void _seg *)dest; // modify the pointer to the new spot + } + } + } + + PatchPointers(); // let the main program fix up any + // internal references +} + + +//========================================================================== + +/* +======================= += += MMBlockDump += += Dewbug tool += +======================= +*/ + +void MMBlockDump (void) +{ + int i; + unsigned free; + + fprintf (stdprn,"-------------\n"); + for (i=0;i>1)&1; + + sx=0; + sy=3; + + if (!OpenMenu) + ConstantRoutine(); + switch(buttonstatus=((buttonstatus<<1)|temp|temp1)&3) + { + case upup: break; + case updown: HandleOpenMenu(UserRoutine,0); + break; + case downdown: HandleHighlight(UserRoutine); + break; + case downup: HandleCloseMenu(UserRoutine); + if (ItemOn && ItemRoutine) + ItemRoutine(); + ItemOn=0; + break; + } + + if (bioskey(1)) + { + char key=bioskey(1)>>8; + int nitems; + + if (OpenMenu) + { + bioskey(0); + + nitems=(MBarPtr+OpenMenu-1)->num_items; + + switch(key) + { + case 0x48: if (OpenMenu) + if (ItemOn) + if (ItemOn==1) + ChangeItem(nitems); + else + ChangeItem(ItemOn-1); + break; + case 0x50: if (OpenMenu) + if (ItemOn) + if (ItemOn==nitems) + ChangeItem(1); + else + ChangeItem(ItemOn+1); + break; + case 0x1c: oldmenu=OpenMenu; + olditem=ItemOn; + HandleCloseMenu(UserRoutine); + if (ItemOn) + ItemRoutine(); + + break; + case 0x4b: if (OpenMenu) + { + int newmenu; + + ItemOn=0; + if (OpenMenu==1) + newmenu=NumMenus; + else + newmenu=OpenMenu-1; + + HandleCloseMenu(UserRoutine); + HandleOpenMenu(UserRoutine,newmenu); + + ChangeItem(1); + } + break; + case 0x4d: if (OpenMenu) + { + int newmenu; + + ItemOn=0; + if (OpenMenu==NumMenus) + newmenu=1; + else + newmenu=OpenMenu+1; + + HandleCloseMenu(UserRoutine); + HandleOpenMenu(UserRoutine,newmenu); + + ChangeItem(1); + } + break; + case 0x01: if (!OpenMenu) + { + HandleOpenMenu(UserRoutine,oldmenu); + ChangeItem(olditem); + } + break; + } + } + else + { + int i,j,numitems,run=0; + MenuDef *items; + + for (i=0;inum_items; + items=(MBarPtr+i)->menu_def; + + for (j=0;jhotkey==key && (items+j)->hotkey) + { + if (((items+j)->shiftflag) && + (!keydown[(items+j)->shiftflag])) + continue; + + ItemRoutine=(items+j)->routine; + ItemRoutine(); + run=1; + break; + } + if (run) + { + if (bioskey(1)) + bioskey(0); + break; + } + } + if (!run) + UserRoutine(); + } + } + } +} + + + +///////////////////////////////////////////////////////////////// +// +// See if a menu was opened +// +///////////////////////////////////////////////////////////////// +void HandleOpenMenu(void (*UserRoutine)(void),int which) +{ + int x,y,loop,flag,tempx,tempw,maxw,loopsize; + MenuDef *items; + + if (!which) + { + MouseCoords(&x,&y); + if (y>8 && !OpenMenu) + { + UserRoutine(); + return; + } + + flag=DetectMenu(x,y); + if (!flag) return; + } + else + flag=which; + + + tempx=MenuInfo[flag-1].menux; + tempw=MenuInfo[flag-1].menuwidth; + items=(MBarPtr+flag-1)->menu_def; + + sx=tempx+1; + sy=0; + maxw=0; + + MouseHide(); + + + // + // BUILD MENU STRINGS + // + loopsize=(MBarPtr+flag-1)->num_items; + + for (loop=0;loopitem_name); + + len=strlen(MenuStr[loop]); + memset(&MenuStr[loop][len],' ',tempw-len+1); + + switch((items+loop)->shiftflag) + { + case ALT: strcat(MenuStr[loop]," ALT-"); break; + case CTRL:strcat(MenuStr[loop],"CTRL-"); + } + + strcat(MenuStr[loop],PassScancode((items+loop)->hotkey)); + + len=strlen(MenuStr[loop]); + if (len>maxw) + maxw=len; + } + + if (tempx+maxw>ScreenWidth) + tempx=ScreenWidth-1-maxw; + SaveBackground(tempx*8,0,(maxw+1)*8,(MBarPtr+flag-1)->num_items*8+16); + + // + // PRINT MENU STRINGS + // + xormask=0xffff; + print((MBarPtr+flag-1)->menu_name); + xormask=0; + + for (loop=0;loop10) + return 0; + + flag=0; + for (loop=0;loop=MenuInfo[loop].menux && x/8num_items; + tempx=MenuInfo[OpenMenu-1].menux; + tempw=strlen(MenuStr[0])-5; + if (tempx+tempw+5>ScreenWidth) + tempx=ScreenWidth-tempw-5; + + opmen=DetectMenu(x,y); + if (opmen && opmen!=OpenMenu) + { + OpenMenu=0; + RestoreBackground(); + HandleOpenMenu(UserRoutine,0); + return; + } + + // + // IS USER IN A MENU? + // + + if (x/8>tempx && x/88 && y<(nitems+1)*8) + { + if (y/8==ItemOn) + return; // EXIT IF ON SAME ITEM + + // + // IF AN ITEM IS CURRENTLY SELECTED, DEHIGHLIGHT IT + // AND HIGHLIGHT A NEW ITEM + // + + ChangeItem(y/8); + } + else + // + // USER MOVED POINTER OUTSIDE OF MENU; DEHIGHLIGHT ITEM + // + + if (ItemOn) + { + MouseHide(); + + sx=tempx; + sy=ItemOn; + print(MenuStr[ItemOn-1]); + + ItemOn=0; + MouseShow(); + } +} + + + +///////////////////////////////////////////////////////////////// +// +// Set new item highlighted +// +///////////////////////////////////////////////////////////////// +void ChangeItem(int newitem) +{ + int tempx,tempw; + MenuDef *items; + char tempstr[80]=""; + + tempx=MenuInfo[OpenMenu-1].menux; + if (tempx+strlen(MenuStr[0])>ScreenWidth) + tempx=ScreenWidth-strlen(MenuStr[0]); + + MouseHide(); + if (ItemOn) + { + sx=tempx; + sy=ItemOn; + print(MenuStr[ItemOn-1]); + } + + xormask=0xffff; + ItemOn=newitem; + strncpy(tempstr,&MenuStr[ItemOn-1][1],strlen(MenuStr[ItemOn-1])-2); + sx=tempx+1; + sy=ItemOn; + print(tempstr); + xormask=0; + + MouseShow(); +} + + + +///////////////////////////////////////////////////////////////// +// +// See if a menu was closed +// +///////////////////////////////////////////////////////////////// +void HandleCloseMenu(void (*UserRoutine)(void)) +{ + MenuDef *items; + int loop,tempx; + char tempstr[80]=""; + + if (!OpenMenu) + { + UserRoutine(); + return; + } + + if (ItemOn) + { + items=(MBarPtr+OpenMenu-1)->menu_def; + tempx=MenuInfo[OpenMenu-1].menux; + if (tempx+strlen(MenuStr[0])>ScreenWidth) + tempx=ScreenWidth-strlen(MenuStr[0]); + + for (loop=0;looproutine; + } + + OpenMenu=0; + RestoreBackground(); +} + + +///////////////////////////////////////////////////////////////// +// +// Save the background +// +///////////////////////////////////////////////////////////////// +void SaveBackground(int x,int y,int w,int h) +{ + long size; + unsigned loc,loop,loop1,seg,planelen; + + Back[WhichBack].savex=x; + Back[WhichBack].savey=y; + Back[WhichBack].savew=w; + Back[WhichBack].saveh=h; + + MouseHide(); + switch (videomode) + { + case CGA: + MMAllocate(&Background[WhichBack],(w/4)*h); + + for(loop=y;loopnum_items && !flag) + { + int len,max_width,loop; + MenuDef *the_item; + char string[80]; + + // + // First, determine xcoord & namewidth & print + // + + strcpy(string,(MBarPtr+count)->menu_name); + len=strlen(string); + MenuInfo[NumMenus].menux=sx; + MenuInfo[NumMenus].menunamelen=len+2; + if (len+sx>ScreenWidth-1) + { + string[ScreenWidth-1-sx]=0; + MenuInfo[NumMenus].menunamelen=ScreenWidth-1-sx; + MenuInfo[NumMenus].menux=ScreenWidth-MenuInfo[NumMenus].menunamelen; + flag++; + } + + drawchar(sx++,sy,' '); + print(string); + drawchar(sx++,sy,' '); + + // + // Now, figure out length of widest item + // + + max_width=0; + the_item=(MBarPtr+count)->menu_def; + + for (loop=0;loop<(MBarPtr+count)->num_items;loop++) + { + int len; + + len=strlen((the_item+loop)->item_name); + if (len>max_width) + max_width=len; + } + + MenuInfo[NumMenus].menuwidth=max_width+1; + + count++; + NumMenus++; + } + + // + // clear bottom line of menubar + // + switch(videomode) + { + case CGA: + { + unsigned huge *CGAmem=MK_FP(0xb800,240+0x2000); + for(i=0;i<40;i++) + *(CGAmem+i)=0; + } + break; + case EGA1: + case EGA2: + { + char huge *EGAmem=MK_FP(0xa000,0); + outport(GCindex,GCmode); + outport(SCindex,0x0f00 | SCmapmask); + for (i=0;i=0x3b && sc<=0x44) + { + char str[3]; + strcpy(tempstr,"F"); + itoa (sc-0x3a,str,10); + strcat(tempstr,str); + } + else if (sc==0x57) + strcpy(tempstr,"F11"); + else if (sc==0x59) + strcpy(tempstr,"F12"); + else if (sc==0x46) + strcpy(tempstr,"SCRLLK"); + else if (sc==0x1c) + strcpy(tempstr,"ENTER"); + else if (sc==0x36) + strcpy(tempstr,"RSHIFT"); + else if (sc==0x37) + strcpy(tempstr,"PRTSC"); + else if (sc==0x38) + strcpy(tempstr,"ALT"); + else if (sc==0x47) + strcpy(tempstr,"HOME"); + else if (sc==0x49) + strcpy(tempstr,"PGUP"); + else if (sc==0x4f) + strcpy(tempstr,"END"); + else if (sc==0x51) + strcpy(tempstr,"PGDN"); + else if (sc==0x52) + strcpy(tempstr,"INS"); + else if (sc==0x53) + strcpy(tempstr,"DEL"); + else if (sc==0x45) + strcpy(tempstr,"NUMLK"); + else + { + smallstr[0]=chartable[sc]; + smallstr[1]=0; + strcpy(tempstr,smallstr); + } + + return tempstr; +} + +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// +// +// +// DIALOG MANAGER CODE +// +// +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// +///////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////// +// +// Dialog Boxes! +// +///////////////////////////////////////////////////////// +int DoDialog(DialogDef *TheDialog) +{ + btype *TheButton; + int i,ox,oy,Float=0,Released=0,Clicked=0,xc[30],yc[30],wid[30]; + + for (i=0;i<30;i++) + xc[i]=yc[i]=wid[i]=0; + + MouseHide(); + SaveBackground((screencenterx-TheDialog->width/2)*8, + (screencentery-TheDialog->height/2)*8,(TheDialog->width+2)*8, + (TheDialog->height+2)*8); + + xormask=0; + centerwindow(TheDialog->width,TheDialog->height); + ox=sx; + oy=sy; + print(TheDialog->text); + for (i=0;inumbuttons;i++) + { + int xx,yy,j; + + TheButton=TheDialog->buttons; + + xc[i]=sx=ox+(TheButton+i)->xoff; + yc[i]=sy=oy+(TheButton+i)->yoff; + xx=sx-1; + yy=sy-1; + print((TheButton+i)->text); + wid[i]=strlen((TheButton+i)->text); + + if ((TheButton+i)->border) + DrawBorder(xx,yy,wid[i]+1,2,(TheButton+i)->border); + } + + if (TheDialog->hook) + { + HookRoutine=(void (*)(int x,int y))TheDialog->hook; + HookRoutine(ox,oy); + } + MouseShow(); + + clearkeys(); + do + { + char temp; + int mx,my; + + temp=((temp<<1)|(MouseButton()&1))&3; + MouseCoords(&mx,&my); + mx/=8; + my/=8; + + // + // ENTER press + // + if (keydown[0x1c]) + for(i=0;inumbuttons;i++) + { + TheButton=TheDialog->buttons; + if ((TheButton+i)->border==2) + { + Clicked=i+1; + Released=1; + temp=Float=0; + while(keydown[0x1c]); + clearkeys(); + } + } + + // + // ESC press + // + if (keydown[1]) + { + temp=Float=Clicked=0; + Released=1; + while(keydown[1]); + } + + switch(temp) + { + case 0: // upup (no press) + break; + case 3: // downdown (held down) + if (!Float && Clicked && (mxxc[Clicked-1]+wid[Clicked-1]-1 || my!=yc[Clicked-1])) + { + xormask=0; + sx=xc[Clicked-1]; + sy=yc[Clicked-1]; + MouseHide(); + print((TheButton+Clicked-1)->text); + MouseShow(); + xormask=1; + Float=1; + } + else + if (Float && mx>=xc[Clicked-1] && + mxtext); + MouseShow(); + xormask=0; + Float=0; + } + break; + case 1: // updown (press) + for (i=0;inumbuttons;i++) + { + if (mx>=xc[i] && mxtext); + MouseShow(); + xormask=0; + break; + } + } + break; + case 2: // downup (release) + if (Clicked && !Float) + Released++; + } + } while (!Released); + + RestoreBackground(); + return Clicked; +} + + +///////////////////////////////////////////////////////// +// +// Just CHECK a Dialog Box's BUTTONS +// +///////////////////////////////////////////////////////// +int CheckButtons(DialogDef *TheDialog) +{ + btype *TheButton; + int i,ox,oy,Float=0,Released=0,Clicked=0,xc[30],yc[30],wid[30]; + + for (i=0;i<30;i++) + xc[i]=yc[i]=wid[i]=0; + + ox=screencenterx-TheDialog->width/2+1; + oy=screencentery-TheDialog->height/2+1; + for (i=0;inumbuttons;i++) + { + int xx,yy,j; + + TheButton=TheDialog->buttons; + + xc[i]=ox+(TheButton+i)->xoff; + yc[i]=oy+(TheButton+i)->yoff; + wid[i]=strlen((TheButton+i)->text); + } + + + clearkeys(); + do + { + char temp; + int mx,my; + + temp=((temp<<1)|(MouseButton()&1))&3; + MouseCoords(&mx,&my); + mx/=8; + my/=8; + + // + // ENTER press + // + if (keydown[0x1c]) + for(i=0;inumbuttons;i++) + { + TheButton=TheDialog->buttons; + if ((TheButton+i)->border==2) + { + Clicked=i+1; + Released=1; + temp=Float=0; + while(keydown[0x1c]); + clearkeys(); + } + } + + // + // ESC press + // + if (keydown[1]) + { + temp=Float=Clicked=0; + Released=1; + while(keydown[1]); + } + + switch(temp) + { + case 0: // upup (no press) + break; + case 3: // downdown (held down) + if (!Float && Clicked && (mxxc[Clicked-1]+wid[Clicked-1]-1 || my!=yc[Clicked-1])) + { + xormask=0; + sx=xc[Clicked-1]; + sy=yc[Clicked-1]; + MouseHide(); + print((TheButton+Clicked-1)->text); + MouseShow(); + xormask=1; + Float=1; + } + else + if (Float && mx>=xc[Clicked-1] && + mxtext); + MouseShow(); + xormask=0; + Float=0; + } + break; + case 1: // updown (press) + for (i=0;inumbuttons;i++) + { + if (mx>=xc[i] && mxtext); + MouseShow(); + xormask=0; + break; + } + } + break; + case 2: // downup (release) + if (Clicked && !Float) + Released++; + } + } while (!Released); + clearkeys(); + + if (Clicked) + { + sx=xc[Clicked-1]; + sy=yc[Clicked-1]; + MouseHide(); + print((TheButton+Clicked-1)->text); + MouseShow(); + } + + return Clicked; +} + + +///////////////////////////////////////////////////////// +// +// Just CHECK a Dialog Box's BUTTONS +// BUT!...RETURN IF MOUSE BUTTON IS PRESSED OUTSIDE DIALOG BUTTON! +// +///////////////////////////////////////////////////////// +int CheckButtonsRet(DialogDef *TheDialog) +{ + btype *TheButton; + int i,ox,oy,Float=0,Released=0,Clicked=0,xc[30],yc[30],wid[30]; + + for (i=0;i<30;i++) + xc[i]=yc[i]=wid[i]=0; + + ox=screencenterx-TheDialog->width/2+1; + oy=screencentery-TheDialog->height/2+1; + for (i=0;inumbuttons;i++) + { + int xx,yy,j; + + TheButton=TheDialog->buttons; + + xc[i]=ox+(TheButton+i)->xoff; + yc[i]=oy+(TheButton+i)->yoff; + wid[i]=strlen((TheButton+i)->text); + } + + do + { + char temp; + int mx,my; + + temp=((temp<<1)|(MouseButton()&1))&3; + if (MouseButton()&2) + return -1; + + MouseCoords(&mx,&my); + mx/=8; + my/=8; + + // + // ENTER press + // + if (keydown[0x1c]) + for(i=0;inumbuttons;i++) + { + TheButton=TheDialog->buttons; + if ((TheButton+i)->border==2) + { + Clicked=i+1; + Released=1; + temp=Float=0; + while(keydown[0x1c]); + clearkeys(); + } + } + + // + // ESC press + // + if (keydown[1]) + { + temp=Float=Clicked=0; + Released=1; + while(keydown[1]); + } + + // + // arrows or PgUp/PgDn/Home/End + // + if (keydown[0x48] || keydown[0x50] || keydown[0x4b] || keydown[0x4d] || + keydown[0x49] || keydown[0x51] || keydown[0x47] || keydown[0x4f] || + keydown[0x39] || keydown[0x2e]) + return -1; + + switch(temp) + { + case 0: // upup (no press) + break; + case 3: // downdown (held down) + if (!Float && Clicked && (mxxc[Clicked-1]+wid[Clicked-1]-1 || my!=yc[Clicked-1])) + { + xormask=0; + sx=xc[Clicked-1]; + sy=yc[Clicked-1]; + MouseHide(); + print((TheButton+Clicked-1)->text); + MouseShow(); + xormask=1; + Float=1; + } + else + if (Float && mx>=xc[Clicked-1] && + mxtext); + MouseShow(); + xormask=0; + Float=0; + } + break; + case 1: // updown (press) + for (i=0;inumbuttons;i++) + { + if (mx>=xc[i] && mxtext); + MouseShow(); + xormask=0; + break; + } + } + + if (!Clicked) // MOD TO ORIGINAL CHECKBUTTONS + return -1; + + break; + case 2: // downup (release) + if (Clicked && !Float) + Released++; + } + } while (!Released); + clearkeys(); + return Clicked; +} + + +///////////////////////////////////////////////////////// +// +// Just DRAW a Dialog Box +// +///////////////////////////////////////////////////////// +void DrawDialog(DialogDef *TheDialog,int saveback) +{ + btype *TheButton; + int i,ox,oy,xc[30],yc[30],wid[30]; + + for (i=0;i<30;i++) + xc[i]=yc[i]=wid[i]=0; + + MouseHide(); + if (saveback) + SaveBackground((screencenterx-TheDialog->width/2)*8, + (screencentery-TheDialog->height/2)*8,(TheDialog->width+2)*8, + (TheDialog->height+2)*8); + + xormask=0; + centerwindow(TheDialog->width,TheDialog->height); + ox=sx; + oy=sy; + print(TheDialog->text); + for (i=0;inumbuttons;i++) + { + int xx,yy,j; + + TheButton=TheDialog->buttons; + + xc[i]=sx=ox+(TheButton+i)->xoff; + yc[i]=sy=oy+(TheButton+i)->yoff; + xx=sx-1; + yy=sy-1; + print((TheButton+i)->text); + wid[i]=strlen((TheButton+i)->text); + + if ((TheButton+i)->border) + DrawBorder(xx,yy,wid[i]+1,2,(TheButton+i)->border); + } + + if (TheDialog->hook) + { + HookRoutine=(void (*)(int x,int y))TheDialog->hook; + HookRoutine(ox,oy); + } + + MouseShow(); +} + + +///////////////////////////////////////////////////////// +// +// Error Dialog Box +// +///////////////////////////////////////////////////////// +char errstring[200],bstring[20]; +btype ERROKb={bstring,0,0,2}; +DialogDef ERRR={errstring,0,0,1,&ERROKb,NULL}; + +void ErrDialog(char *string,char *bstr) +{ + int maxw=0,width=0,height=1,i; + + if (strlen(string)>200) + Quit("Programmer Error: ErrDialog string is too long!"); + + for (i=0;imaxw) + maxw=width; + + if (string[i]=='\n') + { + height++; + width=0; + } + } + height+=3; // add for button! + + if (strlen(bstr)>maxw) + Quit("Programmer Error: ErrDialog BUTTONstring is longer than dialog!"); + + strcpy(bstring,bstr); + strcpy(errstring,string); + ERRR.width=maxw; + ERRR.height=height; + ERRR.numbuttons=1; + if (!bstr[0]) + { + ERRR.numbuttons=0; + ERRR.height-=3; + } + + ERROKb.xoff=(maxw/2)-(strlen(bstr)/2); + ERROKb.yoff=height-2; + + if (bstr[0]) + DoDialog(&ERRR); + else + DrawDialog(&ERRR,1); +} + + +///////////////////////////////////////////////////////// +// +// Draw a border +// +///////////////////////////////////////////////////////// +void DrawBorder(int x,int y,int w,int h,int b) +{ + int xx=x,yy=y,j; + + if (b==2) + { + drawchar(xx,yy,15); + drawchar(xx+w,yy,17); + drawchar(xx,yy+h,20); + drawchar(xx+w,yy+h,22); + + for (j=yy+1;jbuttons; + + *x=(TheButton+button)->xoff+screencenterx-TheDialog->width/2+1; + *y=(TheButton+button)->yoff+screencentery-TheDialog->height/2+1; +} + + +///////////////////////////////////////////////////////// +// +// Get the XY coords of a dialog +// +///////////////////////////////////////////////////////// +void GetDialogXY(DialogDef *TheDialog,unsigned *x,unsigned *y) +{ + *x=screencenterx-TheDialog->width/2+1; + *y=screencentery-TheDialog->height/2+1; +} + + +//////////////////////////////////////////////////// +// +// Allow user to select a list item (like the menus) +// +//////////////////////////////////////////////////// +int CheckList(int x,int y,int w,int h,void (*oncode)(),void (*offcode)(),int blink) +{ + enum {upup,updown,downup,downdown} clicks; + static char bpress=0; + unsigned mx,my,i; + int high=-1; + + + while(1) + { + MouseCoords(&(int)mx,&(int)my); + mx/=8; + my/=8; + bpress=((bpress<<1)|(MouseButton()&1))&3; + switch(bpress) + { + case upup: + return -1; + case updown: + if (mx>=x && mx=y && my=x && mx=y && my200) + Quit("Programmer Error: Message string is too long!"); + + for (i=0;imaxw) + maxw=width; + + if (string[i]=='\n') + { + height++; + width=0; + } + } + height+=3; // add for buttons! + + strcpy(MessStr,string); + Mess.width=maxw; + Mess.height=height; + + MessOKb[1].xoff=(maxw/4)-(strlen(MessOKb[0].text)/2); + MessOKb[1].yoff=height-2; + MessOKb[0].xoff=(maxw/4)*3-(strlen(MessOKb[1].text)/2); + MessOKb[0].yoff=height-2; + + return DoDialog(&Mess); +} + + +///////////////////////////////////////////////// +// +// GetPath dialog +// *path is returned +// (exit:0 if OK,-1 if Not Successful,-2 if Canceled) +// +///////////////////////////////////////////////// +#define LISTX 1 +#define LISTY 3 + +char dstr[80]; +btype GPb={"Cancel",15,3,1}; +DialogDef GPd={dstr,22,14,1,&GPb,NULL}; +char NameList[MAXFDNAMES][13]; +int base; +struct ffblk f; + +int GetPath(char *string,char *filter,char *path) +{ + char pname[64]; + unsigned int numnames=0,max,dx,dy,redraw,exit; + int select,zset,i; + + + strcpy(pname,filter); + for (zset=0,i=strlen(pname);i>=0;i--) + if (pname[i]=='\\') + { + pname[i+1]=0; + zset++; + break; + } + if (!zset) + pname[0]=0; + + strcpy(dstr,string); + // + // FIRST, GET THE NAMES FROM THE DIRECTORY + // + if (findfirst(filter,&f,FA_ARCH)) + return -1; + strcpy(NameList[numnames++],f.ff_name); + + while(!findnext(&f) && numnames=0) + { + redraw=exit=1; + continue; + } + + GetButtonXY(&GPd,0,&sx,&sy); + select=CheckList(sx,sy,strlen(GPb.text),1,CancelOn,CancelOff,0); + if (!select || keydown[1]) + { + RestoreBackground(); + while(keydown[1]); + clearkeys(); + return -2; + } + + // + // CHECK ARROWS & PGUP/DN + // + if (keydown[0x48] && base) + { + base--; + redraw=1; + if (!keydown[0x1d]) + while(keydown[0x48]); + } + else + if (keydown[0x50] && base+10numnames) + base=numnames-10; + redraw=1; + if (!keydown[0x1d]) + while(keydown[0x51]); + } + + } while(!redraw); + } while(!exit); + + // + // RETURN PATHNAME + // + RestoreBackground(); + strcpy(path,pname); + strcat(path,NameList[select+base]); + findfirst(path,&f,FA_ARCH); + return 0; +} + + +static void FDon(int x,int y,int w) +{ + xormask=1; + FDoff(x,y,w); + xormask=0; +} + +static void FDoff(int x,int y,int w) +{ + MouseHide(); + sx=x; + sy=y; + print(NameList[w+base]); + MouseShow(); +} + + +static void CancelOn(int x,int y) +{ + xormask=1; + CancelOff(x,y); + xormask=0; +} + +static void CancelOff(int x,int y) +{ + MouseHide(); + sx=x; + sy=y; + print("Cancel"); + MouseShow(); +} + + +///////////////////////////////////////////////// +// +// GetList dialog +// Fill "NameList[?][13]" with your strings +// (exit:>=0 is selection,-1 if Not Successful,-2 if Canceled) +// +///////////////////////////////////////////////// +int GetList(char *string,int numnames) +{ + unsigned int max,dx,dy,redraw,exit,i; + int select; + + + strcpy(dstr,string); + + DrawDialog(&GPd,1); + MouseHide(); + GetDialogXY(&GPd,&dx,&dy); + DrawBorder(dx+LISTX-1,dy+LISTY-1,13,11,1); + MouseShow(); + + base=exit=0; + + // + // THIS LOOP DRAWS THE DIALOG + // + do + { + redraw=0; + MouseHide(); + max=10; + if (numnames<10) + max=numnames; + for (i=0;i=0) + { + redraw=exit=1; + continue; + } + + GetButtonXY(&GPd,0,&sx,&sy); + select=CheckList(sx,sy,strlen(GPb.text),1,CancelOn,CancelOff,0); + if (!select || keydown[1]) + { + RestoreBackground(); + while(keydown[1]); + clearkeys(); + return -2; + } + + // + // CHECK ARROWS & PGUP/DN + // + if (keydown[0x48] && base) + { + base--; + redraw=1; + if (!keydown[0x1d]) + while(keydown[0x48]); + } + else + if (keydown[0x50] && base+10numnames) + base=numnames-10; + redraw=1; + if (!keydown[0x1d]) + while(keydown[0x51]); + } + + } while(!redraw); + } while(!exit); + + // + // RETURN SELECTION + // + RestoreBackground(); + return select+base; +} diff --git a/16/ted5/MENU.H b/16/ted5/MENU.H new file mode 100755 index 00000000..4b624de7 --- /dev/null +++ b/16/ted5/MENU.H @@ -0,0 +1,78 @@ +///////////////////////////////////////////////////////////////// +// +// Pull-Down menu interface .H file +// +///////////////////////////////////////////////////////////////// +typedef struct { char *item_name; + void (*routine)(void); + char shiftflag; + char hotkey; + } MenuDef; + +typedef struct { int num_items; + MenuDef *menu_def; + char *menu_name; + } MBarDef; + +typedef struct { int menux; + int menunamelen; + int menuwidth; + } MInfoType; + +typedef struct { char *text; + int xoff,yoff,border; + } btype; + +typedef struct { char *text; + int width,height,numbuttons; + btype *buttons; + void (*hook)(int x,int y); + } DialogDef; + +typedef struct { int x,y,w,h; + void _seg *buffer; + } BackSaveStr; + +#define SCindex 0x3C4 +#define SCmapmask 2 +#define GCindex 0x3CE +#define GCreadmap 4 +#define GCmode 5 +#define crtcaddr 0x3d4 + +#define NUMFLASHES 10 +#define ALT 0x38 +#define CTRL 0x1d + +#define MAXFDNAMES 40 +extern struct ffblk f; // more info from GetPath + + +void extern InitDesktop(MBarDef *menubar,int initmouse); +void extern DeskEventLoop(void (*UserRoutine)(void),void (*ConstantRoutine)(void)); +void extern ClearScreen(void); +void extern RedrawDesktop(void); +void extern SaveBackground(int x,int y,int w,int h); +void extern RestoreBackground(void); +int extern DoDialog(DialogDef *TheDialog); +void extern ErrDialog(char *string,char *bstring); +void extern DrawBorder(int x,int y,int w,int h,int b); +int extern CheckButtons(DialogDef *TheDialog); +int extern CheckButtonsRet(DialogDef *TheDialog); +void extern DrawDialog(DialogDef *TheDialog,int saveback); +void extern GetButtonXY(DialogDef *TheDialog,int button,unsigned *x,unsigned *y); +void extern GetDialogXY(DialogDef *TheDialog,unsigned *x,unsigned *y); +int extern CheckList(int x,int y,int w,int h,void (*oncode)(),void (*offcode)(),int blink); +int extern Message(char *mstring); + +// +// RETURNS 0=OK,-1=NO FILES MATCH FILTER,-2=CANCELED +// +extern char NameList[MAXFDNAMES][13]; +int GetPath(char *string,char *filter,char *path); +int GetList(char *string,int numnames); + +static void FDon(int x,int y,int w); +static void FDoff(int x,int y,int w); +static void CancelOn(int x,int y); +static void CancelOff(int x,int y); diff --git a/16/ted5/README.TXT b/16/ted5/README.TXT new file mode 100755 index 00000000..72a71031 --- /dev/null +++ b/16/ted5/README.TXT @@ -0,0 +1,13 @@ +Ted 5.0 +======= + +The Ted source code needs to be compiled with Borland C/C++ 3.1. It will +probably compile with 4.0 but there are a few OBJ's that are linked in and +not built (the vgapalette, the tedfont etc.). + +This code was written by John Romero of Id Software Inc. A screen blanker +was added and a scrolling bug was fixed by Mark Dochtermann of Apogee +Software Ltd. + +Do not contact Apogee or id regarding any questions on this software. It +is provided "AS IS" with no warranty. diff --git a/16/ted5/README.md b/16/ted5/README.md new file mode 100755 index 00000000..1973000c --- /dev/null +++ b/16/ted5/README.md @@ -0,0 +1,2 @@ +TED5 +==== diff --git a/16/ted5/T.BAT b/16/ted5/T.BAT new file mode 100755 index 00000000..dfa9dc84 --- /dev/null +++ b/16/ted5/T.BAT @@ -0,0 +1,4 @@ +cd test +td386 ..\ted5 +cd .. +bcx diff --git a/16/ted5/TDCONFIG.TD b/16/ted5/TDCONFIG.TD new file mode 100755 index 00000000..c2d4161e Binary files /dev/null and b/16/ted5/TDCONFIG.TD differ diff --git a/16/ted5/TED.NSC b/16/ted5/TED.NSC new file mode 100755 index 00000000..117c3c24 --- /dev/null +++ b/16/ted5/TED.NSC @@ -0,0 +1,7 @@ +start chars + +load chars +grab 128 + +save ted +. \ No newline at end of file diff --git a/16/ted5/TED5-1.C b/16/ted5/TED5-1.C new file mode 100755 index 00000000..2eb31714 --- /dev/null +++ b/16/ted5/TED5-1.C @@ -0,0 +1,2089 @@ +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +// +// TED5-1 +// +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +#include "ted5.h" +#pragma hdrstop + +void InputMap(char *lvlname,unsigned *levelw,unsigned *levelh,int exitok); +void MNameOn(int x,int y,int i); +void MNameOff(int x,int y,int i); +void DnarOn(int x,int y); +void DnarOff(int x,int y); +void UparOn(int x,int y); +void UparOff(int x,int y); +void ExitOn(int x,int y); +void ExitOff(int x,int y); +void TInfoNon(int x,int y,int b); +void TInfoNoff(int x,int y,int b); +void TInfoMNon(int x,int y,int b); +void TInfoMNoff(int x,int y,int b); +void TIDoneOn(int x,int y); +void TIDoneOff(int x,int y); + + +//////////////////////////////////////////////////// +// +// SAVE the current map +// +//////////////////////////////////////////////////// +void SaveMap(int delmap) +{ + memptr block; + long fsize,size,nsize,change; + MapHeaderStr TempHeader; + int i,XMStemp; + char string[100],TEDid[]=IDSTRING; + + + + RemoveUndoBuffers(); + if (delmap) + { + LoadFile(mapname,(char huge *)&TempHeader, + MapFileHeader->dataoffsets[whichmap],sizeof(MapHeaderStr)); + strcpy(string,"Deleting Map, '"); + strcat(string,TempHeader.name); + } + else + { + strcpy(string,"Saving Map, '"); + strcat(string,MapHeader.name); + } + + strcat(string,"'."); + ErrDialog(string,""); + + + BackupFile(mapheadname); + BackupFile(SM_loadname); + + + if (delmap || DirtyFlag) + { + // + // SAVE MAP FILE HEADER + // + if (delmap) + MapFileHeader->dataoffsets[whichmap]=-1; + + SaveFile(mapheadname,MK_FP(MapFileHeader,0),0,sizeof(MapFileHeaderStr)); + fsize=sizeof(MapFileHeaderStr); + + // + // COMPRESS & SAVE TILEINFOS + // + MMAllocate(&block,tilenum); + for (i=0;itileinfooff[i]=fsize; + nsize=RLEBCompress(MK_FP(Tinfo[i],0),tilenum,MK_FP(block,0),MapFileHeader->RLEWtag); + MapFileHeader->tileinfolen[i]=nsize; + SaveFile(mapheadname,MK_FP(block,0),fsize,nsize); + fsize+=nsize; + } + MMFreePtr(&block); + + MMAllocate(&block,tilemnum); + for (i=0;itileinfomoff[i]=fsize; + nsize=RLEBCompress(MK_FP(TMinfo[i],0),tilemnum,MK_FP(block,0),MapFileHeader->RLEWtag); + MapFileHeader->tileinfomlen[i]=nsize; + SaveFile(mapheadname,MK_FP(block,0),fsize,nsize); + fsize+=nsize; + } + MMFreePtr(&block); + + MapFileHeader->oldtilenum=tilenum; + MapFileHeader->oldtilemnum=tilemnum; + + SaveFile(mapheadname,MK_FP(MapFileHeader,2),2,sizeof(MapFileHeaderStr)-2); + // + // SAVE ALREADY COMPRESSED MAPS + // + + // + // IF MAPS ARE IN XMS ALREADY, ALLOCATE A NEW BUFFER + // TO SHUFFLE ALREADY-COMPRESSED MAPS INTO + // + if (XMSmaps) + { + int planes; + long len=filelen(SM_loadname); + + + planes=(MapFileHeader->maptype&BPLANE>0)+ + (MapFileHeader->maptype&FPLANE>0)+ + (MapFileHeader->maptype&IPLANE>0); + len+=2L*mapwidth*mapheight*planes; + + if (1024L*XMSTotalFree()dataoffsets[i]==-1 || i==whichmap) + continue; + + oldoff=MapFileHeader->dataoffsets[i]; + + if (XMSmaps) + XMSmove(XMSmaps,oldoff,0,(long)&TempHeader,sizeof(MapHeaderStr)); + else + LoadFile(SM_loadname,(char huge *)&TempHeader,oldoff,sizeof(MapHeaderStr)); + + strcpy(TempHeader.name,MapNames[i]); + MapFileHeader->dataoffsets[i]=fsize; + size=TempHeader.mapbkgndlen+TempHeader.mapfrgndlen+TempHeader.mapinfolen; + change=TempHeader.mapbkgndpl-fsize-sizeof(MapHeaderStr); + TempHeader.mapbkgndpl-=change; + TempHeader.mapfrgndpl-=change; + TempHeader.mapinfopl-=change; + + if (XMSmaps) + XMSmove(0,(long)&TempHeader,XMStemp,fsize,sizeof(MapHeaderStr)); + else + SaveFile(SM_name,(char huge *)&TempHeader,fsize,sizeof(MapHeaderStr)); + fsize+=sizeof(MapHeaderStr); + + if (XMSmaps) + { + XMSmove(XMSmaps,oldoff+sizeof(MapHeaderStr),XMStemp,fsize,size); + fsize+=size; + XMSmove(0,(long)"!ID!",XMStemp,fsize,4); + fsize+=4; + } + else + { + MMAllocate(&block,size); + LoadFile(SM_loadname,MK_FP(block,0),oldoff+sizeof(MapHeaderStr),size); + SaveFile(SM_name,MK_FP(block,0),fsize,size); + fsize+=size; + SaveFile(SM_name,"!ID!",fsize,4); + fsize+=4; + MMFreePtr(&block); + } + } + + // + // SAVE CURRENT MAP AT END OF FILE + // + if (!delmap) + { + MapFileHeader->dataoffsets[whichmap]=fsize; + MapFileHeader->datalengths[whichmap]=sizeof(MapHeaderStr); + if (XMSmaps) + XMSmove(0,(long)&MapHeader,XMStemp,fsize,sizeof(MapHeaderStr)); + else + SaveFile(SM_name,(char huge *)&MapHeader,fsize,sizeof(MapHeaderStr)); + fsize+=sizeof(MapHeaderStr); + + size=MapHeader.width*MapHeader.height*sizeof(int); + MMAllocate(&block,size); + if (MapFileHeader->maptype & BPLANE) + { + MapHeader.mapbkgndpl=fsize; + nsize=RLEWCompress(MK_FP(MapBkgnd,0),size,MK_FP(block,0),MapFileHeader->RLEWtag); + + MapHeader.mapbkgndlen=nsize+2; + + if (XMSmaps) + XMSmove(0,(long)&size,XMStemp,fsize,2); + else + SaveFile(SM_name,(char huge *)&size,fsize,2); + + fsize+=2; + + if (XMSmaps) + XMSmove(0,(long)MK_FP(block,0),XMStemp,fsize,nsize); + else + SaveFile(SM_name,MK_FP(block,0),fsize,nsize); + + fsize+=nsize; + } + else + MapHeader.mapbkgndlen=0; + + if (MapFileHeader->maptype & FPLANE) + { + MapHeader.mapfrgndpl=fsize; + nsize=RLEWCompress(MK_FP(MapFrgnd,0),size,MK_FP(block,0),MapFileHeader->RLEWtag); + + MapHeader.mapfrgndlen=nsize+2; + + if (XMSmaps) + XMSmove(0,(long)&size,XMStemp,fsize,2); + else + SaveFile(SM_name,(char huge *)&size,fsize,2); + + fsize+=2; + + if (XMSmaps) + XMSmove(0,(long)MK_FP(block,0),XMStemp,fsize,nsize); + else + SaveFile(SM_name,MK_FP(block,0),fsize,nsize); + + fsize+=nsize; + } + else + MapHeader.mapfrgndlen=0; + + if (MapFileHeader->maptype & IPLANE) + { + MapHeader.mapinfopl=fsize; + nsize=RLEWCompress(MK_FP(MapInfoPl,0),size,MK_FP(block,0),MapFileHeader->RLEWtag); + + MapHeader.mapinfolen=nsize+2; + + if (XMSmaps) + XMSmove(0,(long)&size,XMStemp,fsize,2); + else + SaveFile(SM_name,(char huge *)&size,fsize,2); + + fsize+=2; + + if (XMSmaps) + XMSmove(0,(long)MK_FP(block,0),XMStemp,fsize,nsize); + else + SaveFile(SM_name,MK_FP(block,0),fsize,nsize); + + fsize+=nsize; + } + else + MapHeader.mapinfolen=0; + + if (XMSmaps) + XMSmove(0,(long)"!ID!",XMStemp,fsize,4); + else + SaveFile(SM_name,"!ID!",fsize,4); + + fsize+=4; + + MMFreePtr(&block); + + // RE-SAVE HEADER + if (XMSmaps) + XMSmove(0,(long)&MapHeader,XMStemp, + MapFileHeader->dataoffsets[whichmap],sizeof(MapHeaderStr)); + else + SaveFile(SM_name,(char huge *)&MapHeader, + MapFileHeader->dataoffsets[whichmap],sizeof(MapHeaderStr)); + + // + // RE-SAVE FILE HEADER + // NOTE: The "2" is so SaveFile doesn't truncate the fucking file! + // + SaveFile(mapheadname,MK_FP(MapFileHeader,2),2,sizeof(MapFileHeaderStr)-2); + } + + if (XMSmaps) + { + #define BCSIZE 0x4000 + long size=fsize,clen,coff; + + // + // SAVE ENTIRE MAPFILE IN XMS TO DISK! + // + XMSFreeMem(XMSmaps); + XMSmaps=XMStemp; + + MMAllocate(&block,BCSIZE); + coff=0; + do + { + clen=BCSIZE; + if (size0); + + MMFreePtr(&block); + } + else + { + unlink(SM_loadname); + rename(SM_name,SM_loadname); + } + } + + AllocateUndoBuffers(); + UndoRegion.x=-1; + SaveUndo(0,0,mapwidth,mapheight); + RestoreBackground(); +} + + + + + + +//////////////////////////////////////////////////// +// +// BACKUP FILES! +// +//////////////////////////////////////////////////// +void BackupFile(char *filename) +{ + #define BUFSIZE 0x8000 + memptr block; + long size,clen,coff; + int i; + char backupname[14]; + + + size = filelen(filename); + if (!size) + return; + + strcpy(backupname,filename); + for (i=strlen(backupname);i;i--) + if (backupname[i] == '.') + backupname[i+1] = 0; + strcat(backupname,"BAK"); + + MMAllocate(&block,BUFSIZE); + coff=0; + do + { + clen=BUFSIZE; + if (size0); + + MMFreePtr(&block); +} + + +//////////////////////////////////////////////////// +// +// SAVE OUT TEDINFO FILE +// +//////////////////////////////////////////////////// +void SaveTEDInfo(void) +{ + BackupFile(infoname); + + TEDInfo->oscrx=xbase; + TEDInfo->oscry=ybase; + _fstrcpy(TEDInfo->launchname,(char far *)launchname); + SaveFile(infoname,MK_FP(TEDInfo,0),0,sizeof(InfoStruct)); +} + + +//////////////////////////////////////////////////// +// +// WRITE OUT THE OUTPUT HEADER FILE +// +//////////////////////////////////////////////////// +char * _nfstrcpy(char *dest,char far *source) +{ + int i; + + for (i=0;i<_fstrlen(source);i++) + *(dest+i)=*(source+i); + + return dest; +} + + +void SaveOutputHeader(void) +{ + char outhead[14]="MAPHEAD.",dot_h[14]="MAPS",t[15],tm[15],temp[40],temp1[40]; + FILE *fp; + OutputHeadStr OutHead; + int i,Thelast; + long fsize; + + + ErrDialog("Saving header...",""); + + strcat(outhead,ext); + + BackupFile(outhead); + + memset(&OutHead,0,sizeof(OutputHeadStr)); + + OutHead.RLEWtag=MapFileHeader->RLEWtag; + + for (i=0;i<100;i++) + OutHead.dataoffsets[i]=MapFileHeader->dataoffsets[i]; + + fsize=sizeof(OutputHeadStr); + SaveFile(outhead,(char huge *)&OutHead,0,fsize); + for (i=0;i=0;i--) + if (MapFileHeader->dataoffsets[i]>=0) + { + Thelast=i; + break; + } + + + fprintf(fp,"\n"); + fprintf(fp,"//\n"); + fprintf(fp,"// Map Names\n"); + fprintf(fp,"//\n"); + + fprintf(fp,"typedef enum {\n"); + for (i=0;i<100;i++) + if (MapFileHeader->dataoffsets[i]>=0) + { + char temp[28]; + int j; + + + strcpy(temp,&MapNames[i][0]); + strcat(temp,"_MAP"); + + for (j=0;jtnames[0])), + sizeof(OutputHeadStr)); + for (i=1;itnames[i])), + strupr(_nfstrcpy(temp1,MapFileHeader->tnames[i-1])), + t); + } + } + + if (numtmplanes) + { + fprintf(fp,"\n"); + fprintf(fp,"//\n"); + fprintf(fp,"// TILEINFOM offsets\n"); + fprintf(fp,"//\n"); + + memset(temp,0,sizeof(temp)); + memset(temp1,0,sizeof(temp1)); + fprintf(fp,"#define %s\x9\x9(%s+%s)\n", + strupr(_nfstrcpy(temp,MapFileHeader->tmnames[0])), + strupr(_nfstrcpy(temp1,MapFileHeader->tnames[numtplanes-1])), + t); + for (i=1;itmnames[i])), + strupr(_nfstrcpy(temp1,MapFileHeader->tmnames[i-1])), + tm); + } + } + + fclose(fp); + writeH=0; + RestoreBackground(); + } + +} + + +//////////////////////////////////////////////////// +// +// Initialize the TILEINFO/M arrays +// +//////////////////////////////////////////////////// +btype TIb[]={{" ",1,2,1}, + {" ",1,6,1}, + {" Done ",12,9,2}}; +DialogDef TId={" How many TILEINFO planes?\n\n\n\n" + " How many TILEINFOM planes?", + 27,11,3,&TIb[0],NULL}; + +void InitTileinfo(void) +{ + unsigned temp,which,oktoexit=0,ox,oy,i,j; + long fsize; + + numtplanes=numtmplanes=0; + DrawDialog(&TId,1); + GetButtonXY(&TId,0,&sx,&sy); + printint(numtplanes); + if (MapFileHeader->maptype&FPLANE) + { + GetButtonXY(&TId,1,&sx,&sy); + printint(numtmplanes); + } + do + { + which=CheckButtons(&TId); + switch(which) + { + case 1: + MouseHide(); + GetButtonXY(&TId,0,&sx,&sy); + ox=sx; + oy=sy; + print(TIb[0].text); + sx=ox; + sy=oy; + if ((temp=inputint(9))!=ESCOUT && temp<11 && temp) + numtplanes=temp; + sx=ox; + sy=oy; + print(TIb[0].text); + sx=ox; + sy=oy; + printint(numtplanes); + MouseShow(); + + case 2: + MouseHide(); + GetButtonXY(&TId,1,&sx,&sy); + ox=sx; + oy=sy; + print(TIb[1].text); + sx=ox; + sy=oy; + if (MapFileHeader->maptype&FPLANE) + { + if ((temp=inputint(9))!=ESCOUT && temp<11 && temp) + numtmplanes=temp; + sx=ox; + sy=oy; + print(TIb[1].text); + sx=ox; + sy=oy; + printint(numtmplanes); + } + MouseShow(); + break; + + case 3: + MouseHide(); + oktoexit=1; + GetButtonXY(&TId,2,&sx,&sy); + print(TIb[2].text); + MouseShow(); + } + + } while(!oktoexit); + + RestoreBackground(); + + // + // allocate arrays + // + fsize=sizeof(MapFileHeaderStr); + + for (i=0;itileinfooff[i]=fsize; // THIS DOESN'T REALLY MATTER + fsize+=tilenum; // ....YET! + for(j=0;jtileinfomoff[i]=fsize; + fsize+=tilemnum; + for(j=0;jnumtplanes=numtplanes; + MapFileHeader->numtmplanes=numtmplanes; + + MapFileHeader->oldtilenum=tilenum; + MapFileHeader->oldtilemnum=tilemnum; + writeH=1; +} + + +//////////////////////////////////////////////////// +// +// Item - Edit the TILEINFO names +// +//////////////////////////////////////////////////// +btype TINb={" Done ",8,15,1}; +DialogDef TINd={" Enter plane names:\n" + " TILEINFO TILEINFOM", + 22,17,1,&TINb,NULL}; + +void Item_EditTinfoNames(void) +{ + unsigned ox,oy,i,oktoexit=0; + int which; + + MouseHide(); + DrawDialog(&TINd,1); + GetDialogXY(&TINd,&sx,&sy); + ox=sx; + oy=sy; + DrawBorder(sx,sy+2,10,11,1); + sx=ox; + sy=oy; + DrawBorder(sx+11,sy+2,10,11,1); + + for (i=0;i<10;i++) + { + sx=ox+1; + sy=oy+i+3; + fprint(MapFileHeader->tnames[i]); + sx=ox+12; + sy=oy+i+3; + fprint(MapFileHeader->tmnames[i]); + } + MouseShow(); + + do + { + if ((which=CheckList(ox+1,oy+3,8,numtplanes,TInfoNon,TInfoNoff,0))>=0) + { + char temp[8]; + + MouseHide(); +redo: + sx=ox+1; + sy=oy+which+3; + print(" "); + sx=ox+1; + sy=oy+which+3; + if (input(temp,7)) + { + for(i=0;i<8;i++) + MapFileHeader->tnames[which][i]=temp[i]; + which++; + writeH=DirtyFlag=1; + if (which=0) + { + char temp[8]; + + MouseHide(); +redo1: + sx=ox+12; + sy=oy+which+3; + print(" "); + sx=ox+12; + sy=oy+which+3; + if (input(temp,7)) + { + for(i=0;i<8;i++) + MapFileHeader->tmnames[which][i]=temp[i]; + which++; + writeH=DirtyFlag=1; + if (whichtnames[b][0]) + print(" "); + else + fprint(MapFileHeader->tnames[b]); + xormask=0; +} +void TInfoNoff(int x,int y,int b) +{ + sx=x; + sy=y; + if (!MapFileHeader->tnames[b][0]) + print(" "); + else + fprint(MapFileHeader->tnames[b]); +} +void TInfoMNon(int x,int y,int b) +{ + xormask=1; + sx=x; + sy=y; + if (!MapFileHeader->tmnames[b][0]) + print(" "); + else + fprint(MapFileHeader->tmnames[b]); + xormask=0; +} +void TInfoMNoff(int x,int y,int b) +{ + sx=x; + sy=y; + if (!MapFileHeader->tmnames[b][0]) + print(" "); + else + fprint(MapFileHeader->tmnames[b]); +} +void TIDoneOn(int x,int y) +{ + xormask=1; + sx=x; + sy=y; + print(" Done "); + xormask=0; +} +void TIDoneOff(int x,int y) +{ + sx=x; + sy=y; + print(" Done "); +} + +//////////////////////////////////////////////////// +// +// Create a new map! +// +//////////////////////////////////////////////////// +void CreateMap(int exitok) +{ + unsigned lwidth,lheight,i; + int mapnum; + long size; + char lname[16]; + + if ((mapnum=SelectMap(exitok,NOTCREATED,"TO CREATE"))==-1) + return; + + InputMap(lname,&lwidth,&lheight,exitok); + if (!lname[0]) + return; + + RemoveUndoBuffers(); + SaveCutBuffers(); + + if (MapBkgnd) + { + MMFreePtr((memptr *)&MapBkgnd); + MMFreePtr((memptr *)&CutBkgnd); + } + if (MapFrgnd) + { + MMFreePtr((memptr *)&MapFrgnd); + MMFreePtr((memptr *)&CutFrgnd); + } + if (MapInfoPl) + { + MMFreePtr((memptr *)&MapInfoPl); + MMFreePtr((memptr *)&CutInfoPl); + } + + size=2L*(lwidth*lheight); + + if (MapFileHeader->maptype&BPLANE) + { + MMAllocate((memptr *)&MapBkgnd,size); + MMAllocate((memptr *)&CutBkgnd,size); + for(i=0;imaptype&FPLANE) + { + MMAllocate((memptr *)&MapFrgnd,size); + MMAllocate((memptr *)&CutFrgnd,size); + for(i=0;imaptype&IPLANE) + { + MMAllocate((memptr *)&MapInfoPl,size); + MMAllocate((memptr *)&CutInfoPl,size); + for(i=0;idataoffsets[mapnum],0,(long)&MapHeader,sizeof(MapHeaderStr)); + else + LoadFile(mapname,(char huge *)&MapHeader,MapFileHeader->dataoffsets[mapnum],sizeof(MapHeaderStr)); + + // + // LOAD & DECOMPRESS MAP PLANES + // + if (MapFileHeader->maptype & BPLANE) + { + if (XMSmaps) + XMSmove(XMSmaps,MapHeader.mapbkgndpl,0,(long)&size,2); + else + LoadFile(mapname,(char huge *)&size,MapHeader.mapbkgndpl,2); + + MMAllocate((memptr *)&MapBkgnd,size); + MMAllocate((memptr *)&CutBkgnd,size); + csize=MapHeader.mapbkgndlen-2; + MMAllocate(&block,csize); + + if (XMSmaps) + XMSmove(XMSmaps,MapHeader.mapbkgndpl+2,0,(long)MK_FP(block,0),csize); + else + LoadFile(mapname,MK_FP(block,0),MapHeader.mapbkgndpl+2,csize); + + RLEWExpand(MK_FP(block,0),MK_FP(MapBkgnd,0),size,MapFileHeader->RLEWtag); + MMFreePtr(&block); + } + if (MapFileHeader->maptype & FPLANE) + { + if (XMSmaps) + XMSmove(XMSmaps,MapHeader.mapfrgndpl,0,(long)&size,2); + else + LoadFile(mapname,(char huge *)&size,MapHeader.mapfrgndpl,2); + + MMAllocate((memptr *)&MapFrgnd,size); + MMAllocate((memptr *)&CutFrgnd,size); + csize=MapHeader.mapfrgndlen-2; + MMAllocate(&block,csize); + + if (XMSmaps) + XMSmove(XMSmaps,MapHeader.mapfrgndpl+2,0,(long)MK_FP(block,0),csize); + else + LoadFile(mapname,MK_FP(block,0),MapHeader.mapfrgndpl+2,csize); + + RLEWExpand(MK_FP(block,0),MK_FP(MapFrgnd,0),size,MapFileHeader->RLEWtag); + MMFreePtr(&block); + } + if (MapFileHeader->maptype & IPLANE) + { + if (XMSmaps) + XMSmove(XMSmaps,MapHeader.mapinfopl,0,(long)&size,2); + else + LoadFile(mapname,(char huge *)&size,MapHeader.mapinfopl,2); + + MMAllocate((memptr *)&MapInfoPl,size); + MMAllocate((memptr *)&CutInfoPl,size); + csize=MapHeader.mapinfolen-2; + MMAllocate(&block,csize); + + if (XMSmaps) + XMSmove(XMSmaps,MapHeader.mapinfopl+2,0,(long)MK_FP(block,0),csize); + else + LoadFile(mapname,MK_FP(block,0),MapHeader.mapinfopl+2,csize); + + RLEWExpand(MK_FP(block,0),MK_FP(MapInfoPl,0),size,MapFileHeader->RLEWtag); + MMFreePtr(&block); + } + + mapwidth=MapHeader.width; + mapheight=MapHeader.height; + strcpy(MapNames[mapnum],MapHeader.name); + + AllocateUndoBuffers(); + UndoRegion.x=-1; + SaveUndo(0,0,mapwidth,mapheight); + RestoreCutBuffers(); + + SelectMode=PasteMode=xbase=ybase=0; + SelX1=SelX2=SelY1=SelY2=-1; +} + + +//////////////////////////////////////////////////// +// +// Select a new map! +// +//////////////////////////////////////////////////// +btype ClvlB[]={{"\xb",28,5,1}, + {"\xc",28,14,1}, + {" Exit ",12,17,1}}; +DialogDef ClvlD={" SELECT MAP", + 30,19,2,&ClvlB[0],NULL}; +int smbase=0; + +int SelectMap(int exitok,int createflg,char *title) +{ + MapHeaderStr TempMapHeader; + unsigned ox,oy,i,dx,dy; + int select=-1,redraw; + + if (exitok) + { + ClvlD.numbuttons=3; + ClvlD.height=19; + } + else + { + ClvlD.numbuttons=2; + ClvlD.height=16; + } + + DrawDialog(&ClvlD,1); + GetDialogXY(&ClvlD,&dx,&dy); + sy=dy+1; + sx=screencenterx-strlen(title)/2; + print(title); + + dx+=3; + dy+=5; + + MouseHide(); + GetButtonXY(&ClvlD,0,&sx,&sy); + sx-=27; + sy-=2; + print("Map Name\n"); + ox=sx+1; + oy=sy+1; + DrawBorder(sx,sy,26,11,2); + MouseShow(); + + + do + { + int mx,my; + + // + // DRAW MAP NAMES + // + MouseHide(); + for (i=0;i<10;i++) + { + sy=oy+i; + sx=ox; + if (i+smbase==whichmap) + print("*"); + else + print(" "); + + printint(i+smbase); + print(" "); + sx=ox+5; + MNameOff(sx,sy,i); + } + MouseShow(); + redraw=0; + + do + { + GetButtonXY(&ClvlD,0,&(unsigned)mx,&(unsigned)my); + if (!CheckList(mx,my,1,1,UparOn,UparOff,0) || keydown[0x48]) + { + MouseHide(); + GetButtonXY(&ClvlD,0,&sx,&sy); + print(ClvlB[0].text); + + smbase-=10; + if (smbase<0) + smbase=0; + redraw=1; + MouseShow(); + while(keydown[0x48]); + continue; + } + + GetButtonXY(&ClvlD,1,&(unsigned)mx,&(unsigned)my); + if (!CheckList(mx,my,1,1,DnarOn,DnarOff,0) || keydown[0x50]) + { + MouseHide(); + GetButtonXY(&ClvlD,1,&sx,&sy); + print(ClvlB[1].text); + + smbase+=10; + if (smbase>90) + smbase=90; + redraw=1; + MouseShow(); + while(keydown[0x50]); + continue; + } + + if (exitok) + { + GetButtonXY(&ClvlD,2,&(unsigned)mx,&(unsigned)my); + if (!CheckList(mx,my,6,1,ExitOn,ExitOff,0)) + { + RestoreBackground(); + return -1; + } + } + + if (exitok && keydown[1]) + { + RestoreBackground(); + return -1; + } + + select=CheckList(ox+5,oy,20,10,MNameOn,MNameOff,0); + if (select>=0) + { + MouseHide(); + sy=select+oy; + sx=ox+5; + MNameOff(sx,sy,select); + MouseShow(); + if ((MapFileHeader->dataoffsets[select+smbase]!=-1 && createflg==NOTCREATED)|| + (MapFileHeader->dataoffsets[select+smbase]==-1 && createflg==CREATED)) + select=-1; + } + + } while(!redraw && select<0); + } while(select<0); + + RestoreBackground(); + return select+smbase; +} + +// +// Print arrows +// +void DnarOn(int x,int y) +{ + sx=x; + sy=y; + xormask=1; + drawchar(sx,sy,0xc); + xormask=0; +} +void DnarOff(int x,int y) +{ + sx=x; + sy=y; + drawchar(sx,sy,0xc); +} +void UparOn(int x,int y) +{ + sx=x; + sy=y; + xormask=1; + drawchar(sx,sy,0xb); + xormask=0; +} +void UparOff(int x,int y) +{ + sx=x; + sy=y; + drawchar(sx,sy,0xb); +} +void ExitOn(int x,int y) +{ + sx=x; + sy=y; + xormask=1; + print(" Exit "); + xormask=0; +} +void ExitOff(int x,int y) +{ + sx=x; + sy=y; + print(" Exit "); +} + +// +// Highlight Map Name +// +void MNameOn(int x,int y,int i) +{ + xormask=1; + MNameOff(x,y,i); + xormask=0; +} + +// +// De-Highlight Map Name +// +void MNameOff(int x,int y,int i) +{ + MapHeaderStr TempMapHeader; + + sx=x; + sy=y; + if (MapFileHeader->dataoffsets[i+smbase]!=-1) + { + print(" "); + sx=x; + print(MapNames[i+smbase]); + } + else + print("--not created yet--"); +} + + + +//////////////////////////////////////////////////// +// +// Pick more planes for the map set +// +//////////////////////////////////////////////////// +btype PickPlaneb[]={{"X",1,3,1}, + {"X",1,6,1}, + {" Done ",1,9,2}}; +DialogDef PickPlaneD={"Which other planes\n" + "to enable?\n\n" + " Foreground\n\n\n" + " Information" + ,18,11,3,&PickPlaneb[0],NULL}; + +int PickMorePlanes(void) +{ + int which; + char planes=7; // 1=bkgnd/2=frgnd/4=info + + DrawDialog(&PickPlaneD,1); + do + { + which=CheckButtons(&PickPlaneD); + switch(which) + { + case 0: + RestoreBackground(); + return 1; + case 1: + GetButtonXY(&PickPlaneD,0,&sx,&sy); + planes^=2; + MouseHide(); + if (planes&2) + print("X"); + else + print(" "); + MouseShow(); + break; + case 2: + GetButtonXY(&PickPlaneD,1,&sx,&sy); + planes^=4; + MouseHide(); + if (planes&4) + print("X"); + else + print(" "); + MouseShow(); + } + } while(which!=3); + + RestoreBackground(); + MapFileHeader->maptype=planes; + return 0; +} + +//////////////////////////////////////////////////// +// +// Get map dimensions +// +//////////////////////////////////////////////////// +btype LvlSpecb[]={{" ",1,3,1}, + {" ",1,7,1}, + {" ",1,11,1}, + {" Done ",7,14,2}}; +DialogDef LvlSpec={" MAP DIMENSIONS\n" + " Map Name:\n\n\n\n" + " Map Width:\n\n\n\n" + " Map Height:\n", + 20,16,4,&LvlSpecb[0],NULL}; + +void InputMap(char *lvlname,unsigned *levelw,unsigned *levelh,int exitok) +{ + unsigned butn,ok=0,nameok=0,widok=0,heightok=0, + ox,oy,width=0,height=0,oldwidth=0,oldheight=0; + char oldname[16]="",name[16]=""; + + MouseHide(); + DrawDialog(&LvlSpec,1); + GetButtonXY(&LvlSpec,1,&sx,&sy); + printint(width); + GetButtonXY(&LvlSpec,2,&sx,&sy); + printint(height); + MouseShow(); + + // + // START INPUT IMMEDIATELY + // + butn=1; + goto firsttime; + +#pragma warn -rch + while (!ok) +#pragma warn +rch + { + butn=CheckButtons(&LvlSpec); + if (!butn) + if (exitok) + { + RestoreBackground(); + lvlname[0]=0; + return; + } + else + continue; + +firsttime: + + xormask=0; + GetButtonXY(&LvlSpec,butn-1,&sx,&sy); + MouseHide(); + ox=sx; + oy=sy; + print(LvlSpecb[butn-1].text); + sx=ox; + sy=oy; + switch(butn) + { + case 1: + name[0]=0; + if (!input(name,15)) + { + strcpy(name,oldname); + sx=ox; + sy=oy; + print(LvlSpecb[butn-1].text); + } + strcpy(oldname,name); + sx=ox; + sy=oy; + if (name[0]) + { + print(name); + nameok=1; + } + else + nameok=0; + + if (nameok) + { + butn=2; + GetButtonXY(&LvlSpec,butn-1,&sx,&sy); + ox=sx; + oy=sy; + print(LvlSpecb[butn-1].text); + sx=ox; + sy=oy; + } + else + break; + + case 2: + width=0; + if ((width=inputint(9))==ESCOUT) + { + widok=0; + width=oldwidth; + } + if (width) + widok=1; + + oldwidth=width; + sx=ox; + sy=oy; + print(LvlSpecb[butn-1].text); + sx=ox; + sy=oy; + printint(width); + if (widok) + { + butn=3; + GetButtonXY(&LvlSpec,butn-1,&sx,&sy); + ox=sx; + oy=sy; + print(LvlSpecb[butn-1].text); + sx=ox; + sy=oy; + } + else + break; + + case 3: + height=0; + if ((height=inputint(9))==ESCOUT) + { + heightok=0; + height=oldheight; + } + if (height) + heightok=1; + + oldheight=height; + sx=ox; + sy=oy; + print(LvlSpecb[butn-1].text); + sx=ox; + sy=oy; + printint(height); + break; + + case 4: + if (2L*height*width>0x10000) // TOO BIG! TRIM IT! + { + errsound(); + errsound(); + widok=heightok=0; + break; + } + if (nameok && widok && heightok) + ok=1; + } + + MouseShow(); + } + + RestoreBackground(); + + *levelw=width; + *levelh=height; + strcpy(lvlname,name); +} + +//////////////////////////////////////////////////// +// +// Item - Input INFOPLANE value +// +//////////////////////////////////////////////////// +btype EnterIVb={" ",1,3,1}; +DialogDef EnterIV={"Enter a value for\nthe INFO plane:\n\n\n",18,5,1,&EnterIVb,NULL}; + +void Item_InputInfoplane(void) +{ + unsigned val; + + + if (TsearchMode || BfillMode || FillMode || PasteMode || SelectMode) + return; + + clearkeys(); + DrawDialog(&EnterIV,1); + MouseHide(); + GetButtonXY(&EnterIV,0,&sx,&sy); + if ((val=inputint(9))!=ESCOUT) + whichi=val+tilenum; + RestoreBackground(); + DrawInfoBar(); + MouseShow(); +} + +//////////////////////////////////////////////////// +// +// Item - Select Tile +// +//////////////////////////////////////////////////// +void Item_SelectTile(void) +{ + SelectTiles(0); +} + +//////////////////////////////////////////////////// +// +// Item - Block Fill +// +//////////////////////////////////////////////////// +void Item_BlockFill(void) +{ + ZeroModes(); + BfillMode=1; + DrawInfoBar(); +} + +// +// DO THE ACTUAL BLOCK FILL +// +void DoBlockFill(void) +{ + unsigned loc,i,j,ctrl=0,newt,newm,newi,tton,tmon,tion,from; + + if (keydown[0x1d]) + ctrl++; + + MouseHide(); + + CopyUndoRegion(); + UndoRegion.x=SelX1; + UndoRegion.y=SelY1; + UndoRegion.w=SelX2-SelX1+1; + UndoRegion.h=SelY2-SelY1+1; + + if (ctrl) + { + for (j=SelY1;j<=SelY2;j++) + for (i=SelX1;i<=SelX2;i++) + { + loc=j*mapwidth+i; + from=(TileCopy.y+((j-SelY1)%TileCopy.h))*mapwidth+ + TileCopy.x+((i-SelX1)%TileCopy.w); + + switch(TileCopy.MapOrTileSelect) + { + case 0: // COPY BUFFER + tton=TileCopy.PlanesCopied&BPLANE; + tmon=TileCopy.PlanesCopied&FPLANE; + tion=TileCopy.PlanesCopied&IPLANE; + + newt=CutBkgnd[from]; + newm=CutFrgnd[from]; + newi=CutInfoPl[from]; + + break; + case 1: // TILES + tton=1; + tmon=tion=0; + + newt=((j%TileCopy.h)+TileCopy.y)*selectcols+ + TileCopy.x+(i%TileCopy.w); + if (XMSlookup[newt]<0) + tton=0; + break; + case 2: // MASKED + tton=tion=0; + tmon=1; + + newm=((j%TileCopy.h)+TileCopy.y)*selectcols+ + TileCopy.x+(i%TileCopy.w)+tilenum+maxiconrows*selectcols; + if (XMSlookup[newm]<0) + tmon=0; + else + newm-=tilenum; + } + + if (tton) + *(MapBkgnd+loc)=newt; + if (tmon) + *(MapFrgnd+loc)=newm; + if (tion) + *(MapInfoPl+loc)=newi; + + if (j>=ybase && j=xbase && i=ybase && j=xbase && imaptype&BPLANE) + XMSundoB=XMSAllocate(size); + if (MapFileHeader->maptype&FPLANE) + XMSundoF=XMSAllocate(size); + if (MapFileHeader->maptype&IPLANE) + XMSundoI=XMSAllocate(size); +} + + +//////////////////////////////////////////////////// +// +// Save Undo buffers +// +//////////////////////////////////////////////////// +void SaveUndo(int x,int y,int w,int h) +{ + unsigned hsize=w*2,j; + + for (j=y;jmaptype&BPLANE) + XMSmove(0,(long)MK_FP(MapBkgnd,off),XMSundoB,off,hsize); + if (MapFileHeader->maptype&FPLANE) + XMSmove(0,(long)MK_FP(MapFrgnd,off),XMSundoF,off,hsize); + if (MapFileHeader->maptype&IPLANE) + XMSmove(0,(long)MK_FP(MapInfoPl,off),XMSundoI,off,hsize); + } +} + + +//////////////////////////////////////////////////// +// +// Restore Undo buffers +// +//////////////////////////////////////////////////// +void RestoreUndo(void) +{ + long size=2L*UndoRegion.w; + unsigned j; + + sound(2000); + for (j=UndoRegion.y;jmaptype&BPLANE) + XMSmove(XMSundoB,loc,0,(long)MK_FP(MapBkgnd,loc),size); + if (MapFileHeader->maptype&FPLANE) + XMSmove(XMSundoF,loc,0,(long)MK_FP(MapFrgnd,loc),size); + if (MapFileHeader->maptype&IPLANE) + XMSmove(XMSundoI,loc,0,(long)MK_FP(MapInfoPl,loc),size); + } + + nosound(); +} + + +//////////////////////////////////////////////////// +// +// Copy the current UNDO region to the undo buffers +// +//////////////////////////////////////////////////// +void CopyUndoRegion(void) +{ + if (UndoRegion.x==-1) + return; + + SaveUndo(UndoRegion.x,UndoRegion.y,UndoRegion.w,UndoRegion.h); +} + + +//////////////////////////////////////////////////// +// +// Item - Undo +// +//////////////////////////////////////////////////// +void Item_Undo(void) +{ + if (UndoRegion.x==-1) + { + ErrDialog("You don't have anything to UNDO!"," Oh, yeah. "); + return; + } + + RestoreUndo(); + DrawMap(); +} + + +//////////////////////////////////////////////////// +// +// Item - Tile Search! +// +//////////////////////////////////////////////////// +void Item_TileSearch(void) +{ + int num=planeton+planemon+planeion; + + ZeroModes(); + if (num>1) + { + ErrDialog("TILE SEARCH will only work\n" + "with ONE active plane! Make\n" + "sure that the tile you're\n" + "searching for is selected!"," OK "); + return; + } + + TsearchMode=1; + DrawInfoBar(); + DrawMap(); +} + +//////////////////////////////////////////////////// +// +// Item - Launch +// +//////////////////////////////////////////////////// +char tempparm[40]; + +void Item_Launch(void) +{ + TempStruct LaunchInfo; + char ename[64],*envstr[15],temp[40],temp1[40],temp2[40],tiname[14]="TEDINFO.TMP",i,j; + long size; + int rottlaunch; + int startp; + unsigned mx,my; + + + rottlaunch=0; + if (!TEDInfo->launchname[0]) + { + ErrDialog("You didn't specify a launching\n" + "name on the command line? What\n" + "do I launch, Einstein? Geez!"," What a goober. "); + return; + } + + // + // Save the handles for all XMS memory so we don't + // have to re-install this shit! + // + TEDInfo->OldCgaXMS=CgaXMS; + TEDInfo->OldEgaXMS=EgaXMS; + TEDInfo->OldVgaXMS=VgaXMS; + + TEDInfo->OldCgaXMSsize=CgaXMSsize; + TEDInfo->OldEgaXMSsize=EgaXMSsize; + TEDInfo->OldVgaXMSsize=VgaXMSsize; + + size=4L*(tilenum+tilemnum); + if (CgaXMS) + { + if (1024L*XMSTotalFree()OldCgaXMS=TEDInfo->OldCgaXMSsize=0; + } + else + { + TEDInfo->CgaXMSlook=XMSAllocate(size); + XMSmove(0,(long)MK_FP(CgaXMSlookup,0),TEDInfo->CgaXMSlook,0,size); + } + } + + if (EgaXMS) + { + if (1024L*XMSTotalFree()OldEgaXMS=TEDInfo->OldEgaXMSsize=0; + } + else + { + TEDInfo->EgaXMSlook=XMSAllocate(size); + XMSmove(0,(long)MK_FP(EgaXMSlookup,0),TEDInfo->EgaXMSlook,0,size); + } + } + + if (VgaXMS) + { + if (1024L*XMSTotalFree()OldVgaXMS=TEDInfo->OldVgaXMSsize=0; + } + else + { + TEDInfo->VgaXMSlook=XMSAllocate(size); + XMSmove(0,(long)MK_FP(VgaXMSlookup,0),TEDInfo->VgaXMSlook,0,size); + } + } + + // + // SAVE CURRENT VIDEOMODE FOR LAUNCH RETURN + // + LaunchInfo.lastmode=videomode; + strcpy(LaunchInfo.ext,ext); + SaveFile(tiname,(char huge *)&LaunchInfo,0,sizeof(TempStruct)); + + // + // ICON CHANGE ON LAUNCH? + // + if (keydown[0x2A]) + { + rottlaunch=1; + startp=5; + mx=xbase+(pixelx>>(tsize+2)); + my=ybase+((pixely-8)>>(tsize+2)); + } + else + startp=3; + if (pixely>=8 && pixelypermicon + && MapFileHeader->maptype&IPLANE && !usingbat && keydown[0x1d]) + { + unsigned i,j; + + mx=xbase+(pixelx>>(tsize+2)); + my=ybase+((pixely-8)>>(tsize+2)); + + for (j=0;jpermicon) + { + MapInfoPl[j*mapwidth+i]=0; + TEDInfo->lastx=i; + TEDInfo->lasty=j; + break; + } + + MapInfoPl[my*mapwidth+mx]=TEDInfo->permicon; + DrawMap(); + DirtyFlag=1; + } + + TEDInfo->oscrx=xbase; + TEDInfo->oscry=ybase; + TEDInfo->pflags=((planeton&1)<<6)| + ((planemon&1)<<5)| + ((planeion&1)<<4)| + ((viewton&1)<<2)| + ((viewmon&1)<<1)| + (viewion&1); + + _fmemcpy((void far *)TEDInfo->parmstring,(void far *)parmstring,64); + + Item_SaveMap(); + SaveTEDInfo(); + SaveOutputHeader(); + + if (XMSmaps) + XMSFreeMem(XMSmaps); + + strcpy(temp,"Launching "); + _fstrcat((char far *)temp,(char far *)TEDInfo->launchname); + strcat(temp,"..."); + ErrDialog(temp,""); + clearkeys(); + nosound(); + MouseHide(); + + _fmemcpy((char far *)ename,(char far *)TEDInfo->launchname,14); + + envstr[0] = ename; + envstr[1] = "/TEDLEVEL"; + itoa(whichmap,temp,10); + envstr[2] = temp; + if (rottlaunch) + { + itoa(mx,temp1,10); + envstr[3] = temp1; + itoa(my,temp2,10); + envstr[4] = temp2; + } + // + // CHOP UP THE PARMSTRING FOR 'EXECV' + // + strcpy(tempparm,parmstring); + envstr[startp]=&tempparm[0]; + for(j=startp+1,i=0;imapheight && mapheight>screenh) + ybase--; + DrawMap(); + DrawInfoBar(); + MouseShow(); +} + + +//////////////////////////////////////////////////// +// +// Tile Select +// +//////////////////////////////////////////////////// +btype SelTb[]={{" Tiles ",2,21,1}, + {" Masked ",11,21,1}, + {" Icons ",21,21,1}, + {" Exit ",30,21,2}}; +DialogDef SelTd={"",38,23,4,&SelTb[0],NULL}; + +void SelectTiles(int screen) +{ + int exitok=0,which,i,numrows,numcols,b0,b1,redraw=0; + + // + // if parameter passed, change the screen + // + if (screen) + whichscreen=screen-1; + + if (PasteMode || SelectMode) // RE-BLIT MAP IF WE ARE ENTERING WHILE + redraw=1; // FLOATING AN IMAGE + + PasteMode=SelectMode=0; + SelX1=SelX2=SelY1=SelY2=-1; + + switch(videomode) + { + case CGA: + case EGA1: + case VGA: + SelTd.height=23; + for(i=0;i<4;i++) + SelTb[i].yoff=21; + break; + case EGA2: + SelTd.height=58; + for(i=0;i<4;i++) + SelTb[i].yoff=56; + } + + DrawDialog(&SelTd,1); + DrawTileSelect(0,&numrows,&numcols); + selectcols=numcols; // VERY IMPORTANT TO PASTE-FROM-TILESELECT MODE + DrawCurrentTiles(); + while(keydown[0x39]); // WAIT FOR SPACE-UP + + do + { + which=CheckButtonsRet(&SelTd); + b0=MouseButton()&1; + b1=(MouseButton()>>1)&1; + + if (which<0) + { + // + // GRAB CURRENT TILE FROM MATRIX + // + if (b0 || b1) + { + int mx,my; + + MouseCoords(&mx,&my); + mx/=8; + if (mx>=left && mx=16 && my<=16+(numrows<<(2+tsize))) + { + int tile; + + tile=((my-16)>>(tsize+2))*numcols+ + ((mx-left)>>(tsize-1)); + + if (SelectMode) + { + int thebase; + switch(whichscreen) + { + case TILES: thebase=tilebase/numcols; break; + case MASKED: thebase=tilembase/numcols; + } + + if (b0) + { + sound(1000); + SelY1=((my-16)>>(tsize+2))+thebase; + SelX1=((mx-left)>>(tsize-1)); + if (SelX2==-1 && SelY2==-1) + { + SelX2=SelX1; + SelY2=SelY1; + } + DrawTileSelect(0,&numrows,&numcols); + nosound(); + } + else + if (b1) + { + sound(1000); + SelY2=((my-16)>>(tsize+2))+thebase; + SelX2=((mx-left)>>(tsize-1)); + if (SelX1==-1 && SelY1==-1) + { + SelX1=SelX2; + SelY1=SelY2; + } + DrawTileSelect(0,&numrows,&numcols); + nosound(); + } + } + else + { + switch(whichscreen) + { + case TILES: + if (XMSlookup[tile+tilebase]>=0) + whicht=tile+tilebase; + else + errsound(); + break; + case MASKED: + whichtm=tile+tilembase+numcols*maxiconrows+tilenum; + if (XMSlookup[whichtm]==-1) + whichtm=tilenum; + break; + case ICONS: + if (XMSlookup[tile+tilenum]>=0 || !tile) + whichi=tile+tilenum; + else + errsound(); + break; + } + DrawCurrentTiles(); + } + } + } + + if (keydown[0x48]) // UP + DrawTileSelect(-1,&numrows,&numcols); + else + if (keydown[0x50]) // DOWN + DrawTileSelect(1,&numrows,&numcols); + else + if (keydown[0x47]) // HOME + { + if (whichscreen==TILES) + DrawTileSelect(-tilebase/numcols,&numrows,&numcols); + else + if (whichscreen==MASKED) + DrawTileSelect(-tilembase/numcols,&numrows,&numcols); + } + else + if (keydown[0x4f]) // END + { + if (whichscreen==TILES) + DrawTileSelect(tilenum,&numrows,&numcols); + else + if (whichscreen==MASKED) + DrawTileSelect(tilemnum,&numrows,&numcols); + } + else + if (keydown[0x49]) // PgUP + { + DrawTileSelect(-numrows,&numrows,&numcols); + if (!keydown[0x1d]) // if not CTRL down, wait for keyup + while(keydown[0x49]); + } + else + if (keydown[0x51]) // PgDN + { + DrawTileSelect(numrows,&numrows,&numcols); + if (!keydown[0x1d]) // if not CTRL down, wait for keyup + while(keydown[0x51]); + } + else + if (keydown[0x39]) // SPACEBAR + { + RestoreBackground(); + while(keydown[0x39]); + SelectMode=0; + if (redraw) + DrawMap(); + DrawInfoBar(); + return; + } + else // 'C' TO COPY + if (keydown[0x2e] && (whichscreen==TILES || whichscreen==MASKED)) + { + char temp[]="COPY MODE"; + + sx=screencenterx-strlen(temp)/2; + SelectMode=sy=1; + print(temp); + + while(keydown[0x2e]); + } + } + else + switch(which) + { + case 0: + if (!SelectMode) + exitok=1; + else + { + char temp[]=" "; + + sx=screencenterx-strlen(temp)/2; + SelectMode=0; + SelX1=SelX2=SelY1=SelY2=-1; + sy=1; + print(temp); + DrawTileSelect(0,&numrows,&numcols); + } + break; + + case 4: + if (!SelectMode) + exitok=1; + // + // 'ENTER' TO FINALIZE COPY + // + else + { + char temp[]=" "; + + if (MouseButton()) // IF CLICKED ON 'EXIT' WITH MOUSE + break; + + sound(500); + sx=screencenterx-strlen(temp)/2; + PasteOK=sy=1; + print(temp); + + TileCopy.x=SelX1; + TileCopy.y=SelY1; + TileCopy.w=SelX2-SelX1+1; + TileCopy.h=SelY2-SelY1+1; + TileCopy.MapOrTileSelect=(whichscreen==TILES)+2*(whichscreen==MASKED); + + while(keydown[0x1c]); + nosound(); + SelectMode=0; + SelX1=SelX2=SelY1=SelY2=-1; + DrawTileSelect(0,&numrows,&numcols); + } + break; + // + // NORMAL TILE SELECT + // + case 1: + if (whichscreen!=TILES) + { + SelX1=SelX2=SelY1=SelY2=-1; + SelectMode=0; + whichscreen=TILES; + DrawDialog(&SelTd,0); + DrawCurrentTiles(); + DrawTileSelect(0,&numrows,&numcols); + } + else + errsound(); + GetButtonXY(&SelTd,0,&sx,&sy); + MouseHide(); + print(SelTb[0].text); + MouseShow(); + break; + // + // MASKED TILE SELECT + // + case 2: + if (tilemnum && whichscreen!=MASKED) + { + SelX1=SelX2=SelY1=SelY2=-1; + SelectMode=0; + whichscreen=MASKED; + DrawDialog(&SelTd,0); + DrawCurrentTiles(); + DrawTileSelect(0,&numrows,&numcols); + } + else + errsound(); + GetButtonXY(&SelTd,1,&sx,&sy); + MouseHide(); + print(SelTb[1].text); + MouseShow(); + break; + // + // ICON SELECT + // + case 3: + if (tilemnum && whichscreen!=ICONS) + { + whichscreen=ICONS; + DrawDialog(&SelTd,0); + DrawCurrentTiles(); + DrawTileSelect(0,&numrows,&numcols); + } + else + errsound(); + GetButtonXY(&SelTd,2,&sx,&sy); + MouseHide(); + print(SelTb[2].text); + MouseShow(); + } + + } while(!exitok); + RestoreBackground(); + SelectMode=0; + SelX1=SelX2=SelY1=SelY2=-1; + DrawInfoBar(); + if (redraw) + DrawMap(); +} + + +// +// DRAW THE CURRENT TILES IN THE TILE-SELECT WINDOW +// +void DrawCurrentTiles(void) +{ + MouseHide(); + GetButtonXY(&SelTd,0,&sx,&sy); + sy-=1+tsize; + CombineTiles(whicht,0,0,tsize); + DrawTile(sx,sy*8,tsize); + sx+=2; + printhex(whicht); + sy++; + sx-=5; + printint(whicht); + print(" "); + + if (tilemnum) + { + GetButtonXY(&SelTd,1,&sx,&sy); + sy-=1+tsize; + CombineTiles(-BkgndColor,whichtm,0,tsize); + DrawTile(sx,sy*8,tsize); + sx+=2; + (whichtm==tilenum)?print(" No "):printhex(whichtm-tilenum); + + sy++; + sx-=5; + (whichtm==tilenum)?print(" Tile "):printint(whichtm-tilenum); + print(" "); + + GetButtonXY(&SelTd,2,&sx,&sy); + sy-=1+tsize; + CombineTiles(-ICONBACK,whichi,0,tsize); + DrawTile(sx,sy*8,tsize); + sx+=2; + (whichi==tilenum)?print(" No "):printhex(whichi-tilenum); + sy++; + sx-=5; + (whichi==tilenum)?print(" Icon "):printint(whichi-tilenum); + print(" "); + } + MouseShow(); +} + + +// +// CHECK TILESELECT EDGES +// +void CheckTSelectEdges(int x,int y,int basey) +{ + int xx,yy,temp; + + xx=left+(x<<(tsize-1)); + yy=(y<<(tsize-1))+2; + + if (SelX2SelY1-basey && ySelX1 && xSelY1-basey && ySelX1 && xtilenum) + { + tilebase=0; + numrows=tilenum/numcols; + } + + if (whichscreen==MASKED && tilembase+numrows*numcols>tilemnum-maxiconrows*numcols) + { + tilembase=0; + numrows=tilemnum/numcols-maxiconrows; + } + + if (whichscreen==ICONS && numrows*numcols>maxiconrows*numcols) + { + tilembase=0; + numrows=maxiconrows; + } + + switch((deltarow<0?-1:deltarow>0?1:0)) + { + case -1: + switch(whichscreen) + { + case TILES: + tilebase+=deltarow*numcols; + if (tilebase<0) + tilebase=0; + break; + case MASKED: + tilembase+=deltarow*numcols; + if (tilembase<0) + tilembase=0; + } + break; + case 1: + switch(whichscreen) + { + case TILES: + tilebase+=deltarow*numcols; + if (tilebase+numrows*numcols>tilenum) + tilebase=tilenum-numcols*numrows; + break; + case MASKED: + tilembase+=deltarow*numcols; + if (tilembase+numrows*numcols>tilemnum-maxiconrows*numcols) + tilembase=(tilemnum-maxiconrows*numcols)-numcols*numrows; + } + } + + switch(whichscreen) + { + case TILES: + for(j=0;jmapwidth) + xbase=mapwidth-screenw; + if (mapwidthmapheight) + ybase=mapheight-screenh; + if (mapheightmaptype&BPLANE) + print("BACK"); + if (MapFileHeader->maptype&FPLANE) + print(",FORE"); + if (MapFileHeader->maptype&IPLANE) + print(",INFO"); + + // + // Count amount of unique background tiles + // + sx=ox-9; + sy=oy+4; + if (MapFileHeader->maptype&BPLANE) + { + int amount=0; + + print("Unique Bkgnd Tiles:"); + MMAllocate((memptr *)&unique,tilenum*2); + _fmemset(unique,0,tilenum*2); + for (i=0;imaptype&FPLANE) + { + int amount=0; + + print("Unique Frgnd Tiles:"); + MMAllocate((memptr *)&unique,tilemnum*2); + _fmemset(unique,0,tilemnum*2); + for (i=0;imaptype&IPLANE) + { + int amount=0; + + print("Amount of Icons:"); + for (i=0;imaptype&BPLANE) + length+=2L*mapwidth*mapheight; + if (MapFileHeader->maptype&FPLANE) + length+=2L*mapwidth*mapheight; + if (MapFileHeader->maptype&IPLANE) + length+=2L*mapwidth*mapheight; + length+=sizeof(MapHeaderStr); + + print("Size of map:"); + length=(length+1023)/1024; + printint(length); + print("K"); + } + + MouseShow(); + CheckButtons(&MapStatsd); + RestoreBackground(); +} + + +//////////////////////////////////////////////////// +// +// Item - Edit New Map +// +//////////////////////////////////////////////////// +btype DOSAVEb[]={{" Yes ",3,3,2}, + {" No! ",15,3,1}}; +DialogDef DOSAVEd={"Your map has changed!\n" + " Save it?", + 21,5,2,&DOSAVEb[0],NULL}; + +void Item_EditMap(void) +{ + int which,olddirt; + + olddirt=DirtyFlag; + if (DirtyFlag) + { + which=DoDialog(&DOSAVEd); + if (!which) + return; + if (which==1) + Item_SaveMap(); + DirtyFlag=0; + } + + if ((which=SelectMap(1,CREATED,"TO EDIT"))==-1) + { + DirtyFlag=olddirt; + return; + } + + TEDInfo->level=whichmap=which; + LoadMap(whichmap); + MouseHide(); + InitDesktop(TED5MenuBar,0); + DrawInfoBar(); + FigureScreenEdges(); + DrawMap(); + MouseShow(); +} + +//////////////////////////////////////////////////// +// +// Item - Save Map +// +//////////////////////////////////////////////////// +void Item_SaveMap(void) +{ + SaveMap(0); + DirtyFlag=0; +} + +//////////////////////////////////////////////////// +// +// Item - Create Map +// +//////////////////////////////////////////////////// +void Item_CreateMap(void) +{ + if (DirtyFlag) + { + int button; + + button=DoDialog(&DoCreated); + if (!button) + return; + if (button==1) + Item_SaveMap(); + DirtyFlag=0; + } + + CreateMap(1); + MouseHide(); + InitDesktop(TED5MenuBar,0); + DrawInfoBar(); + FigureScreenEdges(); + DrawMap(); + MouseShow(); +} + +//////////////////////////////////////////////////// +// +// Item - Delete Map +// +//////////////////////////////////////////////////// +btype AreSureB[]={{" Yes ",1,4,1}, + {" No ",11,4,2}}; +DialogDef AreSureD={"Are you sure you\n" + "you want to delete", + 18,6,2,&AreSureB[0],NULL}; + +void Item_DeleteMap(void) +{ + MapHeaderStr TempHead; + int whichdel,which,temp; + + if ((whichdel=SelectMap(1,CREATED,"TO DELETE"))==-1) + return; + + if (whichmap==whichdel) + { + ErrDialog("I'm just not gonna stand for\n" + "you deleting the map you're\n" + "currently editing. I'm not\n" + "gonna doit. Nope."," Gee... "); + return; + } + + LoadFile(mapname,(char huge *)&TempHead, + MapFileHeader->dataoffsets[whichdel],sizeof(MapHeaderStr)); + MouseHide(); + DrawDialog(&AreSureD,1); + GetDialogXY(&AreSureD,&sx,&sy); + sy+=2; + sx=screencenterx-(strlen(TempHead.name)+1)/2; + print(TempHead.name); + print("?"); + MouseShow(); + + which=CheckButtons(&AreSureD); + switch(which) + { + case 1: + temp=whichmap; + whichmap=whichdel; + RestoreBackground(); + SaveMap(1); + whichmap=temp; + return; + } + RestoreBackground(); +} + +//////////////////////////////////////////////////// +// +// Item - Amputate Maps +// +//////////////////////////////////////////////////// +void Item_Amputate(void) +{ + char tstr[40]; + MapHeaderStr TempHead; + int which1,which2,whichtemp,i,button; + long temp; + + + if ((which1 = SelectMap(1,CREATED,"TO START AMPUTATE"))==-1) + return; + + LoadFile(mapname,(char huge *)&TempHead, + MapFileHeader->dataoffsets[which1],sizeof(MapHeaderStr)); + + if ((which2 = SelectMap(1,ANYLIST,"TO END AMPUTATE"))==-1) + return; + + if (which2 < which1) + { + whichtemp = which1; + which1 = which2; + which2 = whichtemp; + } + + if (whichmap >= which1 && whichmap <= which2) + { + ErrDialog ( "The currently loaded map\n" + "is within that range!\n" + "NON-AMPUTATENESS!!","Wah!"); + return; + } + + DrawDialog(&AreSureD,1); + button = CheckButtons(&AreSureD); + switch (button) + { + case 1: + for (i = which1;i <= which2;i++) + { + MapFileHeader->dataoffsets[i] = -1; + MapFileHeader->datalengths[i] = 0; + } + + DirtyFlag = writeH = 1; + SaveMap(0); + } +} + + +//////////////////////////////////////////////////// +// +// Item - Switch Maps +// +//////////////////////////////////////////////////// +void Item_SwitchMap(void) +{ + char tstr[40]; + MapHeaderStr TempHead; + int which1,which2; + long temp; + + while(1) + { + if ((which1=SelectMap(1,CREATED,"TO SWAP"))==-1) + return; + LoadFile(mapname,(char huge *)&TempHead, + MapFileHeader->dataoffsets[which1],sizeof(MapHeaderStr)); + strcpy(tstr,"TO SWAP WITH '"); + strcat(tstr,TempHead.name); + strcat(tstr,"'"); + if ((which2=SelectMap(1,ANYLIST,tstr))==-1) + return; + + if (which1==whichmap) // MAKE SURE THE CURRENTLY EDITED MAP GETS CHANGED! + whichmap=which2; + else + if (which2==whichmap) + whichmap=which1; + + temp=MapFileHeader->dataoffsets[which1]; + + strcpy(tstr,MapNames[which1]); + strcpy(MapNames[which1],MapNames[which2]); + strcpy(MapNames[which2],tstr); + + MapFileHeader->dataoffsets[which1]=MapFileHeader->dataoffsets[which2]; + MapFileHeader->dataoffsets[which2]=temp; + writeH=DirtyFlag=1; + } +} + +//////////////////////////////////////////////////// +// +// Item - Quit +// +//////////////////////////////////////////////////// +btype Qbuttons[]={{" Yes ",4,2,2},{" No ",12,2,1}}, + DoSaveb[]={{" Yes ",7,4,2},{" No ",14,4,1}}; +DialogDef Qdialog={"Quit - Are you sure?",20,4,2,&Qbuttons[0],NULL}, + DoSaved={"The map has been modified.\n" + "Do you want to SAVE it\n" + "before exiting TED5?",26,6,2,&DoSaveb[0],NULL}, + DoCreated={"The map has been modified.\n" + "Do you want to SAVE it\n" + "before CREATING a new one?",26,6,2,&DoSaveb[0],NULL}; + +void Item_Quit(void) +{ + int button; + + button=DoDialog(&Qdialog); + + if (button==1) + { + TEDInfo->lastvid=videomode; + TEDInfo->level=whichmap; + TEDInfo->OldCgaXMS=0; + TEDInfo->OldEgaXMS=0; + TEDInfo->OldVgaXMS=0; + TEDInfo->OldCgaXMSsize=0; + TEDInfo->OldEgaXMSsize=0; + TEDInfo->OldVgaXMSsize=0; + + TEDInfo->pflags=((planeton&1)<<6)| + ((planemon&1)<<5)| + ((planeion&1)<<4)| + ((viewton&1)<<2)| + ((viewmon&1)<<1)| + (viewion&1); + + SaveTEDInfo(); + if (DirtyFlag) + { + button=DoDialog(&DoSaved); + if (button==1) + Item_SaveMap(); + if (!button) + return; // ESC exits + } + SaveOutputHeader(); + Quit(""); + } +} + +//////////////////////////////////////////////////// +// +// Item - Edit Map Names +// +//////////////////////////////////////////////////// +char EMNstring[16]; +btype EMNb[]={{EMNstring,1,4,1}, + {" ",1,8,1}, + {" Exit ",7,11,1}}; +DialogDef EMNd={" MAP RENAME\n\nChange...\n\n\n\nTo..." + ,20,13,3,&EMNb[0],NULL}; + +void Item_EditMapNames(void) +{ + int which,mapnum,redraw=0,omapnum,oxb,oyb; + MapHeaderStr TempHeader; + char temp[16]; + + + CheckForMapSave(); + omapnum=whichmap; + oxb=xbase; + oyb=ybase; + + if ((mapnum=SelectMap(1,CREATED,"TO RENAME"))<0) + return; + + whichmap=mapnum; + LoadMap(whichmap); + strcpy(EMNstring,MapHeader.name); + + MouseHide(); + DrawDialog(&EMNd,1); + GetDialogXY(&EMNd,&sx,&sy); + MouseShow(); + which=2; +#pragma warn -rch + goto badboy; + + do + { + which=CheckButtons(&EMNd); + +badboy: +#pragma warn +rch + switch(which) + { + case 1: + RestoreBackground(); + if ((mapnum=SelectMap(1,CREATED,"TO RENAME"))<0) + { + if (redraw) + DrawInfoBar(); + + whichmap=omapnum; + LoadMap(whichmap); + xbase=oxb; + ybase=oyb; + return; + } + + whichmap=mapnum; + LoadMap(whichmap); + strcpy(EMNstring,MapHeader.name); + MouseHide(); + DrawDialog(&EMNd,1); + MouseShow(); + + case 2: + MouseHide(); + GetButtonXY(&EMNd,1,&sx,&sy); + print(EMNb[1].text); + GetButtonXY(&EMNd,1,&sx,&sy); + if (input(temp,15)) + { + writeH=1; + strcpy(MapHeader.name,temp); + strcpy(MapNames[mapnum],temp); + DirtyFlag=1; + Item_SaveMap(); + } + else + { + GetButtonXY(&EMNd,1,&sx,&sy); + print(EMNb[1].text); + } + MouseShow(); + break; + + case 3: + which=0; + } + } while(which); + + RestoreBackground(); + if (redraw) + DrawInfoBar(); + + whichmap=omapnum; + LoadMap(whichmap); + xbase=oxb; + ybase=oyb; +} + +//////////////////////////////////////////////////// +// +// Item - Paste Mode +// +//////////////////////////////////////////////////// +void Item_Paste(void) +{ + if (!TileCopy.w) + return; + + ZeroModes(); + PasteMode=1; + DrawInfoBar(); + px=(pixelx>>(tsize+2))+xbase; + py=((pixely-8)>>(tsize+2))+ybase; +} + +//////////////////////////////////////////////////// +// +// Item - Copy Mode +// +//////////////////////////////////////////////////// +void Item_Copy(void) +{ + ZeroModes(); + SelectMode=1; + SelX1=SelY1=SelX2=SelY2=-1; + DrawInfoBar(); +} + +//////////////////////////////////////////////////// +// +// Item - LastVideo +// +//////////////////////////////////////////////////// +void Item_LastVideo(void) +{ + int temp=videomode; + + + videomode=lastvideo; + lastvideo=temp; + if (temp==EGA1) + videomode=EGA2; + else + videomode=EGA1; + + switch(videomode) + { + case CGA: + xmshandle=CgaXMS; + XMSlookup=CgaXMSlookup; + break; + case EGA1: + case EGA2: + xmshandle=EgaXMS; + XMSlookup=EgaXMSlookup; + break; + case VGA: + xmshandle=VgaXMS; + XMSlookup=VgaXMSlookup; + } + + MouseHide(); + setvideo(videomode); + InitDesktop(TED5MenuBar,0); + DrawInfoBar(); + FigureScreenEdges(); + + if (xbase+screenw>mapwidth) + xbase=mapwidth-screenw; + if (mapwidthmapheight) + ybase=mapheight-screenh; + if (mapheight1) + { + ErrDialog("I will only allow Flood Filling\n" + "one plane at a time; you have\n" + "more than one plane selected."," OK "); + return; + } + + for (i=0;iwidth || oby[0]>height) + { + FillMode=0; + DrawInfoBar(); + return; + } + + Ton=planeton; + Mon=planemon; + Ion=planeion; + + orgt=*(MapBkgnd+ptr); + orgm=*(MapFrgnd+ptr); + orgi=*(MapInfoPl+ptr); + + if (((Ton?whicht==orgt:0) || + (Mon?whichtm-tilenum==orgm:0) || + (Ion?whichi-tilenum==orgi:0)) && !ctrl) + { + FillMode=0; + DrawInfoBar(); + return; + } + + MouseHide(); + CopyUndoRegion(); + UndoRegion.x=UndoRegion.y=0; + UndoRegion.w=mapwidth; + UndoRegion.h=mapheight; + + if (ctrl) + { + unsigned from=(TileCopy.y+(y%TileCopy.h))*mapwidth+ + TileCopy.x+(x%TileCopy.w); + + switch(TileCopy.MapOrTileSelect) + { + case 0: // COPY BUFFER + Ton=TileCopy.PlanesCopied&BPLANE; + Mon=TileCopy.PlanesCopied&FPLANE; + Ion=TileCopy.PlanesCopied&IPLANE; + + newt=CutBkgnd[from]; + newm=CutFrgnd[from]; + newi=CutInfoPl[from]; + + break; + case 1: // TILES + Ton=1; + Mon=Ion=0; + + newt=((y%TileCopy.h)+TileCopy.y)*selectcols+ + TileCopy.x+(x%TileCopy.w); + if (XMSlookup[newt]<0) + Ton=0; + break; + case 2: // MASKED + Ton=Ion=0; + Mon=1; + + newm=((y%TileCopy.h)+TileCopy.y)*selectcols+ + TileCopy.x+(x%TileCopy.w)+tilenum+maxiconrows*selectcols; + if (XMSlookup[newm]<0) + Mon=0; + else + newm-=tilenum; + } + } + else + { + newt=whicht; + newm=whichtm-tilenum; + newi=whichi-tilenum; + } + + if (Ton) + *(MapBkgnd+newoff)=newt; + if (Mon) + *(MapFrgnd+newoff)=newm; + if (Ion) + *(MapInfoPl+newoff)=newi; + + do + { + for (i=0;i<=highest;i++) + // + // SEE IF SPORE EXISTS + // + if (obx[i]!=-1) + { + // + // DRAW TILE AT SPORE IF IT'S ONSCREEN + // + if (oby[i]>=ybase && oby[i]=xbase && obx[i]width || oby[k]<0 || oby[k]>height) + { + obx[k]=-1; + break; + } + + used++; + if (Ton) + *(MapBkgnd+newoff)=whicht; + if (Mon) + *(MapFrgnd+newoff)=whichtm-tilenum; + if (Ion) + *(MapInfoPl+newoff)=whichi-tilenum; + DirtyFlag=1; + if (k>highest) + highest=k; + break; + } + } + + if (keydown[1]) // ESC OUT + { + while(keydown[1]); + goto done; + } + } + else + for (j=0;j<4;j++) + { + unsigned from; + + ny=y+vecty[j]; + nx=x+vectx[j]; + + newoff=ny*mapwidth+nx; + + if ((Ton?*(MapBkgnd+newoff)==orgt:1) && + (Mon?*(MapFrgnd+newoff)==orgm:1) && + (Ion?*(MapInfoPl+newoff)==orgi:1)) + { + for (k=0;kwidth || oby[k]<0 || oby[k]>height) + { + obx[k]=-1; + break; + } + + from=(TileCopy.y+(ny%TileCopy.h))*mapwidth+ + TileCopy.x+(nx%TileCopy.w); + + switch(TileCopy.MapOrTileSelect) + { + case 0: // COPY BUFFER + Ton=TileCopy.PlanesCopied&BPLANE; + Mon=TileCopy.PlanesCopied&FPLANE; + Ion=TileCopy.PlanesCopied&IPLANE; + + newt=CutBkgnd[from]; + newm=CutFrgnd[from]; + newi=CutInfoPl[from]; + + break; + case 1: // TILES + Ton=1; + Mon=Ion=0; + + newt=((ny%TileCopy.h)+TileCopy.y)*selectcols+ + TileCopy.x+(nx%TileCopy.w); + if (XMSlookup[newt]<0) + Ton=0; + break; + case 2: // MASKED + Ton=Ion=0; + Mon=1; + + newm=((ny%TileCopy.h)+TileCopy.y)*selectcols+ + TileCopy.x+(nx%TileCopy.w)+tilenum+maxiconrows*selectcols; + if (XMSlookup[newm]<0) + Mon=0; + else + newm-=tilenum; + } + + if (Ton) + *(MapBkgnd+newoff)=newt; + if (Mon) + *(MapFrgnd+newoff)=newm; + if (Ion) + *(MapInfoPl+newoff)=newi; + used++; + + DirtyFlag=1; + if (k>highest) + highest=k; + break; + } + } + + if (keydown[1]) // ESC OUT + { + while(keydown[1]); + goto done; + } + } + } + } while(used); + +done: + DrawMap(); + MouseShow(); + FillMode=0; + DrawInfoBar(); +} + + + +//////////////////////////////////////////////////// +// +// If map has been changed, ask user if they want +// to SAVE it before continuing. +// +//////////////////////////////////////////////////// +btype oktosaveB[]={{" Yes ",10,2,2},{" No ",20,2,1}}; +DialogDef oktosaveD={"The map has been modified!\n" + "Save it?",26,4,2,&oktosaveB[0],NULL}; + +int CheckForMapSave(void) +{ + if (DirtyFlag) + { + int which=DoDialog(&oktosaveD); + if (!which) + return 0; + if (which==1) + Item_SaveMap(); + } + return 1; +} + + +//////////////////////////////////////////////////// +// +// Zero all special mode flags +// +//////////////////////////////////////////////////// +void ZeroModes(void) +{ + SelX1=SelX2=SelY1=SelY2=-1; + if (BfillMode || SelectMode || PasteMode || FillMode) + { + DrawMap(); + DrawInfoBar(); + } + + BfillMode=SelectMode=PasteMode=FillMode=0; +} + + +//////////////////////////////////////////////////// +// +// Item - Count Map Tiles +// +//////////////////////////////////////////////////// +btype CMTb[]={ + {" Exit ",9,20,2}, + {" TILE ",1,20,1}, + {" MASKED ",17,20,1}, + {" Rebuild ",27,20,1} + }; +DialogDef CMTd={" Count Unused Map Tiles",38,22,4,&CMTb[0],0}; +unsigned char _seg *tarray,_seg *tmarray,thesparse; + + +void Item_CountTiles(void) +{ + enum {TILE,TILEM}; + + unsigned i,j,dx,dy,max,exit=0,numt,numtm,oxbase,oybase,nsize,nmsize,redraw; + int which,dumrow,dumcol; + char pb,pf,pi; + + + CheckForMapSave(); + + oxbase=xbase; + oybase=ybase; + + // + // COMPUTE SIZE OF EACH TILE + // + switch(videomode) + { + case CGA: nsize=16; nmsize=32; break; + case EGA1: + case EGA2: nsize=32; nmsize=40; break; + case VGA: nsize=64; nmsize=128; + } + nsize=nsize<<((tsize-1)<<1); + nmsize=nmsize<<((tsize-1)<<1); + + + MouseHide(); + DrawDialog(&CMTd,1); + GetDialogXY(&CMTd,&dx,&dy); + sx=dx+4; + sy=dy+2; + print("Counting tiles in map:"); + MouseShow(); + + MMAllocate((memptr *)&tarray,tilenum); + MMAllocate((memptr *)&tmarray,tilemnum); + _fmemset(tarray,0,tilenum); + _fmemset(tmarray,0,tilemnum); + + // + // Now, load each map in & count the tiles + // + pb=MapFileHeader->maptype&BPLANE; + pf=MapFileHeader->maptype&FPLANE; + pi=MapFileHeader->maptype&IPLANE; + + for (i=0;i<100;i++) + if (MapFileHeader->dataoffsets[i]>=0) + { + sx=dx+26; + sy=dy+2; + printint(i); + + LoadMap(i); + max=mapwidth*mapheight; + for (j=0;j=0 && !tarray[i]) + numt++; + + numtm=0; + for (i=0;i=0 && !tmarray[i]) + numtm++; + + + // + // INPUT FROM DIALOG + // + do + { + MouseHide(); + xormask=0; + sx=dx+2; + sy=dy+17; + print("Unused TILES:"); + printint(numt); + print(", unused MASKED:"); + printint(numtm); + print(" "); + sx=dx+2; + sy=dy+18; + print("TILE Memory:"); + printint((1023l+(long)numt*nsize)/1024); + print("K, MASKED Memory:"); + printint((1023l+(long)numtm*nmsize)/1024); + print("K "); + MouseShow(); + DrawUnused(0); + redraw=0; + + do + { + if (!MouseButton()) + which=CheckButtonsRet(&CMTd); + MouseCoords(&pixelx,&pixely); + pixelx/=8; + pixely/=8; + if (MouseButton() && pixelx>dx && pixelxdy && pixely>(tsize-1))+((pixely-dy-1)>>(tsize-1))*(9<<(3-tsize)); + + switch(whichscreen) + { + case TILES: + if (!tarray[tile+tilebase] && XMSlookup[tile+tilebase]>=0) + { + tarray[tile+tilebase]=1; + numt--; + redraw=1; + } + break; + case MASKED: + if (!tmarray[tile+tilembase] && XMSlookup[tilenum+tile+tilembase]>=0) + { + tmarray[tile+tilembase]=1; + numtm--; + redraw=1; + } + } + continue; + } + + switch(which) + { + case 0: + case 1: + exit=1; + continue; + + case 2: + MouseHide(); + GetButtonXY(&CMTd,which-1,&sx,&sy); + print(CMTb[which-1].text); + whichscreen=TILES; + DrawUnused(0); + MouseShow(); + continue; + + case 3: + MouseHide(); + GetButtonXY(&CMTd,which-1,&sx,&sy); + print(CMTb[which-1].text); + whichscreen=MASKED; + DrawUnused(0); + MouseShow(); + continue; + + // + // REBUILD GRAPHICS FILE & HEADER + // + case 4: + { + char newgfx[13]="NEW?GA.", + newhead[13]="NEW?HEAD.", + newhobj[13]="NEW?HEAD.", + oldhead[13]="?GAHEAD."; + + char _seg *gfxhead; + + + newgfx[3]=format[0]; + newhead[3]=format[0]; + newhobj[3]=format[0]; + oldhead[0]=format[0]; + + + LoadIn(oldhead,(memptr *)&gfxhead); + for (i=0;itilenum) + { + tilebase=0; + numrows=tilenum/numcols; + } + + if (whichscreen==MASKED && tilembase+numrows*numcols>tilemnum) + { + tilembase=0; + numrows=tilemnum/numcols; + } + + switch((deltarow<0?-1:deltarow>0?1:0)) + { + case -1: + switch(whichscreen) + { + case TILES: + tilebase+=deltarow*numcols; + if (tilebase<0) + tilebase=0; + break; + case MASKED: + tilembase+=deltarow*numcols; + if (tilembase<0) + tilembase=0; + } + break; + case 1: + switch(whichscreen) + { + case TILES: + tilebase+=deltarow*numcols; + if (tilebase+numrows*numcols>tilenum) + tilebase=tilenum-numcols*numrows; + break; + case MASKED: + tilembase+=deltarow*numcols; + if (tilembase+numrows*numcols>tilemnum) + tilembase=tilemnum-numcols*numrows; + } + } + + switch(whichscreen) + { + case TILES: + for(j=0;j=0) + CombineTiles(tilebase+j*numcols+i,0,0,tsize); + else + CombineTiles(thesparse,0,0,tsize); + DrawTile(i*2+left,j*16+top,tsize); + } + break; + + case MASKED: + for(j=0;j=0) + CombineTiles(-BkgndColor,tilenum+tilembase+j*numcols+i,0,tsize); + else + CombineTiles(thesparse,0,0,tsize); + DrawTile(i*2+left,j*16+top,tsize); + } + } + MouseShow(); +} diff --git a/16/ted5/TED5-3.C b/16/ted5/TED5-3.C new file mode 100755 index 00000000..f41aa23b --- /dev/null +++ b/16/ted5/TED5-3.C @@ -0,0 +1,2033 @@ +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +// +// TED5-3 +// +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +#include "ted5.h" +#pragma hdrstop + +int xms1; +extern int tics; + +//////////////////////////////////////////////////// +// +// MAP SCROLLING +// +//////////////////////////////////////////////////// +void CheckMapScroll(void) +{ + // + // LEFT + // + if (keydown[0x4b]) // left arrow + { + int i,j,imax,jmax,tilesmoved; + + tics=biostime(0,0); + + if (xbase) + { + EraseFloatPaste(); + + if (keydown[0x1d]) // CTRL-KEY + { + tilesmoved=screenw; + if (keydown[0x38]) // ALT-KEY + { + xbase=0; + DrawMap(); + return; + } + } + else + switch(videomode) + { + case CGA: + case EGA1: + case VGA: + tilesmoved=1; + break; + case EGA2: + tilesmoved=2; + } + + if (xbasemapheight) + jmax=mapheight; + + for (i=0;i=mapwidth) + tilesmoved=mapwidth-screenw-xbase; + xbase+=tilesmoved; + + MouseHide(); + if (tilesmovedmapheight) + jmax=mapheight; + + for (i=0;imapwidth) + imax=mapwidth; + + for (j=0;j=mapheight) + tilesmoved=mapheight-screenh-ybase; + ybase+=tilesmoved; + + MouseHide(); + if (tilesmovedmapwidth) + imax=mapwidth; + + for (j=0;jSelX1 && xSelX1 && xSelY1 && ySelY1 && y=8 || pixely=xbase+screenw) + mx-=snapxsize; + if (my>=ybase+screenh) + my-=snapysize; + } + + if (!PasteMode || (px==mx && py==my) || (pixely<8 || pixely>infoy*8)) + return; + + if (mx>mapwidth || my>mapheight) + return; + + MouseHide(); + EraseFloatPaste(); + + // + // FLOAT IT... + // + px=mx; + py=my; + + DrawFloatPaste(); + MouseShow(); +} + + +//////////////////////////////////////////////////// +// +// DRAW FLOATING PASTE REGION +// +void DrawFloatPaste(void) +{ + int i,j,maxw,maxh; + + + if (px==-1 || py==-1 || !PasteMode) + return; + // + // NOW, DRAW IT IN A NEW LOCATION! + // + MouseHide(); + + + maxh=TileCopy.h; + if (py+maxh>mapheight) + maxh=mapheight-py; + if (py+maxh-ybase>screenh) + maxh=screenh-(py-ybase); + + maxw=TileCopy.w; + if (px+maxw>mapwidth) + maxw=mapwidth-px; + if (px+maxw-xbase>screenw) + maxw=screenw-(px-xbase); + + switch(TileCopy.MapOrTileSelect) + { + case 0: // MAP PASTE DRAW + for (j=0;jmapheight) + maxh=mapheight-py; + if (py+maxh-ybase>screenh) + maxh=screenh-(py-ybase); + + maxw=TileCopy.w; + if (px+maxw>mapwidth) + maxw=mapwidth-px; + if (px+maxw-xbase>screenw) + maxw=screenw-(px-xbase); + + for (j=0;j0)+ + ((TileCopy.PlanesCopied&FPLANE)>0)+((TileCopy.PlanesCopied&IPLANE)>0)); + + xms1=XMSAllocate(size); + + off=0; + if (TileCopy.PlanesCopied&BPLANE) + for (j=0;jmapwidth)?mapwidth:TileCopy.w; + newheight=(TileCopy.h>mapheight)?mapheight:TileCopy.h; + + ToOff=off=0; + + if (TileCopy.PlanesCopied&BPLANE) + for (j=0;j>8); + sx-=2; + sy++; + printhexb(temp&0xff); + break; + case 3: printhex(temp); + } + } + else + if (viewion && tilei>lasticon) + { + switch(tsize) + { + case 1: + print("#"); + break; + case 2: + printhexb(tilei-tilenum>>8); + sx-=2; + sy++; + printhexb(tilei-tilenum&0xff); + break; + case 3: printhex(tilei-tilenum); + } + } +} + +//////////////////////////////////////////////////// +// +// Item - Edit Map Edges +// +//////////////////////////////////////////////////// +btype MapEdgeB[]={{"\xb",7,3,1}, + {"\xc",7,7,1}, + {"\xe",4,5,1}, + {"\x1f",10,5,1}, + {" Exit ",5,16,2}}; +DialogDef MapEdgeD={" PICK MAP EDGE\n" + " TO CHANGE", + 16,18,5,&MapEdgeB[0],NULL}; + +void Item_EditMapEdges(void) +{ + int which,val,newwidth,newheight,b,f,i, + _seg *tempB,_seg *tempF,_seg *tempI; + unsigned dx,dy,obx,oby,k,j,modified=0; + long size; + + b=MapFileHeader->maptype&BPLANE; + f=MapFileHeader->maptype&FPLANE; + i=MapFileHeader->maptype&IPLANE; + + DrawDialog(&MapEdgeD,1); + GetDialogXY(&MapEdgeD,&dx,&dy); + do + { + MouseHide(); + sx=dx+2; + sy=dy+14; + print("W:"); + printint(MapHeader.width); + print(", H:"); + printint(MapHeader.height); + print(" "); + MouseShow(); + + + which=CheckButtons(&MapEdgeD); + GetButtonXY(&MapEdgeD,which-1,&obx,&oby); + MouseHide(); + if (which>=1 && which<=4) + { + // DRAW INPUT BAR + sx=dx; + sy=dy+9; + print("+ or - value"); + DrawBorder(dx,dy+10,15,2,1); + + // INPUT VALUE + sx=dx+1; + sy=dy+11; + val=inputint(9); + + // ERASE THE ARROW AND INPUT BAR + sx=obx; + sy=oby; + print(MapEdgeB[which-1].text); + bar(dx,dy+9,dx+15,dy+12,' '); + + // CHECK FOR ESC + if (val==(int)ESCOUT) + which=6; + } + + MouseShow(); + switch(which) + { + // + // ADD OR DELETE FROM TOP + // + case 1: + newheight=mapheight+val; + size=2L*newheight*mapwidth; + if (size<=0 || size>0x10000L) + { + RestoreBackground(); + ErrDialog("Invalid Map height!"," OK "); + return; + } + + // FREE UP SOME MEMORY! + SaveCutBuffers(); + RemoveUndoBuffers(); + + if (b) + { + MMFreePtr((memptr *)&CutBkgnd); + MMAllocate((memptr *)&tempB,size); + } + if (f) + { + MMFreePtr((memptr *)&CutFrgnd); + MMAllocate((memptr *)&tempF,size); + } + if (i) + { + MMFreePtr((memptr *)&CutInfoPl); + MMAllocate((memptr *)&tempI,size); + } + + if (val<0) + { + // COPY MAP PLANES INTO TEMP MEMORY (CLIPPED, HERE) + for (j=abs(val);j0x10000L) + { + RestoreBackground(); + ErrDialog("Invalid Map height!"," OK "); + return; + } + + // FREE UP SOME MEMORY! + SaveCutBuffers(); + RemoveUndoBuffers(); + if (b) + { + MMFreePtr((memptr *)&CutBkgnd); + MMAllocate((memptr *)&tempB,size); + } + if (f) + { + MMFreePtr((memptr *)&CutFrgnd); + MMAllocate((memptr *)&tempF,size); + } + if (i) + { + MMFreePtr((memptr *)&CutInfoPl); + MMAllocate((memptr *)&tempI,size); + } + + if (val<0) + { + // COPY MAP PLANES INTO TEMP MEMORY (CLIPPED, HERE) + for (j=0;j=mapheight) + { + if (b) + tempB[j*mapwidth+k]=whicht; + if (f) + tempF[j*mapwidth+k]=whichtm-tilenum; + if (i) + tempI[j*mapwidth+k]=whichi-tilenum; + } + else + { + if (b) + tempB[j*mapwidth+k]=MapBkgnd[j*mapwidth+k]; + if (f) + tempF[j*mapwidth+k]=MapFrgnd[j*mapwidth+k]; + if (i) + tempI[j*mapwidth+k]=MapInfoPl[j*mapwidth+k]; + } + } + } + + // DEALLOCATE & REALLOCATE THE MAP BUFFERS, RESIZED + if (b) + { + MMFreePtr((memptr *)&MapBkgnd); + MMAllocate((memptr *)&MapBkgnd,size); + } + if (f) + { + MMFreePtr((memptr *)&MapFrgnd); + MMAllocate((memptr *)&MapFrgnd,size); + } + if (i) + { + MMFreePtr((memptr *)&MapInfoPl); + MMAllocate((memptr *)&MapInfoPl,size); + } + + // COPY THE REGION BACK IN... + for (j=0;j0x10000L) + { + RestoreBackground(); + ErrDialog("Invalid Map width!"," OK "); + return; + } + + // FREE UP SOME MEMORY! + SaveCutBuffers(); + RemoveUndoBuffers(); + if (b) + { + MMFreePtr((memptr *)&CutBkgnd); + MMAllocate((memptr *)&tempB,size); + } + if (f) + { + MMFreePtr((memptr *)&CutFrgnd); + MMAllocate((memptr *)&tempF,size); + } + if (i) + { + MMFreePtr((memptr *)&CutInfoPl); + MMAllocate((memptr *)&tempI,size); + } + + if (val<0) + { + // COPY MAP PLANES INTO TEMP MEMORY (CLIPPED, HERE) + for (j=0;j0x10000L) + { + RestoreBackground(); + ErrDialog("Invalid Map width!"," OK "); + return; + } + + // FREE UP SOME MEMORY! + SaveCutBuffers(); + RemoveUndoBuffers(); + if (b) + { + MMFreePtr((memptr *)&CutBkgnd); + MMAllocate((memptr *)&tempB,size); + } + if (f) + { + MMFreePtr((memptr *)&CutFrgnd); + MMAllocate((memptr *)&tempF,size); + } + if (i) + { + MMFreePtr((memptr *)&CutInfoPl); + MMAllocate((memptr *)&tempI,size); + } + + if (val<0) + { + // COPY MAP PLANES INTO TEMP MEMORY (CLIPPED, HERE) + for (j=0;j=mapwidth) + { + if (b) + tempB[j*newwidth+k]=whicht; + if (f) + tempF[j*newwidth+k]=whichtm-tilenum; + if (i) + tempI[j*newwidth+k]=whichi-tilenum; + } + else + { + if (b) + tempB[j*newwidth+k]=MapBkgnd[j*mapwidth+k]; + if (f) + tempF[j*newwidth+k]=MapFrgnd[j*mapwidth+k]; + if (i) + tempI[j*newwidth+k]=MapInfoPl[j*mapwidth+k]; + } + } + } + + // DEALLOCATE & REALLOCATE THE MAP BUFFERS, RESIZED + if (b) + { + MMFreePtr((memptr *)&MapBkgnd); + MMAllocate((memptr *)&MapBkgnd,size); + } + if (f) + { + MMFreePtr((memptr *)&MapFrgnd); + MMAllocate((memptr *)&MapFrgnd,size); + } + if (i) + { + MMFreePtr((memptr *)&MapInfoPl); + MMAllocate((memptr *)&MapInfoPl,size); + } + + // COPY THE REGION BACK IN... + for (j=0;jdataoffsets[i]!=-1) + { + // + // LOAD MAP HEADER + // + sx=dx; + printint(i); + LoadFile(mapname,(char huge *)&TempHeader,MapFileHeader->dataoffsets[i],sizeof(MapHeaderStr)); + + // + // COMPRESS EACH MAP PLANE + // + #pragma warn -sus + if (MapFileHeader->maptype&BPLANE) + { + size=TempHeader.mapbkgndlen; + MMAllocate(&block,size); + MMAllocate(&block2,size); + LoadFile(mapname,block,TempHeader.mapbkgndpl,size); + *(int _seg *)block2=TempHeader.mapbkgndlen; + nsize=CarmackCompress((unsigned char huge *)block,size,(unsigned char huge *)block2+2)+2; + maplengths[i]+=nsize; + if (nsize==2) + { + RestoreBackground(); + MMFreePtr(&block2); + MMFreePtr(&block); + MMFreePtr(&block1); + LoadMap(whichmap); + xbase=oxb; + ybase=oyb; + ErrDialog("ESC out of this infernal thing!"," YES! "); + return; + } + + SaveFile(huffname,block2,fsize,nsize); + TempHeader.mapbkgndpl=fsize; + TempHeader.mapbkgndlen=nsize; + MMFreePtr(&block2); + MMFreePtr(&block); + fsize+=nsize; + } + if (MapFileHeader->maptype&FPLANE) + { + size=TempHeader.mapfrgndlen; + MMAllocate(&block,size); + MMAllocate(&block2,size); + LoadFile(mapname,block,TempHeader.mapfrgndpl,size); + *(int _seg *)block2=TempHeader.mapfrgndlen; + nsize=CarmackCompress((unsigned char huge *)block,size,(unsigned char huge *)block2+2)+2; + maplengths[i]+=nsize; + if (nsize==2) + { + RestoreBackground(); + MMFreePtr(&block2); + MMFreePtr(&block); + MMFreePtr(&block1); + LoadMap(whichmap); + xbase=oxb; + ybase=oyb; + ErrDialog("ESC out of this infernal thing!"," YES! "); + return; + } + + SaveFile(huffname,block2,fsize,nsize); + TempHeader.mapfrgndpl=fsize; + TempHeader.mapfrgndlen=nsize; + MMFreePtr(&block2); + MMFreePtr(&block); + fsize+=nsize; + } + if (MapFileHeader->maptype&IPLANE) + { + size=TempHeader.mapinfolen; + MMAllocate(&block,size); + MMAllocate(&block2,size); + LoadFile(mapname,block,TempHeader.mapinfopl,size); + *(int _seg *)block2=TempHeader.mapinfolen; + nsize=CarmackCompress((unsigned char huge *)block,size,(unsigned char huge *)block2+2)+2; + maplengths[i]+=nsize; + if (nsize==2) + { + RestoreBackground(); + MMFreePtr(&block2); + MMFreePtr(&block); + MMFreePtr(&block1); + LoadMap(whichmap); + xbase=oxb; + ybase=oyb; + ErrDialog("ESC out of this infernal thing!"," YES! "); + return; + } + + SaveFile(huffname,block2,fsize,nsize); + TempHeader.mapinfopl=fsize; + TempHeader.mapinfolen=nsize; + MMFreePtr(&block2); + MMFreePtr(&block); + fsize+=nsize; + } + #pragma warn +sus + + // + // SAVE MAP HEADER + // + nsize=sizeof(TempHeader); + maplengths[i]+=nsize; + SaveFile(huffname,(char huge *)&TempHeader,fsize,nsize); + NewFileHeader.dataoffsets[i]=fsize; + fsize+=nsize; + + SaveFile(huffname,"!ID!",fsize,4); + fsize+=4; + } + MMFreePtr(&block1); + + + // + // COPY PERTINENT MAPFILEHEADER DATA TO NEWFILEHEADER + // + { + char outname[14],tempname[14]="MTEMP.TMP",doutname[14]; + + + strcpy(outname,ext); + strcat(outname,"MHEAD.OBJ"); + + NewFileHeader.RLEWtag=MapFileHeader->RLEWtag; + fsize=sizeof(OutputHeadStr); + SaveFile(tempname,(char huge *)&NewFileHeader,0,fsize); + + for (i=0;idataoffsets[i]!=-1) + { + char tstr[16]; + strcpy(tstr,MapNames[i]); + while(strlen(tstr)<16) + strcat(tstr," "); + fprintf(stdprn,"%d\t%s\t%d\n",i,tstr,maplengths[i]); + } + fprintf(stdprn,"%c",12); + } + + LoadMap(whichmap); + xbase=oxb; + ybase=oyb; +} + + +//////////////////////////////////////////////////// +// +// Item - Change the LAUNCH name +// +//////////////////////////////////////////////////// +btype CLNb={" ",1,5,1}; +DialogDef CLNd={"Current LAUNCH name:\n\n\nNew LAUNCH name:",38,7,1,&CLNb,NULL}; + +void Item_LAUNCHname(void) +{ + char tempstr[40]; + + + MouseHide(); + DrawDialog(&CLNd,1); + GetDialogXY(&CLNd,&sx,&sy); + sy++; + sx++; + print(launchname); + GetButtonXY(&CLNd,0,&sx,&sy); + if (input(tempstr,36)) + { + strcpy(launchname,tempstr); + SaveTEDInfo(); + } + MouseShow(); + RestoreBackground(); +} + + +//////////////////////////////////////////////////// +// +// Item - Change the PARM string +// +//////////////////////////////////////////////////// +btype CPSb={" ",1,5,1}; +DialogDef CPSd={"Current PARM string:\n\n\nNew PARM string:",38,7,1,&CPSb,NULL}; + +void Item_PARMstring(void) +{ + char tempstr[40]; + + + MouseHide(); + DrawDialog(&CPSd,1); + GetDialogXY(&CPSd,&sx,&sy); + sy++; + sx++; + print(parmstring); + GetButtonXY(&CPSd,0,&sx,&sy); + if (input(tempstr,36)) + { + strcpy(parmstring,tempstr); + _fstrcpy(TEDInfo->parmstring,(char far *)parmstring); + SaveTEDInfo(); + } + MouseShow(); + RestoreBackground(); +} + + +//////////////////////////////////////////////////// +// +// Item - Change Icon Rows +// +//////////////////////////////////////////////////// +btype CIRb={" ",8,4,1}; +DialogDef CIRd={"Enter amount of icons\n" + "to add/delete.\n" + "Use + or -.",22,6,1,&CIRb,NULL}; + +void Item_ChangeIconRows(void) +{ + unsigned i,j,dx,dy,max,oxbase,oybase,base; + int value,owm; + memptr block; + + + if (!(MapFileHeader->maptype&IPLANE)) + { + ErrDialog("You don't have an icon plane!"," OK "); + return; + } + + CheckForMapSave(); + + oxbase=xbase; + oybase=ybase; + + DrawDialog(&CIRd,1); + GetButtonXY(&CIRd,0,&dx,&dy); + sx=dx; + sy=dy; + MouseHide(); + value=inputint(3); + MouseShow(); + if (!value || value==(int)ESCOUT) + { + RestoreBackground(); + return; + } + + value=SGN(value)*(18*((abs(value)+17)/18)); + + base=18*maxiconrows; + maxiconrows+=value/18; + MapFileHeader->NumIconRows+=value/18; + + owm=whichmap; + RestoreBackground(); + + + // + // MAKE SURE WE ADJUST TILEINFOM! + // + MMAllocate(&block,tilemnum+value); + for (i=0;ioldtilemnum=tilemnum+value; + + + // + // RUN THROUGH EACH MAP AND ADJUST TILEM VALUES + // + for (i=0;i<100;i++) + if (MapFileHeader->dataoffsets[i]>=0) + { + whichmap=i; + LoadMap(i); + max=mapwidth*mapheight; + for (j=0;j0) + MapFrgnd[j]+=value; + DirtyFlag=1; + SaveMap(0); + } + + DirtyFlag=0; + whichmap=owm; + LoadMap(whichmap); + xbase=oxbase; + ybase=oybase; + DrawMap(); + ErrDialog("If your map looks messed up,\n" + "you need to change the amount\n" + "of icons in your IGRAB script\n" + "and re-grab your tiles!"," OK "); +} + + +//////////////////////////////////////////////////// +// +// Item - Change LAUNCH Icon +// +//////////////////////////////////////////////////// +void Item_ChangeLaunchIcon(void) +{ + sound(1700); + TEDInfo->permicon=whichi-tilenum; + delay(30); + nosound(); +} + + +//////////////////////////////////////////////////// +// +// Item - Change Background color +// +//////////////////////////////////////////////////// +btype CBCb[]={{"\xb",5,2,1}, + {"\xc",16,2,1}, + {"Exit",9,2,2}}; +DialogDef CBCd={"Change Backgrnd Color!",22,4,3,&CBCb[0],0}; +void Item_ChangeBkgndColor(void) +{ + int which; + + do + { + which=DoDialog(&CBCd); + switch(which) + { + case 1: + sound(1700); + if (--BkgndColor<0) + BkgndColor=15; + TEDInfo->BackgndColor=BkgndColor; + DrawMap(); + DrawInfoBar(); + break; + case 2: + sound(1700); + if (++BkgndColor>15) + BkgndColor=0; + TEDInfo->BackgndColor=BkgndColor; + DrawMap(); + DrawInfoBar(); + } + nosound(); + } while(which>0 && which<3); +} diff --git a/16/ted5/TED5-4.C b/16/ted5/TED5-4.C new file mode 100755 index 00000000..e235257d --- /dev/null +++ b/16/ted5/TED5-4.C @@ -0,0 +1,2633 @@ +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +// +// TED5-4 +// +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +#include "ted5.h" +#pragma hdrstop + + +void SignalSound(void) +{ + int i; + + for(i=0;i<10;i++) + { + sound(500+i*500); + delay(5); + nosound(); + } +} + + +//////////////////////////////////////////////////// +// +// Create an OBJ linkable file from any type of datafile +// +// Exit: +// 0 = everything's a-ok! +// -1 = file not found +// -2 = file >64K +// +//////////////////////////////////////////////////// +int MakeOBJ(char *filename,char *destfilename,char *public,segtype whichseg,char *farname) +{ + char THEADR[17]={0x80,14,0,12,32,32,32,32,32,32,32,32,32,32,32,32,0}, + COMENT[18]={0x88,0,0,0,0,'M','a','k','e','O','B','J',' ','v','1','.','1',0}, + LNAMES[42]={0x96,0,0, + 6,'D','G','R','O','U','P', + 5,'_','D','A','T','A', + 4,'D','A','T','A', + 0, + 5,'_','T','E','X','T', + 4,'C','O','D','E', + 8,'F','A','R','_','D','A','T','A'}, + SEGDEF[9]={0x98,7,0,0x48,0,0,2,3,4}, // for .DATA + SEGDEF1[9]={0x98,7,0,0x48,0,0,5,6,4}, // for .CODE + SEGDEF2[9]={0x98,7,0,0x60,0,0,8,7,4}, // for .FARDATA + GRPDEF[7]={0x9a,4,0,1,0xff,1,0x61}, + MODEND[5]={0x8a,2,0,0,0x74}; + + unsigned i,j,flag,handle; + long fsize,offset,loffset,temp,amtleft,amount,offset1; + char _seg *dblock,*block; + + + // + // Need to compute the CHECKSUM in the COMENT field + // (so if the "MakeOBJ..." string is modified, the CHECKSUM + // will be correct). + // + COMENT[1]=sizeof(COMENT)-3; + for (flag=i=0;i0x10000L) // BIGGER THAN 1 SEG = ERROR! + return -2; + + LoadIn(filename,(memptr *)&block); // LOAD FILE IN + offset=0; + + MMAllocate((memptr *)&dblock,0x10000L); + + //////////////////////////////////////////////////// + // + // INSERT HEADER RECORD + // + movedata(_DS,FP_OFF(&THEADR),(unsigned)dblock,offset,sizeof(THEADR)); + movedata(FP_SEG(filename),FP_OFF(filename), + (unsigned)dblock,offset+4,strlen(filename)); + offset+=sizeof(THEADR); + + + //////////////////////////////////////////////////// + // + // INSERT COMMENT RECORD + // + movedata(_DS,FP_OFF(COMENT),(unsigned)dblock,offset,sizeof(COMENT)); + offset+=sizeof(COMENT); + + + //////////////////////////////////////////////////// + // + // INSERT START OF LIST-OF-NAMES RECORD + // + loffset=offset; + movedata(_DS,FP_OFF(LNAMES),(unsigned)dblock,offset,sizeof(LNAMES)); + offset+=sizeof(LNAMES); + + // If it's a .FARDATA segment, we need to insert the segment name! + if (whichseg==FARDATA) + { + *(dblock+offset)=strlen(farname); + movedata(FP_SEG(farname),FP_OFF(farname), + (unsigned)dblock,offset+1,strlen(farname)); + offset+=strlen(farname)+1; + } + + // Now, finish the List-Of-Names record by creating + // the CHECKSUM and LENGTH + temp=offset; + offset=offset-loffset-2; + *(int huge *)(dblock+loffset+1)=offset; + offset=temp; + + // Now, figure out the CHECKSUM of the record + for (flag=i=0;i<(offset-loffset);i++) + flag+=*(dblock+i+loffset); + *(dblock+offset)=(flag^0xff)+1; + offset++; + + + //////////////////////////////////////////////////// + // + // CREATE SEGMENT DEFINITION RECORD + // + loffset=offset; + temp=fsize; + switch(whichseg) + { + case DATA: + movedata(FP_SEG(&SEGDEF),FP_OFF(&SEGDEF), + (unsigned)dblock,offset,sizeof(SEGDEF)); + *(int huge *)(dblock+offset+4)=temp; + offset+=sizeof(SEGDEF); + break; + case CODE: + movedata(FP_SEG(&SEGDEF1),FP_OFF(&SEGDEF1), + (unsigned)dblock,offset,sizeof(SEGDEF1)); + *(int huge *)(dblock+offset+4)=temp; + offset+=sizeof(SEGDEF1); + break; + case FARDATA: + movedata(FP_SEG(&SEGDEF2),FP_OFF(&SEGDEF2), + (unsigned)dblock,offset,sizeof(SEGDEF2)); + *(int huge *)(dblock+offset+4)=temp; + offset+=sizeof(SEGDEF2); + break; + } + + // CHECKSUM + for (flag=0,i=loffset;i>24)&0xff; + *(block+fsize+1)=(size>>16)&0xff; + *(block+fsize+2)=(size>>8)&0xff; + *(block+fsize+3)=size&0xff; + fsize+=4; + movedata(FP_SEG(ilbm),FP_OFF(ilbm),(unsigned)block,fsize,8); + fsize+=8; + *(block+fsize)=0; + *(block+fsize+1)=0; + *(block+fsize+2)=0; + *(block+fsize+3)=20; + fsize+=4; + *(block+fsize)=(TileCopy.w<<(tsize+2))/256; // pixel width + *(block+fsize+1)=(TileCopy.w<<(tsize+2))&0xff; + *(block+fsize+2)=(TileCopy.h<<(tsize+2))/256; // pixel height + *(block+fsize+3)=(TileCopy.h<<(tsize+2))&0xff; + *(int huge *)(block+fsize+4)=0; // Xorg + *(int huge *)(block+fsize+6)=0; // Yorg + *(block+fsize+8)=4; // planes + *(block+fsize+9)=0; // mask (stencil!) + *(block+fsize+10)=0; // compression (none) + *(block+fsize+11)=0; // pad (?) + *(int huge *)(block+fsize+12)=0; // trans (?) + *(int huge *)(block+fsize+14)=0x101; // aspt (aspect?) + *(int huge *)(block+fsize+16)=0x4001; // page width + *(int huge *)(block+fsize+18)=0xc800; // page height + fsize+=20; + movedata(FP_SEG(body),FP_OFF(body),(unsigned)block,fsize,4); + fsize+=4; + size=tilelen*TileCopy.w*TileCopy.h; + *(block+fsize)=(size>>24)&0xff; + *(block+fsize+1)=(size>>16)&0xff; + *(block+fsize+2)=(size>>8)&0xff; + *(block+fsize+3)=size&0xff; + fsize+=4; + + strcpy(ext,".LBM"); + } + break; + + case 2: // APPLE PREFERRED + { + int Ctable[16]={0x0000,0x000a,0x00a0,0x00aa,0x0a00,0x0a0a,0x0a50,0x0aaa, + 0x0555,0x055f,0x05f5,0x05ff,0x0f55,0x0f5f,0x0ff5,0x0fff}; + long size,pixwid; + + + PrefHeader.length=sizeof(ApPrefStr)+4L*(TileCopy.h<<(tsize+2))+ + TileCopy.w*TileCopy.h*tilelen+(((TileCopy.w*TileCopy.h*tilelen)+63)/64); + strncpy(PrefHeader.Kind,"\x4MAIN",5); + PrefHeader.MasterMode=0; + PrefHeader.PixelsPerLine=TileCopy.w<<(tsize+2); + PrefHeader.NumColorTables=1; + for (i=0;i<16;i++) + PrefHeader.ColorTable[i]=Ctable[i]; + PrefHeader.NumScanLines=TileCopy.h<<(tsize+2); + + size=sizeof(ApPrefStr)+4L*(TileCopy.h<<(tsize+2)); + MMAllocate((memptr *)&block,size); + movedata(FP_SEG(&PrefHeader),FP_OFF(&PrefHeader),(unsigned)block,fsize,sizeof(ApPrefStr)); + fsize+=sizeof(ApPrefStr); + + pixwid=TileCopy.w*(2<0) + { + if (len>64) + clen=64; + else + clen=len; + + clen--; + SaveFile(filename,(char huge *)&clen,fsize++,1); + clen++; + + SaveFile(filename,MK_FP(block1,off),fsize,clen); + fsize+=clen; + off+=clen; + len-=clen; + } + } + } + } + } + + if (which==2) + MMFreePtr((memptr *)&block1); + + MMFreePtr((memptr *)&block); + RestoreBackground(); + + ErrDialog("Graphic successfully dumped!"," Yeah! "); +} + + +//////////////////////////////////////////////////// +// +// Item - Edit TILEINFO/M values +// +//////////////////////////////////////////////////// +btype ETVb[]={{" Tileinfo ",2,21,1}, + {" TileinfoM ",16,21,1}, + {" Exit ",30,21,2}}; +DialogDef ETVd={" Edit TILEINFO/M values",38,23,3,&ETVb[0],NULL}; +int CurTIvalue; + +void Item_EditTinfoValues(void) +{ + int max,i,which,exitok=0,mx,my,b0,b1,CTRLdown; + static int whichtinfo=0; + + // + // IS THE "CTRL" KEY DOWN? + // + CTRLdown=keydown[0x1d]; + if (CTRLdown) + { + if (planeton) + whichtinfo=0; + else + whichtinfo=1; + } + + switch(whichtinfo) + { + case 0: max=tilenum; break; + case 1: max=tilemnum; + } + + switch(videomode) + { + case CGA: + case EGA1: + case VGA: + ETVd.height=23; + for(i=0;i<3;i++) + ETVb[i].yoff=21; + break; + case EGA2: + ETVd.height=58; + for(i=0;i<3;i++) + ETVb[i].yoff=56; + } + + // + // DRAW THE SCREEN + // + DrawDialog(&ETVd,1); + if (CTRLdown) + { + DrawTinfoScreen(whichtinfo,0,-max); // ALIGN TO TOP + switch(whichtinfo) + { + case 0: DrawTinfoScreen(whichtinfo,0,whicht); break; + case 1: DrawTinfoScreen(whichtinfo,0,whichtm-tilenum); + } + } + else + DrawTinfoScreen(whichtinfo,0,0); + + + do + { + which=CheckButtonsRet(&ETVd); + if (which>=0) + switch(which) + { + case 0: + RestoreBackground(); + return; + case 1: + if (whichtinfo) + { + max=tilenum; + whichtinfo=0; + DrawDialog(&ETVd,0); + DrawTinfoScreen(whichtinfo,0,0); + } + else + { + GetButtonXY(&ETVd,0,&sx,&sy); + MouseHide(); + print(ETVb[0].text); + MouseShow(); + errsound(); + } + break; + case 2: + if (!tilemnum) + { + GetButtonXY(&ETVd,1,&sx,&sy); + MouseHide(); + print(ETVb[1].text); + MouseShow(); + errsound(); + break; + } + + if (!whichtinfo) + { + max=tilemnum; + whichtinfo=1; + DrawDialog(&ETVd,0); + DrawTinfoScreen(whichtinfo,0,0); + } + else + { + GetButtonXY(&ETVd,1,&sx,&sy); + MouseHide(); + print(ETVb[1].text); + MouseShow(); + errsound(); + } + break; + + case 3: + exitok=1; + } + else + { + MouseCoords(&mx,&my); + mx/=8; + my/=8; + b0=MouseButton()&1; + b1=MouseButton()&2; + + // + // CHECK FOR BUTTON PRESSES + // + if (b0) + UseTinfoValue(whichtinfo,mx,my,1); + else + if (b1) + UseTinfoValue(whichtinfo,mx,my,0); + + // + // SPACE = ENTER VALUES HORIZONTALLY + // + if (keydown[0x39]) + { + while(keydown[0x39]); + clearkeys(); + EnterTinfoValue(whichtinfo,mx,my,0); + } + + // + // CHECK FOR SCROLLING + // + if (keydown[0x48]) // UP + { + DrawTinfoScreen(whichtinfo,0,-1); + if (keydown[0x1d]) + while(keydown[0x48]); + } + else + if (keydown[0x50]) // DOWN + { + DrawTinfoScreen(whichtinfo,0,1); + if (keydown[0x1d]) + while(keydown[0x50]); + } + else + if (keydown[0x49]) // PGUP + { + DrawTinfoScreen(whichtinfo,0,-8); + if (!keydown[0x1d]) + while(keydown[0x49]); + } + else + if (keydown[0x51]) // PGDN + { + DrawTinfoScreen(whichtinfo,0,8); + if (!keydown[0x1d]) + while(keydown[0x51]); + } + else + if (keydown[0x47]) // HOME + { + DrawTinfoScreen(whichtinfo,0,-max); + while(keydown[0x47]); + } + else + if (keydown[0x4f]) // END + { + DrawTinfoScreen(whichtinfo,0,max); + while(keydown[0x4f]); + } + else + if (keydown[0x4d]) // RIGHT + { + DrawTinfoScreen(whichtinfo,1,0); + if (!keydown[0x1d]) + while(keydown[0x4d]); + } + else + if (keydown[0x4b]) // LEFT + { + DrawTinfoScreen(whichtinfo,-1,0); + if (!keydown[0x1d]) + while(keydown[0x4b]); + } + + } + + } while(!exitok); + + RestoreBackground(); +} + + +// +// PICKUP/DROP TILEINFO VALUE AT CURSOR +// +void UseTinfoValue(int whichtinfo,int mx,int my,int PickupOrDrop) +{ + int whichx=-1,whichy=-1; + unsigned dialogx,dialogy; + + + GetDialogXY(&ETVd,&dialogx,&dialogy); + + if (mx>=dialogx+10 && mx<=dialogx+45) + whichx=(mx-(dialogx+10))/7; + + if (my>=4 && my<=((videomode==EGA2)?55:19)) + whichy=(my-4)>>(tsize-1); + + switch(whichtinfo) + { + case 0: + if (whichx>=numtplanes) + whichx=-1; + if (whichy>=tilenum) + whichy=-1; + break; + + case 1: + if (whichx>=numtmplanes) + whichx=-1; + if (whichy>=tilemnum) + whichy=-1; + } + + if (whichx>=0 && whichy>=0) + { + if (!PickupOrDrop) + switch(whichtinfo) + { + case 0: // TILE + CurTIvalue=*(Tinfo[whichx+TIxbase]+whichy+TIybase); + break; + case 1: // MASKED + CurTIvalue=*(TMinfo[whichx+TIxmbase]+whichy+TIymbase); + } + else + switch(whichtinfo) + { + case 0: // TILE + *(Tinfo[whichx+TIxbase]+whichy+TIybase)=CurTIvalue; + DirtyFlag=1; + break; + case 1: // MASKED + *(TMinfo[whichx+TIxmbase]+whichy+TIymbase)=CurTIvalue; + DirtyFlag=1; + } + + DrawTinfoScreen(whichtinfo,0,0); + } + while(MouseButton()); +} + + +// +// ENTER TILEINFO/M CELL VALUES +// +void EnterTinfoValue(int whichtinfo,int mx,int my,int H_or_V) +{ + int whichx=-1,whichy=-1,val,outok=0,tempx,tempy,maxx,maxy; + unsigned dialogx,dialogy; + + + GetDialogXY(&ETVd,&dialogx,&dialogy); + + if (mx>=dialogx+10 && mx<=dialogx+45) + whichx=(mx-(dialogx+10))/7; + + if (my>=4 && my<=((videomode==EGA2)?55:19)) + whichy=(my-4)>>(tsize-1); + + switch(whichtinfo) + { + case 0: + if (whichx>=numtplanes) + whichx=-1; + if (whichy>=tilenum) + whichy=-1; + break; + + case 1: + if (whichx>=numtmplanes) + whichx=-1; + if (whichy>=tilemnum) + whichy=-1; + } + + MouseHide(); + + if (whichx>=0 && whichy>=0) + do + { + // + // INPUT VALUE + // + sx=whichx*7+dialogx+10; + sy=(whichy<<(tsize-1))+4; + print(" "); + sx-=4; + if ((val=inputint(3))!=(int)ESCOUT) + switch(whichtinfo) + { + case 0: // TILE + *(Tinfo[whichx+TIxbase]+whichy+TIybase)=val&0xff; + DirtyFlag=1; + break; + case 1: // MASKED + *(TMinfo[whichx+TIxmbase]+whichy+TIymbase)=val&0xff; + DirtyFlag=1; + } + else + outok=1; + + // + // INPUT INTO THE NEXT FIELD! + // + if (!outok) + { + tempx=(whichtinfo?TIxmbase:TIxbase); + tempy=(whichtinfo?TIymbase:TIybase); + maxx=(whichtinfo?numtmplanes:numtplanes); + maxy=(whichtinfo?tilemnum:tilenum); + + switch(H_or_V) + { + case 0: // HORIZONTAL + whichx++; + if (tempx+whichx>=maxx) + outok=1; + else + if (whichx>TINFOWIDTH) + { + whichx=TINFOWIDTH; + tempx++; + if (tempx>=maxx) + outok=1; + } + + switch(whichtinfo) + { + case 0: TIxbase=tempx; break; + case 1: TIxmbase=tempx; + } + break; + + case 1: // VERTICAL + whichy++; + if (tempy+whichy>=maxy) + outok=1; + else + if (whichy>(videomode==EGA2?TINFOHEIGHTEGA2:TINFOHEIGHT)) + { + whichy=(videomode==EGA2?TINFOHEIGHTEGA2:TINFOHEIGHT); + tempy++; + if (tempy>=maxy) + outok=1; + } + + switch(whichtinfo) + { + case 0: TIybase=tempy; break; + case 1: TIymbase=tempy; + } + } + } + + DrawTinfoScreen(whichtinfo,0,0); + + } while (!outok); + + MouseShow(); +} + + + +// +// Draw the Tileinfo screen +// +void DrawTinfoScreen(int thescreen,int deltax,int deltay) +{ + int temp,temp1,i,j,width,height,dialogx; + char _seg *Values[10]; + + + MouseHide(); + switch(videomode) + { + case CGA: + case EGA1: + case VGA: + dialogx=1; + height=16>>(tsize-1); break; + case EGA2: + dialogx=21; + height=52>>(tsize-1); + } + + switch(thescreen) + { + case 0: // TILEINFO + if (height>tilenum) + height=tilenum; + else + { + TIybase+=deltay; + if (TIybase<0) + TIybase=0; + else + if (TIybase+height>tilenum) + TIybase=tilenum-height; + } + temp=TIybase; + break; + + case 1: // TILEINFOM + if (height>tilemnum) + height=tilemnum; + else + { + TIymbase+=deltay; + if (TIymbase<0) + TIymbase=0; + else + if (TIymbase+height>tilemnum) + TIymbase=tilemnum-height; + } + temp=TIymbase; + } + + // + // DRAW TILES AND THEIR VALUES + // + for (i=0;inumtplanes) + width=numtplanes; + else + { + TIxbase+=deltax; + if (TIxbase<0) + TIxbase=0; + else + if (TIxbase+width>numtplanes) + TIxbase=numtplanes-width; + } + temp1=TIxbase; + for (i=0;i<10;i++) + Values[i]=Tinfo[i]; + + break; + + case 1: + if (width>numtmplanes) + width=numtmplanes; + else + { + TIxmbase+=deltax; + if (TIxmbase<0) + TIxmbase=0; + else + if (TIxmbase+width>numtmplanes) + TIxmbase=numtmplanes-width; + } + temp1=TIxmbase; + for (i=0;i<10;i++) + Values[i]=TMinfo[i]; + } + + for (j=0;jtnames[j+TIxbase]); + break; + case 1: + print(" "); + sx-=7; + fprint(MapFileHeader->tmnames[j+TIxmbase]); + } + for (i=0;itnames[numtplanes]),8); + MMAllocate((memptr *)&Tinfo[numtplanes],tilenum); + for (i=0;inumtplanes=++numtplanes; + writeH=DirtyFlag=1; + break; + + case 2: + movedata(FP_SEG(temp),FP_OFF(temp), + (unsigned)MapFileHeader,FP_OFF(MapFileHeader->tmnames[numtmplanes]),8); + MMAllocate((memptr *)&TMinfo[numtmplanes],tilemnum); + for (i=0;inumtmplanes=++numtmplanes; + writeH=DirtyFlag=1; + } + + RestoreBackground(); + MouseShow(); + break; + + // + // DELETE + // + case 2: + { + unsigned ox,oy,i,oktoexit=0; + int which; + + redo: + + MouseHide(); + DrawDialog(&TINd2,1); + GetDialogXY(&TINd2,&sx,&sy); + ox=sx; + oy=sy; + DrawBorder(sx,sy+2,10,11,1); + sx=ox; + sy=oy; + DrawBorder(sx+11,sy+2,10,11,1); + + for (i=0;i<10;i++) + { + sx=ox+1; + sy=oy+i+3; + fprint(MapFileHeader->tnames[i]); + sx=ox+12; + sy=oy+i+3; + fprint(MapFileHeader->tmnames[i]); + } + MouseShow(); + + do + { + if ((which=CheckList(ox+1,oy+3,8,numtplanes,TInfoNon,TInfoNoff,0))>=0) + { + int reply; + + RestoreBackground(); + reply=DoDialog(&AreSureD2); + switch(reply) + { + case 0: + case 2: + goto redo; + } + + if (which!=numtplanes-1) + { + for (i=0;i<8;i++) + { + MapFileHeader->tnames[which][i]=MapFileHeader->tnames[numtplanes-1][i]; + MapFileHeader->tnames[numtplanes-1][i]=0; + } + for (i=0;itnames[which][i]=0; + } + writeH=DirtyFlag=1; + MapFileHeader->numtplanes=--numtplanes; + goto redo; + } + + if ((which=CheckList(ox+12,oy+3,8,numtmplanes,TInfoMNon,TInfoMNoff,0))>=0) + { + int reply; + + RestoreBackground(); + reply=DoDialog(&AreSureD2); + switch(reply) + { + case 0: + case 2: + goto redo; + } + + if (which!=numtmplanes-1) + { + for (i=0;i<8;i++) + { + MapFileHeader->tmnames[which][i]=MapFileHeader->tmnames[numtplanes-1][i]; + MapFileHeader->tmnames[numtmplanes-1][i]=0; + } + for (i=0;itmnames[which][i]=0; + } + writeH=DirtyFlag=1; + MapFileHeader->numtmplanes=--numtmplanes; + goto redo; + } + + GetButtonXY(&TINd2,0,&sx,&sy); + if (!CheckList(sx,sy,6,1,TIDoneOn,TIDoneOff,1)) + oktoexit++; + + if (keydown[1]) + { + while(keydown[1]); + oktoexit++; + } + }while(!oktoexit); + + RestoreBackground(); + } + } + } +} + + + +//////////////////////////////////////////////////// +// +// Item - Project Re-Select +// +//////////////////////////////////////////////////// +btype NGBb[]={{" Do It! ",1,4,2}, + {" No! Help! ",16,4,1}}; +DialogDef NGBd={"Are you sure you want to\n" + "switch projects? Abort now\n" + "or forever hold your peace!", + 28,6,2,&NGBb[0],NULL}; + +void Item_ProjectReSelect(void) +{ + int i,which; + + // + // ARE YOU SURE?! + // + which=DoDialog(&NGBd); + if (!which || which==2) + return; + + + TEDInfo->lastvid=videomode; + TEDInfo->level=whichmap; + SaveTEDInfo(); + SaveOutputHeader(); + + if (!CheckForMapSave()) + return; + + // + // RELEASE ALL MEMORY + // --- + if (MapBkgnd) + { + MMFreePtr((memptr *)&MapBkgnd); + MMFreePtr((memptr *)&CutBkgnd); + } + if (MapFrgnd) + { + MMFreePtr((memptr *)&MapFrgnd); + MMFreePtr((memptr *)&CutFrgnd); + } + if (MapInfoPl) + { + MMFreePtr((memptr *)&MapInfoPl); + MMFreePtr((memptr *)&CutInfoPl); + } + + MMFreePtr((memptr *)&TEDInfo); + MMFreePtr((memptr *)&MapFileHeader); + + if (CgaXMS) + { + MMFreePtr((memptr *)&CgaXMSlookup); + XMSFreeMem(CgaXMS); + } + if (EgaXMS) + { + MMFreePtr((memptr *)&EgaXMSlookup); + XMSFreeMem(EgaXMS); + } + if (VgaXMS) + { + MMFreePtr((memptr *)&VgaXMSlookup); + XMSFreeMem(VgaXMS); + } + if (XMSmaps) + XMSFreeMem(XMSmaps); + + XMSmaps=CgaXMS=EgaXMS=VgaXMS=xmshandle=0; + + + for (i=0;i>(tsize+2))+xbase; + snapy=((pixely-8)>>(tsize+2))+ybase; + snapxsize=TileCopy.w; + snapysize=TileCopy.h; + + snapx=snapx-(snapx/snapxsize)*snapxsize; + snapy=snapy-(snapy/snapysize)*snapysize; + + DrawInfoBar(); + DrawFloatPaste(); +} + + +//////////////////////////////////////////////////// +// +// Item - View Map & Goto +// +//////////////////////////////////////////////////// +void Item_ViewMap(void) +{ + Do_ViewMap(0); +} + + +//////////////////////////////////////////////////// +// +// Item - Review Map & Goto +// +//////////////////////////////////////////////////// +void Item_ReviewMap(void) +{ + Do_ViewMap(1); +} + + +//////////////////////////////////////////////////// +// +// Code to actually do the ViewMap (and save it in +// EGA memory when finished). +// Entry: +// 0 = ViewMap, as normal & save when done (but only +// if a full map was viewed) +// 1 = RestoreMap for GOTO +// +//////////////////////////////////////////////////// +void Do_ViewMap(int how) +{ + int _seg *a_bg,_seg *a_fg,_seg *a_in,CopyArea,bl_width,bl_height,bl_x,bl_y,p_info; + + char huge *EGA=MK_FP(0xa000,0); + char _seg *block,_seg *gblock[4]; + int i,j,k,m,n,pwidth,lwidth,maptype,step,pixnum[4]={0,8,16,32},curpix, + maxpack,curline,lybase,t8=8<<(tsize-1),t1=1<<(tsize-1),scrn_h,scrn_w; + long tilelen,bufsize; + int savevideo; + + + + savevideo=videomode; + MouseHide(); + setvideo(EGA1); + MouseShow(); + if (videomode!=EGA1 && videomode!=EGA2) + { + ErrDialog("This function is currently\n" + "only usable in EGA mode!"," OK "); + return; + } + + // + // SCREEN DIMENSIONS + // + scrn_w=320; + scrn_h=200; + + + bl_x=bl_y=0; + bl_width=mapwidth; + bl_height=mapheight; + a_bg=MapBkgnd; + a_fg=MapFrgnd; + a_in=MapInfoPl; + p_info=MapFileHeader->maptype; + CopyArea=0; + + if ((TileCopy.w>screenw || TileCopy.h>screenh) && !how) + if (Message("\"Yes\" to display full map,\n" + "\"No\" to display COPY buffer.")==1) + { + bl_x=TileCopy.x; + bl_y=TileCopy.y; + bl_width=TileCopy.w; + bl_height=TileCopy.h; + a_bg=CutBkgnd; + a_fg=CutFrgnd; + a_in=CutInfoPl; + p_info=TileCopy.PlanesCopied; + CopyArea=1; + } + + // + // VALIDATE WIDTH & HEIGHT + // + if (bl_height=bl_height) + { + case 1: // WIDTH > HEIGHT + step=(float)(pixnum[tsize]*bl_width)/scrn_w+.5; + if (pixnum[tsize]*bl_width/step>scrn_w) + step++; + if ((float)(pixnum[tsize]*bl_height)/step+.5 WIDTH + step=(float)(pixnum[tsize]*bl_height)/scrn_h+.5; + if (pixnum[tsize]*bl_height/step>scrn_h) + step++; + } + else + step=VMapData.step; + + + // + // POP LAST MAP ON SCREEN + // + if (how) + { + unsigned EGAseg=VMapData.EGAseg; + + if (!VMapData.built_flag) + { + ErrDialog("You haven't previously\n" + "VIEWed a map!"," OK "); + return; + } + + // + // RESTORE MAP IN MEMORY! + // + MouseHide(); + outport(GCindex,GCmode | 0x100); + outport(SCindex,SCmapmask | 0xf00); + asm push ds + asm mov ax,[EGAseg] + asm mov ds,ax + asm mov ax,0xa000 + asm mov es,ax + asm xor si,si + asm xor di,di + asm mov cx,0x2000 + asm rep movsb + asm pop ds + step=VMapData.step; + maxpack=VMapData.maxpack; + MouseShow(); + } + // + // BUILD MAP + // + else + { + // + // CLEAR EGA SCREEN + // + outport(GCindex,GCmode); + outport(SCindex,SCmapmask | 0xf00); + _fmemset(MK_FP(0xa000,0),0,0x2000); + + // + // SET TILE LENGTH + // + switch(tsize) + { + case 1: tilelen=32L; break; + case 2: tilelen=128L; break; + case 3: tilelen=512L; + } + + // + // ALLOCATE TEMP BUFFERS & BEGIN! + // + bufsize=tilelen*bl_width; + pwidth=t1*bl_width; + lwidth=pwidth*4; + MMAllocate((memptr *)&block,bufsize); + maxpack=pwidth/step+1; + for (i=0;i<4;i++) + MMAllocate((memptr *)&gblock[i],maxpack); + + outport(GCindex,GCmode); + curline=0; + for (j=bl_y;j>temp2)&1)<>temp2)&1)<>temp2)&1)<>temp2)&1)<mapwidth) + xbase=mapwidth-screenw; + if (ybase+screenh>mapheight) + ybase=mapheight-screenh; + if (xbase<0) + xbase=0; + if (ybase<0) + ybase=0; + } + while(MouseButton()); + break; + } + + clearkeys(); + MouseHide(); + setvideo(savevideo); + RedrawDesktop(); + DrawMap(); + DrawInfoBar(); + MouseShow(); +} + + +//////////////////////////////////////////////////// +// +// MAP IMPORTING FUNCTIONS FOLLOW: +// +//////////////////////////////////////////////////// +char _seg *oldnames,oldmapname[64],oldmapheadname[64], + oldSM_name[64],oldSM_loadname[64]; + +int IM_swapin(void) +{ + int i; + + + _fstrcpy(mapheadname,TEDInfo->ImportPath); + strcat(mapheadname,oldmapheadname); + if (access(mapheadname,0)) + { + strcpy(mapheadname,oldmapheadname); + return 0; + } + + _fstrcpy(mapname,TEDInfo->ImportPath); + strcat(mapname,oldmapname); + + + _fstrcpy(SM_name,TEDInfo->ImportPath); + strcat(SM_name,oldSM_name); + + _fstrcpy(SM_loadname,TEDInfo->ImportPath); + strcat(SM_loadname,oldSM_loadname); + + MMAllocate((memptr *)&oldnames,100*16); + movedata(FP_SEG(MapNames),FP_OFF(MapNames),(unsigned)oldnames,0,100*16); + + MMFreePtr((memptr *)&MapFileHeader); + + LoadIn(mapheadname,(memptr *)&MapFileHeader); + + for (i=0;i<100;i++) + if (MapFileHeader->dataoffsets[i]>=0) + { + MapHeaderStr TempHead; + + LoadFile(mapname,(char huge *)&TempHead,MapFileHeader->dataoffsets[i],sizeof(MapHeaderStr)); + strcpy(MapNames[i],TempHead.name); + } + return 1; +} + + +void IM_swapout(void) +{ + if (oldnames) // GET RID OF MAPNAMES + { + strcpy(mapname,oldmapname); + strcpy(mapheadname,oldmapheadname); + strcpy(SM_name,oldSM_name); + strcpy(SM_loadname,oldSM_loadname); + + movedata((unsigned)oldnames,0,FP_SEG(MapNames),FP_OFF(MapNames),100*16); + MMFreePtr((memptr *)&oldnames); + MMFreePtr((memptr *)&MapFileHeader); + LoadIn(mapheadname,(memptr *)&MapFileHeader); + + } +} + +void IM_LoadMap(void) +{ + unsigned long csize,size=0; + memptr block; + + // + // DEALLOCATE ALL CURRENT MAP MEMORY + // + if (MapBkgnd) + { + MMFreePtr((memptr *)&MapBkgnd); + MMFreePtr((memptr *)&CutBkgnd); + } + if (MapFrgnd) + { + MMFreePtr((memptr *)&MapFrgnd); + MMFreePtr((memptr *)&CutFrgnd); + } + if (MapInfoPl) + { + MMFreePtr((memptr *)&MapInfoPl); + MMFreePtr((memptr *)&CutInfoPl); + } + + // + // LOAD MAP HEADER + // + LoadFile(mapname,(char huge *)&MapHeader,MapFileHeader->dataoffsets[whichmap],sizeof(MapHeaderStr)); + + // + // LOAD & DECOMPRESS MAP PLANES + // + if (MapFileHeader->maptype & BPLANE) + { + LoadFile(mapname,(char huge *)&size,MapHeader.mapbkgndpl,2); + + MMAllocate((memptr *)&MapBkgnd,size); + MMAllocate((memptr *)&CutBkgnd,size); + csize=MapHeader.mapbkgndlen-2; + MMAllocate(&block,csize); + + LoadFile(mapname,MK_FP(block,0),MapHeader.mapbkgndpl+2,csize); + + RLEWExpand(MK_FP(block,0),MK_FP(MapBkgnd,0),size,MapFileHeader->RLEWtag); + MMFreePtr(&block); + } + if (MapFileHeader->maptype & FPLANE) + { + LoadFile(mapname,(char huge *)&size,MapHeader.mapfrgndpl,2); + + MMAllocate((memptr *)&MapFrgnd,size); + MMAllocate((memptr *)&CutFrgnd,size); + csize=MapHeader.mapfrgndlen-2; + MMAllocate(&block,csize); + + LoadFile(mapname,MK_FP(block,0),MapHeader.mapfrgndpl+2,csize); + + RLEWExpand(MK_FP(block,0),MK_FP(MapFrgnd,0),size,MapFileHeader->RLEWtag); + MMFreePtr(&block); + } + if (MapFileHeader->maptype & IPLANE) + { + LoadFile(mapname,(char huge *)&size,MapHeader.mapinfopl,2); + + MMAllocate((memptr *)&MapInfoPl,size); + MMAllocate((memptr *)&CutInfoPl,size); + csize=MapHeader.mapinfolen-2; + MMAllocate(&block,csize); + + LoadFile(mapname,MK_FP(block,0),MapHeader.mapinfopl+2,csize); + + RLEWExpand(MK_FP(block,0),MK_FP(MapInfoPl,0),size,MapFileHeader->RLEWtag); + MMFreePtr(&block); + } +} + + +void IM_SaveMap(void) +{ + memptr block; + long fsize,size,nsize,change; + MapHeaderStr TempHeader; + int i,XMStemp; + char string[100],TEDid[]=IDSTRING; + + + + strcpy(string,"Saving Map, '"); + strcat(string,MapHeader.name); + + strcat(string,"'."); + ErrDialog(string,""); + + // + // SAVE MAP FILE HEADER + // + SaveFile(mapheadname,MK_FP(MapFileHeader,0),0,sizeof(MapFileHeaderStr)); + fsize=sizeof(MapFileHeaderStr); + + // + // COMPRESS & SAVE TILEINFOS + // + for (i=0;itileinfooff[i]=fsize; + nsize=RLEBCompress(MK_FP(Tinfo[i],0),tilenum,MK_FP(block,0),MapFileHeader->RLEWtag); + MapFileHeader->tileinfolen[i]=nsize; + SaveFile(mapheadname,MK_FP(block,0),fsize,nsize); + fsize+=nsize; + MMFreePtr(&block); + } + + for (i=0;itileinfomoff[i]=fsize; + nsize=RLEBCompress(MK_FP(TMinfo[i],0),tilemnum,MK_FP(block,0),MapFileHeader->RLEWtag); + MapFileHeader->tileinfomlen[i]=nsize; + SaveFile(mapheadname,MK_FP(block,0),fsize,nsize); + fsize+=nsize; + MMFreePtr(&block); + } + + MapFileHeader->oldtilenum=tilenum; + MapFileHeader->oldtilemnum=tilemnum; + + SaveFile(mapheadname,MK_FP(MapFileHeader,2),2,sizeof(MapFileHeaderStr)-2); + // + // SAVE ALREADY COMPRESSED MAPS + // + + // + // NOTE: I AM STORING "TED5" AT THE START OF THE FILE BECAUSE + // SAVING THE FILE AT OFFSET 0 WILL TRASH IT (I HAVE TO RE-SAVE THE HEADER!) + // + SaveFile(SM_name,(char huge *)TEDid,0,strlen(TEDid)); + fsize=strlen(TEDid); + + for (i=0;i<100;i++) + { + long oldoff; + + if (MapFileHeader->dataoffsets[i]==-1 || i==whichmap) + continue; + + oldoff=MapFileHeader->dataoffsets[i]; + + LoadFile(SM_loadname,(char huge *)&TempHeader,oldoff,sizeof(MapHeaderStr)); + + strcpy(TempHeader.name,MapNames[i]); + MapFileHeader->dataoffsets[i]=fsize; + size=TempHeader.mapbkgndlen+TempHeader.mapfrgndlen+TempHeader.mapinfolen; + change=TempHeader.mapbkgndpl-fsize-sizeof(MapHeaderStr); + TempHeader.mapbkgndpl-=change; + TempHeader.mapfrgndpl-=change; + TempHeader.mapinfopl-=change; + + SaveFile(SM_name,(char huge *)&TempHeader,fsize,sizeof(MapHeaderStr)); + fsize+=sizeof(MapHeaderStr); + + MMAllocate(&block,size); + LoadFile(SM_loadname,MK_FP(block,0),oldoff+sizeof(MapHeaderStr),size); + SaveFile(SM_name,MK_FP(block,0),fsize,size); + fsize+=size; + SaveFile(SM_name,"!ID!",fsize,4); + fsize+=4; + MMFreePtr(&block); + } + + // + // SAVE CURRENT MAP AT END OF FILE + // + MapFileHeader->dataoffsets[whichmap]=fsize; + MapFileHeader->datalengths[whichmap]=sizeof(MapHeaderStr); + SaveFile(SM_name,(char huge *)&MapHeader,fsize,sizeof(MapHeaderStr)); + fsize+=sizeof(MapHeaderStr); + + size=MapHeader.width*MapHeader.height*sizeof(int); + MMAllocate(&block,size); + if (MapFileHeader->maptype & BPLANE) + { + MapHeader.mapbkgndpl=fsize; + nsize=RLEWCompress(MK_FP(MapBkgnd,0),size,MK_FP(block,0),MapFileHeader->RLEWtag); + MapHeader.mapbkgndlen=nsize+2; + + SaveFile(SM_name,(char huge *)&size,fsize,2); + fsize+=2; + SaveFile(SM_name,MK_FP(block,0),fsize,nsize); + fsize+=nsize; + } + else + MapHeader.mapbkgndlen=0; + + if (MapFileHeader->maptype & FPLANE) + { + MapHeader.mapfrgndpl=fsize; + nsize=RLEWCompress(MK_FP(MapFrgnd,0),size,MK_FP(block,0),MapFileHeader->RLEWtag); + MapHeader.mapfrgndlen=nsize+2; + + SaveFile(SM_name,(char huge *)&size,fsize,2); + fsize+=2; + SaveFile(SM_name,MK_FP(block,0),fsize,nsize); + fsize+=nsize; + } + else + MapHeader.mapfrgndlen=0; + + if (MapFileHeader->maptype & IPLANE) + { + MapHeader.mapinfopl=fsize; + nsize=RLEWCompress(MK_FP(MapInfoPl,0),size,MK_FP(block,0),MapFileHeader->RLEWtag); + MapHeader.mapinfolen=nsize+2; + + SaveFile(SM_name,(char huge *)&size,fsize,2); + fsize+=2; + SaveFile(SM_name,MK_FP(block,0),fsize,nsize); + fsize+=nsize; + } + else + MapHeader.mapinfolen=0; + + SaveFile(SM_name,"!ID!",fsize,4); + + fsize+=4; + + MMFreePtr(&block); + + // RE-SAVE HEADER + SaveFile(SM_name,(char huge *)&MapHeader, + MapFileHeader->dataoffsets[whichmap],sizeof(MapHeaderStr)); + + // + // RE-SAVE FILE HEADER + // NOTE: The "2" is so MSDOS doesn't truncate the fucking file! + // + SaveFile(mapheadname,MK_FP(MapFileHeader,2),2,sizeof(MapFileHeaderStr)-2); + + unlink(SM_loadname); + rename(SM_name,SM_loadname); + + RestoreBackground(); +} + + +//////////////////////////////////////////////////// +// +// Item - Import Maps +// +//////////////////////////////////////////////////// +btype IMPMb[]={{"New Path",3,2,1}, + {" Import ",3,5,1}, + {" Exit ",3,8,2}}; +DialogDef IMPMd={"Map Importing",13,11,3,&IMPMb[0],NULL}; +btype NPb={" ",1,3,1}; +DialogDef NPd={"Current Path:",38,5,1,&NPb,NULL}; + + +void Item_ImportMaps(void) +{ + char imfile[64],tempstr[40],impath[64]; + int oldwhichmap,which,mapnum,i; + int oldxb,oldyb; + + + CheckForMapSave(); + + // + // THE IMPORT FUNCTION WILL RID THE SYSTEM OF XMSMAPS + // + if (XMSmaps) + { + XMSFreeMem(XMSmaps); + XMSmaps=0; + } + + // + // SAVE PATHS + // + _fstrcpy(impath,TEDInfo->ImportPath); + + strcpy(oldmapname,mapname); + strcpy(oldmapheadname,mapheadname); + strcpy(oldSM_name,SM_name); + strcpy(oldSM_loadname,SM_loadname); + + oldxb=xbase; + oldyb=ybase; + #pragma warn -sus + oldnames=0; + #pragma warn +sus + oldwhichmap=whichmap; + + DrawDialog(&IMPMd,1); + while(1) + { + which=CheckButtons(&IMPMd); + switch(which) + { + // + // NEW PATH + // + case 1: + MouseHide(); + DrawDialog(&NPd,1); + GetDialogXY(&NPd,&sx,&sy); + sy++; + sx++; + if (!impath[0]) + print("- current dir -"); + else + print(impath); + GetButtonXY(&NPd,0,&sx,&sy); + if (input(tempstr,36)) + { + strcpy(impath,tempstr); + if (impath[strlen(impath)-1]!='\\') + strcat(impath,"\\"); + + MouseShow(); + if (access(mapheadname,0)) + { + ErrDialog("Can't find any TED5\n" + "map files at that path."," OK "); + } + else + { + RestoreBackground(); + ErrDialog("Verifying path...",""); + _fstrcpy(TEDInfo->ImportPath,impath); + DirtyFlag=1; + } + + MouseHide(); + } + MouseShow(); + RestoreBackground(); + break; + + // + // IMPORT + // + case 2: + if (!oldnames) + { + ErrDialog("Loading File Info...",""); + if (!IM_swapin()) + { + RestoreBackground(); + ErrDialog("Having problems with your path!"," OK "); + break; + } + RestoreBackground(); + } + + mapnum=SelectMap(1,CREATED,"TO IMPORT"); + if (mapnum>=0) + { + char check[100]="Are you SURE you want to\n" + "Import "; + + strcat(check,MapNames[mapnum]); + strcat(check,"?"); + if (Message(check)<2) + break; + + whichmap=mapnum; + ErrDialog("Importing. One moment.",""); + IM_LoadMap(); + IM_swapout(); + IM_SaveMap(); + IM_swapin(); + RestoreBackground(); + } + break; + + // + // EXIT + // + case 0: + case 3: + RestoreBackground(); + whichmap=oldwhichmap; + IM_swapout(); + + LoadMap(whichmap); + xbase=oldxb; + ybase=oldyb; + DrawMap(); + + return; + } + } +} + + +//////////////////////////////////////////////////// +// +// Item - Visit DOS +// +//////////////////////////////////////////////////// +int olddisk; +char oldpath[64]="\\"; + +void Item_VisitDOS(void) +{ + TempStruct LaunchInfo; + char ename[64],temp[40],tiname[14]="TEDINFO.TMP"; + + long size; + + + // + // Save the handles for all XMS memory so we don't + // have to re-install this shit! + // + TEDInfo->OldCgaXMS=CgaXMS; + TEDInfo->OldEgaXMS=EgaXMS; + TEDInfo->OldVgaXMS=VgaXMS; + + TEDInfo->OldCgaXMSsize=CgaXMSsize; + TEDInfo->OldEgaXMSsize=EgaXMSsize; + TEDInfo->OldVgaXMSsize=VgaXMSsize; + + size=4L*(tilenum+tilemnum); + if (CgaXMS) + { + if (1024L*XMSTotalFree()OldCgaXMS=TEDInfo->OldCgaXMSsize=0; + } + else + { + TEDInfo->CgaXMSlook=XMSAllocate(size); + XMSmove(0,(long)MK_FP(CgaXMSlookup,0),TEDInfo->CgaXMSlook,0,size); + } + } + + if (EgaXMS) + { + if (1024L*XMSTotalFree()OldEgaXMS=TEDInfo->OldEgaXMSsize=0; + } + else + { + TEDInfo->EgaXMSlook=XMSAllocate(size); + XMSmove(0,(long)MK_FP(EgaXMSlookup,0),TEDInfo->EgaXMSlook,0,size); + } + } + + if (VgaXMS) + { + if (1024L*XMSTotalFree()OldVgaXMS=TEDInfo->OldVgaXMSsize=0; + } + else + { + TEDInfo->VgaXMSlook=XMSAllocate(size); + XMSmove(0,(long)MK_FP(VgaXMSlookup,0),TEDInfo->VgaXMSlook,0,size); + } + } + + // + // SAVE CURRENT VIDEOMODE FOR LAUNCH RETURN + // + LaunchInfo.lastmode=videomode; + strcpy(LaunchInfo.ext,ext); + SaveFile(tiname,(char huge *)&LaunchInfo,0,sizeof(TempStruct)); + + TEDInfo->oscrx=xbase; + TEDInfo->oscry=ybase; + _fmemcpy((void far *)TEDInfo->parmstring,(void far *)parmstring,64); + + Item_SaveMap(); + SaveTEDInfo(); + SaveOutputHeader(); + + if (XMSmaps) + XMSFreeMem(XMSmaps); + + strcpy(temp,"Launching "); + _fstrcat((char far *)temp,(char far *)TEDInfo->launchname); + strcat(temp,"..."); + ErrDialog(temp,""); + clearkeys(); + nosound(); + MouseHide(); + + _fmemcpy((char far *)ename,(char far *)TEDInfo->launchname,14); + + RemoveUndoBuffers(); + ShutdownKBD(); + + // + // ARE WE EXITING WITH A BATCH FILE? + // + + setvideo(TEXT); + printf("The TED5 DOS shell. Type 'EXIT' to return to TED5."); + + // + // SAVE CURRENT DRIVE & PATH + // + olddisk=getdisk(); + getcurdir(0,oldpath+1); + + MMShutdown(); + fcloseall(); + spawnlp(P_WAIT,"COMMAND",NULL); + + // + // RESET OLD PATH + // + setdisk(olddisk); + chdir(oldpath); + + execlp("TED5.EXE","TED5.EXE","/LAUNCH",NULL); + + printf("Can't find TED5 for some reason!"); + exit(1); +} + + +//////////////////////////////////////////////////// +// +// Item - Paste Overlay toggle +// +//////////////////////////////////////////////////// +void Item_POtog(void) +{ + F3_flag^=1; + + if (PasteMode) + { + EraseFloatPaste(); + DrawFloatPaste(); + } +} diff --git a/16/ted5/TED5.C b/16/ted5/TED5.C new file mode 100755 index 00000000..8614ef9d --- /dev/null +++ b/16/ted5/TED5.C @@ -0,0 +1,2779 @@ +//////////////////////////////////////////////////// +// +// TED 5 +// MultiVideo mode, MultiTile size, MultiMap editor +// by John Romero (C) 1991 Id Software +// +// Development Log: +// ------------------------------------------------- +// Mar 19 91 - Starting this thing! Getting it to +// compile with the JHUFF and MEM stuff. +// +// Mar 20 91 - Got the whole deal compiling and wrote +// the EGA drawchar routine and got most of +// Dialogs written! +// +// Mar 25 91 - Forgot some days in there! Got the XMS +// stuff going and started the big initialization +// part. Past init will be lots easier! +// +// Mar 30 91 - Got map selection and dimensioning and +// allocation done. Added more MENU abilities to +// allow more flexible dialogs. +// +// Apr 7 91 - Got project initialization done. Got +// tiles into XMS. Wrote XMS routines for all +// memory functions needed. +// +// Apr 12 91 - FINALLY got the maps loading and saving +// correctly - NO THANKS TO MR.C OVER THERE! You +// see, he can't remember whether his expansion +// routines use the compressed or expanded length +// and that was causing me quite a problem. Got +// it solved and the map shuffling shit works +// PERFECTLY now! Got tile select in, map stats, +// and other stuff... +// +// Apr 19 91 - Got all 3 planes working (drawing,etc.) +// TileSelect screens jam...lots of little options +// thrown in... !!! I got my '75 Cougar !!! +// +// Apr 25 91 - Got map dimension changing done! Fixed +// some small bugs...had a WHOPPER of a fucking +// bug today ... I was overwriting the stack +// when the first background save happened. I'm SURE +// I allocated enough memory -- I don't know... +// +// Apr 27 91 - Map Edge Select works (for Copy) & now I +// draw a frame around the entire region. +// +// May 01 91 - Added a nice feature - retaining the Copy +// buffer wherever it may get toasted. Used XMS so +// I didn't chew mainmem. Also made it so you can +// turn the plane READ/WRITEs ON/OFF (obvious advantage). +// Got Copy/Paste from everywhere with FloatingPaste! +// +// May 03 91 - Got entering values for infoplane stuff & all +// that shit encompasses. Trying to get a cursor drawn +// (with backgrnd save/restore) in CGA & EGA3 modes. +// Wish me luck! ... FUCK IT! I removed EGA3 mode -- it +// was too much shit & kludgery to get a cursor going. +// +// May 08 91 - Well! Let's see...I got Huffman map compression +// done; wrote a MakeOBJ function that can be used within +// the Memory Manager or Standard Borland C. Added .OBJ +// generation to IGRAB. Started the function to generate +// graphic map dumps. Modified the MapHeader stuff more +// when John needed "extras". +// +// May 09 91 - Finished ILBM & Apple Preferred map dumps! +// Fixed a couple hidden bugs, made some things nicer, +// started on Flood Fill... +// +// May 11 91 - Got the TILEINFO/M stuff structured and loading +// and saving (with compression). Putting all the "hidden" +// commands in the menus... +// +// May 13 91 - Stuck in a PROJECT SELECT option (for the Keen2 +// trilogy, it'll be nice). +// +// May 16 91 - Got all of TILEINFO stuff finished. Tom and +// Jason's first day! Tom BETAed IGRAB & TED5 big time. +// Had to basically dump the GraphHeaderStr and just +// make the ?GAHEAD.ext file all dataoffsets! (The simpler, +// the better!) +// +// May 19 91 - Almost got the Flood Fill mode working...Tom +// started drawing maps a little early & now I need to add +// a little kludge-fix to reformat his old maps... +// +// May 22 91 - Got AWESOME UNDO working ... fixed the nagging little +// paste/scrolling bug fixed (separated the PasteErase +// & PasteDraw routines) ... finished Block Fill ... fixed +// the floating paste/tile showthru bug ... +// +// May 27 91 - Basically finished up. Tom is BETAing now. I need +// to make SelectMap accept the arrows & make an array for +// the map names instead of the sorry way I'm doing it now. +// +// Jun 2 91 - Got level launching working! Been working on +// TED5 and IGRAB docs and MUSE most of the time. +// +// Jun 18 91 - v0.13 because John C.'s system didn't have +// the SCmapmask set to 15 in CopyEGA! +// +// Jun 20 91 - v0.14: It's annoying to LAUNCH the game and come +// back at the top-left corner! +// +// Jun 26 91 - v0.17: Made LAUNCH with ICON CHANGE ctrl-alt-L +// because Tomshit was having problems...adding Unused Tile +// Scan...fixing a couple minor Tom-irritants... +// +// Jul 12 91 - v0.23: Made VGA & CGA work! Fixed a small +// bug with plane-on starting...added a GridMode for the +// FloatingPaste...XMS Map-Cache...now saves the Launchname +// in TEDINFO? so user program doesn't need to send anything +// back but /LAUNCHED...finally fixed nagging FloatingPaste +// multi-plane viewing bug... +// +// Jul 19 91 - v0.24: Changed TEDINFO structure and added GFXINFO +// to IGRAB. Got most all bugs out...lowercase input now... +// +// Jul 23 91 - v0.26: Only write out .H if it needs to...got the +// SnapPaste feature in that Tom wanted... +// +// Aug 08 91 - v0.28: I can't believe this shit! Mr. Tom decided +// to enter the value "0xF00D" into the map, which was my secret +// value for passing an ESC press back from "inputint". I made +// it a #define now! +// +// Aug 09 91 - v0.29: I FUCKING FRIED THE LIB_A.ASM & LIB.C FILES! +// THESE USED TO HOLD TED5'S TILE-DRAWING AND CGA/VGA ROUTINES! +// AAAARRRRGGGG!!!! Trying to recontruct the program. It'll +// take a bit (I was trying to fix a bug in EditMapNames). +// +// Aug 14 91 - v0.30: Just got finished fixing the FRIED SOURCE HELL! +// +// Aug 16 91 - v0.31: Heh heh, I added the ViewMap function! +// +// Aug 19 91 - v0.32: Added the MapImport function and it works! YES! +// +// Aug 22-23 - v0.35: Fixed a WHOLE BUNCH of little things and added +// some cool features like easier TILEINFO entering, default +// Import drive, F3 to toggle Paste Overlay, etc. Very nice now. +// +// Aug 24 91 - v0.38: Fixed a bug in passing multiple command-line +// parameters to LAUNCHed program. Let user enter new parms and +// a new launch name while in TED5. Added the CarmackCompression +// and trashed the Huffman shit. +// +// Sep 07 91 - v0.40: Only ViewMap planes viewable instead of all; flag +// currently loaded map in SelectMap dialog; check NumIconRows for +// a bogus value for old TED5 compatibility; show map dimensions in +// ChangeMapEdges dialog; CTRL-ALT-arrows will go to map edges. +// +// Sep 12 91 - v0.41: Let user PERMANENTLY change the Launch icon. Also, +// the plane flags are always saved! +// +// Sep 27 91 - v0.43: Added REVIEW_MAP function. Fixed a hard-to-find bug +// in the BlockFill-with-pattern function. +// +// Sep 29 91 - v0.44: Fixed small annoying bug w/Flood-fill w/pattern. +// +// Oct 12 91 - v0.45: Added the PrintReport feature after Carmacizing +// all the maps. +// +// Nov 24 91 - v0.48: Saving the Import Path, added TILEINFOM copying +// from one area to another, getting rid of the "turning the plane +// viewing ON automatically sets it for writing." +// +// May 22 92 - v0.49: Added graphics-select switch to get rid of a dialog. +// +// Oct 20 95 - v0.50: Fixed EGA scrolling bug, added screensaver which comes +// on automatically after 2 minutes. Timelimit adjustable +// through TIMELIMIT command line MED +// +//////////////////////////////////////////////////// +#include "ted5.h" +#pragma hdrstop + +extern unsigned _stklen=0x2000; + +//////////////////////////////////////////////////// +// +// Variables +// +//////////////////////////////////////////////////// +extern char far TEDCHAR,far VGAPAL,tdata; +extern unsigned doubled[256]; + +UndoStr UndoRegion; +CopyStr TileCopy; +MapFileHeaderStr _seg *MapFileHeader; +char _seg *Tinfo[10],_seg *TMinfo[10],_seg *GraphHeader; +long _seg *XMSlookup,_seg *EgaXMSlookup,_seg *CgaXMSlookup,_seg *VgaXMSlookup; +int _seg *MapBkgnd,_seg *MapFrgnd,_seg *MapInfoPl, + _seg *CutBkgnd,_seg *CutFrgnd,_seg *CutInfoPl; +MapHeaderStr MapHeader; + +TempStruct LaunchInfo; +InfoStruct _seg *TEDInfo; +GfxStruct _seg *GFXInfo; +video lastvideo,videomode; +screentype whichscreen=TILES; +VMapStr VMapData; + +char launchname[64],ext[4],format[2],projname[64],mapname[64],planes, + infoname[64],mapheadname[64],MapNames[100][16],parmstring[64]; +char SM_name[64],SM_loadname[64],BkgndColor,GfxToUse; + +unsigned temp,whichmap,numtplanes,tilenum,tilemnum,numtmplanes,left, + DirtyFlag,tilelen,tilemlen,whicht,whichtm,whichi, + tsize,infoy,infomaxw,mapwidth,mapheight,screenw,usingbat, + screenh,planeton,planemon,planeion,maxiconrows,lasticon,firsticon, + viewton,viewmon,viewion,XMSundoB,XMSundoF,XMSundoI,launched, + XMSmaps,EgaXMS,CgaXMS,VgaXMS,xmshandle,GridMode,SnapMode,snapx, + snapy,snapxsize,snapysize,writeH,NoAbout,F3_flag; +int tilebase=0,tilembase=0,infobaron=1,xbase,ybase,scrnbot,scrnrgt, + FillMode=0,PasteMode=0,SelectMode=0,SelX1=-1,SelY1=-1,PasteOK=0,SelX2=-1, + SelY2=-1,pixelx,pixely,selectcols,px,py,lastmap=-1,TIybase,TIymbase,TIxbase, + TIxmbase,BfillMode,Plotting,TsearchMode,NoXMSFlag; +long CgaXMSsize,EgaXMSsize,VgaXMSsize; +long tics, tictime=1092L*2L; + + +// +// harderr-called routine +// +int ignore(void) +{ + hardresume(0); + return 0; +} + +//////////////////////////////////////////////////// +// +// Start of The Beast From Hell +// +//////////////////////////////////////////////////// +void main(void) +{ + ParseCmdline(); + SetupKBD(); + MMStartup(); + setvideo(EGA1); + lastvideo=EGA1; + InitTed5(); + harderr(ignore); + tics=biostime(0,0); + DeskEventLoop(HandleEvent,Continuous); +} + +//////////////////////////////////////////////////// +// +// Parse the commandline +// +//////////////////////////////////////////////////// +void ParseCmdline(void) +{ + int i; + + for (i=1;i<_argc;i++) + { + _argv[i]=strupr(_argv[i]); + + if (_argv[i][0]=='-' || _argv[i][0]=='/') + _argv[i]++; + + if (!strcmp(_argv[i],"?")) + { + printf(TITLESTR" by John Romero (C) 1991 Id Software, Inc.\n\n"); + printf("Command Line parameters:\n"); + printf("/? : gets this stuff\n"); + printf("/EXT=??? : set the project extension\n"); + printf(" : set the Launch filename\n"); + printf("/PARMS= : set parms to Launch with\n"); + printf("/NOXMSMAPS : don't cache maps in XMS\n"); + printf("/GFX=??? : set gfx to use - E,C,V\n"); + printf("/TIME=??? : half-minutes until screenblanker (default 2 minutes)\n"); + exit(0); + } + else + if (!strncmp(_argv[i],"EXT=",4)) + strcpy(ext,&_argv[i][4]); + else + if (!strncmp(_argv[i],"GFX=",4)) + GfxToUse = _argv[i][4]; + else + if (!strcmp(_argv[i],"LAUNCH")) + launched=1; + else + if (!strcmp(_argv[i],"BAT")) + usingbat=1; + else + if (!strncmp(_argv[i],"PARMS=",6)) + strcpy(parmstring,&_argv[i][6]); + else + if (!strncmp(_argv[i],"TIME=",5)) + tictime=(atol(&_argv[i][5]))*546L; + else + if (!strcmp(_argv[i],"NOXMSMAPS")) + NoXMSFlag=1; + else + if (!strcmp(_argv[i],"NOABOUT")) + NoAbout=1; + else + strcpy(launchname,_argv[i]); + } +} + + +//////////////////////////////////////////////////// +// +// Event handler - called when button is pressed +// outside menu bar +// +//////////////////////////////////////////////////// +void HandleEvent(void) +{ + int pixelx,pixely,mx,my,b0,b1; + unsigned loc; + + b0=MouseButton()&1; + b1=(MouseButton()>>1)&1; + + MouseCoords(&mx,&my); + pixely=my; + pixelx=mx; + + // + // PLOT OR PICK-UP TILE + // + if (my>=8 && my>(tsize+2)); + my=ybase+((my-8)>>(tsize+2)); + + loc=my*mapwidth+mx; + + if (mx>=mapwidth || my>=mapheight) + errsound(); + else + { + if (b1) + { + // + // SELECT BOTTOM-RIGHT EDGE + // + if (SelectMode || BfillMode) + { + SelX2=mx; + SelY2=my; + if ((SelX1==-1 && SelY1==-1) || + (SelX2>1); + nosound(); + } + if (b0) + { + // + // SELECT TOP-LEFT EDGE + // + if (SelectMode || BfillMode) + { + SelX1=mx; + SelY1=my; + if ((SelX2==-1 && SelY2==-1) || + (SelX1>SelX2 || SelY1>SelY2)) + { + SelX2=mx; + SelY2=my; + } + + DrawMap(); + sound(2000); + while(MouseButton()); + } + // + // FLOOD FILL! + // + else + if (FillMode) + { + while(MouseButton()); + DoFloodFill(mx,my,0); + } + // + // PASTE A CHUNK O' TILES/MAP + // + else + if (PasteMode) + { + if (TileCopy.MapOrTileSelect) // TILE-SELECT AREA? + { + int i,j; + + if (SnapMode) + { + mx=(mx/snapxsize)*snapxsize+snapx; + my=(my/snapysize)*snapysize+snapy; + } + + if (mx+TileCopy.w>mapwidth || + my+TileCopy.h>mapheight) + sound(500); + else + { + CopyUndoRegion(); + UndoRegion.x=mx; + UndoRegion.y=my; + UndoRegion.w=TileCopy.w; + UndoRegion.h=TileCopy.h; + + sound(500); + switch(TileCopy.MapOrTileSelect) + { + case 1: // TILES + for (j=0;jUndoRegion.x+UndoRegion.w) + UndoRegion.w=mx-UndoRegion.x+1; + if (my+1>UndoRegion.y+UndoRegion.h) + UndoRegion.h=my-UndoRegion.y+1; + + if (planeton) + *(MapBkgnd+loc)=whicht; + if (planemon) + *(MapFrgnd+loc)=whichtm-tilenum; + if (planeion) + *(MapInfoPl+loc)=whichi-tilenum; + + oldt=MapBkgnd[loc]; + oldm=MapFrgnd[loc]+tilenum; + oldi=MapInfoPl[loc]+tilenum; + + CombineTiles(viewton?oldt:-BkgndColor,viewmon*oldm,oldi*viewion,tsize); + if (GridMode) + Overlay(tsize); + MouseHide(); + DrawTile((mx-xbase)<<(tsize-1),(my-ybase)*(4<infoy*8) + { + if (pixelx<7*8) + SelectTiles(1); + else + if (pixelx<8*14 && tilemnum) + SelectTiles(2); + else + if (pixelx<8*20 && tilemnum) + SelectTiles(3); + } + +} + +#define PEL_WRITE_ADR 0x3c8 +#define PEL_READ_ADR 0x3c7 +#define PEL_DATA 0x3c9 +#define PEL_MASK 0x3c6 + +void ScreenBlank ( void ) +{ + int done; + int x; + int y; + int r; + int g; + int b; + int c; + int oldx,oldy; + int i, j; + int xdir,ydir; + int cury; + int size; + int type; + struct { + int x,y; + } snake[256]; + + unsigned char far * screen=(unsigned char far *)0xa0000000l; + + + randomize(); + _AX=0x13; + asm int 10h + done=0; + size=random(10)+2; + clearkeys(); + + for (i=255;i>=0;i--) + { + snake[i].x=160; + snake[i].y=100; + } + type=random(11); + r=random(200)+56; + g=random(200)+56; + b=random(200)+56; + outp (PEL_WRITE_ADR,0); + for (i=0;i<=255;i++) + { + outp (PEL_DATA, (unsigned char)((i*r)>>10)); + outp (PEL_DATA, (unsigned char)((i*g)>>10)); + outp (PEL_DATA, (unsigned char)((i*b)>>10)); + } + xdir=0; + while (!xdir) + xdir=random(size<<1)-size; + ydir=0; + while (!ydir) + ydir=random(size<<1)-size; + while (!done) + { + if ((random(100)-80)>0) + { + xdir+=random(3)-1; + ydir+=random(3)-1; + } + for (i=255;i>0;i--) + snake[i]=snake[i-1]; + snake[0].x+=xdir; + snake[0].y+=ydir; + if ((snake[0].x320-(size+1))) + { + xdir=-xdir; + snake[0].x+=xdir<<1; + } + else if (abs(xdir)>size-1) + xdir=-(xdir>>1); + if ((snake[0].y200-(size+1))) + { + ydir=-ydir; + snake[0].y+=ydir<<1; + } + else if (abs(ydir)>size-1) + ydir=-(ydir>>1); + for (x=255;x>=0;x--) + { + if (type<7) + { + for (j=snake[x].y,cury=320*snake[x].y;jtictime) + { + MouseHide(); + ScreenBlank(); + clearkeys(); + videomode=lastvideo; + Item_ModeSwitch(); + RedrawDesktop(); + DrawMap(); + DrawInfoBar(); + MouseShow(); + tics=biostime(0,0); + } + oldx=pixelx; + oldy=pixely; + MouseCoords(&pixelx,&pixely); + if ((oldx!=pixelx) || (oldy!=pixely)) + { + tics=biostime(0,0); + PrintCoords(); + } + + if (!MouseButton()) + Plotting=0; + + // + // PLANE "WRITE" SELECTION + // + if (keydown[2] && viewton) + { + planeton^=1; + DrawInfoBar(); + DrawMap(); + PrintCoords(); + tics=biostime(0,0); + while(keydown[2]); + } + if (keydown[3] && tilemnum && (MapFileHeader->maptype&FPLANE) && viewmon) + { + planemon^=1; + DrawInfoBar(); + DrawMap(); + PrintCoords(); + tics=biostime(0,0); + while(keydown[3]); + } + if (keydown[4] && (MapFileHeader->maptype&IPLANE) && viewion) + { + planeion^=1; + DrawInfoBar(); + DrawMap(); + PrintCoords(); + tics=biostime(0,0); + while(keydown[4]); + } + + // + // PLANE "VIEW" SELECTION + // + if (keydown[5]) + { + viewton^=1; + if (!viewton) + planeton=0; + DrawInfoBar(); + DrawMap(); + PrintCoords(); + tics=biostime(0,0); + while(keydown[5]); + } + if (keydown[6] && tilemnum && (MapFileHeader->maptype&FPLANE)) + { + viewmon^=1; + if (!viewmon) + planemon=0; + DrawInfoBar(); + DrawMap(); + PrintCoords(); + tics=biostime(0,0); + while(keydown[6]); + } + if (keydown[7] && (MapFileHeader->maptype&IPLANE)) + { + viewion^=1; + if (!viewion) + planeion=0; + DrawInfoBar(); + DrawMap(); + PrintCoords(); + tics=biostime(0,0); + while(keydown[7]); + } + + // + // Cancel COPY or PASTE or FLOOD FILL or BLOCK FILL + // + if (keydown[1] && (PasteMode || SelectMode || FillMode || + BfillMode || TsearchMode)) + { + while(keydown[1]); + + if (PasteMode) + { + EraseFloatPaste(); + px=py=-1; + } + + SnapMode=TsearchMode=BfillMode=FillMode=PasteMode=SelectMode=0; + SelX1=SelX2=SelY1=SelY2=-1; + DrawMap(); + DrawInfoBar(); + tics=biostime(0,0); + } + + // + // END OF COPY || BLOCK FILL + // + if (keydown[0x1c] && (SelectMode || BfillMode)) + { + int temp,j,i; + + tics=biostime(0,0); + while(keydown[0x1c]); + + if (SelX2>(tsize+2))+xbase,((pixely-8)>>(tsize+2))+ybase); +} + +//////////////////////////////////////////////////// +// +// Draw the current map on the screen at xbase,ybase +// +//////////////////////////////////////////////////// +void DrawMap(void) +{ + int i,j,imax,jmax; + + + EraseFloatPaste(); + jmax=screenh; + if (jmax>mapheight) + jmax=mapheight; + + imax=screenw; + if (imax>mapwidth) + imax=mapwidth; + + MouseHide(); + for(j=0;j>(tsize-1); + screenh=22>>(tsize-1); + break; + case EGA2: + screenw=80>>(tsize-1); + screenh=57>>(tsize-1); + break; + } + if (!infobaron) + { + infoy=100; // WAY OFF THE BOTTOM! + screenh+=2*(tsize==1)+(tsize==2); + } +} + + +//////////////////////////////////////////////////// +// +// Print the coords on the INFOBAR +// +//////////////////////////////////////////////////// +void PrintCoords(void) +{ + static zeroed=0; + int mx,my; + + if (!infobaron) + return; + + xormask=0; + MouseCoords(&mx,&my); + if (my<8 || my>=infoy*8) + { + if (zeroed) + return; + sx=infomaxw-9; + sy=infoy; + print("??? ?????"); + sx=infomaxw-9; + sy=infoy+1; + print("??? ?????"); + zeroed=1; + return; + } + + zeroed=0; + mx=mx>>(tsize+2); + sx=infomaxw-9; + sy=infoy; + printint(mx+xbase); + print(" "); + sx=infomaxw-5; + printhex(mx+xbase); + + my=(my-8)>>(tsize+2); + sx=infomaxw-9; + sy=infoy+1; + printint(my+ybase); + print(" "); + sx=infomaxw-5; + printhex(my+ybase); +} + + +//////////////////////////////////////////////////// +// +// Draw the INFOBAR +// +//////////////////////////////////////////////////// +void DrawInfoBar(void) +{ + int ox,oy; + + + if (PasteMode) + { + px=py=-1; + CheckFloatPaste((pixelx>>(tsize+2))+xbase,((pixely-8)>>(tsize+2))+ybase); + } + + if (!infobaron) + return; + + EraseFloatPaste(); + + ox=sx=0; + switch(videomode) + { + case CGA: + case EGA1: + case VGA: + oy=sy=23-2*(tsize==3); + infomaxw=40; + break; + case EGA2: + oy=sy=58-2*(tsize==3)-1*(tsize==2); + infomaxw=80; + } + + MouseHide(); + infoy=oy; + bar(0,infoy,infomaxw-1,infoy+1,' '); + + if (SelectMode) + { + sx=leftedge=1; + sy=infoy; + print("Copy Mode\nESC to exit"); + } + else + if (TsearchMode) + { + sx=leftedge=1; + sy=infoy; + print("Tile Search Mode\nESC to exit"); + } + else + if (BfillMode) + { + sx=leftedge=1; + sy=infoy; + print("Block Fill Mode\nESC to exit"); + } + else + if (PasteMode) + { + sx=leftedge=1; + sy=infoy; + print("Paste Mode\nESC to exit"); + } + else + if (FillMode) + { + sx=leftedge=1; + sy=infoy; + print("Flood Fill Mode\nESC to exit"); + } + else + { + CombineTiles(whicht,0,0,tsize); + DrawTile(ox,oy*8+8*(tsize==1),tsize); + sx=ox+2+2*(tsize==3); + sy=oy; + printhex(whicht); + sx-=5; + sy++; + printint(whicht); + print(" "); + + if (tilemnum) + { + ox+=7; + CombineTiles(-BkgndColor,whichtm,0,tsize); + DrawTile(ox,oy*8+8*(tsize==1),tsize); + sx=ox+2+2*(tsize==3); + sy=oy; + (whichtm==tilenum)?print(" No "):printhex(whichtm-tilenum); + sx-=5; + sy++; + (whichtm==tilenum)?print("Tile"):printint(whichtm-tilenum); + print(" "); + + ox+=7; + CombineTiles(-ICONBACK,(whichi>lasticon)?firsticon:whichi,0,tsize); + DrawTile(ox,oy*8+8*(tsize==1),tsize); + sx=ox+2+2*(tsize==3); + sy=oy; + (whichi==tilenum)?print(" No "):printhex(whichi-tilenum); + sx-=5; + sy++; + (whichi==tilenum)?print("Icon"):printint(whichi-tilenum); + print(" "); + } + } + + + sx=infomaxw-11; + sy=infoy; + print("X="); + sy++; + sx-=2; + print("Y="); + + sx=infomaxw-((videomode==EGA2)?19:18); + sy=infoy+1; + print("123"); + if (SnapMode) + { + sx=infomaxw-((videomode==EGA2)?21:20); + sy=infoy+1; + print("S"); + } + if (GridMode) + { + sx=infomaxw-((videomode==EGA2)?20:19); + sy=infoy+1; + print("G"); + } + sx=infomaxw-((videomode==EGA2)?19:18); + sy=infoy; + (planeton)?print("B"):print(" "); + (planemon)?print("F"):print(" "); + (planeion)?print("I"):print(" "); + + sx=infomaxw-15; + sy=infoy+1; + print("456"); + sx=infomaxw-15; + sy=infoy; + (viewton)?print("b"):print(" "); + (viewmon)?print("f"):print(" "); + (viewion)?print("i"):print(" "); + + if (videomode==EGA2) + { + sx=screencenterx-strlen(MapHeader.name)/2; + sy=infoy; + print(MapHeader.name); + } + + DrawFloatPaste(); + MouseShow(); +} + + +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +// +// Initialize TED5: +// +// * Project Select if multiple projects +// * If Project has NO LEVELS: +// * Init Level 1 +// * Init TILEINFO +// * Init TEDINFO file +// * Load TILES into XMS +// +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +char bstrings[10][15]; +btype ProjButns[10]; +DialogDef ProjSelect={"Select the project to work on:", + 30,0,0,&ProjButns[0],DrawProjBord}; + +void InitTed5(void) +{ + char pname[15]; + unsigned i,loop,which; + + MouseInit(); + MouseShow(); + if (!MouseStatus) + { + ErrDialog("Sorry, but TED5 will NOT\n" + "operate without a mouse!\n"," Press ENTER "); + Quit("Only REAL developers have a mouse!"); + } + MouseOrigin(0,0); + + ErrDialog("Initializing. One moment.",""); + // + // Create bit-doubling lookup table + // for CGA font creation + // + for (loop=0;loop<256;loop++) + { + unsigned result,temp=loop; + + asm mov ax,temp + asm mov ah,al + asm mov cx,8 + LOOP0: + asm shl al,1 + asm rcl bx,1 + asm shl ah,1 + asm rcl bx,1 + asm loop LOOP0 + + asm xchg bh,bl + asm mov result,bx + + doubled[loop]=result; + } + + // + // Init everything! + // + InitXMS(); + FindGraphFile(); + LoadInfoFile(); + LoadMapHeader(); + + RestoreBackground(); + + LoadGraphStuff(0,TEDInfo->lastvid); + DrawInfoBar(); + DrawMap(); + if (!launched && !NoAbout) + Item_About(); + launched=0; +} + + +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +// +// Load the MAPTEMP.ext header in... +// +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +btype SelectTsizeb[]={{" 8x8 ",1,2,1}, + {" 16x16 ",1,5,1}, + {" 32x32 ",1,8,1}}; +DialogDef SelectTsize={" Which tile size to use?" + ,26,10,3,&SelectTsizeb[0],STnot}; + +void LoadMapHeader(void) +{ + unsigned size,i,j,pflag; + char types=0; + + + strcpy(mapheadname,"MAPTHEAD."); + strcat(mapheadname,ext); + strcpy(mapname,"MAPTEMP."); + strcat(mapname,ext); + strcpy(SM_name,"MAPTEMP1."); + strcat(SM_name,ext); + strcpy(SM_loadname,"MAPTEMP."); + strcat(SM_loadname,ext); + + if (access(mapheadname,0)) + { + int i; + // + // Gotta create a new map file! + // + MMAllocate((memptr *)&MapFileHeader,sizeof(MapFileHeaderStr)); + for (i=0;iRLEWtag=0xabcd; + for (i=0;i<100;i++) + { + MapFileHeader->dataoffsets[i]=-1; + MapFileHeader->datalengths[i]=0; + memset(MapNames[i],0,16); + } + + if (!GFXInfo->num8 && + !GFXInfo->num8m && + !GFXInfo->num16 && + !GFXInfo->num16m && + !GFXInfo->num32 && + !GFXInfo->num32m) + { + ErrDialog("Uhh...you 'neglected' to\n" + "grab tiles to use. Running\n" + "TED5 is quite useless at\n" + "this point, I'm afraid.","Duh!"); + Quit("Get some tiles ... quick! Me hungry!"); + } + + if (!GFXInfo->num8 && + !GFXInfo->num16 && + !GFXInfo->num32) + { + ErrDialog("You may have grabbed some\n" + "MASKED tiles, but I require\n" + "NON-MASKED tiles as a\n" + "minimum requirement!","Geez..."); + Quit("Please grab some normal tiles!"); + } + + types+=(GFXInfo->num8>0)+(GFXInfo->num16>0)+(GFXInfo->num32>0); + + redo: + + if (types>1) + { + int which; + + which=DoDialog(&SelectTsize); + switch(which) + { + case 0: + Quit(""); + case 1: + if (!GFXInfo->num8) + which=0; + break; + case 2: + if (!GFXInfo->num16) + which=0; + break; + case 3: + if (!GFXInfo->num32) + which=0; + break; + } + + MapFileHeader->tsize=TEDInfo->tsize=tsize=which; + } + else + { + if (GFXInfo->num8) + TEDInfo->tsize=1; + else + if (GFXInfo->num16) + TEDInfo->tsize=2; + else + if (GFXInfo->num32) + TEDInfo->tsize=3; + + MapFileHeader->tsize=tsize=TEDInfo->tsize; + } + + // + // pick the planes that all maps will use + // + if (PickMorePlanes()) + goto redo; + + // + // initialize TILEINFO/TILEINFOM + // + switch(tsize) + { + case 1: + tilenum=GFXInfo->num8; + tilemnum=GFXInfo->num8m; + break; + case 2: + tilenum=GFXInfo->num16; + tilemnum=GFXInfo->num16m; + break; + case 3: + tilenum=GFXInfo->num32; + tilemnum=GFXInfo->num32m; + } + InitTileinfo(); + if (numtplanes || numtmplanes) // only input if applicable + Item_EditTinfoNames(); // void where prohibited + // + // now create a map! + // + CreateMap(0); + FigureScreenEdges(); + MapFileHeader->NumIconRows=maxiconrows=InputIconAmount(); + } + // + // MAP FILE ALREADY IN PLACE. LOAD STUFF IN... + // + else + { + memptr block,tempblock; + + LoadIn(mapheadname,(memptr *)&MapFileHeader); + + // + // See if the NumIconRows is toasty (old TED5 compatibility) + // + if (MapFileHeader->NumIconRows>50) + MapFileHeader->NumIconRows=4; + + // + // has the TEDINFO?.ext file been changed? + // if so, reconstruct pertinent data... + // + if (!TEDInfo->tsize) + { + tsize=TEDInfo->tsize=MapFileHeader->tsize; + switch(tsize) + { + case 1: + tilenum=GFXInfo->num8; + tilemnum=GFXInfo->num8m; + break; + case 2: + tilenum=GFXInfo->num16; + tilemnum=GFXInfo->num16m; + break; + case 3: + tilenum=GFXInfo->num32; + tilemnum=GFXInfo->num32m; + } + } + + maxiconrows=MapFileHeader->NumIconRows; + + // + // Read-in all the Map Names + // + for (i=0;i<100;i++) + if (MapFileHeader->dataoffsets[i]!=-1) + { + MapHeaderStr TempHead; + + LoadFile(mapname,(char huge *)&TempHead, + MapFileHeader->dataoffsets[i],sizeof(MapHeaderStr)); + strcpy(MapNames[i],TempHead.name); + } + + FigureScreenEdges(); + + if (!TEDInfo->level) + { + for(i=0;i<100;i++) + if (MapFileHeader->dataoffsets[i]!=-1) + { + whichmap=TEDInfo->level=i; + break; + } + } + else + whichmap=TEDInfo->level; + + LoadMap(TEDInfo->level); + + // + // IF WE WERE LAUNCHED AND CHARACTER POSITION WAS CHANGED, + // PUT IT BACK! + // + if (launched && (TEDInfo->lastx || TEDInfo->lasty)) + { + int i; + + for (i=0;ipermicon) + { + MapInfoPl[i]=0; + MapInfoPl[TEDInfo->lasty*mapwidth+TEDInfo->lastx]=TEDInfo->permicon; + TEDInfo->lastx=TEDInfo->lasty=0; + DirtyFlag=1; + break; + } + } + + // + // POSITION SCREEN + // + xbase=TEDInfo->oscrx; + ybase=TEDInfo->oscry; + if (xbase+screenw>mapwidth) + xbase=mapwidth-screenw; + if (ybase+screenh>mapheight) + ybase=mapheight-screenh; + + if (launched) + _fmemcpy((void far *)parmstring,(void far *)TEDInfo->parmstring,64); + + // + // LOAD TILEINFO/M AND ADJUST IF IT CHANGED + // + numtplanes=MapFileHeader->numtplanes; + numtmplanes=MapFileHeader->numtmplanes; + + pflag=0; + for (i=0;ioldtilenum); + // + // SPACE FOR OLD TILEINFO TO LOAD INTO + // + MMAllocate(&block,MapFileHeader->tileinfolen[i]); + LoadFile(mapheadname,MK_FP(block,0),MapFileHeader->tileinfooff[i],MapFileHeader->tileinfolen[i]); + // + // DECOMPRESS FROM "BLOCK" TO "TEMPBLOCK" + // + RLEBExpand(MK_FP(block,0),MK_FP(tempblock,0), + MapFileHeader->oldtilenum,MapFileHeader->RLEWtag); + MMFreePtr(&block); + // + // ALLOCATE TINFO ARRAY + // + MMAllocate((memptr *)&Tinfo[i],tilenum); + // + // MOVE FROM "TEMPBLOCK" TO "TINFO[I]" ARRAY + // + if (MapFileHeader->oldtilenumoldtilenum); + // + // IF NEW TILEINFO IS MORE, FILL END WITH 0s + // + for (j=MapFileHeader->oldtilenum;joldtilenum>tilenum) + DirtyFlag=pflag=2; + } + + MMFreePtr(&tempblock); + } + + switch(pflag) + { + case 1: + ErrDialog("The new TILEINFO data has\n" + "been expanded to accomodate\n" + "the newly grabbed tiles."," OK "); + break; + case 2: + ErrDialog("The new TILEINFO data has\n" + "been shrunk due to a reduced\n" + "amount of tiles."," OK "); + } + + pflag=0; + if (tilemnum && (MapFileHeader->maptype&FPLANE)) + for (i=0;ioldtilemnum); + MMAllocate(&block,MapFileHeader->tileinfomlen[i]); + LoadFile(mapheadname,MK_FP(block,0),MapFileHeader->tileinfomoff[i],MapFileHeader->tileinfomlen[i]); + RLEBExpand(MK_FP(block,0),MK_FP(tempblock,0), + MapFileHeader->oldtilemnum,MapFileHeader->RLEWtag); + MMFreePtr(&block); + MMAllocate((memptr *)&TMinfo[i],tilemnum); + if (MapFileHeader->oldtilemnumoldtilemnum); + for (j=MapFileHeader->oldtilemnum;joldtilemnum>tilemnum) + DirtyFlag=pflag=2; + } + + MMFreePtr(&tempblock); + } + + switch(pflag) + { + case 1: + ErrDialog("The new TILEINFOM data has\n" + "been expanded to accomodate\n" + "the newly grabbed masked tiles."," OK "); + break; + case 2: + ErrDialog("The new TILEINFOM data has\n" + "been shrunk due to a reduced\n" + "amount of tiles."," OK "); + } + + #if 0 + // + // TURN ON PLANES + // + viewton=planeton=1; + if (MapFileHeader->maptype&FPLANE) + viewmon=1; + if (MapFileHeader->maptype&IPLANE) + viewion=1; + planemon=planeion=0; + #endif + + } + + // + // LOAD THE MAPFILE INTO XMS IF ENOUGH ROOM + // + if (1024L*XMSTotalFree()>2L*filelen(mapname) && !NoXMSFlag) + { + #define LBCSIZE 0x4000 + memptr block; + long size,clen,coff; + + + size=filelen(mapname); + MMAllocate(&block,LBCSIZE); + XMSmaps=XMSAllocate(size); + + // + // LOAD ENTIRE MAPFILE FROM DISK TO XMS! + // + coff=0; + do + { + clen=LBCSIZE; + if (size0); + + MMFreePtr(&block); + } + +} + +void STnot(int x,int y) +{ + sx=x+10; + sy=y+2; + if (!GFXInfo->num8) + print("<-Not available"); + else + { + printint(GFXInfo->num8); + print(" total tiles"); + } + sx=x+10; + sy=y+5; + if (!GFXInfo->num16) + print("<-Not available"); + else + { + printint(GFXInfo->num16); + print(" total tiles"); + } + sx=x+10; + sy=y+8; + if (!GFXInfo->num32) + print("<-Not available"); + else + { + printint(GFXInfo->num32); + print(" total tiles"); + } +} + + +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +// +// Load the graphheader file & ?GAGRAPH.ext file and stick it in XMS! +// +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +int LoadGraphStuff(int rtn,video newvid) +{ + #define NUMFASTDECOMP 100 // # of tiles in fast decompress buffer + + char gname[14]="?GAHEAD.",gname1[14]="?GAGRAPH.",_seg *packed,_seg *unpack, + dictname[14]="?GADICT.",hufftable[1020],_seg *CacheBlock; + unsigned index,indexm,num,numm,i,realnum,realnumm,ox,oy,cacheon=0,_seg *tile_len, + _seg *tilem_len,cacheon_h; + long expsize,expmsize,xmsoff=0,unpackoff,unpackmax,unpacksize, + unpackxms; + video tempvid,pickedvid; + + char huge *offsets; + + + + strcat(gname,ext); + strcat(gname1,ext); + strcat(dictname,ext); + gname[0]=format[0]; + gname1[0]=format[0]; + dictname[0]=format[0]; + + if (!launched) + switch(format[0]) + { + case 'C': pickedvid=CGA; break; + case 'E': pickedvid=EGA1; break; + case 'V': pickedvid=VGA; + } + else + pickedvid=TEDInfo->lastvid; + + // + // VALIDATE GRAPHICS MODE + // + tempvid=rtn?newvid:pickedvid; + switch(tempvid) + { + case CGA: + gname[0]='C'; + if (access(gname,0)) + { + if (rtn) + return 0; + } + else + { + TEDInfo->lastvid=CGA; + dictname[0]=format[0]=gname1[0]='C'; + setvideo(CGA); + InitDesktop(TED5MenuBar,1); + MouseShow(); + break; + } + case EGA1: + case EGA2: + gname[0]='E'; + if (access(gname,0)) + { + if (rtn) + return 0; + } + else + { + TEDInfo->lastvid=tempvid; + dictname[0]=format[0]=gname1[0]='E'; + setvideo(tempvid); + InitDesktop(TED5MenuBar,1); + MouseShow(); + break; + } + case VGA: + gname[0]='V'; + if (access(gname,0)) + { + if (rtn) + return 0; + + gname[0]=format[0]; + } + else + { + TEDInfo->lastvid=VGA; + dictname[0]=format[0]=gname1[0]='V'; + setvideo(VGA); + InitDesktop(TED5MenuBar,1); + MouseShow(); + break; + } + } + + + // + // FIND HEADER & LOAD IT + // + if (access(gname,0)) + { + char errstr[100]="Can't find the "; + + strcat(errstr,format); + strcat(errstr,"GAHEAD."); + strcat(errstr,ext); + strcat(errstr,"\nfile! Maybe you didn't\n" + "copy it from the graphics\n" + "subdirectory?"); + + ErrDialog(errstr," OK "); + if (rtn) + return 0; + Quit("You're stupid! Copy the damn file!"); + } + + LoadIn(gname,(memptr *)&GraphHeader); + + switch(MapFileHeader->tsize) + { + case 1: + index=GFXInfo->off8; + indexm=GFXInfo->off8m; + num=GFXInfo->num8; + numm=GFXInfo->num8m; + if (indexm==index+1) + { + ErrDialog("I'm sorry, but you need to\n" + "capture your 8x8 tiles\n" + "individually, and not in a\n" + "big chunk."," Alright "); + if (rtn) + return 0; + Quit("Regrab-time, bag o' shit!"); + } + + switch(tempvid) + { + case CGA: expsize=16; expmsize=32; break; + case EGA1: + case EGA2: expsize=32; expmsize=40; break; + case VGA: expsize=64; expmsize=128; + } + break; + case 2: + index=GFXInfo->off16; + indexm=GFXInfo->off16m; + num=GFXInfo->num16; + numm=GFXInfo->num16m; + switch(tempvid) + { + case CGA: expsize=64; expmsize=128; break; + case EGA1: + case EGA2: expsize=128; expmsize=128+32; break; + case VGA: expsize=256; expmsize=512; + } + break; + case 3: + index=GFXInfo->off32; + indexm=GFXInfo->off32m; + num=GFXInfo->num32; + numm=GFXInfo->num32m; + switch(tempvid) + { + case CGA: expsize=256; expmsize=512; break; + case EGA1: + case EGA2: expsize=512; expsize=512+4*32; break; + case VGA: expsize=1024; expmsize=2048; + } + } + + // + // MOVE TILES INTO XMS MEMORY! + // + + MMAllocate((memptr *)&packed,expmsize); + unpackmax=expmsize*NUMFASTDECOMP; + MMAllocate((memptr *)&unpack,unpackmax); + + + tilelen=expsize; + tilemlen=expmsize; + offsets=MK_FP(GraphHeader,0); + + // + // LOAD DICTIONARY IN & INITIALIZE IT + // + if (!launched) + { + char _seg *block; + + if (access(dictname,0)) + { + char errst[200]="I can't find the \n"; + + strcat(errst,dictname); + strcat(errst," file!"); + + ErrDialog(errst," OK "); + if (rtn) + return 0; + Quit("Look in the graphics grab directory!"); + } + + LoadIn(dictname,(memptr *)&block); + movedata((unsigned)block,0,FP_SEG(hufftable),FP_OFF(hufftable),1020); + MMFreePtr((memptr *)&block); + OptimizeNodes((huffnode *)hufftable); + } + + // + // Count up the REAL number of tiles there are! + // Build tables for tile lengths + // + MMAllocate((memptr *)&tile_len,num*2); + for (realnum=i=0;iOldCgaXMS; + EgaXMS=TEDInfo->OldEgaXMS; + VgaXMS=TEDInfo->OldVgaXMS; + + CgaXMSsize=TEDInfo->OldCgaXMSsize; + EgaXMSsize=TEDInfo->OldEgaXMSsize; + VgaXMSsize=TEDInfo->OldVgaXMSsize; + + size=(num+numm)*4; + if (CgaXMS) + { + MMAllocate((memptr *)&CgaXMSlookup,size); + XMSmove(TEDInfo->CgaXMSlook,0,0,(long)MK_FP(CgaXMSlookup,0),size); + XMSFreeMem(TEDInfo->CgaXMSlook); + TEDInfo->CgaXMSlook=0; + } + if (EgaXMS) + { + MMAllocate((memptr *)&EgaXMSlookup,size); + XMSmove(TEDInfo->EgaXMSlook,0,0,(long)MK_FP(EgaXMSlookup,0),size); + XMSFreeMem(TEDInfo->EgaXMSlook); + TEDInfo->EgaXMSlook=0; + } + if (VgaXMS) + { + MMAllocate((memptr *)&VgaXMSlookup,size); + XMSmove(TEDInfo->VgaXMSlook,0,0,(long)MK_FP(VgaXMSlookup,0),size); + XMSFreeMem(TEDInfo->VgaXMSlook); + TEDInfo->VgaXMSlook=0; + } + + switch(tempvid) + { + case CGA: + xmshandle=CgaXMS; + XMSlookup=CgaXMSlookup; + break; + case EGA1: + case EGA2: + xmshandle=EgaXMS; + XMSlookup=EgaXMSlookup; + break; + case VGA: + xmshandle=VgaXMS; + XMSlookup=VgaXMSlookup; + } + + ErrDialog("RE-INITIALIZING...",""); + } + + ox=sx; + oy=sy; + + // + // INSTALL GRAPHICS IF NOT A LAUNCH... + // + if (!launched) + { + switch(tempvid) + { + case CGA: + MMAllocate((memptr *)&CgaXMSlookup,(num+numm)*4); + XMSlookup=CgaXMSlookup; + break; + case EGA1: + case EGA2: + MMAllocate((memptr *)&EgaXMSlookup,(num+numm)*4); + XMSlookup=EgaXMSlookup; + break; + case VGA: + MMAllocate((memptr *)&VgaXMSlookup,(num+numm)*4); + XMSlookup=VgaXMSlookup; + } + + + // + // SET UP MEMORY CACHE IF ENOUGH IS AVAILABLE... + // + cacheon_h=0; + if (filelen(gname1)<16L*MMTotalFree()) + { + LoadIn(gname1,(memptr *)&CacheBlock); + cacheon=1; + } + else + // + // DAMN! TRY XMS AS A LAST RESORT... + // + if (filelen(gname1)<1024l*XMSTotalFree()) + { + #define TMPBUFSIZE 32000l + long amtleft,tmpoff=0,tmpsize; + memptr tblock; + + + amtleft=filelen(gname1); + MMAllocate(&tblock,TMPBUFSIZE); + cacheon_h=XMSAllocate(amtleft); + tmpsize=TMPBUFSIZE; + while(amtleft>0) + { + LoadFile(gname1,MK_FP(tblock,0),tmpoff,tmpsize); + XMSmove(0,(long)MK_FP(tblock,0),cacheon_h,tmpoff,tmpsize); + amtleft-=TMPBUFSIZE; + tmpoff+=TMPBUFSIZE; + tmpsize=(amtleft>TMPBUFSIZE)?TMPBUFSIZE:amtleft; + } + + MMFreePtr(&tblock); + cacheon=2; + } + + clearkeys(); + + // + // MOVE NONMASKED TILES INTO XMS MEMORY! + // --------- + unpacksize=unpackoff=0; + unpackxms=xmsoff; + for (i=0;iunpackmax-expsize) + { + XMSmove(0,(long)MK_FP(unpack,0),xmshandle,unpackxms,unpacksize); + unpacksize=unpackoff=0; + unpackxms=xmsoff; + + sx=ox; + sy=oy; + printint(num+numm-i); + print(" "); + } + + // + // ESC will exit! + // + if (keydown[1]) + if (rtn) + { + switch(tempvid) + { + case CGA: + XMSFreeMem(CgaXMS); + MMFreePtr((memptr *)&CgaXMSlookup); + CgaXMS=0; + break; + case EGA1: + case EGA2: + XMSFreeMem(EgaXMS); + MMFreePtr((memptr *)&EgaXMSlookup); + EgaXMS=0; + break; + case VGA: + XMSFreeMem(VgaXMS); + MMFreePtr((memptr *)&VgaXMSlookup); + VgaXMS=0; + } + + switch(videomode) + { + case CGA: + xmshandle=CgaXMS; + XMSlookup=CgaXMSlookup; + break; + case EGA1: + case EGA2: + xmshandle=EgaXMS; + XMSlookup=EgaXMSlookup; + break; + case VGA: + xmshandle=VgaXMS; + XMSlookup=VgaXMSlookup; + } + + MMFreePtr((memptr *)&GraphHeader); + MMFreePtr((memptr *)&packed); + MMFreePtr((memptr *)&unpack); + + if (cacheon) + MMFreePtr((memptr *)&CacheBlock); + + return 0; + } + else + Quit("XMS LOADING ABORTED!"); + } + + // + // FLUSH THE FAST(?)-CACHE + // + if (unpacksize) + { + XMSmove(0,(long)MK_FP(unpack,0),xmshandle,unpackxms,unpacksize); + unpacksize=unpackoff=0; + unpackxms=xmsoff; + } + + // + // MOVE MASKED TILES INTO XMS MEMORY! + // ------ + for (i=0;iunpackmax-expmsize) + { + XMSmove(0,(long)MK_FP(unpack,0),xmshandle,unpackxms,unpacksize); + unpacksize=unpackoff=0; + unpackxms=xmsoff; + + sx=ox; + sy=oy; + printint(numm-i); + print(" "); + } + + + // + // ESC will exit! + // + if (keydown[1]) + if (rtn) + { + switch(tempvid) + { + case CGA: + XMSFreeMem(CgaXMS); + MMFreePtr((memptr *)&CgaXMSlookup); + CgaXMS=0; + break; + case EGA1: + case EGA2: + XMSFreeMem(EgaXMS); + MMFreePtr((memptr *)&EgaXMSlookup); + EgaXMS=0; + break; + case VGA: + XMSFreeMem(VgaXMS); + MMFreePtr((memptr *)&VgaXMSlookup); + VgaXMS=0; + } + + switch(videomode) + { + case CGA: + xmshandle=CgaXMS; + XMSlookup=CgaXMSlookup; + break; + case EGA1: + case EGA2: + xmshandle=EgaXMS; + XMSlookup=EgaXMSlookup; + break; + case VGA: + xmshandle=VgaXMS; + XMSlookup=VgaXMSlookup; + } + + MMFreePtr((memptr *)&GraphHeader); + MMFreePtr((memptr *)&packed); + MMFreePtr((memptr *)&unpack); + + if (cacheon) + MMFreePtr((memptr *)&CacheBlock); + + return 0; + } + else + Quit("XMS LOADING ABORTED!"); + } + // + // FLUSH THE FAST-CACHE + // + if (unpacksize) + { + XMSmove(0,(long)MK_FP(unpack,0),xmshandle,unpackxms,unpacksize); + unpacksize=unpackoff=0; + unpackxms=xmsoff; + } + + if (cacheon==1) + MMFreePtr((memptr *)&CacheBlock); + else + if (cacheon==2) + XMSFreeMem(cacheon_h); + } + + // + // GET RID OF TILE-FILE CACHE MEMORY (OR WE'RE TOASTY) + // + MMFreePtr((memptr *)&GraphHeader); + MMFreePtr((memptr *)&packed); + MMFreePtr((memptr *)&unpack); + + MMFreePtr((memptr *)&tile_len); + MMFreePtr((memptr *)&tilem_len); + + whicht=0; + whichi=tilenum; + whichtm=tilenum; + + switch(tsize) + { + case 1: lasticon=tilenum+36*maxiconrows; + break; + case 2: lasticon=tilenum+18*maxiconrows; + break; + case 3: lasticon=tilenum+7*maxiconrows; + } + firsticon=tilenum; + + RestoreBackground(); + return 1; +} + + +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +// +// Load TEDINFO.ext file +// +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +void LoadInfoFile(void) +{ + char pname[14]="TEDINFO.",gfxname[14]="GFXINFO"; + + + // + // Load the TEDINFO.ext file! + // + strcat(pname,ext); + strcpy(infoname,pname); + + if (access(pname,0)) + { + MMAllocate((memptr *)&TEDInfo,sizeof(InfoStruct)); + _fmemset(TEDInfo,0,sizeof(InfoStruct)); + // BFI BFI + TEDInfo->pflags=0x27; // 0010 0111 + } + else + LoadIn(pname,(memptr *)&TEDInfo); + + tsize=TEDInfo->tsize; + if (launchname[0]) + _fmemcpy((char far *)TEDInfo->launchname,(char far *)launchname,14); + + // + // LOAD THE "GFXINFO?.EXT" FILE + // + strcat(gfxname,format); + strcat(gfxname,"."); + strcat(gfxname,ext); + LoadIn(gfxname,(memptr *)&GFXInfo); + + switch(tsize) + { + case 1: + tilenum=GFXInfo->num8; + tilemnum=GFXInfo->num8m; + break; + case 2: + tilenum=GFXInfo->num16; + tilemnum=GFXInfo->num16m; + break; + case 3: + tilenum=GFXInfo->num32; + tilemnum=GFXInfo->num32m; + } + + _fstrcpy((char far *)launchname,(char far *)TEDInfo->launchname); + + if (launched) + TEDInfo->lastvid=LaunchInfo.lastmode; + + // + // SET PLANE FLAGS BACK TO NORMAL + // + planeton=(TEDInfo->pflags>>6)&1; + planemon=(TEDInfo->pflags>>5)&1; + planeion=(TEDInfo->pflags>>4)&1; + viewton=(TEDInfo->pflags>>2)&1; + viewmon=(TEDInfo->pflags>>1)&1; + viewion=(TEDInfo->pflags)&1; + + // + // SET BACKGROUND COLOR + // + BkgndColor=TEDInfo->BackgndColor; + if (BkgndColor>16) + TEDInfo->BackgndColor=BkgndColor=O_FGNDBACK; +} + + +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +// +// Find ?GAGRAPH.ext file +// +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +void FindGraphFile(void) +{ + struct ffblk ffblk; + char pname[15]="?GAGRAPH.*",*tempstr,tiname[13]="TEDINFO.TMP"; + int i,which; + + + // + // RETURNING FROM LAUNCH...GET INFO BACK + // + if (launched) + { + LoadFile(tiname,(char huge *)&LaunchInfo,0,0); + unlink(tiname); + videomode=LaunchInfo.lastmode; + switch(videomode) + { + case CGA: + format[0]='C'; + break; + case EGA1: + case EGA2: + format[0]='E'; + break; + case VGA: + format[0]='V'; + } + + strcpy(ext,LaunchInfo.ext); + projname[0]=format[0]; + strcat(projname,"GAGRAPH."); + strcat(projname,ext); + return; + } + + // + // Find ?GAGRAPH.ext + // + if (ext[0]) + { + strcpy(pname,"?GAGRAPH."); + strcat(pname,ext); + } + + if (findfirst(pname,&ffblk,FA_ARCH)) + { + ErrDialog("I can't find a graphics\nfile! (ex:?GAGRAPH.ext)"," Alright "); + Quit("Can't work without graphics ya know!"); + } + + + if (GfxToUse) + format[0] = GfxToUse; + else + { + // setup the dialog + + strcpy(bstrings[0],ffblk.ff_name); + ProjButns[0].xoff=9; + ProjButns[0].yoff=2; + ProjButns[0].border=0; + ProjButns[0].text=bstrings[0]; + for (i=1;i<10;i++) + { + if (findnext(&ffblk)) + break; + strcpy(bstrings[i],ffblk.ff_name); + ProjButns[i].xoff=9; + ProjButns[i].yoff=2+i; + ProjButns[i].border=0; + ProjButns[i].text=bstrings[i]; + } + ProjSelect.numbuttons=i; + ProjSelect.height=i+3; + + which=1; + if (i>1) + do + { + which=DoDialog(&ProjSelect); + } while(!which); + which--; + + tempstr=strpbrk(bstrings[which],".")+1; + strcpy(ext,tempstr); + format[0]=bstrings[which][0]; + } + + strcpy(projname,bstrings[which]); +} + +// +// draw border for project window +// +void DrawProjBord(int x,int y) +{ + DrawBorder(x+8,y+1,13,ProjSelect.height-2,1); +} + + +//////////////////////////////////////////////////// +// +// Input amount of icons to reserve +// Returns maximum # of icon rows to reserve +// +//////////////////////////////////////////////////// +btype ICb={" ",8,3,1}; +DialogDef ICd={"Enter maximum amount\nof icons to reserve:",20,5,1,&ICb,NULL}; + +int InputIconAmount(void) +{ + char tempstr[4]; + int value; + + + if (!(MapFileHeader->maptype&IPLANE)) + return 4; + + MouseHide(); + DrawDialog(&ICd,1); + while(1) + { + GetDialogXY(&ICd,&sx,&sy); + GetButtonXY(&ICd,0,&sx,&sy); + if (input(tempstr,3)) + { + value=atoi(tempstr); + if (value>0) + { + MouseShow(); + RestoreBackground(); + return (value+17)/18; + } + } + } +} + + +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +// +// Unhook everything +// +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +void Unhook(void) +{ + ShutdownKBD(); + if (CgaXMS) + XMSFreeMem(CgaXMS); + if (EgaXMS) + XMSFreeMem(EgaXMS); + if (VgaXMS) + XMSFreeMem(VgaXMS); + if (XMSundoB) + XMSFreeMem(XMSundoB); + if (XMSundoF) + XMSFreeMem(XMSundoF); + if (XMSundoI) + XMSFreeMem(XMSundoI); + if (XMSmaps) + XMSFreeMem(XMSmaps); +} + +void PatchPointers(void) +{ +} + + +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +// +// Menu Definitions +// +//////////////////////////////////////////////////// +//////////////////////////////////////////////////// +MenuDef AboutMenu[]= + {{"About...",Item_About,0,0}, + {"Video Mode Switch",Item_ModeSwitch,0,0x43}, + {"Last Video Mode",Item_LastVideo,ALT,0x2c}, + {"Memory Available",Item_PrintMem,0,0x44}, + {"Launch Project",Item_Launch,ALT,0x26}, + {"--------------------",NULL,0,0}, +// {"Display Unused Tiles",Item_CountTiles,0,0}, + {"Project Re-Select",Item_ProjectReSelect,0,0}, + {"Visit DOS",Item_VisitDOS,0,0} + }; + +MenuDef FileMenu[]= + {{"Edit New Map",Item_EditMap,ALT,0x18}, + {"Save Map",Item_SaveMap,ALT,0x1f}, + {"Create Map",Item_CreateMap,ALT,0x2e}, + {"Delete Map",Item_DeleteMap,ALT,0x20}, + {"Switch Map",Item_SwitchMap,ALT,0x11}, + {"Amputate Maps",Item_Amputate}, + {"---------------",NULL,0,0}, + {"Import Maps",Item_ImportMaps,0,0}, + {"Change ICON Rows",Item_ChangeIconRows,0,0}, + {"Carmacize Maps",Item_Huffman,0,0}, + {"Quit TED5",Item_Quit,ALT,0x2d}}; + +MenuDef EditMenu[]= + {{"Switch to Last Map",Item_LastMap,ALT,0x32}, + {"Edit TILEINFO/M Values",Item_EditTinfoValues,ALT,0x14}, + {"Change LAUNCH name",Item_LAUNCHname,0,0}, + {"Change PARM string",Item_PARMstring,0,0}, + {"Edit TILEINFO/M Names",Item_EditTinfoNames,0,0}, + {"Add/Del TILEINFO/M Planes",Item_AddDelTinfo,0,0}, + {"Edit MAP Names",Item_EditMapNames,0,0}, + {"Change MAP Edges",Item_EditMapEdges,0,0}}; + +MenuDef ModeMenu[]= +{ + {"Copy Mode",Item_Copy,0,0x2e}, + {"Paste Mode",Item_Paste,0,0x19}, + {"Block Fill",Item_BlockFill,0,0x30}, + {"Flood Fill",Item_FloodFill,0,0x21}, + {"Undo last action",Item_Undo,0,0x16}, + {"Tile Search",Item_TileSearch,0,0x14}, + {"GridMode toggle",Item_GridMode,0,0x22}, + {"Snap-Paste toggle",Item_SnapTog,0,0x1f}, + {"Paste Overlay toggle",Item_POtog,0,0x3d} +}; + + +MenuDef MiscMenu[]= +{ + {"Select Tile",Item_SelectTile,0,0x39}, + {"Map Stats",Item_MapStats,0,0x17}, + {"Toggle INFOBAR",Item_ToggleInfo,0,0x42}, + {"New INFOPLANE value",Item_InputInfoplane,0,0x1c}, + {"View Map & Goto",Item_ViewMap,ALT,0x2f}, + {"ReView Map & Goto",Item_ReviewMap,0,0xe}, + {"Change LAUNCH icon",Item_ChangeLaunchIcon,0,0}, + {"Change bkgnd color",Item_ChangeBkgndColor,0,0}, + {"TILEINFOM Copy",Item_TINFOCopy,0,0}, + {"Graphic Map Dump",Item_GraphicDump,0,0} +}; + + +MBarDef TED5MenuBar[]= + {{9,AboutMenu," ? "}, + {11,FileMenu,"File"}, + {8,EditMenu,"Edit"}, + {9,ModeMenu,"Modes"}, + {10,MiscMenu,"Misc"}, + {0,0,""}}; diff --git a/16/ted5/TED5.DSK b/16/ted5/TED5.DSK new file mode 100755 index 00000000..2e179205 Binary files /dev/null and b/16/ted5/TED5.DSK differ diff --git a/16/ted5/TED5.EXE b/16/ted5/TED5.EXE new file mode 100755 index 00000000..02076f91 Binary files /dev/null and b/16/ted5/TED5.EXE differ diff --git a/16/ted5/TED5.H b/16/ted5/TED5.H new file mode 100755 index 00000000..e44ff89c --- /dev/null +++ b/16/ted5/TED5.H @@ -0,0 +1,356 @@ +#define IDSTRING "TED5v1.0" +#define TITLESTR "TED5 vD.IP" +#define IDSTSTR " "TITLESTR + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lib.h" +#include "memmgr.h" +#include "menu.h" +#include "jhuff.h" +#include "xms.h" + +#define SGN(x) (x>0?1:x<0?-1:0) +#define OFF3(m,i) (*(long huge *)((char huge *)m+(i)*3)&0xffffff) + + +// +// Defs for TED5 +// + +typedef enum {TILES,MASKED,ICONS} screentype; +typedef enum {DATA,CODE,FARDATA} segtype; // FOR MAKEOBJ ONLY + +#define SCindex 0x3C4 +#define SCmapmask 2 +#define GCindex 0x3CE +#define GCreadmap 4 +#define GCmode 5 +#define crtcaddr 0x3d4 + +// +// STRUCTURE OF TED5 TEMPFILE WHILE LAUNCHING +// +typedef struct { + video lastmode; + char ext[4]; + } TempStruct; + +// +// STRUCTURE OF THE "TEDINFO.EXT" FILE THAT TED5 CREATES +// +typedef struct { + int level,lastvid,lastx,lasty,tsize; + int OldCgaXMS,OldEgaXMS,OldVgaXMS; + long OldCgaXMSsize,OldEgaXMSsize,OldVgaXMSsize; + int CgaXMSlook,EgaXMSlook,VgaXMSlook; + char permicon,pflags; + int oscrx,oscry; + char parmstring[64],launchname[14]; + char BackgndColor; + char ImportPath[64]; + } InfoStruct; + +// +// STRUCTURE OF THE "GFXINFO?.EXT" FILE THAT IGRAB CREATES +// +typedef struct { + int num8,num8m,num16,num16m,num32,num32m; + int off8,off8m,off16,off16m,off32,off32m; + int numpics,numpicm,numsprites; + int offpic,offpicm,offsprites; + int offpicstr,offpicmstr,offsprstr; + int numexterns,offexterns; + } GfxStruct; + +// +// TED5 LOADS & SAVES THIS HEADER FOR INTERNAL MAPFILE USAGE +// +typedef struct { unsigned maptype; //bit 0=bkgnd/1=frgnd/2=info + unsigned tsize; //1=8/2=16/3=32 + + unsigned numtplanes,oldtilenum; + long tileinfooff[10]; + unsigned tileinfolen[10]; + char tnames[10][8]; + + unsigned numtmplanes,oldtilemnum; + long tileinfomoff[10]; + unsigned tileinfomlen[10]; + char tmnames[10][8]; + + unsigned RLEWtag; + long dataoffsets[100]; + long datalengths[100]; + + int NumIconRows; + } MapFileHeaderStr; + +// +// TED5 SAVES THIS MAPFILE HEADER FOR THE GAME +// +typedef struct { + unsigned RLEWtag; + long dataoffsets[100]; + + } OutputHeadStr; + +// +// EACH AND EVERY MAP HAS THIS HEADER (IF THE MAP EXISTS) +// +typedef struct { long mapbkgndpl; + long mapfrgndpl; + long mapinfopl; + unsigned mapbkgndlen; + unsigned mapfrgndlen; + unsigned mapinfolen; + unsigned width,height; + char name[16]; + } MapHeaderStr; + +// +// SPECIFY WHAT, WHEREFROM, AND HOW TO COPY A REGION +// +typedef struct { + char PlanesCopied; // use BPLANE,FPLANE,IPLANE to mask + int MapOrTileSelect; // 0:map,1:tileselect + int x,y,w,h; // from map or tileselect + } CopyStr; + +// +// UNDO REGION +// +typedef struct { + int x,y,w,h; + } UndoStr; + +// +// LAST-BUILT "VIEWMAP" +// +typedef struct { + unsigned step,built_flag,EGAseg,maxpack; + } VMapStr; + + +// +// HEADER FOR APPLE-PREFERRED FILES +// +typedef struct { long length; + char Kind[5]; + int MasterMode; + int PixelsPerLine; + int NumColorTables; + int ColorTable[16]; + int NumScanLines; + } ApPrefStr; + +#define CREATED 1 +#define NOTCREATED 2 +#define ANYLIST 3 + +#define BPLANE 1 +#define FPLANE 2 +#define IPLANE 4 + +#define O_FGNDBACK 4 +#define ICONBACK 3 + +#define TINFOWIDTH 3 +#define TINFOHEIGHT 7 +#define TINFOHEIGHTEGA2 25 + +extern MBarDef TED5MenuBar[]; +extern DialogDef DoCreated; + +extern UndoStr UndoRegion; +extern CopyStr TileCopy; +extern MapFileHeaderStr _seg *MapFileHeader; +extern char _seg *Tinfo[10],_seg *TMinfo[10],_seg *GraphHeader; +extern long _seg *XMSlookup,_seg *CgaXMSlookup,_seg *EgaXMSlookup,_seg *VgaXMSlookup; +extern int _seg *MapBkgnd,_seg *MapFrgnd,_seg *MapInfoPl, + _seg *CutBkgnd,_seg *CutFrgnd,_seg *CutInfoPl; +extern MapHeaderStr MapHeader; + +#if 0 +extern char far TOM; // JOKE SHIT! +#endif + +extern TempStruct LaunchInfo; +extern InfoStruct _seg *TEDInfo; +extern GfxStruct _seg *GfxInfo; +extern video lastvideo,videomode; +extern screentype whichscreen; +extern VMapStr VMapData; + +extern char launchname[64],ext[4],format[2],projname[64],mapname[64],planes, + infoname[64],mapheadname[64],tdata,MapNames[100][16],parmstring[64]; +extern char SM_name[64],SM_loadname[64],BkgndColor; + +extern unsigned temp,whichmap,numtplanes,tilenum,tilemnum,numtmplanes,left, + DirtyFlag,tilelen,tilemlen,whicht,whichtm,whichi, + tsize,infoy,infomaxw,mapwidth,mapheight,screenw,usingbat, + screenh,planeton,planemon,planeion,maxiconrows,lasticon,firsticon, + viewton,viewmon,viewion,XMSundoB,XMSundoF,XMSundoI,XMSmaps, + EgaXMS,CgaXMS,VgaXMS,xmshandle,GridMode,SnapMode,snapx,snapy, + snapxsize,snapysize,writeH,F3_flag,NoAbout; +extern int tilebase,tilembase,infobaron,xbase,ybase,scrnbot,scrnrgt, + FillMode,PasteMode,SelectMode,SelX1,SelY1,PasteOK,SelX2,SelY2,pixelx,pixely, + selectcols,px,py,lastmap,TIybase,TIymbase,TIxbase,TIxmbase,BfillMode, + Plotting,TsearchMode; +extern long CgaXMSsize,EgaXMSsize,VgaXMSsize; + +extern void far *XMSdriver; + +// +// FUNCTION PROTOTYPES +// + +// +// LIB_A.ASM +// +extern void CGAcharout(int x,int y,char ch); +extern void EGAcharout(int x,int y,char ch,video vid); +extern void VGAcharout(int x,int y,char ch); + +// +// TED5_A.ASM +// +extern unsigned EGA1lookup[200]; +extern unsigned EGA2lookup[200]; +extern void DrawTile(int x,int y,int tile); +extern void CopyCGA(int srcx,int srcy,int width,int height,int destx,int desty); +extern void CopyEGA(int srcx,int srcy,int width,int height,int destx,int desty); +extern void CopyVGA(int srcx,int srcy,int width,int height,int destx,int desty); +extern void Overlay(int tsize); + +// +// TED5 +// +void FindGraphFile(void); +void HandleEvent(void); +void Continuous(void); +void LoadInfoFile(void); +int LoadGraphStuff(int rtn,video newvid); +void LoadMapHeader(void); +void ParseCmdline(void); +void InitTed5(void); +void CallDesktop(void); +void SelectTiles(int screen); +void STnot(int x,int y); +void DrawProjBord(int x,int y); +void DrawInfoBar(void); +void PrintCoords(void); +void FigureScreenEdges(void); +void errsound(void); +void DrawMap(void); +void CheckSelectEdges(int x,int y,int i,int j); +int InputIconAmount(void); + +// +// TED5-1 +// +void Item_InputInfoplane(void); +void Item_SelectTile(void); +void Item_EditTinfoNames(void); +void Item_BlockFill(void); +void Item_TileSearch(void); +void Item_Launch(void); +void Item_Undo(void); +void Item_TINFOCopy(void); + +void CreateMap(int exitok); +int SelectMap(int exitok,int createflg,char *title); +int PickMorePlanes(void); +void DoBlockFill(void); +void RemoveUndoBuffers(void); +void AllocateUndoBuffers(void); +void RestoreUndo(void); +void SaveUndo(int x,int y,int w,int h); +void CopyUndoRegion(void); +void SaveOutputHeader(void); +void SaveTEDInfo(void); +void BackupFile(char *filename); + +void TInfoNon(int x,int y,int b); +void TInfoNoff(int x,int y,int b); +void TInfoMNon(int x,int y,int b); +void TInfoMNoff(int x,int y,int b); +void TIDoneOn(int x,int y); +void TIDoneOff(int x,int y); + + +// +// TED5-2 +// +void Item_About(void); +void Item_ModeSwitch(void); +void Item_DeleteMap(void); +void Item_EditMap(void); +void Item_SaveMap(void); +void Item_CreateMap(void); +void Item_Quit(void); +void Item_MapStats(void); +void Item_ToggleInfo(void); +void Item_Amputate(void); +void Item_SwitchMap(void); +void Item_EditMapNames(void); +void Item_Copy(void); +void Item_Paste(void); +void Item_LastVideo(void); +void Item_FloodFill(void); +void Item_LastMap(void); +void Item_CountTiles(void); +int CheckForMapSave(void); +void DoFloodFill(int x,int y,int whichb); + +void DrawTileSelect(int deltarows,int *numrows,int *numcols); +void DrawUnused(int deltarow); +void DrawCurrentTiles(void); +void ZeroModes(void); + +// +// TED5-3 +// +void Item_EditMapEdges(void); +void Item_PrintMem(void); +void Item_Huffman(void); +void CheckInfoValues(int i,int j,int tilei); +void PrintMem(int x,int y); +void EraseFloatPaste(void); +void DrawFloatPaste(void); +void CopyScreen(int srcx,int srcy,int width,int height,int destx,int desty); +void Item_LAUNCHname(void); +void Item_PARMstring(void); +void Item_ChangeIconRows(void); +void Item_ChangeLaunchIcon(void); +void Item_ChangeBkgndColor(void); + +// +// TED5-4 +// +void SignalSound(void); +void Item_GraphicDump(void); +void Item_EditTinfoValues(void); +void Item_ProjectReSelect(void); +void Item_AddDelTinfo(void); +void Item_GridMode(void); +void Item_SnapTog(void); +void Item_ViewMap(void); +void Item_ReviewMap(void); +void Item_ImportMaps(void); +void Item_VisitDOS(void); +void Item_POtog(void); +void Do_ViewMap(int how); +int MakeOBJ(char *filename,char *destfilename,char *public,segtype whichseg,char *farname); +void DrawTinfoScreen(int thescreen,int deltax,int deltay); +void EnterTinfoValue(int whichtinfo,int mx,int my,int H_or_V); +void UseTinfoValue(int whichtinfo,int mx,int my,int PickupOrDrop); diff --git a/16/ted5/TED5.MAP b/16/ted5/TED5.MAP new file mode 100755 index 00000000..1d9315ef --- /dev/null +++ b/16/ted5/TED5.MAP @@ -0,0 +1,37 @@ + + Start Stop Length Name Class + + 00000H 03D85H 03D86H _TEXT CODE + 03D86H 075F3H 0386EH TED5_TEXT CODE + 075F4H 0AAB4H 034C1H TED5-1_TEXT CODE + 0AAB5H 0DF0EH 0345AH TED5-2_TEXT CODE + 0DF0FH 11A7EH 03B70H TED5-3_TEXT CODE + 11A7FH 155C6H 03B48H TED5-4_TEXT CODE + 155C8H 15F88H 009C1H TED5_A_TEXT CODE + 15F89H 18B31H 02BA9H MENU_TEXT CODE + 18B32H 1998FH 00E5EH LIB_TEXT CODE + 19990H 1A2B3H 00924H MEMMGR_TEXT CODE + 1A2B4H 1A55FH 002ACH XMS_TEXT CODE + 1A560H 1B034H 00AD5H JHUFF_TEXT CODE + 1B038H 1B3D8H 003A1H LIB_A_TEXT CODE + 1B3E0H 1DB46H 02767H EMU_PROG CODE + 1DB50H 1E117H 005C8H E87_PROG CODE + 1E120H 1E120H 00000H _FARDATA FAR_DATA + 1E120H 1F11FH 01000H TEDcharset FAR_DATA + 1F120H 1F120H 00000H _FARBSS FAR_BSS + 1F120H 1F120H 00000H _OVERLAY_ OVRINFO + 1F120H 1F120H 00000H _1STUB_ STUBSEG + 1F120H 25277H 06158H _DATA DATA + 25278H 25279H 00002H _CVTSEG DATA + 2527AH 2527AH 00000H _SCNSEG DATA + 2527AH 2527AH 00000H _CONST CONST + 2527AH 25291H 00018H _INIT_ INITDATA + 25292H 25292H 00000H _INITEND_ INITDATA + 25292H 25297H 00006H _EXIT_ EXITDATA + 25298H 25298H 00000H _EXITEND_ EXITDATA + 25298H 29B6BH 048D4H _BSS BSS + 29B6CH 29B6CH 00000H _BSSEND BSSEND + 29B70H 29BEFH 00080H _STACK STACK + +Program entry point at 0000:0000 + diff --git a/16/ted5/TED5.PRJ b/16/ted5/TED5.PRJ new file mode 100755 index 00000000..f05bc862 Binary files /dev/null and b/16/ted5/TED5.PRJ differ diff --git a/16/ted5/TED5.SYM b/16/ted5/TED5.SYM new file mode 100755 index 00000000..6e4d3db8 Binary files /dev/null and b/16/ted5/TED5.SYM differ diff --git a/16/ted5/TED5.TDK b/16/ted5/TED5.TDK new file mode 100755 index 00000000..e69de29b diff --git a/16/ted5/TED5_A.ASM b/16/ted5/TED5_A.ASM new file mode 100755 index 00000000..d8150eae --- /dev/null +++ b/16/ted5/TED5_A.ASM @@ -0,0 +1,1385 @@ +;==================================================== +; +; TED5 ASM Routines +; +;==================================================== + IDEAL + P386N + MODEL medium,C + +extrn XMSdriver:DWORD +extrn videomode:WORD,xmshandle:WORD,XMSlookup:WORD +extrn tilenum:WORD,lasticon:WORD,firsticon:WORD +extrn CGAlookup:WORD,EGA1lookup:WORD,EGA2lookup:WORD,VGAlookup:WORD + + DATASEG + +SCindex = 3c4h +SCmapmask = 2 +GCindex = 3CEh +GCreadmap = 4 +GCmode = 5 + +CombTable dw CombineCGA,CombineEGA,CombineEGA,CombineVGA +DrawTable dw DrawTCGA,DrawTEGA1,DrawTEGA2,DrawTVGA +OverTable dw OverlayCGA,OverlayEGA,OverlayEGA,OverlayVGA + +cgacolors db 55h,0aah +egacolors dw 0,0ffffh + +oldh db 0 +oldy dw 0 +horzadd dw 0 +wsize dw 1,2,4 +hsize dw 8,16,32 +twidth dw 0 +theight dw 0 +bmlen dw 0 +masklen dw 0 + +csize dw 32,64,256 +esize dw 32,128,512 +vsize dw 64,256,1024 + +cmsize dw 64,128,512 +emsize dw 40,160,640 +vmsize dw 128,512,2048 + + PUBLIC tdata +tdata db 2048 dup(?) +tdata1 db 2048 dup(?) + +; +; XMS move structure +; +blen dw 0,0 +shandle dw 0 +soff dd 0 +dhandle dw 0 +doff dd tdata1 + + +Csparse dw csp8,csp16,csp32 +Esparse dw esp8,esp16,esp32 +Vsparse dw vsp8,vsp16,vsp32 + +csp8 db 0ffh,0ffh + REPT 7 + db 0c0h,0 + ENDM +csp16 db 4 dup (0ffh) + REPT 15 + db 0c0h + db 3 dup (0) + ENDM +csp32 db 8 dup (0ffh) + REPT 31 + db 0c0h + db 7 dup(0) + ENDM + +LABEL esp8 BYTE + REPT 4 + db 0ffh + db 7 dup (80h) + ENDM +LABEL esp16 BYTE + REPT 4 + db 0ffh,0ffh + REPT 15 + db 80h,0 + ENDM + ENDM +LABEL esp32 BYTE + REPT 4 + db 4 dup (0ffh) + REPT 31 + db 80h,0,0,0 + ENDM + ENDM + +vsp8 db 8 dup(0ffh) + REPT 7 + db 0ffh,7 dup(0) + ENDM +vsp16 db 16 dup(0ffh) + REPT 15 + db 0ffh,15 dup(0) + ENDM +vsp32 db 32 dup(0ffh) + REPT 31 + db 0ffh,31 dup(0) + ENDM + + + CODESEG +;==================================================== +; +; Combine tiles together (background,foreground,icons) +; +;==================================================== +PUBLIC CombineTiles +PROC CombineTiles + ARG tileb:WORD,tilef:WORD,tilei:WORD,tsize:WORD + + push si + push di + + cld + mov bx,[tsize] + shl bx,1 + mov dx,[hsize+bx-2] + mov [theight],dx + mov cx,[wsize+bx-2] + mov [twidth],cx + mov ax,[xmshandle] + mov [shandle],ax ;set XMS handle + + mov si,[videomode] + shl si,1 + mov ax,[CombTable+si] + jmp ax +; +; Combine CGA tiles +; +LABEL CombineCGA PROC + + shl [twidth],1 + mov cx,[cmsize+bx-2] + mov [bmlen],cx + mov ax,[csize+bx-2] ;get length of block to move + mov [blen],ax + sub cx,ax + mov [masklen],cx + +; +; Handle the background tiles first! +; + mov ax,[tileb] + cmp ax,8000h ;solid color? + jb @@c1 + neg ax + + mov di,ds + mov es,di + mov di,OFFSET tdata + mov bx,ax + and bx,1 + mov al,[cgacolors+bx] + + mov cx,[blen] + rep stosb + jmp SHORT @@c2 + +@@c1: + shl ax,2 + mov bx,ax + mov es,[XMSlookup] ;(LONG SEG *) + mov ax,[es:bx] + mov [WORD PTR soff],ax + mov ax,[es:bx+2] + mov [WORD PTR soff+2],ax + cmp ax,-1 ;SPARSE TILE? + je @@c1a + + mov ax,OFFSET tdata ;(quickie modification since "doff" + mov [WORD doff],ax ; should always point to "tdata1") + mov si,OFFSET blen + mov ah,11 + call [DWORD XMSdriver] ;move tile into tdata1 + mov ax,OFFSET tdata1 + mov [WORD doff],ax ;ahhh....back to normal + + jmp @@c2 +; +; Copy sparse tile to tdata +; +@@c1a: + mov bx,[tsize] + shl bx,1 + mov si,[Csparse+bx-2] + mov di,OFFSET tdata + mov cx,[blen] + shr cx,1 ;for WORD copy + mov ax,ds + mov es,ax + rep movsw + +; +; Handle foreground tiles +; +@@c2: + mov bx,[tilef] + cmp bx,0 + je @@c3 ;any masked tile? + + shl bx,2 + mov es,[XMSlookup] + mov ax,[es:bx] + mov [WORD PTR soff],ax + mov ax,[es:bx+2] + mov [WORD PTR soff+2],ax + cmp ax,-1 ;SPARSE MASKED TILE? + je @@c3 + + mov ax,[bmlen] + mov [blen],ax ;set masked tile length for XMS copy + mov si,OFFSET blen + mov ah,11 + call [DWORD XMSdriver] ;move tile into tdata1 +; +; now we have the masked tile in "tdata1". +; time to mask it onto "tdata" +; + mov si,OFFSET tdata1 + add si,[masklen] ;SI = masked tile's tiledata + mov di,OFFSET tdata ;DI = tile in "tdata" + + mov dx,[theight] + mov bx,OFFSET tdata1 ;BX = mask +@@c2a: + mov cx,[twidth] +@@c2b: + mov al,[bx] ;get mask byte + and [di],al ;and tdata with it + lodsb ;get tilem byte + or [di],al ;OR it onto tdata + inc di + inc bx + loop @@c2b + dec dx + jnz @@c2a +; +; Handle icons (foreground tiles) +; +@@c3: + mov bx,[tilei] + cmp bx,[lasticon] + ja @@cexit ;any icons? + cmp bx,[firsticon] + jbe @@cexit + + shl bx,2 + mov es,[XMSlookup] + mov ax,[es:bx] + mov [WORD PTR soff],ax + mov ax,[es:bx+2] + mov [WORD PTR soff+2],ax + + mov ax,[bmlen] + mov [blen],ax ;set masked tile length for XMS copy + mov si,OFFSET blen + mov ah,11 + call [DWORD XMSdriver] ;move tile into tdata1 +; +; now we have the masked tile in "tdata1". +; time to mask it onto "tdata" +; + mov si,OFFSET tdata1 + add si,[masklen] ;SI = masked tile's tiledata + mov di,OFFSET tdata ;DI = tile in "tdata" + + mov dx,[theight] + mov bx,OFFSET tdata1 ;BX = mask +@@c3a: + mov cx,[twidth] +@@c3b: + mov al,[bx] ;get mask byte + and [di],al ;and tdata with it + lodsb ;get tilem byte + or [di],al ;OR it onto tdata + inc di + inc bx + loop @@c3b + dec dx + jnz @@c3a +@@cexit: + pop di + pop si + ret + +; +; Combine EGA tiles +; +LABEL CombineEGA PROC + + mov cx,[emsize+bx-2] + mov [bmlen],cx + mov ax,[esize+bx-2] ;get length of block to move + mov [blen],ax + sub cx,ax + mov [masklen],cx + +; +; Handle the background tiles first! +; + mov ax,[tileb] + cmp ax,8000h ;solid color? + jb @@e1 + neg ax + + mov di,ds + mov es,di + mov di,OFFSET tdata + mov dx,ax + + mov cx,[blen] ;plane 0 + shr cx,3 + mov bx,dx + shr dx,1 + and bx,1 + shl bx,1 + mov ax,[egacolors+bx] + rep stosw + + mov cx,[blen] ;plane 1 + shr cx,3 + mov bx,dx + shr dx,1 + and bx,1 + shl bx,1 + mov ax,[egacolors+bx] + rep stosw + + mov cx,[blen] ;plane 2 + shr cx,3 + mov bx,dx + shr dx,1 + and bx,1 + shl bx,1 + mov ax,[egacolors+bx] + rep stosw + + mov cx,[blen] ;plane 3 + shr cx,3 + mov bx,dx + shr dx,1 + and bx,1 + shl bx,1 + mov ax,[egacolors+bx] + rep stosw + jmp SHORT @@e2 + +@@e1: + shl ax,2 + mov bx,ax + mov es,[XMSlookup] ;(LONG SEG *) + mov ax,[es:bx] + mov [WORD PTR soff],ax + mov ax,[es:bx+2] + mov [WORD PTR soff+2],ax + cmp ax,-1 ;SPARSE TILE? + je @@e1a + + mov ax,OFFSET tdata ;(quickie modification since "doff" + mov [WORD doff],ax ; should always point to "tdata1") + mov si,OFFSET blen + mov ah,11 + call [DWORD XMSdriver] ;move tile into tdata1 + mov ax,OFFSET tdata1 + mov [WORD doff],ax ;ahhh....back to normal + + jmp @@e2 +; +; Copy sparse tile to tdata +; +@@e1a: + mov bx,[tsize] + shl bx,1 + mov si,[Esparse+bx-2] + mov di,OFFSET tdata + mov cx,[blen] + shr cx,1 ;for WORD copy + mov ax,ds + mov es,ax + rep movsw + +; +; Handle foreground tiles +; +@@e2: + mov bx,[tilef] + cmp bx,0 + je @@e3 ;any masked tile? + + shl bx,2 + mov es,[XMSlookup] + mov ax,[es:bx] + mov [WORD PTR soff],ax + mov ax,[es:bx+2] + mov [WORD PTR soff+2],ax + cmp ax,-1 ;SPARSE MASKED TILE? + je @@e3 + + mov ax,[bmlen] + mov [blen],ax ;set masked tile length for XMS copy + mov si,OFFSET blen + mov ah,11 + call [DWORD XMSdriver] ;move tile into tdata1 +; +; now we have the masked tile in "tdata1". +; time to mask it onto "tdata" +; + mov si,OFFSET tdata1 + add si,[masklen] ;SI = masked tile's tiledata + mov di,OFFSET tdata ;DI = tile in "tdata" + mov ah,4 +@@e2a0: + mov dx,[theight] + mov bx,OFFSET tdata1 ;BX = mask +@@e2a: + mov cx,[twidth] +@@e2b: + mov al,[bx] ;get mask byte + and [di],al ;and tdata with it + lodsb ;get tilem byte + or [di],al ;OR it onto tdata + inc di + inc bx + loop @@e2b + dec dx + jnz @@e2a + dec ah + jnz @@e2a0 ;do all 4 planes! +; +; Handle icons (foreground tiles) +; +@@e3: + mov bx,[tilei] + cmp bx,[lasticon] + ja @@eexit ;any icons? + cmp bx,[firsticon] + jbe @@eexit + + shl bx,2 + mov es,[XMSlookup] + mov ax,[es:bx] + mov [WORD PTR soff],ax + mov ax,[es:bx+2] + mov [WORD PTR soff+2],ax + + mov ax,[bmlen] + mov [blen],ax ;set masked tile length for XMS copy + mov si,OFFSET blen + mov ah,11 + call [DWORD XMSdriver] ;move tile into tdata1 +; +; now we have the masked tile in "tdata1". +; time to mask it onto "tdata" +; + mov si,OFFSET tdata1 + add si,[masklen] ;SI = masked tile's tiledata + mov di,OFFSET tdata ;DI = tile in "tdata" + mov ah,4 +@@e3a0: + mov dx,[theight] + mov bx,OFFSET tdata1 ;BX = mask +@@e3a: + mov cx,[twidth] +@@e3b: + mov al,[bx] ;get mask byte + and [di],al ;and tdata with it + lodsb ;get tilem byte + or [di],al ;OR it onto tdata + inc di + inc bx + loop @@e3b + dec dx + jnz @@e3a + dec ah + jnz @@e3a0 ;do all 4 planes! +@@eexit: + pop di + pop si + ret + +; +; Combine VGA tiles +; +LABEL CombineVGA PROC + + shl [twidth],3 + mov cx,[vmsize+bx-2] + mov [bmlen],cx + mov ax,[vsize+bx-2] ;get length of block to move + mov [blen],ax + sub cx,ax + mov [masklen],cx + +; +; Handle the background tiles first! +; + mov ax,[tileb] + cmp ax,8000h ;solid color? + jb @@v1 + neg ax + + mov di,ds + mov es,di + mov di,OFFSET tdata + shl ax,4 + mov bx,[blen] + shr bx,3 + + mov cx,bx + rep stosb + inc al + mov cx,bx + rep stosb + inc al + mov cx,bx + rep stosb + inc al + mov cx,bx + rep stosb + inc al + mov cx,bx + rep stosb + inc al + mov cx,bx + rep stosb + inc al + mov cx,bx + rep stosb + inc al + mov cx,bx + rep stosb + + jmp SHORT @@v2 + +@@v1: + shl ax,2 + mov bx,ax + mov es,[XMSlookup] ;(LONG SEG *) + mov ax,[es:bx] + mov [WORD PTR soff],ax + mov ax,[es:bx+2] + mov [WORD PTR soff+2],ax + cmp ax,-1 ;SPARSE TILE? + je @@v1a + + mov ax,OFFSET tdata ;(quickie modification since "doff" + mov [WORD doff],ax ; should always point to "tdata1") + mov si,OFFSET blen + mov ah,11 + call [DWORD XMSdriver] ;move tile into tdata1 + mov ax,OFFSET tdata1 + mov [WORD doff],ax ;ahhh....back to normal + + jmp @@v2 +; +; Copy sparse tile to tdata +; +@@v1a: + mov bx,[tsize] + shl bx,1 + mov si,[Vsparse+bx-2] + mov di,OFFSET tdata + mov cx,[blen] + shr cx,1 ;for WORD copy + mov ax,ds + mov es,ax + rep movsw + +; +; Handle foreground tiles +; +@@v2: + mov bx,[tilef] + cmp bx,0 + je @@v3 ;any masked tile? + + shl bx,2 + mov es,[XMSlookup] + mov ax,[es:bx] + mov [WORD PTR soff],ax + mov ax,[es:bx+2] + mov [WORD PTR soff+2],ax + cmp ax,-1 ;SPARSE MASKED TILE? + je @@v3 + + mov ax,[bmlen] + mov [blen],ax ;set masked tile length for XMS copy + mov si,OFFSET blen + mov ah,11 + call [DWORD XMSdriver] ;move tile into tdata1 +; +; now we have the masked tile in "tdata1". +; time to mask it onto "tdata" +; + mov si,OFFSET tdata1 + add si,[masklen] ;SI = masked tile's tiledata + mov di,OFFSET tdata ;DI = tile in "tdata" + + mov dx,[theight] + mov bx,OFFSET tdata1 ;BX = mask +@@v2a: + mov cx,[twidth] +@@v2b: + mov al,[bx] ;get mask byte + and [di],al ;and tdata with it + lodsb ;get tilem byte + or [di],al ;OR it onto tdata + inc di + inc bx + loop @@v2b + dec dx + jnz @@v2a +; +; Handle icons (foreground tiles) +; +@@v3: + mov bx,[tilei] + cmp bx,[lasticon] + ja @@vexit ;any icons? + cmp bx,[firsticon] + jbe @@vexit + + shl bx,2 + mov es,[XMSlookup] + mov ax,[es:bx] + mov [WORD PTR soff],ax + mov ax,[es:bx+2] + mov [WORD PTR soff+2],ax + + mov ax,[bmlen] + mov [blen],ax ;set masked tile length for XMS copy + mov si,OFFSET blen + mov ah,11 + call [DWORD XMSdriver] ;move tile into tdata1 +; +; now we have the masked tile in "tdata1". +; time to mask it onto "tdata" +; + mov si,OFFSET tdata1 + add si,[masklen] ;SI = masked tile's tiledata + mov di,OFFSET tdata ;DI = tile in "tdata" + + mov dx,[theight] + mov bx,OFFSET tdata1 ;BX = mask +@@v3a: + mov cx,[twidth] +@@v3b: + mov al,[bx] ;get mask byte + and [di],al ;and tdata with it + lodsb ;get tilem byte + or [di],al ;OR it onto tdata + inc di + inc bx + loop @@v3b + dec dx + jnz @@v3a +@@vexit: + pop di + pop si + ret +ENDP + + +;==================================================== +; +; Draw a tile in any of the video modes +; NOTE: ONLY WORKS WITH TSIZE=2! +; +;==================================================== +PUBLIC DrawTile +PROC DrawTile + ARG x:WORD,y:WORD,tsize:WORD + + push si + push di + + mov bx,[tsize] + shl bx,1 + mov ah,[BYTE PTR hsize+bx-2] + mov [oldh],ah + mov cx,[wsize+bx-2] + + mov bx,[videomode] + shl bx,1 + mov dx,[DrawTable+bx] + + mov bx,[y] + shl bx,1 + jmp dx + +label DrawTCGA proc + + mov ax,0b800h + mov es,ax + mov si,OFFSET tdata + mov di,[x] + shl di,1 + add di,[CGAlookup+bx] + mov bx,cx + shl bx,1 + mov ah,[oldh] +@@c1: + mov cx,bx + rep movsb + sub di,bx + xor di,2000h + mov cx,bx + rep movsb + sub di,bx + xor di,2000h + add di,80 + + sub ah,2 + jnz @@c1 + + pop di + pop si + ret +; +; EGA1/2/3 TILE DRAW ROUTINES +; +label DrawTEGA1 proc + mov [horzadd],38 + mov di,[EGA1lookup+bx] + jmp SHORT DoDrawEGAT +label DrawTEGA2 proc + mov [horzadd],78 + mov di,[EGA2lookup+bx] + jmp SHORT DoDrawEGAT +label DoDrawEGAT proc + add di,[x] + mov [oldy],di + mov si,OFFSET tdata + mov bx,0a000h + mov es,bx + mov bx,cx +; +; AH : height +; BX : width +; ES:DI : dest +; DS:SI : source +; + cld + mov dx,GCindex + mov al,GCmode + out dx,al + inc dx + mov al,0 + out dx,al +; +; Plane 0 +; + mov dx,SCindex + mov al,SCmapmask + out dx,al + inc dx + mov al,1 + out dx,al + + mov dx,[horzadd] +@@1: + mov cx,bx + rep movsb + add di,dx + dec ah + jne @@1 +; +; Plane 1 +; + mov dx,SCindex + mov al,SCmapmask + out dx,al + inc dx + mov al,2 + out dx,al + + mov dx,[horzadd] + mov di,[oldy] + mov ah,[oldh] +@@2: + mov cx,bx + rep movsb + add di,dx + dec ah + jne @@2 +; +; Plane 2 +; + mov dx,SCindex + mov al,SCmapmask + out dx,al + inc dx + mov al,4 + out dx,al + + mov dx,[horzadd] + mov di,[oldy] + mov ah,[oldh] +@@3: + mov cx,bx + rep movsb + add di,dx + dec ah + jne @@3 +; +; Plane 3 +; + mov dx,SCindex + mov al,SCmapmask + out dx,al + inc dx + mov al,8 + out dx,al + + mov dx,[horzadd] + mov di,[oldy] + mov ah,[oldh] +@@4: + mov cx,bx + rep movsb + add di,dx + dec ah + jne @@4 + + pop di + pop si + ret + +label DrawTVGA proc + + mov ax,0a000h + mov es,ax + mov si,OFFSET tdata + mov di,[x] + shl di,3 + add di,[VGAlookup+bx] + mov bx,cx + shl bx,2 + mov ah,[oldh] +@@v1: + mov cx,bx + rep movsw + add di,304 + + dec ah + jnz @@v1 + + pop di + pop si + ret +ENDP + +;//////////////////////////////////////////////////////////////////// +; +; TED5 screen scroll routines! +; +;//////////////////////////////////////////////////////////////////// +PROC CopyCGA +PUBLIC CopyCGA + ARG srcx:WORD,srcy:WORD,width:WORD,height:WORD,destx:WORD,desty:WORD + USES si,di + push ds + + mov ax,0b800h + mov es,ax + mov ds,ax + shl [width],1 + shl [destx],1 + shl [srcx],1 + + mov ax,[srcy] + cmp ax,[desty] + jb @@1 + ja @@2 + mov ax,[srcx] + cmp ax,[destx] + jb @@0 +; +; Copy from sourcex to destx, right +; + mov dx,[height] + mov bx,[srcy] ;source & dest are the same! + shl bx,1 + cld + +@@aa: + mov si,[ss:CGAlookup+bx] + mov di,si + add si,[srcx] + add di,[destx] + mov cx,[width] + rep movsb + add bx,2 + dec dx + jnz @@aa + jz @@exit +; +; Copy from end of sourcex to end of destx, left +; +@@0: + mov dx,[height] + mov bx,[srcy] ;source & dest are the same! + shl bx,1 + +@@0a0: + mov si,[ss:CGAlookup+bx] + mov di,si + add si,[srcx] + add si,[width] + dec si + add di,[destx] + add di,[width] + dec di + mov cx,[width] + std + rep movsb + cld + add bx,2 + dec dx + jnz @@0a0 + jz @@exit +; +; Copy from end of sourcey to end of desty, up +; +@@1: + mov ah,[BYTE height] + mov dl,[BYTE srcy] + add dl,ah + dec dl + mov dh,[BYTE desty] + add dh,ah + dec dh + cld + +@@1a0: + mov bx,[srcy] + add bx,[height] + dec bx + shl bx,1 + mov si,[ss:CGAlookup+bx] + mov bx,[desty] + add bx,[height] + dec bx + shl bx,1 + mov di,[ss:CGAlookup+bx] + add si,[srcx] + add di,[destx] + mov cx,[width] + rep movsb + dec [height] + jnz @@1a0 + jz @@exit +; +; Copy from sourcey to desty, down +; +@@2: + mov ah,[BYTE height] + mov dl,[BYTE srcy] + mov dh,[BYTE desty] + cld + +@@2a0: + mov bx,[srcy] + shl bx,1 + mov si,[ss:CGAlookup+bx] + mov bx,[desty] + shl bx,1 + mov di,[ss:CGAlookup+bx] + add si,[srcx] + add di,[destx] + mov cx,[width] + rep movsb + inc [srcy] + inc [desty] + dec [height] + jnz @@2a0 + jz @@exit +@@exit: + pop ds + ret +ENDP + + +PROC CopyEGA +PUBLIC CopyEGA + ARG srcx:WORD,srcy:WORD,width:WORD,height:WORD,destx:WORD,desty:WORD + USES si,di + push ds + + mov dx,GCindex + mov ax,GCmode OR 100h + out dx,ax + + mov ax,0a000h + mov es,ax + mov ds,ax + + mov ax,[srcy] + cmp ax,[desty] + jb @@1 + ja @@2 + mov ax,[srcx] + cmp ax,[destx] + jb @@0 +; +; Copy from sourcex to destx, right +; + mov dx,[height] + mov bx,[srcy] ;source & dest are the same! + shl bx,1 + cld + + cmp [ss:videomode],2 + jb @@a +@@aa: + mov si,[ss:EGA2lookup+bx] + mov di,si + add si,[srcx] + add di,[destx] + mov cx,[width] + rep movsb + add bx,2 + dec dx + jnz @@aa + jz @@exit +@@a: + mov si,[ss:EGA1lookup+bx] + mov di,si + add si,[srcx] + add di,[destx] + mov cx,[width] + rep movsb + add bx,2 + dec dx + jnz @@a + jz @@exit +; +; Copy from end of sourcex to end of destx, left +; +@@0: + mov dx,[height] + mov bx,[srcy] ;source & dest are the same! + shl bx,1 + + cmp [ss:videomode],2 + jb @@0a +@@0a0: + mov si,[ss:EGA2lookup+bx] + mov di,si + add si,[srcx] + add si,[width] + dec si + add di,[destx] + add di,[width] + dec di + mov cx,[width] + std + rep movsb + cld + add bx,2 + dec dx + jnz @@0a0 + jz @@exit +@@0a: + mov si,[ss:EGA1lookup+bx] + mov di,si + add si,[srcx] + add si,[width] + dec si + add di,[destx] + add di,[width] + dec di + mov cx,[width] + std + rep movsb + cld + add bx,2 + dec dx + jnz @@0a + jz @@exit +; +; Copy from end of sourcey to end of desty, up +; +@@1: + mov ah,[BYTE height] + mov dl,[BYTE srcy] + add dl,ah + dec dl + mov dh,[BYTE desty] + add dh,ah + dec dh + cld + + cmp [ss:videomode],2 + jb @@1a +@@1a0: + mov bx,[srcy] + add bx,[height] + dec bx + shl bx,1 + mov si,[ss:EGA2lookup+bx] + mov bx,[desty] + add bx,[height] + dec bx + shl bx,1 + mov di,[ss:EGA2lookup+bx] + add si,[srcx] + add di,[destx] + mov cx,[width] + rep movsb + dec [height] + jnz @@1a0 + jz @@exit +@@1a: + mov bl,dl + xor bh,bh + shl bx,1 + mov si,[ss:EGA1lookup+bx] + mov bl,dh + xor bh,bh + shl bx,1 + mov di,[ss:EGA1lookup+bx] + add si,[srcx] + add di,[destx] + mov cx,[width] + rep movsb + dec dl + dec dh + dec ah + jnz @@1a + jz @@exit +; +; Copy from sourcey to desty, down +; +@@2: + mov ah,[BYTE height] + mov dl,[BYTE srcy] + mov dh,[BYTE desty] + cld + + cmp [ss:videomode],2 + jb @@2a +@@2a0: + mov bx,[srcy] + shl bx,1 + mov si,[ss:EGA2lookup+bx] + mov bx,[desty] + shl bx,1 + mov di,[ss:EGA2lookup+bx] + add si,[srcx] + add di,[destx] + mov cx,[width] + rep movsb + inc [srcy] + inc [desty] + dec [height] + jnz @@2a0 + jz @@exit +@@2a: + mov bl,dl + xor bh,bh + shl bx,1 + mov si,[ss:EGA1lookup+bx] + mov bl,dh + xor bh,bh + shl bx,1 + mov di,[ss:EGA1lookup+bx] + add si,[srcx] + add di,[destx] + mov cx,[width] + rep movsb + inc dl + inc dh + dec ah + jnz @@2a +@@exit: + pop ds + ret +ENDP + +PROC CopyVGA +PUBLIC CopyVGA + ARG srcx:WORD,srcy:WORD,width:WORD,height:WORD,destx:WORD,desty:WORD + USES si,di + push ds + + mov ax,0a000h + mov es,ax + mov ds,ax + shl [width],3 + shl [destx],3 + shl [srcx],3 + + mov ax,[srcy] + cmp ax,[desty] + jb @@1 + ja @@2 + mov ax,[srcx] + cmp ax,[destx] + jb @@0 +; +; Copy from sourcex to destx, right +; + mov dx,[height] + mov bx,[srcy] ;source & dest are the same! + shl bx,1 + cld + +@@aa: + mov si,[ss:VGAlookup+bx] + mov di,si + add si,[srcx] + add di,[destx] + mov cx,[width] + rep movsb + add bx,2 + dec dx + jnz @@aa + jz @@exit +; +; Copy from end of sourcex to end of destx, left +; +@@0: + mov dx,[height] + mov bx,[srcy] ;source & dest are the same! + shl bx,1 + +@@0a0: + mov si,[ss:VGAlookup+bx] + mov di,si + add si,[srcx] + add si,[width] + dec si + add di,[destx] + add di,[width] + dec di + mov cx,[width] + std + rep movsb + cld + add bx,2 + dec dx + jnz @@0a0 + jz @@exit +; +; Copy from end of sourcey to end of desty, up +; +@@1: + mov ah,[BYTE height] + mov dl,[BYTE srcy] + add dl,ah + dec dl + mov dh,[BYTE desty] + add dh,ah + dec dh + cld + +@@1a0: + mov bx,[srcy] + add bx,[height] + dec bx + shl bx,1 + mov si,[ss:VGAlookup+bx] + mov bx,[desty] + add bx,[height] + dec bx + shl bx,1 + mov di,[ss:VGAlookup+bx] + add si,[srcx] + add di,[destx] + mov cx,[width] + rep movsb + dec [height] + jnz @@1a0 + jz @@exit +; +; Copy from sourcey to desty, down +; +@@2: + mov ah,[BYTE height] + mov dl,[BYTE srcy] + mov dh,[BYTE desty] + cld + +@@2a0: + mov bx,[srcy] + shl bx,1 + mov si,[ss:VGAlookup+bx] + mov bx,[desty] + shl bx,1 + mov di,[ss:VGAlookup+bx] + add si,[srcx] + add di,[destx] + mov cx,[width] + rep movsb + inc [srcy] + inc [desty] + dec [height] + jnz @@2a0 + jz @@exit +@@exit: + pop ds + ret +ENDP + +;//////////////////////////////////////////////////////////////////// +; +; OVERLAY routine +; +;//////////////////////////////////////////////////////////////////// +PROC Overlay +PUBLIC Overlay + ARG tsize:WORD + + push di + push si + + mov di,OFFSET tdata + mov bx,[tsize] + shl bx,1 + mov si,[videomode] + shl si,1 + mov ax,[OverTable+si] + jmp ax + +LABEL OverlayCGA PROC + + mov cx,[csize+bx-2] + shr cx,1 + mov si,[Csparse+bx-2] +@@c1: lodsw + or [di],ax + add di,2 + loop @@c1 + + pop si + pop di + ret + +LABEL OverlayEGA PROC + + mov cx,[esize+bx-2] + shr cx,1 + mov si,[Esparse+bx-2] +@@e1: lodsw + or [di],ax + add di,2 + loop @@e1 + + pop si + pop di + ret + +LABEL OverlayVGA PROC + + mov cx,[vsize+bx-2] + shr cx,1 + mov si,[Vsparse+bx-2] +@@v1: lodsw + or [di],ax + add di,2 + loop @@v1 + + pop si + pop di + ret + +ENDP + +END \ No newline at end of file diff --git a/16/ted5/TEST.BAT b/16/ted5/TEST.BAT new file mode 100755 index 00000000..c9cf28a7 --- /dev/null +++ b/16/ted5/TEST.BAT @@ -0,0 +1,6 @@ +copy ted5.exe .. +lcd keen4 +ted5 +lcd ted5 +bcx + diff --git a/16/ted5/XMS.C b/16/ted5/XMS.C new file mode 100755 index 00000000..a3b32f8e --- /dev/null +++ b/16/ted5/XMS.C @@ -0,0 +1,200 @@ +//////////////////////////////////////////////////// +// +// XMS routines - uses the MENU.C & LIB.C routines for output +// +//////////////////////////////////////////////////// +#include "ted5.h" +#pragma hdrstop + + +long TTLxms; +unsigned XMSavail; +void far *XMSdriver; + +//////////////////////////////////////////////////// +// +// CALL the XMSdriver with a function # +// +//////////////////////////////////////////////////// +void CallXMS(char func) +{ + asm mov ah,[func] + asm call [DWORD PTR XMSdriver] +} + +//////////////////////////////////////////////////// +// +// Initialize the XMS memory +// +//////////////////////////////////////////////////// +void InitXMS(void) +{ + // + // See if XMS driver is present... + // + asm mov ax,0x4300 + asm int 0x2f + asm cmp al,0x80 // installed? + asm je Present + + ErrDialog("You poor bastard! I refuse\n" + "to work without Extended\n" + "Memory! Goodbye!"," I Suck "); + Quit("No Extended Memory Driver found!"); + + // + // YES! We found an XMS driver! Now we + // need to get the XMS driver's entry address... + // + Present: + asm mov ax,0x4310 + asm int 0x2f + asm mov WORD PTR XMSdriver,bx + asm mov WORD PTR XMSdriver+2,es + + XMSTotalFree(); +} + + +//////////////////////////////////////////////////// +// +// Report an XMS error, if any +// +//////////////////////////////////////////////////// +void XMSerror(void) +{ + if (_AX==0) + switch(_BL) + { + case 0x80: Quit("Function not implemented!"); + case 0x81: Quit("VDISK device driver was detected!"); + case 0x82: Quit("A20 error occurred!"); + case 0x8e: Quit("General driver error!"); + case 0x8f: Quit("Unrecoverable driver error!"); + + case 0x90: Quit("High memory area does not exist!"); + case 0x91: Quit("High memory area already in use!"); + case 0x92: Quit("DX is less than /HMAMIN= parameter!"); + case 0x93: Quit("High memory area not allocated!"); + case 0x94: Quit("A20 line still enabled!"); + + case 0xa0: Quit("Not enough Extended Memory available!"); + case 0xa1: Quit("Extended memory handles exhausted!"); + case 0xa2: Quit("Invalid handle!"); + case 0xa3: Quit("Invalid source handle!"); + case 0xa4: Quit("Invalid source offset!"); + case 0xa5: Quit("Invalid destination handle!"); + case 0xa6: Quit("Invalid destination offset!"); + case 0xa7: Quit("Invalid length!"); + case 0xa8: Quit("Invalid overlap in move request!"); + case 0xa9: Quit("Parity error detected!"); + case 0xaa: Quit("Block is not locked!"); + case 0xab: Quit("Block is locked!"); + case 0xac: Quit("Lock count overflowed!"); + case 0xad: Quit("Lock failed!"); + + case 0xb0: Quit("Smaller UMB is available!"); + case 0xb1: Quit("No UMBs are available!"); + case 0xb2: Quit("Invalid UMB segment number!"); + + default: Quit("Unknown XMS Memory Error! I'm totally stumped!"); + } +} + +//////////////////////////////////////////////////// +// +// Allocate XMS memory +// +//////////////////////////////////////////////////// +int XMSAllocate(long size) +{ + #if 0 + static int allocnum=0; + + _MouseHide(); + sx=0; + sy=1; + print("XMS allocation #"); + printint(allocnum++); + print(":"); + printint((1023L+size)/1024L); + print("K"); + while(!keydown[0x1c]); + clearkeys(); + _MouseShow(); + #endif + + + _DX=(size+1023)/1024; + CallXMS(9); + XMSerror(); + asm push dx + TTLxms=1024L*XMSTotalFree(); + asm pop dx + return _DX; +} + +//////////////////////////////////////////////////// +// +// Free XMS memory +// +//////////////////////////////////////////////////// +void XMSFreeMem(int handle) +{ + _DX=handle; + CallXMS(10); + XMSerror(); + TTLxms=1024L*XMSTotalFree(); +} + + +//////////////////////////////////////////////////// +// +// Return XMS memory available +// +//////////////////////////////////////////////////// +unsigned XMSTotalFree(void) +{ + CallXMS(8); + XMSerror(); + XMSavail=_DX; + return XMSavail; +} + +//////////////////////////////////////////////////// +// +// Move XMS memory +// +//////////////////////////////////////////////////// +void XMSmove(int srchandle,long srcoff,int desthandle,long destoff,long size) +{ + struct { long bsize; + int shandle; + long soff; + int dhandle; + long doff; + } XMSparms; + + unsigned DSreg,SIreg; + + XMSparms.bsize=size+(size&1); + XMSparms.shandle=srchandle; + XMSparms.dhandle=desthandle; + XMSparms.soff=srcoff; + XMSparms.doff=destoff; + + DSreg=FP_SEG(&XMSparms); + SIreg=FP_OFF(&XMSparms); + + asm push ds + asm push si + asm mov si,SIreg + asm mov ds,DSreg + + CallXMS(11); + + asm pop si + asm pop ds + + XMSerror(); +} \ No newline at end of file diff --git a/16/ted5/XMS.H b/16/ted5/XMS.H new file mode 100755 index 00000000..d51a2c02 --- /dev/null +++ b/16/ted5/XMS.H @@ -0,0 +1,8 @@ +void InitXMS(void); +int XMSAllocate(long size); +unsigned XMSTotalFree(void); // returns KB free +void XMSFreeMem(int handle); +void XMSmove(int srchandle,long srcoff,int desthandle,long destoff,long size); + +extern unsigned XMSavail; +extern long TTLxms; \ No newline at end of file diff --git a/16/ted5/_TEDCHAR.EGA b/16/ted5/_TEDCHAR.EGA new file mode 100755 index 00000000..a01c32fe Binary files /dev/null and b/16/ted5/_TEDCHAR.EGA differ diff --git a/16/ted5/_TOM.PIC b/16/ted5/_TOM.PIC new file mode 100755 index 00000000..ad3b7a45 Binary files /dev/null and b/16/ted5/_TOM.PIC differ