From 4c15d088479b9b6c4a8b298a9db585bc11582321 Mon Sep 17 00:00:00 2001 From: sparky4 Date: Thu, 26 Oct 2023 19:37:56 -0500 Subject: [PATCH] ted5 added --- 16/ted5/BACKUP.BAT | 6 + 16/ted5/CHARSE.LBM | Bin 0 -> 11094 bytes 16/ted5/EGAHEAD.TED | Bin 0 -> 64 bytes 16/ted5/EGALATCH.TED | Bin 0 -> 4096 bytes 16/ted5/GRAB.BAT | 2 + 16/ted5/GRAPHTED.H | 12 + 16/ted5/INFO.TXT | 97 ++ 16/ted5/JHUFF.C | 1287 +++++++++++++++++++ 16/ted5/JHUFF.H | 26 + 16/ted5/LIB.C | 1011 +++++++++++++++ 16/ted5/LIB.H | 42 + 16/ted5/LIB_A.ASM | 259 ++++ 16/ted5/MAPTEMP | Bin 0 -> 74 bytes 16/ted5/MAPTHEAD | Bin 0 -> 1096 bytes 16/ted5/MEMMGR.C | 781 ++++++++++++ 16/ted5/MEMMGR.H | 28 + 16/ted5/MENU.C | 1877 ++++++++++++++++++++++++++++ 16/ted5/MENU.H | 78 ++ 16/ted5/README.TXT | 13 + 16/ted5/README.md | 2 + 16/ted5/T.BAT | 4 + 16/ted5/TDCONFIG.TD | Bin 0 -> 733 bytes 16/ted5/TED.NSC | 7 + 16/ted5/TED5-1.C | 2089 +++++++++++++++++++++++++++++++ 16/ted5/TED5-2.C | 2184 +++++++++++++++++++++++++++++++++ 16/ted5/TED5-3.C | 2033 ++++++++++++++++++++++++++++++ 16/ted5/TED5-4.C | 2633 +++++++++++++++++++++++++++++++++++++++ 16/ted5/TED5.C | 2779 ++++++++++++++++++++++++++++++++++++++++++ 16/ted5/TED5.DSK | Bin 0 -> 1873 bytes 16/ted5/TED5.EXE | Bin 0 -> 304195 bytes 16/ted5/TED5.H | 356 ++++++ 16/ted5/TED5.MAP | 37 + 16/ted5/TED5.PRJ | Bin 0 -> 8562 bytes 16/ted5/TED5.SYM | Bin 0 -> 123418 bytes 16/ted5/TED5.TDK | 0 16/ted5/TED5_A.ASM | 1385 +++++++++++++++++++++ 16/ted5/TEST.BAT | 6 + 16/ted5/XMS.C | 200 +++ 16/ted5/XMS.H | 8 + 16/ted5/_TEDCHAR.EGA | Bin 0 -> 4096 bytes 16/ted5/_TOM.PIC | Bin 0 -> 32008 bytes 41 files changed, 19242 insertions(+) create mode 100755 16/ted5/BACKUP.BAT create mode 100755 16/ted5/CHARSE.LBM create mode 100755 16/ted5/EGAHEAD.TED create mode 100755 16/ted5/EGALATCH.TED create mode 100755 16/ted5/GRAB.BAT create mode 100755 16/ted5/GRAPHTED.H create mode 100755 16/ted5/INFO.TXT create mode 100755 16/ted5/JHUFF.C create mode 100755 16/ted5/JHUFF.H create mode 100755 16/ted5/LIB.C create mode 100755 16/ted5/LIB.H create mode 100755 16/ted5/LIB_A.ASM create mode 100755 16/ted5/MAPTEMP create mode 100755 16/ted5/MAPTHEAD create mode 100755 16/ted5/MEMMGR.C create mode 100755 16/ted5/MEMMGR.H create mode 100755 16/ted5/MENU.C create mode 100755 16/ted5/MENU.H create mode 100755 16/ted5/README.TXT create mode 100755 16/ted5/README.md create mode 100755 16/ted5/T.BAT create mode 100755 16/ted5/TDCONFIG.TD create mode 100755 16/ted5/TED.NSC create mode 100755 16/ted5/TED5-1.C create mode 100755 16/ted5/TED5-2.C create mode 100755 16/ted5/TED5-3.C create mode 100755 16/ted5/TED5-4.C create mode 100755 16/ted5/TED5.C create mode 100755 16/ted5/TED5.DSK create mode 100755 16/ted5/TED5.EXE create mode 100755 16/ted5/TED5.H create mode 100755 16/ted5/TED5.MAP create mode 100755 16/ted5/TED5.PRJ create mode 100755 16/ted5/TED5.SYM create mode 100755 16/ted5/TED5.TDK create mode 100755 16/ted5/TED5_A.ASM create mode 100755 16/ted5/TEST.BAT create mode 100755 16/ted5/XMS.C create mode 100755 16/ted5/XMS.H create mode 100755 16/ted5/_TEDCHAR.EGA create mode 100755 16/ted5/_TOM.PIC 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 0000000000000000000000000000000000000000..25e4f26ab675c767b3eb56e8f96df74b8fe319b6 GIT binary patch literal 11094 zcmeI2%WoUk6~@oy=tU=mtjI{?)+nsdg&<@RQL`ctfUaY-4G=p<+Q8^a+phXAhyoXa zS3=5e1O(9DUKrT~$Vzp%Ui@8y=P$XZ9G_e8jKZ#vSW{!ySk zmFX3~P%L=<@@O+3M3HL$-%-%Zdn+rxUwm`LTOMsr9Q0KWA~lC!Ps|s6e?Icf!sXGX zz;E(E18w#Mev|XQ=bPox=63_~{E;52HjkPId-;OD;QOXv=4G^Ljt)WI%pLCUnZiQk ztH~|Q$!Ifwp#5gQ*$npg^7DSt6piubT%cRJtD$0MS+pFa zA)O+oJ8@ju@&ehCT?wTlV{n`XpN(W!&ymm7MSH-vt|b)@WC-J{t3!M!jPq;K9`LP8 z33FKXj^Kl4vV(R4KA@VIt)g$M@3eC@kZR{F6SGz1ZNV5qk+XHAc2=(eo8T}&3*6Nz zB5UPvI-O#JmW-<+u2n>K430+c9}g7kvMGOsreZ~KET@R@0_4tAyQP?vH1LgsybP?3n@kJfBmIwn__WDA-1**jV` zaSs8oeT~713GD9f(wJSs9iQBf!7=S;sWpw~K%n2~=CQt3)rQuQ^DSM6WnclKg*^I3 zHcv2Cr6G0Xd`s408CYX*ddZtudu5ZI*8>4>=GEau}X~XB4QUHdLeQvj2SzK zQU4{hc#CreOv zD`niWs<}L5CWbcicw9n+w^GKe9j%5rR4@i6M_5Kw*RiTLH#eXnqP!>+C#hsdSVpYZ zv8pydH=v@eaq2) z**tRTw_$PIkW__44Lr)Ks0L$OADhi1mws708ueXJFR^e-Xe`|OXf9=Iu~6*r99dZ8#78Pt`|))<(MJEf?9yNJ=s; zvQcO4h-gB^ZN#~QhDSorl6m+nBGx3FB_SIh9IQdURfrRek#Pyy)$I{V z2*>u;OR@ki#@GXqV_brEb$i4TvSm`1Y#m)b7D3?}4V5FKfp(n0s3OWdNwXp-TwaDT zqk(puz^Ee2JkG}~9g~_#7+pTrkfWTj%V6vbGcvl4(dATZLwj`g|@DHNnK~{_$?l{|FjWGnjW9OseRf) zDAQBfIHrv-wUAx-4oJ$_I@liJJ)n%ZGO`UITMD-2GB#2?vNqpD%g`+)9E0O2G>h5O z9PmbgC6GkrQ#n~rft}qk(kpzUuE#Wa- z1{#~(ofwb`I=G9tG6qMhU;%k{2OGOEzcFI|)h%FE3%D{6rhq)VgNK3pn z1zZ_}qfz+}zGlHJIQy+mltGAJwp>Z-(tWyDjM+i8vU)rG1zWa$X}?P?&Zx)y)oGxc z`emeD@yPUJ%fcp+E`B+BqK9 zB~_J7L!o|-@5l!K?2m1SN-8RughKgTS|m8j<#{N~B60+Ly~lKe_Kw-c?4|^pwtyS~ zU+p>BzzN$f3C?o)hnS|SF##vQB5WH45PXsnY(s-|`YXbAGOK(-g0oyELB|r*(D7=h zP0n}7gVO{ZOHf0%tD!EpPZPZOWfFMtx896F#~va3K~Ndiz>B}}W(+!bLb>!;sW=T@ p{4(3YaeAk;z-YNv5TE0n&T=^|^HG-j{~a&)FBN#H!1qak{{nur7#08k literal 0 HcmV?d00001 diff --git a/16/ted5/EGAHEAD.TED b/16/ted5/EGAHEAD.TED new file mode 100755 index 0000000000000000000000000000000000000000..053a72c40ca822fa668e0fb9fa59f2ea88b79c4d GIT binary patch literal 64 UcmZQzVE_XMAPK?^Kuih%05m)S1poj5 literal 0 HcmV?d00001 diff --git a/16/ted5/EGALATCH.TED b/16/ted5/EGALATCH.TED new file mode 100755 index 0000000000000000000000000000000000000000..a01c32fe145957cd4753848931cb71d3b87e670e GIT binary patch literal 4096 zcmeHJy=vn?5Y|S8aTQXgJgzXVj|apC_zLR<%eW2qDb^t zm+0${{t;)8qkB%Bb3`ENvpZ6f{Cs+SrS~?C()L}4;x7r>CYzG`p=ZhE* zM%&dc5n0IP+>iTmh?3oTz;3|c%}E5K_pwuv>W;k;_%UTZpDT;}g)zz)ijCoy<64WjGmY}}jFh#pwQAs8x4knaBm4_DLu+neyQa4g z0@q{o;(DPCS%D&Rqn2!EZs(ui$nk+(^1)=3L!Tep+- zKDT*@vCcT3gUoJO&oO_Nm#SdS4G@{@K|C}dCWi&eeq1a6Hr{t0>+|>1FW3SLw|{(0 vY25zNwEw65k9CRF$S?25Y5!0Ae>(rC^M5-3r}KZh|4;Y->Hhy8-v9prwO5%d literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..48f87ccd3de5d5a99482d6c7c27168d226f08b86 GIT binary patch literal 74 zcmWG>bule7)HBdyU|=u=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 0000000000000000000000000000000000000000..c2d4161e80d2b007529afac65ff47fd93af911c4 GIT binary patch literal 733 zcmbu5!A^rf5QhI*C_}+zH(pFU?a4Fo0jdY%wHIH&Hk6Q%Bi zu>A84|IfS){iby<)n=&cs(0IVziaBDfB$USz1uY()&2JH&>x5*`1%5v*~kg69fv2e zTuf)WAbLUsnn*8?#3z>@^}P(0hO*a%>V!Z literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..2e17920504a141d52eaf85ac5c59ab9d172a9274 GIT binary patch literal 1873 zcmb_d&rcIU6#iyGz>10nB|#-s5w(d8RH}xHS+?6!?6!5cZ8T|ug|4BYbSqs7YK(t^ z7;eUk9=w1?4<<(c0MEvY@nXDr@`N!lCirG{ksn#42lwUm&5v)sH*e;>X=Zk2-0~}a z#j4omyzP&c%BH^?Z12G?)(!ZIxGQx4(52JTZ}x#bWA~WO0u1aEmT@0xoFEy?#pJY{ z2&RTdK~w(}U@W6Xlo45P5Kidum>iT14Ttf)iQx;Ww*ZOwu#07QLMX1@0$kIKpt8;E z`Wj$#BpZziWK3c>NxD_|_=+UF3tT55xOxkqshSqk8*;9x$*ce_laEIpzL#ihnSAqO zIyWewpIaE7lWvtNjooT-q2~oO!5G4%n`JK&Y=G2-h6MC2IeO}`fhb)^tjUEA2&hVY zT(`=rR)$xt4wQglydcP97xrNHI=s_I2j~M#TtW-l(MKuR0w4C_5RM=aRMKhwOFAL~ zCld$`%U7VJ($@_|SJfou@DuydgO9Yfoz@+vL>)i`SBdp57AQ4d;vL@OCZ&AYtoQ@L z3DisGoM_~zp%tp4jks-2k44LtRiyGLZ|Mq1&9v*KqG^eafNNIKH0Db7#N;+( zYCf4t%9`5WFK&4~C%jw08JBp0E%x0w0XVjqJUpZXcD~hBvLU{KU(~2}z3E-E!0=FB zPpBeqy;J}fdl$njskhKmEA}R#$qjB(kVY!2D=LpQ wlwYgg2Jb%CC@+uQ{bSha$p?P0LAqEcU0)ts?0eG-I95VZ@t$czO6OVj2RL{P_5c6? literal 0 HcmV?d00001 diff --git a/16/ted5/TED5.EXE b/16/ted5/TED5.EXE new file mode 100755 index 0000000000000000000000000000000000000000..02076f91b67a7b3a52694e295597940361c9ccc2 GIT binary patch literal 304195 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

+H|mUh(L^Y*8U>(zC=gvk!RQ_eK@^7} zM;wk~aU?2_qfi?hgJ$Abv=+ysEjR(4#YwPVXbSp_a}g$m$N)dIvXGJ}h?GK!q%=w= z6;Ljzgqo4cs28bI4_Y7XA`Q_o(g>X)jnPHY1dgWY18Ig3?ER?F zmdHq3!S0&vV9U-9D2R4M(X9gddJk+50hIM{`80_+vZ_nn-Cj?u|*Ohr%VG}!WRChT@N3qoi%>^nFIS=fB! z!4{xEwh%?JMJSssL&ex~REDiW)!477E?a}zvGr&W+W^N#G>2_QOW76#n_;50Y#Z9d zwxby2|#U8|-&V^+RFkl?mW-`hDvs3BaE6wS%WIjqftH0w zYuR{`mV@VLxp=--44>5U@B=L$Kh=uk*IGIJL92ir4HdDQp)&S2RKYQZYBEUey$s!OUqg4?-_QdOG4#aC4ZZPdLtnh!&=2o348Ru*1Mz3W zARO*67*}=}f_pd&#r+(H<3SE1@OX!jc#gwpyvkuL-rz6>Uv(IVZ#hiB4;{v1i*Yjc zGfu@Njni-&;|x5>I1^7d&cfS_v+-Wz9DLaL1HNgTiys>2;aA4__>J*LtT-;fE{=~Xu$K|+z<1e_W<4Qc%aTPx0xCWnbT#r4RHef%ejX1>V zH=OLW372%*jLSJ~!Ihl0;+jqqabu_LxV6(h+`;Jp?%{L@&v818=R5s@7dail%bbql zRZhq7I;Z1!lhX;j-RUIW<8%ria5{r8JDtThoX+8UPUrDkrwiEN3>yeLU%?^HS8=TK zO`Pm}8y7g=!KIw<;_}Y-a24nKxTf<1+}8OK?&ACePjh~XXFET`^PHdKMb0nqGUu0g zr}Jz4yYpLo-T589OZc<6CNh3)n14%bI zkQ|edR5v-1dL|R;W^y6DO|E2+$&HLKnaNm_g-kM8$#j!D`NiZ()|tG?0h13oV)7-Y zO@8Ep$)8*`1(2JjKyuF%L?o98qPRrD0duiSEXj3=Cna1GNLiO;Qq3iWv~Wo!-CWX0 zZDv~!YmB=TT8icsk zA_mvm#N=9sSX}E8FV}h`(zOwZacx4{*Jh;9wK*x{+JaPfZAluswj#}3+mXJm z?a6T04rH8bCo-s z25tk%w{F8pOSciEt=mX4(`^Eo>o%1vcAG|)yGjjP+YjW7 z+gx(NZ63MmwvgO(`-!}ETTGaF3Gpy5Bhluc$+za^q_uek>0YVBSownYWS~=3V54c{f3pJ;d3vkGNR&6MxG=5@k6|5-op_bjwlFz;c$fv|J?Z zESE@E%N5eYa+UP6Tq9#G*U4PV4f2!aCRu8^MSiv1CL1kx$S%uWa>#OzoUq&{7cCFS zUzW$@rsWB_Z+S}IS)LJWeNI&C3u3jtBmve}B+~kZq+8#TvetK`n)N-YYyCi4T0fFb z)=#9j^=~rLD$}u62Rg~>NM~A|=#N$xdc+F*d0EZ$oYhJ%S>5Rks}Fr)^`$0vKWcRk zpdRjlw6uE&t>_*~tGS2KTJ90Fi+dF9?H)~sxW~{@?y+==dpw=)o=AUiPoj(6lj#cg z6uQAZjc#(!pgY|&=|T4_ddxkW{^_1eFS+N@8}9k^p?d*+?p{bgx|g7z-Ahr~qcnwm zwW-CUEcN%OK!ZFg(hQGE^jnY0w4X;6I>@6c9ph1rPV}fwr+U<&b3JO&r5<(Y8jrek zy+=KI%;OvS&Z9mxdp4jRo(*Z1XCs>D*_amhY(krRHl-aro6*jm&FKu!7Ic?qOM1z( z6}{%!nqsf-sN&UzI(W6Ev0j~Mx>skK@70Bt^6E;fcy*&Syt>o6UOj13uU@pTS8qDR zs}CLL)sIf~>Q8_18bH^14WiqQ2>Qee)?B?uQ77-wG{k!h&GH^c zt9Xy6b-gFh#@-X@cixj|7ubTom-iGp!FwwG$$L88;ysh@_MS!0d(Wm7pR}3J1=_;r5^e2so%Zp$K?nNWq{Dn}(a}D4 z=mej8bgIvNy2R%JUGDRcuJU{c_nczXEo~uaI5$E6JYum1ZCO$}q*h zEHnC-XHNbVn3sP==I>vb1^QQEvHn$Al79`B;$M@M^RL4y_}681{J&w%{p+(%{ta1w z|3+-Ie-k#%za?Ah--`X}-;S;G@5m1LcVegfJF_ePUD-ANZtQ`7Pxi{c7n1_|Fo%G? z%oNa%`2`GO!2yF=Ou!J95HOVG2aILK117O*0h3w7fSIgyz--nnU=AA@FqeHFFpn(> zn9tS(EMV&b7P1`yi`l_|CG2#-a&|RfHM<}1D|;NUo~eNw;MmAg0yneDfm>Pi!0oJ2 z;11R_a2M+rxSNd*+{-2h?q^d253qTGN7>52lk9llDRw&W47(qAmc0o)$AW^+vy`Ae zSys?BRwn2#Rz2uCYZ!EcwF$b(x&_^0gM;p{u|ap)l%Pj!MbKlmG3Y7V9rTR-9`u_1 z5%iwj4En%62YqHq!IGR5jO1^EncO^Bllulc$fJXulHY|^fuotMhP9Ck!`jN#!rIBr!#c~|!n(-=!n(_&!g|Ov z!+Ob!!g|ZQ!}`cK!urY&!}`f@!v@G&_+Z&Be5f24K3t9oA0elNkCb!5N6BTv$I2DM z$I11>C&(?rC(7-^C&}HzC(DDwr^zG2r_0mBXUg-#XUR*$XUnU@=g3>b=gPan=gG&z zf0QqTFPE=`uafVCua+GmewBSA*2+NlLI1e%0ZF0rOZW8%M?h^S{?iKl7?i=|*9vu0%JT&sNJRwq2W=A?G^CKOVHIdHBzDSdD zCelT@73r$HiZsJvRalg}Vu|ulyrVo7zbGFiBFaxmj|x<3M+GV0Mg=SFqC%AJQK8D9 zsBmR;R1_T1%B-juWnNUQvLGr!SrL__Y>7%yPDG_DccRjj4^f%Q-%(kL7M-n_qjMDB z=v*ZtI!{TDE>J2)7b;DoODH{}ODVmgODjX8%P13~%PKRY%P9+^D=2HCD=7z}D=Sx` zYb(#A>nJp)uHqF_Ux|rnpd`gKR5D_kD#c@3Divc|D~)2>D4k>4DuZL%E0be7C<|gb zDobNJDa&KJD(hpqDSKnOE0e{D_{T3$dc-eO2FCxS ztdC!;7!sB$-U&Y|z6q<9q=Yp}PQrSnYr;llYQk^IuL+x#GYMOi3kh4{*sk15*rB{g z*r|L<*sUmudlbjSeTpUVfa0HcNC`_ktRy5JQL++`DFungmGX%vm70mCmHLTilopBS zl#YoPl*x&gl^+wYDC-ihD!US|D|-@eC}$IIDmM~uE4LEwC~p(*D=g^|9FG-q(o4lX z>6H?c^je8cdaGn4y;CYAy;mA1eN?(8eNu)ceOAUMN$T7rr0z??>ggn^UQLqK+ewQ0 zHc3_elQlIi*+I=rc2x6|oz!Z{&T6k@lR7flO`Vc#RTm_?t4otT)RoEJ>gr@4bwjeh zx+OV4-IW}y{+=ABo=px{FD1vQ*OTMahslZRhvX#HoRX}1rKG7oDd}ozN|u_HlC4%x zDOBsG6jvLjlvIbNlv1aplvZb^R8Z%nR91gasji+#siFRrQd51IQcI<&byZVpJvA=% z8?{nueYJLK1GRB#ZFO*JV|8L`6LofKGj(2SYjsiTcj~&-HtNpQj_SVDPU@@FE-Fsz zs=BB3P`%RnsxfJU)TFe*a12pfrwvovq>WHJrA<_)q)kf!a8Ik=i!>C$)3>Vzp=b5_Nd`FY3hfmFn#D)#}3Zwd$Jm zb?Vmi_3Hlg4eB51o7AJ}o7MB_Th#06Th+Vi+tvH&JJgryJJr9__oy^uziQ6-UG>U1 zpax_dR)aGBP$M#qsj(Ty)#Qv*YG%f1wRpxEwPMCOwRXmNwL!)OwPnUd^}CGAYTJw( zYX6K|>hO%)>XM8*>c)&m>Yj{e>Vb^s>f4N$D$9JO24%igLo+|A>6uu|%_MM8t!t*N zb#jwWzE>tuQM{Ynm0Tb;%0V24sb4 z!?MD)FImYiKl%gnB-70a%smB_BCmCLTB)yS@` zHO#K7waTuiwa;##^~r9e^~-LiP0Vhg&CG78ZOU$?9n5Z{oyl&iUCeH;-O28tJ<9H; zz0U5gNjW_ zb4F`}bH->Ra>i=oa;9q!a%O7Ja^`B5+<96^?vGk>?n13(?jo&D?qaQd?h>tM?lP@+ z?s9EZ?h0*c?l0P$+%?*|+_l=C+;!T?-1XXDxf`{oxtldwY>VbxY^&x~Y`f-DY=;(J zY`2zJY>$>xY`<2z*a5A6v4dLEVn?<1#g1u%iXGRc7CWIWDRxrZTD-a^7>TO5O{tUfxTsao!uPW8Pb>Tiyq)N8U%R zZ{FWp|2$+El7|hG;pMcMuu0RBJO{(ZJV(R!JSW4EJQu^IJU7G3JhOr1dl($^Jq_l3 zKZ94kzacU|z!0AwXh_WuGGylm8w&D64W;tK3^nq@4Yl$k3~lox4L$Rt3?uTR4O8-C z4Zq~a8Gg-AFl@?CG;GaJG3?4uH5|!LGn~lJFr3WKG(61DGQ7{vH5dwt83GE58{!H| z8WIai8EO<%Gt?@mV`xxN*YI7zH--)c^$lGM8X1NZG&amAXku7d(A2Q2pqb%FK?}o) zf|iD}1+5Gh3)&j)7j!o~Dd=fLg7$D^}=C>28F{7%?d{t+82&8bSxZW=u!w92}|Lyz#lCIz&9U5 z;VX~PQal_9@Ug)}_`qK(e77%6>JOi091mY*oC_<9E2U!av4{fr21F_N*j8!ya93Ga zg)AqzqRNsFsv^asYElZSE>%D^;KN@v;lp{gq@}2iv>nxhFME6gpUh|gU&3ez--u`g zA0TK9oBlU}t?rw`M)A#IOZOJA=XxvH6ulE{^W7CTorwgPNbRnz~|0M0Di>1SKsq}y@li+C)tQ7wudB9`3JhnAI%qjZSqI$IjB#hX!V&?R(&B=RbNVV z)Yno^^{q5reJ3qYKS+zzPtwooXK6DmXaBBZ^bD5I->VEEO+kU0hVnEAR9Z8lN}3aD zubI$T%>~WW+|X>zg63;hv_$hjziVFTmga*VY5wSq7J&ZN0^tZoafT2$qELN9Eb4Da zKqC#QXsRI%%{6481%^zt-jIWK7;@1;LosyTkdJN}3J`NBM8OWlQH(=Ll;Kbsm31hC zsymcNH61FTMh;a_dxxs1i$gWk%b_}&;7|iib!ZHqSZj@ba`+CdacF}!JG4XF9NMFU z4js@rhmPp7Lnn0Gp$mHD&=sl19>~?$6Zsf>p=e_tly2;csu}yCj>i6|mvJB(W*m&B z8;79z#xd}_3i3i@Q610QgkhZM*8$iZ;|iga9vVjUO5 zx7?PZEXP%-q2sTpo#R^6*Ks`>=C~2fa@>S|a@>rTIc`O#9k-z?j@!{k$DK%W+J!=# z_MlX!eJImuKWgA~5VdzYin=%*NBx{mqOne=&>W}J=x3+1Xr0qJbkONf^oP?0bl&MA zy6JQYy>hyYkn>gK=zI;iI{$^-oo}FI=bI?a`7X+JzK6;>-$$_ihMG7(LhYO%qh8KW zP=DuFXuk7nw88l;+VA`h9dUk-E;@fi@16ffpPfG;XLxAhZ$dcJL~yo=;(U{gYnxQu z)Z~DBn2dP1$q`R8IpY~76JBg`!^=%(yxHV|51PF2DU&z8YVyGkOuqPy$sZG!0Bm&$ z#8EE6aD?DmE@8O7OE~V}5{ZYn#K4h&Z@VPnr!L9(qe}`_UE!l9uIV_yH3KKRX5!MW zIdJ6SS+03_o@+i{<64OKyOxBbERJ+5hZEe&<21KQINPlOE^upv%esAwE4ekrwcMKF z=5Eb#U$+)`xLYec#jQ17?$!>kcWaM#yLG~s-8$pzZe8#@x32iJTQ|(i-LbQ|2ez1d zVsCRVoN4Zj^UQs4NpoLZ-rNt@H225fm;zqf3`X6sh$Z{3cgtUGY3btlfZ?!u+4M{xz~aa_ZC3fHxs z#tp4!a69W+Jji+ukFcJ{`@>tFb(^*UDEZ(x)A zP3-M{8)vxR$GPs0ad-EpxR3iYJlOp?9`F7F&vbu@=efVa%iZ7L?e1^!ZufWin)`cv z!~Fw(=>8GEa{q+ixPQj)+~GU09)x&!D5ScFM(TJNND~hS($2$3dU!aJfgVm|tcQur z^Kc;xJzU8y4>z*c!%U8NSjbrqD>?7sK`wZBlGh$STXD)H{Dn?9R`NZ9;fcSb9l3=gmB+{z{$@MBl%6gS1jlIf{ z7G7mZYp?R8qgMse-K!$$>s5(N^r}L>_o_h9U)ne~@$OCPdG{sFy!(?j-UCQC??GgM_YgANdnlRcJ%Y^k9z|Aok0G19$CAU| ziG=!0CN4fxNU+aTlIk;!Wcth?^?hcM);_aIAD=m7oX_`UlFvM{&SyT^ z?DHcz=(B*F^jSzQ`Ya;Pd|*A;XEFKcvxHFJrNrR7j5z!LOniNplNjF>B*}Lj$?)Ak z3Vk<`3clM&Ro@+?mhUdoz;`!k>ARP7^4(8*`u!g?84Kl{>CYj}Tn=JQ(9~=7JBUk($5a$1o zMEXA_$^K7CasOweoc{~b!T%MR;QyNZ=>LYS^?yrt`M)Qp{6CNj{-1~(@R`I0NVIAI zrr!j>%P0Yib`DVJi~x;p3^34x0S@$HfRWw{aH1aqoGA`;p>ct3v}T~0_6l^TLjpbM zs6bCTA<&yH3iP4N0)6SKKtH-KFn}Hk45a4+gXo>WMEWo=mA(v2r*8r?>8HRfN`m0K zfkDNnLr@-d2`Z%SLB(lUPzjn9RFW11m7=wR%FsqZWogr(^0Z}81==>KA{`P`iH;1a zOveRPp)-Q2(z!v^=ubh_;WK{?=>DLF^l(sPdMv03Js0#Xy&Tk(-V16@9|yIhZ-ZJ< z7TlUT2Y*LBg4@#g;C3`6xD(9`?o6u$ccnvvyU|g>-Rb<`p7iJ7UUXG(Z@MA458WEv zm+lJgM-K$|r^kW^(UZZ0>HXlL)GuTh4GtMjvqMJGk|CpLxscJcYRDK`J7g@aA2N$bS3Q@x{8hp{gqA(T|=jZuBCHBf1`^+H`67dTj(#LTj|=+ZFE!U zc6uaq2R#+Klb#9PP0xq!p;top(wm|C=-bf!@Oi@n^i$|TO2Q6NE$lFL4*P=!haI7j zVMl3n*l`*cc7mpaoupY|r)Z_H)3i$1Sz0~p9IYF6o;C{mlQs{#Ks$t8q}{?U(H>z} zXz#GAbYR#uIy~$zIx*}vog8+TP7Aw7=Y-v-E5aVoHDOQby0DjYN7yU6C+syn81|Ol z342GMg~6BY!ah+N{x@|BH!;_6H|7~`VZPxWEGFEOWrX{%^5MR$O1M9(6&}Fag$J@u z;X$l>crfc59?AxVhp{o?;cQ}fB%2%_#eNQtW-G&E*xK+|wkbTGZ4Xai2f~xsk?<6D zCOnm02v1|T!_(P=@G|UacsceqygV~TRA2!Sl~{?0%B*Ze6;>yrD(e_gjrEGC&L&0F zV6!9YvUw5p*n)`0Y)M2Dwl?BhwlSg^+ZNHB?T%={4n(wMha+0EBN6S`@rd^9Y(xk4 zIHDta5z&dgiRjEeMRZ|KkzJW zV!a~=v;L7o*wDyfY;@#sHZ^htn-w{V&50bt=0}cWizCOgWswuuuE>dOU*sfqIC3(( z6gh=mi=4`CM^0yVBWJM(k+a#;$nP1B`hh7?^O$4QeC8IlfO$kMWPVYLSWwhYEFx+# z%ZysWa-){A;!(?3g{bAMTGR?wGwK)CE@~y~6t#-=h+54?M*YghMy+9!qt>yhQ5)He zsNdN4QJdMys4Z-5)Hb#$YCGEzwUh0Q+Qkk2lI(O!UCg@vasl5EH3&4ONc(n3Zu`k($NiAh3NCFX7mMCFZv?;Hu@6#F8VU- z8GVNhkABF;Mn7V!qMxu|qo1-3(a+ev=;!QE^b7V^^h@?4`W5>W{hHyJH%y6n%ZxFf znJEUzZZTN)iP2=g7za5p#wdryILa|GPI6+5o17eDk+Wmm<@^{Axpa(|TrS2(t{mel z*NE|x>&5uXjbj4jHZehR_m~iQKuoASJSJQo7ZV}RjERIJTHYHICtr+-mv6-+$WLOD z-O#g>(?#8!}R##WT?$HMw_Y-Ra#Y!%rluBvQ~t1bt})qtapTs5w)+&HeD z+$FBQJUp&}yf&_(yg9Csyf^M!S&nZeYw^uxQ+!L=J-)RZ6#tzZ8Q(_Eh;J+B#kZ5I z#kZI1#&?w4#&?3Fn>;(dySyyEhrBhumwYU~xBM}_k4zH!%8m&G<;n?zNy`E=rb`9k6W`Fi4E`Dx-G^83W2GDNk zuJR`38^tBHzT%zQKuJk$tfZwjQOc*bQaY!$R(hs>r;JGLpe#=9r2LZFSy_|XMcJ6z zRrw>en{qQ1)}vE62Nb9duOdF^)PaCAPP8+PWOBv=Pn)E$^yzTSRH~-WR=!K0qjX6BUg?rPSLu;HPwAij zqcSpmfig3Fp|Uc4k+MDgC*^4RV&zo&66JjQGUamma^-dU3gu(^FAB<7saP{sDZUxM zD#00Rl=O_XO0kS}O0|qlO5KdjN~?@5O81Pd%FvAM%A|}P%Cd}|%DRl*%F&Fy%GHd0 z%8iV}%H513%9D(v%Dapcikx{;amYNSm@>~O{+VZ$kj!&RWafD#F7r<~E-1N~7nQ=y z%SzqMD@xPMt4h1f$4ZyXmr9?^SIWT5*UE&WEnU|1I#A*D+bU~OnFtO>zN34B&GU#txsl8VEJKuf^- zP)Yd4dKq|Qtt`BiRu0}gD=(Q)1<4)OiTqGiDH_&_(qNsaII0WlMGd5HU|r}tSQqM! z8pF{{+Jc(H(Gu2+zJqU^wuLW^wu3K#c7$(rc7`u+c7bnXc7;z(c7u;O_JB_+_Jj{4 z_J+?L_JQvR_Jy^i{_sJ-f$(|1LGU5I!SFr1A@IexVes9y;qVo8mQSh;{G17HB z9zHfU2|nI68NOXLRSG22;G0o1;44uxr2;Zbsz+wS`qKB(x8w)->is-vJee;|Aq%8w zWQjDJER}vFKTE%n<!+$1Y1L?244ju1RItb*T!wDOG28 zq~`3d)RsMvy0AymF!orQ!=6Y#vZvB&_DtHqo=ZF7Rr^!y4XkIql`g~A>2Ja7l5b$C z2tF`|h)j{A%uui_qZnC5X|e|Iry1bgGzU~sHljMR6B-~pqv5g%jgei@B-s_sm(6Ic z?1?tW-e{ZbgZ_|x(Mj14otOR5Z8-ovkYOE34u;n*Ll9F!k&hCF0+m=4uEe8MB>|OC z5>YuN3EovpMh%q|)Kp1D-Ia9IQ^`R6luR^D$wIT0Y_v$pLCcf^v|K5UHYp|G{k4+l zh*AojR7#^;N?CMADTf{^Je)oLhAt&U>U8Yo+>iSpH2sFYe8 zl~)^}rfMV9LT!xNs7=sd^;Jic8781whKZ=PVKVAvn2H7)romde4Lx(%j<9hDV#Zy_*SH%c z826x3#(k)vaX;#0{2h%j9!9f`N6S>c!RSU-cPgOi_TVj+1VXG zb@srr$rJm*I#;~O4=0%da2-<+Zf6R{T}&Z(s3{cBG=<^Wrf~d=DFW{?MdFL5Sp3kG zf}fi*@q1Gi{%p#_&Mx`5z@-3}b}5d_x|G0uTuS3XE@kmFmvVTvOL;ucr4nA?QUz~z zsfu^H)WC;aYT-vNwebs=dKkIZ#~!W?u%ByV9OBv(mvwD{YrD3@ja^&emaeUFJJ&Y2 zgKJyd)3qHQ;MxHXbM1sjxOTN3C%R3*Gu|9}(Cb8$8EJY3g2A2&5Ggf+6C@J#b!Jm0(o|72c{*P4I98_X;5 zPV*{!$h;aKGyjH9m^b6|=B@aFc^m#<-i{qCJFvH9Cmg$Rv}F&@wj77`vD3J;AY_>$#s{Feoh8x~CNStxm8VdSkvAs;LnyjNx*ZdN04w>lCZs}me9 zB-H8(@0Yoe7^|5iTHQ&q)q`YOy-1$bmz1#jlk(O8Qr{Xx8e4-&b8843;iQ8#f^@M) zlJ3?h(#IN0`dQ=15NiS%Wlbg%tf^$WHH|E>W{~C9OtRXV^?z}6j?s~&T^l}+&xtCj zN>Z*Q<)jc>ZQHhO+qP|YPusR_+qV1L-}__FT0K*%e(tH~>g&EYOfK0OnMd|U=92@F z1<29J!sK{l5pp)N7`Yr-lH83fMP5giCLbcplCP2F2+@`&!P*KWQd^Ojw3SG#wlYc9 zRv|gsYNU|1Iw`KLLCR>GlRDZqq=~jI>8x!>dT85|G1?Afinb$}tL;P7tuJM(ZY$@w!Q5y>2quteZlP>!y;6y4mEGZVq{* zn@e8n=9AyLg#_srkwE=o60KiC()CM8wtg8Ysb5Z7=~s|;`jupmeia#`Ur(m$H;}pd zjbxdAGufoyO1A5_k%Ri}L{6s9qFC^3W6&T$QQqcI5lr#P!HH^PWUE?3%bAL$( z<3C_@676L~w7*fNLyQ4*xG|7UFb2_SMh%@|jG%Ljdb-$Xp#K?-bd%9Uw;0WIr_n<9 z8e`~Tqm`aD+UO;tojx!+=u@MUzB0P#d!w6vF{aY*#w_~Jm`x3)TxvGuQ=6#}OktX2 zDn?UH#bHX&hNhC>yOp9{O{M8bQyDtWRF*C^l>@h}Jl$ccNcWm5(Nm_X^opq(y=AIS z@0n`Q$EKR}t*I9MY^p=Qn(ESDrY2M}x1qAREw!23Q>VEDOeb2&+?lpDccmT7-Dwwd z58B<_llC9!MBSwOqi)etQMc)xs5|ss)IEx#AHzJQWuu?bO3^Q9&FGi3Y4j`FD*82T7ySmf z;XB$T`aSI#{gDoime{ap%*I6vHaS{mGolqXFFJrNi4J0`qJ!DtXcapa9m-Bchp{Ws z8umCkoV|#SVBe!7Sx}6Yg~jMuc#N4v#>6mdjGbl1I9Ohci`9s6vwAU!tXWJFYZa5s zy2PZg!7-_9L`)i+9+S!D#ALCBG1+WKOb$B~lgnRi1=#19f{a)TF`czAvsjCO z6IYzsttD8FwG=C6EzL?>%dxW73aq@f602sd%xYV!u!h!ZteLesYh$g!x>;+oKGs^` z$~9yotc}@dYZErf+Kf%HHfJ-fE!cc(OSZ(?3f#HY?2NS&J7?{}E?T>?Yu0Y;j1^Ye+cuv0Z4+3EZ8A%8zk_1}kox&C1&5uu8VMtd4CSYh|0y+S?YgF1AH%plvZ5ZCk>o*p{+cwq!o?1^nBduH3s-rDvsYTwHg`#u(EKgd+}LoC96 zm>KOyS&aP{^VpBGO#2CzXFtgb+fT6)_KU2n{W7ayzrw28ud>?qYpj9&25V%$%Uav- zvGMjtY^MD&TV{XCR@$GjZT1&zkNp+QYj)cHj-9i=XP4|B*%$jK_S^oM5yux6;rPmo zj&Cf+@trvxKbXhyiX3*lNSWV%vhF*N*#RyYR%=t~@KYJGgm0dGpxbFn#%x*na$F>;V2db|BZr z4dO|0LwKjSp?pBx2tFuoBp(_#ijR&P&1c1p;S1u%@=bB$_>Q>o{B+y|elcz$zZN%% z-;A5apT^DL@8V|iuW_?E^UUS4XCV*uEaFzr5}x8&#tV8@z^vl?JgfO(&su)fvyMOU z{Kr3gHt-bhMqbFfg%|a1h1t$qdUx>w-ranZcMqT9-N)y7_w%*h1AMpl5I^NT!q0k- z@=M<1z|c;>oaB=46gT)z^C;h09^*R){Okhovx_j7cq89sU}jhOVBZZs)_0Rn_TA!( ze7E@u-yOcqcNh5CJ$~BvfS>a{?)OuX;^!j6FN=J?B1-!MM0tOpsO%3CHT)r>j$b7j`n95oUoV>b4WgUh zBqsUIV!A(C%<;#FRsLkL#-A=W`*Xw&f1cRm&liXMMZ^hzF>%9RLOk)86d(Mh#V>yu z5foounByx5YkWnK7+*;gjjt@q#a9v4@zq7M_!^>Td`&SXzLr=NUtesGZy=7u zHxw7+8;g7KO~kYKX5a!g7n+0?!j#ZTI1*Y5e?l9Pk#I=Os0ws77Y%xA@j+l`+S1d}LCsrrU2S;#$*qgXeJWE_8 zJ|r#{#-t^}k+f9AB`p)lNvpsITrCPFtr6vt){44G>qN_>|3ufM4Pr~uCh;t3tN5C< zUAU8Xi1g&0A|rXX$W7iW@{{+AuE__0r5zN*laGio$;W}Iofk`zFNl@N7lEl=5|@&1 zh+D}w#r@=4;z#mr5s-36gr?jT`jmUZlJZoP&o=a*Bcd@F^?_fxq1Fh!OhrzrBPltB4gN|5|F zB}5KL4VA-E!(?-+TDGT#%g)qD*_W!7GgA$6fmEYhKGiJONVUjyQ={bOsWEc-`sLZF@$#b7M0rJOvb;7mMZTAsDnCh0lV7H0$RAQO|Bt*QJyt(h#+TgXa!OIe-XO17o9latar z%0<#U$z{^J$Q9GO%Hz|!%PZ4+$OqDU$=}lZ%0JWl$v9(xEHVblB{K$t4>&{~lrdc1 zo-sn+lc9k$s16dDCLmiDU|Z2(HCcgL*`;jwQ$9FP#UL?R2G|x*D5;9%ld3^_vKg?g z|975RLyEE;aIG%jJoS)rq(0z14FtwDTq+C3Vf>)@U1Gqw3^_)Qghs2Y6&c>4IU!(2A(wn50}OO&zcB4 zYdY|(OL&ZQ1CIr+HC}p-CrEGb6gXZ#4eq;7hvVuqqy*qug~@EG7ci}Xz_dn_dD2ec zTIYdjg@6mCrb{F(_)sSBp}cghluS2Bxxli@(k)VTx=pGB9IG+iDK!U<)sF55m+GL@ zlOB^s0=F6i%xWC)s)_WhG#!}LY~WS%fmba7UbPBX)m>m!kLfkwRyU+iz^i`IyOPB2 zOB(h-vI4701y)spJ(2per{GvUlO_PO+Qwc;N7-vAM0f)U__xqw@DAz;-a~@_qh#RU zBs2d7aq2%1Vg3iPVT8&6uc{2ZsyeW$dcde!1D|ROOsX$1sR6*G25~JK%5`W8u&IT> zrj`PmS_N!sJ#eYVz@=USm-+-;>Ib(YB;1ILI20v3kfrpZg2Iog0G}ESd} zjsu^%16)ccXCRZD30x@)xKcJslk-rnTnt!J3Diz5h57-1ng;x7qg);xmusNQavk(g zu7_R$Yx)4J=^JpSKfsu{(i8W0x)QV!eGFQM0)p2gYw$*t4sKM5;LWHs_)(36x1zqm+tE1iqt*li zR{}@sHTY3MA^U*q>_?@*jcOEf3=IP}YF@}mv^(S!x*2jBeGNH-!c=FGMs*H(R2NXT z>MAOxx{g|@ZleCGTWEsnHkz!ugVul_wGaHL+u%q2R6Rt7&}S$$^aZLJ`U-UneT~M2 zzCo))-=gE8@6e;r_vlIJ2lO}e6AB6Yj`U$aQEu38R4MEaY8>_#H4FQP`h_7pDGcNF zVFaHIqxfZ*f|)uL2dX1*q*{x!)jC{OZNT-_M%+|w0v2P&oz)iHTOEamsiW~Ybqx4S zcDzvSz{k}td{XVkSJiR&y4r*9s1xu*bs~PMPR1|QDfk`uP@lnp`mQdBB~2k5p(%!S znv&QI?voANr+7^noT(`b-cxy8Q&R!g*Hi>nQwev~RK`O!Rq<3!4g8;`Cf=;6hj)M< zbxP9^+^0tPH8@hgz>x|GZ;G|y&9EuFIgSr+feVGV1mCF@t`Ob^xJ_H!BfK3R72Y0C z2=9OwhIa(7sS`dJ-WgvC?}FcgGxZsqDJ7x@4vpxE4H3O@D$h##bZ8!Hmb6$O+gGIT70Dx9hP54@xGc(`^e9;@Ajr)qcORoa7it@be9s6B$W zYLDUr+GF^n_Bg(wJ&B)dPl1DU8vLU(Skj%vD&2W((Otk!-4*QDUBiWR*KtMN4ctU` z3wPJu#+!9_@Gjk5d_?yEhwC3=z5XSR(tpBE{TG~|{|fURPt^a!3-!P7YW;7#QU4cj z)&GN$$PYasAqGk!44mi<0!Aiv41uJhA&B%agn%EUf(Zp5NJB0gjO2zPnmjN#$SZ@B z{580V+89TyMh}TK`iRfyCv}YRq@^*5^fe}vA;wfP!k9+38PmyOV-~q?%qI7Yx#W>C zkEl)gB+68XB%2D8Y*P`EZz@KLno5xJrV6C0sS>Gcs!Up&s*+x&>STziCK+a`O=g+u zl7*)FWTUA8*=}k?cA1)xJ*H;lu&D*PZfZ#$np%@5rncmnsU3N1>Oio$BMCBh0q>_P z(U^M>m$@gj==3JZ=02pLxi2YZ?ng?Q2axLKL8O6s2x(*FwQMGdmMtX9 zvXvCJY$IhY+evlH4${!FleD(%B3&(eNiWMjGTgGCEU+9POD%`VHp>yR$8wY$wHzbo zEhoua%PI23a+>_LoFjoz=Sf)91)`0*NZe6ZNSUasq;k{^QX}dnsT*~lbclLDdPY4Y zQ==Y}4N*_X)~KiCNYqPmJn9uW9rcD>hLd9S^_lzt=ZHjqBN5R*h%x#n zaYX+i>EIa^h(^E<2=D_+Yk+GsD4Np|(SmM_mg)BB0QxmLnEr?kp?{-8DTz^26}Uzb z;2L>iB4}bvBrOBZQ6+GW+JbM?0equw;2SLf-)LD(6g>~l(bX6y)mh!tVvVJ4s|S1{ zA1z?@(^A$1TF0718(EXVB}%9LtQp`FWr0tWO~+Yt=oV`(-330PipT%i`l!<3ij@_ zk-aBvVedsd+56HV_5pOPeIT7=A55p)htRq9q4cnQ7(HnpPCtNq^vynsra8vaOvgBy z=a@hXJ0{VRj>)vVV+w8Rm`YnarqN-J>2!=^1~@~r=_)AZ`Ub0)OChVcb%hiUFYd?*8{rS^^hKM zJ)#d>Pv{@lQ;OZMXps9g4Rybv5$<=?=zdQf?vFIx{h8*vztH0DZ?vZS2d(e^Nn5)A z(B5u|4RIqj(oNVjH)V6&j2&@vaB>9u?3US2cK}O|4Q5%fAuK;Olog3pgLk80)ndcJ zxrtyMVel|2N0i2j5Ha9MrEsskFA0~tCjmu((;{N!}rB zhIc62>m9}pdxx`^-VyA*cNFvc#Ke;3=}-_5T2_psaky$r?gVQaD zhVds^^Y~M&WBeI5IQ|?P8GoKlj=#i~#$RTu<8QOg@pssv_`B?Q{C##d{sFrh|B&5^ zf5cwIKW1;^pRiBy&)E0)pNuC!M_0lhrb+n6A`&RKB{1$u;5;!w@Zt$Fua*!1UP~Zv zkr2c?Bn0zG2_bw%f{JfT2;&D5)ciz(hF?es=hqV=`JDtEf0m%QUxBBREay2D)WS- zs^Gm;=LM5$@X|@Oc-5pjyiQVG-Ylsx?~v4lcS~x@`y@5v!;)I?u}LlY^rTjNPf{Cx zHmNOtnADDcO={1Tq)3{7TAP{vc%@|CBPHv(yFLk-Cs4q%PtOQy23-sZ05Y z)Mb2Z>T*6kbp>CTx{|L>UB$PguI4*Z*YJI*>-mY)4g7iPM*cN*6aSOCnTxb7JS=S+ zH>d63zO(JIYD= zF&>fnwwRDrOialtEoNnv5%aUkigj7##KElc;%HU{aWbo-xSUl< zyvnK~{$^Db!P(V>HM@pzW!Dtm>{=o*ySYfsZYOfHJBU)*T||}aZlY#(cTqpPr)Zkp zOLWQZEkwWyHyMpVsvCu-%r7xnW# zh}L;QkoyV+|3?kxj|PZHIM_XrKs#)}M;t&joZ$Spr1p>rYY+5f5coe+;1kP$lWYf0 zauPmu8+gcl;2|%7hkOMdBB7#^1{Ig|sD$K3B_%L8q09>RNrS}6gs|ueFOpfhy?cG1Xsro+@mHqI!(dR=>(3>WcEo~ z%)Usg*>CAF`vY~47~C9!;Abd`13xDPm`5fzpnPB%C4gg80*+CWJ78i_W9~y8c>+ud z>djNp7@md3^BlC8=c5039@@o=pd-8}y3C8A8@xDr&r2c#?u-oXOt2`6LPa?gE-D~{ zsE910GKv>fP>QGt-BR^X83CS*XoSXyCTN~$infSmXpd-)UWgV5fg=+pw?c8?$z;lH zP(g5IYJe-#KyHs($sJHvxg#1NcS57(&S7Z7fiqJIoSACM0Mtks2-&qksGBkvja7!Asmf5aOBn`k&2aQc8G(K)BT*oD zG@5|1$Qm#aIl!ZFfIpKFFdb$FS_K}>-hf%?5V$lK!KJwdF3qigdFVU%G$L>zas@6z znSqN@g}|k#M&L5k27HQe*eg|$thM?WZ9<&GLf;&?_ zXg_KQ?o4ZNXL{*7J)|AE2K1;z025RR9I2)rRA6gr^7paV*S4}?VEvmufAN{9|iDm^AD z1Li6tR#X-oq>92Js%RXliot4?6^E;AI8tTDI+X((R4!~%xv@nRi=$O>*sAhCSCkh! zRX*%i`Ei^o5qnih*sn^)391yFq)Nppsx+LYO2-+h44kFP0zW4k=c#gV0aY$8q{_oZ zRQb>^RREVz6~v`fMQ|BaQCv<{47#R@<4UR$xQePIuBIx5Yp6=&TB@?Rj;b84rz#JA zPX*jaRS`E)Rl?0wm2nGI72HZy9lEJ%fcH}qyq{XQld3lEqN;HO;{-WxOQD{H-pXLDQvl@goq2Snr4#9b$!*IdS;kZHQ2;4e!B<>X28}|&IfER{N z#LGh`;|-xx@UGBlcz@`0d@gh;z7o0|-w9odABL{OFGJVk_n{jgW48%hqOF*PZO59h z9atZ>8=J!pV1L*_oDy~jXM`QbrNWNlGGWJXrLg0WzdMUtgq_3P!!F>yVHfelu*={X zUBR2fuHjQ*H}ILTyZBz%J^VWCKK>H+6bGrFV~zR+)~a7(v-%bGs9)n;^*fxeevhlE zKj7NxkHEM-;a2J|;2V9zozy>YPxVhcQT+=~Q~$;b)PL|&^b7dd}HAYfK z6HTgXVxZ&7M!IV3q_-xPOwf49OpTW;(D=wwO)_*_rIG`hG;&#!PVQ(jpwB9cJk#Wm zx0+mn!t+Q#cs>aWFG#|}3ln2_5#kRoN;1QXkpkf*Na65Oq*QomQa8K|X%SwQv=1*& zI)zsxJ;N)J@!^%pwD78AMtF5HKfDIn5MGmP53fyjhSwzr!t0UC;q}SA@CM{*cq8&W zya{<1-jv{oW+XVGH3^SsOUx1Nh&7@M$%yDi3PkiG#UlEUS`mFohlu`USi}IbAYu?% zA2F2djTlA_M+_&&B1Vui5hKa@h%w}1#8`4YVjOf}jfW1bNzj2cg?x;d3ck_|!XsxA zbL4Ci6*-5bMb0A`kqb$&$VK2HEhdd3my#xt%b@#eB^eO8noN#dL*_(oB#R<9lU0%1 z$(G2Sb@l=cwuX%B-(bcCd7kAh2djO1%il7iY(;1iuDrL<>A z1?_oKS$mPx&|W9av^PjM?M*UFdy7oa-X>GEcfcpQ4=&LIaz^_Q9HPhMiuMV4qkT#~ zX`hoX+Bf8<_8kNP-;;3N2XKf!k~H0CQe5|qRMUMY)pb807x;^`(EWjIAUHI-f26Zc zqP=y54uJcN<8+)()5&y>E)Y7fg6Mo*FkPur(e=78dPoOdUOElErVFR{bXxjYr>7rv z2KrMMMJ0U<4b$7GL2su~dJlEz6RA(1M3eOC(227@mx>sM39@AH$=k!(SRed#jM_+?J(buFO z^tI_v=-rYGjVUuUfo`p))M#i%U54h+vDJbm8d}n9=-ny+om*uL?P)DT2iggGx4J;z z))eU1IspAzM-2n$73kKw3%y!Tp;zmTVHo`ky;{EwBcWSsGz~M3p<3wGGD4?T3Uq0u zL6=rO^k@|~PN(IdORFmMXw@~&rY)gMs}po-^?)v|KE_3Ks&NUOYg|e<7?;s)#+CGl zaTPshTum<<*ML{F4*ItKqrZ*oDKc#Yr)V>^nzqn1(^gu{w2f9UZKrKaJD@XbCmmwi z1uoHUI@z?3o`g=WbI`4I$Mk?cfnKeTrl*vfUs1*Unns%6P?Px`jWU0ve)DIVYW@QA zo#vT;(E{c_w7B^%3}zL~lvOt~7!KW8GHVHaTCJf^tCu;L^@mQa$z~OsWe#Nv&0%bh zSn`(pOT0Ca9Og1)V0QRP@$=-lc7om=Cfb8ALaCAJuPxAsHl))DC1`Wsc3k?4BRo7D(< zvzoG)=;q89-I66nw_!u(j61Y@_uE+iN`v{a7d1Nh>tiTTik3*3;~X^(=d7JqM1@W%kv2mHn|^W5RZW zh1qU_+jE;)ZFia1cAq8N94thVh1Yh-)L+Sp#RZnn3quk9ThZu`I{ z+CH%vw$E&l?JHYj`^Gleey}~Z-|VdI54&jl%kJ3zv5(Nn^%Xj~ke%~LyWoj-g{RvC zc#b`g7qkcQV)kHO#U8?I+Eu)sJ(M@Lhw&D6HE#>uTpjHu-o>jgy`u!TLid*4QHi@8m3gA00Z)b=u53p$UewW?S9i4KogM9XPe*%jdOGkC zj*j5;bmp@iU0}NMRgT_#t)ma$=;+V4IR@~3j)DA$V-P>(7|bs?hVW~Sq5O_x81#IN z;BOowIdhJJ8NGkbEk6x_c|x?Bm;9_Rf`jtaBCL>s$>E&>DWzxt5!tpUdLfz{|Tf@)oX5ytQi!Z|mB{JG=Jqp00ho zzv}=vKL=q>@CmMy;QpNAb6ltSV%HhI#C4W0cb(%aUFZ24*9E@LbrF1^OMIj2GT-95 z!ne7u^6jo`e6Q;|_(3=L3D-k@+VzNEay^EAuowKj>lLT&*BqEAH@QD?r~5O{cYom} z++TSm_cz|e{hhaW|KQ!+zxWLIZ$97shc9ve<7?fL*yXMMZ~?hqT*p( zG4Uj>xOg5{LcEGADc;7F5+CBqh>vmQ#Fx18;%i(5@jb4h_!(D8{En*(9bZ+1S-_14ih9?GV&1i)q<5Vt?fp-b^R5>aycVxMOWVw(aZN< z4Dfvs!+l@H9N#yw+V?~3@%}l@$wU1bd7(dCKI4y+pZm4)Tfag6+kIP0ozB z%N64ta_xAh+%!H`?h@~jyT$wDKJm%&u=rGYY&w=}2694TBe_sw6S-w#Q+aG+b9s7VOL=)>Yx!7W8~H|JTlrODJNZXq z2RSgQlbn>)S+17URc?^fLvE7PPi~VmNbZ+3SRR)&6gtg@$?K9v%X^c?$aj+_%FmM~ z%WsmV$WroDS(iLbE}lGHu9iGQ?vgxH9*{goo{~IIo|!yfUX#2)KAOBx{*t^%W+{th zTgnnSK4rOFIAw)gE@c(;lx>oGr)-uNq->QprtFlrrRa@G^?zDU03q1f==%M^7?U5Xj{zSHO)UhlT4q|GBZW#n3)NkV%bXH%p7HSW+7#4W)WpkW>IBBW-(=d zW^v_QW=Z94W+~-yW*OyWW;x}3W(DPIW@R`!QAJT_)l!^UwG~fR9VIKPu2L?mo>D2R zzEUl#fl@E45%iBWR@!DYQHEqSQ)Xo~S5{`VQ1)lFQqEYW3!c)*>jY)*>jbT z+4G=pY`*d{d!h0#dj*8TRw_Jal@gS*MhVSXs~B?DDbYFqDbAb?iYI5Yl901c$;~;a z6v;WIRLeQ7G|V}pw8=TAbk8}jjLx~B%+I-`Y|6Q;oXEMVoX@$gyv(_we9pP41n1sS zRJnJdi|nCNI`^?sDfg+;Cij`rE%&)HKKGR}G558yEcd-~CikOqIrp>jHusD2J@=~; zmiI%^Avh$4r1@dD8isoAb%ICWRYUaBG z8s^6Zw9oehbjkMy^vq8T7@eOKFf~6VV19mDz}Ecqfc^Oy0Vned1f0z;6mTKGNWj(n zVgYyZiw8W+FB$MG-wW3T{8HHe2yC)s22(9wN(Tci3#_voaMN<7I>1{S0dH*yytNJF zD@Oxw9V-=u>}4@&fmB>tE0vJ`lS)dvrBc#qpttA2Zo4X#2S=?U@YyPG380!pfw=~Q zdlrN0NQJ;XD+zha3cz5iqlQu))JSTM8bkiFiPRA_m3p9N(g0wxLxIUoK&_<7sI@c` z*zA1NR$2pmb`$C#Z9^TUov5pH0CfX?+g&<~dP!Qb3EL)> z1AbeD90up@gfxhpl17lz(sXiGT0+iA%gIG)6}coq%0${vu1W{V4Pd=Dr7Pr?^orb( z{*t>AqxYmh`alY$&!hE)z(2Y=SGV6=&ap>0f!PB9I-#KO^M7KsADQ40k} zEfV}RANXm>;HPClcCrX?-DcpZwdYpU6WDG)aMT6?-yOmIXdF*M(|9tP18jEzPeY4% zI$Fjv(F@?bZ-MiE1J3&k*zP}G3JFmLg#gnH1D+cWJl7^Fp>$xnMSUK4c><~@Peh&M$!Lf?1&x%ap$YPIG)10)X34YB8hH-* zadRPOIS;*%=c9M>0`x^*i2lio5mT1HX^*u?rEEZ2WfO{3wtySA6?pItl&0*0yyb3G zMcD&9crUQv{b+=85c|A0QTpTLQKqbh-aQJuhlsBNHxI|X7Gh7SkI_-LSlUj_!?w}C;}9u$mY zgF+>2RSSBQ6$X!li=Da6=#pw+pi4Zb2>>H{KW&hj#~g;EsS7Ukmc#M?vxU zV^9Lz5lF@X!KqjkoQ4yFGjN;W9Na!Q7xxa%!-Ikg;8DQ^@xtIjcv)}}m||EPQWEP! zO2G|*vbb7EdE7LlB5oB@3AYQWjQfOC!J|T|;u#^;@UoD4z=#{+-62hY5jVvrLYl*U zfEM_9NK5=OqznEO(iPZnH*8dOhx-6M;5I-n;IzGQLscK#6S(MX)c`zCH4rkEgWwLp z2z*^N5;B&fA!9ine^X7sA;3Z-frBOk2Q3O5v{+~>Tq<-fZW_7}_Xu5t2Zb(%KC-3I zLADaF3tfe`hpxu^Lf7D=s@EOmsCc(e+^uA&dD4pALJB zFNHn9H^ZI-FMWw0hrPm2!d^p{*&F;k>@9v3_71X|@1fW11O5>95i*;ffTw=OU&FrQ zZ(-k{>r5gF@J@|d1-Ae~Nt8N_B&yYL3qS)m0K!RGbp)xej)WTkTGCCeBfZsnxB*}w zlhj7CL~SA~)n>9wZ6W*BQRJdJnp{)IkQZt@`J{FbtZ@>Z#zkBjH;Dr_8n1~1Zt5Y$ zfREMyK3Z4fC+#)yq>Cnj4AUf%(V8SO7ntcHO$ylz+;j(U(^J4r&jUAosL2Fwnnk{A zvdJIdry=3FL<9WP4*WDWya34phMFH&k0 zQNTiH0t=lR-kcl{Z$Zw4w}NRyLV<}!0u!}Gv?s9<9Y}mcN4OEtmE=TpCxs$a1)gvd7 z#*xz@dpQGgm$QI<&Ia~5mrMjUIz4he@XrNg88Fhdkt@jd$W>$?aM6>%MK47DN3H`K zeFJRtedHFHZKQ~HJMhjOq^5Q!X{p^s+G%%_!P-4!gmy0(r`<;;YY&iV+Ji8M$s^#U zFMyYR2VN@cj+0>B31ZcqBre@4;?tcWNxE|+Rd<18=`KOv*=5pKcZCerT_qEB*T@3h zb+S}3)XT=x|6lF!Ho-8=FRn5nG)Otkth z#Hjy9is`?T+WH@)gZ>ZcqW?$w>Y>q6kAPD$dRHGvAL)bWH+?YWh7hVYXsE>yP926w z8f(zfB!iw7HW+A0gOQdqm}m`ynbtShX4!V=gUi%!4TaImd!@p0N;JYb;Fn7>hv9 ze^GkPSd88_7N-x5CFwI`Y5LMwmcBEVr(RP9$S+o;8IVgXW~vNb{#BsIzbb7D`NU3; zPwWA?#9@$2909q+DW>{#x~TzOU}^-J#wO6&-<0k&H3J^m9C&04$T7C2FHCJ9%Lr$; zO+6?x_oCtE-c)DqOAA9rv4*)nv7T_K~`2QrGoE&tJR zkWHKlxx}fK?evyqC%tRgLqA#e(XW>MFb8R=s6&udJWT6H9ii=`j?yks$LPqY<8)lq z3CJp*q%)&V(>YORV9wDOQRg9}c!B42NER!D_}RFoBRk3}TC7g4usDA#6*GitUOC zg)Cw?J026s&O)~FO^l8OTOr?QH87*q2<*`e*+UC-^2e~LRvVjZwX;=L7u#xevt8B{ zcEFkjJ^UH$hBcEtvt~n%FqeI|=0S!qpAlO@rq~Lza9a@;VJpr&wvvz^EXA^HWmpkg zSysVTj@7f3XH9GsSPNT4*3MR$b+uJty=~Rm09y?<(^iWuwAE(IY;_?sSdZN!ua z0nU?bxbqYn<2=n~I?u3q&I@dj6I?Rq6}HNGm92MPXWN`N*ly=dcEWj!ops(}*PVCS z9p^pv(s`eKc0OX*^^^(Ma~A7*$F0zlTrt1@H;QGv(y1uY3u5YZT z>nH2&`ppKo{;;90zif(2;xk>0FLJ4Y^MwQ3i{uAgTIl=N1J5(^2QCwT>@xEgt|5B`@4(sp>VEmES%#T z?=H*dy36tP?h1UXyCUD|uEh7ioxQ_wS?{E~I@|!L&2PKw@K5dr{1;>l)v=AZBepS5 zj%@;c|4n)6*k-&ZVI0Wxx)Ez)A?e^7OsG7 z;ikA*d}rJoz9()TKN~k6@`no`f4Go8j9bKC#4X{k;+FA`am)F)xE1_w+)7R%Z>T`t zFx<0-8zFCK_N?c2$Q#CbHu7Z8CZ6rt%nNw7@X{XWlJe}}wLN=z6VE>0!n2=u^Bmw4 zJO}w=&mq3TbCj?19OoN6C-^qcNq*dOil6nI;paW)_$AMIe%*6{-}PMNk3E<8PtRrk z&vOmRSZ;9Yy~zW-x471Oo149Nd6f4)w|XCNm-iv}c^^TK*khjSeFE9Xcf5%A3oqmS z2K`~*c?<6k-q!mQGLXOcLhm2G%uB^OFB9v%9PS1PvC}Jy{a!^J^#+QQ-XQVW8zMq| z5hB7DDT?}ZqO?yB?9L>r`OKn?&mtE1qQzQYjM(I}ik&{2*yoECM|>V}$>$Z0?U4svGirNa0V zWX*m^a8XUFfPaH$^+#%j|4BVCLVYksV=+OCFhlFHK%23Qj$j4d!hz@o4n}Wq2;B8E zA(_}v5V50B;zaOE6{V3_RDfh4NG~90S4AaAX;d0+{dFK^(NMVcHyrN!jVCqHbW$75 zfjfVz;I`jd(g+=f`+jFgGjy4>Ko3bv^o+DdFGv&gl5{{nNJoTdSEQodPz2ogGt(X@ zj`l?9v==G@H~!$75~@cBp(b=V>PknT{&X4|N@t)EaKCRForPA@m1r$phc?pnXgA$} zj?#^A?{5=2O*f;f^dP!P;T|77f*#VN=rKKpp3>v!1wDaY)01!u@D%z;PovND4Ejpp z?MTm~-}E9v>=L5vGUDtC66`8c*fkW$uA>lk1BJ1hD4g9wT6P=h*&SqLcafPrKr!qQ z^0Fr=fjvjb>;)>oUZNuG72FVfipsJ#s0w?F!23eY*+UQ%nWy~qwoc0$2XY+zhrS(;U28!UYy8% zIFI{rSsst;@-*C%r{j)119#;GaBp4&59USjBwh+H*R&lDKEmw@?y9(xD=O{m%)v}<+z=^2KSfO z;UV%KJW4)@$IFNCJoyM-Bp-!2hHuIz@I(0|rphTSD`#=Eat_BScd=i2gp-vgI8}Lu zGnMDKpz;d0QeNYB$}ikWkw|w1lb#ACec`b1XoZuhiXd~90CH3bBqtR(Mhv;p2-qBP zusIUIiOhxVQRIKw(RkPzi9ptpU=Jk2rbq){GF_?%+0h2DK^g(KYYd-m3R|T4|F~T# z*b`->ez0?f!v+~ERg$K|7MTzGW&?b~M%Xu-q?*v7R!iCfJ7+6wmTmBD+u_^xNDZaE z@QwT68~001qyzA+2O+I`NNOP+hMjZ@_R%$|t8^E3(ObCq`4M)}U#Ty2t@VeVwE@tx zHVAeJ5JNOpDvrhh^BWKO)EQDUG)HQKWu^Ez9y%&LK*yv<=(zM0cF{}NMQ_j<=^Z*NeS=-}3tf`_ zqAQZXSET@aO$x@>rBHlBQsdju-F8>f;`>rGegGWsq2z?!6pJ5A9@tNQ{8UQB&!iOm zTuOsIl>vJy8+KF?*ipqXblu}GzzV-fV6RmoIj9E7MYTvCYCsC079<@FBn9Dq zX$iCl_T38Db^Br09U~Rcb5aSxiPynrqw6q?w(q_m`!I7k`Q32Wpm84xz zS=eipVXxJJz1A4^+DN!pIu`DgPKBMegN{U}=xB5S?v-An6VNlbRr(%omHwbpk%~=2 z8a4y=%uM8Cb6~H`MTOWx*ei=r4YmX|V9QWTwj6fHO0diyH9raGUf3Fv&}( z3%`tdzHYhi=Q(GP5#HDPzwcf5|E=|9)+9UoBsod;&fdv>auP+b zdWy_iD0bFS@q`@lW}_89Hc|0s3zR^%TnS=Zl@Q33Pp>y`<5Q7qPgPGy!*# zCb4d6G8>G0M#tcu(b>3TbcveDR;XEQty-LIR&!Zp+$-7;cZ$A-J4IXIPSJK+KI^Cz zKrWPLJv5vus8wPEw90IlR)vkxs!s z8uk@xz1W{xANEM=%Q)^Nwct+D2;50p(=wdZwv1#AETeFj>1g(n!ux4$A`EZ@Q2jwya=BEi2g> z%PMxkvYK78tYOzIYuTTc&l$C@W2$vM3$bosDb`J_q;)f^WZlAQTDP)R*6nPdbq9OT zx|2<|e!-Smce72_J#3eCFZdtyDu9JUL%6ZIm?vHimG zY`?;;d5zV!{mz=$uCunbKUgQ*pRAkh7VB@j&4$?SviEKG*fiUHHqZ8eEwVjgpW2?V z&umZG1{>vH+8F=VCir(YiJ!A6{8yXGZ`m~d$mYq3-IvRDKW?-8b5DB!53&dHNP7@Z zw1@Bvdnhk%598VP2%c+?lI8`Rn#<-proETiSDZYkMi))?S9cVbA9s>;=5Dy%O(gugtsItMGU1Re3La zHQv`=oe!|r;DhWn`4D?8KFnT+54YFlW9;?#`}X>LqP+p1YR5i9dm}!_{u-ZWf1S^_ zH{pxyP5DRmW_+2wIbUIK!9TUPW!kJ?j7miWf>KM%(jxpTbF_wEe z-sRqoaoo@G9uIJg=RuASc&K9nk8n)nQI5$x)-i=AIHvMs$8?_Rn87m~GkI~xES~L{ z$4fcp^RkWwJm0a9S8y!il^u(DRmVrXx?>5i?f972b*$j^9G~!pj!*e3j+Oj%$12{; zv6{DVtl_O3pYb-1wY;rk9e=~Io_BO?;N2V>c@M`X-p8?-_j7FFgB?5gP{&R_%<%;u z>Da}`ICk@Kjy-(5V=tfJ*vBV1_VX!@1AMCE5TEWi%;z|c@r90W_=k?;e2L>EU*-dFVb6n;39KUhu_B(fXyUqjL{@`(LH+a5VGVasPz%AYB(B7Gt z-{)a|UjXe~0h+iXv~Ok1>8oG{Umf2))F3mUljoA=`2L{<^tG;w+c zhd;?ueha^U-65;_U9z6vBYXLMa)>`5=lCQ1{*_5@K*!yOeq*96^$>Y9T$H1!qJWka z<&YqXDeo%V;G8w5Q!L^P*EMJqa7 zw5B6P8_dbu(s!Zz-oqW<tmF{+ot-yl3DZ?^(FVdp308T+H|9W4^x-^Zmup zhaW*7F2h~k%f&#<QAS zh?oYwIh`KITHvIZgZchkdPdBn=fr%>`xju|zYz2OMVR+5hF<*;bN?muSFxP_CO*de ze+9iEKA|_UcDRkT!#%7W?ql8XNPJG8igj2AtfySsfVIFztOd4E6*|-g9qND%^^kT! zFGGh)d$AU%%|fI`ELwVnrAy6O8>t0*Lu$>sNNreGsU;gEwPQ1-x7cE-BikZ%!W_Oc zyCl8Cu1G!Db*VSA$$eR*+>ce4`?LBobb`E$wUn2$aq`EQx36H+%ippy@+o#s{*GOcPqQE7GwhOlmi;21!`k3H z`%S*UuFDtM4fzLlQ~r_NmVaV*<)7Jo`4W35|H7WiR~b`&WkR{eWaT%eDc6}*`GeV& zKbf2InE5CY4^|W&r#N_?;>OD>p1hXg#p^2WyoKV!hb#EaLIalL(fSSP5)I^@GmgHsB*LX$sb>2j6!dt0L`I~Ap-dSzV-%(rezG_E4Snb4z zsh#;qwF@7kcID&LZhXA@4xga*;1kuJe6re$PgQ&KX=*<{L+#IJsss3Jbs(Rk4(0RI zVSJ%FoG(^K@Q>7ye5pE$FIPwN73vuNsXCUgQs3ok)Ny>R`aa*Fj^~@z5BOGf0^hDq zwcmL&?K*F--QXRy zKly0wCZD0*;`6lI{3Goy|5&@v*J$_n=h{R5o%WcY)1L5)8WWE+N#Lk5k!4XtBa13t zwP>P=#Uff;tfGU(COTQ%#M>5kF~s5_7F#^U5{s8uZt)hYEk0s{#b0c)1c=?1P;tx> zCVsGli$5$8;-)21+_6N9dzKg>S>uFijTbg+g7CH`3qNa`h_I%M7;A<|vu24bYYCBK z%@zgL98uL;TGY0d5lyXS#T(X&;%#ds(c9{Ub(s(LOZYlZulC0oKY>`Ih2VUjaIDiJ zu}+J^8Z8E^wiul6Qyg+W4>G<0R-OuoRlz!~2G(hHu`a6*Y$I5BnnLFHfSqU% zm;_7D9LWA9NVyueqRr3@d$4Xhf?VHW?e-&b{)W}xUD%8$zG<`Kn>HWpuL#5WKJnON zkx5^N4F_5T`z-2WpT+C61!;?Y7F}p7(ucOedaE6I54z$u)@S$V5aPpzVqe5C5`lAl zBC%hhB=$>WW4}ac?2#yoJreoYBT)foRM)^hi8|OP(U#4IK9~y|%{-iUJs&z@0d&Gb zoOiv941vxV4V|%=ts~3XdYpT`foy@^*blvN5PAc*zmsEZJI)H)f$!zMz3K>!Ek+V-?&0E8vDGsS!$Qj9kr-x;f5O>Hy1GN9fQ#Sikl~pZ3FfN&}!r z2V&34AnaKgOiq&__`Yx`zAqe3et=c&5*Z2G*(mh+XmSHu`4;SIcd?3o2%Fjy*wiSU zKscR5Bs!U>bPDJ(6?0k+}>+$Mr`;{fpZKzx}w7(5RCKwtQiVW7ou&|w7VFcQ2y3LHKfr&odXN5&ILv0VU9B&GnxgU#v)i37Q?de zA*>1?VJ5Q#)LDvi-j|bZ+0O4^Gv;`gD1{m6X)Ile^dgGlieY#N6!mpTkyIF3{& z@bo0Gr?7|VJMhG5*fze0e+Fl5oh27x<@kx5$9(G|`4yb;J4WISU~b_Qt~=n62f#ii z*T4_I!?t=Iyl?}&a1(rR3w&@Jd~gT$*1O+VNi~{FEwl`^(tK*C6{v$&rf#$vb*I=#Lu*rCTA%vSM%16aMgwV6 z8bn*7#5OdHzKK#h&8;zmeX)Jw*#?ziOf%c+_v^UM5eeuSD zG>Zg6n8b!bF>+~K%3K_(3(rM6}?JZ)8Ejl>$EMsLEF(=^bL9kEqp-R(?@9G6SR=B z&Xlt*RAF7Ig>|EL_BQok-KjTwhx)OeG>G-0p{zHJV0~y5>q}!;KbpY$(_}V~rm8R*|Z~@OS`gpv^$$mAtPxYwvhH?OXwiBln!Of=t#Dlj$te4yX+G> zo~@)4*=jnKt)bJ|XLKf8OJ}jq=^VC>&SmRiN7_Iau#K>TZ=#FYX4sT=z^1g5e$2k0 zE7>mk8QV?Qv%PdP+ef#t{qzfV0Cw^(>3(*Qe#H*aBkV9e#*WYv>}z_89i^w)NqUZb zOE0oh^k?=Ry~4hS4eAX2ot>jM*adodo&_e}10^^9MAHKco?yuxL(M9A_+%bC${_ zmd<6C$rV}V^z32tHwQ84erTmaW7Vfd$W4nhc)27 ztP%HPuW*0%8V_Jicpz)WgIEh5%v$jf)`o|&c07!|$-`L(9>F^DNY1lM`jV7m`!wMcF~2oiLT6DbYmXkZRRDqGjGwG`HDU)K=frHq92P8{aLga z$l}EymLvwVG%eHbK^$e9#4)x_U`8R1voFL6wp*NJ z`^71CP<+P@i|^Uj;tV?~&az|T2Xwx+KBfB#C=S z3ip&W?kicizhvcsl8pyTb{;BuaGa9Ei%DKQTJq*Gk`IrSe0jX&&l98oo+1VE3@MnG zkV1I26v}g@FkV^;=VhfRUQUYU<)s*2QHtf2q&Qw#isx0OL|#ow;Y@lQMV{DU&yoO7a#`Hg7HE@U~JeZzq-FZ%Czid#Nn%Am#DSQaS#%RKR;m<#}(Z z0`DtTHR7|R zSNJ^XRlY!ajW3d#@Fh}HzD#P)KbBhX6;ex%+p_pdsS95xb>$nSZhW)!Hs30B=R2f# z_%5j@-z)Xv2c+KoE2$6vTI$P>Oa1t_Qh$D08qCj0L-<8$DE~>fTd4as1mzOv2O7cctRo=v_$(wl%c?+*AZ{-c-ZM?C(oxdXQ z;IGL$d2{&--b&uZ+seE7oAMssLEg(d$@_R0`77RCKE!*tw#2>OMZp)guD_g_^*(x5(HbE4-V2VRXikpxXccCht z!lrl$55-$}DL%qi@f87zp9og`MW_-WB9uT8sRW5AC0xWQ5h78E6e&uSNK>Lk2_;tK zDsduDi5K}wf~cS*ipolosG=l`>Pm{JrKF15N}8yrq>K7WhG?i{ibhJ7cvUGbUQ2!=QOb*cN(IqhsVD|1 zmBe7BvKXq=5F?eEVvJHtj8kfh_mw*01EsE*q|_5rl=@w+*Epr z+e&Y7SLq|}D}BX7WsrEP3>HisA|!RFP}Si=Q%49lb(HW@M+;wdjPO^-iV*c(5w4CC zk?MOQR()S2sN+Sl`hiGOCx{GnqA0FT64~lxQA(X6%Ba&szB*l$S7(Td>P%5toh53h zvqdd+j;N!~74_74qOm$(yrwP?P1S{>g}O+zQWuLh>W8A8`jL23T`D@L%fwsiD$zw< zBYLWzi9YID(NFzc3{cmJA?kWDLd7pg>LxKx-7Lnd_|8||DyFI1#7uR&n4|6z3)J0W zvARbrQTK{v>H)D_{Zgz{4~o?)ekE5AiS_DXu}M85wy0l=?dnmnLp>(GP`?#>)l=et z`knYnJtGdQXT>+_IdMWgFHWf!#P{k&aYp??oL7GoKd3*6AJw15CH0cHtX>wss8_^Q z^%wD*dR6?c{wn@Z{}8v-8{)3|r+A>=6pz$f;)!}&Q0PWAHIsH}&86L13u&*`QaYfumJVud zq_4EL(jko)PT<5J-BJ82#LWroo-fvay5sl{fQ8$1{jh#b>9%Qio5Yo#L3;oEQEn4ZZp)l`UuL9bb3#^<8`N%7m z)(7kZ_$RN^W-;V~_aG=C^G<{}T?ybH3a(-4ggS%+J`r5O(gx`x0JjS{%~}JF z)bXJ`V4-JDeEIM_Qd{7ofL9~(Njn4nI-)mek8B5HMC?}59dI1rq}Vm2 zhk-vA`?>ch9u6x3Xc4=@yBEqy1iU7`C+TCrHIo*T-hh*VZ=Tc$U&*-AxFz?c{S0_j zN*~%EW$JlLr=6k$4ZL5*b~*_4(eeATPT`jYSDHP=S7Rpcg7;@{FXWkDOM7D0&S0e= z9(|^0>lA^tWt{a(lvy6|Mp)Fo zLK+?3g;m8N@PiJIwj3ni8+m71ZS)NIzcTP2T5(gF;Xbmx>V&GoUuJ7Wel*(h)RsYh zMmg1iSL`}PTrS=2E?-3*Y9g9zSL7>5UkmVjw;4tXLh`+={5Dr%TO*{Z7YZ?44ctuh zluNL;5z+v+7ClDY>I3fSw-8@0x#0T#ONkJ!EFA-0AqwC|NYg!_F0mN+-2pX-9q=o_ z9}K97FP&WJ-2-1GUVvW%-Y>8o@ip-618b51z)gVf8dwRZg}dmrE-;pa0&WKU#=s~N zZs5-b29Zd>Er7oe=#LxmT-|jqupCxJ3TXvA4=Rq8kqe(4vQ{JuLD~Rc5Q1BUjrU%Q z*uYB&3--Pcaw}pL&qA4R0Nxw93#%tr9TrEYlLEl)fnO4xLMj;e6VcJ665zLhKNTH` zQ@UK~A0T}-z@319jPx}Od}2&AsRg(T@F_8oq>h2F6BA470qzET{g^1yz`*y42_lUE zcL%<2j6ZqBsPjbReI0NQ;HSidk!A*dZA>%L5^yizx5wyIb2-o0bEFN*>4RuM?6Dg+M<$LX{m^d%0FO%?4&UY6lN?S!mvUZ7Rs%~&Xp$}o z2^oU_h$NRT(Bqj&$zrIml3{>LB}I$=sGD9|-IN75!OR8EOkJQSb-EU5<(=Uu_^s2* zIbq#fls1UGhx&{GyezE`PK0;WKQes-nIvS`DG5nPUqvP&%{ai>>F>jLxzp)ilbL9{ zj`<;dKbe6v;{nqQ-FLa=87?_60ntw~B26?ok`d#CC&53KQLGSuJEH=bjdG>{^Dsk~ z3@(?GnJdo|4%kM)W0~pl9K3fr;Or9XjT9IoIkEVKQNdnKLi*)A(*+jiC?>FU65OI$ zh3rQ8x@$-tDPIWfISPOHx>BF-E-gk>zrEK3?n>l(`Dg%05=t zzyaLEZyf&v^j!nEjo)y74S7EUT*v=i@|yua@}EI|H{j0#a>#W9ejIQVDP8VL;B0aW zeYFA6>w!9@TyA)fuE7Z`#e|Fs(lx%zO%H0}1h&AR9n^%}L77_tFA9oq;&ty{kV@~O zZrcGr4SFV@Nr*3fh`!nhyc*(g_NSiSH?$po!IiM94r3&=Ss}iEm<7M)QvCWu$lx%! z5RV(8V1ZCz(1A-Hbd<94P+~ z;JcA03-Kq4^(OAX9|7h}v2Mf-@YjHUFZL{N%_!GcJ_dZ9C{N-cxk%h9>KNv(A+VbLV%^P`701l3+f?uG86HbdeMgk1Hd*ZK!G|fs$LrMbMJH|pv5-Eu^rvc}s=rbIb zYm-vN37modMoL8k3w}yDA(xdrV528wZOS1z8+p$I{ygI}$wA-ha75N>QX6>PO)8$o z>qs)}_=LMpD2Zv=OkW5*@<$5U^G%iZ&wB32{sEj{Y>o|r3H$!&le zy{6M;!0T{VpI^x*2He;8j-Jx#-t(JCHv)eju_=CI>F0nS08a7Osqb=O0h{Pn(E1Ug zF#(?y^4@oW{hja=;4cQgLwBIgPXYfL*oN*gc%xzP0DNuCi9RBl2KS)*0W-kEgLP`U z+_8`(&%=@@enBDRbO;#BaB`ZP6VgY4mS!UtjDGM*t44o7Jyqa~rIm*7a?R71slT8c z3ovh{&sQ%Yy%n%;_5*SSJfOq|L~dIFErUkiEolQQ~jmf)8jLROV|HrF~`2EPuX^1i^IEAv5NIS%Xs3IyIC zcu&lPgJjA1ED!7vE(hWlA_9qj%Z0>~Jb9|6n(T>R5(&XKE|y$bkPyH%l#|$5&7E+x zWk1a~@at^rX;qZ3r&;SbhuxEy=L6p9ct9!}@NaGt3+r>jy}oE7TSyeroOQ1*+MyiX zW&3oX9b^^1S`t#urxktMz%TS2#(K&QoVrTLa^HSzIO?FgXxywgO19$HO+u1!vwc;S?!47j;fYnl+Kz z;k#V7sBkBc3CufD&t%1fs1Z(lao{IM4Rs}k?;GuK!X<$Zh<-LdiHdgdSPt;9(Ka$4 zbiAqNRI%n0C)kuBr)C1lwnS=67Y9Y2AgQo zGxc|N6n$O=`2MN*{nl`8G9=}MtdVNKcg%P!A4i$h0k6**58vh5=X}M^%L;yJCZt== zZtSX|q!!?DrMjC*NSV?TIIMu!xlKrg(qjwhcsS3cyXygeG|!(rM7wmSk-A(}WYPe5 z4^oxO3L^~xmnB|Y0B!{M7xE@{@Kc=r06wI7iYcj@?U>;iEhz3%#QZ|@3 zXF16GCScjRjZ^@vy8>Ghsf_d;fUjhWbK-Qbv#l(vj=UX#?`bPhNUyaH?5;)L&cJVR z3}FrM-Y$S|IvUgZs83hGcip1NtAKTUZ+GncH{eg*>yy_Fn0sWA=0-nM^k__40`7tI zRXiFL)?u+nQ_>pvUci6s(TKD~UfpT9&G!w|p%0>7o^P>s!1o1w(=&^7FwzY4?jyQ_ z7X5)A>)lDbg>nV}F730MbV6Po&hq`3^)u2x^}o#rA^l+B)qrcx&KUyuoq(34Kho>) zj{$4hSR?(TU^iG_tz2>(~5MMsSXrouer*w{@kRf5dL`k&$L+q@YW|lkWomRpfp0Df(7-dy37YpMe(d0e`62G`iWKZ<}cBvP2qv zq`V#7fb7P5b+F=B;{hKu%u`r0iFkZWKtwi419&8mP}JMvHPvUXzUnu(Pt&_m0**|HtJu6=aF2% ztAVf1OOw(DeiVO#ajW8F7|2zAhg34^GeX3X%78xyezd^eAtU`KBAHY}J=X)j25D-k zF8ZDpk)$r*jliE5A*6wUe}ue^0dEGLO5x-+10NxcBTWHs1wKg{LRuK_{RHc#ma2r) z#WDYs_7=9QpIjfeyDN}+gbb5)Y3y=`l`W(b%Gm|XNoB2xCS%pbq$}#Y2l(;oyh416 zR)M??{663_HOv$Y_qNuAyaW6J;CpF}Nq?h04p@)|p!|ct`@nKF*udAto}M9q4*}nR z_?g9kx*f?-;Ew=55MKtF?ps(YhN1kUz@PgIeJjvNXOeG#uS~WHR3S1MqEFGMQq$cLIBrOhaG&1pGW! zoy{`d;^cOa>)YJ^D6L5c_Z?nfq%kd z$VY&$0Z&CSvc$kgiFmRU<@^qO0`SWXd`(e~d<^^_z}FYK_Hp-*(@rPL)y06zjgRH;Oc8TIL?5bO}8pcQyexy`;o+n)j+t?VY> zsIP;?;qCM2~y958Jtsa!5iw}u?8xb1j|G>-k4aCjBZ?iupUYZ;Dl#t!_ zyChNr0JqsOjznn^cGzQm?iffi47@_hku1PC2c1~3XVG+(A#qD+oCE@23)a^hz`C1D zvS?|P6AV1=Npy7@@W<#uny)Fi$r1XIenG2fu19lt15y=v!+~GQtCAW|VL;5)2gOvz6 z!oZhNmy+NjZN3Q@D(uZE$VnS4fRY09AQl%tBg83@axQKz^TA{ zIDgG?HXYI`#|fkZAL6v+yYTg$Git~};2V(~y2dEyHmyoN16&;Vd$bZ+Yv9YWc=9>m zlECM)7*`?i-(Z1GI0yI+%#W-?KkIG?dy8z=RLB+ZGiyWk8ML#(YIMM8?{0hteaOJK zV%6yde8H(Z2WcxFYqAsWE=p5wahey%N{Qlj0GkuPO5ToBpj`Mas-R&O7p=QPo>N#W z1?g5mNj_jom~#|Q$t{3o9Gf-qn^`NHg>1~84ZV$(H4)@@H%{Iv`xEwL3dALH+{;0} z&-16H0po)@a?DR7vr`)2Rty<&g=`6w(27MAN1-CFl2?KpB**O_tqEBFEv-hdLV8*K z(H|P(7Q#au_|_wpIRIlFP0~YbWC1V3IA99Oy@lsH@lBfySg*1E=Zn=hBYx6ASn@cT zqHRE%1gYt$DkRius%L9hK4fy=?}YPLy~9BsRK?rR2j8U{-g+{$3$@^F6~kY_JFH|* zcuSORBTvF7yE+QJ2yO(!Gcx$;)2D+F2jxI5U=0K)fQXY0P7Hb*>0N#P6zMf*dW(}D zPk{i0^e+0K$ftH^oany^Ix|7TI1^(f=`1wPS)MZo%5~`?y)f2tqMe*RCD_y4sVlfM7y`ux-K%=f>n{<4z~b*bj!%cALQFTod0XU1Pv zub1KfX+GJg$1KV8S?C$|SPA|gs+^Ls9r~7&w{Nb$c z3!Xpz>+=uv*$dJ;LzD}Z+SA~N0XjYkzvNR_J%<|n@_8YD{5yIfzjF$Ju#H|Hlmk6H zQZLup@2>Vxqg-cwo&Dp|-_Cfjkq;Y*J}9iGYrOdC^+Gw5jQmc0kM^4Fc7{$q#rw?A z?0+*f`^gNQ^>UT(>`!OhtS>?{U(xrNaa75TBHdr;JLft6nD3frIO+Y|xG2=~|Bmlp z{@i@;i$WRmdEm|V{B1lK{pPHfncqd9@_Ik7$F3N?|IK`6KRDyAbVd2L8g=2FbO8UF z@tS&h;NLBJdFZ#I{99MAr%8_&Ja72d=P%&jLk9mIe+i$Oa^935rk*fEvwzL!X1r+l z@17S;Z^oVN#YEZEpSG9O(@bxMX1&e$zYER!xltFNnfX18xEU6GZpO`U7%WA)d@B0B zk<>L#isFmLje0-3tjJfRzLH(3vagf+4G|5|L=+y>EHj@Jo)AQgZ{+&&DsCYg)TmE&R_QH z&s}oCV(5dPb-I~y3FF zFa3&kl#|IXFOsvEAF${2z;)<>NFAv=tUv!OoHyJs1}3!W3*QiFbW_WujyYM3$ZV)Sz0WQK8w`Aec92UIfK1m9zRT20Sqj+;0moilXxm(ibv@~3G3 z7LEVs`w#UiXVeRFYM{Yi&i0u2=jMNZl}|OPxvm+Z^X+y(es_i_7wee5hP)c0mk&2v ze;?$PId7S3jK8r(U6=l9B=9sLvGG6 z;wKEc%{S!cw}tdVe#praI$wZaP88ywZ>QNG|NjeJ{q+1i;lsjl=NzX_6Fk}n6Sy;O zuCI%R3C45m^>e1fX4~iTo9WH+!VNix@$XzmJ44VR9lvnt+=`L z@#}@_yXVKTDTmDdGUc!tn)EWCo1uv>8k*0|@MX`7;{P5;d;cP*&FB9qdHu5bneQ<} zGhIJ!+S6S9*N?lxKMeV3_M;g$!=Xk#v%H~3J~M8X|FY0bS0pT4-pA9H>2L?jdu7N^OuW%eQ#+)kNuB?u6kRH_Wn`$URV47ER3T)<@EZy_`~3P z=&wi}sXO#<5c;<${~+HB7TQY>3s`7x34C1L=nv;N^3MGx&h#$1>6C+L7t%Y& zlW7+*zQ*J}fy2^2`4^WOXd{!Tn@2c;ZLcYLz>gexzj!*wBf0+IBw$bnA zJi+XD6K{rQdNZ6MT>UfCl^^@YpC4Dx_{fDf%YR0HCmwwETt1Y8_MkP`-=_z>sl9CGT_2hyQ^bHpfBH`u@{+k^26{F8y3P3h`!tzO4M0mG?5dSmbm<;4ko%PM>G?k!R&U-~OWYbLIQ%dtK>GzA!_x zyrOXv|MyU@k09UZav$Np&*ze7&0O>He=ts5eE#?My6SJzw`hA`mY(Y8N?`uv{Lxdw)Oky#>0rQ1=$;-eMk1cEsp8KIHH|;;6fRZUr{)ax!?CUg&b3itl!G z+zLI%C%X5kUg%1mMs{GA9_$qyyX{xw5?ZoGPp2PPu>;k_CxH5cg?cHAbnkQBTgSIy zQO$Rd9hhkvNjB&YHtOCcc&@yg_2?Ge+p2rpbZ@)v?a;lQy7z_d?b5y7y0=I7_Uhg~ z-P^Bw2XyaC-8-mzU+LZ<-8-y%M|AIN-8%|zM~YsdV|oL>(Y@okcLJWPLMQbe`W8Jj z_>|tt@APb^b?dlN8S5L$Nj8(mvry4UX*?k2Khyg zUe&!{`LBdr+|tH_;s=a1>s;3y?$qP?@!&kse8BZK?=Fe z?_#lsL(a)v9d}Rn?(+xubcjF1w+{S~zDpCh$NUMlt8;7|eTw()fTaRX-wIDLHN%a< z@N||UI0z8y26#JQJbv*5C%J{5P7;u#xUS2n{U3p6oM9Cnfy)A;=$hpExvSEk0VA+G9t-;kBlwZ zb0hRk<{F{@D`XtWK*mwbB;#oIuLjt71~PuYK*kB|IWkVdCr2C?b3No!m`TQIIvJ<` zhsiicC*!vJPGmS+|y>sJ{{ZxK8+!g@i|v7ZKk1T`JBM zC4)8H8r4RC$1FHrlvpvt!Z9uI?7F8PH;Pj^AYSpC$A4vR;ovTQ!EGcQ0y&8P8-e^% z)%!mwsmpONQa(2sseu10MykTWNL4u)sTzNdk!o--QcVs(Ye|^O81iKg2V?Ft zD6>{C;BVY?PJj7@!j~h-i(dXxDNtMIp*p%(SLY$8AgiZG>+4~^zPtTIfZiUQk_tPW zFOKxqqtGwVU#MVqmdvWNw-}E9W}Debc8=Xn#pM!mX}PRiAXk$6%7f*F@*;Veyj)%-?~uQcabb)6jeJ^WikA|l z)KMBLO_Yhs3}u6|T{)$kSGa0XW7JqRO-)yG)f#Fe^%b?H+D3g#eOH~V&Quqv%hZkP zZuPi&UcIE=Rv)Quny(hG_0;-lL$nFnEbWf=P@@*R#mf?AiMAwJvMqU*N|rj7MwaH5 z{+5B3&n+h`CoQKfL##`!%d9J{>#XOkKU=R^eQZItP+LXY1lv^G2HQs4R@({NPqw=@ z#qMDbvM1Qf*lXGw+nd^3+sD~Iw{Nw7V?SYccX&Ab9i<%=9n~DQ91R_>IbL_PaI|-H zarAOba!hf|a-4NgH;Y@8Te4fGTdrHaTSvFUm7|nCtPO$4ZaA9)~^aMGm*kY5zUUR)Z^4jFJ!|RCG39s{BKY6wH?(V(Kd%O2O@BQ9id!P2c;Qgcb zW$$a=H@z)B9zF>^={{wB%KKFGsqNFir;$%npErCu`Ml%P%V(m`T%QkpmiqkUGun5Y z?*!lJzK48|`+n>Dqwi(kYrZ#qANW4?rGEZ?VSZ75F@DAUa{WsC)%5G@H`Q;B-$uV3 zerNoC^n2Q zv<(;4>%NXB;c2TTLCnX1$qaD1ttY12bK)%5ZEQ~?ZC-_vjXP_ zE(+WhxF_(dz@vf31Fr|(349p%B+w@)FeoG_Dkw21EhsZ6Hz+@-Qc%^PIzfYjMg)xx z8Xq(@XjahNpbvvq1g#EQ8?-s-i=Zn(e+E4Xl7fAMQ-f;<*9&eK+&K8P;3mP%f?EW) z3T_kJF1UU0JHb7I`vtEH-WvQx@c!UK!6$;-g$xK85i&AlT*$1DpF(~Pxf*gOgoQdn z14Cm%GeWC}HV$na+9h;!=;Y8Dp|e7lhJF&dGIV?B?$EuVM?z18{t)_e=+)30p$|iq zFk6@-EHErAEFvs9EF&x{tXf!&uvfy`hII=Y7&bO+O4!n{)nRMH)`x8g+ZnbuY=7AI zVHd(~hgrk@!b8K0g_jF2AKomyeRz-X(c$lge-J(;d}jFU@Ri|f!w-a?5C1)!M5qx} zBdSHzj%XgyI-*C!fQWGs??p_Em>e-LVnf94h_54#M_i349a$!_O5|ISJtBujj*FZW zxgzqb$g#yX7TaI!V6o%H&KI*pc}0apg+|3jB}Ao0Wkr>UsvOlQs%=z{sJ>C9qu+|| z8$BR;Wb}mSEzx_Tk3@eR{ay5#=!?;pqOU~Xk5*$+W71=?V+vvh#f*=c5Hmeyam>A# zCov>ei}i|)h)s&E5?eF2d2GAbp|PW4XT;8r-4eSq_M6z#vFBnh$G#ocGp=9U;J6WS zqvGC=n-VuOZg$*~xKHBN#C;yOA#QWruDCDbF2r4myAtu@qOa^#}AL6AHOC(C?PZ*XUP6V08VL;&8YhfRn3u3HVMW5qgtZBq6OJZa zPI#E`Bq1&_F)=N%WMa+4)``6m`y?(({3!9`#5IZg6VE07nOHNadD7CPkCQ%6x{>6T zTsFBfqE>sh_9X z(%jO5(n8YW(-P7$(n_a|O&gasIqgW=(XrepK?~l50vHE_t;iPKnO8XM1Od zWJhKvXXj)$&3+@hLw3jPp4q*!2WF4V-j%&S`)Rh66P;5gr)N(8oVht$axUkT$}N*y zkh>uFvOl{?#ex%`!Lt1R6wcFQqiSSN@bQRTdG>A&ZT;n>Q`z&sZpgym-?X8 z^in5EeP8NwsozT7DV1BgOzDEsl}pzsU8{71(ydB&DBZvGd!>IZeWP^6GJVU8DKo3g z+A@EXxmo63na5>VSy9%nY;f81vX#rWF59{6wX*liJ}xWeW#+ZWYm?VLuWMefyn%Vc z^48~V%R7^IE6-leyIf$oO63}qYgBGYxuxYkDYvuSp>jvdDfyQC(ERZHl>GGk2KkNh zo91`O@08yqe^~y`{G<6-@~`G!&;K+3NxoX(RuE7SUXW0bUQnu_prA%U{eq?iZ3;RU zbS>zPLth>En5;7yf&(S@ogWb$lGTwmoa_$a=D z@8T!;S^gux1g)MRs)&Q)SD`^yzaz=ABD=}{aznX?JV`z*`zXbg`bsNhs4`#qR9UO+ zR;+5GS{0hLw>ni_tS(nKsZ@*5^0Zo7XKkD|Q=6|X(e`OSYfrQkOB3kK(U$F&BbK9< zQ^+MryjKVc==TDsp-?gXO7P@pXENQ zd{+Cc_u1_80CP9R*Y4}^_4cjgTf?`3?>XNLzf8YuzcPM3{rdTB^ZUZ@wBPrB7yNGf z-SxZg=jHG3U*G=~|9Sq4{5Sh=@!#ox(*KnIY5zO^5B&=QDnh%}3TPPcN71MURa1Kk7t0?Pze4QvtEF0g%I*T4?~X9s>3xGr#G;P-)N z11~_c-3#PF!9ig`rGxUI%i09J6*MSlWYEl@jX@WK?gu>x62Tt9Il*IKmp~7r8g`NaQb(zenDPycZc? zETLFxv7BN9iVZKeuGki6izCI374w6hs2kNds&!O{s7_Jcqc%kCh}so(AnNO=V^LCc z<>=bc4WTi*NB4>DA3ZdBO!NoQbE6kWFNyvp`b6}p=zGx*q8~@c$0Ww2#MFwZ6H`B? zM@+AnzA+!fOpKWlvnFP3%=Vb`F_&XRtP<;p^^6UG{>YBajV&8n9(tsDZ2j0qvHfF* z#14;rH+Ev|#@KDpCHrF!#h!@$HTI9#d$Eh5J=Vuc;5|<{fOkACKGx2evEy+E}D=9cBG$|q}Jt;G(R8r-nYDt5V zMkc+Nv^!~E(!r#!lTIalpA?_mDY;8>kL13|{gaO*A5H!?`CRf($ybx_CqGSgK%*2( zNlM90DW6g|WnRkSl;tU#Qg)~OnQ}AbQOaXX%e7SZRKL{t)a=x})Ox9}rglv2kvc4O zT$DDO@1*rh8v)HTHEluKqO@gc$J2gF zyOBoI9qFOzk?9HP+3EG5dj_P>N?)43H+^6F@$}Q_Kcv%);Eddi${B4l-p=?SV?xHf zjKvwtGd{^!o3SqAP{xsrV;SFNT+O(daXaH-hIeLkX7S9N%!14}GW%rS%#^d#EPGZ) zR_Cl9S);SYW{uBUoApQ5-7HISTXB!#C5pdY{FCCBivL>tc5$hMcZsMHDJ8N?v@g-A z#Cs*yl~`Y5Yl&?oc9*zbVqnS9C5vUhnms&wLiYOXP1%RDuV>3SopQS8^vgMrb2R5} z&i$N_+_2ozxm|O+<@U-QpF26%f;|i+NjXvhM_Dz*vACUZ0bD;a6qlFHB@1!g*rzza zV>dn${t}mdog_byA90MQ9}UIDRrPQY)lgh>wU}%)#BcFOT3cJdQWuuR*f6;=OnuK8O$F@AFA~3ZKar zU=_EWpMm?L;RrPP~s5+;lNdY!+L^Zm~}s7AM3RaYg(l zZi~C(iI60lR8^`Y)t4Gc&7`(cN2$B?jdW5vEB!1Hnaj=PHgY?;EA&M#d5}C({!Csc zZZ zI?cMsy4t$dy3xALiYuF~Us)emCEHABj$b>ksoN)RtK8PP9dkSDmg=4XZBoPi75CTOTe!D%@8I6a zy}SE(_nGe3-2Zfc;QrK|d#E069=;wy9w8p7&b3%ok2)R=JsNwo_vq}=)nkaqaE~z_ z?|V%0nBphYTg^;A9mJ)=AmJX1Z3d**tU_RROJ z^Eu=5qtA7p8$J(xn6IC2v~Rp`l5eJOo^J);>b@;}yZCnZ?ddzfcZ~0N->JSI`)=~x z=DX8(KURY0e7T?9&(|;5FCMzFv|oW=WxpDJP5jzGCsKb0bYirBs(&5-@&1ebKlESa zzZQD&3;+H8-}^uEFBMQVpjklkfDQqj1NsH@$GUGyz-Iw_1C9rL8*nP%$AD`Aj|02| zGXnDhn_|5;I`DAd4}n*(!g~~G3vvW`1^EYs2IXL7Hz;U$&?v0vrU%UqS`_qI(C0y$ zg8ols-yPpn_5Od8X0}bzz0;A-G)=k}r9j)Hw9vGr4Fw#;G)>#sEHXN9;X)iZaNqz% z^n=@vhCU^xFg!XwF$Xtxw*N`x$|@H%H5UwAndkha$m>|UI^ z^VjEJnE!PCbNOinx`LttJrJ{@pt)dW!D?7rqXke@%Hx=$Ie5mk= z!WRqQF8rwQ%ffwy-xn&2;)*myT}9TS{-P6#hKnYOwiWFtx~1sRqSuPvEc(9ahoWDK zYKohS+l!YL_ZDATd`OJAsXbTxQt=zbdy4lKf5B|E?}`r< z|5BV&vZ$n^WN}GPiLGQs$$v_|DcN80W65FIY)fIM4VE5LIs#j5UFrJL%S*2*y|whN z(#K1mE`1018dH{0Rs}2VQrKx*%eI%@Say5aPN1z=KM&TJSAVMhO#RvVbAYs$=r`+c z*59H3uYRZg9{t1mC-uAa@9N*zf2jXh|E2z0{h#_aV6US*Sbj$N`Q=xaZ!6yg41T%% z-SQ90KPul-{#E&b@*m0%mmewrvs`LW7!rWRD-FjR>;{Kn#4ur4V>rWbj^SLx`GyM( zmm97z+zwRUWw_VyfZ=h&(}s5pF%>Blg%x!bmI`-;ry@`hsW_!#UB#;vNyZdomNCy* zUZ+=3Rd-k2Q}s~Q|Eiv;dbR4^s&A_HGpxq9 zn}OF^)m7Cs!0WE+rPaOFE2^7n+G=`hPKT9vP0fy)du#Rqk-rBfAFhe5&9Bwfmesb_ zF037__15}pBefUQUR1lO_UhW}Yj3Rmur{Htpl);Bjdjn~y->Hi?yb5H>-N@tQMVr` z{Wowrv0htWR9{kWtZ%MgRNqnb_?)tate}qN( zPral;*`RJnXh?-^sRg3fH&_~a8jc61hZ?3EPHi}|;p~R<8ZK(s)NpyjRSnlRY-_j+ zSpPu7^9`>yyx#C;!@ICUKW_M~LEflrENrZ4tZ!^?Y-=<(_B1YQoM=3!@!ZCX8gFTQ zu<^;p&l>kOe$)6};y0lOd@VizukGnE=g0g8&#Vl{u9g(S zlB!lYy^yj$@+Jgs{b`xSpFWXcR>k+Mozt87xX zD%+J7Sc|Ka*D8InL0E|A#cqt<6uUWgOYC*AH^=UZ{U!E3ScT8V?T&jp?gMyOzlhrx zcQEdcxP|dDRjevarBfBdr&_71Q#Gm~->%Du2D|CjOt?8?_u-iLp6 zU&{9>Kc^(5W~DAm9Y{SU_1IKr>S*c&aQKzfcTzt~{VMhA)Pt$Nr2d-v55ABVo0gSU zly+>|acLuIt~762AT5%%Hf?X({CaZ%w}={mJwf)89}38tBVqXfkp$N-|6tXJnj{ac;&X8CPUnnXwHh zd>ic3XEOfI5M?Se<1$8p7Q`ytmrvQ;RWbe*?GyA>l zPqIJHHs+XeYT;E~o^yQ8Svl9|+@13G63d+-xe;|Kl{u%I(-ktwI{@(o0^S{eK zkbgM;NdDjXF$J1})B;06bwN+TK!LX)P%v4rtzZYdqVE)NI*~3`7pKe6I)T&UMQ0UlEZS7GxoB(A(?u^9{aEyCQEqWwaapmxxB+;*ptz&B8y2z) z7V`Sy3t$x!UcU>BmXyT8i&|6CQZm1!yQHsVqGV0U#*#}*{tJuvLDZzSXnJ&MmtF zUe#w{6aQTHds(5rNN?1e^o>C6g?h8TUq1xvc#Zyip!RM0JAv1G^q=eF%ah7m%IBAN zmoF(FEMHX~DL)C8@>ZbqW93hkzfk^t`OoE8Z{8s094i0 zmDP>bt*Lva?(I7Av%XNTZ7?=`(C}$PL1Uybrb*Hi-;@Sq+SznBQ0bAT{Y~FB9coHw zu4o=^4#RJ{sd-!T_U5~r-)erl`Ge-~o5k}K^VIW#^VZM1820Sd^ZuS!+EU$8-_i=d zsjX#a%l$2nx4hNze#@Sgy)9p~w9bEj{s;3vpa1v#gw~|itk#BBOY5>$TkCPH6Rn=s zHLcgR-qds_tywSLh0aqG9O-?jeOdKlhQ^@8LD1zN(tD*J!k+y?+ALcr>yoXKIbqSBDDwjWPm*0AyGXW4wpq3X7zb z{C$WBJ{|v3{HO8X#vh1382@wppYalv97tBBY5;}}sBEg$s(>n}Is*~HJ5?X6_Nu;7 zEmPZARL~1-n*zF>1{?Jp^*!nb)laJ5R{yI0UCn7?G&0~^yhg1_&?IS6G-k>94T%K@!!c7S~6P`)G9lB!MBr8cE5N_7Eo*QZ{PdTHvFsn@{jy(@JW{JW39 z@_jn>IbiYYsk>9(OZ^at{6*^i)I+Ji!3HKomZjyTHKaAAwJ4WL^^wIR2fX;WO?@GTn z{q6Lh;4%I^Jtjj5`#3QpD}*qZWp-V51N_m8 zvzKQdpY6^LW}l4s>c!cYXK&5EpIPEhWj}-1sy0WLvkTtnM{*v|c`@g;oISw)Lpi_X z{F5WoDz!P$MBCi?oZi{m=ncLj#!5?nPwvYwZE;A?+{Py4?2Mj@)j< zRky<~-w7SywcL+#Kg%7>dnoVWyeIOW$@@DmAwL;$(HulZ3*gDF&JV#xpUFQ3-s~&$ zug$+J|Ec`<^FKgb^!NPwg2jl6_7)7n!@aU#q+q<@)`Hs#?kc#a;MIcH3f_j#`}cwb zU7{{cSFM}Yodmo6EZFTA>Ne}P=&sY7h%00*8QbRg!NugSX;QbaJX<1 z{_sl*uPnU1a981@@Q3dy++X+|w1LBgBG~K+MQQMguPF)_tt&da=%S)aiY_a<2HHSM zaawU^v97qNxU{&sxVE^Z_%c}S+l%igK3x1yv9u(mWC?uX$CZqh_~8#fx#ZN6vrEo{ z2Jmjl2PHYBxuxT!6Q$nLQ0WZp@{3DvD7~@trqWwVZ!f(Q_W9kV_m3ewI55w~wuAHnqxpHIW^_4eQ zJ_60*-O5y0=O0&XuD+@Igqo2WPtAdv^J>qpy{z`C+GfOJJL>L-RsBZYyLBJbbv7(+ z=!0z=Xq;?Z-CCy8PAG>7U>Uqw2qw~B#{U_$V zHt(x>zs@UZF|;(bENmHS@wNn8Espb8(vKQqeBa{i26NPl{fJ?TkO&FBXfH;ta7?Tqy3w>81f#%RccMSj;!Vcm6!I zg`c4(WX5F00rZ6~oY-3i-}%~@Gh#MCQ@Ana)|f|Qo{0Hh%rh}YSj!Je z9)rg449+wCBx%A4riIeQ@PZ#Ny&wMXpQWX;GMQ1fL3W|+3g`yc%C^aN$R3w{BReSj zQTD6s57|F5xm*n`!6BcJualoEzX{RP=jE@;Ka_t9FZkbbDNZRhDi*+EK1*@2;&w%> zQlm_VjohGIgcC^{5KH||c|dtcnHZZBtBW<9%qXSGOzbz zagWD64SV_fIJhnmJ*|qbi*Jwbj9(J(iXV-ii1)=$BAR+x{0;GU!x#Q*{2%c#u%k69 zyJ}eFQTgE!-=X?jB~r(!)#`M0raD*Mt?p3|sdqrvctrh^x*uNdUo~k7If$0lCMk`if zhF_g{W8!UzcLBv8Onf5o<-|7=KLD10k@zJdtY0VYhnM>x&LRB-bU&Q#bbtPGo>`5a@ld!orCT&W(G3gdq+fO9zPI@=#o22iPeo87$E{B!fmfV@V64>ug z4kxcqK0kSD@^)rnzm)uX@?K#7Z^?fpt5cHUWqHamK>jdr|5VuBTVZKG zg_BJ4f!+9yR+=&`F|9nU4nFF&z~~)mcck5&wkz#{w8zulNP92sqqMKm4x}ASI|8&$ zPOnKf<8;z>z~VP>HmN3~K4Tv6b~IxOHu19=uV%cCxa~*4)2}mr%=jlmk(r&jD6=iI zGc%m|cIG>oAHy$QoTbm|06yBYMzUO4UZCXqtc_Wh;4ISitp8-)nRS2G^I7{~6)(-U zWsf61du8^%>~FJwfG;{bry^%9P7tln*^qN#&Sg29bGGH&mh%lP;6HPu+6-+gkgo%A z+TGeWwI9L<{ipUHtueP6=ZH=~oYs@;&5h)qoO@yJ<+)pOZ^*qB==T7;($D6;lKWQf zhlt|t&HXO-r`*H2|Kuw2GV_`c&)t&upS%ZQ34fEMqx9)!he6_eq=v+Q%ZkF@?&) z6xh4kLPOy^SiF(Kb%i_NpMD$`?<+Vb)Le8-(XlueE`3*^#n8%94O=#W)?bQGc=iGX2~7ci?;eRG(I^gU@-U z{Iv4*z_BZVWIN$`eyIFWM1Nl`{}h<^4G`@RFic`dGNb^pw7{xbLyMu?u+%VMI2PXL zn+TxuLL?l9hA z++}>o_&?(_@G-w>{M`7Z@jK%W#=}ODDbbW{$};7^yIg6ihh5uYT4L&fciCz3n5Io@ zO{beS;H1%YCMkTIS}q?ydMoBiIXzc_zhzv74*)bkvbW%)5)1M1fDX=r4+eL0eTapw zz~^%(5DoQn0sINwv$+lUjL*&ZRN?pBPxx?;L{tY0Z=R?XHeMU#y;)=tEkiuiA##g; z62*&a;Q?KObEyjY6jw|xWOr%IqL>bxQtgUa8gn*IvRo9iIc5u__8l>Av2&{5#vF+e zNf1JmXe0xYLCI>#h{P@NNFtKcBxg%DNN$tdA-NkTR6me>BH1hX0_Rk}k$i`4{Ecr zP3csQC{M(Bo1k(^d5ZFU<>kt)%Ey&YD4$ins8qxIT+Y^|hg$~!^9uN%kLOl%Cvd}@ z6MrCi3+!y~MqXKM8$^ z`<45R`Bn4e?t(;RSs4sq^s zNw>rb9&k#6@P)6HtdpDxPryb*yI(?#`wjR34oD74j!2TRx|LYjdTEn%k+dD>lvhhn zkh-N)(zCI?H%NC#@08vpeMI`C^f{bbegj_febW6>i7Zx@AWM~z$G{@%mMxPF$X38} zZ~{CB{Rf<2H8g0)v{}#A6yTfxK*|j@$om|OaDgpgG`N+%(-$Mir z56DlDd%z*5$~VYg17FO8PrU=N@*eQS3Y=uVU2%`%VMUqJpsZHb!H>Q`xmei^Px^A@ zG2nyClslC#E8kImrTm)d4Y9FiM9;0UeX+LK(b&n@Q)0Kp-WU5SV&@;lD&o@PGUBvx zjd9kvYyHODW6CeasvT)a1aP5jC6 zr^jCye;ss*JL7lZtn-UF>HKc|`|%&g?}tx=Q^`~{s(MuuPG_~kuhFhDt2$NPsvcDz zd>qSh26~n1Sa>=dI0@}ijj2vl`QY_fqYA60RBKhIs7_Ozt~yh7mg-#i^fw_+f2C@x z>N?dn)eX>4Zb8KUPSstiyH&dow|_wOkm@nj)2iQ9f8qR>SS?X2nEsNWPEw~ZEhZa! zOo6&cU8*iu8*x6Y1}DUt)Gg`->Nd4my%;*qQgxqtnR)r1jJpbFL3ZGb-XTs5-&O|n+5Ku zn`3sy+#mC7%quY;$9#s<9{aHyj>NbmV>sgxkc4nje+HksK235uB0^_L)0QHgpxDLt7-*O14S1OKz0xklX_8_YTQ_B|9a%a4zIA$rI3npOw5Id0Fy`% z8-gnon-y2#mjqiBTNT$qHs7e&p|}}mAa7UPskjRfuX_{^V23`ccwF(M;wi;5isuwB zC|**$qId(5uy+*iDLz!}!EX;fQ|wdxpfD>}E8R*D&b(Zvyh?eUa)jQ`c=SY^QaT;+ z$v4Ei5uqgi>}T-Lehv>U{W|6U=RdnW90?BlJ0`=N-R_(Wk2)qmgj``qaBR|U=V_O3 zGQjAzuEDPEP8&7#xE#JnfT(eobHW$#ctD3;L9g5A2)jTBU7@f)=vwOv`Z>E}*dGjY z=EVbj%ljAMqSe}Gw)B9oj|R}tMNc0MMBKhG*V#QduxuI1D?5hhNuvQ*Fz640>hD`o zUB%f0{wZXg_D)-0&mxXb?Re(28@&v>{UO(yh#Mm#((Cg2gEKrGc6%`{=lF=5Iy3hT zc390kVd)(LG2#!|$6Vo2H(o6qrZ!ZAvHhQ#QMYeo)Ex}bn5hMoeXi+f5nYS~-IFv0 z!u>*#AD~^xoY9=G=(P8&v@XZ{2wA7Szr%{D;?qw1U`Jp7szscT(KwxvAiYUvcL$p; zdMulG5d51`jXQ+p#4GRwY9?Jy3=}nt=(YElyN57|Le7^^yF6OW6G9mmux_k5%lQ&D z=Zk!X&UgYBR`v{bvGzP6lHNE!!Hgg+w#^-!$x3_h5_jU|$ zxIEa-UuHR9VmGl7qd9UurMAo4SywFQOQ`Mc<$GW`UqY?f!q>8#FHsNeSRM?9<$P+l zclTKa2KolD_TVppbceuB;6Zy&U+-dDUmK|9Ec1k1F4}F@rM+!d3kaLF9~53iU;;da zF@Zf4bofR%JD=JIEo}oGUHxsgF5DAxIfB@NzR6iS1m5lJwlJ;;xyFJn2W}-EVC(^c zXAi211l-u1A-+OL{gD869A}UCJZ>KiZ>WEuyVqu+mkNag&VaC;CS3GR_TeD4v4>dB z5}tHo?|WRMV73vL$3ab9(=I2+QV(_~m1xY^KKxd)dmL;_*@ON`dj6;*I2v?e8-egT zJRU!828q|X3&aM0->S%=(<$)%il7dfVY<-X_zU-U|V=iqQK z62Rjz^iDikX>c@HTos1NC^k^{m=Ajiljv|`*!_-R$kpK;!RAC=7vzG+WtnsVIPHT@@S?BX z2ZG-1PX1?L7UHyr_xqf9CQT62g8xkQA|G%-&9R~bb{sRi9Ws& zU!(_M`<&R0=g||ezTHm0ug#0uMwiQd<9!`mJz%gm3zThG*K(qMA@jfUO#4A zpzvNiX+2sClCL)VeXc&%mQhsM0XY!n$4c|S20e(K=L|E_>~jR^4wh5<GDt9X$BUB_j5VSW%cwkE8iokSC6 z68qZhpHmos;xy@6?i=y9V^!Jow~^e%YyGQ|rkN@@`v9-+@r4e5V1}px*O=RnQL|_9 zml#PS7-YyLThA6Aqn?B|Hvia|$HlMo(H9Z;wIc#(@L@GQG#4GD zl-l@40*4dN@sFi-000Gpf*fWKYa8}QP|Ikmf5bI7gvJ0%h%57e-Btv3WsHo zF&7D|0sqwOM6pVqh3V42+O|)O`9?bY9x`DDAIf+uW-It`Tr84JJ&(AVirhbiiy3MrR&8 z9vXByd`>o@X203(@X&iOhHa08!+sxLcy4Kc^dwrrXj4lt7$vEippsB`u?stb?q9iz z75Fw(V7>LYNr|>XjdYA*DbX4r3NZ$PzrJtEmL^31$g6=V5Z&v7Wd))*H ztk4DVE0BZZ{waavS4t>EwJWCeMzw3`wxoHDyQYVak^+T#ff}ZVx=Br9b&P^(KyKs#SR!VD~YRV!5D!=@Ew6V%A+U{Z!kszJ%?FPqFsPD zTiizT$>f)14m~u7#*?uw5XnsApgl??%}QVf_wxj9<_X-1DS%~5#;~iZse$A-TvLn$ z%LL)j2~(-@=!Hfw=G+UISZoMryB%F^1DqK@WFNFFCU+WGx@rg#kh#fFsGD1;pIc~{ zEp$}D#RsFy&ImHaJE~yUxr2mXc2GS8dPKm9z!QUP9qoY-Mq&4d@G>E$-GTNxPGk@N zSDhP%3sbawq?&j=0fmHLV=iD2|Mg)9TT=N+$PvYo*H*M$3x84 z;p|~dIo}UaUY;b49-D(+g!CRB)tK7BlRWOt(krV;7I;=6V~zTjvhvCrz8V?1CcHHF zVYicalMseR;gip8A&>T9WZj3e#v7FZ6cmxnhHZL8Vp}&b%&fhg@vvs zikV@yZuDg9Mo+fxUPktU?!Y9q^BKfgNO*s;4474bcC$3D_e^>Q11=|O1xipNx`$B3 z)QRpP>Yv7o*RY|MGL(j_gViWeh7u`#qz zN72vhC-6o4Wg`MQ@-@_zpI4(nTCDW8NJ0AnyCDMXqa=Flu+l)0q6I+`3|cf0C|oCb zjJ=LF0)=)RJ=7~wqWcGl?jIz&dw}Tf0ixS!@sNTZfm+rMnN6x8aw?jIB65q3O`vTE zE!+CcxXadOMH+p7a1bpTGF(L)Tt(VTizzfQ^G!yO^)7D5tw?dT+uBe4P)0ZO(}jLe ze$NQ=b=b+pxD>U>2k_1ipR7m(FrV5lruO`9;YB{28FPy;uFxA`r5W$KxDB=fOlx$w zxUG5)T@$4t#-b!S6yec9O@A9;)!qczg)9*ClQITF0d6w04e5w$)B!gUyXx{nT@$?Z zPQo|4GdvT3)CAzT!@O6AD8U8AY6YJW^l+EMi}!++&jc;=B8}2>M!gJe;93hW_d3Yu z4PR1JUNEu3BnLTk00>MPfrN(T58C{L;Q3iEq~L@Ue2{iQL{cyWf^1egdf{9dHJ5df-lC2s}~jXBVeBoCHs4&5<_w(%}vUflJ2{P6#hWN*hL3Zl{0 zJuOHMP`n7Wbn}u$B z{eqp{Sqldwy&iL#b>Rls8#DZi5IKF6ME9%)`xh7Z*EnjdOnc$QBqta+k-aq7SjhPa z;p~L!%)kH8Gu16!_dZEyrlwi$~{8rIw2VP$7Q03&-nRZ*axpL z%fnEFd4kvm=*O6xC`Opw!SIa0L(CEHi+ICcHYmntxB)f%t&E`S(aWq~j0cxpWRd>M zinZEdw~z3QKWMe{1YB6&sHtpq1bUfAjeomnTY49vvEZ}96NC!jDNl|1q1S^DdpaelwbUnpiBu zxC?Ot_dG;C+;1l@O zY~7ROULk{n9zTL-@mMoRgdn<@o);a(QrFDzNFO#1xeF-ojd)3uL4QY$_CdA-R`3i@ zS84juG1MJqHIm`Y*;kOZ$CGm{ahe!m9KHw}2R&*43Onx?2aL@YdhsT_@e8jh47*`I z97A0QB+D>3?0{JkMj++}tPg(xPheqLu$o{ChVLvLCTr76W~t5AV}+NVSr$OhS}%4k z%OM&^{E=Y~iE#iXwgLJ8-15Y*-w&G;(=-zrcT>oW0%tDhF_;aqKuOu6xtpe~!6LdO z6VWGLhBwAxyxC_UHz=PL@)B4E8>@{s1dFjM$E3rJt_3hhkPEcn;iB~;?bX!5GMs?}2XQBIVB&5{tQ?rlO$kmb zdPc$=R)ia_=7y^{Oqq9@6L3X<6<&ODK!FJt$J7NT4G{sK;btfZK1~TanxSMGNAJcs zRB|H($h6EH2}L(c@yB97hq)6WUO6`d4{6 zT43#o#y{Bc=n;CnYlJ$Zm!Lf23t(5!3h)%`fhXxzc#66}6Ut!4ds!P0{G2(Q<1W9? zKF&`DI1R(cgfPO%U&JIhJlG1}D8aD;5)MYbYg)*-4r<=cHWTqw*a80LMqnW^8N!c+ zqw!*P;rH~qs`-o?8=YoNc-aqb^h{t7tcqTgri_<3B=TuBq{@E@ zQmTNSge(FlKS>mUq-7LHo}CyU@!m7DYm^&iWfDGAB5_1Hc69(f@(9CREcP&mni2Qt zD5%i@&VPhCnptF!ro-gy4S0wgC4k{c68JpDuG5@H8wfPDAd-iFK_6ffLY@Rt#wn@c z$ctdJth8}>JXqBgL|m0nG?*<7=CUY3?j{C!q zC}1`mW+721SZdLn1?8rRt!5~}ksk6$qG1zDyp&cq@F^?Q)=;6g2Ah0zw238*L?cvG zH?RU4p+Jq$791ZEa#jw(J4Ws$w7?}HW4HbLN(hU@w;>&bNL(ihed29gK`7a%jFO0= z1i0ad+Y{!sP|PhkIk1I@T{&BKk7bavwhb<|n7QtbzTQF3QB`7}#0TWos! zJR^eI2})2rK?y49?A2)7IlB66D|YRuD#0DqF}S132Zys6UZ#ICaf7!4H&3&4277H* z1)HNdG1!cTAb5W}^9j?-FeQqX8~n&N0Ol*I1NtGDAsJA^Bm}W2rf`-fc4a%AE!eDL zDcr?WOD1)3n|JPgOiK-Wi5Wv2x%$E|1IU!5MI)(4G&%uhZ>1R44M1UJS zZ*>Iv5d5GhB8y>6apSbsc4F@kwyiHhW+zWDz9%>`Rttb+tmbek1@DY?^>KpEi;>ef z(GY?byhBzJkdGwNEC_(#;TJ>%i1YEgice{p@IKryxF^C(HN+N!PKZN9MLF9zj=&)A zL={IpKt2|v;CM5Q1116y8T*d&*%Sw-5$hFi9LcrDn+RKZF6+ z9diOWMT!?75y_1P{lq3PmcUa;$m{_Sx+%dB|V8) ziBu_^6j=jh8N-265~lg0xnQ~kZsQ3yCRSC$SAZ4h#r-qGP(tueSZ~&3nDarYnC2S_ zyow1WUL|bmM(!%%mIrwNLA zw)2dz937AQhfkyxiI4Q#wgART8Kw-JOey19lB1Y$>>Ap0wbA*m zWuhZQ4)zhYFTj}?(KHtdI%g=sP2(;b>4MeN#W*EX>?S*}yV-e31gK@hV@5M5o?~tP zKAI5@BF#NYB7!Cv+9uLYmbT;10s+s3oz0YXR?lw%ur=Gkq|VfEOv9s51fr4%q?@fa zsX8<@tT`1J(d(L;W6k-&^K53=4AezuppJtr!J4y$CCCZDC;+h0M37U9T^!-{OI{vU zV?LN*WS|DcRq%E&z{aslORt$*Jb+V)og9Jz$ZCYVTFAK`I$b!(b@W*+y*AF)Woa`H z0K6d>+@4`CNA@=9+n7bJgV*7(7T{Z6Z=k(_adCoY0-6igA9Rg&G4)H}W`YK;!#2>v zj1lrUM7N>p{dV4#jy+uFE&{d=ixaQ!hxNjA|ZkE zUHAv~<;M7#hdRIonCAtIV4tA`Mui8CM8VYKa*Q(ujHWB(Yot~o4$HnA97q}3_#k_I;izp4Z(=Y?V^Ia=&TbNPMBY#(>xqXZEaVjD517ED{704hOV&r8GI8bL??K08(qPAPzL3fGG>*+5^)1*Aj=rWBicjLi042XcM^IN zP6q{crqh{JWgB<#3O}J5H{;}{om>aK52VEaxE!(!$6M%33N>x#B{#7X;X1$tU0}E3 zbRBjii|qUP06)oAZkYT5u-Pcwj;)L(tW0waHb+W*()br_+8xLDh{hRLA4wrIQa1* zsA`s0ar`!7*9iH9)hE^^+=}J|XS~)+H9SRiV67?A@tp|p3tR@?5v~lgD^8keo_j_j zI0^*jgJ6e33(-T)D1ind2pwSEh4&f82nY1wXNz)dd; z4IlG`lpDnfMD{`g!U6@^i{N-YA7B{l20L-)K}vB0v$kM8^B0-BWke`2Ljr7U$KRVD zv=T$x+qgxGs`1aVvfGBN3jb=jmE0<>qicX0>NZ>Yh|zoc`j#&5X9oXKvPK{w{{#vx z=?FmIavL>`lDHlvN$(II&Xagt2R*){ng-HQ!xElsC%Tp;tfH1x2;;P{F|(U2bd#l~ zjfRelrPS0y_gZTC`dU`cy08dc3{e+DtcxM)Vu;;4RMSp0-8;l?8e%sM2{%!F9sadZ ze^spSYL@cP=WB6^b&C$kWN&9_Cri6I+hF%G7H)8$VnED|o7J$TGlFG}V1QeFKARrg^Hb$K1ssS;ckr4IG0XmT)WB z!@5{%osGH zgMFQyoLMNCsn9Xl-!?F4;VeQvB;=@XqKojhAcdO+4VoxH1yWR?WfLW+K#B^Qitb(u z-Z@H=DkRjB?@1te2ML=lYRd?;te&N6ICCG>q7su$(@J+Uf~+?BF%$og{#E=F`d3i{ Sn)aSHc1a-VszA +#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 0000000000000000000000000000000000000000..f05bc8623b1882c2f4747c22f37807943b8211d2 GIT binary patch literal 8562 zcmeI1X>gmx8OQ&xZXZdU%T^48w~Yunu#`B7b5IUNl5Kf(RZ`M4n7BS<5- zCqOw8?u4|Zr7chjEwm{;(oSb+`PL!fNT;PC9K+{+ECpJirRx7#S&9=RD^WbQr_+_^ zr{~%C*?o5R-F7Pw+mW zeIU|5U;_35{}kmz!AF9RrIh}hi8TC8)o`+g*{=&usdl^};+quf@D^#pzogu+W)c6U zWcWnX{|K@IX!OVg%}Br`Fbgb_XC)Tch`uU9uO?6EuWV{C-peU1SJmt= zP`r-Nt`}?*^ay$deS(CbUoarJfxu3|kRT~}yG0rnWCS-!-X4)|7U|1^uLy1te3iic zg0G1>BG@a~C%9E`o8Wc=Ul-{P!JVSsCAeGE1A==5_X!>pJR~?MI3zID5oUo!U=`Q| zO`4Y@c;U&Z?Sp4S=hn`R;b_1e@_IV`Ax~hF*9ZPhQgVH&4FUf~@NW{+3Qo^e&A>{{ zjOI0T+)QERiWR^rZSN$uqo}LZ+CnTV`XryZrmRIvS&Ox0E!LH_SYOs+Ls^R}%UXP{ zti@GjEv_zWaZOo^YdLYJI=QEQdU`b**Us9OwHyl{<#j99b0q<-Q{OZXSFzI*iJ(nw z71=D;Gc4R|uj)A1QH{UYFwz$FMb6yDr=xTIzEQr!^>$G+f> z=#EG<9E`+uhlffq*0w|%*GysQP07JNeVMaYKW7J%WcX568;PrfoO^gUv9ssKM5>hM zxH}ds^{kS7S8$8&+UnO`Vcjv&byw1!O3S>QMQ#K~yosL7z(DB{M7pn1C&kM-d|P}W zcW~0S`r@s)@Z47lL&zT!{rnwKauOoFixwB|u~5VR$`HPq)uJPb;bbP&o6tSUox4hp zV$@UU{e%dPiLP)$T6O-FoM0^U@7$G4rS-sIPpUgL*gaID7Jo1zhujHEj)|^t!diBI z75y8*(Tdcq`Th3S0O4dHcm(nZrX6CWYikU3ksC@l)9qmTZeK8u?uN_wd^=94;v2QYPO{>oGC3=Oa2DS85%hC&#ueYuNVtiLTo#uS4KFgQr z6{eYdS9PdiX&oB-^{5l@a7Z_^UqN4J6KgKajZwWqPrQ4=9L(h?@(u?E`Z`v{yB?ia zR7UX?47Np2_p6{+=xrY6qn_`Kw?t~rujiC(=XKNj^u;JkM}b1Wa(ac1Sge6_eE~S> zuvqnL4~O$O$I!<4(b2xCwUyrT>npEU>a7tMaR&0`V2SeejsfUrpI&6nmSF6Re&zH^ zJpq?+{$0v7#?^}&zAwgMm83?FS(n=>r}tdkIIUOaPse9CD>z`dLe2THzGQukIxEDe zQN1E(i#R7PW0cCLvA(+K!PD-JI>Q?~z<79uo-c47--~fM-xOcaXgb5!<~Dc49Z;?$ z_I8cY^Y-WSy_D~1xm-H$%k=l_dy=UggF^$%W7KlFsi~$cBh?sEZv<-^P!$j z>V1j+!J&knz9FFx4)rHFn>lr9FGps5IGxJ$rZcI;6?!7w>oiDYce${FF@xWFN2Ud{ zs~9pcXfaoPWIJX1jqR{4ZTq}!m2IBwJ?m@Mqt-*#-PVZJWp!BVt<}~~EZZ#4nS>oe(ez)z!0|alYRG#2Rg<~0bYWm36h!3 z5+fg;Fgrg!Vdf1g;>vdHR5Wowikb#wgIcPdnH0@9w!F5@qG&~9`;k_glB*P}@gkqr zDAp>@P@Jir&Qh#XoUQWbD9%+i&r_VQSg+Win9YjEvG%I@`BiJ@%#o%~v*w)+V0JE| z^*l~YqXtTI^3mLmMbmNo#%yeM#=L3xh6~%gozZ_9wohU~Q|`!P=N>g(TbMfl+PPm( z*B0iE!*X_++7>bjo)Iq#5nuf{CR3Cf zNob-dTZz;8sei9^wt7PGz<36paL6AP1KBu=)ewt&M}3sGi26fqyUY#6x%x z58!^>hkJ1k4?X*FH}1lnxC3bnBZY2!30*t}U5`#&hpqgKrXpADMY8hNMZe`<<-h(> BNUZ<> literal 0 HcmV?d00001 diff --git a/16/ted5/TED5.SYM b/16/ted5/TED5.SYM new file mode 100755 index 0000000000000000000000000000000000000000..6e4d3db864f081702a9d2b08f0eeee7026b03792 GIT binary patch literal 123418 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 literal 0 HcmV?d00001 diff --git a/16/ted5/_TOM.PIC b/16/ted5/_TOM.PIC new file mode 100755 index 0000000000000000000000000000000000000000..ad3b7a45b16fab280bc6a44dbe9b8f5b685681c3 GIT binary patch literal 32008 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