/* * "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 */ /**@file build.c * @brief master build editor source file * * The main implementation file for the Build Editor. * */ #include #include #include #include #include #include #include "engine.h" #include "platform.h" #include "build.h" #include "pragmas.h" #include "display.h" #include "bstub.h" /* #if !defined (getch) && defined(PLATFORM_UNIX) #define getch getchar #endif */ #define MAXMENUFILES 256 #define updatecrc16(crc,dat) (crc = (((crc<<8)&65535)^crctable[((((unsigned short)crc)>>8)&65535)^dat])) static long crctable[256]; static char kensig[24]; #define KEYFIFOSIZ 64 volatile unsigned char keystatus[256]; /* Which keys on the keyboard are pressed? */ static volatile unsigned char keyfifo[KEYFIFOSIZ], keyfifoplc, keyfifoend; static volatile unsigned char readch, oldreadch, extended, keytemp; long vel; /* Camera Velocity in Forward-Backward direction */ long svel; /* Camera Velocity in Left-Right direction */ long angvel; /* Camera Velocity in Angular Spin */ #define NUMKEYS 19 unsigned char buildkeys[NUMKEYS] = { 0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39, 0x1e,0x2c,0xd1,0xc9,0x33,0x34, 0x9c,0x1c,0xd,0xc,0xf, }; /* Or, in plain english, for those of us who don't speak keyboard: unsigned char buildkeys[NUMKEYS] = { [UP]-released,[DOWN]-released,[LEFT]-released,[RIGHT]-released,[L.SHIFT]-pushed,[R.CTRL]-pushed,[L.CTRL]-pushed,[SPACE]-pushed, [A]-pressed,[Z]-pressed,[PgDn]-released,[PgUp]-released,[,|<]-pressed,[.|>]-pressed, [KPEnter]-pressed,[ENTER]-pressed,[+|=]-pressed,[-|_]-pressed,[TAB]-pressed, }; ------------------- BUILD KEYS: 00 = Up arrow 01 = Down arrow 02 = Left arrow 03 = Right arrow 04 = Left Shift key 05 = Right Ctrl key 06 = Left Ctrl key 07 = Space 08 = A 09 = Z 10 = PageDown 11 = PageUp 12 = < 13 = > 14 = Keypad Enter 15 = Enter 16 = + 17 = - 18 = Tab ------------------- */ long posx; /* The camera's X position (east travel is positive, west travel negative. */ long posy; /* The camera's Y position (north travel is negative, south travel positive. */ long posz; /* The camera's Z position (upwards travel is negative, downwards travel positive. */ long horiz = 100; short ang; /* The angle the camera is facing */ short cursectnum; /* The sector the camera is in currently. */ long hvel; /* The Z velocity of the camera, used for jumping in gravity mode. */ /* -512 is the starting value when you jump in gravity mode. */ static long synctics = 0, lockclock = 0; extern volatile long stereomode; extern char vgacompatible; extern char picsiz[MAXTILES]; extern long startposx, startposy, startposz; extern short startang, startsectnum; extern long frameplace, pageoffset, ydim16; extern long cachesize, artsize; static short oldmousebstatus = 0, brightness = 0; long zlock = 0x7fffffff, zmode = 0, whitecol, kensplayerheight = 32; short defaultspritecstat = 0; static short localartfreq[MAXTILES]; /* This is used to calculate the number of occurences of a tile in the map, used mainly in the 3d tile picker (key V in 3D mode.) */ static short localartlookup[MAXTILES], localartlookupnum; char tempbuf[4096]; char names[MAXTILES][17]; /* Reserve 17 characters to name each tile. (Names come from names.h.) */ short asksave = 0; /* Will be 1 if there are unsaved changes, 0 otherwise. */ extern short editstatus, searchit; extern long searchx, searchy; /* search input */ extern short searchsector, searchwall, searchstat; /* search output */ extern short pointhighlight, linehighlight, highlightcnt; /* Initial Status of Editor */ short grid = 3; /* Initial Grid Size is 3. */ short gridlock = 1; /* Grid Locking is On. */ short showtags = 1; /* Sector/Sprite/Wall labels is On. */ long zoom = 768; /* Initial Zoom factor is 768. */ long gettilezoom = 1; int numsprites; short highlight[MAXWALLS]; short highlightsector[MAXSECTORS], highlightsectorcnt = -1; /*extern char textfont[128][8];*/ static char pskysearch[MAXSECTORS]; short temppicnum, tempcstat, templotag, temphitag, tempextra; char tempshade, temppal, tempvis, tempxrepeat, tempyrepeat; char somethingintab = 255; static char boardfilename[13], oboardfilename[13]; static long repeatcountx, repeatcounty; #define BUILD_MAXPATH 255 static char menuname[MAXMENUFILES][BUILD_MAXPATH+1], curpath[80], menupath[80]; static long menunamecnt, menuhighlight; static long fillist[640]; 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, }; /**@brief Build Movement and Accelleration routine * * This code handles the default turning, walking, and strafing actions. * This function acts on buildkeys[] 0, 1, 2, 3, 5, 12, and 13. */ void keytimerstuff(void) { /* Turn and strafe with the left and right arrow keys. */ if (keystatus[buildkeys[5]] == 0) /* Is [R.Ctrl] down? */ { /* No, it isn't, we want to turn. */ if (keystatus[buildkeys[2]] > 0) angvel = max(angvel-16,-128); if (keystatus[buildkeys[3]] > 0) angvel = min(angvel+16,127); } else { /* Yes, it is, we want to strafe. */ if (keystatus[buildkeys[2]] > 0) svel = min(svel+8,127); if (keystatus[buildkeys[3]] > 0) svel = max(svel-8,-128); } /* Move Forward */ if (keystatus[buildkeys[0]] > 0) vel = min(vel+8,127); /* Move Backward */ if (keystatus[buildkeys[1]] > 0) vel = max(vel-8,-128); /* Use the [<] and [>] keys to strafe, too. */ if (keystatus[buildkeys[12]] > 0) svel = min(svel+8,127); if (keystatus[buildkeys[13]] > 0) svel = max(svel-8,-128); /* Accelleration Limiter for Movement */ if (angvel < 0) angvel = min(angvel+12,0); if (angvel > 0) angvel = max(angvel-12,0); if (svel < 0) svel = min(svel+2,0); if (svel > 0) svel = max(svel-2,0); if (vel < 0) vel = min(vel+2,0); if (vel > 0) vel = max(vel-2,0); } void __interrupt __far timerhandler(void) { totalclock++; keytimerstuff(); #ifdef PLATFORM_DOS outp(0x20,0x20); #endif } void __interrupt __far keyhandler(void) { /* * ryan sez: End Of Interrupt call on DOS. This seems like a * dangerous place to put it, if you ask me, but oh well. --ryan. */ #ifdef PLATFORM_DOS koutp(0x20,0x20); #endif oldreadch = readch; readch = _readlastkeyhit(); #if 0 printf("keyhandler() got a (0x%X) ... \n", readch); #endif /* * ryan sez: these inp/outp calls read the keyboard state, * reset the keyboard, and put the original state back in. * This is apparently needed on some XTs, but not newer boxes, and * obviously never on Linux. --ryan. */ #ifdef PLATFORM_DOS keytemp = kinp(0x61); koutp(0x61,keytemp|128); koutp(0x61,keytemp&127); #else keytemp = readch; #endif if ((readch|1) == 0xe1) { extended = 128; return; } if (oldreadch != readch) { if ((readch&128) == 0) { keytemp = readch+extended; if (keystatus[keytemp] == 0) { keystatus[keytemp] = 1; keyfifo[keyfifoend] = keytemp; keyfifo[(keyfifoend+1)&(KEYFIFOSIZ-1)] = 1; keyfifoend = ((keyfifoend+2)&(KEYFIFOSIZ-1)); } } else { keytemp = (readch&127)+extended; keystatus[keytemp] = 0; keyfifo[keyfifoend] = keytemp; keyfifo[(keyfifoend+1)&(KEYFIFOSIZ-1)] = 0; keyfifoend = ((keyfifoend+2)&(KEYFIFOSIZ-1)); } } extended = 0; } static void _initkeys(void) { long i; keyfifoplc = 0; keyfifoend = 0; for(i=0;i<256;i++) keystatus[i] = 0; initkeys(); /* rcg06082001 platform driver-specific initialization. */ } #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); \ } \ /**@brief Load Tile Names from names.h * * This function will load the names of special tiles into names[], * provided the file names.h is in the current directory. * @return -1 on failure, 0 on success. */ int 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 != '\r') && (ch != '\n')); for(i=0;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); } } void initmenupaths(char *filename) { long i; strcpy(curpath,filename); i = 0; while ((i < 80) && (curpath[i] != 0)) i++; while ((i > 0) && (curpath[i] != 92)) i--; curpath[i] = 0; strcpy(menupath,curpath); } /**@brief Draw the mouse in 3D mode. * * This function will draw the white 3D mode cursor at * the location [searchx, searchy]. * (The mouse routine should set these automatically.) */ void showmouse(void) { long 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 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); } /**@brief Show the tile picker. * * This function will show the tile picker and let the user change a tile. * @param tilenum The current tile (what to return if the user cancels.) * @return The new user-selected tile. * @remark Notes: * Make sure you set searchstat for the right situation if you call this function yourself: * 0: Wall tile * 1 or 2: Ceiling or Floor tile. * 3: Sprite * 4: Wall Above tile (overpic) -- * */ long gettile(long tilenum) { char snotbuf[80]; long i, j, k, otilenum, topleft, gap, temp, templong; long xtiles; /* Number of tiles that will fit horizontally on the screen. */ long ytiles; /* Number of tiles that will fit vertically on the screen. */ long tottiles; /* Total tiles that fit on the screen at once. */ /* Calculate how the tiles fit, given the tile previews are 32 pixels wide and tall. */ xtiles = (xdim>>6); ytiles = (ydim>>6); tottiles = xtiles*ytiles; otilenum = tilenum; /* Back up the old value, in case the user cancels. */ keystatus[0x2f] = 0; /* Clear [V] */ /* Recalculate the tile occurance stats for the "choose commonly used tile" screen. */ for(i=0;i>1); do { for(i=0;i= 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-(tottiles<<(gettilezoom<<1))) topleft = MAXTILES-(tottiles<<(gettilezoom<<1)); while ((keystatus[0x1c]|keystatus[1]) == 0) { drawtilescreen(topleft,tilenum); if ((vidoption != 2) && ((vidoption != 1) || (vgacompatible == 1))) limitrate(); nextpage(); synctics = totalclock-lockclock; lockclock += synctics; if ((keystatus[0x37] > 0) && (gettilezoom < 2)) { gettilezoom++; topleft = ((tilenum/(xtiles< MAXTILES-(tottiles<<(gettilezoom<<1))) topleft = MAXTILES-(tottiles<<(gettilezoom<<1)); keystatus[0x37] = 0; } if ((keystatus[0xb5] > 0) && (gettilezoom > 0)) { gettilezoom--; topleft = ((tilenum/(xtiles< 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< 0) && (tilenum < MAXTILES-(xtiles< 0) && (tilenum >= (xtiles< 0) && (tilenum < MAXTILES-(xtiles<= 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 0) /* G (goto) */ { if (tilenum < localartlookupnum) /* Automatically press 'V' */ tilenum = localartlookup[tilenum]; else tilenum = 0; localartlookupnum = MAXTILES; for(i=0;i 0) { keystatus[((k+9)%10)+2] = 0; i = (j*10)+k; if (i < MAXTILES) j = i; } if (keystatus[0xe] > 0) { keystatus[0xe] = 0; j /= 10; } if (keystatus[0x1c] > 0) { keystatus[0x1c] = 0; tilenum = j; break; } } } while (tilenum < topleft) topleft -= (xtiles<= topleft+(tottiles<<(gettilezoom<<1))) topleft += (xtiles< 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); } 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); } static char visited[8192]; 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+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; } } #if (defined PLATFORM_DOS) #define statusbar_printext16 printext16 #define statusbar_printext16_noupdate printext16 #else void statusbar_printext16(long xpos, long ypos, short col, short backcol, char name[82], char fontsize) { printext256(xpos, ypos + 336, col, backcol, name, fontsize); } void statusbar_printext16_noupdate(long xpos, long ypos, short col, short backcol, char name[82], char fontsize) { printext256_noupdate(xpos, ypos + 336, col, backcol, name, fontsize); } #endif 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; statusbar_printext16(200L, 8L, 0, 6, snotbuf, 0); } 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(0L,0L,whitecol,0,snotbuf,0); } short getnumber16(char namestart[80], short num, long maxnumber) { char buffer[80]; long j, k, n, danum, oldnum; danum = (long) num; oldnum = danum; while ((keystatus[0x1c] != 2) && (keystatus[0x1] == 0)) { sprintf(buffer, "%s%ld_ ", namestart, danum); printmessage16(buffer); _idle(); /* rcg06232002 prevent hang while waiting for input. */ for(j=2;j<=11;j++) if (keystatus[j] > 0) { keystatus[j] = 0; k = j-1; if (k == 10) k = 0; n = (danum*10)+k; if (n < maxnumber) danum = n; } if (keystatus[0xe] > 0) /* backspace */ { danum /= 10; keystatus[0xe] = 0; } if (keystatus[0x1c] == 1) { oldnum = danum; keystatus[0x1c] = 2; asksave = 1; } } keystatus[0x1c] = 0; keystatus[0x1] = 0; return((short)oldnum); } short getnumber256(char namestart[80], short num, long maxnumber) { char buffer[80]; long j, k, n, danum, oldnum; danum = (long)num; oldnum = danum; while ((keystatus[0x1c] != 2) && (keystatus[0x1] == 0)) { drawrooms(posx,posy,posz,ang,horiz,cursectnum); ExtAnalyzeSprites(); drawmasks(); sprintf(buffer,"%s%ld_ ",namestart,danum); printmessage256(buffer); nextpage(); for(j=2;j<=11;j++) if (keystatus[j] > 0) { keystatus[j] = 0; k = j-1; if (k == 10) k = 0; n = (danum*10)+k; if (n < maxnumber) danum = n; } if (keystatus[0xe] > 0) /* backspace */ { danum /= 10; keystatus[0xe] = 0; } if (keystatus[0x1c] == 1) { oldnum = danum; keystatus[0x1c] = 2; asksave = 1; } } keystatus[0x1c] = 0; keystatus[0x1] = 0; lockclock = totalclock; /* Reset timing */ return((short)oldnum); } void updatenumsprites(void) { long i; numsprites = 0; for(i=0;i 0)) if ((fileinfo.name[0] != '.') || (fileinfo.name[1] != 0)) { strcpy(menuname[menunamecnt],fileinfo.name); menuname[menunamecnt][BUILD_MAXPATH] = type; menunamecnt++; } } while (_dos_findnext(&fileinfo) == 0); #elif (defined PLATFORM_UNIX) DIR *dir; struct dirent *dent; struct stat statbuf; int add_this; char *ptr = NULL; int len = 0; int subdirs = 0; if (strcmp(kind,"SUBD") == 0) subdirs = 1; dir = opendir("."); if (dir == NULL) return(-1); do { add_this = 0; dent = readdir(dir); if (dent != NULL) { if (stat(dent->d_name, &statbuf) == 0) { if (subdirs) { if (S_ISDIR(statbuf.st_mode)) add_this = 1; } /* if */ else { /* need to expand support if this assertion ever fails. */ assert(stricmp(kind, "*.MAP") == 0); len = strlen(dent->d_name); if (len >= 5) { ptr = ((char *) dent->d_name) + len; ptr += strlen(ptr) - 4; if (stricmp(ptr, ".MAP") == 0) add_this = 1; } /* if */ } /* else */ if (add_this) { strcpy(menuname[menunamecnt],dent->d_name); menuname[menunamecnt][BUILD_MAXPATH] = subdirs; menunamecnt++; } /* if */ } /* if */ } /* if */ } while (dent != NULL); closedir(dir); #endif return(0); } void sortfilenames(void) { char sortbuffer[BUILD_MAXPATH+1]; long i, j, k; for(i=1;i>3,0L,640L*336L); #else fillscreen16(0,0L,640L*336L); #endif if (menuhighlight < 0) menuhighlight = 0; if (menuhighlight >= menunamecnt) menuhighlight = menunamecnt-1; newhighlight = menuhighlight; do { if (menunamecnt <= 36) { topplc = 0; } else { topplc = newhighlight-11; if (topplc < 0) topplc = 0; if (topplc > menunamecnt-37) topplc = menunamecnt-37; } for(i=0;i= 0) && (i-topplc <= 36)) { if (menuname[i][BUILD_MAXPATH] == 1) { #ifdef PLATFORM_DOS printext16(0L,((i-topplc)<<3)+16L+((399360-pageoffset)/640),4,0,buffer,0); #else printext16(0L,((i-topplc)<<3)+16L,4,0,buffer,0); #endif } else { #ifdef PLATFORM_DOS printext16(0L,((i-topplc)<<3)+16L+((399360-pageoffset)/640),7,0,buffer,0); #else printext16(0L,((i-topplc)<<3)+16L,7,0,buffer,0); #endif } } } keystatus[0xcb] = 0; keystatus[0xcd] = 0; keystatus[0xc8] = 0; keystatus[0xd0] = 0; keystatus[0x1c] = 0; keystatus[1] = 0; ch = 0; /* Interesting fakery of ch = getch() */ while (ch == 0) { _idle(); if (keystatus[0xcb] > 0) ch = 75; if (keystatus[0xcd] > 0) ch = 77; if (keystatus[0xc8] > 0) ch = 72; if (keystatus[0xd0] > 0) ch = 80; if (keystatus[0x1c] > 0) ch = 13; if (keystatus[1] > 0) ch = 27; } if ((ch == 75) || (ch == 72)) { newhighlight--; if (newhighlight < 0) newhighlight = menunamecnt-1; } if ((ch == 77) || (ch == 80)) { newhighlight++; if (newhighlight >= menunamecnt) newhighlight = 0; } if ((ch == 13) && (menuname[newhighlight][BUILD_MAXPATH] == 1)) { if ((menuname[newhighlight][0] == '.') && (menuname[newhighlight][1] == '.')) { i = 0; while ((i < 80) && (menupath[i] != 0)) i++; while ((i > 0) && (menupath[i] != 92)) i--; menupath[i] = 0; } else { #if ((defined PLATFORM_DOS) || (defined PLATFORM_WIN32)) strcat(menupath,"\\"); #elif PLATFORM_UNIX strcat(menupath,"/"); #else #error Define your platform! #endif strcat(menupath,menuname[newhighlight]); } chdir(menuname[newhighlight]); menunamecnt = 0; getfilenames("SUBD"); getfilenames("*.MAP"); sortfilenames(); newhighlight = 0; ch = 0; #ifdef PLATFORM_DOS fillscreen16((399360-pageoffset)>>3,0L,640L*336L); #else fillscreen16(0, 0L,640L*336L); #endif } } while ((ch != 13) && (ch != 27)); if (ch == 13) { menuhighlight = newhighlight; return(newhighlight); } return(-1); } int 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 = 640; 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)+200; y2 = (((wall[wall[z].point2].y-posy)*zoom)>>14)+200; 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+(numframes%3);sy<=maxy;sy+=3) { y = posy+(((sy-200)<<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)+320; if (dax >= lborder) fillist[fillcnt++] = dax; } } if (fillcnt > 0) { for(z=1;z rborder) break; if (fillist[z+1] > rborder) fillist[z+1] = rborder; drawline16(fillist[z],sy,fillist[z+1],sy,fillcolor); } } } return(0); } int 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); } short whitelinescan(short dalinehighlight) { long i, j, k; short sucksect, newnumwalls; sucksect = sectorofwall(dalinehighlight); memcpy(§or[numsectors],§or[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= 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= 0) { wall[newnumwalls].nextwall += deststartwall-startwall; wall[newnumwalls].nextsector += destsector-soursector; } newnumwalls++; } #if 0 for(j=deststartwall;j= 0) checksectorpointer(wall[j].nextwall,wall[j].nextsector); checksectorpointer((short)j,destsector); } #endif if (newnumwalls > deststartwall) { /* duplicate sectors */ memcpy(§or[destsector],§or[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); memcpy(&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]; sprintf(snotbuf,"Sector %d",sectnum); statusbar_printext16(8,32,11,-1,snotbuf,0); sprintf(snotbuf,"Firstwall: %d",sector[sectnum].wallptr); statusbar_printext16(8,48,11,-1,snotbuf,0); sprintf(snotbuf,"Numberofwalls: %d",sector[sectnum].wallnum); statusbar_printext16(8,56,11,-1,snotbuf,0); sprintf(snotbuf,"Firstsprite: %d",headspritesect[sectnum]); statusbar_printext16(8,64,11,-1,snotbuf,0); sprintf(snotbuf,"Tags: %d, %d",sector[sectnum].hitag,sector[sectnum].lotag); statusbar_printext16(8,72,11,-1,snotbuf,0); sprintf(snotbuf," (0x%x), (0x%x)",sector[sectnum].hitag,sector[sectnum].lotag); statusbar_printext16(8,80,11,-1,snotbuf,0); sprintf(snotbuf,"Extra: %d",sector[sectnum].extra); statusbar_printext16(8,88,11,-1,snotbuf,0); sprintf(snotbuf,"Visibility: %d",sector[sectnum].visibility); statusbar_printext16(8,96,11,-1,snotbuf,0); sprintf(snotbuf,"Pixel height: %ld",(sector[sectnum].floorz-sector[sectnum].ceilingz)>>8); statusbar_printext16(8,104,11,-1,snotbuf,0); statusbar_printext16(200,32,11,-1,"CEILINGS:",0); sprintf(snotbuf,"Flags (hex): %x",sector[sectnum].ceilingstat); statusbar_printext16(200,48,11,-1,snotbuf,0); sprintf(snotbuf,"(X,Y)pan: %d, %d",sector[sectnum].ceilingxpanning,sector[sectnum].ceilingypanning); statusbar_printext16(200,56,11,-1,snotbuf,0); sprintf(snotbuf,"Shade byte: %d",sector[sectnum].ceilingshade); statusbar_printext16(200,64,11,-1,snotbuf,0); sprintf(snotbuf,"Z-coordinate: %ld",sector[sectnum].ceilingz); statusbar_printext16(200,72,11,-1,snotbuf,0); sprintf(snotbuf,"Tile number: %d",sector[sectnum].ceilingpicnum); statusbar_printext16(200,80,11,-1,snotbuf,0); sprintf(snotbuf,"Ceiling heinum: %d",sector[sectnum].ceilingheinum); statusbar_printext16(200,88,11,-1,snotbuf,0); sprintf(snotbuf,"Palookup number: %d",sector[sectnum].ceilingpal); statusbar_printext16(200,96,11,-1,snotbuf,0); statusbar_printext16(400,32,11,-1,"FLOORS:",0); sprintf(snotbuf,"Flags (hex): %x",sector[sectnum].floorstat); statusbar_printext16(400,48,11,-1,snotbuf,0); sprintf(snotbuf,"(X,Y)pan: %d, %d",sector[sectnum].floorxpanning,sector[sectnum].floorypanning); statusbar_printext16(400,56,11,-1,snotbuf,0); sprintf(snotbuf,"Shade byte: %d",sector[sectnum].floorshade); statusbar_printext16(400,64,11,-1,snotbuf,0); sprintf(snotbuf,"Z-coordinate: %ld",sector[sectnum].floorz); statusbar_printext16(400,72,11,-1,snotbuf,0); sprintf(snotbuf,"Tile number: %d",sector[sectnum].floorpicnum); statusbar_printext16(400,80,11,-1,snotbuf,0); sprintf(snotbuf,"Floor heinum: %d",sector[sectnum].floorheinum); statusbar_printext16(400,88,11,-1,snotbuf,0); sprintf(snotbuf,"Palookup number: %d",sector[sectnum].floorpal); statusbar_printext16(400,96,11,-1,snotbuf,0); } void showwalldata(short wallnum) { long dax, day, dist; char snotbuf[80]; sprintf(snotbuf,"Wall %d",wallnum); statusbar_printext16(8,32,11,-1,snotbuf,0); sprintf(snotbuf,"X-coordinate: %ld",wall[wallnum].x); statusbar_printext16(8,48,11,-1,snotbuf,0); sprintf(snotbuf,"Y-coordinate: %ld",wall[wallnum].y); statusbar_printext16(8,56,11,-1,snotbuf,0); sprintf(snotbuf,"Point2: %d",wall[wallnum].point2); statusbar_printext16(8,64,11,-1,snotbuf,0); sprintf(snotbuf,"Sector: %d",sectorofwall(wallnum)); statusbar_printext16(8,72,11,-1,snotbuf,0); sprintf(snotbuf,"Tags: %d, %d",wall[wallnum].hitag,wall[wallnum].lotag); statusbar_printext16(8,88,11,-1,snotbuf,0); sprintf(snotbuf," (0x%x), (0x%x)",wall[wallnum].hitag,wall[wallnum].lotag); statusbar_printext16(8,96,11,-1,snotbuf,0); statusbar_printext16(200,32,11,-1,names[wall[wallnum].picnum],0); sprintf(snotbuf,"Flags (hex): %x",wall[wallnum].cstat); statusbar_printext16(200,48,11,-1,snotbuf,0); sprintf(snotbuf,"Shade: %d",wall[wallnum].shade); statusbar_printext16(200,56,11,-1,snotbuf,0); sprintf(snotbuf,"Pal: %d",wall[wallnum].pal); statusbar_printext16(200,64,11,-1,snotbuf,0); sprintf(snotbuf,"(X,Y)repeat: %d, %d",wall[wallnum].xrepeat,wall[wallnum].yrepeat); statusbar_printext16(200,72,11,-1,snotbuf,0); sprintf(snotbuf,"(X,Y)pan: %d, %d",wall[wallnum].xpanning,wall[wallnum].ypanning); statusbar_printext16(200,80,11,-1,snotbuf,0); sprintf(snotbuf,"Tile number: %d",wall[wallnum].picnum); statusbar_printext16(200,88,11,-1,snotbuf,0); sprintf(snotbuf,"OverTile number: %d",wall[wallnum].overpicnum); statusbar_printext16(200,96,11,-1,snotbuf,0); sprintf(snotbuf,"nextsector: %d",wall[wallnum].nextsector); statusbar_printext16(400,48,11,-1,snotbuf,0); sprintf(snotbuf,"nextwall: %d",wall[wallnum].nextwall); statusbar_printext16(400,56,11,-1,snotbuf,0); sprintf(snotbuf,"Extra: %d",wall[wallnum].extra); statusbar_printext16(400,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); sprintf(snotbuf,"Wall length: %ld",dist>>4); statusbar_printext16(400,96,11,-1,snotbuf,0); dax = (long)sectorofwall(wallnum); sprintf(snotbuf,"Pixel height: %ld",(sector[dax].floorz-sector[dax].ceilingz)>>8); statusbar_printext16(400,104,11,-1,snotbuf,0); } void showspritedata(short spritenum) { char snotbuf[80]; sprintf(snotbuf,"Sprite %d",spritenum); statusbar_printext16(8,32,11,-1,snotbuf,0); sprintf(snotbuf,"X-coordinate: %ld",sprite[spritenum].x); statusbar_printext16(8,48,11,-1,snotbuf,0); sprintf(snotbuf,"Y-coordinate: %ld",sprite[spritenum].y); statusbar_printext16(8,56,11,-1,snotbuf,0); sprintf(snotbuf,"Z-coordinate: %ld",sprite[spritenum].z); statusbar_printext16(8,64,11,-1,snotbuf,0); sprintf(snotbuf,"Sectnum: %d",sprite[spritenum].sectnum); statusbar_printext16(8,72,11,-1,snotbuf,0); sprintf(snotbuf,"Statnum: %d",sprite[spritenum].statnum); statusbar_printext16(8,80,11,-1,snotbuf,0); sprintf(snotbuf,"Tags: %d, %d",sprite[spritenum].hitag,sprite[spritenum].lotag); statusbar_printext16(8,96,11,-1,snotbuf,0); sprintf(snotbuf," (0x%x), (0x%x)",sprite[spritenum].hitag,sprite[spritenum].lotag); statusbar_printext16(8,104,11,-1,snotbuf,0); statusbar_printext16(200,32,11,-1,names[sprite[spritenum].picnum],0); sprintf(snotbuf,"Flags (hex): %x",sprite[spritenum].cstat); statusbar_printext16(200,48,11,-1,snotbuf,0); sprintf(snotbuf,"Shade: %d",sprite[spritenum].shade); statusbar_printext16(200,56,11,-1,snotbuf,0); sprintf(snotbuf,"Pal: %d",sprite[spritenum].pal); statusbar_printext16(200,64,11,-1,snotbuf,0); sprintf(snotbuf,"(X,Y)repeat: %d, %d",sprite[spritenum].xrepeat,sprite[spritenum].yrepeat); statusbar_printext16(200,72,11,-1,snotbuf,0); sprintf(snotbuf,"(X,Y)offset: %d, %d",sprite[spritenum].xoffset,sprite[spritenum].yoffset); statusbar_printext16(200,80,11,-1,snotbuf,0); sprintf(snotbuf,"Tile number: %d",sprite[spritenum].picnum); statusbar_printext16(200,88,11,-1,snotbuf,0); sprintf(snotbuf,"Angle (2048 degrees): %d",sprite[spritenum].ang); statusbar_printext16(400,48,11,-1,snotbuf,0); sprintf(snotbuf,"X-Velocity: %d",sprite[spritenum].xvel); statusbar_printext16(400,56,11,-1,snotbuf,0); sprintf(snotbuf,"Y-Velocity: %d",sprite[spritenum].yvel); statusbar_printext16(400,64,11,-1,snotbuf,0); sprintf(snotbuf,"Z-Velocity: %d",sprite[spritenum].zvel); statusbar_printext16(400,72,11,-1,snotbuf,0); sprintf(snotbuf,"Owner: %d",sprite[spritenum].owner); statusbar_printext16(400,80,11,-1,snotbuf,0); sprintf(snotbuf,"Clipdist: %d",sprite[spritenum].clipdist); statusbar_printext16(400,88,11,-1,snotbuf,0); sprintf(snotbuf,"Extra: %d",sprite[spritenum].extra); statusbar_printext16(400,96,11,-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); } int drawtilescreen(long pictopleft, long picbox) { long i, j, vidpos, vidpos2, 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; 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)) && (ydime <= (64>>gettilezoom))) { for(i=0;i 64 */ { if (xdime > ydime) scaledown = ((xdime+(63>>gettilezoom))>>(6-gettilezoom)); else scaledown = ((ydime+(63>>gettilezoom))>>(6-gettilezoom)); for(i=0;i>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]; sprintf(snotbuf,"%ld",i); printext256(0L,ydim-8,whitecol,-1,snotbuf,0); printext256(xdim-(strlen(names[i])<<3),ydim-8,whitecol,-1,names[i],0); return(0); } void getpoint(long searchxe, long searchye, long *x, long *y) { if (posx <= -131072) posx = -131072; if (posx >= 131072) posx = 131072; if (posy <= -131072) posy = -131072; if (posy >= 131072) posy = 131072; *x = posx + divscale14(searchxe-320,zoom); *y = posy + divscale14(searchye-200,zoom); if (*x <= -131072) *x = -131072; if (*x >= 131072) *x = 131072; if (*y <= -131072) *y = -131072; if (*y >= 131072) *y = 131072; } long getlinehighlight(long xplc, long yplc) { long i, dst, dist, closest, x1, y1, x2, y2, nx, ny; if (numwalls == 0) return(-1); dist = 0x7fffffff; closest = numwalls-1; for(i=0;i= 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; } return(closest); } long getpointhighlight(long xplc, long yplc) { long i, dst, dist, closest; if (numwalls == 0) return(-1); dist = 0; if (grid > 0) dist = 1024; closest = -1; for(i=0;i 0) && (gridlock > 0)) pointlockdist = (128>>grid); dist = pointlockdist; dax = *xplc; day = *yplc; for(i=0;i 0) && (grid > 0)) { dax = ((dax+(1024>>grid))&(0xffffffff<<(11-grid))); day = ((day+(1024>>grid))&(0xffffffff<<(11-grid))); } *xplc = dax; *yplc = day; return(0); } int checkautoinsert(long dax, long day, short danumwalls) { long i, x1, y1, x2, y2; if (danumwalls < 0) danumwalls = numwalls; for(i=0;i>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; } } int movewalls(long start, long offs) { long i; if (offs < 0) /* Delete */ { for(i=start;i 0) /* Insert */ { for(i=numwalls+offs-1;i>=start+offs;i--) memcpy(&wall[i],&wall[i-offs],sizeof(walltype)); } numwalls += offs; for(i=0;i= start) wall[i].nextwall += offs; if (wall[i].point2 >= start) wall[i].point2 += offs; } return(0); } 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= 0) { k = wall[j].nextwall; sucksect = sectorofwall((short)k); sector[sucksect].wallnum++; for(i=sucksect+1;i= 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); } short 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= 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= getceilzofslope(j,dax,day)) if (sprite[i].z-daz <= getflorzofslope(j,dax,day)) { changespritesect((short)i,(short)j); break; } } } } void clearmidstatbar16(void) { long opageoffset; opageoffset = pageoffset; /* clear bottom part of status bar */ pageoffset = 0; ydim16 = 144; fillscreen16((640L*25L)>>3,8L,640L*(143L-(25<<1))); drawline16(0,0,0,143,7); drawline16(639,0,639,143,7); pageoffset = opageoffset; ydim16 = 336; } 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=0;i--) { startwall = sector[highlightsector[i]].wallptr; endwall = startwall + sector[highlightsector[i]].wallnum; for(j=startwall;j= 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; oldmousebstatus = 0; keystatus[buildkeys[14]] = 0; while ((keystatus[buildkeys[14]]>>1) == 0) { _idle(); oldmousebstatus = bstatus; getmousevalues(&mousx,&mousy,&bstatus); searchx += (mousx>>1); searchy += (mousy>>1); if (searchx < 8) searchx = 8; if (searchx > 631) searchx = 631; if (searchy < 8) searchy = 8; if (searchy > 341) searchy = 341; 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); } 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 = 336; 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 (((320+x2) >= 2) && ((320+x2) <= 637)) if (((200+y2) >= 2) && ((200+y2) <= ydim16-3)) { x1 = mulscale11(sintable[(startang+2560)&2047],zoom) / 768; y1 = mulscale11(sintable[(startang+2048)&2047],zoom) / 768; drawline16((320+x2)+x1,(200+y2)+y1,(320+x2)-x1,(200+y2)-y1,6); drawline16((320+x2)+x1,(200+y2)+y1,(320+x2)+y1,(200+y2)-x1,6); drawline16((320+x2)+x1,(200+y2)+y1,(320+x2)-y1,(200+y2)+x1,6); } draw2dscreen(posx,posy,ang,zoom,grid); if ((showtags == 1) && (zoom >= 768)) { for(i=0;i startwall) { dax /= (endwall-startwall+1); day /= (endwall-startwall+1); } dax = mulscale14(dax-posx,zoom); day = mulscale14(day-posy,zoom); x1 = 320+dax-(strlen(dabuffer)<<1); y1 = 200+day-4; x2 = x1 + (strlen(dabuffer)<<2)+2; y2 = y1 + 7; if ((x1 >= 0) && (x2 < 640) && (y1 >= 0) && (y2 < ydim16)) { #ifdef PLATFORM_DOS printext16(x1,y1+(pageoffset/640),0,7,dabuffer,1); #else printext16(x1,y1,0,7,dabuffer,1); #endif } /* if */ } } x3 = divscale14(-320,zoom)+posx; y3 = divscale14(-196,zoom)+posy; x4 = divscale14(320,zoom)+posx; y4 = divscale14(ydim16-196,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 = 320+dax-(strlen(dabuffer)<<1); y1 = 200+day-4; x2 = x1 + (strlen(dabuffer)<<2)+2; y2 = y1 + 7; if ((x1 >= 0) && (x2 < 640) && (y1 >= 0) && (y2 < ydim16)) { #ifdef PLATFORM_DOS printext16(x1,y1+(pageoffset/640),0,4,dabuffer,1); #else printext16(x1,y1,0,4,dabuffer,1); #endif } /* if */ } } } 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 = 320+dax-(strlen(dabuffer)<<1); y1 = 200+day-4; x2 = x1 + (strlen(dabuffer)<<2)+2; y2 = y1 + 7; if ((x1 >= 0) && (x2 < 640) && (y1 >= 0) && (y2 < ydim16)) { if ((sprite[i].cstat&1) == 0) col = 3; else col = 5; { #ifdef PLATFORM_DOS printext16(x1,y1+(pageoffset/640),0,col,dabuffer,1); #else printext16(x1,y1,0,col,dabuffer,1); #endif } /* if */ } } j--; } i++; } } printcoords16(posx,posy,ang); numwalls = templong; if (highlightsectorcnt > 0) for(i=0;i= 0) drawline16(320+x2,200+y2,320+x2,200+y2,15); else drawline16(320+x2,200+y2,320+x2,200+y2,5); if (keystatus[88] > 0) /* F12 */ { keystatus[88] = 0; i = pageoffset; pageoffset = 92160; j = ydim16; ydim16 = 480; outpw(0x3d4,0x000c); outpw(0x3d4,0x000d); clear2dscreen(); draw2dgrid(posx,posy,ang,zoom,grid); draw2dscreen(posx,posy,ang,zoom,grid); screencapture("captxxxx.pcx",keystatus[0x2a]|keystatus[0x36]); pageoffset = i; ydim16 = j; } 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 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= 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 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= 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 0) /* F6 */ { keystatus[0x40] = 0; if (pointhighlight >= 16384) { i = pointhighlight-16384; opageoffset = pageoffset; pageoffset = 0; ydim16 = 144; ExtShowSpriteData((short)i); pageoffset = opageoffset; ydim16 = 336; } else if (linehighlight >= 0) { i = linehighlight; opageoffset = pageoffset; pageoffset = 0; ydim16 = 144; ExtShowWallData((short)i); pageoffset = opageoffset; ydim16 = 336; } } if (keystatus[0x41] > 0) /* F7 */ { keystatus[0x41] = 0; for (i=0;i 0) /* F8 */ { keystatus[0x42] = 0; if (pointhighlight >= 16384) { i = pointhighlight-16384; opageoffset = pageoffset; pageoffset = 0; ydim16 = 144; ExtEditSpriteData((short)i); pageoffset = opageoffset; ydim16 = 336; } else if (linehighlight >= 0) { i = linehighlight; opageoffset = pageoffset; pageoffset = 0; ydim16 = 144; ExtEditWallData((short)i); pageoffset = opageoffset; ydim16 = 336; } } 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; sprintf(buffer,"Sprite (%ld) Lo-tag: ",i); sprite[i].lotag = getnumber16(buffer,sprite[i].lotag,65536L); clearmidstatbar16(); showspritedata((short)i); } else if (linehighlight >= 0) { i = linehighlight; sprintf(buffer,"Wall (%ld) Lo-tag: ",i); wall[i].lotag = getnumber16(buffer,wall[i].lotag,65536L); clearmidstatbar16(); showwalldata((short)i); } printmessage16(""); } else { for (i=0;i 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; sprintf(buffer,"Sprite (%ld) Hi-tag: ",i); sprite[i].hitag = getnumber16(buffer,sprite[i].hitag,65536L); clearmidstatbar16(); showspritedata((short)i); } else if (linehighlight >= 0) { i = linehighlight; sprintf(buffer,"Wall (%ld) Hi-tag: ",i); wall[i].hitag = getnumber16(buffer,wall[i].hitag,65536L); clearmidstatbar16(); showwalldata((short)i); } } else { for (i=0;i 0) /* P (palookup #) */ { keystatus[0x19] = 0; for (i=0;i 0) /* E (status list) */ { if (pointhighlight >= 16384) { i = pointhighlight-16384; sprintf(buffer,"Sprite (%ld) Status list: ",i); changespritestat(i,getnumber16(buffer,sprite[i].statnum,65536L)); clearmidstatbar16(); showspritedata((short)i); } printmessage16(""); keystatus[0x12] = 0; } if (keystatus[0x0f] > 0) /* TAB */ { clearmidstatbar16(); if ((keystatus[0x38]|keystatus[0xb8]) > 0) /* ALT */ { if (pointhighlight >= 16384) showspritedata((short)pointhighlight-16384); else if (linehighlight >= 0) showwalldata((short)linehighlight); } else { for (i=0;i 0) /* Right shift (point highlighting) */ { if (highlightcnt == 0) { highlightx2 = searchx, highlighty2 = searchy; ydim16 = 336; 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>3] |= (1<<(j&7)); } i = wall[i].point2; } while (i != linehighlight); } } else { for(i=0;i= 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= 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 = 336; drawline16(highlightx2,highlighty1,highlightx1,highlighty1,10); drawline16(highlightx2,highlighty2,highlightx1,highlighty2,10); drawline16(highlightx1,highlighty2,highlightx1,highlighty1,10); drawline16(highlightx2,highlighty2,highlightx2,highlighty1,10); } if (highlightsectorcnt != 0) { for(i=0;i= 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 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= 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; } } } } } } } /* * rcg02192001 added pointhighlight check to stop segfault that * was (miraculously) not exposed before the port to Watcom/win32. * Not sure of total ramifications of this patch; if left mouse * button behaviour in the overhead editor suddenly goes screwey, * this is why. */ if (((bstatus&1) < (oldmousebstatus&1)) && (highlightsectorcnt < 0) && (pointhighlight >= 0)) /* after dragging */ { j = 1; if (highlightcnt > 0) for (i=0;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 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 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=0;j=nextspritesect[j]) { sprite[j].x += dax; sprite[j].y += day; } } #if 0 for(i=0;i= 0) checksectorpointer(wall[j].nextwall,wall[j].nextsector); checksectorpointer((short)j,highlightsector[i]); } } #endif 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= 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 = 320; searchy = 200; posx = mousxplc; posy = mousyplc; } if ((keystatus[buildkeys[8]] > 0) && (zoom < 16384)) zoom += (zoom>>4); if ((keystatus[buildkeys[9]] > 0) && (zoom > 24)) zoom -= (zoom>>4); 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= 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 { memcpy(&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) { memcpy(§or[numsectors],§or[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= 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 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 0) /* S */ { sucksect = -1; for(i=0;i= 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 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 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 (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(320+dax-2,200+day-2,320+dax+2,200+day+2,14); drawline16(320+dax-2,200+day+2,320+dax+2,200+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 <= -131072) dax = -131072; if (dax >= 131072) dax = 131072; if (day <= -131072) day = -131072; if (day >= 131072) day = 131072; 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(320+dax-2,200+day-2,320+dax+2,200+day-2,14); drawline16(320+dax+2,200+day-2,320+dax+2,200+day+2,14); drawline16(320+dax+2,200+day+2,320+dax-2,200+day+2,14); drawline16(320+dax-2,200+day+2,320+dax-2,200+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((void *) FP_OFF(&wall[newnumwalls]),sizeof(walltype),0L); wall[newnumwalls].extra = -1; wall[newnumwalls].x = mousxplc; wall[newnumwalls].y = mousyplc; wall[newnumwalls].nextsector = -1; wall[newnumwalls].nextwall = -1; for(i=0;i>1); day = ((wall[numwalls].y+mousyplc)>>1); for(i=0;i= 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= 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((void *) FP_OFF(&wall[newnumwalls]),sizeof(walltype),0L); 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+3)) { wall[newnumwalls-1].point2 = numwalls; if (suckwall == -1) /* if no connections to other sectors */ { k = -1; for(i=0;i= suckwall) wall[i].nextwall += j; if (wall[i].point2 >= suckwall) wall[i].point2 += j; } for(i=newnumwalls-1;i>=suckwall;i--) memcpy(&wall[i+j],&wall[i],sizeof(walltype)); for(i=0;inumwalls;j--) { memcpy(&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) { memcpy(&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 { memcpy(&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= 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= 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;mnumwalls;j--) { memcpy(&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 { memcpy(&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 { memcpy(&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= 0) { wall[wall[j].nextwall].nextwall = j; wall[wall[j].nextwall].nextsector = numsectors; } } /* copy sector attributes & fix wall pointers */ memcpy(§or[numsectors],§or[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= 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=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= 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= 0) for(j=0;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= 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= 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>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."); } } #endif asksave = 1; } keystatus[0xd2] = 0; } ExtCheckKeys(); j = 0; for(i=22-1;i>=0;i--) updatecrc16(j,kensig[i]); if ((j&0xffff) != 0xebf) { setvmode(0x3); printf("Don't screw with my name.\n"); exit(0); } statusbar_printext16_noupdate(9L,9L,4,-1,kensig,0); statusbar_printext16(8L,8L,12,-1,kensig,0); nextpage(); 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."); } if (keystatus[1] > 0) { keystatus[1] = 0; printmessage16("(N)ew, (L)oad, (S)ave, save (A)s, (Q)uit"); bad = 1; while (bad == 1) { _idle(); if (keystatus[1] > 0) { keystatus[1] = 0; bad = 0; printmessage16(""); } if (keystatus[0x31] > 0) /* N */ { bad = 0; keystatus[0x31] = 0; printmessage16("Are you sure you want to start a new board?"); while ((keystatus[1]|keystatus[0x1c]|keystatus[0x39]|keystatus[0x31]) == 0) { _idle(); if (keystatus[0x15] != 0) { /* !!! this should probably prompt to save changes to the current map. --ryan. */ keystatus[0x15] = 0; 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 0) /* L */ { bad = 0; keystatus[0x26] = 0; i = menuselect(); if (i < 0) { if (i == -2) printmessage16("No .MAP files found."); } else { strcpy(boardfilename,menuname[menuhighlight]); if (highlightsectorcnt >= 0) { j = 0; k = 0; for(i=0;i MAXSECTORS) || (numwalls+j > MAXWALLS) || (numsprites+k > MAXSPRITES)) { highlightsectorcnt = -1; } else { /* Put sectors&walls to end of lists */ j = MAXWALLS; for(i=0;i=0;i--) if (sprite[i].statnum < MAXSTATUS) { k = sprite[i].sectnum; for(j=0;j= 0) { if ((numsectors+highlightsectorcnt > MAXSECTORS) || (sector[MAXSECTORS-highlightsectorcnt].wallptr < numwalls)) { highlightsectorcnt = -1; } else { /* Re-attach sectors&walls */ for(i=0;i= 0) checksectorpointer(wall[j].nextwall,wall[j].nextsector); checksectorpointer((short)j,highlightsector[i]); } } } } printmessage16("Map loaded successfully."); asksave = 0; /* rcg09032000 my add. */ } updatenumsprites(); startposx = posx; /* this is same */ startposy = posy; startposz = posz; startang = ang; startsectnum = cursectnum; } chdir(curpath); keystatus[0x1c] = 0; } if (keystatus[0x1e] > 0) /* A */ { bad = 0; keystatus[0x1e] = 0; strcpy(oboardfilename,boardfilename); i = 0; while ((boardfilename[i] != 0) && (i < 13)) i++; if (boardfilename[i-4] == '.') i -= 4; boardfilename[i] = 0; while (bad == 0) { _idle(); sprintf(buffer,"Save as: %s",boardfilename); printmessage16(buffer); if (keystatus[1] > 0) bad = 1; if (keystatus[0x1c] > 0) bad = 2; if (i > 0) { if (keystatus[0xe] > 0) { keystatus[0xe] = 0; i--; boardfilename[i] = 0; } } if (i < 8) { if ((keystatus[0x2a]|keystatus[0x36]) > 0) { for(j=0;j<128;j++) if (scantoascwithshift[j] > 0) if (keystatus[j] > 0) { keystatus[j] = 0; boardfilename[i++] = scantoascwithshift[j]; boardfilename[i] = 0; } } else { for(j=0;j<128;j++) if (scantoasc[j] > 0) if (keystatus[j] > 0) { keystatus[j] = 0; boardfilename[i++] = scantoasc[j]; boardfilename[i] = 0; } } } } if (bad == 1) { strcpy(boardfilename,oboardfilename); keystatus[1] = 0; printmessage16("Operation cancelled"); } if (bad == 2) { keystatus[0x1c] = 0; boardfilename[i] = '.'; boardfilename[i+1] = 'm'; boardfilename[i+2] = 'a'; boardfilename[i+3] = 'p'; boardfilename[i+4] = 0; sprintf(buffer,"Saving to %s...",boardfilename); printmessage16(buffer); fixspritesectors(); /* Do this before saving! */ updatesector(startposx,startposy,&startsectnum); saveboard(boardfilename,&startposx,&startposy,&startposz,&startang,&startsectnum); ExtSaveMap(boardfilename); printmessage16("Board saved."); asksave = 0; /* rcg09032000 my add. */ } bad = 0; } if (keystatus[0x1f] > 0) /* S */ { bad = 0; keystatus[0x1f] = 0; printmessage16("Saving board..."); fixspritesectors(); /* Do this before saving! */ updatesector(startposx,startposy,&startsectnum); saveboard(boardfilename,&startposx,&startposy,&startposz,&startang,&startsectnum); ExtSaveMap(boardfilename); printmessage16("Board saved."); asksave = 0; /* rcg09032000 my add. */ } if (keystatus[0x10] > 0) /* Q */ { bad = 0; keystatus[0x10] = 0; printmessage16("Are you sure you want to quit?"); while ((keystatus[1]|keystatus[0x1c]|keystatus[0x39]|keystatus[0x31]) == 0) { _idle(); if (keystatus[0x15] != 0) { keystatus[0x15] = 0; /* QUIT! */ if (asksave) /* rcg09032000 my add. */ { printmessage16("Save changes?"); while ((keystatus[1]|keystatus[0x1c]|keystatus[0x39]|keystatus[0x31]) == 0) { _idle(); if (keystatus[0x15] > 0) { keystatus[0x15] = 0; fixspritesectors(); /* Do this before saving! */ updatesector(startposx,startposy,&startsectnum); saveboard(boardfilename,&startposx,&startposy,&startposz,&startang,&startsectnum); ExtSaveMap(boardfilename); asksave = 0; /* rcg09032000 my add. */ break; } } } /* if */ uninittimer(); uninitkeys(); ExtUnInit(); uninitengine(); setvmode(0x3); printf("Memory status: %ld(%ld) bytes\n", cachesize, artsize); printf("%s\n", kensig); printf("%s\n", PORTSIG); exit(0); } } printmessage16(""); } } } } for(i=0;i= 0) checksectorpointer(wall[j].nextwall,wall[j].nextsector); checksectorpointer((short)j,highlightsector[i]); } } fixspritesectors(); if (setgamemode(vidoption,xdim,ydim) < 0) { ExtUnInit(); uninitkeys(); uninittimer(); printf("%ld * %ld not supported in this graphics mode\n",xdim,ydim); exit(0); } posz = oposz; searchx = scale(searchx,xdim,640); searchy = scale(searchy,ydim,480); } void editinput(void) { char smooshyalign, repeatpanalign, buffer[80]; short startwall, endwall, dasector, daang; short mousx, mousy, mousz, bstatus; long i, j, k, templong=0, doubvel, changedir; 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((char) brightness, (unsigned char *) palette); } if (keystatus[88] > 0) /* F12 */ { screencapture("captxxxx.pcx",keystatus[0x2a]|keystatus[0x36]); keystatus[88] = 0; } mousz = 0; getmousevalues(&mousx,&mousy,&bstatus); searchx += (mousx>>1); searchy += (mousy>>1); if (searchx < 4) searchx = 4; if (searchy < 4) searchy = 4; if (searchx > xdim-5) searchx = xdim-5; if (searchy > ydim-5) searchy = ydim-5; 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); } 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)<<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)<<2)); else { goalz += (12<<8); if (keystatus[buildkeys[4]] > 0) /* Either shift key */ goalz += (12<<8); } } if (goalz != posz) { if (posz < goalz) hvel += 32; 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)<<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)<<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< goalz) hvel -= (32< 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) > 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 0) { for(i=0;i 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 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 0) { for(i=0;i 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 0) /* PGUP */ { k = 0; if (highlightsectorcnt >= 0) { for(i=0;i 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 0) /* PGDN */ { k = 0; if (highlightsectorcnt >= 0) { for(i=0;i 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 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((long *)(&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 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 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 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) */ { repeatcountx++; if ((repeatcountx == 1) || (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; } } else repeatcountx = 0; if ((keystatus[0x48]|keystatus[0x50]) > 0) /* 2 & 8 (keypad) */ { repeatcounty++; if ((repeatcounty == 1) || (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; } } 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); #if 0 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+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)); #endif 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: strcpy(buffer,"Wall pal: "); wall[searchwall].pal = getnumber256(buffer,wall[searchwall].pal,256L); break; case 1: strcpy(buffer,"Ceiling pal: "); sector[searchsector].ceilingpal = getnumber256(buffer,sector[searchsector].ceilingpal,256L); break; case 2: strcpy(buffer,"Floor pal: "); sector[searchsector].floorpal = getnumber256(buffer,sector[searchsector].floorpal,256L); break; case 3: strcpy(buffer,"Sprite pal: "); sprite[searchwall].pal = getnumber256(buffer,sprite[searchwall].pal,256L); 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) { strcpy(buffer,"Sprite clipdist: "); sprite[searchwall].clipdist = getnumber256(buffer,sprite[searchwall].clipdist,256L); } } } 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 0 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; } #endif 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 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 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 |= (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 */ { overheadeditor(); keystatus[buildkeys[14]] = 0; } } int main(int argc,char **argv) { char ch, quitflag; long i, j, k; _platform_init(argc, argv, "BUILD editor by Ken Silverman", "BUILD"); if (getenv("BUILD_NOPENTIUM") != NULL) setmmxoverlay(0); editstatus = 1; if (argc >= 2) { strcpy(boardfilename,argv[1]); if (strchr(boardfilename,'.') == 0) strcat(boardfilename,".map"); } else strcpy(boardfilename,"newboard.map"); ExtInit(); _initkeys(); inittimer(); loadpics("tiles000.art"); loadnames(); strcpy(kensig,"BUILD by Ken Silverman"); initcrc(); if (setgamemode(vidoption,xdim,ydim) < 0) { ExtUnInit(); uninitkeys(); uninittimer(); printf("%ld * %ld not supported in this graphics mode\n",xdim,ydim); exit(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; } } initmenupaths(argv[0]); menunamecnt = 0; menuhighlight = 0; for(i=0;i 0) { keystatus[1] = 0; printext256(0,0,whitecol,0,"Really want to quit?",0); nextpage(); synctics = totalclock-lockclock; lockclock += synctics; while ((keystatus[1]|keystatus[0x1c]|keystatus[0x39]|keystatus[0x31]) == 0) { /* * rcg08212000 Rewrote this to prompt for changes in * graphics mode, rather than through stdio later. */ _idle(); if (keystatus[0x15] != 0) { keystatus[0x15] = 0; quitflag = 1; if (asksave) { asksave = 0; printext256(0,0,whitecol,0,"Save changes? ",0); nextpage(); while ((keystatus[0x15]|keystatus[0x31]) == 0) _idle(); if (keystatus[0x15]) /* 'y' pressed. */ { updatesector(startposx,startposy,&startsectnum); saveboard(boardfilename,&startposx,&startposy,&startposz,&startang,&startsectnum); ExtSaveMap(boardfilename); } /* if */ } /* if */ break; } /* if */ } } } uninittimer(); uninitkeys(); ExtUnInit(); uninitengine(); setvmode(0x3); if (asksave) { printf("Save changes?\n"); do { ch = getchar(); } while ((ch != 'y') && (ch != 'Y') && (ch != 'n') && (ch != 'N')); if ((ch == 'y') || (ch == 'Y')) { updatesector(startposx,startposy,&startsectnum); saveboard(boardfilename,&startposx,&startposy,&startposz,&startang,&startsectnum); ExtSaveMap(boardfilename); } } printf("Memory status: %ld(%ld) bytes\n",cachesize,artsize); printf("%s\n",kensig); printf("%s\n",PORTSIG); return(0); } /* end of build.c ... */