raze/polymer/build/src/build.c

7496 lines
282 KiB
C
Raw Normal View History

// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
// Ken Silverman's official web site: "http://www.advsys.net/ken"
// See the included license file "BUILDLIC.TXT" for license info.
//
// This file has been modified from Ken Silverman's original release
// by Jonathon Fowler (jonof@edgenetwk.com)
#include "build.h"
#include "compat.h"
#include "pragmas.h"
#include "osd.h"
#include "cache1d.h"
#include "editor.h"
#define VERSION "("__DATE__" "__TIME__")"
#include "baselayer.h"
#ifdef RENDERTYPEWIN
#include "winlayer.h"
#endif
#define TIMERINTSPERSECOND 120
#define updatecrc16(crc,dat) (crc = (((crc<<8)&65535)^crctable[((((unsigned short)crc)>>8)&65535)^dat]))
static long crctable[256];
static char kensig[24];
extern int ExtInit(void);
extern int ExtPreInit(int argc,char **argv);
extern void ExtUnInit(void);
extern void ExtPreCheckKeys(void);
#ifdef SUPERBUILD
extern void ExtAnalyzeSprites(void);
#endif
extern void ExtCheckKeys(void);
extern void ExtLoadMap(const char *mapname);
extern void ExtSaveMap(const char *mapname);
extern const char *ExtGetSectorCaption(short sectnum);
extern const char *ExtGetWallCaption(short wallnum);
extern const char *ExtGetSpriteCaption(short spritenum);
extern void ExtShowSectorData(short sectnum);
extern void ExtShowWallData(short wallnum);
extern void ExtShowSpriteData(short spritenum);
extern void ExtEditSectorData(short sectnum);
extern void ExtEditWallData(short wallnum);
extern void ExtEditSpriteData(short spritenum);
extern char ExtCustomSpriteColor(short picnum);
extern void ExtSetupSpecialSpriteCols(void);
extern char spritecol2d[MAXTILES][2];
char noclip=0;
void _printmessage16(char name[82]);
long vel, svel, angvel;
unsigned char buildkeys[NUMBUILDKEYS] =
{
0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39,
0x1e,0x2c,0xd1,0xc9,0x33,0x34,
0x9c,0x1c,0xd,0xc,0xf,0x29
};
long posx, posy, posz, horiz = 100;
long mousexsurp = 0, mouseysurp = 0;
short ang, cursectnum;
long hvel;
long grponlymode = 0;
extern long editorgridextent; // in engine.c
extern double msens;
long synctics = 0, lockclock = 0;
extern char vgacompatible;
extern char picsiz[MAXTILES];
extern long startposx, startposy, startposz;
extern short startang, startsectnum;
extern long frameplace, ydim16, halfxdim16, midydim16;
long xdim2d = 640, ydim2d = 480, xdimgame = 640, ydimgame = 480, bppgame = 8;
long forcesetup = 1;
extern long cachesize, artsize;
static short oldmousebstatus = 0;
short brightness = 0;
long zlock = 0x7fffffff, zmode = 0, whitecol, kensplayerheight = 32;
short defaultspritecstat = 0;
static short localartfreq[MAXTILES];
static short localartlookup[MAXTILES], localartlookupnum;
char tempbuf[4096];
char names[MAXTILES][25];
short asksave = 0;
extern short editstatus, searchit;
extern long searchx, searchy; //search input
extern short searchsector, searchwall, searchstat; //search output
long osearchx, osearchy; //old search input
extern long pointhighlight, linehighlight, highlightcnt;
short grid = 3, gridlock = 1, showtags = 1;
long zoom = 768, gettilezoom = 1;
long lastpm16time;
long numsprites;
extern long mapversion;
short highlight[MAXWALLS];
short highlightsector[MAXSECTORS], highlightsectorcnt = -1;
extern char textfont[128][8];
static char pskysearch[MAXSECTORS];
short temppicnum, tempcstat, templotag, temphitag, tempextra;
unsigned char tempshade, temppal, tempvis, tempxrepeat, tempyrepeat;
unsigned char somethingintab = 255;
char mlook = 0;
static char boardfilename[BMAX_PATH], selectedboardfilename[BMAX_PATH];
static CACHE1D_FIND_REC *finddirs=NULL, *findfiles=NULL, *finddirshigh=NULL, *findfileshigh=NULL;
static int numdirs=0, numfiles=0;
static int currentlist=0;
static long repeatcountx, repeatcounty;
static long fillist[640];
long mousx, mousy;
static char scantoasc[128] =
{
0,0,'1','2','3','4','5','6','7','8','9','0','-','=',0,0,
'q','w','e','r','t','y','u','i','o','p','[',']',0,0,'a','s',
'd','f','g','h','j','k','l',';',39,'`',0,92,'z','x','c','v',
'b','n','m',',','.','/',0,'*',0,32,0,0,0,0,0,0,
0,0,0,0,0,0,0,'7','8','9','-','4','5','6','+','1',
'2','3','0','.',0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};
static char scantoascwithshift[128] =
{
0,0,'!','@','#','$','%','^','&','*','(',')','_','+',0,0,
'Q','W','E','R','T','Y','U','I','O','P','{','}',0,0,'A','S',
'D','F','G','H','J','K','L',':',34,'~',0,'|','Z','X','C','V',
'B','N','M','<','>','?',0,'*',0,32,0,0,0,0,0,0,
0,0,0,0,0,0,0,'7','8','9','-','4','5','6','+','1',
'2','3','0','.',0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};
char changechar(char dachar, long dadir, char smooshyalign, char boundcheck);
long adjustmark(long *xplc, long *yplc, short danumwalls);
long checkautoinsert(long dax, long day, short danumwalls);
void keytimerstuff(void);
long clockdir(short wallstart);
void flipwalls(short numwalls, short newnumwalls);
void insertpoint(short linehighlight, long dax, long day);
void deletepoint(short point);
long deletesector(short sucksect);
long checksectorpointer(short i, short sectnum);
void fixrepeats(short i);
short loopinside(long x, long y, short startwall);
long fillsector(short sectnum, char fillcolor);
short whitelinescan(short dalinehighlight);
void printcoords16(long posxe, long posye, short ange);
void copysector(short soursector, short destsector, short deststartwall, char copystat);
void showsectordata(short sectnum);
void showwalldata(short wallnum);
void showspritedata(short spritenum);
long drawtilescreen(long pictopleft, long picbox);
void overheadeditor(void);
long getlinehighlight(long xplc, long yplc);
void fixspritesectors(void);
long movewalls(long start, long offs);
long loadnames(void);
void updatenumsprites(void);
void getclosestpointonwall(long x, long y, long dawall, long *nx, long *ny);
void initcrc(void);
void AutoAlignWalls(long nWall0, long ply);
long gettile(long tilenum);
long menuselect(void);
long getfilenames(char *path, char *kind);
void clearfilenames(void);
void clearkeys(void) { memset(keystatus,0,sizeof(keystatus)); }
static int osdcmd_restartvid(const osdfuncparm_t *parm)
{
extern long qsetmode;
if (qsetmode != 200) return OSDCMD_OK;
resetvideomode();
if (setgamemode(fullscreen,xdim,ydim,bpp))
OSD_Printf("restartvid: Reset failed...\n");
return OSDCMD_OK;
}
static int osdcmd_vidmode(const osdfuncparm_t *parm)
{
long newx = xdim, newy = ydim, newbpp = bpp, newfullscreen = fullscreen;
extern long qsetmode;
if (qsetmode != 200) return OSDCMD_OK;
switch (parm->numparms) {
case 1: // bpp switch
newbpp = Batol(parm->parms[0]);
break;
case 4: // fs, res, bpp switch
newfullscreen = (Batol(parm->parms[3]) != 0);
case 3: // res & bpp switch
newbpp = Batol(parm->parms[2]);
case 2: // res switch
newx = Batol(parm->parms[0]);
newy = Batol(parm->parms[1]);
break;
default:
return OSDCMD_SHOWHELP;
}
if (setgamemode(newfullscreen,newx,newy,newbpp))
OSD_Printf("vidmode: Mode change failed!\n");
xdimgame = newx; ydimgame = newy; bppgame = newbpp; fullscreen = newfullscreen;
return OSDCMD_OK;
}
extern int startwin_run(void);
extern char *defsfilename; // set in bstub.c
int app_main(int argc, char **argv)
{
char ch, quitflag, cmdsetup = 0, grpstoadd = 0;
char **grps = NULL;
long i, j, k;
pathsearchmode = 1; // unrestrict findfrompath so that full access to the filesystem can be had
#ifdef USE_OPENGL
OSD_RegisterFunction("restartvid","restartvid: reinitialise the video mode",osdcmd_restartvid);
OSD_RegisterFunction("vidmode","vidmode [xdim ydim] [bpp] [fullscreen]: immediately change the video mode",osdcmd_vidmode);
#endif
wm_setapptitle("Mapster32");
if ((i = ExtPreInit(argc,argv)) < 0) return -1;
#ifdef RENDERTYPEWIN
backgroundidle = 1;
#endif
editstatus = 1;
boardfilename[0] = 0;
for (i=1; i<argc; i++) {
if (argv[i][0] == '-') {
if (!strcmp(argv[i], "-setup")) cmdsetup = 1;
else if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "-grp")) {
i++;
grps = (char**)realloc(grps, sizeof(char*)*(grpstoadd+1));
grps[grpstoadd++] = argv[i];
}
else if (!strcmp(argv[i], "-help") || !strcmp(argv[i], "--help") || !strcmp(argv[i], "-?")) {
char *s =
"Mapster32\n"
"Syntax: mapster32 [options] mapname\n"
"Options:\n"
"\t-grp\tUse an extra GRP or ZIP file.\n"
"\t-g\tSame as above.\n"
#if defined RENDERTYPEWIN || (defined RENDERTYPESDL && !defined __APPLE__ && defined HAVE_GTK2)
"\t-setup\tDisplays the configuration dialogue box before entering the editor.\n"
#endif
;
#if defined RENDERTYPEWIN || (defined RENDERTYPESDL && !defined __APPLE__ && defined HAVE_GTK2)
wm_msgbox("Mapster32",s);
#else
puts(s);
#endif
return 0;
}
continue;
}
if (!boardfilename[0]) {
strncpy(boardfilename, argv[i], BMAX_PATH-4-1);
boardfilename[i-BMAX_PATH] = 0;
}
}
if (boardfilename[0] == 0) {
Bstrcpy(boardfilename,"newboard.map");
} else if (Bstrchr(boardfilename,'.') == 0) {
Bstrcat(boardfilename, ".map");
}
//Bcanonicalisefilename(boardfilename,0);
if ((i = ExtInit()) < 0) return -1;
#if defined RENDERTYPEWIN || (defined RENDERTYPESDL && !defined __APPLE__ && defined HAVE_GTK2)
if (i || forcesetup || cmdsetup) {
if (quitevent || !startwin_run()) return -1;
}
#endif
if (initinput()) return -1;
// if (option[3] != 0) moustat =
initmouse();
if (grps && grpstoadd > 0) {
for (i=0;i<grpstoadd;i++) {
initprintf("Adding %s\n",grps[i]);
initgroupfile(grps[i]);
}
free(grps);
}
inittimer(TIMERINTSPERSECOND);
installusertimercallback(keytimerstuff);
loadpics("tiles000.art",1048576*16);
loadnames();
Bstrcpy(kensig,"Based on BUILD by Ken Silverman");
initcrc();
ExtSetupSpecialSpriteCols();
if (!loaddefinitionsfile(defsfilename)) initprintf("Definitions file loaded.\n");
if (setgamemode(fullscreen,xdimgame,ydimgame,bppgame) < 0)
{
ExtUnInit();
uninitengine();
Bprintf("%ld * %ld not supported in this graphics mode\n",xdim,ydim);
exit(0);
}
setbrightness(brightness,palette,0);
k = 0;
for (i=0;i<256;i++)
{
j = ((long)palette[i*3])+((long)palette[i*3+1])+((long)palette[i*3+2]);
if (j > k) { k = j; whitecol = i; }
}
for (i=0;i<MAXSECTORS;i++) sector[i].extra = -1;
for (i=0;i<MAXWALLS;i++) wall[i].extra = -1;
for (i=0;i<MAXSPRITES;i++) sprite[i].extra = -1;
ExtPreLoadMap();
i = loadboard(boardfilename,(!pathsearchmode&&grponlymode?2:0),&posx,&posy,&posz,&ang,&cursectnum);
if (i == -2) i = loadoldboard(boardfilename,(!pathsearchmode&&grponlymode?2:0),&posx,&posy,&posz,&ang,&cursectnum);
if (i < 0)
{
initspritelists();
posx = 32768;
posy = 32768;
posz = 0;
ang = 1536;
numsectors = 0;
numwalls = 0;
cursectnum = -1;
}
else
{
ExtLoadMap(boardfilename);
}
updatenumsprites();
startposx = posx;
startposy = posy;
startposz = posz;
startang = ang;
startsectnum = cursectnum; // TX 20050225: moved to loadboard
totalclock = 0;
updatesector(posx,posy,&cursectnum);
if (cursectnum == -1)
{
setbrightness(0,palette,0);
overheadeditor();
keystatus[buildkeys[14]] = 0;
}
CANCEL:
quitflag = 0;
while (quitflag == 0)
{
if (handleevents()) {
if (quitevent) {
keystatus[1] = 1;
quitevent = 0;
}
}
OSD_DispatchQueued();
ExtPreCheckKeys();
drawrooms(posx,posy,posz,ang,horiz,cursectnum);
#ifdef SUPERBUILD
ExtAnalyzeSprites();
#endif
drawmasks();
ExtCheckKeys();
nextpage();
synctics = totalclock-lockclock;
lockclock += synctics;
if (keystatus[1] > 0)
{
keystatus[1] = 0;
begindrawing(); //{{{
printext256(0,0,whitecol,0,"Are you sure you want to quit?",0);
enddrawing(); //}}}
showframe(1);
synctics = totalclock-lockclock;
lockclock += synctics;
while ((keystatus[1]|keystatus[0x1c]|keystatus[0x39]|keystatus[0x31]) == 0)
{
if (handleevents()) {
if (quitevent) {
quitflag = 1;
break;
}
}
idle();
if (keystatus[0x15] != 0) {
keystatus[0x15] = 0;
quitflag = 1; break;
}
}
while (keystatus[1])
{
keystatus[1] = 0;
quitevent = 0;
goto CANCEL;
}
}
}
if (asksave)
{
begindrawing(); //{{{
printext256(0,8,whitecol,0,"Save changes?",0);
showframe(1); //}}}
while ((keystatus[1]|keystatus[0x1c]|keystatus[0x39]|keystatus[0x31]|keystatus[0x2e]) == 0)
{
if (handleevents()) { if (quitevent) break; } // like saying no
idle();
if (keystatus[0x15] != 0) {
keystatus[0x15] = 0;
updatesector(startposx,startposy,&startsectnum);
ExtPreSaveMap();
saveboard(boardfilename,&startposx,&startposy,&startposz,&startang,&startsectnum);
ExtSaveMap(boardfilename);
break;
}
}
while (keystatus[1]||keystatus[0x2e])
{
keystatus[1] = 0;
keystatus[0x2e] = 0;
quitevent = 0;
goto CANCEL;
}
}
clearfilenames();
ExtUnInit();
uninitengine();
Bprintf("Memory status: %ld(%ld) bytes\n",cachesize,artsize);
Bprintf("%s\n",kensig);
return(0);
}
void showmouse(void)
{
int i;
for (i=1;i<=4;i++)
{
plotpixel(searchx+i,searchy,whitecol);
plotpixel(searchx-i,searchy,whitecol);
plotpixel(searchx,searchy-i,whitecol);
plotpixel(searchx,searchy+i,whitecol);
}
}
void editinput(void)
{
char smooshyalign, repeatpanalign, *ptr, buffer[80];
short sectnum, nextsectnum, startwall, endwall, dasector, daang;
long mousz, bstatus;
long i, j, k, cnt, templong=0, doubvel, changedir, wallfind[2], daz[2];
long dashade[2], goalz, xvect, yvect, hiz, loz;
short hitsect, hitwall, hitsprite;
long hitx, hity, hitz, dax, day, hihit, lohit;
if (keystatus[0x57] > 0) //F11 - brightness
{
keystatus[0x57] = 0;
brightness++;
if (brightness >= 16) brightness = 0;
setbrightness(brightness,palette,0);
}
if (keystatus[88] > 0) //F12
{
screencapture("captxxxx.tga",keystatus[0x2a]|keystatus[0x36]);
keystatus[88] = 0;
}
mousz = 0;
getmousevalues(&mousx,&mousy,&bstatus);
mousx = (mousx<<16)+mousexsurp;
mousy = (mousy<<16)+mouseysurp;
{
ldiv_t ld;
ld = ldiv((long)(mousx), (1<<16)); mousx = ld.quot; mousexsurp = ld.rem;
ld = ldiv((long)(mousy), (1<<16)); mousy = ld.quot; mouseysurp = ld.rem;
}
if (mlook == 1)
{
ang += (mousx>>1)*msens;
horiz -= (mousy>>2)*msens;
if (mousy && !(mousy>>2))
horiz--;
if (mousx && !(mousx>>1))
ang++;
if (horiz > 299)
horiz = 299;
if (horiz < -99)
horiz = -99;
searchx = xdim>>1;
searchy = ydim>>1;
osearchx = searchx-mousx;
osearchy = searchy-mousy;
}
else
{
osearchx = searchx;
osearchy = searchy;
searchx += mousx;
searchy += mousy;
if (searchx < 8) searchx = 8;
if (searchy < 8) searchy = 8;
if (searchx > xdim-9) searchx = xdim-9;
if (searchy > ydim-9) searchy = ydim-9;
}
showmouse();
if (keystatus[0x3b] > 0) posx--;
if (keystatus[0x3c] > 0) posx++;
if (keystatus[0x3d] > 0) posy--;
if (keystatus[0x3e] > 0) posy++;
if (keystatus[0x43] > 0) ang--;
if (keystatus[0x44] > 0) ang++;
if (angvel != 0) //ang += angvel * constant
{ //ENGINE calculates angvel for you
doubvel = synctics;
if (keystatus[buildkeys[4]] > 0) //Lt. shift makes turn velocity 50% faster
doubvel += (synctics>>1);
ang += ((angvel*doubvel)>>4);
ang = (ang+2048)&2047;
}
if ((vel|svel) != 0)
{
doubvel = synctics;
if (keystatus[buildkeys[4]] > 0) //Lt. shift doubles forward velocity
doubvel += synctics;
xvect = 0, yvect = 0;
if (vel != 0)
{
xvect += ((vel*doubvel*(long)sintable[(ang+2560)&2047])>>3);
yvect += ((vel*doubvel*(long)sintable[(ang+2048)&2047])>>3);
}
if (svel != 0)
{
xvect += ((svel*doubvel*(long)sintable[(ang+2048)&2047])>>3);
yvect += ((svel*doubvel*(long)sintable[(ang+1536)&2047])>>3);
}
if (noclip)
{
posx += xvect>>14;
posy += yvect>>14;
updatesector(posx,posy,&cursectnum);
}
else clipmove(&posx,&posy,&posz,&cursectnum,xvect,yvect,128L,4L<<8,4L<<8,CLIPMASK0);
}
getzrange(posx,posy,posz,cursectnum,&hiz,&hihit,&loz,&lohit,128L,CLIPMASK0);
if (keystatus[0x3a] > 0)
{
zmode++;
if (zmode == 3) zmode = 0;
if (zmode == 1) zlock = (loz-posz)&0xfffffc00;
keystatus[0x3a] = 0;
}
if (zmode == 0)
{
goalz = loz-(kensplayerheight<<8); //playerheight pixels above floor
if (goalz < hiz+(16<<8)) //ceiling&floor too close
goalz = ((loz+hiz)>>1);
goalz += mousz;
if (keystatus[buildkeys[8]] > 0) //A (stand high)
{
if (keystatus[0x1d] > 0)
horiz = max(-100,horiz-((keystatus[buildkeys[4]]+1)*synctics*2));
else
{
goalz -= (16<<8);
if (keystatus[buildkeys[4]] > 0) //Either shift key
goalz -= (24<<8);
}
}
if (keystatus[buildkeys[9]] > 0) //Z (stand low)
{
if (keystatus[0x1d] > 0)
horiz = min(300,horiz+((keystatus[buildkeys[4]]+1)*synctics*2));
else
{
goalz += (12<<8);
if (keystatus[buildkeys[4]] > 0) //Either shift key
goalz += (12<<8);
}
}
if (goalz != posz)
{
if (posz < goalz) hvel += 64;
if (posz > goalz) hvel = ((goalz-posz)>>3);
posz += hvel;
if (posz > loz-(4<<8)) posz = loz-(4<<8), hvel = 0;
if (posz < hiz+(4<<8)) posz = hiz+(4<<8), hvel = 0;
}
}
else
{
goalz = posz;
if (keystatus[buildkeys[8]] > 0) //A
{
if (keystatus[0x1d] > 0) {
horiz = max(-100,horiz-((keystatus[buildkeys[4]]+1)*synctics*2));
} else {
if (zmode != 1)
goalz -= (8<<8);
else
{
zlock += (4<<8);
keystatus[buildkeys[8]] = 0;
}
}
}
if (keystatus[buildkeys[9]] > 0) //Z (stand low)
{
if (keystatus[0x1d] > 0) {
horiz = min(300,horiz+((keystatus[buildkeys[4]]+1)*synctics*2));
} else {
if (zmode != 1)
goalz += (8<<8);
else if (zlock > 0)
{
zlock -= (4<<8);
keystatus[buildkeys[9]] = 0;
}
}
}
if (goalz < hiz+(4<<8)) goalz = hiz+(4<<8);
if (goalz > loz-(4<<8)) goalz = loz-(4<<8);
if (zmode == 1) goalz = loz-zlock;
if (goalz < hiz+(4<<8)) goalz = ((loz+hiz)>>1); //ceiling&floor too close
if (zmode == 1) posz = goalz;
if (goalz != posz)
{
//if (posz < goalz) hvel += (32<<keystatus[buildkeys[4]]);
//if (posz > goalz) hvel -= (32<<keystatus[buildkeys[4]]);
if (posz < goalz) hvel = ((synctics* 192)<<keystatus[buildkeys[4]]);
if (posz > goalz) hvel = ((synctics*-192)<<keystatus[buildkeys[4]]);
posz += hvel;
if (posz > loz-(4<<8)) posz = loz-(4<<8), hvel = 0;
if (posz < hiz+(4<<8)) posz = hiz+(4<<8), hvel = 0;
}
else
hvel = 0;
}
searchit = 2;
if (searchstat >= 0)
{
if ((bstatus&(1|2|4)) > 0)
searchit = 0;
if (keystatus[0x4a] > 0) // -
{
keystatus[0x4a] = 0;
if ((keystatus[0x38]|keystatus[0xb8]) > 0) //ALT
{
if ((keystatus[0x1d]|keystatus[0x9d]) > 0) //CTRL
{
if (visibility < 16384) visibility += visibility;
}
else
{
if ((keystatus[0x2a]|keystatus[0x36]) == 0)
k = 16; else k = 1;
if (highlightsectorcnt >= 0)
for (i=0;i<highlightsectorcnt;i++)
if (highlightsector[i] == searchsector)
{
while (k > 0)
{
for (i=0;i<highlightsectorcnt;i++)
{
sector[highlightsector[i]].visibility++;
if (sector[highlightsector[i]].visibility == 240)
sector[highlightsector[i]].visibility = 239;
}
k--;
}
break;
}
while (k > 0)
{
sector[searchsector].visibility++;
if (sector[searchsector].visibility == 240)
sector[searchsector].visibility = 239;
k--;
}
asksave = 1;
}
}
else
{
k = 0;
if (highlightsectorcnt >= 0)
{
for (i=0;i<highlightsectorcnt;i++)
if (highlightsector[i] == searchsector)
{
k = 1;
break;
}
}
if (k == 0)
{
if (searchstat == 0) wall[searchwall].shade++;
if (searchstat == 1) sector[searchsector].ceilingshade++;
if (searchstat == 2) sector[searchsector].floorshade++;
if (searchstat == 3) sprite[searchwall].shade++;
if (searchstat == 4) wall[searchwall].shade++;
}
else
{
for (i=0;i<highlightsectorcnt;i++)
{
dasector = highlightsector[i];
sector[dasector].ceilingshade++; //sector shade
sector[dasector].floorshade++;
startwall = sector[dasector].wallptr; //wall shade
endwall = startwall + sector[dasector].wallnum - 1;
for (j=startwall;j<=endwall;j++)
wall[j].shade++;
j = headspritesect[dasector]; //sprite shade
while (j != -1)
{
sprite[j].shade++;
j = nextspritesect[j];
}
}
}
asksave = 1;
}
}
if (keystatus[0x4e] > 0) // +
{
keystatus[0x4e] = 0;
if ((keystatus[0x38]|keystatus[0xb8]) > 0) //ALT
{
if ((keystatus[0x1d]|keystatus[0x9d]) > 0) //CTRL
{
if (visibility > 32) visibility >>= 1;
}
else
{
if ((keystatus[0x2a]|keystatus[0x36]) == 0)
k = 16; else k = 1;
if (highlightsectorcnt >= 0)
for (i=0;i<highlightsectorcnt;i++)
if (highlightsector[i] == searchsector)
{
while (k > 0)
{
for (i=0;i<highlightsectorcnt;i++)
{
sector[highlightsector[i]].visibility--;
if (sector[highlightsector[i]].visibility == 239)
sector[highlightsector[i]].visibility = 240;
}
k--;
}
break;
}
while (k > 0)
{
sector[searchsector].visibility--;
if (sector[searchsector].visibility == 239)
sector[searchsector].visibility = 240;
k--;
}
asksave = 1;
}
}
else
{
k = 0;
if (highlightsectorcnt >= 0)
{
for (i=0;i<highlightsectorcnt;i++)
if (highlightsector[i] == searchsector)
{
k = 1;
break;
}
}
if (k == 0)
{
if (searchstat == 0) wall[searchwall].shade--;
if (searchstat == 1) sector[searchsector].ceilingshade--;
if (searchstat == 2) sector[searchsector].floorshade--;
if (searchstat == 3) sprite[searchwall].shade--;
if (searchstat == 4) wall[searchwall].shade--;
}
else
{
for (i=0;i<highlightsectorcnt;i++)
{
dasector = highlightsector[i];
sector[dasector].ceilingshade--; //sector shade
sector[dasector].floorshade--;
startwall = sector[dasector].wallptr; //wall shade
endwall = startwall + sector[dasector].wallnum - 1;
for (j=startwall;j<=endwall;j++)
wall[j].shade--;
j = headspritesect[dasector]; //sprite shade
while (j != -1)
{
sprite[j].shade--;
j = nextspritesect[j];
}
}
}
asksave = 1;
}
}
if (keystatus[0xc9] > 0) // PGUP
{
k = 0;
if (highlightsectorcnt >= 0)
{
for (i=0;i<highlightsectorcnt;i++)
if (highlightsector[i] == searchsector)
{
k = 1;
break;
}
}
if ((searchstat == 0) || (searchstat == 1))
{
if (k == 0)
{
i = headspritesect[searchsector];
while (i != -1)
{
templong = getceilzofslope(searchsector,sprite[i].x,sprite[i].y);
templong += ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<2);
if (sprite[i].cstat&128) templong += ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1);
if (sprite[i].z == templong)
sprite[i].z -= 1024 << ((keystatus[0x1d]|keystatus[0x9d])<<1); // JBF 20031128
i = nextspritesect[i];
}
sector[searchsector].ceilingz -= 1024 << ((keystatus[0x1d]|keystatus[0x9d])<<1); // JBF 20031128
}
else
{
for (j=0;j<highlightsectorcnt;j++)
{
i = headspritesect[highlightsector[j]];
while (i != -1)
{
templong = getceilzofslope(highlightsector[j],sprite[i].x,sprite[i].y);
templong += ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<2);
if (sprite[i].cstat&128) templong += ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1);
if (sprite[i].z == templong)
sprite[i].z -= 1024 << ((keystatus[0x1d]|keystatus[0x9d])<<1); // JBF 20031128
i = nextspritesect[i];
}
sector[highlightsector[j]].ceilingz -= 1024 << ((keystatus[0x1d]|keystatus[0x9d])<<1); // JBF 20031128
}
}
}
if (searchstat == 2)
{
if (k == 0)
{
i = headspritesect[searchsector];
while (i != -1)
{
templong = getflorzofslope(searchsector,sprite[i].x,sprite[i].y);
if (sprite[i].cstat&128) templong += ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1);
if (sprite[i].z == templong)
sprite[i].z -= 1024 << ((keystatus[0x1d]|keystatus[0x9d])<<1); // JBF 20031128
i = nextspritesect[i];
}
sector[searchsector].floorz -= 1024 << ((keystatus[0x1d]|keystatus[0x9d])<<1); // JBF 20031128
}
else
{
for (j=0;j<highlightsectorcnt;j++)
{
i = headspritesect[highlightsector[j]];
while (i != -1)
{
templong = getflorzofslope(highlightsector[j],sprite[i].x,sprite[i].y);
if (sprite[i].cstat&128) templong += ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1);
if (sprite[i].z == templong)
sprite[i].z -= 1024 << ((keystatus[0x1d]|keystatus[0x9d])<<1); // JBF 20031128
i = nextspritesect[i];
}
sector[highlightsector[j]].floorz -= 1024 << ((keystatus[0x1d]|keystatus[0x9d])<<1); // JBF 20031128
}
}
}
if (sector[searchsector].floorz < sector[searchsector].ceilingz)
sector[searchsector].floorz = sector[searchsector].ceilingz;
if (searchstat == 3)
{
if ((keystatus[0x1d]|keystatus[0x9d]) > 0) //CTRL - put sprite on ceiling
{
sprite[searchwall].z = getceilzofslope(searchsector,sprite[searchwall].x,sprite[searchwall].y);
if (sprite[searchwall].cstat&128) sprite[searchwall].z -= ((tilesizy[sprite[searchwall].picnum]*sprite[searchwall].yrepeat)<<1);
if ((sprite[searchwall].cstat&48) != 32)
sprite[searchwall].z += ((tilesizy[sprite[searchwall].picnum]*sprite[searchwall].yrepeat)<<2);
}
else
{
k = 0;
if (highlightcnt >= 0)
for (i=0;i<highlightcnt;i++)
if (highlight[i] == searchwall+16384)
{
k = 1;
break;
}
if (k == 0)
sprite[searchwall].z -= (4<<8);
else
{
for (i=0;i<highlightcnt;i++)
if ((highlight[i]&0xc000) == 16384)
sprite[highlight[i]&16383].z -= (4<<8);
}
}
}
asksave = 1;
keystatus[0xc9] = 0;
}
if (keystatus[0xd1] > 0) // PGDN
{
k = 0;
if (highlightsectorcnt >= 0)
{
for (i=0;i<highlightsectorcnt;i++)
if (highlightsector[i] == searchsector)
{
k = 1;
break;
}
}
if ((searchstat == 0) || (searchstat == 1))
{
if (k == 0)
{
i = headspritesect[searchsector];
while (i != -1)
{
templong = getceilzofslope(searchsector,sprite[i].x,sprite[i].y);
if (sprite[i].cstat&128) templong += ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1);
templong += ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<2);
if (sprite[i].z == templong)
sprite[i].z += 1024 << ((keystatus[0x1d]|keystatus[0x9d])<<1); // JBF 20031128
i = nextspritesect[i];
}
sector[searchsector].ceilingz += 1024 << ((keystatus[0x1d]|keystatus[0x9d])<<1); // JBF 20031128
}
else
{
for (j=0;j<highlightsectorcnt;j++)
{
i = headspritesect[highlightsector[j]];
while (i != -1)
{
templong = getceilzofslope(highlightsector[j],sprite[i].x,sprite[i].y);
if (sprite[i].cstat&128) templong += ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1);
templong += ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<2);
if (sprite[i].z == templong)
sprite[i].z += 1024 << ((keystatus[0x1d]|keystatus[0x9d])<<1); // JBF 20031128
i = nextspritesect[i];
}
sector[highlightsector[j]].ceilingz += 1024 << ((keystatus[0x1d]|keystatus[0x9d])<<1); // JBF 20031128
}
}
}
if (searchstat == 2)
{
if (k == 0)
{
i = headspritesect[searchsector];
while (i != -1)
{
templong = getflorzofslope(searchsector,sprite[i].x,sprite[i].y);
if (sprite[i].cstat&128) templong += ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1);
if (sprite[i].z == templong)
sprite[i].z += 1024 << ((keystatus[0x1d]|keystatus[0x9d])<<1); // JBF 20031128
i = nextspritesect[i];
}
sector[searchsector].floorz += 1024 << ((keystatus[0x1d]|keystatus[0x9d])<<1); // JBF 20031128
}
else
{
for (j=0;j<highlightsectorcnt;j++)
{
i = headspritesect[highlightsector[j]];
while (i != -1)
{
templong = getflorzofslope(highlightsector[j],sprite[i].x,sprite[i].y);
if (sprite[i].cstat&128) templong += ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1);
if (sprite[i].z == templong)
sprite[i].z += 1024 << ((keystatus[0x1d]|keystatus[0x9d])<<1); // JBF 20031128
i = nextspritesect[i];
}
sector[highlightsector[j]].floorz += 1024 << ((keystatus[0x1d]|keystatus[0x9d])<<1); // JBF 20031128
}
}
}
if (sector[searchsector].ceilingz > sector[searchsector].floorz)
sector[searchsector].ceilingz = sector[searchsector].floorz;
if (searchstat == 3)
{
if ((keystatus[0x1d]|keystatus[0x9d]) > 0) //CTRL - put sprite on ground
{
sprite[searchwall].z = getflorzofslope(searchsector,sprite[searchwall].x,sprite[searchwall].y);
if (sprite[searchwall].cstat&128) sprite[searchwall].z -= ((tilesizy[sprite[searchwall].picnum]*sprite[searchwall].yrepeat)<<1);
}
else
{
k = 0;
if (highlightcnt >= 0)
for (i=0;i<highlightcnt;i++)
if (highlight[i] == searchwall+16384)
{
k = 1;
break;
}
if (k == 0)
sprite[searchwall].z += (4<<8);
else
{
for (i=0;i<highlightcnt;i++)
if ((highlight[i]&0xc000) == 16384)
sprite[highlight[i]&16383].z += (4<<8);
}
}
}
asksave = 1;
keystatus[0xd1] = 0;
}
if (keystatus[0x0f] > 0) //TAB
{
if (searchstat == 0)
{
temppicnum = wall[searchwall].picnum;
tempshade = wall[searchwall].shade;
temppal = wall[searchwall].pal;
tempxrepeat = wall[searchwall].xrepeat;
tempyrepeat = wall[searchwall].yrepeat;
tempcstat = wall[searchwall].cstat;
templotag = wall[searchwall].lotag;
temphitag = wall[searchwall].hitag;
tempextra = wall[searchwall].extra;
}
if (searchstat == 1)
{
temppicnum = sector[searchsector].ceilingpicnum;
tempshade = sector[searchsector].ceilingshade;
temppal = sector[searchsector].ceilingpal;
tempvis = sector[searchsector].visibility;
tempxrepeat = sector[searchsector].ceilingxpanning;
tempyrepeat = sector[searchsector].ceilingypanning;
tempcstat = sector[searchsector].ceilingstat;
templotag = sector[searchsector].lotag;
temphitag = sector[searchsector].hitag;
tempextra = sector[searchsector].extra;
}
if (searchstat == 2)
{
temppicnum = sector[searchsector].floorpicnum;
tempshade = sector[searchsector].floorshade;
temppal = sector[searchsector].floorpal;
tempvis = sector[searchsector].visibility;
tempxrepeat = sector[searchsector].floorxpanning;
tempyrepeat = sector[searchsector].floorypanning;
tempcstat = sector[searchsector].floorstat;
templotag = sector[searchsector].lotag;
temphitag = sector[searchsector].hitag;
tempextra = sector[searchsector].extra;
}
if (searchstat == 3)
{
temppicnum = sprite[searchwall].picnum;
tempshade = sprite[searchwall].shade;
temppal = sprite[searchwall].pal;
tempxrepeat = sprite[searchwall].xrepeat;
tempyrepeat = sprite[searchwall].yrepeat;
tempcstat = sprite[searchwall].cstat;
templotag = sprite[searchwall].lotag;
temphitag = sprite[searchwall].hitag;
tempextra = sprite[searchwall].extra;
}
if (searchstat == 4)
{
temppicnum = wall[searchwall].overpicnum;
tempshade = wall[searchwall].shade;
temppal = wall[searchwall].pal;
tempxrepeat = wall[searchwall].xrepeat;
tempyrepeat = wall[searchwall].yrepeat;
tempcstat = wall[searchwall].cstat;
templotag = wall[searchwall].lotag;
temphitag = wall[searchwall].hitag;
tempextra = wall[searchwall].extra;
}
somethingintab = searchstat;
keystatus[0x0f] = 0;
}
if (keystatus[0x1c] > 0) //Left ENTER
{
if ((keystatus[0x2a]|keystatus[0x36]) > 0) //Either shift key
{
if (((searchstat == 0) || (searchstat == 4)) && ((keystatus[0x1d]|keystatus[0x9d]) > 0)) //Ctrl-shift Enter (auto-shade)
{
dashade[0] = 127;
dashade[1] = -128;
i = searchwall;
do
{
if ((long)wall[i].shade < dashade[0]) dashade[0] = wall[i].shade;
if ((long)wall[i].shade > dashade[1]) dashade[1] = wall[i].shade;
i = wall[i].point2;
}
while (i != searchwall);
daang = getangle(wall[wall[searchwall].point2].x-wall[searchwall].x,wall[wall[searchwall].point2].y-wall[searchwall].y);
i = searchwall;
do
{
j = getangle(wall[wall[i].point2].x-wall[i].x,wall[wall[i].point2].y-wall[i].y);
k = ((j+2048-daang)&2047);
if (k > 1024)
k = 2048-k;
wall[i].shade = dashade[0]+mulscale10(k,dashade[1]-dashade[0]);
i = wall[i].point2;
}
while (i != searchwall);
}
else if (somethingintab < 255)
{
if (searchstat == 0) wall[searchwall].shade = tempshade, wall[searchwall].pal = temppal;
if (searchstat == 1)
{
sector[searchsector].ceilingshade = tempshade, sector[searchsector].ceilingpal = temppal;
if ((somethingintab == 1) || (somethingintab == 2))
sector[searchsector].visibility = tempvis;
}
if (searchstat == 2)
{
sector[searchsector].floorshade = tempshade, sector[searchsector].floorpal = temppal;
if ((somethingintab == 1) || (somethingintab == 2))
sector[searchsector].visibility = tempvis;
}
if (searchstat == 3) sprite[searchwall].shade = tempshade, sprite[searchwall].pal = temppal;
if (searchstat == 4) wall[searchwall].shade = tempshade, wall[searchwall].pal = temppal;
}
}
else if (((searchstat == 0) || (searchstat == 4)) && ((keystatus[0x1d]|keystatus[0x9d]) > 0) && (somethingintab < 255)) //Either ctrl key
{
i = searchwall;
do
{
wall[i].picnum = temppicnum;
wall[i].shade = tempshade;
wall[i].pal = temppal;
if ((somethingintab == 0) || (somethingintab == 4))
{
wall[i].xrepeat = tempxrepeat;
wall[i].yrepeat = tempyrepeat;
wall[i].cstat = tempcstat;
}
fixrepeats((short)i);
i = wall[i].point2;
}
while (i != searchwall);
}
else if (((searchstat == 1) || (searchstat == 2)) && ((keystatus[0x1d]|keystatus[0x9d]) > 0) && (somethingintab < 255)) //Either ctrl key
{
clearbuf(&pskysearch[0],(long)((numsectors+3)>>2),0L);
if (searchstat == 1)
{
i = searchsector;
if ((sector[i].ceilingstat&1) > 0)
pskysearch[i] = 1;
while (pskysearch[i] == 1)
{
sector[i].ceilingpicnum = temppicnum;
sector[i].ceilingshade = tempshade;
sector[i].ceilingpal = temppal;
if ((somethingintab == 1) || (somethingintab == 2))
{
sector[i].ceilingxpanning = tempxrepeat;
sector[i].ceilingypanning = tempyrepeat;
sector[i].ceilingstat = tempcstat;
}
pskysearch[i] = 2;
startwall = sector[i].wallptr;
endwall = startwall + sector[i].wallnum - 1;
for (j=startwall;j<=endwall;j++)
{
k = wall[j].nextsector;
if (k >= 0)
if ((sector[k].ceilingstat&1) > 0)
if (pskysearch[k] == 0)
pskysearch[k] = 1;
}
for (j=0;j<numsectors;j++)
if (pskysearch[j] == 1)
i = j;
}
}
if (searchstat == 2)
{
i = searchsector;
if ((sector[i].floorstat&1) > 0)
pskysearch[i] = 1;
while (pskysearch[i] == 1)
{
sector[i].floorpicnum = temppicnum;
sector[i].floorshade = tempshade;
sector[i].floorpal = temppal;
if ((somethingintab == 1) || (somethingintab == 2))
{
sector[i].floorxpanning = tempxrepeat;
sector[i].floorypanning = tempyrepeat;
sector[i].floorstat = tempcstat;
}
pskysearch[i] = 2;
startwall = sector[i].wallptr;
endwall = startwall + sector[i].wallnum - 1;
for (j=startwall;j<=endwall;j++)
{
k = wall[j].nextsector;
if (k >= 0)
if ((sector[k].floorstat&1) > 0)
if (pskysearch[k] == 0)
pskysearch[k] = 1;
}
for (j=0;j<numsectors;j++)
if (pskysearch[j] == 1)
i = j;
}
}
}
else if (somethingintab < 255)
{
if (searchstat == 0)
{
wall[searchwall].picnum = temppicnum;
wall[searchwall].shade = tempshade;
wall[searchwall].pal = temppal;
if (somethingintab == 0)
{
wall[searchwall].xrepeat = tempxrepeat;
wall[searchwall].yrepeat = tempyrepeat;
wall[searchwall].cstat = tempcstat;
wall[searchwall].lotag = templotag;
wall[searchwall].hitag = temphitag;
wall[searchwall].extra = tempextra;
}
fixrepeats(searchwall);
}
if (searchstat == 1)
{
sector[searchsector].ceilingpicnum = temppicnum;
sector[searchsector].ceilingshade = tempshade;
sector[searchsector].ceilingpal = temppal;
if ((somethingintab == 1) || (somethingintab == 2))
{
sector[searchsector].ceilingxpanning = tempxrepeat;
sector[searchsector].ceilingypanning = tempyrepeat;
sector[searchsector].ceilingstat = tempcstat;
sector[searchsector].visibility = tempvis;
sector[searchsector].lotag = templotag;
sector[searchsector].hitag = temphitag;
sector[searchsector].extra = tempextra;
}
}
if (searchstat == 2)
{
sector[searchsector].floorpicnum = temppicnum;
sector[searchsector].floorshade = tempshade;
sector[searchsector].floorpal = temppal;
if ((somethingintab == 1) || (somethingintab == 2))
{
sector[searchsector].floorxpanning= tempxrepeat;
sector[searchsector].floorypanning= tempyrepeat;
sector[searchsector].floorstat = tempcstat;
sector[searchsector].visibility = tempvis;
sector[searchsector].lotag = templotag;
sector[searchsector].hitag = temphitag;
sector[searchsector].extra = tempextra;
}
}
if (searchstat == 3)
{
sprite[searchwall].picnum = temppicnum;
if ((tilesizx[temppicnum] <= 0) || (tilesizy[temppicnum] <= 0))
{
j = 0;
for (k=0;k<MAXTILES;k++)
if ((tilesizx[k] > 0) && (tilesizy[k] > 0))
{
j = k;
break;
}
sprite[searchwall].picnum = j;
}
sprite[searchwall].shade = tempshade;
sprite[searchwall].pal = temppal;
if (somethingintab == 3)
{
sprite[searchwall].xrepeat = tempxrepeat;
sprite[searchwall].yrepeat = tempyrepeat;
if (sprite[searchwall].xrepeat < 1) sprite[searchwall].xrepeat = 1;
if (sprite[searchwall].yrepeat < 1) sprite[searchwall].yrepeat = 1;
sprite[searchwall].cstat = tempcstat;
sprite[searchwall].lotag = templotag;
sprite[searchwall].hitag = temphitag;
sprite[searchwall].extra = tempextra;
}
}
if (searchstat == 4)
{
wall[searchwall].overpicnum = temppicnum;
if (wall[searchwall].nextwall >= 0)
wall[wall[searchwall].nextwall].overpicnum = temppicnum;
wall[searchwall].shade = tempshade;
wall[searchwall].pal = temppal;
if (somethingintab == 4)
{
wall[searchwall].xrepeat = tempxrepeat;
wall[searchwall].yrepeat = tempyrepeat;
wall[searchwall].cstat = tempcstat;
wall[searchwall].lotag = templotag;
wall[searchwall].hitag = temphitag;
wall[searchwall].extra = tempextra;
}
fixrepeats(searchwall);
}
}
asksave = 1;
keystatus[0x1c] = 0;
}
if (keystatus[0x2e] > 0) //C
{
keystatus[0x2e] = 0;
if (keystatus[0x38] > 0) //Alt-C
{
if (somethingintab < 255)
{
switch (searchstat)
{
case 0:
j = wall[searchwall].picnum;
for (i=0;i<numwalls;i++)
if (wall[i].picnum == j) wall[i].picnum = temppicnum;
break;
case 1:
j = sector[searchsector].ceilingpicnum;
for (i=0;i<numsectors;i++)
if (sector[i].ceilingpicnum == j) sector[i].ceilingpicnum = temppicnum;
break;
case 2:
j = sector[searchsector].floorpicnum;
for (i=0;i<numsectors;i++)
if (sector[i].floorpicnum == j) sector[i].floorpicnum = temppicnum;
break;
case 3:
j = sprite[searchwall].picnum;
for (i=0;i<MAXSPRITES;i++)
if (sprite[i].statnum < MAXSTATUS)
if (sprite[i].picnum == j) sprite[i].picnum = temppicnum;
break;
case 4:
j = wall[searchwall].overpicnum;
for (i=0;i<numwalls;i++)
if (wall[i].overpicnum == j) wall[i].overpicnum = temppicnum;
break;
}
}
}
else //C
{
if (searchstat == 3)
{
sprite[searchwall].cstat ^= 128;
asksave = 1;
}
}
}
if (keystatus[0x2f] > 0) //V
{
if (searchstat == 0) templong = wall[searchwall].picnum;
if (searchstat == 1) templong = sector[searchsector].ceilingpicnum;
if (searchstat == 2) templong = sector[searchsector].floorpicnum;
if (searchstat == 3) templong = sprite[searchwall].picnum;
if (searchstat == 4) templong = wall[searchwall].overpicnum;
templong = gettile(templong);
if (searchstat == 0) wall[searchwall].picnum = templong;
if (searchstat == 1) sector[searchsector].ceilingpicnum = templong;
if (searchstat == 2) sector[searchsector].floorpicnum = templong;
if (searchstat == 3) sprite[searchwall].picnum = templong;
if (searchstat == 4)
{
wall[searchwall].overpicnum = templong;
if (wall[searchwall].nextwall >= 0)
wall[wall[searchwall].nextwall].overpicnum = templong;
}
asksave = 1;
keystatus[0x2f] = 0;
}
if (keystatus[0x1a]) // [
{
keystatus[0x1a] = 0;
if (keystatus[0x38]|keystatus[0xb8])
{
i = wall[searchwall].nextsector;
if (i >= 0)
switch (searchstat)
{
case 0:
case 1:
case 4:
alignceilslope(searchsector,wall[searchwall].x,wall[searchwall].y,getceilzofslope(i,wall[searchwall].x,wall[searchwall].y));
break;
case 2:
alignflorslope(searchsector,wall[searchwall].x,wall[searchwall].y,getflorzofslope(i,wall[searchwall].x,wall[searchwall].y));
break;
}
}
else
{
i = 512;
if (keystatus[0x36]) i = 8;
if (keystatus[0x2a]) i = 1;
if (searchstat == 1)
{
if (!(sector[searchsector].ceilingstat&2))
sector[searchsector].ceilingheinum = 0;
sector[searchsector].ceilingheinum = max(sector[searchsector].ceilingheinum-i,-32768);
}
if (searchstat == 2)
{
if (!(sector[searchsector].floorstat&2))
sector[searchsector].floorheinum = 0;
sector[searchsector].floorheinum = max(sector[searchsector].floorheinum-i,-32768);
}
}
if (sector[searchsector].ceilingheinum == 0)
sector[searchsector].ceilingstat &= ~2;
else
sector[searchsector].ceilingstat |= 2;
if (sector[searchsector].floorheinum == 0)
sector[searchsector].floorstat &= ~2;
else
sector[searchsector].floorstat |= 2;
asksave = 1;
}
if (keystatus[0x1b]) // ]
{
keystatus[0x1b] = 0;
if (keystatus[0x38]|keystatus[0xb8])
{
i = wall[searchwall].nextsector;
if (i >= 0)
switch (searchstat)
{
case 1:
alignceilslope(searchsector,wall[searchwall].x,wall[searchwall].y,getceilzofslope(i,wall[searchwall].x,wall[searchwall].y));
break;
case 0:
case 2:
case 4:
alignflorslope(searchsector,wall[searchwall].x,wall[searchwall].y,getflorzofslope(i,wall[searchwall].x,wall[searchwall].y));
break;
}
}
else
{
i = 512;
if (keystatus[0x36]) i = 8;
if (keystatus[0x2a]) i = 1;
if (searchstat == 1)
{
if (!(sector[searchsector].ceilingstat&2))
sector[searchsector].ceilingheinum = 0;
sector[searchsector].ceilingheinum = min(sector[searchsector].ceilingheinum+i,32767);
}
if (searchstat == 2)
{
if (!(sector[searchsector].floorstat&2))
sector[searchsector].floorheinum = 0;
sector[searchsector].floorheinum = min(sector[searchsector].floorheinum+i,32767);
}
}
if (sector[searchsector].ceilingheinum == 0)
sector[searchsector].ceilingstat &= ~2;
else
sector[searchsector].ceilingstat |= 2;
if (sector[searchsector].floorheinum == 0)
sector[searchsector].floorstat &= ~2;
else
sector[searchsector].floorstat |= 2;
asksave = 1;
}
smooshyalign = keystatus[0x4c];
repeatpanalign = (keystatus[0x2a]|keystatus[0x36]);
if ((keystatus[0x4b]|keystatus[0x4d]) > 0) // 4 & 6 (keypad)
{
if ((repeatcountx == 0) || (repeatcountx > 16))
{
changedir = 0;
if (keystatus[0x4b] > 0) changedir = -1;
if (keystatus[0x4d] > 0) changedir = 1;
if ((searchstat == 0) || (searchstat == 4))
{
if (repeatpanalign == 0)
wall[searchwall].xrepeat = changechar(wall[searchwall].xrepeat,changedir,smooshyalign,1);
else
wall[searchwall].xpanning = changechar(wall[searchwall].xpanning,changedir,smooshyalign,0);
}
if ((searchstat == 1) || (searchstat == 2))
{
if (searchstat == 1)
sector[searchsector].ceilingxpanning = changechar(sector[searchsector].ceilingxpanning,changedir,smooshyalign,0);
else
sector[searchsector].floorxpanning = changechar(sector[searchsector].floorxpanning,changedir,smooshyalign,0);
}
if (searchstat == 3)
{
sprite[searchwall].xrepeat = changechar(sprite[searchwall].xrepeat,changedir,smooshyalign,1);
if (sprite[searchwall].xrepeat < 4)
sprite[searchwall].xrepeat = 4;
}
asksave = 1;
repeatcountx = max(1,repeatcountx);
}
repeatcountx += (synctics>>1);
}
else
repeatcountx = 0;
if ((keystatus[0x48]|keystatus[0x50]) > 0) // 2 & 8 (keypad)
{
if ((repeatcounty == 0) || (repeatcounty > 16))
{
changedir = 0;
if (keystatus[0x48] > 0) changedir = -1;
if (keystatus[0x50] > 0) changedir = 1;
if ((searchstat == 0) || (searchstat == 4))
{
if (repeatpanalign == 0)
wall[searchwall].yrepeat = changechar(wall[searchwall].yrepeat,changedir,smooshyalign,1);
else
wall[searchwall].ypanning = changechar(wall[searchwall].ypanning,changedir,smooshyalign,0);
}
if ((searchstat == 1) || (searchstat == 2))
{
if (searchstat == 1)
sector[searchsector].ceilingypanning = changechar(sector[searchsector].ceilingypanning,changedir,smooshyalign,0);
else
sector[searchsector].floorypanning = changechar(sector[searchsector].floorypanning,changedir,smooshyalign,0);
}
if (searchstat == 3)
{
sprite[searchwall].yrepeat = changechar(sprite[searchwall].yrepeat,changedir,smooshyalign,1);
if (sprite[searchwall].yrepeat < 4)
sprite[searchwall].yrepeat = 4;
}
asksave = 1;
repeatcounty = max(1,repeatcounty);
}
repeatcounty += (synctics>>1);
//}
}
else
repeatcounty = 0;
if (keystatus[0x33] > 0) // , Search & fix panning to the left (3D)
{
if (searchstat == 3)
{
i = searchwall;
if ((keystatus[0x2a]|keystatus[0x36]) > 0)
sprite[i].ang = ((sprite[i].ang+2048-1)&2047);
else
{
sprite[i].ang = ((sprite[i].ang+2048-128)&2047);
keystatus[0x33] = 0;
}
}
}
if (keystatus[0x34] > 0) // . Search & fix panning to the right (3D)
{
if ((searchstat == 0) || (searchstat == 4))
{
AutoAlignWalls((long)searchwall,0L);
/*wallfind[0] = searchwall;
cnt = 4096;
do
{
wallfind[1] = wall[wallfind[0]].point2;
j = -1;
if (wall[wallfind[1]].picnum == wall[searchwall].picnum)
j = wallfind[1];
k = wallfind[1];
while ((wall[wallfind[1]].nextwall >= 0) && (wall[wall[wallfind[1]].nextwall].point2 != k))
{
i = wall[wall[wallfind[1]].nextwall].point2; //break if going around in circles on red lines with same picture on both sides
if (wallfind[1] == wall[wall[i].nextwall].point2)
break;
wallfind[1] = wall[wall[wallfind[1]].nextwall].point2;
if (wall[wallfind[1]].picnum == wall[searchwall].picnum)
j = wallfind[1];
}
wallfind[1] = j;
if ((j >= 0) && (wallfind[1] != searchwall))
{
j = (wall[wallfind[0]].xpanning+(wall[wallfind[0]].xrepeat<<3)) % tilesizx[wall[wallfind[0]].picnum];
wall[wallfind[1]].cstat &= ~8; //Set to non-flip
wall[wallfind[1]].cstat |= 4; //Set y-orientation
wall[wallfind[1]].xpanning = j;
for(k=0;k<2;k++)
{
sectnum = sectorofwall((short)wallfind[k]);
nextsectnum = wall[wallfind[k]].nextsector;
if (nextsectnum == -1)
{
if ((wall[wallfind[k]].cstat&4) == 0)
daz[k] = sector[sectnum].ceilingz;
else
daz[k] = sector[sectnum].floorz;
}
else //topstep
{
if (sector[nextsectnum].ceilingz > sector[sectnum].ceilingz)
daz[k] = sector[nextsectnum].ceilingz;
else if (sector[nextsectnum].floorz < sector[sectnum].floorz)
daz[k] = sector[nextsectnum].floorz;
}
}
j = (picsiz[wall[searchwall].picnum]>>4);
if ((1<<j) != tilesizy[wall[searchwall].picnum]) j++;
j = ((wall[wallfind[0]].ypanning+(((daz[1]-daz[0])*wall[wallfind[0]].yrepeat)>>(j+3)))&255);
wall[wallfind[1]].ypanning = j;
wall[wallfind[1]].yrepeat = wall[wallfind[0]].yrepeat;
if (nextsectnum >= 0)
if (sector[nextsectnum].ceilingz >= sector[sectnum].ceilingz)
if (sector[nextsectnum].floorz <= sector[sectnum].floorz)
{
if (wall[wall[wallfind[1]].nextwall].picnum == wall[searchwall].picnum)
{
wall[wall[wallfind[1]].nextwall].yrepeat = wall[wallfind[0]].yrepeat;
if ((wall[wall[wallfind[1]].nextwall].cstat&4) == 0)
daz[1] = sector[nextsectnum].floorz;
else
daz[1] = sector[sectnum].ceilingz;
wall[wall[wallfind[1]].nextwall].ypanning = j;
}
}
}
wallfind[0] = wallfind[1];
cnt--;
}
while ((wall[wallfind[0]].picnum == wall[searchwall].picnum) && (wallfind[0] != searchwall) && (cnt > 0));
*/
keystatus[0x34] = 0;
}
if (searchstat == 3)
{
i = searchwall;
if ((keystatus[0x2a]|keystatus[0x36]) > 0)
sprite[i].ang = ((sprite[i].ang+2048+1)&2047);
else
{
sprite[i].ang = ((sprite[i].ang+2048+128)&2047);
keystatus[0x34] = 0;
}
}
}
if (keystatus[0x35] > 0) // /? Reset panning&repeat to 0
{
if ((searchstat == 0) || (searchstat == 4))
{
wall[searchwall].xpanning = 0;
wall[searchwall].ypanning = 0;
wall[searchwall].xrepeat = 8;
wall[searchwall].yrepeat = 8;
wall[searchwall].cstat = 0;
fixrepeats((short)searchwall);
}
if (searchstat == 1)
{
sector[searchsector].ceilingxpanning = 0;
sector[searchsector].ceilingypanning = 0;
sector[searchsector].ceilingstat &= ~2;
sector[searchsector].ceilingheinum = 0;
}
if (searchstat == 2)
{
sector[searchsector].floorxpanning = 0;
sector[searchsector].floorypanning = 0;
sector[searchsector].floorstat &= ~2;
sector[searchsector].floorheinum = 0;
}
if (searchstat == 3)
{
if ((keystatus[0x2a]|keystatus[0x36]) > 0)
{
sprite[searchwall].xrepeat = sprite[searchwall].yrepeat;
}
else
{
sprite[searchwall].xrepeat = 64;
sprite[searchwall].yrepeat = 64;
}
}
keystatus[0x35] = 0;
asksave = 1;
}
if (keystatus[0x19] > 0) // P (parallaxing sky)
{
if ((keystatus[0x1d]|keystatus[0x9d]) > 0)
{
parallaxtype++;
if (parallaxtype == 3)
parallaxtype = 0;
}
else if ((keystatus[0x38]|keystatus[0xb8]) > 0)
{
switch (searchstat)
{
case 0:
case 4:
Bstrcpy(buffer,"Wall pal: ");
wall[searchwall].pal = getnumber256(buffer,wall[searchwall].pal,256L,0);
break;
case 1:
Bstrcpy(buffer,"Ceiling pal: ");
sector[searchsector].ceilingpal = getnumber256(buffer,sector[searchsector].ceilingpal,256L,0);
break;
case 2:
Bstrcpy(buffer,"Floor pal: ");
sector[searchsector].floorpal = getnumber256(buffer,sector[searchsector].floorpal,256L,0);
break;
case 3:
Bstrcpy(buffer,"Sprite pal: ");
sprite[searchwall].pal = getnumber256(buffer,sprite[searchwall].pal,256L,0);
break;
}
}
else
{
if ((searchstat == 0) || (searchstat == 1) || (searchstat == 4))
{
sector[searchsector].ceilingstat ^= 1;
asksave = 1;
}
else if (searchstat == 2)
{
sector[searchsector].floorstat ^= 1;
asksave = 1;
}
}
keystatus[0x19] = 0;
}
if (keystatus[0x20] != 0) //Alt-D (adjust sprite[].clipdist)
{
keystatus[0x20] = 0;
if ((keystatus[0x38]|keystatus[0xb8]) > 0)
{
if (searchstat == 3)
{
Bstrcpy(buffer,"Sprite clipdist: ");
sprite[searchwall].clipdist = getnumber256(buffer,sprite[searchwall].clipdist,256L,0);
}
}
}
if (keystatus[0x30] > 0) // B (clip Blocking xor) (3D)
{
if (searchstat == 3)
{
sprite[searchwall].cstat ^= 1;
sprite[searchwall].cstat &= ~256;
sprite[searchwall].cstat |= ((sprite[searchwall].cstat&1)<<8);
asksave = 1;
}
else
{
wall[searchwall].cstat ^= 1;
wall[searchwall].cstat &= ~64;
if ((wall[searchwall].nextwall >= 0) && ((keystatus[0x2a]|keystatus[0x36]) == 0))
{
wall[wall[searchwall].nextwall].cstat &= ~(1+64);
wall[wall[searchwall].nextwall].cstat |= (wall[searchwall].cstat&1);
}
asksave = 1;
}
keystatus[0x30] = 0;
}
if (keystatus[0x14] > 0) // T (transluscence for sprites/masked walls)
{
/*if (searchstat == 1) //Set masked/transluscent ceilings/floors
{
i = (sector[searchsector].ceilingstat&(128+256));
sector[searchsector].ceilingstat &= ~(128+256);
switch(i)
{
case 0: sector[searchsector].ceilingstat |= 128; break;
case 128: sector[searchsector].ceilingstat |= 256; break;
case 256: sector[searchsector].ceilingstat |= 384; break;
case 384: sector[searchsector].ceilingstat |= 0; break;
}
asksave = 1;
}
if (searchstat == 2)
{
i = (sector[searchsector].floorstat&(128+256));
sector[searchsector].floorstat &= ~(128+256);
switch(i)
{
case 0: sector[searchsector].floorstat |= 128; break;
case 128: sector[searchsector].floorstat |= 256; break;
case 256: sector[searchsector].floorstat |= 384; break;
case 384: sector[searchsector].floorstat |= 0; break;
}
asksave = 1;
}*/
if (searchstat == 3)
{
if ((sprite[searchwall].cstat&2) == 0)
sprite[searchwall].cstat |= 2;
else if ((sprite[searchwall].cstat&512) == 0)
sprite[searchwall].cstat |= 512;
else
sprite[searchwall].cstat &= ~(2+512);
asksave = 1;
}
if (searchstat == 4)
{
if ((wall[searchwall].cstat&128) == 0)
wall[searchwall].cstat |= 128;
else if ((wall[searchwall].cstat&512) == 0)
wall[searchwall].cstat |= 512;
else
wall[searchwall].cstat &= ~(128+512);
if (wall[searchwall].nextwall >= 0)
{
wall[wall[searchwall].nextwall].cstat &= ~(128+512);
wall[wall[searchwall].nextwall].cstat |= (wall[searchwall].cstat&(128+512));
}
asksave = 1;
}
keystatus[0x14] = 0;
}
if (keystatus[0x2] > 0) // 1 (make 1-way wall)
{
if (searchstat != 3)
{
wall[searchwall].cstat ^= 32;
asksave = 1;
}
else
{
sprite[searchwall].cstat ^= 64;
i = sprite[searchwall].cstat;
if ((i&48) == 32)
{
sprite[searchwall].cstat &= ~8;
if ((i&64) > 0)
if (posz > sprite[searchwall].z)
sprite[searchwall].cstat |= 8;
}
asksave = 1;
}
keystatus[0x2] = 0;
}
if (keystatus[0x3] > 0) // 2 (bottom wall swapping)
{
if (searchstat != 3)
{
wall[searchwall].cstat ^= 2;
asksave = 1;
}
keystatus[0x3] = 0;
}
if (keystatus[0x18] > 0) // O (top/bottom orientation - for doors)
{
if ((searchstat == 0) || (searchstat == 4))
{
wall[searchwall].cstat ^= 4;
asksave = 1;
}
if (searchstat == 3) // O (ornament onto wall) (2D)
{
asksave = 1;
i = searchwall;
hitscan(sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].sectnum,
sintable[(sprite[i].ang+2560+1024)&2047],
sintable[(sprite[i].ang+2048+1024)&2047],
0,
&hitsect,&hitwall,&hitsprite,&hitx,&hity,&hitz,CLIPMASK1);
sprite[i].x = hitx;
sprite[i].y = hity;
sprite[i].z = hitz;
changespritesect(i,hitsect);
if (hitwall >= 0)
sprite[i].ang = ((getangle(wall[wall[hitwall].point2].x-wall[hitwall].x,wall[wall[hitwall].point2].y-wall[hitwall].y)+512)&2047);
//Make sure sprite's in right sector
if (inside(sprite[i].x,sprite[i].y,sprite[i].sectnum) == 0)
{
j = wall[hitwall].point2;
sprite[i].x -= ksgn(wall[j].y-wall[hitwall].y);
sprite[i].y += ksgn(wall[j].x-wall[hitwall].x);
}
}
keystatus[0x18] = 0;
}
if (keystatus[0x32] > 0) // M (masking walls)
{
if (searchstat != 3)
{
i = wall[searchwall].nextwall;
templong = (keystatus[0x2a]|keystatus[0x36]);
if (i >= 0)
{
wall[searchwall].cstat ^= 16;
if ((wall[searchwall].cstat&16) > 0)
{
wall[searchwall].cstat &= ~8;
if (templong == 0)
{
wall[i].cstat |= 8; //auto other-side flip
wall[i].cstat |= 16;
wall[i].overpicnum = wall[searchwall].overpicnum;
}
}
else
{
wall[searchwall].cstat &= ~8;
if (templong == 0)
{
wall[i].cstat &= ~8; //auto other-side unflip
wall[i].cstat &= ~16;
}
}
wall[searchwall].cstat &= ~32;
if (templong == 0) wall[i].cstat &= ~32;
asksave = 1;
}
}
keystatus[0x32] = 0;
}
if (keystatus[0x23] > 0) // H (hitscan sensitivity)
{
if (searchstat == 3)
{
sprite[searchwall].cstat ^= 256;
asksave = 1;
}
else
{
wall[searchwall].cstat ^= 64;
if ((wall[searchwall].nextwall >= 0) && ((keystatus[0x2a]|keystatus[0x36]) == 0))
{
wall[wall[searchwall].nextwall].cstat &= ~64;
wall[wall[searchwall].nextwall].cstat |= (wall[searchwall].cstat&64);
}
asksave = 1;
}
keystatus[0x23] = 0;
}
if (keystatus[0x12] > 0) // E (expand)
{
if (searchstat == 1)
{
sector[searchsector].ceilingstat ^= 8;
asksave = 1;
}
if (searchstat == 2)
{
sector[searchsector].floorstat ^= 8;
asksave = 1;
}
keystatus[0x12] = 0;
}
if (keystatus[0x13] > 0) // R (relative alignment, rotation)
{
if (searchstat == 1)
{
sector[searchsector].ceilingstat ^= 64;
asksave = 1;
}
if (searchstat == 2)
{
sector[searchsector].floorstat ^= 64;
asksave = 1;
}
if (searchstat == 3)
{
i = sprite[searchwall].cstat;
if ((i&48) < 32) i += 16; else i &= ~48;
sprite[searchwall].cstat = i;
asksave = 1;
}
keystatus[0x13] = 0;
}
if (keystatus[0x21] > 0) //F (Flip)
{
keystatus[0x21] = 0;
if ((keystatus[0x38]|keystatus[0xb8]) > 0) //ALT-F (relative alignmment flip)
{
if (searchstat != 3)
{
setfirstwall(searchsector,searchwall);
asksave = 1;
}
}
else
{
if ((searchstat == 0) || (searchstat == 4))
{
i = wall[searchwall].cstat;
i = ((i>>3)&1)+((i>>7)&2); //3-x,8-y
switch (i)
{
case 0:
i = 1; break;
case 1:
i = 3; break;
case 2:
i = 0; break;
case 3:
i = 2; break;
}
i = ((i&1)<<3)+((i&2)<<7);
wall[searchwall].cstat &= ~0x0108;
wall[searchwall].cstat |= i;
asksave = 1;
}
if (searchstat == 1) //8-way ceiling flipping (bits 2,4,5)
{
i = sector[searchsector].ceilingstat;
i = (i&0x4)+((i>>4)&3);
switch (i)
{
case 0:
i = 6; break;
case 6:
i = 3; break;
case 3:
i = 5; break;
case 5:
i = 1; break;
case 1:
i = 7; break;
case 7:
i = 2; break;
case 2:
i = 4; break;
case 4:
i = 0; break;
}
i = (i&0x4)+((i&3)<<4);
sector[searchsector].ceilingstat &= ~0x34;
sector[searchsector].ceilingstat |= i;
asksave = 1;
}
if (searchstat == 2) //8-way floor flipping (bits 2,4,5)
{
i = sector[searchsector].floorstat;
i = (i&0x4)+((i>>4)&3);
switch (i)
{
case 0:
i = 6; break;
case 6:
i = 3; break;
case 3:
i = 5; break;
case 5:
i = 1; break;
case 1:
i = 7; break;
case 7:
i = 2; break;
case 2:
i = 4; break;
case 4:
i = 0; break;
}
i = (i&0x4)+((i&3)<<4);
sector[searchsector].floorstat &= ~0x34;
sector[searchsector].floorstat |= i;
asksave = 1;
}
if (searchstat == 3)
{
i = sprite[searchwall].cstat;
if (((i&48) == 32) && ((i&64) == 0))
{
sprite[searchwall].cstat &= ~0xc;
sprite[searchwall].cstat |= (i&4)^4;
}
else
{
i = ((i>>2)&3);
switch (i)
{
case 0:
i = 1; break;
case 1:
i = 3; break;
case 2:
i = 0; break;
case 3:
i = 2; break;
}
i <<= 2;
sprite[searchwall].cstat &= ~0xc;
sprite[searchwall].cstat |= i;
}
asksave = 1;
}
}
}
if (keystatus[0x1f] > 0) //S (insert sprite) (3D)
{
dax = 16384;
day = divscale14(searchx-(xdim>>1),xdim>>1);
rotatepoint(0,0,dax,day,ang,&dax,&day);
hitscan(posx,posy,posz,cursectnum, //Start position
dax,day,(scale(searchy,200,ydim)-horiz)*2000, //vector of 3D ang
&hitsect,&hitwall,&hitsprite,&hitx,&hity,&hitz,CLIPMASK1);
if (hitsect >= 0)
{
dax = hitx;
day = hity;
if ((gridlock > 0) && (grid > 0))
{
if ((searchstat == 0) || (searchstat == 4))
{
hitz = (hitz&0xfffffc00);
}
else
{
dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid)));
day = ((day+(1024>>grid))&(0xffffffff<<(11-grid)));
}
}
i = insertsprite(hitsect,0);
sprite[i].x = dax, sprite[i].y = day;
sprite[i].cstat = defaultspritecstat;
sprite[i].shade = 0;
sprite[i].pal = 0;
sprite[i].xrepeat = 64, sprite[i].yrepeat = 64;
sprite[i].xoffset = 0, sprite[i].yoffset = 0;
sprite[i].ang = 1536;
sprite[i].xvel = 0; sprite[i].yvel = 0; sprite[i].zvel = 0;
sprite[i].owner = -1;
sprite[i].clipdist = 32;
sprite[i].lotag = 0;
sprite[i].hitag = 0;
sprite[i].extra = -1;
for (k=0;k<MAXTILES;k++)
localartfreq[k] = 0;
for (k=0;k<MAXSPRITES;k++)
if (sprite[k].statnum < MAXSTATUS)
localartfreq[sprite[k].picnum]++;
j = 0;
for (k=0;k<MAXTILES;k++)
if (localartfreq[k] > localartfreq[j])
j = k;
if (localartfreq[j] > 0)
sprite[i].picnum = j;
else
sprite[i].picnum = 0;
if (somethingintab == 3)
{
sprite[i].picnum = temppicnum;
if ((tilesizx[temppicnum] <= 0) || (tilesizy[temppicnum] <= 0))
{
j = 0;
for (k=0;k<MAXTILES;k++)
if ((tilesizx[k] > 0) && (tilesizy[k] > 0))
{
j = k;
break;
}
sprite[i].picnum = j;
}
sprite[i].shade = tempshade;
sprite[i].pal = temppal;
sprite[i].xrepeat = tempxrepeat;
sprite[i].yrepeat = tempyrepeat;
if (sprite[i].xrepeat < 1) sprite[i].xrepeat = 1;
if (sprite[i].yrepeat < 1) sprite[i].yrepeat = 1;
sprite[i].cstat = tempcstat;
}
j = ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1);
if ((sprite[i].cstat&128) == 0)
sprite[i].z = min(max(hitz,getceilzofslope(hitsect,hitx,hity)+(j<<1)),getflorzofslope(hitsect,hitx,hity));
else
sprite[i].z = min(max(hitz,getceilzofslope(hitsect,hitx,hity)+j),getflorzofslope(hitsect,hitx,hity)-j);
if ((searchstat == 0) || (searchstat == 4))
{
sprite[i].cstat = (sprite[i].cstat&~48)|(16+64);
if (hitwall >= 0)
sprite[i].ang = ((getangle(wall[wall[hitwall].point2].x-wall[hitwall].x,wall[wall[hitwall].point2].y-wall[hitwall].y)+512)&2047);
//Make sure sprite's in right sector
if (inside(sprite[i].x,sprite[i].y,sprite[i].sectnum) == 0)
{
j = wall[hitwall].point2;
sprite[i].x -= ksgn(wall[j].y-wall[hitwall].y);
sprite[i].y += ksgn(wall[j].x-wall[hitwall].x);
}
}
else
{
if (tilesizy[sprite[i].picnum] >= 32) sprite[i].cstat |= 1;
}
updatenumsprites();
asksave = 1;
}
keystatus[0x1f] = 0;
}
if (keystatus[0xd3] > 0)
{
if (searchstat == 3)
{
deletesprite(searchwall);
updatenumsprites();
asksave = 1;
}
keystatus[0xd3] = 0;
}
if ((keystatus[0x3f]|keystatus[0x40]) > 0) //F5,F6
{
switch (searchstat)
{
case 1:
case 2:
ExtShowSectorData(searchsector); break;
case 0:
case 4:
ExtShowWallData(searchwall); break;
case 3:
ExtShowSpriteData(searchwall); break;
}
keystatus[0x3f] = 0, keystatus[0x40] = 0;
}
if ((keystatus[0x41]|keystatus[0x42]) > 0) //F7,F8
{
switch (searchstat)
{
case 1:
case 2:
ExtEditSectorData(searchsector); break;
case 0:
case 4:
ExtEditWallData(searchwall); break;
case 3:
ExtEditSpriteData(searchwall); break;
}
keystatus[0x41] = 0, keystatus[0x42] = 0;
}
}
if (keystatus[buildkeys[14]] > 0) // Enter
{
setbrightness(0,palette,0);
overheadeditor();
keystatus[buildkeys[14]] = 0;
}
}
char changechar(char dachar, long dadir, char smooshyalign, char boundcheck)
{
if (dadir < 0)
{
if ((dachar > 0) || (boundcheck == 0))
{
dachar--;
if (smooshyalign > 0)
dachar = (dachar&0xf8);
}
}
else if (dadir > 0)
{
if ((dachar < 255) || (boundcheck == 0))
{
dachar++;
if (smooshyalign > 0)
{
if (dachar >= 256-8) dachar = 255;
else dachar = ((dachar+7)&0xf8);
}
}
}
return(dachar);
}
long gettile(long tilenum)
{
char snotbuf[80], ch;
long i, j, k, otilenum, topleft, gap, temp, templong;
long xtiles, ytiles, tottiles;
if (tilenum < 0) tilenum = 0;
xtiles = (xdim>>6); ytiles = (ydim>>6); tottiles = xtiles*ytiles;
otilenum = tilenum;
keystatus[0x2f] = 0;
for (i=0;i<MAXTILES;i++)
{
localartfreq[i] = 0;
localartlookup[i] = i;
}
if ((searchstat == 1) || (searchstat == 2))
for (i=0;i<numsectors;i++)
{
localartfreq[sector[i].ceilingpicnum]++;
localartfreq[sector[i].floorpicnum]++;
}
if (searchstat == 0)
for (i=0;i<numwalls;i++)
localartfreq[wall[i].picnum]++;
if (searchstat == 4)
for (i=0;i<numwalls;i++)
localartfreq[wall[i].overpicnum]++;
if (searchstat == 3)
for (i=0;i<MAXSPRITES;i++)
if (sprite[i].statnum < MAXSTATUS)
localartfreq[sprite[i].picnum]++;
gap = (MAXTILES>>1);
do
{
for (i=0;i<MAXTILES-gap;i++)
{
temp = i;
while ((localartfreq[temp] < localartfreq[temp+gap]) && (temp >= 0))
{
templong = localartfreq[temp];
localartfreq[temp] = localartfreq[temp+gap];
localartfreq[temp+gap] = templong;
templong = localartlookup[temp];
localartlookup[temp] = localartlookup[temp+gap];
localartlookup[temp+gap] = templong;
if (tilenum == temp)
tilenum = temp+gap;
else if (tilenum == temp+gap)
tilenum = temp;
temp -= gap;
}
}
gap >>= 1;
}
while (gap > 0);
localartlookupnum = 0;
while (localartfreq[localartlookupnum] > 0)
localartlookupnum++;
if (localartfreq[0] == 0)
{
tilenum = otilenum;
localartlookupnum = MAXTILES;
for (i=0;i<MAXTILES;i++)
localartlookup[i] = i;
}
topleft = ((tilenum/(xtiles<<gettilezoom))*(xtiles<<gettilezoom))-(xtiles<<gettilezoom);
if (topleft < 0) topleft = 0;
if (topleft > MAXTILES-(tottiles<<(gettilezoom<<1))) topleft = MAXTILES-(tottiles<<(gettilezoom<<1));
while ((keystatus[0x1c]|keystatus[1]) == 0)
{
drawtilescreen(topleft,tilenum);
if (handleevents()) {
if (quitevent) quitevent = 0;
}
idle();
synctics = totalclock-lockclock;
lockclock += synctics;
if ((keystatus[0x37] > 0) && (gettilezoom < 2))
{
gettilezoom++;
topleft = ((tilenum/(xtiles<<gettilezoom))*(xtiles<<gettilezoom))-(xtiles<<gettilezoom);
if (topleft < 0) topleft = 0;
if (topleft > MAXTILES-(tottiles<<(gettilezoom<<1))) topleft = MAXTILES-(tottiles<<(gettilezoom<<1));
keystatus[0x37] = 0;
}
if ((keystatus[0xb5] > 0) && (gettilezoom > 0))
{
gettilezoom--;
topleft = ((tilenum/(xtiles<<gettilezoom))*(xtiles<<gettilezoom))-(xtiles<<gettilezoom);
if (topleft < 0) topleft = 0;
if (topleft > MAXTILES-(tottiles<<(gettilezoom<<1))) topleft = MAXTILES-(tottiles<<(gettilezoom<<1));
keystatus[0xb5] = 0;
}
if ((keystatus[0xcb] > 0) && (tilenum > 0))
tilenum--, keystatus[0xcb] = 0;
if ((keystatus[0xcd] > 0) && (tilenum < MAXTILES-1))
tilenum++, keystatus[0xcd] = 0;
if ((keystatus[0xc8] > 0) && (tilenum >= (xtiles<<gettilezoom)))
tilenum-=(xtiles<<gettilezoom), keystatus[0xc8] = 0;
if ((keystatus[0xd0] > 0) && (tilenum < MAXTILES-(xtiles<<gettilezoom)))
tilenum+=(xtiles<<gettilezoom), keystatus[0xd0] = 0;
if ((keystatus[0xc9] > 0) && (tilenum >= (xtiles<<gettilezoom)))
{
tilenum-=(tottiles<<(gettilezoom<<1));
if (tilenum < 0) tilenum = 0;
keystatus[0xc9] = 0;
}
if ((keystatus[0xd1] > 0) && (tilenum < MAXTILES-(xtiles<<gettilezoom)))
{
tilenum+=(tottiles<<(gettilezoom<<1));
if (tilenum >= MAXTILES) tilenum = MAXTILES-1;
keystatus[0xd1] = 0;
}
if (keystatus[0x2f] > 0) //V
{
keystatus[0x2f] = 0;
if (tilenum < localartlookupnum)
tilenum = localartlookup[tilenum];
else
tilenum = 0;
localartlookupnum = MAXTILES;
for (i=0;i<MAXTILES;i++)
localartlookup[i] = i;
}
if (keystatus[0x22] > 0) //G (goto)
{
if (tilenum < localartlookupnum) //Automatically press 'V'
tilenum = localartlookup[tilenum];
else
tilenum = 0;
localartlookupnum = MAXTILES;
for (i=0;i<MAXTILES;i++)
localartlookup[i] = i;
keystatus[0x22] = 0;
bflushchars();
j = tilenum;
while (keystatus[1] == 0)
{
if (handleevents()) {
if (quitevent) quitevent = 0;
}
idle();
ch = bgetchar();
//drawtilescreen(topleft,tilenum);
Bsprintf(snotbuf,"Goto tile: %ld_ ",j);
printext256(0,0,whitecol,0,snotbuf,0);
showframe(1);
if (ch >= '0' && ch <= '9') {
i = (j*10)+(ch-'0');
if (i < MAXTILES) j = i;
} else if (ch == 8) {
j /= 10;
} else if (ch == 13) {
tilenum = j;
break;
}
}
clearkeys();
}
while (tilenum < topleft) topleft -= (xtiles<<gettilezoom);
while (tilenum >= topleft+(tottiles<<(gettilezoom<<1))) topleft += (xtiles<<gettilezoom);
if (topleft < 0) topleft = 0;
if (topleft > MAXTILES-(tottiles<<(gettilezoom<<1))) topleft = MAXTILES-(tottiles<<(gettilezoom<<1));
}
if (keystatus[0x1c] == 0)
{
tilenum = otilenum;
}
else
{
if (tilenum < localartlookupnum)
{
tilenum = localartlookup[tilenum];
if ((tilesizx[tilenum] == 0) || (tilesizy[tilenum] == 0))
tilenum = otilenum;
}
else
tilenum = otilenum;
}
keystatus[0x1] = 0;
keystatus[0x1c] = 0;
return(tilenum);
}
long drawtilescreen(long pictopleft, long picbox)
{
long i, j, vidpos, vidpos2, dat, wallnum, xdime, ydime, cnt, pinc;
long dax, day, scaledown, xtiles, ytiles, tottiles;
char *picptr, snotbuf[80];
xtiles = (xdim>>6); ytiles = (ydim>>6); tottiles = xtiles*ytiles;
begindrawing(); //{{{
setpolymost2dview(); // JBF 20040205: set to 2d rendering
pinc = ylookup[1];
clearview(0L);
for (cnt=0;cnt<(tottiles<<(gettilezoom<<1));cnt++) //draw the 5*3 grid of tiles
{
wallnum = cnt+pictopleft;
if (wallnum < localartlookupnum)
{
wallnum = localartlookup[wallnum];
if ((tilesizx[wallnum] != 0) && (tilesizy[wallnum] != 0))
{
if (waloff[wallnum] == 0) loadtile(wallnum);
picptr = (char *)(waloff[wallnum]);
xdime = tilesizx[wallnum];
ydime = tilesizy[wallnum];
dax = ((cnt%(xtiles<<gettilezoom))<<(6-gettilezoom));
day = ((cnt/(xtiles<<gettilezoom))<<(6-gettilezoom));
if (polymost_drawtilescreen(dax, day, wallnum, 64>>gettilezoom)) {
vidpos = ylookup[day]+dax+frameplace;
if ((xdime <= (64>>gettilezoom)) && (ydime <= (64>>gettilezoom)))
{
for (i=0;i<xdime;i++)
{
vidpos2 = vidpos+i;
for (j=0;j<ydime;j++)
{
*(char *)vidpos2 = *picptr++;
vidpos2 += pinc;
}
}
}
else //if 1 dimension > 64
{
if (xdime > ydime)
scaledown = ((xdime+(63>>gettilezoom))>>(6-gettilezoom));
else
scaledown = ((ydime+(63>>gettilezoom))>>(6-gettilezoom));
for (i=0;i<xdime;i+=scaledown)
{
if (waloff[wallnum] == 0) loadtile(wallnum);
picptr = (char *)(waloff[wallnum]) + ydime*i;
vidpos2 = vidpos;
for (j=0;j<ydime;j+=scaledown)
{
*(char *)vidpos2 = *picptr;
picptr += scaledown;
vidpos2 += pinc;
}
vidpos++;
}
}
}
if (localartlookupnum < MAXTILES)
{
dax = ((cnt%(xtiles<<gettilezoom))<<(6-gettilezoom));
day = ((cnt/(xtiles<<gettilezoom))<<(6-gettilezoom));
Bsprintf(snotbuf,"%d",localartfreq[cnt+pictopleft]);
printext256(dax,day,whitecol,-1,snotbuf,1);
}
}
}
}
cnt = picbox-pictopleft; //draw open white box
dax = ((cnt%(xtiles<<gettilezoom))<<(6-gettilezoom));
day = ((cnt/(xtiles<<gettilezoom))<<(6-gettilezoom));
for (i=0;i<(64>>gettilezoom);i++)
{
plotpixel(dax+i,day,whitecol);
plotpixel(dax+i,day+(63>>gettilezoom),whitecol);
plotpixel(dax,day+i,whitecol);
plotpixel(dax+(63>>gettilezoom),day+i,whitecol);
}
i = localartlookup[picbox];
Bsprintf(snotbuf,"%ld",i);
printext256(0L,ydim-8,whitecol,-1,snotbuf,0);
printext256(xdim-(Bstrlen(names[i])<<3),ydim-8,whitecol,-1,names[i],0);
Bsprintf(snotbuf,"%dx%d",tilesizx[i],tilesizy[i]);
printext256(xdim>>2,ydim-8,whitecol,-1,snotbuf,0);
enddrawing(); //}}}
showframe(1);
return(0);
}
void overheadeditor(void)
{
char buffer[80], *dabuffer, ch;
long i, j, k, m=0, mousxplc, mousyplc, firstx=0, firsty=0, oposz, col;
long templong, templong1, templong2, doubvel;
long startwall=0, endwall, dax, day, daz, x1, y1, x2, y2, x3, y3, x4, y4;
long highlightx1, highlighty1, highlightx2, highlighty2, xvect, yvect;
short pag, suckwall=0, sucksect, newnumwalls, newnumsectors, split=0, bad;
short splitsect=0, danumwalls, secondstartwall, joinsector[2], joinsectnum;
short splitstartwall=0, splitendwall, loopnum;
long mousx, mousy, bstatus;
long centerx, centery, circlerad;
short circlewall, circlepoints, circleang1, circleang2, circleangdir;
long sectorhighlightx=0, sectorhighlighty=0;
short cursectorhighlight, sectorhighlightstat;
short hitsect, hitwall, hitsprite;
long hitx, hity, hitz;
walltype *wal;
//qsetmode640480();
qsetmodeany(xdim2d,ydim2d);
xdim2d = xdim;
ydim2d = ydim;
osearchx = searchx;
osearchy = searchy;
searchx = scale(searchx,xdim2d,xdimgame);
searchy = scale(searchy,ydim2d-STATUS2DSIZ,ydimgame);
oposz = posz;
begindrawing(); //{{{
clearbuf((char *)(frameplace + (ydim16*bytesperline)), (bytesperline*STATUS2DSIZ) >> 2, 0x00000000l);
clearbuf((char *)frameplace, (ydim16*bytesperline) >> 2, 0L);
ydim16 = ydim;
drawline16(0,ydim-STATUS2DSIZ,xdim-1,ydim-STATUS2DSIZ,1);
drawline16(0,ydim-1,xdim-1,ydim-1,1);
drawline16(0,ydim-STATUS2DSIZ,0,ydim-1,1);
drawline16(xdim-1,ydim-STATUS2DSIZ,xdim-1,ydim-1,1);
drawline16(0,ydim-STATUS2DSIZ+24,xdim-1,ydim-STATUS2DSIZ+24,1);
drawline16(192,ydim-STATUS2DSIZ,192,ydim-STATUS2DSIZ+24,1);
if (totalclock < 120*5) printext16(8L,ydim-STATUS2DSIZ+32L,9,-1,kensig,0);
// printmessage16("Version: "VERSION);
if (totalclock < 30) printmessage16("Press F1 for help");
drawline16(0,ydim-1-20,xdim-1,ydim-1-20,1);
drawline16(256,ydim-1-20,256,ydim-1,1);
ydim16 = ydim-STATUS2DSIZ;
enddrawing(); //}}}
pag = 0;
highlightcnt = -1;
cursectorhighlight = -1;
lastpm16time = -1;
//White out all bordering lines of grab that are
//not highlighted on both sides
for (i=highlightsectorcnt-1;i>=0;i--)
{
startwall = sector[highlightsector[i]].wallptr;
endwall = startwall + sector[highlightsector[i]].wallnum;
for (j=startwall;j<endwall;j++)
{
if (wall[j].nextwall >= 0)
{
for (k=highlightsectorcnt-1;k>=0;k--)
if (highlightsector[k] == wall[j].nextsector)
break;
if (k < 0)
{
wall[wall[j].nextwall].nextwall = -1;
wall[wall[j].nextwall].nextsector = -1;
wall[j].nextwall = -1;
wall[j].nextsector = -1;
}
}
}
}
for (i=0;i<(MAXWALLS>>3);i++) //Clear all highlights
show2dwall[i] = 0;
for (i=0;i<(MAXSPRITES>>3);i++)
show2dsprite[i] = 0;
sectorhighlightstat = -1;
newnumwalls = -1;
joinsector[0] = -1;
circlewall = -1;
circlepoints = 7;
bstatus = 0;
keystatus[buildkeys[14]] = 0;
while ((keystatus[buildkeys[14]]>>1) == 0)
{
if (handleevents()) {
if (quitevent) {
keystatus[1] = 1;
quitevent = 0;
}
}
idle();
OSD_DispatchQueued();
oldmousebstatus = bstatus;
getmousevalues(&mousx,&mousy,&bstatus);
mousx = (mousx<<16)+mousexsurp;
mousy = (mousy<<16)+mouseysurp;
{
ldiv_t ld;
ld = ldiv((long)(mousx), (1<<16)); mousx = ld.quot; mousexsurp = ld.rem;
ld = ldiv((long)(mousy), (1<<16)); mousy = ld.quot; mouseysurp = ld.rem;
}
searchx += mousx*msens;
searchy += mousy*msens;
if (searchx < 8) searchx = 8;
if (searchx > xdim-8-1) searchx = xdim-8-1;
if (searchy < 8) searchy = 8;
if (searchy > ydim-8-1) searchy = ydim-8-1;
/* if (keystatus[0x3b] > 0) posx--, keystatus[0x3b] = 0;
if (keystatus[0x3c] > 0) posx++, keystatus[0x3c] = 0;
if (keystatus[0x3d] > 0) posy--, keystatus[0x3d] = 0;
if (keystatus[0x3e] > 0) posy++, keystatus[0x3e] = 0;
if (keystatus[0x43] > 0) ang--, keystatus[0x43] = 0;
if (keystatus[0x44] > 0) ang++, keystatus[0x44] = 0; */
if (angvel != 0) //ang += angvel * constant
{ //ENGINE calculates angvel for you
doubvel = synctics;
if (keystatus[buildkeys[4]] > 0) //Lt. shift makes turn velocity 50% faster
doubvel += (synctics>>1);
ang += ((angvel*doubvel)>>4);
ang = (ang+2048)&2047;
}
if ((vel|svel) != 0)
{
doubvel = synctics;
if (keystatus[buildkeys[4]] > 0) //Lt. shift doubles forward velocity
doubvel += synctics;
xvect = 0, yvect = 0;
if (vel != 0)
{
xvect += ((vel*doubvel*(long)sintable[(ang+2560)&2047])>>3);
yvect += ((vel*doubvel*(long)sintable[(ang+2048)&2047])>>3);
}
if (svel != 0)
{
xvect += ((svel*doubvel*(long)sintable[(ang+2048)&2047])>>3);
yvect += ((svel*doubvel*(long)sintable[(ang+1536)&2047])>>3);
}
if (noclip)
{
posx += xvect>>14;
posy += yvect>>14;
updatesector(posx,posy,&cursectnum);
}
else clipmove(&posx,&posy,&posz,&cursectnum,xvect,yvect,128L,4L<<8,4L<<8,CLIPMASK0);
}
getpoint(searchx,searchy,&mousxplc,&mousyplc);
linehighlight = getlinehighlight(mousxplc, mousyplc);
if (newnumwalls >= numwalls)
{
dax = mousxplc;
day = mousyplc;
adjustmark(&dax,&day,newnumwalls);
wall[newnumwalls].x = dax;
wall[newnumwalls].y = day;
}
ydim16 = ydim - STATUS2DSIZ;
templong = numwalls;
numwalls = newnumwalls;
if (numwalls < 0) numwalls = templong;
clear2dscreen();
draw2dgrid(posx,posy,ang,zoom,grid);
x2 = mulscale14(startposx-posx,zoom); //Draw brown arrow (start)
y2 = mulscale14(startposy-posy,zoom);
if (((halfxdim16+x2) >= 2) && ((halfxdim16+x2) <= xdim-3))
if (((midydim16+y2) >= 2) && ((midydim16+y2) <= ydim16-3))
{
x1 = mulscale11(sintable[(startang+2560)&2047],zoom) / 768;
y1 = mulscale11(sintable[(startang+2048)&2047],zoom) / 768;
begindrawing(); //{{{
drawline16((halfxdim16+x2)+x1,(midydim16+y2)+y1,(halfxdim16+x2)-x1,(midydim16+y2)-y1,2);
drawline16((halfxdim16+x2)+x1,(midydim16+y2)+y1,(halfxdim16+x2)+y1,(midydim16+y2)-x1,2);
drawline16((halfxdim16+x2)+x1,(midydim16+y2)+y1,(halfxdim16+x2)-y1,(midydim16+y2)+x1,2);
enddrawing(); //}}}
}
draw2dscreen(posx,posy,ang,zoom,grid);
begindrawing(); //{{{
if ((showtags == 1) && (zoom >= 768))
{
for (i=0;i<numsectors;i++)
{
dabuffer = (char *)ExtGetSectorCaption(i);
if (dabuffer[0] != 0)
{
dax = 0; //Get average point of sector
day = 0;
startwall = sector[i].wallptr;
endwall = startwall + sector[i].wallnum - 1;
for (j=startwall;j<=endwall;j++)
{
dax += wall[j].x;
day += wall[j].y;
}
if (endwall > startwall)
{
dax /= (endwall-startwall+1);
day /= (endwall-startwall+1);
}
dax = mulscale14(dax-posx,zoom);
day = mulscale14(day-posy,zoom);
x1 = halfxdim16+dax-(Bstrlen(dabuffer)<<1);
y1 = midydim16+day-4;
x2 = x1 + (Bstrlen(dabuffer)<<2)+2;
y2 = y1 + 7;
if ((x1 >= 0) && (x2 < xdim) && (y1 >= 0) && (y2 < ydim16))
printext16(x1,y1,0,7,dabuffer,1);
}
}
x3 = divscale14(-halfxdim16,zoom)+posx;
y3 = divscale14(-(midydim16-4),zoom)+posy;
x4 = divscale14(halfxdim16,zoom)+posx;
y4 = divscale14(ydim16-(midydim16-4),zoom)+posy;
for (i=numwalls-1,wal=&wall[i];i>=0;i--,wal--)
{
//Get average point of wall
dax = ((wal->x+wall[wal->point2].x)>>1);
day = ((wal->y+wall[wal->point2].y)>>1);
if ((dax > x3) && (dax < x4) && (day > y3) && (day < y4))
{
dabuffer = (char *)ExtGetWallCaption(i);
if (dabuffer[0] != 0)
{
dax = mulscale14(dax-posx,zoom);
day = mulscale14(day-posy,zoom);
x1 = halfxdim16+dax-(Bstrlen(dabuffer)<<1);
y1 = midydim16+day-4;
x2 = x1 + (Bstrlen(dabuffer)<<2)+2;
y2 = y1 + 7;
if ((x1 >= 0) && (x2 < xdim) && (y1 >= 0) && (y2 < ydim16))
printext16(x1,y1,0,4,dabuffer,1);
}
}
}
i = 0; j = numsprites;
while ((j > 0) && (i < MAXSPRITES))
{
if (sprite[i].statnum < MAXSTATUS)
{
dabuffer = (char *)ExtGetSpriteCaption(i);
if (dabuffer[0] != 0)
{
//Get average point of sprite
dax = sprite[i].x;
day = sprite[i].y;
dax = mulscale14(dax-posx,zoom);
day = mulscale14(day-posy,zoom);
x1 = halfxdim16+dax-(Bstrlen(dabuffer)<<1);
y1 = midydim16+day-4;
x2 = x1 + (Bstrlen(dabuffer)<<2)+2;
y2 = y1 + 7;
if ((x1 >= 0) && (x2 < xdim) && (y1 >= 0) && (y2 < ydim16))
{
col = 3;
if (spritecol2d[sprite[i].picnum][0])
col = spritecol2d[sprite[i].picnum][0];
if ((sprite[i].cstat&1) > 0)
{
col = 5;
if (spritecol2d[sprite[i].picnum][1])
col = spritecol2d[sprite[i].picnum][1];
}
if ((i == pointhighlight-16384) && (totalclock & 32)) col += (2<<2);
printext16(x1,y1,0,col,dabuffer,1);
}
}
j--;
}
i++;
}
}
printcoords16(posx,posy,ang);
numwalls = templong;
if (highlightsectorcnt > 0)
for (i=0;i<highlightsectorcnt;i++)
fillsector(highlightsector[i],2);
if (keystatus[0x2a]) {
drawlinepat = 0x00ff00ff;
drawline16(searchx,0,searchx,ydim2d-1,15);
drawline16(0,searchy,xdim2d-1,searchy,15);
drawlinepat = 0xffffffff;
Bsprintf(tempbuf,"(%ld,%ld)",mousxplc,mousyplc);
i = (Bstrlen(tempbuf)<<3)+6;
if ((searchx+i) < (xdim2d-1))
i = 0;
else i = (searchx+i)-(xdim2d-1);
if ((searchy+16) < (ydim2d-STATUS2DSIZ-1))
j = 0;
else j = (searchy+16)-(ydim2d-STATUS2DSIZ-1);
printext16(searchx+6-i,searchy+6-j,11,-1,tempbuf,0);
}
drawline16(searchx,0,searchx,8,15);
drawline16(0,searchy,8,searchy,15);
col = 15-((gridlock<<1)+gridlock);
drawline16(searchx,searchy-8,searchx,searchy-1,col);
drawline16(searchx+1,searchy-8,searchx+1,searchy-1,col);
drawline16(searchx,searchy+2,searchx,searchy+9,col);
drawline16(searchx+1,searchy+2,searchx+1,searchy+9,col);
drawline16(searchx-8,searchy,searchx-1,searchy,col);
drawline16(searchx-8,searchy+1,searchx-1,searchy+1,col);
drawline16(searchx+2,searchy,searchx+9,searchy,col);
drawline16(searchx+2,searchy+1,searchx+9,searchy+1,col);
//Draw the white pixel closest to mouse cursor on linehighlight
getclosestpointonwall(mousxplc,mousyplc,(long)linehighlight,&dax,&day);
x2 = mulscale14(dax-posx,zoom);
y2 = mulscale14(day-posy,zoom);
if (wall[linehighlight].nextsector >= 0)
drawline16(halfxdim16+x2,midydim16+y2,halfxdim16+x2,midydim16+y2,15);
else
drawline16(halfxdim16+x2,midydim16+y2,halfxdim16+x2,midydim16+y2,5);
enddrawing(); //}}}
OSD_Draw();
ExtCheckKeys(); // TX 20050101, it makes more sense to have this here so keys can be overwritten with new functions in bstub.c
// Flip/mirror sector Ed Coolidge
if (keystatus[0x2d] > 0) // X (2D)
{
if (highlightsectorcnt > 0)
{
k = 0;
dax = 0;
day = 0;
for (i=0;i<highlightsectorcnt;i++)
{
startwall = sector[highlightsector[i]].wallptr;
endwall = startwall+sector[highlightsector[i]].wallnum-1;
for (j=startwall;j<=endwall;j++)
{
dax += wall[j].x;
day += wall[j].y;
k++;
}
}
if (k > 0)
{
dax /= k;
day /= k;
}
k = (keystatus[0x38]|keystatus[0xb8]); //ALT-X mirror sector in x
if ((gridlock > 0) && (grid > 0))
{
dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid)));
day = ((day+(1024>>grid))&(0xffffffff<<(11-grid)));
// dax = ((dax+(GRIDMAX>>grid))&(0xffffffff-(GRIDMAX>>(grid-1))+1));
// day = ((day+(GRIDMAX>>grid))&(0xffffffff-(GRIDMAX>>(grid-1))+1));
}
for (i=0;i<highlightsectorcnt;i++)
{
long startofloop;
long endofloop;
long numtoswap = -1;
long w=0;
walltype tempwall;
startofloop = startwall = sector[highlightsector[i]].wallptr;
endofloop = endwall = startwall+sector[highlightsector[i]].wallnum-1;
/*
if (k != 0)
{
//mirror sector textures
sector[highlightsector[i]].ceilingstat ^= 0x10;
sector[highlightsector[i]].floorstat ^= 0x10;
}
*/
//save position of wall at start of loop
x3 = wall[startofloop].x;
y3 = wall[startofloop].y;
for (j=startwall;j<=endwall;j++)
{
//fix position of walls
wall[j].x = dax-wall[wall[j].point2].x+dax; //flip wall.x about dax
wall[j].y = wall[wall[j].point2].y;
if (k != 0)
{
//mirror walls about dax
wall[j].cstat ^= 8;
}
if (wall[j].point2==startofloop) //check if j is end of loop
{
endofloop = j;
wall[endofloop].x = dax-x3+dax; //flip wall.x about dax
wall[endofloop].y = y3;
//correct order of walls in loop to maintain player space (right-hand rule)
numtoswap = (endofloop-startofloop)>>1;
for (w=1;w<=numtoswap;w++)
{
Bmemcpy(&tempwall,&wall[startofloop+w],sizeof(walltype));
Bmemcpy(&wall[startofloop+w],&wall[endofloop-w+1],sizeof(walltype));
Bmemcpy(&wall[endofloop-w+1],&tempwall,sizeof(walltype));
}
//make point2 point to next wall in loop
for (w=startofloop;w<endofloop;w++)
{
wall[w].point2 = w+1;
}
wall[endofloop].point2 = startofloop;
startofloop = endofloop+1; //set first wall of next loop
//save position of wall at start of loop
x3 = wall[startofloop].x;
y3 = wall[startofloop].y;
}
}
j = headspritesect[highlightsector[i]];
while (j != -1)
{
x3 = sprite[j].x;
sprite[j].x = dax-x3+dax; //flip sprite.x about dax
sprite[j].ang = ((1024+2048-sprite[j].ang)&2047); //flip ang about 512
if (k != 0)
{
//don't mirror monsters
if ((sprite[j].cstat & 0x30) != 0)
{
//mirror sprites about day
sprite[j].cstat ^= 4;
}
}
j = nextspritesect[j];
}
}
if (k == 0) keystatus[0x2d] = 0;
printmessage16("Selected sector(s) flipped");
asksave = 1;
}
}
if (keystatus[0x15] > 0) // Y (2D)
{
if (highlightsectorcnt > 0)
{
k = 0;
dax = 0;
day = 0;
for (i=0;i<highlightsectorcnt;i++)
{
startwall = sector[highlightsector[i]].wallptr;
endwall = startwall+sector[highlightsector[i]].wallnum-1;
for (j=startwall;j<=endwall;j++)
{
dax += wall[j].x;
day += wall[j].y;
k++;
}
}
if (k > 0)
{
dax /= k;
day /= k;
}
k = (keystatus[0x38]|keystatus[0xb8]); //ALT-Y mirror sectors in y
if ((gridlock > 0) && (grid > 0))
{
dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid)));
day = ((day+(1024>>grid))&(0xffffffff<<(11-grid)));
// dax = ((dax+(GRIDMAX>>grid))&(0xffffffff-(GRIDMAX>>(grid-1))+1));
// day = ((day+(GRIDMAX>>grid))&(0xffffffff-(GRIDMAX>>(grid-1))+1));
}
for (i=0;i<highlightsectorcnt;i++)
{
long startofloop;
long endofloop;
long numtoswap = -1;
long w=0;
walltype tempwall;
startofloop = startwall = sector[highlightsector[i]].wallptr;
endofloop = endwall = startwall+sector[highlightsector[i]].wallnum-1;
/*
if (k != 0)
{
//mirror sector textures
sector[highlightsector[i]].ceilingstat ^= 0x10;
sector[highlightsector[i]].floorstat ^= 0x10;
}
*/
//save position of wall at start of loop
x3 = wall[startofloop].x;
y3 = wall[startofloop].y;
for (j=startwall;j<=endwall;j++)
{
//fix position of walls
wall[j].x = wall[wall[j].point2].x;
wall[j].y = day-wall[wall[j].point2].y+day; //flip wall.y about day
if (k != 0)
{
//mirror walls about day
wall[j].cstat ^= 8;
}
if (wall[j].point2==startofloop) //check if j is end of loop
{
endofloop = j;
wall[endofloop].x = x3;
wall[endofloop].y = day-y3+day; //flip wall.y about dax
//correct order of walls in loop to maintain player space (right-hand rule)
numtoswap = (endofloop-startofloop)>>1;
for (w=1;w<=numtoswap;w++)
{
Bmemcpy(&tempwall,&wall[startofloop+w],sizeof(walltype));
Bmemcpy(&wall[startofloop+w],&wall[endofloop-w+1],sizeof(walltype));
Bmemcpy(&wall[endofloop-w+1],&tempwall,sizeof(walltype));
}
//make point2 point to next wall in loop
for (w=startofloop;w<endofloop;w++)
{
wall[w].point2 = w+1;
}
wall[endofloop].point2 = startofloop;
startofloop = endofloop+1; //set first wall of next loop
//save position of wall at start of loop
x3 = wall[startofloop].x;
y3 = wall[startofloop].y;
}
}
j = headspritesect[highlightsector[i]];
while (j != -1)
{
y3 = sprite[j].y;
sprite[j].y = day-y3+day; //flip sprite.y about day
sprite[j].ang = ((2048-sprite[j].ang)&2047); //flip ang about 512
if (k != 0)
{
//don't mirror monsters
if ((sprite[j].cstat & 0x30) != 0)
{
//mirror sprites about day
sprite[j].cstat ^= 4;
}
}
j = nextspritesect[j];
}
}
if (k == 0) keystatus[0x15] = 0;
printmessage16("Selected sector(s) flipped");
asksave = 1;
}
}
// end edit for sector flip
if (keystatus[88] > 0) //F12
{
keystatus[88] = 0;
/*
j = ydim16; ydim16 = ydim;
clear2dscreen();
draw2dgrid(posx,posy,ang,zoom,grid);
draw2dscreen(posx,posy,ang,zoom,grid);
*/
screencapture("captxxxx.tga",keystatus[0x2a]|keystatus[0x36]);
/*
ydim16 = j;
clear2dscreen();
draw2dgrid(posx,posy,ang,zoom,grid);
draw2dscreen(posx,posy,ang,zoom,grid);
*/
showframe(1);
}
if (keystatus[0x30] > 0) // B (clip Blocking xor) (2D)
{
pointhighlight = getpointhighlight(mousxplc, mousyplc);
linehighlight = getlinehighlight(mousxplc, mousyplc);
if ((pointhighlight&0xc000) == 16384)
{
sprite[pointhighlight&16383].cstat ^= 1;
sprite[pointhighlight&16383].cstat &= ~256;
sprite[pointhighlight&16383].cstat |= ((sprite[pointhighlight&16383].cstat&1)<<8);
asksave = 1;
}
else if (linehighlight >= 0)
{
wall[linehighlight].cstat ^= 1;
wall[linehighlight].cstat &= ~64;
if ((wall[linehighlight].nextwall >= 0) && ((keystatus[0x2a]|keystatus[0x36]) == 0))
{
wall[wall[linehighlight].nextwall].cstat &= ~(1+64);
wall[wall[linehighlight].nextwall].cstat |= (wall[linehighlight].cstat&1);
}
asksave = 1;
}
keystatus[0x30] = 0;
}
if (keystatus[0x21] > 0) //F (F alone does nothing in 2D right now)
{
keystatus[0x21] = 0;
if ((keystatus[0x38]|keystatus[0xb8]) > 0) //ALT-F (relative alignmment flip)
{
linehighlight = getlinehighlight(mousxplc, mousyplc);
if (linehighlight >= 0)
{
setfirstwall(sectorofwall(linehighlight),linehighlight);
asksave = 1;
printmessage16("This wall now sector's first wall (sector[].wallptr)");
}
}
}
if (keystatus[0x18] > 0) // O (ornament onto wall) (2D)
{
keystatus[0x18] = 0;
if ((pointhighlight&0xc000) == 16384)
{
asksave = 1;
i = (pointhighlight&16383);
hitscan(sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].sectnum,
sintable[(sprite[i].ang+2560+1024)&2047],
sintable[(sprite[i].ang+2048+1024)&2047],
0,
&hitsect,&hitwall,&hitsprite,&hitx,&hity,&hitz,CLIPMASK1);
sprite[i].x = hitx;
sprite[i].y = hity;
sprite[i].z = hitz;
changespritesect(i,hitsect);
if (hitwall >= 0)
sprite[i].ang = ((getangle(wall[wall[hitwall].point2].x-wall[hitwall].x,wall[wall[hitwall].point2].y-wall[hitwall].y)+512)&2047);
//Make sure sprite's in right sector
if (inside(sprite[i].x,sprite[i].y,sprite[i].sectnum) == 0)
{
j = wall[hitwall].point2;
sprite[i].x -= ksgn(wall[j].y-wall[hitwall].y);
sprite[i].y += ksgn(wall[j].x-wall[hitwall].x);
}
}
}
if (keystatus[0x33] > 0) // , (2D)
{
if (highlightsectorcnt > 0)
{
k = 0;
dax = 0;
day = 0;
for (i=0;i<highlightsectorcnt;i++)
{
startwall = sector[highlightsector[i]].wallptr;
endwall = startwall+sector[highlightsector[i]].wallnum-1;
for (j=startwall;j<=endwall;j++)
{
dax += wall[j].x;
day += wall[j].y;
k++;
}
}
if (k > 0)
{
dax /= k;
day /= k;
}
k = (keystatus[0x2a]|keystatus[0x36]);
if (k == 0)
{
if ((gridlock > 0) && (grid > 0))
{
dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid)));
day = ((day+(1024>>grid))&(0xffffffff<<(11-grid)));
}
}
for (i=0;i<highlightsectorcnt;i++)
{
startwall = sector[highlightsector[i]].wallptr;
endwall = startwall+sector[highlightsector[i]].wallnum-1;
for (j=startwall;j<=endwall;j++)
{
if (k == 0)
{
x3 = wall[j].x;
y3 = wall[j].y;
wall[j].x = dax+day-y3;
wall[j].y = day+x3-dax;
}
else
{
rotatepoint(dax,day,wall[j].x,wall[j].y,1,&wall[j].x,&wall[j].y);
}
}
j = headspritesect[highlightsector[i]];
while (j != -1)
{
if (k == 0)
{
x3 = sprite[j].x;
y3 = sprite[j].y;
sprite[j].x = dax+day-y3;
sprite[j].y = day+x3-dax;
sprite[j].ang = ((sprite[j].ang+512)&2047);
}
else
{
rotatepoint(dax,day,sprite[j].x,sprite[j].y,1,&sprite[j].x,&sprite[j].y);
sprite[j].ang = ((sprite[j].ang+1)&2047);
}
j = nextspritesect[j];
}
}
if (k == 0) keystatus[0x33] = 0;
asksave = 1;
}
else
{
if (pointhighlight >= 16384)
{
i = pointhighlight-16384;
if ((keystatus[0x2a]|keystatus[0x36]) > 0)
sprite[i].ang = ((sprite[i].ang+2048-1)&2047);
else
{
sprite[i].ang = ((sprite[i].ang+2048-128)&2047);
keystatus[0x33] = 0;
}
clearmidstatbar16();
showspritedata((short)pointhighlight-16384);
}
}
}
if (keystatus[0x34] > 0) // . (2D)
{
if (highlightsectorcnt > 0)
{
k = 0;
dax = 0;
day = 0;
for (i=0;i<highlightsectorcnt;i++)
{
startwall = sector[highlightsector[i]].wallptr;
endwall = startwall+sector[highlightsector[i]].wallnum-1;
for (j=startwall;j<=endwall;j++)
{
dax += wall[j].x;
day += wall[j].y;
k++;
}
}
if (k > 0)
{
dax /= k;
day /= k;
}
k = (keystatus[0x2a]|keystatus[0x36]);
if (k == 0)
{
if ((gridlock > 0) && (grid > 0))
{
dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid)));
day = ((day+(1024>>grid))&(0xffffffff<<(11-grid)));
}
}
for (i=0;i<highlightsectorcnt;i++)
{
startwall = sector[highlightsector[i]].wallptr;
endwall = startwall+sector[highlightsector[i]].wallnum-1;
for (j=startwall;j<=endwall;j++)
{
if (k == 0)
{
x3 = wall[j].x;
y3 = wall[j].y;
wall[j].x = dax+y3-day;
wall[j].y = day+dax-x3;
}
else
{
rotatepoint(dax,day,wall[j].x,wall[j].y,2047,&wall[j].x,&wall[j].y);
}
}
j = headspritesect[highlightsector[i]];
while (j != -1)
{
if (k == 0)
{
x3 = sprite[j].x;
y3 = sprite[j].y;
sprite[j].x = dax+y3-day;
sprite[j].y = day+dax-x3;
sprite[j].ang = ((sprite[j].ang+1536)&2047);
}
else
{
rotatepoint(dax,day,sprite[j].x,sprite[j].y,2047,&sprite[j].x,&sprite[j].y);
sprite[j].ang = ((sprite[j].ang+2047)&2047);
}
j = nextspritesect[j];
}
}
if (k == 0) keystatus[0x34] = 0;
asksave = 1;
}
else
{
if (pointhighlight >= 16384)
{
i = pointhighlight-16384;
if ((keystatus[0x2a]|keystatus[0x36]) > 0)
sprite[i].ang = ((sprite[i].ang+2048+1)&2047);
else
{
sprite[i].ang = ((sprite[i].ang+2048+128)&2047);
keystatus[0x34] = 0;
}
clearmidstatbar16();
showspritedata((short)pointhighlight-16384);
}
}
}
if (keystatus[0x46] > 0) //Scroll lock (set starting position)
{
startposx = posx;
startposy = posy;
startposz = posz;
startang = ang;
startsectnum = cursectnum;
keystatus[0x46] = 0;
asksave = 1;
}
if (keystatus[0x3f] > 0) //F5
{
keystatus[0x3f] = 0;
for (i=0;i<numsectors;i++)
if (inside(mousxplc,mousyplc,i) == 1)
{
ydim16 = STATUS2DSIZ;
ExtShowSectorData((short)i);
ydim16 = ydim-STATUS2DSIZ;
break;
}
}
if (keystatus[0x40] > 0) //F6
{
keystatus[0x40] = 0;
if (pointhighlight >= 16384)
{
i = pointhighlight-16384;
ydim16 = STATUS2DSIZ;
ExtShowSpriteData((short)i);
ydim16 = ydim-STATUS2DSIZ;
}
else if (linehighlight >= 0)
{
i = linehighlight;
ydim16 = STATUS2DSIZ;
ExtShowWallData((short)i);
ydim16 = ydim-STATUS2DSIZ;
}
}
if (keystatus[0x41] > 0) //F7
{
keystatus[0x41] = 0;
for (i=0;i<numsectors;i++)
if (inside(mousxplc,mousyplc,i) == 1)
{
ydim16 = STATUS2DSIZ;
ExtEditSectorData((short)i);
ydim16 = ydim-STATUS2DSIZ;
break;
}
}
if (keystatus[0x42] > 0) //F8
{
keystatus[0x42] = 0;
if (pointhighlight >= 16384)
{
i = pointhighlight-16384;
ydim16 = STATUS2DSIZ;
ExtEditSpriteData((short)i);
ydim16 = ydim-STATUS2DSIZ;
}
else if (linehighlight >= 0)
{
i = linehighlight;
ydim16 = STATUS2DSIZ;
ExtEditWallData((short)i);
ydim16 = ydim-STATUS2DSIZ;
}
}
if (keystatus[0x14] > 0) // T (tag)
{
keystatus[0x14] = 0;
if ((keystatus[0x1d]|keystatus[0x9d]) > 0) //Ctrl-T
{
showtags ^= 1;
if (showtags == 0)
printmessage16("Show tags OFF");
else
printmessage16("Show tags ON");
}
else if ((keystatus[0x38]|keystatus[0xb8]) > 0) //ALT
{
if (pointhighlight >= 16384)
{
i = pointhighlight-16384;
Bsprintf(buffer,"Sprite (%ld) Lo-tag: ",i);
sprite[i].lotag = getnumber16(buffer,sprite[i].lotag,65536L,0);
clearmidstatbar16();
showspritedata((short)i);
}
else if (linehighlight >= 0)
{
i = linehighlight;
Bsprintf(buffer,"Wall (%ld) Lo-tag: ",i);
wall[i].lotag = getnumber16(buffer,wall[i].lotag,65536L,0);
clearmidstatbar16();
showwalldata((short)i);
}
printmessage16("");
}
else
{
for (i=0;i<numsectors;i++)
if (inside(mousxplc,mousyplc,i) == 1)
{
Bsprintf(buffer,"Sector (%ld) Lo-tag: ",i);
sector[i].lotag = getnumber16(buffer,sector[i].lotag,65536L,0);
clearmidstatbar16();
showsectordata((short)i);
break;
}
printmessage16("");
}
}
if (keystatus[0x23] > 0) //H (Hi 16 bits of tag)
{
keystatus[0x23] = 0;
if ((keystatus[0x1d]|keystatus[0x9d]) > 0) //Ctrl-H
{
pointhighlight = getpointhighlight(mousxplc, mousyplc);
linehighlight = getlinehighlight(mousxplc, mousyplc);
if ((pointhighlight&0xc000) == 16384)
{
sprite[pointhighlight&16383].cstat ^= 256;
asksave = 1;
}
else if (linehighlight >= 0)
{
wall[linehighlight].cstat ^= 64;
if ((wall[linehighlight].nextwall >= 0) && ((keystatus[0x2a]|keystatus[0x36]) == 0))
{
wall[wall[linehighlight].nextwall].cstat &= ~64;
wall[wall[linehighlight].nextwall].cstat |= (wall[linehighlight].cstat&64);
}
asksave = 1;
}
}
else if ((keystatus[0x38]|keystatus[0xb8]) > 0) //ALT
{
if (pointhighlight >= 16384)
{
i = pointhighlight-16384;
Bsprintf(buffer,"Sprite (%ld) Hi-tag: ",i);
sprite[i].hitag = getnumber16(buffer,sprite[i].hitag,65536L,0);
clearmidstatbar16();
showspritedata((short)i);
}
else if (linehighlight >= 0)
{
i = linehighlight;
Bsprintf(buffer,"Wall (%ld) Hi-tag: ",i);
wall[i].hitag = getnumber16(buffer,wall[i].hitag,65536L,0);
clearmidstatbar16();
showwalldata((short)i);
}
}
else
{
for (i=0;i<numsectors;i++)
if (inside(mousxplc,mousyplc,i) == 1)
{
Bsprintf(buffer,"Sector (%ld) Hi-tag: ",i);
sector[i].hitag = getnumber16(buffer,sector[i].hitag,65536L,0);
clearmidstatbar16();
showsectordata((short)i);
break;
}
}
printmessage16("");
}
if (keystatus[0x19] > 0) // P (palookup #)
{
keystatus[0x19] = 0;
for (i=0;i<numsectors;i++)
if (inside(mousxplc,mousyplc,i) == 1)
{
Bsprintf(buffer,"Sector (%ld) Ceilingpal: ",i);
sector[i].ceilingpal = getnumber16(buffer,sector[i].ceilingpal,256L,0);
clearmidstatbar16();
showsectordata((short)i);
Bsprintf(buffer,"Sector (%ld) Floorpal: ",i);
sector[i].floorpal = getnumber16(buffer,sector[i].floorpal,256L,0);
clearmidstatbar16();
showsectordata((short)i);
printmessage16("");
break;
}
}
if (keystatus[0x12] > 0) // E (status list)
{
if (pointhighlight >= 16384)
{
i = pointhighlight-16384;
Bsprintf(buffer,"Sprite (%ld) Status list: ",i);
changespritestat(i,getnumber16(buffer,sprite[i].statnum,65536L,0));
clearmidstatbar16();
showspritedata((short)i);
}
printmessage16("");
keystatus[0x12] = 0;
}
if (keystatus[0x0f] > 0) //TAB
{
clearmidstatbar16();
if ((keystatus[0x38]|keystatus[0xb8]|keystatus[0x1d]|keystatus[0x9d]) > 0) //ALT or CTRL
{
if (pointhighlight >= 16384)
showspritedata((short)pointhighlight-16384);
else if (linehighlight >= 0)
showwalldata((short)linehighlight);
}
else
{
for (i=0;i<numsectors;i++)
if (inside(mousxplc,mousyplc,i) == 1)
{
showsectordata((short)i);
break;
}
}
keystatus[0x0f] = 0;
}
if (highlightsectorcnt < 0)
{
if (keystatus[0x36] > 0) //Right shift (point highlighting)
{
if (highlightcnt == 0)
{
highlightx2 = searchx, highlighty2 = searchy;
ydim16 = ydim-STATUS2DSIZ;
drawline16(highlightx2,highlighty1,highlightx1,highlighty1,5);
drawline16(highlightx2,highlighty2,highlightx1,highlighty2,5);
drawline16(highlightx1,highlighty2,highlightx1,highlighty1,5);
drawline16(highlightx2,highlighty2,highlightx2,highlighty1,5);
}
if (highlightcnt != 0)
{
highlightx1 = searchx;
highlighty1 = searchy;
highlightx2 = searchx;
highlighty2 = searchx;
highlightcnt = 0;
for (i=0;i<(MAXWALLS>>3);i++) //Clear all highlights
show2dwall[i] = 0;
for (i=0;i<(MAXSPRITES>>3);i++)
show2dsprite[i] = 0;
}
}
else
{
if (highlightcnt == 0)
{
getpoint(highlightx1,highlighty1,&highlightx1,&highlighty1);
getpoint(highlightx2,highlighty2,&highlightx2,&highlighty2);
if (highlightx1 > highlightx2)
{
templong = highlightx1; highlightx1 = highlightx2; highlightx2 = templong;
}
if (highlighty1 > highlighty2)
{
templong = highlighty1; highlighty1 = highlighty2; highlighty2 = templong;
}
if ((keystatus[0x1d]|keystatus[0x9d]) > 0)
{
if ((linehighlight >= 0) && (linehighlight < MAXWALLS))
{
i = linehighlight;
do
{
highlight[highlightcnt++] = i;
show2dwall[i>>3] |= (1<<(i&7));
for (j=0;j<numwalls;j++)
if (wall[j].x == wall[i].x)
if (wall[j].y == wall[i].y)
if (i != j)
{
highlight[highlightcnt++] = j;
show2dwall[j>>3] |= (1<<(j&7));
}
i = wall[i].point2;
}
while (i != linehighlight);
}
}
else
{
for (i=0;i<numwalls;i++)
if ((wall[i].x >= highlightx1) && (wall[i].x <= highlightx2))
if ((wall[i].y >= highlighty1) && (wall[i].y <= highlighty2))
{
highlight[highlightcnt++] = i;
show2dwall[i>>3] |= (1<<(i&7));
}
for (i=0;i<MAXSPRITES;i++)
if (sprite[i].statnum < MAXSTATUS)
if ((sprite[i].x >= highlightx1) && (sprite[i].x <= highlightx2))
if ((sprite[i].y >= highlighty1) && (sprite[i].y <= highlighty2))
{
highlight[highlightcnt++] = i+16384;
show2dsprite[i>>3] |= (1<<(i&7));
}
}
if (highlightcnt <= 0)
highlightcnt = -1;
}
}
}
if (highlightcnt < 0)
{
if (keystatus[0xb8] > 0) //Right alt (sector highlighting)
{
if (highlightsectorcnt == 0)
{
highlightx2 = searchx, highlighty2 = searchy;
ydim16 = ydim-STATUS2DSIZ;
begindrawing(); //{{{
drawline16(highlightx2,highlighty1,highlightx1,highlighty1,10);
drawline16(highlightx2,highlighty2,highlightx1,highlighty2,10);
drawline16(highlightx1,highlighty2,highlightx1,highlighty1,10);
drawline16(highlightx2,highlighty2,highlightx2,highlighty1,10);
enddrawing(); //}}}
}
if (highlightsectorcnt != 0)
{
for (i=0;i<highlightsectorcnt;i++)
{
startwall = sector[highlightsector[i]].wallptr;
endwall = startwall+sector[highlightsector[i]].wallnum-1;
for (j=startwall;j<=endwall;j++)
{
if (wall[j].nextwall >= 0)
checksectorpointer(wall[j].nextwall,wall[j].nextsector);
checksectorpointer((short)j,highlightsector[i]);
}
}
highlightx1 = searchx;
highlighty1 = searchy;
highlightx2 = searchx;
highlighty2 = searchx;
highlightsectorcnt = 0;
}
}
else
{
if (highlightsectorcnt == 0)
{
getpoint(highlightx1,highlighty1,&highlightx1,&highlighty1);
getpoint(highlightx2,highlighty2,&highlightx2,&highlighty2);
if (highlightx1 > highlightx2)
{
templong = highlightx1; highlightx1 = highlightx2; highlightx2 = templong;
}
if (highlighty1 > highlighty2)
{
templong = highlighty1; highlighty1 = highlighty2; highlighty2 = templong;
}
for (i=0;i<numsectors;i++)
{
startwall = sector[i].wallptr;
endwall = startwall + sector[i].wallnum;
bad = 0;
for (j=startwall;j<endwall;j++)
{
if (wall[j].x < highlightx1) bad = 1;
if (wall[j].x > highlightx2) bad = 1;
if (wall[j].y < highlighty1) bad = 1;
if (wall[j].y > highlighty2) bad = 1;
if (bad == 1) break;
}
if (bad == 0)
highlightsector[highlightsectorcnt++] = i;
}
if (highlightsectorcnt <= 0)
highlightsectorcnt = -1;
//White out all bordering lines of grab that are
//not highlighted on both sides
for (i=highlightsectorcnt-1;i>=0;i--)
{
startwall = sector[highlightsector[i]].wallptr;
endwall = startwall + sector[highlightsector[i]].wallnum;
for (j=startwall;j<endwall;j++)
{
if (wall[j].nextwall >= 0)
{
for (k=highlightsectorcnt-1;k>=0;k--)
if (highlightsector[k] == wall[j].nextsector)
break;
if (k < 0)
{
wall[wall[j].nextwall].nextwall = -1;
wall[wall[j].nextwall].nextsector = -1;
wall[j].nextwall = -1;
wall[j].nextsector = -1;
}
}
}
}
}
}
}
if (((bstatus&1) < (oldmousebstatus&1)) && (highlightsectorcnt < 0)) //after dragging
{
j = 1;
if (highlightcnt > 0)
for (i=0;i<highlightcnt;i++)
if (pointhighlight == highlight[i])
{
j = 0;
break;
}
if (j == 0)
{
for (i=0;i<highlightcnt;i++)
{
if ((highlight[i]&0xc000) == 16384)
{
j = (highlight[i]&16383);
setsprite(j,sprite[j].x,sprite[j].y,sprite[j].z);
templong = ((tilesizy[sprite[j].picnum]*sprite[j].yrepeat)<<2);
sprite[j].z = max(sprite[j].z,getceilzofslope(sprite[j].sectnum,sprite[j].x,sprite[j].y)+templong);
sprite[j].z = min(sprite[j].z,getflorzofslope(sprite[j].sectnum,sprite[j].x,sprite[j].y));
}
}
}
else if ((pointhighlight&0xc000) == 16384)
{
j = (pointhighlight&16383);
setsprite(j,sprite[j].x,sprite[j].y,sprite[j].z);
templong = ((tilesizy[sprite[j].picnum]*sprite[j].yrepeat)<<2);
sprite[j].z = max(sprite[j].z,getceilzofslope(sprite[j].sectnum,sprite[j].x,sprite[j].y)+templong);
sprite[j].z = min(sprite[j].z,getflorzofslope(sprite[j].sectnum,sprite[j].x,sprite[j].y));
}
if ((pointhighlight&0xc000) == 0)
{
dax = wall[pointhighlight].x;
day = wall[pointhighlight].y;
}
else if ((pointhighlight&0xc000) == 16384)
{
dax = sprite[pointhighlight&16383].x;
day = sprite[pointhighlight&16383].y;
}
for (i=numwalls-1;i>=0;i--) //delete points
{
if (wall[i].x == wall[wall[i].point2].x)
if (wall[i].y == wall[wall[i].point2].y)
{
deletepoint((short)i);
printmessage16("Point deleted.");
asksave = 1;
}
}
for (i=0;i<numwalls;i++) //make new red lines?
{
if ((wall[i].x == dax) && (wall[i].y == day))
{
checksectorpointer((short)i,sectorofwall((short)i));
fixrepeats((short)i);
asksave = 1;
}
else if ((wall[wall[i].point2].x == dax) && (wall[wall[i].point2].y == day))
{
checksectorpointer((short)i,sectorofwall((short)i));
fixrepeats((short)i);
asksave = 1;
}
}
}
if ((bstatus&1) > 0) //drag points
{
if (highlightsectorcnt > 0)
{
if ((bstatus&1) > (oldmousebstatus&1))
{
newnumwalls = -1;
sectorhighlightstat = -1;
updatesector(mousxplc,mousyplc,&cursectorhighlight);
if ((cursectorhighlight >= 0) && (cursectorhighlight < numsectors))
{
for (i=0;i<highlightsectorcnt;i++)
if (cursectorhighlight == highlightsector[i])
{
//You clicked inside one of the flashing sectors!
sectorhighlightstat = 1;
dax = mousxplc;
day = mousyplc;
if ((gridlock > 0) && (grid > 0))
{
dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid)));
day = ((day+(1024>>grid))&(0xffffffff<<(11-grid)));
}
sectorhighlightx = dax;
sectorhighlighty = day;
break;
}
}
}
else if (sectorhighlightstat == 1)
{
dax = mousxplc;
day = mousyplc;
if ((gridlock > 0) && (grid > 0))
{
dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid)));
day = ((day+(1024>>grid))&(0xffffffff<<(11-grid)));
}
dax -= sectorhighlightx;
day -= sectorhighlighty;
sectorhighlightx += dax;
sectorhighlighty += day;
for (i=0;i<highlightsectorcnt;i++)
{
startwall = sector[highlightsector[i]].wallptr;
endwall = startwall+sector[highlightsector[i]].wallnum-1;
for (j=startwall;j<=endwall;j++)
{ wall[j].x += dax; wall[j].y += day; }
for (j=headspritesect[highlightsector[i]];j>=0;j=nextspritesect[j])
{ sprite[j].x += dax; sprite[j].y += day; }
}
//for(i=0;i<highlightsectorcnt;i++)
//{
// startwall = sector[highlightsector[i]].wallptr;
// endwall = startwall+sector[highlightsector[i]].wallnum-1;
// for(j=startwall;j<=endwall;j++)
// {
// if (wall[j].nextwall >= 0)
// checksectorpointer(wall[j].nextwall,wall[j].nextsector);
// checksectorpointer((short)j,highlightsector[i]);
// }
//}
asksave = 1;
}
}
else
{
if ((bstatus&1) > (oldmousebstatus&1))
pointhighlight = getpointhighlight(mousxplc, mousyplc);
if (pointhighlight >= 0)
{
dax = mousxplc;
day = mousyplc;
if ((gridlock > 0) && (grid > 0))
{
dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid)));
day = ((day+(1024>>grid))&(0xffffffff<<(11-grid)));
}
j = 1;
if (highlightcnt > 0)
for (i=0;i<highlightcnt;i++)
if (pointhighlight == highlight[i])
{ j = 0; break; }
if (j == 0)
{
if ((pointhighlight&0xc000) == 0)
{
dax -= wall[pointhighlight].x;
day -= wall[pointhighlight].y;
}
else
{
dax -= sprite[pointhighlight&16383].x;
day -= sprite[pointhighlight&16383].y;
}
for (i=0;i<highlightcnt;i++)
{
if ((highlight[i]&0xc000) == 0)
{
wall[highlight[i]].x += dax;
wall[highlight[i]].y += day;
}
else
{
sprite[highlight[i]&16383].x += dax;
sprite[highlight[i]&16383].y += day;
}
}
}
else
{
if ((pointhighlight&0xc000) == 0)
dragpoint(pointhighlight,dax,day);
else if ((pointhighlight&0xc000) == 16384)
{
daz = ((tilesizy[sprite[pointhighlight&16383].picnum]*sprite[pointhighlight&16383].yrepeat)<<2);
for (i=0;i<numsectors;i++)
if (inside(dax,day,i) == 1)
if (sprite[pointhighlight&16383].z >= getceilzofslope(i,dax,day))
if (sprite[pointhighlight&16383].z-daz <= getflorzofslope(i,dax,day))
{
sprite[pointhighlight&16383].x = dax;
sprite[pointhighlight&16383].y = day;
if (sprite[pointhighlight&16383].sectnum != i)
changespritesect(pointhighlight&16383,(short)i);
break;
}
}
}
asksave = 1;
}
}
}
else
{
pointhighlight = getpointhighlight(mousxplc, mousyplc);
sectorhighlightstat = -1;
}
if ((bstatus&6) > 0)
{
searchx = halfxdim16;
searchy = midydim16;
posx = mousxplc;
posy = mousyplc;
}
if (((keystatus[buildkeys[8]] > 0) || (bstatus&16)) && (zoom < 16384)) zoom += synctics*(zoom>>4);
if (((keystatus[buildkeys[9]] > 0) || (bstatus&32)) && (zoom > 24)) zoom -= synctics*(zoom>>4);
if (zoom < 24) zoom = 24;
if (zoom > 16384) zoom = 16384;
if (keystatus[0x22] > 0) // G (grid on/off)
{
grid++;
if (grid == 7) grid = 0;
keystatus[0x22] = 0;
}
if (keystatus[0x26] > 0) // L (grid lock)
{
gridlock = 1-gridlock, keystatus[0x26] = 0;
if (gridlock == 0)
printmessage16("Grid locking OFF");
else
printmessage16("Grid locking ON");
}
if (keystatus[0x24] > 0) // J (join sectors)
{
if (joinsector[0] >= 0)
{
joinsector[1] = -1;
for (i=0;i<numsectors;i++)
if (inside(mousxplc,mousyplc,i) == 1)
{
joinsector[1] = i;
break;
}
if ((joinsector[1] >= 0) && (joinsector[0] != joinsector[1]))
{
newnumwalls = numwalls;
for (k=0;k<2;k++)
{
startwall = sector[joinsector[k]].wallptr;
endwall = startwall + sector[joinsector[k]].wallnum - 1;
for (j=startwall;j<=endwall;j++)
{
if (wall[j].cstat == 255)
continue;
joinsectnum = k;
if (wall[j].nextsector == joinsector[1-joinsectnum])
{
wall[j].cstat = 255;
continue;
}
i = j;
m = newnumwalls;
do
{
Bmemcpy(&wall[newnumwalls],&wall[i],sizeof(walltype));
wall[newnumwalls].point2 = newnumwalls+1;
newnumwalls++;
wall[i].cstat = 255;
i = wall[i].point2;
if (wall[i].nextsector == joinsector[1-joinsectnum])
{
i = wall[wall[i].nextwall].point2;
joinsectnum = 1 - joinsectnum;
}
}
while ((wall[i].cstat != 255) && (wall[i].nextsector != joinsector[1-joinsectnum]));
wall[newnumwalls-1].point2 = m;
}
}
if (newnumwalls > numwalls)
{
Bmemcpy(&sector[numsectors],&sector[joinsector[0]],sizeof(sectortype));
sector[numsectors].wallptr = numwalls;
sector[numsectors].wallnum = newnumwalls-numwalls;
//fix sprites
for (i=0;i<2;i++)
{
j = headspritesect[joinsector[i]];
while (j != -1)
{
k = nextspritesect[j];
changespritesect(j,numsectors);
j = k;
}
}
numsectors++;
for (i=numwalls;i<newnumwalls;i++)
{
if (wall[i].nextwall >= 0)
{
wall[wall[i].nextwall].nextwall = i;
wall[wall[i].nextwall].nextsector = numsectors-1;
}
}
numwalls = newnumwalls;
newnumwalls = -1;
for (k=0;k<2;k++)
{
startwall = sector[joinsector[k]].wallptr;
endwall = startwall + sector[joinsector[k]].wallnum - 1;
for (j=startwall;j<=endwall;j++)
{
wall[j].nextwall = -1;
wall[j].nextsector = -1;
}
}
deletesector((short)joinsector[0]);
if (joinsector[0] < joinsector[1])
joinsector[1]--;
deletesector((short)joinsector[1]);
printmessage16("Sectors joined.");
}
}
joinsector[0] = -1;
}
else
{
joinsector[0] = -1;
for (i=0;i<numsectors;i++)
if (inside(mousxplc,mousyplc,i) == 1)
{
joinsector[0] = i;
printmessage16("Join sector - press J again on sector to join with.");
break;
}
}
keystatus[0x24] = 0;
}
if (((keystatus[0x38]|keystatus[0xb8])&keystatus[0x1f]) > 0) //ALT-S
{
if ((linehighlight >= 0) && (wall[linehighlight].nextwall == -1))
{
if ((newnumwalls = whitelinescan(linehighlight)) < numwalls)
{
printmessage16("Can't make a sector out there.");
}
else
{
for (i=numwalls;i<newnumwalls;i++)
{
wall[wall[i].nextwall].nextwall = i;
wall[wall[i].nextwall].nextsector = numsectors;
}
numwalls = newnumwalls;
newnumwalls = -1;
numsectors++;
printmessage16("Inner loop made into new sector.");
}
}
keystatus[0x1f] = 0;
}
else if (keystatus[0x1f] > 0) //S
{
sucksect = -1;
for (i=0;i<numsectors;i++)
if (inside(mousxplc,mousyplc,i) == 1)
{
sucksect = i;
break;
}
if (sucksect >= 0)
{
dax = mousxplc;
day = mousyplc;
if ((gridlock > 0) && (grid > 0))
{
dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid)));
day = ((day+(1024>>grid))&(0xffffffff<<(11-grid)));
}
i = insertsprite(sucksect,0);
sprite[i].x = dax, sprite[i].y = day;
sprite[i].cstat = defaultspritecstat;
sprite[i].shade = 0;
sprite[i].pal = 0;
sprite[i].xrepeat = 64, sprite[i].yrepeat = 64;
sprite[i].xoffset = 0, sprite[i].yoffset = 0;
sprite[i].ang = 1536;
sprite[i].xvel = 0; sprite[i].yvel = 0; sprite[i].zvel = 0;
sprite[i].owner = -1;
sprite[i].clipdist = 32;
sprite[i].lotag = 0;
sprite[i].hitag = 0;
sprite[i].extra = -1;
sprite[i].z = getflorzofslope(sucksect,dax,day);
if ((sprite[i].cstat&128) != 0)
sprite[i].z -= ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1);
for (k=0;k<MAXTILES;k++)
localartfreq[k] = 0;
for (k=0;k<MAXSPRITES;k++)
if (sprite[k].statnum < MAXSTATUS)
localartfreq[sprite[k].picnum]++;
j = 0;
for (k=0;k<MAXTILES;k++)
if (localartfreq[k] > localartfreq[j])
j = k;
if (localartfreq[j] > 0)
sprite[i].picnum = j;
else
sprite[i].picnum = 0;
if (somethingintab == 3)
{
sprite[i].picnum = temppicnum;
if ((tilesizx[temppicnum] <= 0) || (tilesizy[temppicnum] <= 0))
{
j = 0;
for (k=0;k<MAXTILES;k++)
if ((tilesizx[k] > 0) && (tilesizy[k] > 0))
{
j = k;
break;
}
sprite[i].picnum = j;
}
sprite[i].shade = tempshade;
sprite[i].pal = temppal;
sprite[i].xrepeat = tempxrepeat;
sprite[i].yrepeat = tempyrepeat;
if (sprite[i].xrepeat < 1) sprite[i].xrepeat = 1;
if (sprite[i].yrepeat < 1) sprite[i].yrepeat = 1;
sprite[i].cstat = tempcstat;
}
if (tilesizy[sprite[i].picnum] >= 32)
sprite[i].cstat |= 1;
printmessage16("Sprite inserted.");
updatenumsprites();
asksave = 1;
}
keystatus[0x1f] = 0;
}
if (keystatus[0x2e] > 0) // C (make circle of points)
{
if (highlightsectorcnt >= 0)
{
newnumsectors = numsectors;
newnumwalls = numwalls;
for (i=0;i<highlightsectorcnt;i++)
{
copysector(highlightsector[i],newnumsectors,newnumwalls,1);
newnumsectors++;
newnumwalls += sector[highlightsector[i]].wallnum;
}
for (i=0;i<highlightsectorcnt;i++)
{
startwall = sector[highlightsector[i]].wallptr;
endwall = startwall+sector[highlightsector[i]].wallnum-1;
for (j=startwall;j<=endwall;j++)
{
if (wall[j].nextwall >= 0)
checksectorpointer(wall[j].nextwall,wall[j].nextsector);
checksectorpointer((short)j,highlightsector[i]);
}
highlightsector[i] = numsectors+i;
}
numsectors = newnumsectors;
numwalls = newnumwalls;
newnumwalls = -1;
newnumsectors = -1;
updatenumsprites();
printmessage16("Sectors duplicated and stamped.");
asksave = 1;
}
else if (highlightcnt >= 0)
{
for (i=0;i<highlightcnt;i++)
if ((highlight[i]&0xc000) == 16384)
{
//duplicate sprite
k = (highlight[i]&16383);
j = insertsprite(sprite[k].sectnum,sprite[k].statnum);
Bmemcpy(&sprite[j],&sprite[k],sizeof(spritetype));
sprite[j].sectnum = sprite[k].sectnum; //Don't let memcpy overwrite sector!
setsprite(j,sprite[j].x,sprite[j].y,sprite[j].z);
}
updatenumsprites();
printmessage16("Sprites duplicated and stamped.");
asksave = 1;
}
else if (circlewall >= 0)
{
circlewall = -1;
}
else
{
if (linehighlight >= 0)
circlewall = linehighlight;
}
keystatus[0x2e] = 0;
}
if (keystatus[0x4a] > 0) // -
{
if (circlepoints > 1)
circlepoints--;
keystatus[0x4a] = 0;
}
if (keystatus[0x4e] > 0) // +
{
if (circlepoints < 63)
circlepoints++;
keystatus[0x4e] = 0;
}
bad = (keystatus[0x39] > 0); //Gotta do this to save lots of 3 spaces!
if (circlewall >= 0)
{
x1 = wall[circlewall].x;
y1 = wall[circlewall].y;
x2 = wall[wall[circlewall].point2].x;
y2 = wall[wall[circlewall].point2].y;
x3 = mousxplc;
y3 = mousyplc;
adjustmark(&x3,&y3,newnumwalls);
templong1 = dmulscale4(x3-x2,x1-x3,y1-y3,y3-y2);
templong2 = dmulscale4(y1-y2,x1-x3,y1-y3,x2-x1);
if (templong2 != 0)
{
centerx = (((x1+x2) + scale(y1-y2,templong1,templong2))>>1);
centery = (((y1+y2) + scale(x2-x1,templong1,templong2))>>1);
dax = mulscale14(centerx-posx,zoom);
day = mulscale14(centery-posy,zoom);
drawline16(halfxdim16+dax-2,midydim16+day-2,halfxdim16+dax+2,midydim16+day+2,14);
drawline16(halfxdim16+dax-2,midydim16+day+2,halfxdim16+dax+2,midydim16+day-2,14);
circleang1 = getangle(x1-centerx,y1-centery);
circleang2 = getangle(x2-centerx,y2-centery);
circleangdir = 1;
k = ((circleang2-circleang1)&2047);
if (mulscale4(x3-x1,y2-y1) < mulscale4(x2-x1,y3-y1))
{
circleangdir = -1;
k = -((circleang1-circleang2)&2047);
}
circlerad = (ksqrt(dmulscale4(centerx-x1,centerx-x1,centery-y1,centery-y1))<<2);
for (i=circlepoints;i>0;i--)
{
j = ((circleang1 + scale(i,k,circlepoints+1))&2047);
dax = centerx+mulscale14(sintable[(j+512)&2047],circlerad);
day = centery+mulscale14(sintable[j],circlerad);
if (dax <= -editorgridextent) dax = -editorgridextent;
if (dax >= editorgridextent) dax = editorgridextent;
if (day <= -editorgridextent) day = -editorgridextent;
if (day >= editorgridextent) day = editorgridextent;
if (bad > 0)
{
m = 0;
if (wall[circlewall].nextwall >= 0)
if (wall[circlewall].nextwall < circlewall) m = 1;
insertpoint(circlewall,dax,day);
circlewall += m;
}
dax = mulscale14(dax-posx,zoom);
day = mulscale14(day-posy,zoom);
drawline16(halfxdim16+dax-2,midydim16+day-2,halfxdim16+dax+2,midydim16+day-2,14);
drawline16(halfxdim16+dax+2,midydim16+day-2,halfxdim16+dax+2,midydim16+day+2,14);
drawline16(halfxdim16+dax+2,midydim16+day+2,halfxdim16+dax-2,midydim16+day+2,14);
drawline16(halfxdim16+dax-2,midydim16+day+2,halfxdim16+dax-2,midydim16+day-2,14);
}
if (bad > 0)
{
bad = 0;
keystatus[0x39] = 0;
asksave = 1;
printmessage16("Circle points inserted.");
circlewall = -1;
}
}
}
if (bad > 0) //Space bar test
{
keystatus[0x39] = 0;
adjustmark(&mousxplc,&mousyplc,newnumwalls);
if (checkautoinsert(mousxplc,mousyplc,newnumwalls) == 1)
{
printmessage16("You must insert a point there first.");
bad = 0;
}
}
if (bad > 0) //Space
{
if ((newnumwalls < numwalls) && (numwalls < MAXWALLS-1))
{
firstx = mousxplc, firsty = mousyplc; //Make first point
newnumwalls = numwalls;
suckwall = -1;
split = 0;
//clearbufbyte(&wall[newnumwalls],sizeof(walltype),0L);
memset(&wall[newnumwalls],0,sizeof(walltype));
wall[newnumwalls].extra = -1;
wall[newnumwalls].x = mousxplc;
wall[newnumwalls].y = mousyplc;
wall[newnumwalls].nextsector = -1;
wall[newnumwalls].nextwall = -1;
for (i=0;i<numwalls;i++)
if ((wall[i].x == mousxplc) && (wall[i].y == mousyplc))
suckwall = i;
wall[newnumwalls].point2 = newnumwalls+1;
printmessage16("Sector drawing started.");
newnumwalls++;
}
else
{ //if not back to first point
if ((firstx != mousxplc) || (firsty != mousyplc)) //nextpoint
{
j = 0;
for (i=numwalls;i<newnumwalls;i++)
if ((mousxplc == wall[i].x) && (mousyplc == wall[i].y))
j = 1;
if (j == 0)
{
//check if starting to split a sector
if (newnumwalls == numwalls+1)
{
dax = ((wall[numwalls].x+mousxplc)>>1);
day = ((wall[numwalls].y+mousyplc)>>1);
for (i=0;i<numsectors;i++)
if (inside(dax,day,i) == 1)
{ //check if first point at point of sector
m = -1;
startwall = sector[i].wallptr;
endwall = startwall + sector[i].wallnum - 1;
for (k=startwall;k<=endwall;k++)
if (wall[k].x == wall[numwalls].x)
if (wall[k].y == wall[numwalls].y)
{
m = k;
break;
}
if (m >= 0)
if ((wall[wall[k].point2].x != mousxplc) || (wall[wall[k].point2].y != mousyplc))
if ((wall[lastwall((short)k)].x != mousxplc) || (wall[lastwall((short)k)].y != mousyplc))
{
split = 1;
splitsect = i;
splitstartwall = m;
break;
}
}
}
//make new point
//make sure not drawing over old red line
bad = 0;
for (i=0;i<numwalls;i++)
{
if (wall[i].nextwall >= 0)
{
if ((wall[i].x == mousxplc) && (wall[i].y == mousyplc))
if ((wall[wall[i].point2].x == wall[newnumwalls-1].x) && (wall[wall[i].point2].y == wall[newnumwalls-1].y))
bad = 1;
if ((wall[i].x == wall[newnumwalls-1].x) && (wall[i].y == wall[newnumwalls-1].y))
if ((wall[wall[i].point2].x == mousxplc) && (wall[wall[i].point2].y == mousyplc))
bad = 1;
}
}
if (bad == 0)
{
//clearbufbyte(&wall[newnumwalls],sizeof(walltype),0L);
memset(&wall[newnumwalls],0,sizeof(walltype));
wall[newnumwalls].extra = -1;
wall[newnumwalls].x = mousxplc;
wall[newnumwalls].y = mousyplc;
wall[newnumwalls].nextsector = -1;
wall[newnumwalls].nextwall = -1;
for (i=0;i<numwalls;i++)
if ((wall[i].x == mousxplc) && (wall[i].y == mousyplc))
suckwall = i;
wall[newnumwalls].point2 = newnumwalls+1;
newnumwalls++;
}
else
{
printmessage16("You can't draw new lines over red lines.");
}
}
}
//if not split and back to first point
if ((split == 0) && (firstx == mousxplc) && (firsty == mousyplc) && (newnumwalls >= numwalls+3))
{
wall[newnumwalls-1].point2 = numwalls;
if (suckwall == -1) //if no connections to other sectors
{
k = -1;
for (i=0;i<numsectors;i++)
if (inside(firstx,firsty,i) == 1)
k = i;
if (k == -1) //if not inside another sector either
{ //add island sector
if (clockdir(numwalls) == 1)
flipwalls(numwalls,newnumwalls);
//clearbufbyte(&sector[numsectors],sizeof(sectortype),0L);
memset(&sector[numsectors],0,sizeof(sectortype));
sector[numsectors].extra = -1;
sector[numsectors].wallptr = numwalls;
sector[numsectors].wallnum = newnumwalls-numwalls;
sector[numsectors].ceilingz = (-32<<8);
sector[numsectors].floorz = (32<<8);
for (i=numwalls;i<newnumwalls;i++)
{
wall[i].cstat = 0;
wall[i].shade = 0;
wall[i].yrepeat = 8;
fixrepeats((short)i);
wall[i].picnum = 0;
wall[i].overpicnum = 0;
wall[i].nextsector = -1;
wall[i].nextwall = -1;
}
headspritesect[numsectors] = -1;
numsectors++;
}
else //else add loop to sector
{
if (clockdir(numwalls) == 0)
flipwalls(numwalls,newnumwalls);
j = newnumwalls-numwalls;
sector[k].wallnum += j;
for (i=k+1;i<numsectors;i++)
sector[i].wallptr += j;
suckwall = sector[k].wallptr;
for (i=0;i<numwalls;i++)
{
if (wall[i].nextwall >= suckwall)
wall[i].nextwall += j;
if (wall[i].point2 >= suckwall)
wall[i].point2 += j;
}
for (i=newnumwalls-1;i>=suckwall;i--)
Bmemcpy(&wall[i+j],&wall[i],sizeof(walltype));
for (i=0;i<j;i++)
Bmemcpy(&wall[i+suckwall],&wall[i+newnumwalls],sizeof(walltype));
for (i=suckwall;i<suckwall+j;i++)
{
wall[i].point2 += (suckwall-numwalls);
wall[i].cstat = wall[suckwall+j].cstat;
wall[i].shade = wall[suckwall+j].shade;
wall[i].yrepeat = wall[suckwall+j].yrepeat;
fixrepeats((short)i);
wall[i].picnum = wall[suckwall+j].picnum;
wall[i].overpicnum = wall[suckwall+j].overpicnum;
wall[i].nextsector = -1;
wall[i].nextwall = -1;
}
}
}
else
{
//add new sector with connections
if (clockdir(numwalls) == 1)
flipwalls(numwalls,newnumwalls);
//clearbufbyte(&sector[numsectors],sizeof(sectortype),0L);
memset(&sector[numsectors],0,sizeof(sectortype));
sector[numsectors].extra = -1;
sector[numsectors].wallptr = numwalls;
sector[numsectors].wallnum = newnumwalls-numwalls;
sucksect = sectorofwall(suckwall);
sector[numsectors].ceilingstat = sector[sucksect].ceilingstat;
sector[numsectors].floorstat = sector[sucksect].floorstat;
sector[numsectors].ceilingxpanning = sector[sucksect].ceilingxpanning;
sector[numsectors].floorxpanning = sector[sucksect].floorxpanning;
sector[numsectors].ceilingshade = sector[sucksect].ceilingshade;
sector[numsectors].floorshade = sector[sucksect].floorshade;
sector[numsectors].ceilingz = sector[sucksect].ceilingz;
sector[numsectors].floorz = sector[sucksect].floorz;
sector[numsectors].ceilingpicnum = sector[sucksect].ceilingpicnum;
sector[numsectors].floorpicnum = sector[sucksect].floorpicnum;
sector[numsectors].ceilingheinum = sector[sucksect].ceilingheinum;
sector[numsectors].floorheinum = sector[sucksect].floorheinum;
for (i=numwalls;i<newnumwalls;i++)
{
wall[i].cstat = wall[suckwall].cstat;
wall[i].shade = wall[suckwall].shade;
wall[i].yrepeat = wall[suckwall].yrepeat;
fixrepeats((short)i);
wall[i].picnum = wall[suckwall].picnum;
wall[i].overpicnum = wall[suckwall].overpicnum;
checksectorpointer((short)i,(short)numsectors);
}
headspritesect[numsectors] = -1;
numsectors++;
}
numwalls = newnumwalls;
newnumwalls = -1;
asksave = 1;
}
if (split == 1)
{
//split sector
startwall = sector[splitsect].wallptr;
endwall = startwall + sector[splitsect].wallnum - 1;
for (k=startwall;k<=endwall;k++)
if (wall[k].x == wall[newnumwalls-1].x)
if (wall[k].y == wall[newnumwalls-1].y)
{
bad = 0;
if (loopnumofsector(splitsect,splitstartwall) != loopnumofsector(splitsect,(short)k))
bad = 1;
if (bad == 0)
{
//SPLIT IT!
//Split splitsect given: startwall,
// new points: numwalls to newnumwalls-2
splitendwall = k;
newnumwalls--; //first fix up the new walls
for (i=numwalls;i<newnumwalls;i++)
{
wall[i].cstat = wall[startwall].cstat;
wall[i].shade = wall[startwall].shade;
wall[i].yrepeat = wall[startwall].yrepeat;
fixrepeats((short)i);
wall[i].picnum = wall[startwall].picnum;
wall[i].overpicnum = wall[startwall].overpicnum;
wall[i].nextwall = -1;
wall[i].nextsector = -1;
wall[i].point2 = i+1;
}
danumwalls = newnumwalls; //where to add more walls
m = splitendwall; //copy rest of loop next
while (m != splitstartwall)
{
Bmemcpy(&wall[danumwalls],&wall[m],sizeof(walltype));
wall[danumwalls].point2 = danumwalls+1;
danumwalls++;
m = wall[m].point2;
}
wall[danumwalls-1].point2 = numwalls;
//Add other loops for 1st sector
loopnum = loopnumofsector(splitsect,splitstartwall);
i = loopnum;
for (j=startwall;j<=endwall;j++)
{
k = loopnumofsector(splitsect,(short)j);
if ((k != i) && (k != loopnum))
{
i = k;
if (loopinside(wall[j].x,wall[j].y,numwalls) == 1)
{
m = j; //copy loop
k = danumwalls;
do
{
Bmemcpy(&wall[danumwalls],&wall[m],sizeof(walltype));
wall[danumwalls].point2 = danumwalls+1;
danumwalls++;
m = wall[m].point2;
}
while (m != j);
wall[danumwalls-1].point2 = k;
}
}
}
secondstartwall = danumwalls;
//copy split points for other sector backwards
for (j=newnumwalls;j>numwalls;j--)
{
Bmemcpy(&wall[danumwalls],&wall[j],sizeof(walltype));
wall[danumwalls].nextwall = -1;
wall[danumwalls].nextsector = -1;
wall[danumwalls].point2 = danumwalls+1;
danumwalls++;
}
m = splitstartwall; //copy rest of loop next
while (m != splitendwall)
{
Bmemcpy(&wall[danumwalls],&wall[m],sizeof(walltype));
wall[danumwalls].point2 = danumwalls+1;
danumwalls++;
m = wall[m].point2;
}
wall[danumwalls-1].point2 = secondstartwall;
//Add other loops for 2nd sector
loopnum = loopnumofsector(splitsect,splitstartwall);
i = loopnum;
for (j=startwall;j<=endwall;j++)
{
k = loopnumofsector(splitsect,(short)j);
if ((k != i) && (k != loopnum))
{
i = k;
if (loopinside(wall[j].x,wall[j].y,secondstartwall) == 1)
{
m = j; //copy loop
k = danumwalls;
do
{
Bmemcpy(&wall[danumwalls],&wall[m],sizeof(walltype));
wall[danumwalls].point2 = danumwalls+1;
danumwalls++;
m = wall[m].point2;
}
while (m != j);
wall[danumwalls-1].point2 = k;
}
}
}
//fix all next pointers on old sector line
for (j=numwalls;j<danumwalls;j++)
{
if (wall[j].nextwall >= 0)
{
wall[wall[j].nextwall].nextwall = j;
if (j < secondstartwall)
wall[wall[j].nextwall].nextsector = numsectors;
else
wall[wall[j].nextwall].nextsector = numsectors+1;
}
}
//set all next pointers on split
for (j=numwalls;j<newnumwalls;j++)
{
m = secondstartwall+(newnumwalls-1-j);
wall[j].nextwall = m;
wall[j].nextsector = numsectors+1;
wall[m].nextwall = j;
wall[m].nextsector = numsectors;
}
//copy sector attributes & fix wall pointers
Bmemcpy(&sector[numsectors],&sector[splitsect],sizeof(sectortype));
Bmemcpy(&sector[numsectors+1],&sector[splitsect],sizeof(sectortype));
sector[numsectors].wallptr = numwalls;
sector[numsectors].wallnum = secondstartwall-numwalls;
sector[numsectors+1].wallptr = secondstartwall;
sector[numsectors+1].wallnum = danumwalls-secondstartwall;
//fix sprites
j = headspritesect[splitsect];
while (j != -1)
{
k = nextspritesect[j];
if (loopinside(sprite[j].x,sprite[j].y,numwalls) == 1)
changespritesect(j,numsectors);
//else if (loopinside(sprite[j].x,sprite[j].y,secondstartwall) == 1)
else //Make sure no sprites get left out & deleted!
changespritesect(j,numsectors+1);
j = k;
}
numsectors+=2;
//Back of number of walls of new sector for later
k = danumwalls-numwalls;
//clear out old sector's next pointers for clean deletesector
numwalls = danumwalls;
for (j=startwall;j<=endwall;j++)
{
wall[j].nextwall = -1;
wall[j].nextsector = -1;
}
deletesector(splitsect);
//Check pointers
for (j=numwalls-k;j<numwalls;j++)
{
if (wall[j].nextwall >= 0)
checksectorpointer(wall[j].nextwall,wall[j].nextsector);
checksectorpointer((short)j,sectorofwall((short)j));
}
//k now safe to use as temp
for (m=numsectors-2;m<numsectors;m++)
{
j = headspritesect[m];
while (j != -1)
{
k = nextspritesect[j];
setsprite(j,sprite[j].x,sprite[j].y,sprite[j].z);
j = k;
}
}
newnumwalls = -1;
printmessage16("Sector split.");
break;
}
else
{
//Sector split - actually loop joining
splitendwall = k;
newnumwalls--; //first fix up the new walls
for (i=numwalls;i<newnumwalls;i++)
{
wall[i].cstat = wall[startwall].cstat;
wall[i].shade = wall[startwall].shade;
wall[i].yrepeat = wall[startwall].yrepeat;
fixrepeats((short)i);
wall[i].picnum = wall[startwall].picnum;
wall[i].overpicnum = wall[startwall].overpicnum;
wall[i].nextwall = -1;
wall[i].nextsector = -1;
wall[i].point2 = i+1;
}
danumwalls = newnumwalls; //where to add more walls
m = splitendwall; //copy rest of loop next
do
{
Bmemcpy(&wall[danumwalls],&wall[m],sizeof(walltype));
wall[danumwalls].point2 = danumwalls+1;
danumwalls++;
m = wall[m].point2;
} while (m != splitendwall);
//copy split points for other sector backwards
for (j=newnumwalls;j>numwalls;j--)
{
Bmemcpy(&wall[danumwalls],&wall[j],sizeof(walltype));
wall[danumwalls].nextwall = -1;
wall[danumwalls].nextsector = -1;
wall[danumwalls].point2 = danumwalls+1;
danumwalls++;
}
m = splitstartwall; //copy rest of loop next
do
{
Bmemcpy(&wall[danumwalls],&wall[m],sizeof(walltype));
wall[danumwalls].point2 = danumwalls+1;
danumwalls++;
m = wall[m].point2;
} while (m != splitstartwall);
wall[danumwalls-1].point2 = numwalls;
//Add other loops to sector
loopnum = loopnumofsector(splitsect,splitstartwall);
i = loopnum;
for (j=startwall;j<=endwall;j++)
{
k = loopnumofsector(splitsect,(short)j);
if ((k != i) && (k != loopnumofsector(splitsect,splitstartwall)) && (k != loopnumofsector(splitsect,splitendwall)))
{
i = k;
m = j; k = danumwalls; //copy loop
do
{
Bmemcpy(&wall[danumwalls],&wall[m],sizeof(walltype));
wall[danumwalls].point2 = danumwalls+1;
danumwalls++;
m = wall[m].point2;
} while (m != j);
wall[danumwalls-1].point2 = k;
}
}
//fix all next pointers on old sector line
for (j=numwalls;j<danumwalls;j++)
{
if (wall[j].nextwall >= 0)
{
wall[wall[j].nextwall].nextwall = j;
wall[wall[j].nextwall].nextsector = numsectors;
}
}
//copy sector attributes & fix wall pointers
Bmemcpy(&sector[numsectors],&sector[splitsect],sizeof(sectortype));
sector[numsectors].wallptr = numwalls;
sector[numsectors].wallnum = danumwalls-numwalls;
//fix sprites
j = headspritesect[splitsect];
while (j != -1)
{
k = nextspritesect[j];
changespritesect(j,numsectors);
j = k;
}
numsectors++;
//Back of number of walls of new sector for later
k = danumwalls-numwalls;
//clear out old sector's next pointers for clean deletesector
numwalls = danumwalls;
for (j=startwall;j<=endwall;j++)
{
wall[j].nextwall = -1;
wall[j].nextsector = -1;
}
deletesector(splitsect);
//Check pointers
for (j=numwalls-k;j<numwalls;j++)
{
if (wall[j].nextwall >= 0)
checksectorpointer(wall[j].nextwall,wall[j].nextsector);
checksectorpointer((short)j,numsectors-1);
}
newnumwalls = -1;
printmessage16("Loops joined.");
break;
}
}
}
}
}
if (keystatus[0x1c] > 0) //Left Enter
{
keystatus[0x1c] = 0;
if (keystatus[0x2a]&keystatus[0x1d])
{
printmessage16("CHECKING ALL POINTERS!");
for (i=0;i<numsectors;i++)
{
startwall = sector[i].wallptr;
for (j=startwall;j<numwalls;j++)
if (wall[j].point2 < startwall) startwall = wall[j].point2;
sector[i].wallptr = startwall;
}
for (i=numsectors-2;i>=0;i--)
sector[i].wallnum = sector[i+1].wallptr-sector[i].wallptr;
sector[numsectors-1].wallnum = numwalls-sector[numsectors-1].wallptr;
for (i=0;i<numwalls;i++)
{
wall[i].nextsector = -1;
wall[i].nextwall = -1;
}
for (i=0;i<numsectors;i++)
{
startwall = sector[i].wallptr;
endwall = startwall + sector[i].wallnum;
for (j=startwall;j<endwall;j++)
checksectorpointer((short)j,(short)i);
}
printmessage16("ALL POINTERS CHECKED!");
asksave = 1;
}
else
{
if (linehighlight >= 0)
{
checksectorpointer(linehighlight,sectorofwall(linehighlight));
printmessage16("Highlighted line pointers checked.");
asksave = 1;
}
}
}
if ((keystatus[0x0e] > 0) && (newnumwalls >= numwalls)) //Backspace
{
if (newnumwalls > numwalls)
{
newnumwalls--;
asksave = 1;
keystatus[0x0e] = 0;
}
if (newnumwalls == numwalls)
{
newnumwalls = -1;
asksave = 1;
keystatus[0x0e] = 0;
}
}
if ((keystatus[0xd3] > 0) && (keystatus[0x9d] > 0) && (numwalls >= 0))
{ //sector delete
keystatus[0xd3] = 0;
sucksect = -1;
for (i=0;i<numsectors;i++)
if (inside(mousxplc,mousyplc,i) == 1)
{
k = 0;
if (highlightsectorcnt >= 0)
for (j=0;j<highlightsectorcnt;j++)
if (highlightsector[j] == i)
{
for (j=highlightsectorcnt-1;j>=0;j--)
{
deletesector(highlightsector[j]);
for (k=j-1;k>=0;k--)
if (highlightsector[k] >= highlightsector[j])
highlightsector[k]--;
}
printmessage16("Highlighted sectors deleted.");
newnumwalls = -1;
k = 1;
highlightsectorcnt = -1;
break;
}
if (k == 0)
{
deletesector((short)i);
highlightsectorcnt = -1;
printmessage16("Sector deleted.");
}
newnumwalls = -1;
asksave = 1;
break;
}
}
if ((keystatus[0xd3] > 0) && (pointhighlight >= 0))
{
if ((pointhighlight&0xc000) == 16384) //Sprite Delete
{
deletesprite(pointhighlight&16383);
printmessage16("Sprite deleted.");
updatenumsprites();
asksave = 1;
}
keystatus[0xd3] = 0;
}
if (keystatus[0xd2] > 0) //InsertPoint
{
if (highlightsectorcnt >= 0)
{
newnumsectors = numsectors;
newnumwalls = numwalls;
for (i=0;i<highlightsectorcnt;i++)
{
copysector(highlightsector[i],newnumsectors,newnumwalls,1);
newnumsectors++;
newnumwalls += sector[highlightsector[i]].wallnum;
}
for (i=0;i<highlightsectorcnt;i++)
{
startwall = sector[highlightsector[i]].wallptr;
endwall = startwall+sector[highlightsector[i]].wallnum-1;
for (j=startwall;j<=endwall;j++)
{
if (wall[j].nextwall >= 0)
checksectorpointer(wall[j].nextwall,wall[j].nextsector);
checksectorpointer((short)j,highlightsector[i]);
}
highlightsector[i] = numsectors+i;
}
numsectors = newnumsectors;
numwalls = newnumwalls;
newnumwalls = -1;
newnumsectors = -1;
updatenumsprites();
printmessage16("Sectors duplicated and stamped.");
asksave = 1;
}
else if (highlightcnt >= 0)
{
for (i=0;i<highlightcnt;i++)
if ((highlight[i]&0xc000) == 16384)
{
//duplicate sprite
k = (highlight[i]&16383);
j = insertsprite(sprite[k].sectnum,sprite[k].statnum);
Bmemcpy(&sprite[j],&sprite[k],sizeof(spritetype));
sprite[j].sectnum = sprite[k].sectnum; //Don't let memcpy overwrite sector!
setsprite(j,sprite[j].x,sprite[j].y,sprite[j].z);
}
updatenumsprites();
printmessage16("Sprites duplicated and stamped.");
asksave = 1;
}
else if (linehighlight >= 0)
{
getclosestpointonwall(mousxplc,mousyplc,(long)linehighlight,&dax,&day);
adjustmark(&dax,&day,newnumwalls);
insertpoint(linehighlight,dax,day);
printmessage16("Point inserted.");
j = 0;
//Check to see if point was inserted over another point
for (i=numwalls-1;i>=0;i--) //delete points
if (wall[i].x == wall[wall[i].point2].x)
if (wall[i].y == wall[wall[i].point2].y)
{
deletepoint((short)i);
j++;
}
for (i=0;i<numwalls;i++) //make new red lines?
{
if ((wall[i].x == dax) && (wall[i].y == day))
{
checksectorpointer((short)i,sectorofwall((short)i));
fixrepeats((short)i);
}
else if ((wall[wall[i].point2].x == dax) && (wall[wall[i].point2].y == day))
{
checksectorpointer((short)i,sectorofwall((short)i));
fixrepeats((short)i);
}
}
//if (j != 0)
//{
// dax = ((wall[linehighlight].x + wall[wall[linehighlight].point2].x)>>1);
// day = ((wall[linehighlight].y + wall[wall[linehighlight].point2].y)>>1);
// if ((dax != wall[linehighlight].x) || (day != wall[linehighlight].y))
// if ((dax != wall[wall[linehighlight].point2].x) || (day != wall[wall[linehighlight].point2].y))
// {
// insertpoint(linehighlight,dax,day);
// printmessage16("Point inserted at midpoint.");
// }
//}
asksave = 1;
}
keystatus[0xd2] = 0;
}
/*j = 0;
for(i=22-1;i>=0;i--) updatecrc16(j,kensig[i]);
if ((j&0xffff) != 0xebf)
{
printf("Don't screw with my name.\n");
exit(0);
}*/
//printext16(9L,336+9L,4,-1,kensig,0);
//printext16(8L,336+8L,12,-1,kensig,0);
showframe(1);
synctics = totalclock-lockclock;
lockclock += synctics;
if (keystatus[buildkeys[14]] > 0)
{
updatesector(posx,posy,&cursectnum);
if (cursectnum >= 0)
keystatus[buildkeys[14]] = 2;
else
printmessage16("Arrow must be inside a sector before entering 3D mode.");
}
CANCEL:
if (keystatus[1] > 0)
{
keystatus[1] = 0;
printmessage16("(N)ew, (L)oad, (S)ave, save (A)s, (Q)uit");
showframe(1);
bflushchars();
bad = 1;
while (bad == 1)
{
if (handleevents()) {
if (quitevent) {
quitevent = 0;
}
}
idle();
ch = bgetchar();
if (keystatus[1] > 0)
{
keystatus[1] = 0;
bad = 0;
printmessage16("");
}
else if (ch == 'n' || ch == 'N') //N
{
bad = 0;
printmessage16("Are you sure you want to start a new board? (Y/N)");
showframe(1);
bflushchars(); ch = 0;
while (keystatus[1] == 0)
{
if (handleevents()) {
if (quitevent) {
quitevent = 0;
}
}
idle();
ch = bgetchar();
if (ch == 'Y' || ch == 'y')
{
highlightsectorcnt = -1;
highlightcnt = -1;
for (i=0;i<(MAXWALLS>>3);i++) //Clear all highlights
show2dwall[i] = 0;
for (i=0;i<(MAXSPRITES>>3);i++)
show2dsprite[i] = 0;
for (i=0;i<MAXSECTORS;i++) sector[i].extra = -1;
for (i=0;i<MAXWALLS;i++) wall[i].extra = -1;
for (i=0;i<MAXSPRITES;i++) sprite[i].extra = -1;
sectorhighlightstat = -1;
newnumwalls = -1;
joinsector[0] = -1;
circlewall = -1;
circlepoints = 7;
posx = 32768; //new board!
posy = 32768;
posz = 0;
ang = 1536;
numsectors = 0;
numwalls = 0;
numsprites = 0;
cursectnum = -1;
initspritelists();
Bstrcpy(boardfilename,"newboard.map");
break;
} else if (ch == 'N' || ch == 'n' || ch == 13 || ch == ' ') {
break;
}
}
printmessage16("");
showframe(1);
}
else if (ch == 'l' || ch == 'L') //L
{
bad = 0;
i = menuselect();
if (i < 0)
{
if (i == -2)
printmessage16("No .MAP files found.");
}
else
{
Bstrcpy(boardfilename, selectedboardfilename);
if (highlightsectorcnt >= 0)
{
j = 0; k = 0;
for (i=0;i<highlightsectorcnt;i++)
{
j += sector[highlightsector[i]].wallnum;
m = headspritesect[highlightsector[i]];
while (m != -1)
{
k++;
m = nextspritesect[m];
}
}
updatenumsprites();
if ((numsectors+highlightsectorcnt > MAXSECTORS) || (numwalls+j > MAXWALLS) || (numsprites+k > MAXSPRITES))
{
highlightsectorcnt = -1;
}
else
{
//Put sectors&walls to end of lists
j = MAXWALLS;
for (i=0;i<highlightsectorcnt;i++)
{
j -= sector[highlightsector[i]].wallnum;
copysector(highlightsector[i],(short)(MAXSECTORS-highlightsectorcnt+i),(short)j,0);
}
//Put sprites to end of list
//DONT USE m BETWEEN HERE AND SPRITE RE-ATTACHING!
m = MAXSPRITES;
for (i=MAXSPRITES-1;i>=0;i--)
if (sprite[i].statnum < MAXSTATUS)
{
k = sprite[i].sectnum;
for (j=0;j<highlightsectorcnt;j++)
if (highlightsector[j] == k)
{
m--;
if (i != m)
Bmemcpy(&sprite[m],&sprite[i],sizeof(spritetype));
//HACK - THESE 2 buffers back up .sectnum and .statnum
//for initspritelists() inside the loadboard call
//tsprite[m].picnum = MAXSECTORS-highlightsectorcnt+j;
//tsprite[m].owner = sprite[i].statnum;
// JBF: I see your hack and raise you another
spriteext[m].mdanimcur = MAXSECTORS-highlightsectorcnt+j;
spriteext[m].angoff = sprite[i].statnum;
break;
}
}
}
}
highlightcnt = -1;
sectorhighlightstat = -1;
newnumwalls = -1;
joinsector[0] = -1;
circlewall = -1;
circlepoints = 7;
for (i=0;i<MAXSECTORS;i++) sector[i].extra = -1;
for (i=0;i<MAXWALLS;i++) wall[i].extra = -1;
for (i=0;i<MAXSPRITES;i++) sprite[i].extra = -1;
ExtPreLoadMap();
i = loadboard(boardfilename,(!pathsearchmode&&grponlymode?2:0),&posx,&posy,&posz,&ang,&cursectnum);
if (i == -2) i = loadoldboard(boardfilename,(!pathsearchmode&&grponlymode?2:0),&posx,&posy,&posz,&ang,&cursectnum);
if (i < 0)
{
printmessage16("Invalid map format.");
}
else
{
ExtLoadMap(boardfilename);
if (highlightsectorcnt >= 0)
{
if ((numsectors+highlightsectorcnt > MAXSECTORS) || (sector[MAXSECTORS-highlightsectorcnt].wallptr < numwalls))
{
highlightsectorcnt = -1;
}
else
{
//Re-attach sectors&walls
for (i=0;i<highlightsectorcnt;i++)
{
copysector((short)(MAXSECTORS-highlightsectorcnt+i),numsectors,numwalls,0);
highlightsector[i] = numsectors;
numwalls += sector[numsectors].wallnum;
numsectors++;
}
//Re-attach sprites
while (m < MAXSPRITES)
{
//HACK - THESE 2 buffers back up .sectnum and .statnum
//for initspritelists() inside the loadboard call
//tsprite[m].picnum = sprite[i].sectnum;
//tsprite[m].owner = sprite[i].statnum;
j = insertsprite(tsprite[m].picnum+(numsectors-MAXSECTORS),tsprite[m].owner);
Bmemcpy(&sprite[j],&sprite[m],sizeof(spritetype));
//sprite[j].sectnum = tsprite[m].picnum+(numsectors-MAXSECTORS);
//sprite[j].statnum = tsprite[m].owner;
// JBF: I see your hack and raise you another
sprite[j].sectnum = spriteext[m].mdanimcur+(numsectors-MAXSECTORS);
sprite[j].statnum = spriteext[m].angoff;
spriteext[m].mdanimcur = spriteext[m].angoff = 0;
m++;
}
for (i=0;i<highlightsectorcnt;i++)
{
startwall = sector[highlightsector[i]].wallptr;
endwall = startwall+sector[highlightsector[i]].wallnum-1;
for (j=startwall;j<=endwall;j++)
{
if (wall[j].nextwall >= 0)
checksectorpointer(wall[j].nextwall,wall[j].nextsector);
checksectorpointer((short)j,highlightsector[i]);
}
}
}
}
if (mapversion < 7) printmessage16("Map loaded successfully and autoconverted to V7!");
else printmessage16("Map loaded successfully.");
}
updatenumsprites();
startposx = posx; //this is same
startposy = posy;
startposz = posz;
startang = ang;
startsectnum = cursectnum;
}
showframe(1);
keystatus[0x1c] = 0;
}
else if (ch == 'a' || ch == 'A') //A
{
bad = 0;
Bstrcpy(selectedboardfilename, boardfilename);
if (Bstrrchr(boardfilename, '/'))
Bstrcpy(boardfilename, Bstrrchr(boardfilename, '/')+1);
i = 0;
while ((boardfilename[i] != 0) && (i < 64))
i++;
if (boardfilename[i-4] == '.')
i -= 4;
boardfilename[i] = 0;
bflushchars();
while (bad == 0)
{
Bsprintf(buffer,"Save as: %s_", boardfilename);
printmessage16(buffer);
showframe(1);
if (handleevents()) {
if (quitevent) quitevent = 0;
}
idle();
ch = bgetchar();
if (keystatus[1] > 0) bad = 1;
else if (ch == 13) bad = 2;
else if (ch > 0) {
if (i > 0 && (ch == 8 || ch == 127)) {
i--;
boardfilename[i] = 0;
}
else if (i < 8 && ch > 32 && ch < 128)
{
boardfilename[i++] = ch;
boardfilename[i] = 0;
}
}
}
if (bad == 1)
{
Bstrcpy(boardfilename, selectedboardfilename);
keystatus[1] = 0;
printmessage16("Operation cancelled");
showframe(1);
}
if (bad == 2)
{
char *f;
keystatus[0x1c] = 0;
boardfilename[i] = '.';
boardfilename[i+1] = 'm';
boardfilename[i+2] = 'a';
boardfilename[i+3] = 'p';
boardfilename[i+4] = 0;
if (Bstrrchr(selectedboardfilename,'/'))
Bstrcpy(Bstrrchr(selectedboardfilename, '/')+1, boardfilename);
else
Bstrcpy(selectedboardfilename, boardfilename);
if (pathsearchmode) f = selectedboardfilename;
else {
// virtual filesystem mode can't save to directories so drop the file into
// the current directory
f = strrchr(selectedboardfilename, '/');
if (!f) f = selectedboardfilename; else f++;
}
Bsprintf(buffer,"Saving to %s...",f);
printmessage16(buffer);
showframe(1);
fixspritesectors(); //Do this before saving!
updatesector(startposx,startposy,&startsectnum);
ExtPreSaveMap();
saveboard(f,&startposx,&startposy,&startposz,&startang,&startsectnum);
ExtSaveMap(f);
printmessage16("Board saved.");
Bstrcpy(boardfilename, selectedboardfilename);
}
bad = 0;
}
else if (ch == 's' || ch == 'S') //S
{
char *f;
bad = 0;
printmessage16("Saving board...");
showframe(1);
fixspritesectors(); //Do this before saving!
updatesector(startposx,startposy,&startsectnum);
if (pathsearchmode) f = boardfilename;
else {
// virtual filesystem mode can't save to directories so drop the file into
// the current directory
f = strrchr(boardfilename, '/');
if (!f) f = boardfilename; else f++;
}
ExtPreSaveMap();
saveboard(f,&startposx,&startposy,&startposz,&startang,&startsectnum);
ExtSaveMap(f);
printmessage16("Board saved.");
showframe(1);
}
else if (ch == 'q' || ch == 'Q') //Q
{
bad = 0;
printmessage16("Are you sure you want to quit?");
showframe(1);
bflushchars();
while ((keystatus[1]|keystatus[0x2e]) == 0)
{
if (handleevents()) {
if (quitevent) quitevent = 0;
}
idle();
ch = bgetchar();
if (ch == 'y' || ch == 'Y')
{
//QUIT!
printmessage16("Save changes?");
showframe(1);
while ((keystatus[1]|keystatus[0x2e]) == 0)
{
if (handleevents()) {
if (quitevent) break; // like saying no
}
idle();
ch = bgetchar();
if (ch == 'y' || ch == 'Y')
{
char *f;
fixspritesectors(); //Do this before saving!
updatesector(startposx,startposy,&startsectnum);
ExtPreSaveMap();
if (pathsearchmode) f = boardfilename;
else {
// virtual filesystem mode can't save to directories so drop the file into
// the current directory
f = strrchr(boardfilename, '/');
if (!f) f = boardfilename; else f++;
}
saveboard(f,&startposx,&startposy,&startposz,&startang,&startsectnum);
ExtSaveMap(f);
break;
} else if (ch == 'n' || ch == 'N' || ch == 13 || ch == ' ') {
break;
}
}
while (keystatus[1] || keystatus[0x2e])
{
keystatus[1] = 0;
keystatus[0x2e] = 0;
quitevent = 0;
printmessage16("Operation cancelled");
showframe(1);
goto CANCEL;
}
clearfilenames();
uninittimer();
uninitinput();
ExtUnInit();
uninitengine();
printf("Memory status: %ld(%ld) bytes\n",cachesize,artsize);
printf("%s\n",kensig);
exit(0);
} else if (ch == 'n' || ch == 'N' || ch == 13 || ch == ' ') {
break;
}
}
printmessage16("");
showframe(1);
}
}
clearkeys();
}
//nextpage();
}
for (i=0;i<highlightsectorcnt;i++)
{
startwall = sector[highlightsector[i]].wallptr;
endwall = startwall+sector[highlightsector[i]].wallnum-1;
for (j=startwall;j<=endwall;j++)
{
if (wall[j].nextwall >= 0)
checksectorpointer(wall[j].nextwall,wall[j].nextsector);
checksectorpointer((short)j,highlightsector[i]);
}
}
fixspritesectors();
if (setgamemode(fullscreen,xdimgame,ydimgame,bppgame) < 0)
{
ExtUnInit();
uninitinput();
uninittimer();
uninitsystem();
clearfilenames();
printf("%ld * %ld not supported in this graphics mode\n",xdim,ydim);
exit(0);
}
setbrightness(brightness,palette,0);
posz = oposz;
searchx = scale(searchx,xdimgame,xdim2d);
searchy = scale(searchy,ydimgame,ydim2d-STATUS2DSIZ);
}
void getpoint(long searchxe, long searchye, long *x, long *y)
{
if (posx <= -editorgridextent) posx = -editorgridextent;
if (posx >= editorgridextent) posx = editorgridextent;
if (posy <= -editorgridextent) posy = -editorgridextent;
if (posy >= editorgridextent) posy = editorgridextent;
*x = posx + divscale14(searchxe-halfxdim16,zoom);
*y = posy + divscale14(searchye-midydim16,zoom);
if (*x <= -editorgridextent) *x = -editorgridextent;
if (*x >= editorgridextent) *x = editorgridextent;
if (*y <= -editorgridextent) *y = -editorgridextent;
if (*y >= editorgridextent) *y = editorgridextent;
}
long getlinehighlight(long xplc, long yplc)
{
long i, dst, dist, closest, x1, y1, x2, y2, nx, ny;
if (numwalls == 0)
return(-1);
dist = 1024;
closest = numwalls-1;
for (i=0;i<numwalls;i++)
{
getclosestpointonwall(xplc,yplc,i,&nx,&ny);
dst = klabs(xplc-nx)+klabs(yplc-ny);
if (dst <= dist)
{
dist = dst;
closest = i;
}
}
if (wall[closest].nextwall >= 0)
{ //if red line, allow highlighting of both sides
x1 = wall[closest].x;
y1 = wall[closest].y;
x2 = wall[wall[closest].point2].x;
y2 = wall[wall[closest].point2].y;
if (dmulscale32(xplc-x1,y2-y1,-(x2-x1),yplc-y1) >= 0)
closest = wall[closest].nextwall;
}
if ((pointhighlight&0xc000) == 16384) return (-1);
return(closest);
}
long getpointhighlight(long xplc, long yplc)
{
long i, dst, dist, closest;
if (numwalls == 0)
return(-1);
dist = 0;
if (grid > 0)
dist = 512;
closest = -1;
for (i=0;i<numwalls;i++)
{
dst = klabs(xplc-wall[i].x) + klabs(yplc-wall[i].y);
if (dst <= dist)
dist = dst, closest = i;
}
if (zoom >= 256)
for (i=0;i<MAXSPRITES;i++)
if (sprite[i].statnum < MAXSTATUS)
{
dst = klabs(xplc-sprite[i].x) + klabs(yplc-sprite[i].y);
if (dst <= dist)
dist = dst, closest = i+16384;
}
return(closest);
}
long adjustmark(long *xplc, long *yplc, short danumwalls)
{
long i, dst, dist, dax, day, pointlockdist;
if (danumwalls < 0)
danumwalls = numwalls;
pointlockdist = 0;
if ((grid > 0) && (gridlock > 0))
pointlockdist = (128>>grid);
dist = pointlockdist;
dax = *xplc;
day = *yplc;
for (i=0;i<danumwalls;i++)
{
dst = klabs((*xplc)-wall[i].x) + klabs((*yplc)-wall[i].y);
if (dst < dist)
{
dist = dst;
dax = wall[i].x;
day = wall[i].y;
}
}
if (dist == pointlockdist)
if ((gridlock > 0) && (grid > 0))
{
dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid)));
day = ((day+(1024>>grid))&(0xffffffff<<(11-grid)));
}
*xplc = dax;
*yplc = day;
return(0);
}
long checkautoinsert(long dax, long day, short danumwalls)
{
long i, x1, y1, x2, y2;
if (danumwalls < 0)
danumwalls = numwalls;
for (i=0;i<danumwalls;i++) // Check if a point should be inserted
{
x1 = wall[i].x;
y1 = wall[i].y;
x2 = wall[wall[i].point2].x;
y2 = wall[wall[i].point2].y;
if ((x1 != dax) || (y1 != day))
if ((x2 != dax) || (y2 != day))
if (((x1 <= dax) && (dax <= x2)) || ((x2 <= dax) && (dax <= x1)))
if (((y1 <= day) && (day <= y2)) || ((y2 <= day) && (day <= y1)))
if ((dax-x1)*(y2-y1) == (day-y1)*(x2-x1))
return(1); //insertpoint((short)i,dax,day);
}
return(0);
}
long clockdir(short wallstart) //Returns: 0 is CW, 1 is CCW
{
short i, themin;
long minx, templong, x0, x1, x2, y0, y1, y2;
minx = 0x7fffffff;
themin = -1;
i = wallstart-1;
do
{
i++;
if (wall[wall[i].point2].x < minx)
{
minx = wall[wall[i].point2].x;
themin = i;
}
}
while ((wall[i].point2 != wallstart) && (i < MAXWALLS));
x0 = wall[themin].x;
y0 = wall[themin].y;
x1 = wall[wall[themin].point2].x;
y1 = wall[wall[themin].point2].y;
x2 = wall[wall[wall[themin].point2].point2].x;
y2 = wall[wall[wall[themin].point2].point2].y;
if ((y1 >= y2) && (y1 <= y0)) return(0);
if ((y1 >= y0) && (y1 <= y2)) return(1);
templong = (x0-x1)*(y2-y1) - (x2-x1)*(y0-y1);
if (templong < 0)
return(0);
else
return(1);
}
void flipwalls(short numwalls, short newnumwalls)
{
long i, j, nume, templong;
nume = newnumwalls-numwalls;
for (i=numwalls;i<numwalls+(nume>>1);i++)
{
j = numwalls+newnumwalls-i-1;
templong = wall[i].x; wall[i].x = wall[j].x; wall[j].x = templong;
templong = wall[i].y; wall[i].y = wall[j].y; wall[j].y = templong;
}
}
void insertpoint(short linehighlight, long dax, long day)
{
short sucksect;
long i, j, k;
j = linehighlight;
sucksect = sectorofwall((short)j);
sector[sucksect].wallnum++;
for (i=sucksect+1;i<numsectors;i++)
sector[i].wallptr++;
movewalls((long)j+1,+1L);
Bmemcpy(&wall[j+1],&wall[j],sizeof(walltype));
wall[j].point2 = j+1;
wall[j+1].x = dax;
wall[j+1].y = day;
fixrepeats((short)j);
fixrepeats((short)j+1);
if (wall[j].nextwall >= 0)
{
k = wall[j].nextwall;
sucksect = sectorofwall((short)k);
sector[sucksect].wallnum++;
for (i=sucksect+1;i<numsectors;i++)
sector[i].wallptr++;
movewalls((long)k+1,+1L);
Bmemcpy(&wall[k+1],&wall[k],sizeof(walltype));
wall[k].point2 = k+1;
wall[k+1].x = dax;
wall[k+1].y = day;
fixrepeats((short)k);
fixrepeats((short)k+1);
j = wall[k].nextwall;
wall[j].nextwall = k+1;
wall[j+1].nextwall = k;
wall[k].nextwall = j+1;
wall[k+1].nextwall = j;
}
}
void deletepoint(short point)
{
long i, j, k, sucksect;
sucksect = sectorofwall(point);
sector[sucksect].wallnum--;
for (i=sucksect+1;i<numsectors;i++)
sector[i].wallptr--;
j = lastwall(point);
k = wall[point].point2;
wall[j].point2 = k;
if (wall[j].nextwall >= 0)
{
wall[wall[j].nextwall].nextwall = -1;
wall[wall[j].nextwall].nextsector = -1;
}
if (wall[point].nextwall >= 0)
{
wall[wall[point].nextwall].nextwall = -1;
wall[wall[point].nextwall].nextsector = -1;
}
movewalls((long)point,-1L);
checksectorpointer((short)j,(short)sucksect);
}
long deletesector(short sucksect)
{
long i, j, k, nextk, startwall, endwall;
while (headspritesect[sucksect] >= 0)
deletesprite(headspritesect[sucksect]);
updatenumsprites();
startwall = sector[sucksect].wallptr;
endwall = startwall + sector[sucksect].wallnum - 1;
j = sector[sucksect].wallnum;
for (i=sucksect;i<numsectors-1;i++)
{
k = headspritesect[i+1];
while (k != -1)
{
nextk = nextspritesect[k];
changespritesect((short)k,(short)i);
k = nextk;
}
Bmemcpy(&sector[i],&sector[i+1],sizeof(sectortype));
sector[i].wallptr -= j;
}
numsectors--;
j = endwall-startwall+1;
for (i=startwall;i<=endwall;i++)
if (wall[i].nextwall != -1)
{
wall[wall[i].nextwall].nextwall = -1;
wall[wall[i].nextwall].nextsector = -1;
}
movewalls(startwall,-j);
for (i=0;i<numwalls;i++)
if (wall[i].nextwall >= startwall)
wall[i].nextsector--;
return(0);
}
void fixspritesectors(void)
{
long i, j, dax, day, daz;
for (i=numsectors-1;i>=0;i--)
if ((sector[i].wallnum <= 0) || (sector[i].wallptr >= numwalls))
deletesector((short)i);
for (i=0;i<MAXSPRITES;i++)
if (sprite[i].statnum < MAXSTATUS)
{
dax = sprite[i].x;
day = sprite[i].y;
if (inside(dax,day,sprite[i].sectnum) != 1)
{
daz = ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<2);
for (j=0;j<numsectors;j++)
if (inside(dax,day,(short)j) == 1)
if (sprite[i].z >= getceilzofslope(j,dax,day))
if (sprite[i].z-daz <= getflorzofslope(j,dax,day))
{
changespritesect((short)i,(short)j);
break;
}
}
}
}
long movewalls(long start, long offs)
{
long i;
if (offs < 0) //Delete
{
for (i=start;i<numwalls+offs;i++)
Bmemcpy(&wall[i],&wall[i-offs],sizeof(walltype));
}
else if (offs > 0) //Insert
{
for (i=numwalls+offs-1;i>=start+offs;i--)
Bmemcpy(&wall[i],&wall[i-offs],sizeof(walltype));
}
numwalls += offs;
for (i=0;i<numwalls;i++)
{
if (wall[i].nextwall >= start) wall[i].nextwall += offs;
if (wall[i].point2 >= start) wall[i].point2 += offs;
}
return(0);
}
long checksectorpointer(short i, short sectnum)
{
long j, k, startwall, endwall, x1, y1, x2, y2;
x1 = wall[i].x;
y1 = wall[i].y;
x2 = wall[wall[i].point2].x;
y2 = wall[wall[i].point2].y;
if (wall[i].nextwall >= 0) //Check for early exit
{
k = wall[i].nextwall;
if ((wall[k].x == x2) && (wall[k].y == y2))
if ((wall[wall[k].point2].x == x1) && (wall[wall[k].point2].y == y1))
return(0);
}
wall[i].nextsector = -1;
wall[i].nextwall = -1;
for (j=0;j<numsectors;j++)
{
startwall = sector[j].wallptr;
endwall = startwall + sector[j].wallnum - 1;
for (k=startwall;k<=endwall;k++)
{
if ((wall[k].x == x2) && (wall[k].y == y2))
if ((wall[wall[k].point2].x == x1) && (wall[wall[k].point2].y == y1))
if (j != sectnum)
{
wall[i].nextsector = j;
wall[i].nextwall = k;
wall[k].nextsector = sectnum;
wall[k].nextwall = i;
}
}
}
return(0);
}
void fixrepeats(short i)
{
long dax, day, dist;
dax = wall[wall[i].point2].x-wall[i].x;
day = wall[wall[i].point2].y-wall[i].y;
dist = ksqrt(dax*dax+day*day);
dax = wall[i].xrepeat; day = wall[i].yrepeat;
wall[i].xrepeat = (char)min(max(mulscale10(dist,day),1),255);
}
void clearmidstatbar16(void)
{
begindrawing();
ydim16 = ydim;
// clearbuf((char *)(frameplace + (bytesperline*(ydim-STATUS2DSIZ+25L))),(bytesperline*(STATUS2DSIZ-1-(25<<1))) >> 2, 0x08080808l);
clearbuf((char *)(frameplace + (bytesperline*(ydim-STATUS2DSIZ+25L))),(bytesperline*(STATUS2DSIZ+2-(25<<1))) >> 2, 0x00000000l);
drawline16(0,ydim-STATUS2DSIZ,0,ydim-1,7);
drawline16(xdim-1,ydim-STATUS2DSIZ,xdim-1,ydim-1,7);
ydim16 = ydim-STATUS2DSIZ;
enddrawing();
}
short loopinside(long x, long y, short startwall)
{
long x1, y1, x2, y2, templong;
short i, cnt;
cnt = clockdir(startwall);
i = startwall;
do
{
x1 = wall[i].x; x2 = wall[wall[i].point2].x;
if ((x1 >= x) || (x2 >= x))
{
y1 = wall[i].y; y2 = wall[wall[i].point2].y;
if (y1 > y2)
{
templong = x1, x1 = x2, x2 = templong;
templong = y1, y1 = y2, y2 = templong;
}
if ((y1 <= y) && (y2 > y))
if (x1*(y-y2)+x2*(y1-y) <= x*(y1-y2))
cnt ^= 1;
}
i = wall[i].point2;
}
while (i != startwall);
return(cnt);
}
long numloopsofsector(short sectnum)
{
long i, numloops, startwall, endwall;
numloops = 0;
startwall = sector[sectnum].wallptr;
endwall = startwall + sector[sectnum].wallnum;
for (i=startwall;i<endwall;i++)
if (wall[i].point2 < i) numloops++;
return(numloops);
}
long getnumber16(char namestart[80], long num, long maxnumber, char sign)
{
char buffer[80], ch;
long j, k, n, danum, oldnum;
danum = (long)num;
oldnum = danum;
bflushchars();
while (keystatus[0x1] == 0)
{
if (handleevents()) {
if (quitevent) quitevent = 0;
}
idle();
ch = bgetchar();
Bsprintf(buffer,"%s%ld_ ",namestart,danum);
printmessage16(buffer);
showframe(1);
if (ch >= '0' && ch <= '9') {
if (danum >= 0)
{
n = (danum*10)+(ch-'0');
if (n <= maxnumber) danum = n;
}
else if (sign) // this extra check isn't hurting anything
{
n = (danum*10)-(ch-'0');
if (n >= -maxnumber) danum = n;
}
} else if (ch == 8 || ch == 127) { // backspace
danum /= 10;
} else if (ch == 13) {
oldnum = danum;
asksave = 1;
break;
} else if (ch == '-' && sign) { // negate
danum = -danum;
}
}
clearkeys();
return(oldnum);
}
long getnumber256(char namestart[80], long num, long maxnumber, char sign)
{
char buffer[80], ch;
long j, k, n, danum, oldnum;
danum = num;
oldnum = danum;
bflushchars();
while (keystatus[0x1] == 0)
{
if (handleevents()) {
if (quitevent) quitevent = 0;
}
drawrooms(posx,posy,posz,ang,horiz,cursectnum);
#ifdef SUPERBUILD
ExtAnalyzeSprites();
#endif
drawmasks();
ch = bgetchar();
Bsprintf(buffer,"%s%ld_ ",namestart,danum);
printmessage256(buffer);
showframe(1);
if (ch >= '0' && ch <= '9') {
if (danum >= 0)
{
n = (danum*10)+(ch-'0');
if (n <= maxnumber) danum = n;
}
else if (sign)
{
n = (danum*10)-(ch-'0');
if (n >= -maxnumber) danum = n;
}
} else if (ch == 8 || ch == 127) { // backspace
danum /= 10;
} else if (ch == 13) {
oldnum = danum;
asksave = 1;
break;
} else if (ch == '-' && sign) { // negate
danum = -danum;
}
}
clearkeys();
lockclock = totalclock; //Reset timing
return(oldnum);
}
void clearfilenames(void)
{
klistfree(finddirs);
klistfree(findfiles);
finddirs = findfiles = NULL;
numfiles = numdirs = 0;
}
long getfilenames(char *path, char *kind)
{
CACHE1D_FIND_REC *r;
clearfilenames();
finddirs = klistpath(path,"*",CACHE1D_FIND_DIR|CACHE1D_FIND_DRIVE|(!pathsearchmode&&grponlymode?CACHE1D_OPT_NOSTACK:0));
findfiles = klistpath(path,kind,CACHE1D_FIND_FILE|(!pathsearchmode&&grponlymode?CACHE1D_OPT_NOSTACK:0));
for (r = finddirs; r; r=r->next) numdirs++;
for (r = findfiles; r; r=r->next) numfiles++;
finddirshigh = finddirs;
findfileshigh = findfiles;
currentlist = 0;
if (findfileshigh) currentlist = 1;
return(0);
}
long menuselect(void)
{
int listsize;
long i, j, topplc;
char ch, buffer[78], *sb;
static char oldpath[BMAX_PATH];
CACHE1D_FIND_REC *dir;
int bakpathsearchmode = pathsearchmode;
listsize = (ydim16-32)/8;
Bstrcpy(selectedboardfilename, oldpath);
if (pathsearchmode)
Bcanonicalisefilename(selectedboardfilename, 1); // clips off the last token and compresses relative path
else
Bcorrectfilename(selectedboardfilename, 1);
getfilenames(selectedboardfilename, "*.map");
begindrawing();
printmessage16("Select map file with arrow keys and enter.");
enddrawing();
do {
begindrawing();
clearbuf((char *)frameplace, (bytesperline*ydim16) >> 2, 0l);
if (pathsearchmode) {
strcpy(buffer,"Local filesystem mode; press F for game filesystem.");
} else {
sprintf(buffer,"Game filesystem %smode; press F for local filesystem or G for %s.",
grponlymode?"GRP-only ":"", grponlymode?"all files":"GRP contents only");
}
printext16(halfxdim16-(8*strlen(buffer)/2), 4, 12,0,buffer,0);
Bsnprintf(buffer,78,"(%d dirs, %d files) %s",numdirs,numfiles,selectedboardfilename);
buffer[sizeof(buffer)-1] = 0;
printext16(1,ydim16-8-1,8,0,buffer,0);
if (finddirshigh) {
dir = finddirshigh;
for (i=listsize/2-1; i>=0; i--) if (!dir->prev) break; else dir=dir->prev;
for (i=0; i<listsize && dir; i++, dir=dir->next) {
int c = dir->type == CACHE1D_FIND_DIR ? 4 : 3;
memset(buffer,0,sizeof(buffer));
strncpy(buffer,dir->name,25);
if (strlen(buffer) == 25)
buffer[21] = buffer[22] = buffer[23] = '.', buffer[24] = 0;
if (dir == finddirshigh) {
if (currentlist == 0) printext16(8,16+8*i,c|8,0,"->",0);
printext16(32,16+8*i,c|8,0,buffer,0);
} else {
printext16(32,16+8*i,c,0,buffer,0);
}
}
}
if (findfileshigh) {
dir = findfileshigh;
for (i=listsize/2-1; i>=0; i--) if (!dir->prev) break; else dir=dir->prev;
for (i=0; i<listsize && dir; i++, dir=dir->next) {
if (dir == findfileshigh) {
if (currentlist == 1) printext16(240,16+8*i,7|8,0,"->",0);
printext16(240+24,16+8*i,7|8,0,dir->name,0);
} else {
printext16(240+24,16+8*i,7,0,dir->name,0);
}
}
}
enddrawing();
showframe(1);
keystatus[0xcb] = 0;
keystatus[0xcd] = 0;
keystatus[0xc8] = 0;
keystatus[0xd0] = 0;
keystatus[0x1c] = 0; //enter
keystatus[0xf] = 0; //tab
keystatus[1] = 0; //esc
ch = 0; //Interesting fakery of ch = getch()
while (ch == 0)
{
if (handleevents()) {
if (quitevent) {
keystatus[1] = 1;
quitevent = 0;
}
}
idle();
ch = bgetchar();
{ // JBF 20040208: seek to first name matching pressed character
CACHE1D_FIND_REC *seeker = currentlist ? findfiles : finddirs;
if ((keystatus[0xc7]|keystatus[0xcf]) > 0) // home/end
{
while (keystatus[0xcf]?seeker->next:seeker->prev)
seeker = keystatus[0xcf]?seeker->next:seeker->prev;
if (seeker) {
if (currentlist) findfileshigh = seeker;
else finddirshigh = seeker;
}
ch = keystatus[0xcf]?80:72;
keystatus[0xc7] = keystatus[0xcf] = 0;
}
else if ((keystatus[0xc9]|keystatus[0xd1]) > 0) // page up/down
{
seeker = currentlist?findfileshigh:finddirshigh;
i = (ydim2d-STATUS2DSIZ-48)>>3;
while (i>0) {
if (keystatus[0xd1]?seeker->next:seeker->prev)
seeker = keystatus[0xd1]?seeker->next:seeker->prev;
i--;
}
if (seeker) {
if (currentlist) findfileshigh = seeker;
else finddirshigh = seeker;
}
ch = keystatus[0xd1]?80:72;
keystatus[0xc9] = keystatus[0xd1] = 0;
}
else
{
char ch2;
if (ch > 0 && ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9'))) {
if (ch >= 'a') ch -= ('a'-'A');
while (seeker) {
ch2 = seeker->name[0];
if (ch2 >= 'a' && ch2 <= 'z') ch2 -= ('a'-'A');
if (ch2 == ch) break;
seeker = seeker->next;
}
if (seeker) {
if (currentlist) findfileshigh = seeker;
else finddirshigh = seeker;
continue;
}
}
}
}
if (keystatus[0xcb] > 0) ch = 9; // left arr
if (keystatus[0xcd] > 0) ch = 9; // right arr
if (keystatus[0xc8] > 0) ch = 72; // up arr
if (keystatus[0xd0] > 0) ch = 80; // down arr
}
if (ch == 'f' || ch == 'F') {
currentlist = 0;
pathsearchmode = 1-pathsearchmode;
if (pathsearchmode) {
strcpy(selectedboardfilename, "");
Bcanonicalisefilename(selectedboardfilename, 0);
} else strcpy(selectedboardfilename, "/");
getfilenames(selectedboardfilename, "*.map");
Bstrcpy(oldpath,selectedboardfilename);
} else if (ch == 'g' || ch == 'G') {
if (!pathsearchmode) {
grponlymode = 1-grponlymode;
getfilenames(selectedboardfilename, "*.map");
Bstrcpy(oldpath,selectedboardfilename);
}
} else if (ch == 9) {
if ((currentlist == 0 && findfiles) || (currentlist == 1 && finddirs))
currentlist = 1-currentlist;
} else if ((ch == 75) || (ch == 72)) {
if (currentlist == 0) {
if (finddirshigh && finddirshigh->prev) finddirshigh = finddirshigh->prev;
} else {
if (findfileshigh && findfileshigh->prev) findfileshigh = findfileshigh->prev;
}
} else if ((ch == 77) || (ch == 80)) {
if (currentlist == 0) {
if (finddirshigh && finddirshigh->next) finddirshigh = finddirshigh->next;
} else {
if (findfileshigh && findfileshigh->next) findfileshigh = findfileshigh->next;
}
} else if ((ch == 13) && (currentlist == 0)) {
if (finddirshigh->type == CACHE1D_FIND_DRIVE) {
strcpy(selectedboardfilename, finddirshigh->name);
} else {
strcat(selectedboardfilename, finddirshigh->name);
}
strcat(selectedboardfilename, "/");
if (pathsearchmode)
Bcanonicalisefilename(selectedboardfilename, 1);
else
Bcorrectfilename(selectedboardfilename, 1);
Bstrcpy(oldpath,selectedboardfilename);
//printf("Changing directories to: %s\n", selectedboardfilename);
getfilenames(selectedboardfilename, "*.map");
ch = 0;
begindrawing();
clearbuf((char *)frameplace, (bytesperline*ydim16) >> 2, 0l);
enddrawing();
showframe(1);
}
if (ch == 13 && !findfileshigh) ch = 0;
}
while ((ch != 13) && (ch != 27));
if (ch == 13)
{
Bstrcat(selectedboardfilename, findfileshigh->name);
//printf("Selected file: %s\n", selectedboardfilename);
return(0);
}
pathsearchmode = bakpathsearchmode;
return(-1);
}
long fillsector(short sectnum, char fillcolor)
{
long x1, x2, y1, y2, sy, y, templong;
long lborder, rborder, uborder, dborder, miny, maxy, dax;
short z, zz, startwall, endwall, fillcnt;
lborder = 0; rborder = xdim;
uborder = 0; dborder = ydim16;
if (sectnum == -1)
return(0);
miny = dborder-1;
maxy = uborder;
startwall = sector[sectnum].wallptr;
endwall = startwall + sector[sectnum].wallnum - 1;
for (z=startwall;z<=endwall;z++)
{
y1 = (((wall[z].y-posy)*zoom)>>14)+midydim16;
y2 = (((wall[wall[z].point2].y-posy)*zoom)>>14)+midydim16;
if (y1 < miny) miny = y1;
if (y2 < miny) miny = y2;
if (y1 > maxy) maxy = y1;
if (y2 > maxy) maxy = y2;
}
if (miny < uborder) miny = uborder;
if (maxy >= dborder) maxy = dborder-1;
for (sy=miny+((totalclock>>2)&3);sy<=maxy;sy+=3) // JBF 20040116: numframes%3 -> (totalclock>>2)&3
{
y = posy+(((sy-midydim16)<<14)/zoom);
fillist[0] = lborder; fillcnt = 1;
for (z=startwall;z<=endwall;z++)
{
x1 = wall[z].x; x2 = wall[wall[z].point2].x;
y1 = wall[z].y; y2 = wall[wall[z].point2].y;
if (y1 > y2)
{
templong = x1; x1 = x2; x2 = templong;
templong = y1; y1 = y2; y2 = templong;
}
if ((y1 <= y) && (y2 > y))
//if (x1*(y-y2) + x2*(y1-y) <= 0)
{
dax = x1+scale(y-y1,x2-x1,y2-y1);
dax = (((dax-posx)*zoom)>>14)+halfxdim16;
if (dax >= lborder)
fillist[fillcnt++] = dax;
}
}
if (fillcnt > 0)
{
for (z=1;z<fillcnt;z++)
for (zz=0;zz<z;zz++)
if (fillist[z] < fillist[zz])
{
templong = fillist[z]; fillist[z] = fillist[zz]; fillist[zz] = templong;
}
for (z=(fillcnt&1);z<fillcnt-1;z+=2)
{
if (fillist[z] > rborder) break;
if (fillist[z+1] > rborder)
fillist[z+1] = rborder;
drawline16(fillist[z],sy,fillist[z+1],sy,fillcolor);
}
}
}
return(0);
}
short whitelinescan(short dalinehighlight)
{
long i, j, k;
short sucksect, newnumwalls;
sucksect = sectorofwall(dalinehighlight);
Bmemcpy(&sector[numsectors],&sector[sucksect],sizeof(sectortype));
sector[numsectors].wallptr = numwalls;
sector[numsectors].wallnum = 0;
i = dalinehighlight;
newnumwalls = numwalls;
do
{
j = lastwall((short)i);
if (wall[j].nextwall >= 0)
{
j = wall[j].point2;
for (k=0;k<numwalls;k++)
{
if (wall[wall[k].point2].x == wall[j].x)
if (wall[wall[k].point2].y == wall[j].y)
if (wall[k].nextwall == -1)
{
j = k;
break;
}
}
}
Bmemcpy(&wall[newnumwalls],&wall[i],sizeof(walltype));
wall[newnumwalls].nextwall = j;
wall[newnumwalls].nextsector = sectorofwall((short)j);
newnumwalls++;
sector[numsectors].wallnum++;
i = j;
}
while (i != dalinehighlight);
for (i=numwalls;i<newnumwalls-1;i++)
wall[i].point2 = i+1;
wall[newnumwalls-1].point2 = numwalls;
if (clockdir(numwalls) == 1)
return(-1);
else
return(newnumwalls);
}
/*
#define loadbyte(fil,tempbuf,bufplc,dat) \
{ \
if (bufplc == 0) \
{ \
for(bufplc=0;bufplc<4096;bufplc++) \
tempbuf[bufplc] = 0; \
bufplc = 0; \
read(fil,tempbuf,4096); \
} \
dat = tempbuf[bufplc]; \
bufplc = ((bufplc+1)&4095); \
} \
long loadnames(void)
{
char buffer[80], firstch, ch;
long fil, i, num, buffercnt, bufplc;
if ((fil = open("names.h",O_BINARY|O_RDWR,S_IREAD)) == -1) return(-1);
bufplc = 0;
do { loadbyte(fil,tempbuf,bufplc,firstch); } while (firstch != '#');
while ((firstch == '#') || (firstch == '/'))
{
do { loadbyte(fil,tempbuf,bufplc,ch); } while (ch > 32);
buffercnt = 0;
do
{
loadbyte(fil,tempbuf,bufplc,ch);
if (ch > 32) buffer[buffercnt++] = ch;
}
while (ch > 32);
num = 0;
do
{
loadbyte(fil,tempbuf,bufplc,ch);
if ((ch >= 48) && (ch <= 57)) num = num*10+(ch-48);
}
while (ch != 13);
for(i=0;i<buffercnt;i++) names[num][i] = buffer[i];
names[num][buffercnt] = 0;
loadbyte(fil,tempbuf,bufplc,firstch);
if (firstch == 10) loadbyte(fil,tempbuf,bufplc,firstch);
}
close(fil);
return(0);
}
*/
long loadnames(void)
{
char buffer[1024], *p, *name, *number, *endptr;
int num, syms=0, line=0, a;
BFILE *fp;
fp = fopenfrompath("NAMES.H","r");
if (!fp) {
if ((fp = fopenfrompath("names.h","r")) == NULL) {
printf("Failed to open NAMES.H\n");
return -1;
}
}
//clearbufbyte(names, sizeof(names), 0);
memset(names,0,sizeof(names));
printf("Loading NAMES.H\n");
while (Bfgets(buffer, 1024, fp)) {
a = Bstrlen(buffer);
if (a >= 1) {
if (a > 1)
if (buffer[a-2] == '\r') buffer[a-2] = 0;
if (buffer[a-1] == '\n') buffer[a-1] = 0;
}
p = buffer;
line++;
while (*p == 32) p++;
if (*p == 0) continue; // blank line
if (*p == '#') {
p++;
while (*p == 32) p++;
if (*p == 0) continue; // null directive
if (!Bstrncmp(p, "define ", 7)) {
// #define_...
p += 7;
while (*p == 32) p++;
if (*p == 0) {
printf("Error: Malformed #define at line %d\n", line-1);
continue;
}
name = p;
while (*p != 32 && *p != 0) p++;
if (*p == 32) {
*(p++) = 0;
while (*p == 32) p++;
if (*p == 0) { // #define_NAME with no number
printf("Error: No number given for name \"%s\" (line %d)\n", name, line-1);
continue;
}
number = p;
while (*p != 0) p++;
if (*p != 0) *p = 0;
// add to list
num = Bstrtol(number, &endptr, 10);
if (*endptr != 0) {
p = endptr;
goto badline;
}
//printf("Grokked \"%s\" -> \"%d\"\n", name, num);
if (num < 0 || num >= MAXTILES) {
printf("Error: Constant %d for name \"%s\" out of range (line %d)\n", num, name, line-1);
continue;
}
if (Bstrlen(name) > 24)
printf("Warning: Name \"%s\" longer than 24 characters (line %d). Truncating.\n", name, line-1);
Bstrncpy(names[num], name, 24);
names[num][24] = 0;
syms++;
continue;
} else { // #define_NAME with no number
printf("Error: No number given for name \"%s\" (line %d)\n", name, line-1);
continue;
}
} else goto badline;
} else if (*p == '/') {
if (*(p+1) == '/') continue; // comment
}
badline:
printf("Error: Invalid statement found at character %d on line %d\n", (p-buffer), line-1);
}
printf("Read %d lines, loaded %d names.\n", line, syms);
Bfclose(fp);
return 0;
}
void printcoords16(long posxe, long posye, short ange)
{
char snotbuf[80];
long i,m;
Bsprintf(snotbuf,"x=%ld y=%ld ang=%d",posxe,posye,ange);
i = 0;
while ((snotbuf[i] != 0) && (i < 30))
i++;
while (i < 30)
{
snotbuf[i] = 32;
i++;
}
snotbuf[30] = 0;
m = (numsectors > MAXSECTORSV7 || numwalls > MAXWALLSV7 || numsprites > MAXSPRITESV7);
printext16(8, ydim-STATUS2DSIZ+128+2, 9, 0, snotbuf,0);
Bsprintf(snotbuf,"%d/%d sect. %d/%d walls %ld/%d spri.",
numsectors,m?MAXSECTORSV8:MAXSECTORSV7,
numwalls,m?MAXWALLSV8:MAXWALLSV7,
numsprites,m?MAXSPRITESV8:MAXSPRITESV7);
i = 0;
while ((snotbuf[i] != 0) && (i < 46))
i++;
while (i < 46)
{
snotbuf[i] = 32;
i++;
}
snotbuf[46] = 0;
printext16(264, ydim-STATUS2DSIZ+128+2, 9+m, 0, snotbuf,0);
}
void updatenumsprites(void)
{
long i;
numsprites = 0;
for (i=0;i<MAXSPRITES;i++)
if (sprite[i].statnum < MAXSTATUS)
numsprites++;
}
void copysector(short soursector, short destsector, short deststartwall, char copystat)
{
short j, k, m, newnumwalls, startwall, endwall;
newnumwalls = deststartwall; //erase existing sector fragments
//duplicate walls
startwall = sector[soursector].wallptr;
endwall = startwall + sector[soursector].wallnum;
for (j=startwall;j<endwall;j++)
{
Bmemcpy(&wall[newnumwalls],&wall[j],sizeof(walltype));
wall[newnumwalls].point2 += deststartwall-startwall;
if (wall[newnumwalls].nextwall >= 0)
{
wall[newnumwalls].nextwall += deststartwall-startwall;
wall[newnumwalls].nextsector += destsector-soursector;
}
newnumwalls++;
}
//for(j=deststartwall;j<newnumwalls;j++)
//{
// if (wall[j].nextwall >= 0)
// checksectorpointer(wall[j].nextwall,wall[j].nextsector);
// checksectorpointer((short)j,destsector);
//}
if (newnumwalls > deststartwall)
{
//duplicate sectors
Bmemcpy(&sector[destsector],&sector[soursector],sizeof(sectortype));
sector[destsector].wallptr = deststartwall;
sector[destsector].wallnum = newnumwalls-deststartwall;
if (copystat == 1)
{
//duplicate sprites
j = headspritesect[soursector];
while (j >= 0)
{
k = nextspritesect[j];
m = insertsprite(destsector,sprite[j].statnum);
Bmemcpy(&sprite[m],&sprite[j],sizeof(spritetype));
sprite[m].sectnum = destsector; //Don't let memcpy overwrite sector!
j = k;
}
}
}
}
void showsectordata(short sectnum)
{
char snotbuf[80];
Bsprintf(snotbuf,"Sector %d",sectnum);
printext16(8,ydim-STATUS2DSIZ+32,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Firstwall: %d",sector[sectnum].wallptr);
printext16(8,ydim-STATUS2DSIZ+48,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Numberofwalls: %d",sector[sectnum].wallnum);
printext16(8,ydim-STATUS2DSIZ+56,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Firstsprite: %d",headspritesect[sectnum]);
printext16(8,ydim-STATUS2DSIZ+64,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Tags: %d, %d",sector[sectnum].hitag,sector[sectnum].lotag);
printext16(8,ydim-STATUS2DSIZ+72,11,-1,snotbuf,0);
Bsprintf(snotbuf," (0x%x), (0x%x)",sector[sectnum].hitag,sector[sectnum].lotag);
printext16(8,ydim-STATUS2DSIZ+80,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Extra: %d",sector[sectnum].extra);
printext16(8,ydim-STATUS2DSIZ+88,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Visibility: %d",sector[sectnum].visibility);
printext16(8,ydim-STATUS2DSIZ+96,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Pixel height: %ld",(sector[sectnum].floorz-sector[sectnum].ceilingz)>>8);
printext16(8,ydim-STATUS2DSIZ+104,11,-1,snotbuf,0);
printext16(200,ydim-STATUS2DSIZ+32,11,-1,"CEILINGS:",0);
Bsprintf(snotbuf,"Flags (hex): %x",sector[sectnum].ceilingstat);
printext16(200,ydim-STATUS2DSIZ+48,11,-1,snotbuf,0);
Bsprintf(snotbuf,"(X,Y)pan: %d, %d",sector[sectnum].ceilingxpanning,sector[sectnum].ceilingypanning);
printext16(200,ydim-STATUS2DSIZ+56,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Shade byte: %d",sector[sectnum].ceilingshade);
printext16(200,ydim-STATUS2DSIZ+64,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Z-coordinate: %ld",sector[sectnum].ceilingz);
printext16(200,ydim-STATUS2DSIZ+72,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Tile number: %d",sector[sectnum].ceilingpicnum);
printext16(200,ydim-STATUS2DSIZ+80,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Ceiling heinum: %d",sector[sectnum].ceilingheinum);
printext16(200,ydim-STATUS2DSIZ+88,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Palookup number: %d",sector[sectnum].ceilingpal);
printext16(200,ydim-STATUS2DSIZ+96,11,-1,snotbuf,0);
printext16(400,ydim-STATUS2DSIZ+32,11,-1,"FLOORS:",0);
Bsprintf(snotbuf,"Flags (hex): %x",sector[sectnum].floorstat);
printext16(400,ydim-STATUS2DSIZ+48,11,-1,snotbuf,0);
Bsprintf(snotbuf,"(X,Y)pan: %d, %d",sector[sectnum].floorxpanning,sector[sectnum].floorypanning);
printext16(400,ydim-STATUS2DSIZ+56,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Shade byte: %d",sector[sectnum].floorshade);
printext16(400,ydim-STATUS2DSIZ+64,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Z-coordinate: %ld",sector[sectnum].floorz);
printext16(400,ydim-STATUS2DSIZ+72,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Tile number: %d",sector[sectnum].floorpicnum);
printext16(400,ydim-STATUS2DSIZ+80,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Floor heinum: %d",sector[sectnum].floorheinum);
printext16(400,ydim-STATUS2DSIZ+88,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Palookup number: %d",sector[sectnum].floorpal);
printext16(400,ydim-STATUS2DSIZ+96,11,-1,snotbuf,0);
}
void showwalldata(short wallnum)
{
long dax, day, dist;
char snotbuf[80];
Bsprintf(snotbuf,"Wall %d",wallnum);
printext16(8,ydim-STATUS2DSIZ+32,11,-1,snotbuf,0);
Bsprintf(snotbuf,"X-coordinate: %ld",wall[wallnum].x);
printext16(8,ydim-STATUS2DSIZ+48,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Y-coordinate: %ld",wall[wallnum].y);
printext16(8,ydim-STATUS2DSIZ+56,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Point2: %d",wall[wallnum].point2);
printext16(8,ydim-STATUS2DSIZ+64,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Sector: %ld",sectorofwall(wallnum));
printext16(8,ydim-STATUS2DSIZ+72,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Tags: %d, %d",wall[wallnum].hitag,wall[wallnum].lotag);
printext16(8,ydim-STATUS2DSIZ+88,11,-1,snotbuf,0);
Bsprintf(snotbuf," (0x%x), (0x%x)",wall[wallnum].hitag,wall[wallnum].lotag);
printext16(8,ydim-STATUS2DSIZ+96,11,-1,snotbuf,0);
printext16(200,ydim-STATUS2DSIZ+32,11,-1,names[wall[wallnum].picnum],0);
Bsprintf(snotbuf,"Flags (hex): %x",wall[wallnum].cstat);
printext16(200,ydim-STATUS2DSIZ+48,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Shade: %d",wall[wallnum].shade);
printext16(200,ydim-STATUS2DSIZ+56,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Pal: %d",wall[wallnum].pal);
printext16(200,ydim-STATUS2DSIZ+64,11,-1,snotbuf,0);
Bsprintf(snotbuf,"(X,Y)repeat: %d, %d",wall[wallnum].xrepeat,wall[wallnum].yrepeat);
printext16(200,ydim-STATUS2DSIZ+72,11,-1,snotbuf,0);
Bsprintf(snotbuf,"(X,Y)pan: %d, %d",wall[wallnum].xpanning,wall[wallnum].ypanning);
printext16(200,ydim-STATUS2DSIZ+80,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Tile number: %d",wall[wallnum].picnum);
printext16(200,ydim-STATUS2DSIZ+88,11,-1,snotbuf,0);
Bsprintf(snotbuf,"OverTile number: %d",wall[wallnum].overpicnum);
printext16(200,ydim-STATUS2DSIZ+96,11,-1,snotbuf,0);
Bsprintf(snotbuf,"nextsector: %d",wall[wallnum].nextsector);
printext16(400,ydim-STATUS2DSIZ+48,11,-1,snotbuf,0);
Bsprintf(snotbuf,"nextwall: %d",wall[wallnum].nextwall);
printext16(400,ydim-STATUS2DSIZ+56,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Extra: %d",wall[wallnum].extra);
printext16(400,ydim-STATUS2DSIZ+72,11,-1,snotbuf,0);
dax = wall[wallnum].x-wall[wall[wallnum].point2].x;
day = wall[wallnum].y-wall[wall[wallnum].point2].y;
dist = ksqrt(dax*dax+day*day);
// TX 20050102 I'm not sure what unit dist<<4 is supposed to be, but dist itself is correct in terms of game coordinates as one would expect
Bsprintf(snotbuf,"Wall length: %ld",dist);
printext16(400,ydim-STATUS2DSIZ+96,11,-1,snotbuf,0);
dax = (long)sectorofwall(wallnum);
Bsprintf(snotbuf,"Pixel height: %ld",(sector[dax].floorz-sector[dax].ceilingz)>>8);
printext16(400,ydim-STATUS2DSIZ+104,11,-1,snotbuf,0);
}
void showspritedata(short spritenum)
{
char snotbuf[80];
Bsprintf(snotbuf,"Sprite %d",spritenum);
printext16(8,ydim-STATUS2DSIZ+32,11,-1,snotbuf,0);
Bsprintf(snotbuf,"X-coordinate: %ld",sprite[spritenum].x);
printext16(8,ydim-STATUS2DSIZ+48,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Y-coordinate: %ld",sprite[spritenum].y);
printext16(8,ydim-STATUS2DSIZ+56,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Z-coordinate: %ld",sprite[spritenum].z);
printext16(8,ydim-STATUS2DSIZ+64,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Sectnum: %d",sprite[spritenum].sectnum);
printext16(8,ydim-STATUS2DSIZ+72,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Statnum: %d",sprite[spritenum].statnum);
printext16(8,ydim-STATUS2DSIZ+80,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Tags: %d, %d",sprite[spritenum].hitag,sprite[spritenum].lotag);
printext16(8,ydim-STATUS2DSIZ+96,11,-1,snotbuf,0);
Bsprintf(snotbuf," (0x%x), (0x%x)",sprite[spritenum].hitag,sprite[spritenum].lotag);
printext16(8,ydim-STATUS2DSIZ+104,11,-1,snotbuf,0);
printext16(200,ydim-STATUS2DSIZ+32,11,-1,names[sprite[spritenum].picnum],0);
Bsprintf(snotbuf,"Flags (hex): %x",sprite[spritenum].cstat);
printext16(200,ydim-STATUS2DSIZ+48,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Shade: %d",sprite[spritenum].shade);
printext16(200,ydim-STATUS2DSIZ+56,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Pal: %d",sprite[spritenum].pal);
printext16(200,ydim-STATUS2DSIZ+64,11,-1,snotbuf,0);
Bsprintf(snotbuf,"(X,Y)repeat: %d, %d",sprite[spritenum].xrepeat,sprite[spritenum].yrepeat);
printext16(200,ydim-STATUS2DSIZ+72,11,-1,snotbuf,0);
Bsprintf(snotbuf,"(X,Y)offset: %d, %d",sprite[spritenum].xoffset,sprite[spritenum].yoffset);
printext16(200,ydim-STATUS2DSIZ+80,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Tile number: %d",sprite[spritenum].picnum);
printext16(200,ydim-STATUS2DSIZ+88,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Angle (2048 degrees): %d",sprite[spritenum].ang);
printext16(400,ydim-STATUS2DSIZ+48,11,-1,snotbuf,0);
Bsprintf(snotbuf,"X-Velocity: %d",sprite[spritenum].xvel);
printext16(400,ydim-STATUS2DSIZ+56,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Y-Velocity: %d",sprite[spritenum].yvel);
printext16(400,ydim-STATUS2DSIZ+64,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Z-Velocity: %d",sprite[spritenum].zvel);
printext16(400,ydim-STATUS2DSIZ+72,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Owner: %d",sprite[spritenum].owner);
printext16(400,ydim-STATUS2DSIZ+80,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Clipdist: %d",sprite[spritenum].clipdist);
printext16(400,ydim-STATUS2DSIZ+88,11,-1,snotbuf,0);
Bsprintf(snotbuf,"Extra: %d",sprite[spritenum].extra);
printext16(400,ydim-STATUS2DSIZ+96,11,-1,snotbuf,0);
}
void keytimerstuff(void)
{
static long ltotalclock=0;
int i;
if (totalclock == ltotalclock) return;
ltotalclock=totalclock;
if (keystatus[buildkeys[5]] == 0)
{
if (keystatus[buildkeys[2]] > 0) angvel = max(angvel-16,-128);
if (keystatus[buildkeys[3]] > 0) angvel = min(angvel+16,127);
}
else
{
if (keystatus[buildkeys[2]] > 0) svel = min(svel+16,255); // svel and vel aren't even chars...
if (keystatus[buildkeys[3]] > 0) svel = max(svel-16,-256);
}
if (keystatus[buildkeys[0]] > 0) vel = min(vel+16,255);
if (keystatus[buildkeys[1]] > 0) vel = max(vel-16,-256);
/* if (keystatus[buildkeys[12]] > 0) svel = min(svel+8,127);
if (keystatus[buildkeys[13]] > 0) svel = max(svel-8,-128); */
if (angvel < 0) angvel = min(angvel+12,0);
if (angvel > 0) angvel = max(angvel-12,0);
if (svel < 0) svel = min(svel+6,0);
if (svel > 0) svel = max(svel-6,0);
if (vel < 0) vel = min(vel+6,0);
if (vel > 0) vel = max(vel-6,0);
/* if(mlook)
posz -= (horiz-101)*(vel/40); */
}
void _printmessage16(char name[82])
{
char snotbuf[60];
long i;
i = 0;
while ((name[i] != 0) && (i < 54))
{
snotbuf[i] = name[i];
i++;
}
while (i < 54)
{
snotbuf[i] = 32;
i++;
}
snotbuf[54] = 0;
begindrawing();
printext16(200L, ydim-STATUS2DSIZ+8L, 9, 0, snotbuf, 0);
enddrawing();
}
void printmessage16(char name[82])
{
_printmessage16(name);
lastpm16time = totalclock;
}
void printmessage256(char name[82])
{
char snotbuf[40];
long i;
i = 0;
while ((name[i] != 0) && (i < 38))
{
snotbuf[i] = name[i];
i++;
}
while (i < 38)
{
snotbuf[i] = 32;
i++;
}
snotbuf[38] = 0;
printext256(2L,2L,0,-1,snotbuf,0);
printext256(0L,0L,whitecol,-1,snotbuf,0);
}
//Find closest point (*dax, *day) on wall (dawall) to (x, y)
void getclosestpointonwall(long x, long y, long dawall, long *nx, long *ny)
{
walltype *wal;
long i, j, dx, dy;
wal = &wall[dawall];
dx = wall[wal->point2].x-wal->x;
dy = wall[wal->point2].y-wal->y;
i = dx*(x-wal->x) + dy*(y-wal->y);
if (i <= 0) { *nx = wal->x; *ny = wal->y; return; }
j = dx*dx+dy*dy;
if (i >= j) { *nx = wal->x+dx; *ny = wal->y+dy; return; }
i = divscale30(i,j);
*nx = wal->x + mulscale30(dx,i);
*ny = wal->y + mulscale30(dy,i);
}
void initcrc(void)
{
long i, j, k, a;
for (j=0;j<256;j++) //Calculate CRC table
{
k = (j<<8); a = 0;
for (i=7;i>=0;i--)
{
if (((k^a)&0x8000) > 0)
a = ((a<<1)&65535) ^ 0x1021; //0x1021 = genpoly
else
a = ((a<<1)&65535);
k = ((k<<1)&65535);
}
crctable[j] = (a&65535);
}
}
static char visited[MAXWALLS];
long GetWallZPeg(long nWall)
{
long z=0, nSector, nNextSector;
nSector = sectorofwall((short)nWall);
nNextSector = wall[nWall].nextsector;
if (nNextSector == -1)
{
//1-sided wall
if (wall[nWall].cstat&4) z = sector[nSector].floorz;
else z = sector[nSector].ceilingz;
}
else
{
//2-sided wall
if (wall[nWall].cstat&4)
z = sector[nSector].ceilingz;
else
{
if (sector[nNextSector].ceilingz > sector[nSector].ceilingz)
z = sector[nNextSector].ceilingz; //top step
if (sector[nNextSector].floorz < sector[nSector].floorz)
z = sector[nNextSector].floorz; //bottom step
}
}
return(z);
}
void AlignWalls(long nWall0, long z0, long nWall1, long z1, long nTile)
{
long n;
//do the x alignment
wall[nWall1].cstat &= ~0x0108; //Set to non-flip
wall[nWall1].xpanning = (char)((wall[nWall0].xpanning+(wall[nWall0].xrepeat<<3))%tilesizx[nTile]);
z1 = GetWallZPeg(nWall1);
for (n=(picsiz[nTile]>>4);((1<<n)<tilesizy[nTile]);n++);
wall[nWall1].yrepeat = wall[nWall0].yrepeat;
wall[nWall1].ypanning = (char)(wall[nWall0].ypanning+(((z1-z0)*wall[nWall0].yrepeat)>>(n+3)));
}
void AutoAlignWalls(long nWall0, long ply)
{
long z0, z1, nTile, nWall1, branch, visible, nNextSector, nSector;
nTile = wall[nWall0].picnum;
branch = 0;
if (ply == 0)
{
//clear visited bits
memset(visited,0,sizeof(visited));
visited[nWall0] = 1;
}
z0 = GetWallZPeg(nWall0);
nWall1 = wall[nWall0].point2;
//loop through walls at this vertex in CCW order
while (1)
{
//break if this wall would connect us in a loop
if (visited[nWall1]) break;
visited[nWall1] = 1;
//break if reached back of left wall
if (wall[nWall1].nextwall == nWall0) break;
if (wall[nWall1].picnum == nTile)
{
z1 = GetWallZPeg(nWall1);
visible = 0;
nNextSector = wall[nWall1].nextsector;
if (nNextSector < 0)
visible = 1;
else
{
//ignore two sided walls that have no visible face
nSector = wall[wall[nWall1].nextwall].nextsector;
if (getceilzofslope((short)nSector,wall[nWall1].x,wall[nWall1].y) <
getceilzofslope((short)nNextSector,wall[nWall1].x,wall[nWall1].y))
visible = 1;
if (getflorzofslope((short)nSector,wall[nWall1].x,wall[nWall1].y) >
getflorzofslope((short)nNextSector,wall[nWall1].x,wall[nWall1].y))
visible = 1;
}
if (visible)
{
branch++;
AlignWalls(nWall0,z0,nWall1,z1,nTile);
//if wall was 1-sided, no need to recurse
if (wall[nWall1].nextwall < 0)
{
nWall0 = nWall1;
z0 = GetWallZPeg(nWall0);
nWall1 = wall[nWall0].point2;
branch = 0;
continue;
}
else
AutoAlignWalls(nWall1,ply+1);
}
}
if (wall[nWall1].nextwall < 0) break;
nWall1 = wall[wall[nWall1].nextwall].point2;
}
}
/*
* vim:ts=4:
*/