2634 lines
52 KiB
C++
2634 lines
52 KiB
C++
////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////
|
|
//
|
|
// 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;i<sizeof(COMENT);i++)
|
|
flag+=COMENT[i];
|
|
COMENT[sizeof(COMENT)-1]=(flag^0xff)+1;
|
|
|
|
if ((handle=open(filename,O_BINARY))==NULL)
|
|
return -1;
|
|
|
|
fsize=filelength(handle);
|
|
close(handle);
|
|
if (fsize>0x10000L) // 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<offset;i++)
|
|
flag+=*(dblock+i);
|
|
*(dblock+offset)=(flag^0xff)+1;
|
|
offset++;
|
|
|
|
|
|
////////////////////////////////////////////////////
|
|
//
|
|
// CREATE GROUP DEFINITION RECORD
|
|
//
|
|
switch(whichseg)
|
|
{
|
|
case DATA:
|
|
case CODE:
|
|
movedata(FP_SEG(&GRPDEF),FP_OFF(&GRPDEF),
|
|
(unsigned)dblock,offset,sizeof(GRPDEF));
|
|
offset+=sizeof(GRPDEF);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////
|
|
//
|
|
// CREATE PUBLIC DEFINITION RECORD
|
|
//
|
|
loffset=offset;
|
|
*(dblock+offset)=0x90; // PUBDEF ID
|
|
offset+=3; // point to public base, skip length
|
|
*(dblock+offset)=1; // group index=1
|
|
*(dblock+offset+1)=1; // segment index=1
|
|
offset+=2; // point to public name
|
|
|
|
temp=0;
|
|
movedata(FP_SEG(public),FP_OFF(public),
|
|
(unsigned)dblock,offset+1,strlen(public));
|
|
*(dblock+offset)=strlen(public);
|
|
offset+=strlen(public)+1;
|
|
*(int huge *)(dblock+offset)=0; // public offset within segment
|
|
offset+=2;
|
|
*(dblock+offset)=0; // type index
|
|
offset++;
|
|
|
|
// LENGTH
|
|
temp=offset-loffset-2;
|
|
*(int huge *)(dblock+loffset+1)=temp;
|
|
offset++;
|
|
|
|
// CHECKSUM
|
|
for (flag=0,i=loffset;i<offset;i++)
|
|
flag+=*(dblock+i);
|
|
*(dblock+offset)=(flag^0xff)+1;
|
|
|
|
|
|
////////////////////////////////////////////////////
|
|
//
|
|
// DATA RECORD(S). YUCK.
|
|
//
|
|
|
|
amtleft=fsize;
|
|
amount=1024;
|
|
for (i=0;i<(fsize+1023)/1024;i++)
|
|
{
|
|
offset1=offset;
|
|
if (amtleft<1024)
|
|
amount=amtleft;
|
|
//
|
|
// RECORD HEADER
|
|
//
|
|
*(dblock+offset)=0xa0; // LEDATA ID
|
|
*(int huge *)(dblock+offset+1)=amount+4; // length of record
|
|
offset+=3;
|
|
*(dblock+offset)=1; // segment index
|
|
*(int huge *)(dblock+offset+1)=i*1024; // index into segment
|
|
offset+=3;
|
|
//
|
|
// LOAD DATA IN
|
|
//
|
|
LoadFile(filename,(char huge *)dblock+offset,i*1024,amount);
|
|
offset+=amount;
|
|
//
|
|
// CHECKSUM!
|
|
//
|
|
for (flag=0,j=offset1;j<offset;j++)
|
|
flag+=*(dblock+j);
|
|
*(dblock+offset)=(flag^0xff)+1;
|
|
offset++;
|
|
|
|
amtleft-=1024;
|
|
}
|
|
|
|
////////////////////////////////////////////////////
|
|
//
|
|
// MODULE END! YES!
|
|
//
|
|
movedata(FP_SEG(&MODEND),FP_OFF(&MODEND),(unsigned)dblock,offset,sizeof(MODEND));
|
|
offset+=sizeof(MODEND);
|
|
|
|
//
|
|
// Save the little puppy out!
|
|
//
|
|
SaveFile(destfilename,(char huge *)dblock,0,offset);
|
|
MMFreePtr((memptr *)&dblock);
|
|
MMFreePtr((memptr *)&block);
|
|
return 0;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////
|
|
//
|
|
// DUMP THE PASTE BUFFER OUT TO EITHER AN
|
|
// "APPLE PREFERRED" OR "ILBM" GRAPHICS FORMAT FILE
|
|
//
|
|
// NOTE: THIS IS ONLY AVAILABLE IN EGA, BECAUSE I
|
|
// DON'T FEEL LIKE WRITING A CGA ILBM PIXEL-SPLICER --
|
|
// AND APPLE PREFERRED ONLY HANDLES 4-BIT COLOR ANYWAY!
|
|
// (YES, I KNOW, I COULD ONLY USE 4 OUT OF 16 COLORS...SHUT UP!)
|
|
//
|
|
////////////////////////////////////////////////////
|
|
btype dumpB[]={{" DeluxePaint II ILBM ",4,2,2},
|
|
{" Apple Preferred ",4,5,1}},
|
|
fnameB={" ",4,3,1};
|
|
DialogDef dumpD={" Which format do you require?",30,7,2,&dumpB[0],NULL},
|
|
fnameD={"Enter filename to\nsave (no suffix)",17,5,1,&fnameB,NULL};
|
|
|
|
void Item_GraphicDump(void)
|
|
{
|
|
char filename[14],ext[5],_seg *block,_seg *block1;
|
|
ApPrefStr PrefHeader;
|
|
int which,i,j,k,m,n,pwidth,lwidth,dx,dy;
|
|
long tilelen,fsize=0,bufsize;
|
|
|
|
if (!PasteOK)
|
|
{
|
|
ErrDialog("You need to use the Copy command\n"
|
|
"to copy part of the map or tiles\n"
|
|
"so I know what I need to dump!"," OK ");
|
|
return;
|
|
}
|
|
|
|
switch(videomode)
|
|
{
|
|
case CGA:
|
|
case VGA:
|
|
ErrDialog("Sorry, but this function is only\n"
|
|
"available for EGA mode. If you\n"
|
|
"have a REAL NEED for this to work\n"
|
|
"in CGA or VGA, talk to Id Software!"," OK ");
|
|
return;
|
|
}
|
|
|
|
if (!(which=DoDialog(&dumpD)))
|
|
return;
|
|
|
|
//
|
|
// SET TILE LENGTH
|
|
//
|
|
switch(tsize)
|
|
{
|
|
case 1: tilelen=32L; break;
|
|
case 2: tilelen=128L; break;
|
|
case 3: tilelen=512L;
|
|
}
|
|
|
|
//
|
|
// GET FILENAME TO SAVE UNDER
|
|
//
|
|
DrawDialog(&fnameD,1);
|
|
MouseHide();
|
|
GetButtonXY(&fnameD,0,&sx,&sy);
|
|
if (!input(filename,8))
|
|
{
|
|
RestoreBackground();
|
|
MouseShow();
|
|
return;
|
|
}
|
|
for (i=0;i<strlen(filename);i++)
|
|
if (filename[i]=='.')
|
|
{
|
|
filename[i]=0;
|
|
break;
|
|
}
|
|
RestoreBackground();
|
|
MouseShow();
|
|
|
|
//
|
|
// SETUP FOR EACH TYPE
|
|
//
|
|
switch(which)
|
|
{
|
|
case 1: // ILBM
|
|
{
|
|
long size;
|
|
char form[5]="FORM",ilbm[9]="ILBMBMHD",body[5]="BODY";
|
|
|
|
|
|
size=48L;
|
|
MMAllocate((memptr *)&block,size);
|
|
|
|
movedata(FP_SEG(form),FP_OFF(form),(unsigned)block,fsize,4);
|
|
fsize+=4;
|
|
size=40L+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;
|
|
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<<tsize);
|
|
for (i=0;i<(TileCopy.h<<(tsize+2));i++)
|
|
{
|
|
*(int huge *)(block+fsize)=pixwid+(pixwid+63)/64;
|
|
*(int huge *)(block+fsize+2)=0;
|
|
fsize+=4;
|
|
}
|
|
|
|
strcpy(ext,".APP");
|
|
MMAllocate((memptr *)&block1,tilelen*TileCopy.w);
|
|
}
|
|
}
|
|
|
|
//
|
|
// SAVE HEADER OUT
|
|
//
|
|
strcat(filename,ext);
|
|
SaveFile(filename,(char huge *)block,0,fsize);
|
|
MMFreePtr((memptr *)&block);
|
|
|
|
//
|
|
// NOW, WRITE THE DATA OUT! EEEE!
|
|
//
|
|
bufsize=tilelen*TileCopy.w;
|
|
MMAllocate((memptr *)&block,bufsize);
|
|
|
|
pwidth=(1<<(tsize-1))*TileCopy.w;
|
|
lwidth=pwidth*4;
|
|
|
|
ErrDialog("One moment. I am busy.\n Countdown:","");
|
|
dx=sx;
|
|
dy=sy;
|
|
|
|
for (j=0;j<TileCopy.h;j++)
|
|
{
|
|
sx=dx;
|
|
sy=dy;
|
|
printint(TileCopy.h-j);
|
|
print(" ");
|
|
|
|
for (i=0;i<TileCopy.w;i++)
|
|
{
|
|
unsigned tilet,tilem,tilei,loc;
|
|
|
|
//
|
|
// ESC out?
|
|
//
|
|
if (keydown[1])
|
|
{
|
|
RestoreBackground();
|
|
while(keydown[1]);
|
|
ErrDialog("You aborted out of the\n"
|
|
"graphic dump conversion!"," Yes, I know ");
|
|
|
|
if (which==2)
|
|
MMFreePtr((memptr *)&block1);
|
|
return;
|
|
}
|
|
//
|
|
// GET THE CORRECT TILE MOVED INTO "TDATA"
|
|
//
|
|
switch(TileCopy.MapOrTileSelect)
|
|
{
|
|
case 0: // MAP COPY
|
|
loc=(j+TileCopy.y)*mapwidth+TileCopy.x+i;
|
|
tilet=(TileCopy.PlanesCopied&BPLANE)?CutBkgnd[loc]:-BkgndColor;
|
|
tilem=(TileCopy.PlanesCopied&FPLANE)?CutFrgnd[loc]+tilenum:0;
|
|
tilei=(TileCopy.PlanesCopied&IPLANE)?CutInfoPl[loc]+tilenum:0;
|
|
CombineTiles(tilet,tilem,tilei,tsize);
|
|
break;
|
|
case 1: // BKGND TILE COPY
|
|
loc=(TileCopy.y+j)*selectcols+TileCopy.x+i;
|
|
CombineTiles(loc,0,0,tsize);
|
|
break;
|
|
case 2: // FRGND TILE COPY
|
|
loc=(TileCopy.y+j)*selectcols+TileCopy.x+i+tilenum;
|
|
CombineTiles(-BkgndColor,loc,0,tsize);
|
|
}
|
|
|
|
//
|
|
// NOW, MUNGE "TDATA" INTO BIT-PLANES!
|
|
//
|
|
// INTERNAL: P0 P1 P2 P3
|
|
// SCANLINE x ...... ...... ...... ......
|
|
//
|
|
for (k=0;k<8<<(tsize-1);k++)
|
|
for (m=0;m<4;m++)
|
|
movedata(FP_SEG(&tdata),FP_OFF(&tdata)+(m*tsize*(8<<(tsize-1)))+k*(1<<(tsize-1)),
|
|
(unsigned)block,k*lwidth+m*pwidth+i*(1<<(tsize-1)),1<<(tsize-1));
|
|
}
|
|
//
|
|
// ALRIGHT. NOW SAVE THIS CHUNK OUT IN THE CORRECT FORMAT
|
|
//
|
|
switch(which)
|
|
{
|
|
case 1: // ILBM
|
|
SaveFile(filename,MK_FP(block,0),fsize,bufsize);
|
|
fsize+=bufsize;
|
|
break;
|
|
case 2: // APPLE PREFERRED
|
|
{
|
|
int len,clen;
|
|
|
|
//
|
|
// FIRST, I NEED TO CONVERT THE ILBM PLANAR FORMAT
|
|
// TO SUPER-RES NIBBLES
|
|
//
|
|
for (k=0;k<8<<(tsize-1);k++)
|
|
for (m=0;m<(1<<(tsize-1))*TileCopy.w;m++)
|
|
{
|
|
unsigned char src[4],dest[4]={0,0,0,0};
|
|
|
|
for (n=0;n<4;n++)
|
|
src[n]=block[k*lwidth+pwidth*n+m];
|
|
|
|
asm mov al,[BYTE PTR src+0]
|
|
asm mov ah,[BYTE PTR src+1]
|
|
asm mov bl,[BYTE PTR src+2]
|
|
asm mov bh,[BYTE PTR src+3]
|
|
|
|
// dest[0]
|
|
asm shl bh,1
|
|
asm rcl cl,1
|
|
asm shl bl,1
|
|
asm rcl cl,1
|
|
asm shl ah,1
|
|
asm rcl cl,1
|
|
asm shl al,1
|
|
asm rcl cl,1
|
|
|
|
asm shl bh,1
|
|
asm rcl cl,1
|
|
asm shl bl,1
|
|
asm rcl cl,1
|
|
asm shl ah,1
|
|
asm rcl cl,1
|
|
asm shl al,1
|
|
asm rcl cl,1
|
|
|
|
// dest[1]
|
|
asm shl bh,1
|
|
asm rcl ch,1
|
|
asm shl bl,1
|
|
asm rcl ch,1
|
|
asm shl ah,1
|
|
asm rcl ch,1
|
|
asm shl al,1
|
|
asm rcl ch,1
|
|
|
|
asm shl bh,1
|
|
asm rcl ch,1
|
|
asm shl bl,1
|
|
asm rcl ch,1
|
|
asm shl ah,1
|
|
asm rcl ch,1
|
|
asm shl al,1
|
|
asm rcl ch,1
|
|
|
|
// dest[2]
|
|
asm shl bh,1
|
|
asm rcl dl,1
|
|
asm shl bl,1
|
|
asm rcl dl,1
|
|
asm shl ah,1
|
|
asm rcl dl,1
|
|
asm shl al,1
|
|
asm rcl dl,1
|
|
|
|
asm shl bh,1
|
|
asm rcl dl,1
|
|
asm shl bl,1
|
|
asm rcl dl,1
|
|
asm shl ah,1
|
|
asm rcl dl,1
|
|
asm shl al,1
|
|
asm rcl dl,1
|
|
|
|
// dest[3]
|
|
asm shl bh,1
|
|
asm rcl dh,1
|
|
asm shl bl,1
|
|
asm rcl dh,1
|
|
asm shl ah,1
|
|
asm rcl dh,1
|
|
asm shl al,1
|
|
asm rcl dh,1
|
|
|
|
asm shl bh,1
|
|
asm rcl dh,1
|
|
asm shl bl,1
|
|
asm rcl dh,1
|
|
asm shl ah,1
|
|
asm rcl dh,1
|
|
asm shl al,1
|
|
asm rcl dh,1
|
|
|
|
asm mov [BYTE PTR dest+0],cl
|
|
asm mov [BYTE PTR dest+1],ch
|
|
asm mov [BYTE PTR dest+2],dl
|
|
asm mov [BYTE PTR dest+3],dh
|
|
|
|
movedata(FP_SEG(&dest),FP_OFF(&dest),
|
|
(unsigned)block1,k*lwidth+m*4,4);
|
|
}
|
|
|
|
//
|
|
// NOW, TIME TO WRITE THE DATA OUT IN 64-BYTE CHUNKS! YUCK!
|
|
//
|
|
for (k=0;k<8<<(tsize-1);k++)
|
|
{
|
|
char clen;
|
|
int off=k*lwidth;;
|
|
|
|
len=4*pwidth;
|
|
while(len>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;i<height;i++)
|
|
{
|
|
sx=dialogx;
|
|
sy=(i<<(tsize-1))+4;
|
|
printhex(i+temp);
|
|
sx=dialogx;
|
|
sy++;
|
|
print(" ");
|
|
sx-=4;
|
|
printint(i+temp);
|
|
|
|
switch(thescreen)
|
|
{
|
|
case 0:
|
|
CombineTiles(temp+i,0,0,tsize);
|
|
break;
|
|
case 1:
|
|
CombineTiles(-BkgndColor,temp+i+tilenum,0,tsize);
|
|
}
|
|
|
|
DrawTile(dialogx+5,(i+2)<<(3+(tsize-1)),tsize);
|
|
}
|
|
|
|
//
|
|
// DRAW TILEINFO ARRAYS
|
|
//
|
|
width=4;
|
|
|
|
switch(thescreen)
|
|
{
|
|
case 0:
|
|
if (width>numtplanes)
|
|
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;j<width;j++)
|
|
{
|
|
sx=(dialogx+10)+j*7;
|
|
sy=3;
|
|
switch(thescreen)
|
|
{
|
|
case 0:
|
|
print(" ");
|
|
sx-=7;
|
|
fprint(MapFileHeader->tnames[j+TIxbase]);
|
|
break;
|
|
case 1:
|
|
print(" ");
|
|
sx-=7;
|
|
fprint(MapFileHeader->tmnames[j+TIxmbase]);
|
|
}
|
|
for (i=0;i<height;i++)
|
|
{
|
|
sx=(dialogx+10)+j*7;
|
|
sy=(i<<(tsize-1))+4;
|
|
print("$");
|
|
printhexb(Values[j+temp1][i+temp]);
|
|
sx=(dialogx+10)+j*7;
|
|
sy++;
|
|
print(" ");
|
|
sx-=3;
|
|
printint(Values[j+temp1][i+temp]&0xff);
|
|
}
|
|
}
|
|
MouseShow();
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////
|
|
//
|
|
// Item - Add or Delete TILEINFO/M planes
|
|
//
|
|
////////////////////////////////////////////////////
|
|
btype AODb[]={{" Add ",1,3,1},
|
|
{" Delete ",8,3,1},
|
|
{" Exit ",18,3,2}},
|
|
TOMb[]={{" Tileinfo ",1,2,1},
|
|
{" TileinfoM ",1,5,1}},
|
|
AreSureB2[]={{" Yes ",1,2,1},
|
|
{" No ",8,2,2}},
|
|
TINb2={" Done ",8,15,1};;
|
|
DialogDef AODd={" TILEINFO/M\n Pick a function",25,5,3,&AODb[0],NULL},
|
|
TOMd={"Add to what?",13,7,2,&TOMb[0],NULL},
|
|
NId={"Gimme a name!",13,4,0,NULL,NULL},
|
|
AreSureD2={"Are you sure?",13,4,2,&AreSureB2[0],NULL},
|
|
TINd2={" Which to delete?\n"
|
|
" TILEINFO TILEINFOM",
|
|
22,17,1,&TINb2,NULL};
|
|
|
|
void Item_AddDelTinfo(void)
|
|
{
|
|
char temp[16];
|
|
int which,i;
|
|
unsigned dx,dy;
|
|
|
|
while(1)
|
|
{
|
|
which=DoDialog(&AODd);
|
|
switch(which)
|
|
{
|
|
case 0: // ESC or EXIT
|
|
case 3:
|
|
return;
|
|
//
|
|
// ADD
|
|
//
|
|
case 1:
|
|
which=DoDialog(&TOMd);
|
|
if (!which)
|
|
break;
|
|
|
|
switch(which)
|
|
{
|
|
case 1:
|
|
if (numtplanes==10)
|
|
{
|
|
ErrDialog("You already have 10 TILEINFO\n"
|
|
"planes defined!"," OK ");
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
if (!tilemnum)
|
|
{
|
|
ErrDialog("You crazy shit! You don't\n"
|
|
"have any masked tiles!"," Duh! ");
|
|
return;
|
|
}
|
|
|
|
if (numtmplanes==10)
|
|
{
|
|
ErrDialog("You already have 10 TILEINFOM\n"
|
|
"planes defined!"," OK ");
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
|
|
DrawDialog(&NId,1);
|
|
MouseHide();
|
|
GetDialogXY(&NId,&dx,&dy);
|
|
sx=dx+1;
|
|
sy=dy+1;
|
|
DrawBorder(sx,sy,9,2,1);
|
|
sx=dx+2;
|
|
sy=dy+2;
|
|
if (!input(temp,7))
|
|
{
|
|
RestoreBackground();
|
|
MouseShow();
|
|
break;
|
|
}
|
|
|
|
//
|
|
// MOVE THE NAME AND ALLOCATE THE MEMORY!
|
|
//
|
|
switch(which)
|
|
{
|
|
case 1:
|
|
movedata(FP_SEG(temp),FP_OFF(temp),
|
|
(unsigned)MapFileHeader,FP_OFF(MapFileHeader->tnames[numtplanes]),8);
|
|
MMAllocate((memptr *)&Tinfo[numtplanes],tilenum);
|
|
for (i=0;i<tilenum;i++)
|
|
*(Tinfo[numtplanes]+i)=0;
|
|
MapFileHeader->numtplanes=++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;i<tilemnum;i++)
|
|
*(TMinfo[numtmplanes]+i)=0;
|
|
MapFileHeader->numtmplanes=++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;i<tilenum;i++)
|
|
*(Tinfo[which]+i)=*(Tinfo[numtplanes-1]+i);
|
|
MMFreePtr((memptr *)&Tinfo[numtplanes-1]);
|
|
}
|
|
else
|
|
{
|
|
MMFreePtr((memptr *)&Tinfo[which]);
|
|
for (i=0;i<8;i++)
|
|
MapFileHeader->tnames[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;i<tilemnum;i++)
|
|
*(TMinfo[which]+i)=*(TMinfo[numtmplanes-1]+i);
|
|
MMFreePtr((memptr *)&TMinfo[numtmplanes-1]);
|
|
}
|
|
else
|
|
{
|
|
MMFreePtr((memptr *)&TMinfo[which]);
|
|
for (i=0;i<8;i++)
|
|
MapFileHeader->tmnames[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<numtplanes;i++)
|
|
if (Tinfo[i])
|
|
MMFreePtr((memptr *)&Tinfo[i]);
|
|
for (i=0;i<numtmplanes;i++)
|
|
if (TMinfo[i])
|
|
MMFreePtr((memptr *)&TMinfo[i]);
|
|
|
|
//
|
|
// FORCE RE-INIT
|
|
//
|
|
writeH=TIxbase=TIxmbase=TIybase=TIymbase=PasteOK=DirtyFlag=ext[0]=0;
|
|
lastmap=-1;
|
|
|
|
FindGraphFile();
|
|
LoadInfoFile();
|
|
LoadMapHeader();
|
|
LoadGraphStuff(0,videomode);
|
|
MouseHide();
|
|
RedrawDesktop();
|
|
MouseShow();
|
|
DrawInfoBar();
|
|
DrawMap();
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////
|
|
//
|
|
// Item - Toggle GRIDMODE on/off
|
|
//
|
|
////////////////////////////////////////////////////
|
|
void Item_GridMode(void)
|
|
{
|
|
GridMode^=1;
|
|
|
|
if (PasteMode)
|
|
DrawFloatPaste();
|
|
|
|
DrawMap();
|
|
DrawInfoBar();
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////
|
|
//
|
|
// Item - Toggle SNAP-PASTE on/off
|
|
//
|
|
////////////////////////////////////////////////////
|
|
void Item_SnapTog(void)
|
|
{
|
|
if (!PasteMode)
|
|
return;
|
|
|
|
EraseFloatPaste();
|
|
SnapMode^=1;
|
|
|
|
snapx=(pixelx>>(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<screenh && bl_width<screenw)
|
|
{
|
|
ErrDialog("The area fits within the\n"
|
|
"screen! Forget it!"," Wah! ");
|
|
return;
|
|
}
|
|
|
|
|
|
//
|
|
// FIGURE OUT THE BEST RATIO FOR CONVERSION
|
|
//
|
|
if (!how)
|
|
switch(bl_width>=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<scrn_h)
|
|
break;
|
|
|
|
case 0: // HEIGHT > 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<bl_y+bl_height;j++)
|
|
{
|
|
lybase=j*t8;
|
|
for (i=bl_x;i<bl_x+bl_width;i++)
|
|
{
|
|
unsigned tilet,tilem,tilei,loc;
|
|
|
|
//
|
|
// ESC out?
|
|
//
|
|
if (keydown[1])
|
|
{
|
|
while(keydown[1]);
|
|
setvideo(savevideo);
|
|
RedrawDesktop();
|
|
DrawMap();
|
|
DrawInfoBar();
|
|
return;
|
|
}
|
|
//
|
|
// GET THE CORRECT TILE MOVED INTO "TDATA"
|
|
//
|
|
loc=j*mapwidth+i;
|
|
tilet=viewton?((p_info&BPLANE)?a_bg[loc]:-BkgndColor):-BkgndColor;
|
|
tilem=viewmon?((p_info&FPLANE)?a_fg[loc]+tilenum:0):0;
|
|
tilei=viewion?((p_info&IPLANE)?a_in[loc]+tilenum:0):0;
|
|
CombineTiles(tilet,tilem,tilei,tsize);
|
|
|
|
//
|
|
// NOW, MUNGE "TDATA" INTO BIT-PLANES!
|
|
//
|
|
// INTERNAL: P0 P1 P2 P3
|
|
// SCANLINE x ...... ...... ...... ......
|
|
//
|
|
for (k=0;k<t8;k++)
|
|
if (!((lybase+k)%step))
|
|
for (m=0;m<4;m++)
|
|
movedata(FP_SEG(&tdata),FP_OFF(&tdata)+(m*tsize*t8)+k*t1,
|
|
(unsigned)block,k*lwidth+m*pwidth+(i-bl_x)*t1,t1);
|
|
}
|
|
|
|
//
|
|
// CONVERT BIT-PLANE LINES TO COMPRESSED FORM...
|
|
//
|
|
for (k=0;k<8<<(tsize-1);k++)
|
|
{
|
|
if (!((lybase+k)%step))
|
|
{
|
|
int midx=k*lwidth;
|
|
|
|
|
|
curpix=0;
|
|
_fmemset(gblock[0],0,maxpack);
|
|
_fmemset(gblock[1],0,maxpack);
|
|
_fmemset(gblock[2],0,maxpack);
|
|
_fmemset(gblock[3],0,maxpack);
|
|
for (m=0;m<pwidth*8;m++)
|
|
{
|
|
if (!(m%step))
|
|
{
|
|
int temp=curpix/8,
|
|
temp1=7-(curpix%8),
|
|
temp2=7-(m%8),
|
|
idx;
|
|
|
|
|
|
idx=midx+m/8;
|
|
|
|
#if 1
|
|
asm push ds
|
|
|
|
asm mov ds,[block]
|
|
asm mov si,[idx]
|
|
asm mov cl,[BYTE PTR temp2]
|
|
asm mov ch,[BYTE PTR temp1]
|
|
asm mov di,[temp]
|
|
asm mov dx,[pwidth]
|
|
asm dec dx
|
|
|
|
asm mov es,[WORD PTR gblock]
|
|
|
|
asm lodsb
|
|
asm shr al,cl
|
|
asm and al,1
|
|
asm xchg ch,cl
|
|
asm shl al,cl
|
|
asm xchg ch,cl
|
|
asm or [es:di],al
|
|
|
|
asm add si,dx
|
|
|
|
asm mov es,[WORD PTR gblock+2]
|
|
|
|
asm lodsb
|
|
asm shr al,cl
|
|
asm and al,1
|
|
asm xchg ch,cl
|
|
asm shl al,cl
|
|
asm xchg ch,cl
|
|
asm or [es:di],al
|
|
|
|
asm add si,dx
|
|
|
|
asm mov es,[WORD PTR gblock+4]
|
|
|
|
asm lodsb
|
|
asm shr al,cl
|
|
asm and al,1
|
|
asm xchg ch,cl
|
|
asm shl al,cl
|
|
asm xchg ch,cl
|
|
asm or [es:di],al
|
|
|
|
asm add si,dx
|
|
|
|
asm mov es,[WORD PTR gblock+6]
|
|
|
|
asm lodsb
|
|
asm shr al,cl
|
|
asm and al,1
|
|
asm xchg ch,cl
|
|
asm shl al,cl
|
|
asm xchg ch,cl
|
|
asm or [es:di],al
|
|
|
|
asm add si,dx
|
|
|
|
asm pop ds
|
|
|
|
#else
|
|
*(gblock[0]+temp)|=((block[idx]>>temp2)&1)<<temp1;
|
|
*(gblock[1]+temp)|=((block[idx+pwidth]>>temp2)&1)<<temp1;
|
|
*(gblock[2]+temp)|=((block[idx+pwidth*2]>>temp2)&1)<<temp1;
|
|
*(gblock[3]+temp)|=((block[idx+pwidth*3]>>temp2)&1)<<temp1;
|
|
#endif
|
|
|
|
curpix++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// BLAST ONTO THE SCREEN
|
|
//
|
|
|
|
MouseHide();
|
|
for (n=0;n<4;n++)
|
|
{
|
|
outport(SCindex,SCmapmask | (0x100<<n));
|
|
for (m=0;m<maxpack;m++)
|
|
*(EGA+EGA1lookup[curline]+m)=*(gblock[n]+m);
|
|
}
|
|
MouseShow();
|
|
|
|
curline++;
|
|
}
|
|
}
|
|
}
|
|
|
|
MMFreePtr((memptr *)&block);
|
|
for(m=0;m<4;m++)
|
|
MMFreePtr((memptr *)&gblock[m]);
|
|
|
|
|
|
//
|
|
// SAVE MAP IN MEMORY!
|
|
//
|
|
if (!CopyArea)
|
|
{
|
|
unsigned EGAseg=0xa800;
|
|
|
|
|
|
MouseHide();
|
|
outport(GCindex,GCmode | 0x100);
|
|
outport(SCindex,SCmapmask | 0xf00);
|
|
asm push ds
|
|
asm mov ax,[EGAseg]
|
|
asm mov es,ax
|
|
asm mov ax,0xa000
|
|
asm mov ds,ax
|
|
asm xor si,si
|
|
asm xor di,di
|
|
asm mov cx,0x2000
|
|
asm rep movsb
|
|
asm pop ds
|
|
VMapData.step=step;
|
|
VMapData.built_flag=1;
|
|
VMapData.EGAseg=EGAseg;
|
|
VMapData.maxpack=maxpack;
|
|
MouseShow();
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// DONE WITH MAP BUILD-N-DISPLAY
|
|
//
|
|
SignalSound();
|
|
clearkeys();
|
|
|
|
//
|
|
// IF MOUSE BUTTON PRESSED WITHIN REGION, GO THERE!
|
|
//
|
|
while(!bioskey(1))
|
|
if (MouseButton())
|
|
{
|
|
int x,y;
|
|
|
|
MouseCoords(&x,&y);
|
|
if (x<maxpack*8 && y<(mapheight*t8/step) && !CopyArea)
|
|
{
|
|
xbase=(x*step)/t8-screenw/2;
|
|
ybase=(y*step)/t8-screenh/2;
|
|
if (xbase+screenw>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;i<numtplanes;i++)
|
|
{
|
|
MMAllocate(&block,tilenum);
|
|
MapFileHeader->tileinfooff[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;i<numtmplanes;i++)
|
|
{
|
|
MMAllocate(&block,tilemnum);
|
|
MapFileHeader->tileinfomoff[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()<size)
|
|
{
|
|
XMSFreeMem(CgaXMS);
|
|
TEDInfo->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()<size)
|
|
{
|
|
XMSFreeMem(EgaXMS);
|
|
TEDInfo->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()<size)
|
|
{
|
|
XMSFreeMem(VgaXMS);
|
|
TEDInfo->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();
|
|
}
|
|
}
|