greed/MEDIT/MEDIT.C
2014-12-12 00:00:00 +00:00

1631 lines
34 KiB
C

/****************************************************************************/
/* */
/* Layer Editor for Greed I */
/* */
/* Copyright(C) 1995 by Robert Morgan of Channel 7 */
/* */
/****************************************************************************/
#include <STDIO.H>
#include <DOS.H>
#include <STDARG.H>
#include <STRING.H>
#include <STDLIB.H>
#include <CONIO.H>
/**** CONSTANTS ****/
#define VERSION "1.017"
#define NUMLAYERS 18
#define XMAX 64
#define YMAX 64
#define TEXTMODE 0x03
#define VGAMODE 0x13
#define PEL_WRITE_ADR 0x3c8
#define PEL_READ_ADR 0x3c7
#define PEL_DATA 0x3c9
#define SCREEN 0xA000
#define SCREENWIDTH 320
#define SCREENHEIGHT 200
#define OUTBYTE(x,y) (outp((unsigned)(x),(unsigned)(y)))
#define OUTWORD(x,y) (outpw((unsigned)(x),(unsigned)(y)))
#define INBYTE(x) (inp((unsigned)(x)))
#define INWORD(x) (inpw((unsigned)(x)))
#define CLI _disable()
#define STI _enable()
#define MAXFONTCHARS 94
#define FONTWIDTH 5
#define TEXTCOLOR 5
#define BUFX 190
#define BUFY 190
/* text modes */
#define TEXT_NORMAL 0
#define TEXT_NOOVERWRITE 1
#define TEXT_CENTER 2
/* flags */
#define F_RIGHT (1<<0)
#define F_LEFT (1<<1)
#define F_UP (1<<2)
#define F_DOWN (1<<3)
#define F_TRANSPARENT (1<<4)
#define F_NOCLIP (1<<5)
#define F_NOBULLETCLIP (1<<6)
#define F_DAMAGE (1<<7)
/* layer names */
#define NORTHWALL 0
#define NORTHFLAGS 1
#define WESTWALL 2
#define WESTFLAGS 3
#define FLOOR 4
#define FLOORFLAGS 5
#define CEILING 6
#define CEILINGFLAGS 7
#define FLOORHEIGHT 8
#define CEILINGHEIGHT 9
#define FLOORDEF 10
#define FLOORDEFFLAGS 11
#define CEILINGDEF 12
#define CEILINGDEFFLAGS 13
#define LIGHTS 14
#define EFFECTS 15
#define SPRITES 16
#define SLOPES 17
char *layernames[NUMLAYERS]=
{
"NORTHWALL ",
"",
"WESTWALL ",
"",
"FLOOR ",
"",
"CEILING ",
"",
"FLOORHEIGHT ",
"CEILINGHEIGHT",
"FLOORDEF ",
"",
"CEILINGDEF ",
"",
"LIGHTS ",
"EFFECTS ",
"SPRITES ",
"SLOPES "
};
/**** TYPES ****/
typedef unsigned char byte;
typedef byte layerdata_t;
typedef layerdata_t layer_t[YMAX][XMAX];
typedef enum {false,true} boolean;
typedef short word;
typedef unsigned long longint;
/* CPR file format header */
typedef struct
{
int signature;
byte version;
int width, height;
byte flags, headersize;
byte indicator;
int orgx, orgy;
} CPR_HEADER;
/* FON character */
typedef struct
{
byte width;
word lines[16];
} fontchartype;
/* FON file format header */
typedef struct
{
char signature[4];
int height;
int asciistart;
int nchars;
fontchartype fontchar[MAXFONTCHARS];
} fonttype;
/**** VARIABLES ****/
layer_t far *layers[NUMLAYERS]; // map layers
char filename[13], printstr[128];
boolean quit, messageready;
byte colors[768];
byte far *screen, *ylookup[SCREENHEIGHT], buffer[BUFY][BUFX],
*bufylookup[BUFY];
fonttype font;
int tcolor, bkcolor, fontmode, fontavgwidth, currentvalue[NUMLAYERS],
currentx, currenty, currentlayer;
/**** FUNCTIONS ****/
/* protos */
void Error(char *error,...);
void ReadFile(char *filename,word length,void *buffer);
/* GRAPHICS *****************************************************************/
void SetPalette(byte *palette)
{
int i;
while (inp(0x3da) & 0x08) ;
while (!(inp(0x3da) & 0x08)) ;
while (!(inp(0x3da) & 0x01)) ;
OUTBYTE(PEL_WRITE_ADR,0);
for (i=0;i<768;i++)
OUTBYTE(PEL_DATA,*palette++);
}
void FillPalette(int red, int green, int blue)
{
int i;
while (inp(0x3da) & 0x08) ;
while (!(inp(0x3da) & 0x08)) ;
while (!(inp(0x3da) & 0x01)) ;
OUTBYTE(PEL_WRITE_ADR,0);
for (i=0;i<256;i++)
{
OUTBYTE(PEL_DATA,red);
OUTBYTE(PEL_DATA,green);
OUTBYTE(PEL_DATA,blue);
}
}
void LoadCPR(char *s)
{
int x, y, i, data, count, orgx, orgy, indicator;
char str1[14];
FILE *f;
CPR_HEADER h;
byte far *t;
FillPalette(0,0,0);
f=fopen(s,"rb");
if (f==NULL)
Error("%s not found");
if (!fread(&h,sizeof(CPR_HEADER),1,f) ||
h.signature!=19794 || fseek(f,h.headersize,0) ||
((h.flags & 1) && !fread(colors,768,1,f)))
Error("Error reading %s");
if (h.version==4)
{
indicator=255;
orgx=0;
orgy=0;
}
else if (h.version==5)
{
indicator=h.indicator;
orgx=h.orgx;
orgy=h.orgy;
memset(screen,0,SCREENHEIGHT*SCREENWIDTH);
}
else Error("Invalid %s CPR file version",s);
y=orgy;
x=orgx;
t=ylookup[y]+x;
while (y<h.height)
{
data=fgetc(f);
if (data==indicator)
{
count=fgetc(f);
data=fgetc(f);
for (i=0;i<count;i++)
{
*t++=data;
++x;
if (x==h.width)
{
x=orgx;
++y;
t=ylookup[y]+x;
}
}
}
else if (data>=0)
{
*t++=data;
++x;
if (x==h.width)
{
x=orgx;
++y;
t=ylookup[y]+x;
}
}
else Error("%s corrupted",s);
}
fclose(f);
SetPalette(colors);
}
void LoadFON(char *s,int setwidth)
{
ReadFile(s,sizeof(fonttype),&font);
fontavgwidth=setwidth;
}
int FontStrLen(char *s)
{
int i, j, result;
i=0;
result=0;
j=font.asciistart;
while (s[i])
{
result+=font.fontchar[s[i]-j].width;
++i;
}
return result;
}
void PrintXY(int x1,int y1,char *s)
{
int i, h, j, k, width, lines;
int x, y, l, letter;
fontchartype *f;
byte *dest;
if (fontmode & TEXT_CENTER)
{
i=FontStrLen(s)>>1;
x1-=i;
}
l=strlen(s);
x=x1;
h=font.height;
for (k=0; k<l; k++)
{
y=y1;
letter=s[k]-font.asciistart;
f=&font.fontchar[letter];
width=f->width;
for (i=0;i<h;i++,y++)
{
lines=f->lines[i];
dest=ylookup[y]+x;
for (j=0;j<width;j++,dest++)
{
if (lines & (1<<j))
*dest=tcolor;
else if (bkcolor!=255)
*dest=bkcolor;
}
}
x+=width;
}
width=l*fontavgwidth+x1;
if (!(fontmode & TEXT_NOOVERWRITE) && x<width && bkcolor!=255)
{
y=y1;
width=width-x+1;
dest=ylookup[y]+x;
for (i=0;i<h;i++,y++,dest+=320)
memset(dest,bkcolor,width);
}
}
void PrintfXY(int x,int y,char *sfmt,...)
{
va_list argptr;
va_start(argptr,sfmt);
vsprintf(printstr,sfmt,argptr);
va_end(argptr);
PrintXY(x,y,printstr);
}
/* MISC & ERROR *************************************************************/
void SetVidMode(int mode)
{
union REGS r;
r.x.ax=mode;
int86(0x10,&r,&r);
}
void Error(char *error,...)
{
va_list argptr;
byte far *vidmode;
vidmode=MK_FP(0x40,0x49);
if (*vidmode!=TEXTMODE)
SetVidMode(TEXTMODE);
printf("Error: ");
va_start(argptr,error);
vprintf(error,argptr);
va_end(argptr);
while (kbhit())
getch();
exit(255);
}
word ReadKey(void)
{
union REGS r;
r.h.ah=0x10;
int86(0x16,&r,&r);
return r.x.ax;
}
void DeleteMessage(void)
{
int i;
for (i=193;i<200;i++)
memset(ylookup[i]+201,0,119);
messageready=false;
}
void Message(char *error,...)
{
va_list argptr;
char s[40];
if (messageready) DeleteMessage();
va_start(argptr,error);
vsprintf(s,error,argptr);
PrintXY(201,193,s);
messageready=true;
va_end(argptr);
}
boolean AskQuestion(char *s)
{
int ans, c;
boolean result;
Message(s);
ans=ReadKey();
c=ans & 255;
if (c=='Y' || c=='y')
result=true;
else
result=false;
while (kbhit())
getch();
DeleteMessage();
return result;
}
boolean AskFileName(char *s,char *name)
{
char str[40];
int cursor, cindex, c, ans;
strcpy(str,s);
strcat(str,name);
cindex=strlen(s);
cursor=strlen(str)-1;
while (cursor>cindex && str[cursor]==' ')
--cursor;
++cursor;
while (1)
{
DeleteMessage();
str[cursor]='_';
Message(str);
ans=ReadKey();
c=ans & 255;
switch (c)
{
case 0x00:
case 0xE0:
c=(word)ans>>8;
switch (c)
{
case 75:
case 83:
if (cursor>cindex)
{
str[cursor]=' ';
--cursor;
str[cursor]='_';
}
break;
default:
break;
}
break;
case 8:
if (cursor>cindex)
{
str[cursor]=' ';
--cursor;
str[cursor]='_';
}
break;
case 13:
str[cursor]=' ';
strcpy(name,&str[strlen(s)]);
DeleteMessage();
return true;
case 27:
DeleteMessage();
return false;
default:
str[cursor]=c;
if (cursor-cindex<12)
cursor++;
str[cursor]='_';
break;
}
}
}
/* CONVERSION ***************************************************************/
void Convert1(char *s)
{
FILE *f;
int result, dest, source, i, j;
layer_t *l[4];
if (stricmp(s,"IGNORE")==0) return;
for (i=0;i<4;i++)
{
l[i]=(layer_t*)malloc(sizeof(layer_t));
if (l[i]==NULL) Error("Out of memory in Convert");
memset(l[i],0,sizeof(layer_t));
}
f=fopen(s,"rt");
if (f==NULL) Error("Error loading %s",s);
do
{
result=fscanf(f,"%i %i\n",&dest,&source);
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
if ((*layers[NORTHWALL])[i][j]==source && !(*l[0])[i][j])
{
(*layers[NORTHWALL])[i][j]=dest;
(*l[0])[i][j]=1;
}
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
if ((*layers[WESTWALL])[i][j]==source && !(*l[1])[i][j])
{
(*layers[WESTWALL])[i][j]=dest;
(*l[1])[i][j]=1;
}
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
if ((*layers[FLOORDEF])[i][j]==source && !(*l[2])[i][j])
{
(*layers[FLOORDEF])[i][j]=dest;
(*l[2])[i][j]=1;
}
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
if ((*layers[CEILINGDEF])[i][j]==source && !(*l[3])[i][j])
{
(*layers[CEILINGDEF])[i][j]=dest;
(*l[3])[i][j]=1;
}
} while (result==2);
fclose(f);
for (i=0;i<4;i++)
free(l);
}
void Convert2(char *s)
{
FILE *f;
int result, dest, source, i, j;
layer_t *l[4];
if (stricmp(s,"IGNORE")==0) return;
for (i=0;i<4;i++)
{
l[i]=(layer_t*)malloc(sizeof(layer_t));
if (l[i]==NULL) Error("Out of memory in Convert");
memset(l[i],0,sizeof(layer_t));
}
f=fopen(s,"rt");
if (f==NULL) Error("Error loading %s",s);
do
{
result=fscanf(f,"%i %i\n",&dest,&source);
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
if ((*layers[FLOOR])[i][j]==source && !(*l[0])[i][j])
{
(*layers[FLOOR])[i][j]=dest;
(*l[0])[i][j]=1;
}
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
if ((*layers[CEILING])[i][j]==source && !(*l[1])[i][j])
{
(*layers[CEILING])[i][j]=dest;
(*l[1])[i][j]=1;
}
} while (result==2);
fclose(f);
for (i=0;i<4;i++)
free(l);
}
void InitMEDIT(void)
{
int i;
/* initialize graphical data */
screen=MK_FP(0xA000,0);
for (i=0;i<SCREENHEIGHT;i++)
ylookup[i]=screen+i*SCREENWIDTH;
for (i=0;i<BUFY;i++)
bufylookup[i]=buffer[i];
/* init font info */
tcolor=TEXTCOLOR;
bkcolor=0;
/* init cursor info */
currentx=31;
currenty=31;
memset(currentvalue,0,sizeof(currentvalue));
currentlayer=0;
/* init layers */
for (i=0;i<NUMLAYERS;i++)
{
layers[i]=(layer_t*)malloc(sizeof(layer_t));
if (layers[i]==NULL)
Error("Out of memory for layers");
}
}
long getlong(FILE *f)
{
long l;
fread(&l,4,1,f);
return l;
}
void ConvertLVL(char *s)
{
FILE *f;
long l;
int i, j;
byte flags;
f=fopen(s,"rb");
if (f==NULL) Error("Error opening %s",s);
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
{
l=getlong(f);
(*layers[WESTWALL])[i][j]=l&255;
l>>=8;
flags=0;
if (l & 0x1)
flags|=F_TRANSPARENT;
if (l & 0x2)
flags|=F_NOCLIP;
if (l & 0x4)
flags|=F_LEFT;
if (l & 0x8)
flags|=F_RIGHT;
if (l & 0x10)
flags|=F_NOBULLETCLIP;
(*layers[WESTFLAGS])[i][j]=flags;
}
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
{
l=getlong(f);
(*layers[NORTHWALL])[i][j]=l&255;
l>>=8;
flags=0;
if (l & 0x1)
flags|=F_TRANSPARENT;
if (l & 0x2)
flags|=F_NOCLIP;
if (l & 0x4)
flags|=F_LEFT;
if (l & 0x8)
flags|=F_RIGHT;
if (l & 0x10)
flags|=F_NOBULLETCLIP;
(*layers[NORTHFLAGS])[i][j]=flags;
}
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
{
l=getlong(f);
(*layers[FLOOR])[i][j]=l&255;
l>>=8;
flags=0;
(*layers[FLOORFLAGS])[i][j]=flags;
}
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
{
l=getlong(f);
(*layers[CEILING])[i][j]=l&255;
l>>=8;
flags=0;
if (l & 0x1)
flags|=F_TRANSPARENT;
(*layers[CEILINGFLAGS])[i][j]=flags;
}
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
(*layers[FLOORHEIGHT])[i][j]=fgetc(f);
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
(*layers[CEILINGHEIGHT])[i][j]=fgetc(f);
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
{
l=getlong(f);
(*layers[FLOORDEF])[i][j]=l&255;
}
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
{
l=getlong(f);
(*layers[CEILINGDEF])[i][j]=l&255;
}
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
(*layers[LIGHTS])[i][j]=fgetc(f);
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
{
l=getlong(f);
(*layers[SPRITES])[i][j]=l&255;
}
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
{
l=getlong(f);
l&=255;
if (l<32)
(*layers[EFFECTS])[i][j]=l;
else
(*layers[SLOPES])[i][j]=l;
}
fclose(f);
}
void CreateNewLAY(void)
{
int i, j;
for (i=0;i<NUMLAYERS;i++)
memset(layers[i],0,sizeof(layer_t));
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
(*layers[CEILINGHEIGHT])[i][j]=255;
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
(*layers[LIGHTS])[i][j]=63;
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
(*layers[CEILINGDEF])[i][j]=1;
for (i=0;i<YMAX;i++)
for (j=0;j<XMAX;j++)
(*layers[FLOORDEF])[i][j]=1;
}
/* DISK IO ******************************************************************/
void ReadLevel(char *s)
{
FILE *f;
int i, result;
char fname[20];
strcpy(fname,s);
/* upcase the string */
i=0;
while (fname[i]!=0)
{
if (fname[i]>='a' && fname[i]<='z')
fname[i]+='A'-'a';
i++;
}
/* find filename extention */
i=0;
while (fname[i]!=0 && fname[i]!='.') i++;
if (fname[i]==0)
strcat(fname,".LAY"); // assume new file format
else if (strcmp(&fname[i],".LVL")==0) // old file format
{
CreateNewLAY();
ConvertLVL(fname);
strcpy(&fname[i],".LAY");
sprintf(filename,"%-13s",fname);
PrintfXY(233,10,filename);
return;
}
sprintf(filename,"%-13s",fname);
PrintfXY(233,10,filename);
/* open and read */
f=fopen(fname,"rb+");
if (f==NULL)
{
CreateNewLAY();
return;
}
for (i=0;i<NUMLAYERS;i++)
if (!fread(layers[i],sizeof(layer_t),1,f))
Error("Reading %s, layer %i",fname,i);
fclose(f);
}
void ReadFile(char *filename,word length,void *buffer)
{
FILE *f;
f=fopen(filename,"rb");
if (f==NULL)
Error("Error opening %s",filename);
if (fread(buffer,length,1,f)==0)
Error("Error reading %s",filename);
fclose(f);
}
void SaveLAYFile(void)
{
int i;
FILE *f;
if (!AskFileName("Save: ",filename))
return;
i=0;
while (filename[i]!=0)
{
if (filename[i]>='a' && filename[i]<='z')
filename[i]+='A'-'a';
i++;
}
PrintfXY(233,10,filename);
f=fopen(filename,"wb");
if (f==NULL)
Error("Error saving %s",filename);
for (i=0;i<NUMLAYERS;i++)
if (!fwrite(layers[i],sizeof(layer_t),1,f))
Error("Error writing %s",filename);
fclose(f);
Message("File Saved");
}
void LoadLAYFile(void)
{
int i;
FILE *f;
if (!AskFileName("Load: ",filename))
return;
i=0;
while (filename[i]!=0)
{
if (filename[i]>='a' && filename[i]<='z')
filename[i]+='A'-'a';
i++;
}
PrintfXY(233,10,filename);
f=fopen(filename,"rb");
if (f==NULL)
Message("%s not found",filename);
for (i=0;i<NUMLAYERS;i++)
if (!fread(layers[i],sizeof(layer_t),1,f))
Error("Error reading %s",filename);
fclose(f);
Message("File Loaded");
}
/* Buffer Functions *********************************************************/
void BlitBuffer(void)
{
int i;
for (i=0;i<BUFY;i++)
memcpy(ylookup[i+5]+5,bufylookup[i],BUFY);
}
void ResetBuffer(void)
{
int i, j;
memset(buffer,0,sizeof(buffer));
for (i=0;i<BUFY;i+=10)
memset(bufylookup[i],1,BUFX);
for (j=0;j<BUFX;j+=10)
for (i=0;i<BUFY;i++)
*(bufylookup[i]+j)=1;
}
void DrawBuffer(void)
{
int tilex, tiley, color, x, y, i, j, upper, lower, cw, ch;
ResetBuffer();
y=0;
switch (currentlayer)
{
case FLOORDEF:
case CEILINGDEF:
upper=CEILINGDEF;
lower=FLOORDEF;
break;
case CEILINGHEIGHT:
case FLOORHEIGHT:
upper=CEILINGHEIGHT;
lower=FLOORHEIGHT;
break;
default:
upper=CEILING;
lower=FLOOR;
break;
}
for (tiley=currenty-9;tiley<=currenty+9;tiley++,y+=10)
if (tiley>=0 && tiley<YMAX)
{
x=0;
for (tilex=currentx-9;tilex<=currentx+9;tilex++,x+=10)
if (tilex>=0 && tilex<XMAX)
{
color=(*layers[lower])[tiley][tilex];
if (color)
{
color=(color%240) + 16;
for (i=1;i<10;i++)
memset(bufylookup[y+i]+x+1,color,9);
}
color=(*layers[upper])[tiley][tilex];
if (color)
{
color=(color%240) + 16;
for (i=1;i<10;i++)
for (j=10-i;j>0;j--)
*(bufylookup[y+i]+x+j)=color;
}
color=(*layers[NORTHWALL])[tiley][tilex];
if (color)
{
if (lower!=FLOOR)
color=5;
else
color=(color%240) + 16;
memset(bufylookup[y]+x,color,10);
memset(bufylookup[y+1]+x,color,10);
}
color=(*layers[WESTWALL])[tiley][tilex];
if (color)
{
if (lower!=FLOOR)
color=5;
else
color=(color%240) + 16;
for (i=0;i<10;i++)
*(bufylookup[y+i]+x)=color;
for (i=0;i<10;i++)
*(bufylookup[y+i]+x+1)=color;
}
color=(*layers[SPRITES])[tiley][tilex];
if (color)
{
color=(color%240) + 16;
*(bufylookup[y+4]+x+4)=color;
*(bufylookup[y+5]+x+4)=color;
*(bufylookup[y+6]+x+4)=color;
*(bufylookup[y+4]+x+5)=color;
*(bufylookup[y+5]+x+5)=color;
*(bufylookup[y+6]+x+5)=color;
*(bufylookup[y+4]+x+6)=color;
*(bufylookup[y+5]+x+6)=color;
*(bufylookup[y+6]+x+6)=color;
}
if ((*layers[SLOPES])[tiley][tilex])
*(bufylookup[y+5]+x+5)=3;
}
else
for (i=0;i<10;i++)
memset(bufylookup[y+i]+x,0,10);
}
else
for (i=0;i<10;i++)
memset(bufylookup[y+i],0,BUFX);
if (currentlayer==WESTWALL)
{
cw=4;
ch=12;
}
else if (currentlayer==NORTHWALL)
{
cw=12;
ch=4;
}
else
{
cw=13;
ch=13;
}
memset(bufylookup[89]+89,6,cw);
memset(bufylookup[88+ch]+89,6,cw);
for (i=90;i<89+ch;i++)
{
*(bufylookup[i]+89)=6;
*(bufylookup[i]+88+cw)=6;
}
}
/* Edit Functions ***********************************************************/
void FloodFill(void)
{
byte *x, *y, *processed;
int index, total, curx, cury;
index=0;
total=1;
x=(byte *)malloc(YMAX*XMAX);
if (x==NULL)
Error("Out of memory for flood fill (1)");
y=(byte *)malloc(YMAX*XMAX);
if (y==NULL)
Error("Out of memory for flood fill (2)");
processed=(byte *)malloc(YMAX*XMAX);
if (processed==NULL)
Error("Out of memory for flood fill (3)");
memset(x,0,XMAX*YMAX);
memset(y,0,XMAX*YMAX);
memset(processed,0,XMAX*YMAX);
x[0]=currentx;
y[0]=currenty;
processed[currenty*XMAX+currentx]=1;
while (index<total)
{
curx=x[index];
cury=y[index];
index++;
if (!(*layers[NORTHWALL])[cury][curx] && cury-1>=0)
{
if (!processed[(cury-1)*XMAX+curx])
{
x[total]=curx;
y[total]=cury-1;
total++;
processed[(cury-1)*XMAX+curx]=1;
}
}
if (!(*layers[WESTWALL])[cury][curx] && curx-1>=0)
{
if (!processed[(cury)*XMAX+curx-1])
{
x[total]=curx-1;
y[total]=cury;
total++;
processed[(cury)*XMAX+curx-1]=1;
}
}
if (cury<YMAX-1 && !(*layers[NORTHWALL])[cury+1][curx])
{
if (!processed[(cury+1)*XMAX+curx])
{
x[total]=curx;
y[total]=cury+1;
total++;
processed[(cury+1)*XMAX+curx]=1;
}
}
if (curx<XMAX-1 && !(*layers[WESTWALL])[cury][curx+1])
{
if (!processed[(cury)*XMAX+curx+1])
{
x[total]=curx+1;
y[total]=cury;
total++;
processed[(cury)*XMAX+curx+1]=1;
}
}
if (total>=XMAX*YMAX)
Error("Flood fill overflow");
(*layers[currentlayer])[cury][curx]=currentvalue[currentlayer];
}
free(x);
free(y);
free(processed);
}
void UpdateLocalInfo(void)
{
char *s;
byte flags;
PrintXY(233,20,layernames[currentlayer]);
PrintfXY(233,30,"%3i",currentvalue[currentlayer]);
PrintfXY(263,30,"%2i",currentx);
PrintfXY(288,30,"%2i",currenty);
PrintfXY(236,52,"%3i",(*layers[NORTHWALL])[currenty][currentx]);
PrintfXY(255,52,"%3i",(*layers[WESTWALL])[currenty][currentx]);
PrintfXY(236,63,"%3i",(*layers[FLOOR])[currenty][currentx]);
PrintfXY(255,63,"%3i",(*layers[CEILING])[currenty][currentx]);
PrintfXY(236,74,"%3i",(*layers[FLOORHEIGHT])[currenty][currentx]);
PrintfXY(255,74,"%3i",(*layers[CEILINGHEIGHT])[currenty][currentx]);
PrintfXY(236,85,"%3i",(*layers[FLOORDEF])[currenty][currentx]);
PrintfXY(255,85,"%3i",(*layers[CEILINGDEF])[currenty][currentx]);
PrintfXY(236,96,"%3i",(*layers[LIGHTS])[currenty][currentx]);
PrintfXY(255,96,"%3i",(*layers[EFFECTS])[currenty][currentx]);
PrintfXY(236,107,"%3i",(*layers[SPRITES])[currenty][currentx]);
PrintfXY(255,107,"%3i",(*layers[SLOPES])[currenty][currentx]);
switch (currentlayer)
{
case NORTHWALL:
case WESTWALL:
case FLOORDEF:
case CEILINGDEF:
case FLOOR:
case CEILING:
flags=(*layers[currentlayer+1])[currenty][currentx];
if (flags & F_RIGHT)
s="Yes";
else
s="No ";
PrintXY(236,130,s);
if (flags & F_LEFT)
s="Yes";
else
s="No ";
PrintXY(255,130,s);
if (flags & F_UP)
s="Yes";
else
s="No ";
PrintXY(236,141,s);
if (flags & F_DOWN)
s="Yes";
else
s="No ";
PrintXY(255,141,s);
if (flags & F_TRANSPARENT)
s="Yes";
else
s="No ";
PrintXY(236,152,s);
if (flags & F_NOCLIP)
s="Yes";
else
s="No ";
PrintXY(255,152,s);
if (flags & F_NOBULLETCLIP)
s="Yes";
else
s="No ";
PrintXY(236,163,s);
if (flags & F_DAMAGE)
s="Yes";
else
s="No ";
PrintXY(255,163,s);
break;
default:
PrintXY(236,130,"No ");
PrintXY(255,130,"No ");
PrintXY(236,141,"No ");
PrintXY(255,141,"No ");
PrintXY(236,152,"No ");
PrintXY(255,152,"No ");
PrintXY(236,163,"No ");
PrintXY(255,163,"No ");
break;
}
}
/* MAIN *********************************************************************/
void MainLoop(void)
{
int c, ans, i;
UpdateLocalInfo();
DrawBuffer();
BlitBuffer();
while (!quit)
{
ans=ReadKey();
if (messageready) DeleteMessage();
c=ans & 255;
switch (c)
{
case 0x00:
case 0xE0:
c=(word)ans>>8;
switch (c)
{
/* keypad controls */
case 75:
if (currentx>0)
{
--currentx;
if (*(byte*)MK_FP(0x0040,0x0017)&64)
(*layers[currentlayer])[currenty][currentx]=currentvalue[currentlayer];
UpdateLocalInfo();
DrawBuffer();
BlitBuffer();
}
break;
case 77:
if (currentx<XMAX-1)
{
++currentx;
if (*(byte*)MK_FP(0x0040,0x0017)&64)
(*layers[currentlayer])[currenty][currentx]=currentvalue[currentlayer];
UpdateLocalInfo();
DrawBuffer();
BlitBuffer();
}
break;
case 72:
if (currenty>0)
{
--currenty;
if (*(byte*)MK_FP(0x0040,0x0017)&64)
(*layers[currentlayer])[currenty][currentx]=currentvalue[currentlayer];
UpdateLocalInfo();
DrawBuffer();
BlitBuffer();
}
break;
case 80:
if (currenty<YMAX-1)
{
++currenty;
if (*(byte*)MK_FP(0x0040,0x0017)&64)
(*layers[currentlayer])[currenty][currentx]=currentvalue[currentlayer];
UpdateLocalInfo();
DrawBuffer();
BlitBuffer();
}
break;
case 73:
currenty-=10;
if (currenty<0) currenty=0;
if (*(byte*)MK_FP(0x0040,0x0017)&64)
(*layers[currentlayer])[currenty][currentx]=currentvalue[currentlayer];
UpdateLocalInfo();
DrawBuffer();
BlitBuffer();
break;
case 81:
currenty+=10;
if (currenty>=YMAX) currenty=YMAX;
if (*(byte*)MK_FP(0x0040,0x0017)&64)
(*layers[currentlayer])[currenty][currentx]=currentvalue[currentlayer];
UpdateLocalInfo();
DrawBuffer();
BlitBuffer();
break;
case 71:
currentx-=10;
if (currentx<0) currentx=0;
if (*(byte*)MK_FP(0x0040,0x0017)&64)
(*layers[currentlayer])[currenty][currentx]=currentvalue[currentlayer];
UpdateLocalInfo();
DrawBuffer();
BlitBuffer();
break;
case 79:
currentx+=10;
if (currentx>=YMAX) currentx=YMAX;
if (*(byte*)MK_FP(0x0040,0x0017)&64)
(*layers[currentlayer])[currenty][currentx]=currentvalue[currentlayer];
UpdateLocalInfo();
DrawBuffer();
BlitBuffer();
break;
/* flood/fill commands */
case 33: // alt-f
if (AskQuestion("Fill? (y/n)"))
{
memset(layers[currentlayer],currentvalue[currentlayer],sizeof(layer_t));
UpdateLocalInfo();
Drawbuffer();
BlitBuffer();
}
break;
case 36: // alt-j
if (AskQuestion("Flood? (y/n)"))
{
FloodFill();
UpdateLocalInfo();
Drawbuffer();
BlitBuffer();
}
break;
/* flag setting commands */
case 59:
switch (currentlayer)
{
case NORTHWALL:
case WESTWALL:
case FLOORDEF:
case CEILINGDEF:
case FLOOR:
case CEILING:
(*layers[currentlayer+1])[currenty][currentx]^=F_RIGHT;
UpdateLocalInfo();
break;
}
break;
case 60:
switch (currentlayer)
{
case NORTHWALL:
case WESTWALL:
case FLOORDEF:
case CEILINGDEF:
case FLOOR:
case CEILING:
(*layers[currentlayer+1])[currenty][currentx]^=F_LEFT;
UpdateLocalInfo();
break;
}
break;
case 61:
switch (currentlayer)
{
case NORTHWALL:
case WESTWALL:
case FLOORDEF:
case CEILINGDEF:
case FLOOR:
case CEILING:
(*layers[currentlayer+1])[currenty][currentx]^=F_UP;
UpdateLocalInfo();
break;
}
break;
case 62:
switch (currentlayer)
{
case NORTHWALL:
case WESTWALL:
case FLOORDEF:
case CEILINGDEF:
case FLOOR:
case CEILING:
(*layers[currentlayer+1])[currenty][currentx]^=F_DOWN;
UpdateLocalInfo();
break;
}
break;
case 64:
switch (currentlayer)
{
case NORTHWALL:
case WESTWALL:
(*layers[currentlayer+1])[currenty][currentx]^=F_NOCLIP;
UpdateLocalInfo();
break;
}
break;
case 63:
switch (currentlayer)
{
case NORTHWALL:
case WESTWALL:
case FLOORDEF:
case CEILINGDEF:
case CEILING:
(*layers[currentlayer+1])[currenty][currentx]^=F_TRANSPARENT;
UpdateLocalInfo();
break;
}
break;
case 65:
switch (currentlayer)
{
case NORTHWALL:
case WESTWALL:
(*layers[currentlayer+1])[currenty][currentx]^=F_NOBULLETCLIP;
UpdateLocalInfo();
break;
}
break;
case 66:
switch (currentlayer)
{
case NORTHWALL:
case WESTWALL:
case FLOOR:
case CEILING:
(*layers[currentlayer+1])[currenty][currentx]^=F_DAMAGE;
UpdateLocalInfo();
break;
}
break;
/* file commands */
case 31: // alt-s
SaveLAYFile();
break;
case 38: // alt-l
LoadLayFile();
UpdateLocalInfo();
Drawbuffer();
BlitBuffer();
break;
/* quit command */
case 45: // alt-x
case 16: // alt-q
if (AskQuestion("Quit? (y/n)")) quit=true;
break;
}
break;
/* value commands */
case ' ':
(*layers[currentlayer])[currenty][currentx]=currentvalue[currentlayer];
UpdateLocalInfo();
Drawbuffer();
BlitBuffer();
break;
case '.':
case '+':
currentvalue[currentlayer]++;
currentvalue[currentlayer]&=255;
UpdateLocalInfo();
break;
case ',':
case '-':
currentvalue[currentlayer]--;
currentvalue[currentlayer]&=255;
UpdateLocalInfo();
break;
case 'z':
case 'Z':
currentvalue[currentlayer]=(*layers[currentlayer])[currenty][currentx];
UpdateLocalInfo();
break;
case 'x':
case 'X':
(*layers[currentlayer])[currenty][currentx]=0;
UpdateLocalInfo();
DrawBuffer();
BlitBuffer();
break;
case 'c':
case 'C':
for (i=0;i<NUMLAYERS;i++)
currentvalue[i]=(*layers[i])[currenty][currentx];
UpdateLocalInfo();
break;
case 'v':
case 'V':
for (i=0;i<NUMLAYERS;i++)
(*layers[i])[currenty][currentx]=currentvalue[i];
UpdateLocalInfo();
DrawBuffer();
BlitBuffer();
break;
/* layer commands */
case 9:
switch (currentlayer)
{
case NORTHWALL:
currentlayer=WESTWALL;
break;
case WESTWALL:
currentlayer=NORTHWALL;
break;
case FLOOR:
currentlayer=CEILING;
break;
case CEILING:
currentlayer=FLOOR;
break;
case FLOORHEIGHT:
currentlayer=CEILINGHEIGHT;
break;
case CEILINGHEIGHT:
currentlayer=FLOORHEIGHT;
break;
case CEILINGDEF:
currentlayer=FLOORDEF;
break;
case FLOORDEF:
currentlayer=CEILINGDEF;
break;
}
UpdateLocalInfo();
DrawBuffer();
BlitBuffer();
break;
case '1':
currentlayer=NORTHWALL;
UpdateLocalInfo();
Drawbuffer();
BlitBuffer();
break;
case '2':
currentlayer=WESTWALL;
UpdateLocalInfo();
Drawbuffer();
BlitBuffer();
break;
case '3':
currentlayer=FLOOR;
UpdateLocalInfo();
Drawbuffer();
BlitBuffer();
break;
case '4':
currentlayer=CEILING;
UpdateLocalInfo();
Drawbuffer();
BlitBuffer();
break;
case '5':
currentlayer=FLOORHEIGHT;
UpdateLocalInfo();
Drawbuffer();
BlitBuffer();
break;
case '6':
currentlayer=CEILINGHEIGHT;
UpdateLocalInfo();
Drawbuffer();
BlitBuffer();
break;
case '7':
currentlayer=FLOORDEF;
UpdateLocalInfo();
Drawbuffer();
BlitBuffer();
break;
case '8':
currentlayer=CEILINGDEF;
UpdateLocalInfo();
Drawbuffer();
BlitBuffer();
break;
case '9':
currentlayer=LIGHTS;
UpdateLocalInfo();
Drawbuffer();
BlitBuffer();
break;
case '0':
currentlayer=EFFECTS;
UpdateLocalInfo();
Drawbuffer();
BlitBuffer();
break;
case 'q':
case 'Q':
currentlayer=SPRITES;
UpdateLocalInfo();
Drawbuffer();
BlitBuffer();
break;
case 'w':
case 'W':
currentlayer=SLOPES;
UpdateLocalInfo();
Drawbuffer();
BlitBuffer();
break;
/* quit */
case 27:
if (AskQuestion("Quit? (y/n)")) quit=true;
break;
}
}
}
cdecl main(int argc, char **argv)
{
/* Initialize */
InitMEDIT();
SetVidMode(VGAMODE);
LoadCPR("MEDIT.CPR");
LoadFON("BLOCK.FON",FONTWIDTH);
/* check parameters */
if (argc==1) Error("No LAY/LVL file specified");
else if (argc>4) Error("Too many parameters");
else
{
ReadLevel(argv[1]);
if (argc>=3) Convert1(argv[2]);
if (argc>=4) Convert2(argv[3]);
MainLoop();
}
/* end message */
SetVidMode(TEXTMODE);
printf("MEDIT (v%s)\n"
"LAY/LVL File Editor\n"
"Copyright (C) 1995 by Robert Morgan of Channel 7\n"
"All rights reserved.\n\n",VERSION);
}