// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman // Ken Silverman's official web site: "http://www.advsys.net/ken" // See the included license file "BUILDLIC.TXT" for license info. // // This file has been modified from Ken Silverman's original release // by Jonathon Fowler (jf@jonof.id.au) #include "compat.h" #include "pragmas.h" #define MAXWADS 4096 #define MAXPOINTS 8192 #define MAXLINES 8192 #define MAXSIDES 8192 #define MAXSECTS 2048 #define MAXTHINGS 4096 #define MAXTEXTS 1024 #define MAXPNAMES 1024 #define MAXTHINGTYPES 3072 #define MAXSECTORS 1024 #define MAXWALLS 8192 #define MAXSPRITES 4096 static unsigned short sqrtable[4096], shlookup[4096+256]; static char iwadata[MAXWADS][9]; static int inumwads, iwadstart, iwadplc[MAXWADS], iwadlen[MAXWADS]; static char pwadata[MAXWADS][9]; static int pnumwads, pwadstart, pwadplc[MAXWADS], pwadlen[MAXWADS]; static short px[MAXPOINTS], py[MAXPOINTS]; typedef struct { short p1, p2, flags, special, tag; short side1, side2; //If side2 = -1, no left } linedeftype; static linedeftype line[MAXLINES]; typedef struct { short xoffset, yoffset; char uppertexture[8], lowertexture[8], middletexture[8]; short sect; } sidedeftype; static sidedeftype side[MAXSIDES]; static short sidetoppic[MAXSIDES], sidebotpic[MAXSIDES], sidemidpic[MAXSIDES]; typedef struct { short floorz, ceilingz; char floorpic[8], ceilingpic[8]; short shade, type, tag; } secttype; static secttype sect[MAXSECTS]; static short sectspri[MAXSECTS][8]; typedef struct { short x, y, ang, type, options; } thingtype; static thingtype thing[MAXTHINGS]; static char textname[MAXTEXTS][9]; static int textoffs[MAXTEXTS]; static short textpname[MAXTEXTS]; static char pname[MAXPNAMES][9]; //Build map-linking variables static short picindex[MAXPOINTS], linindex[MAXPOINTS]; static short wx[MAXPOINTS], wy[MAXPOINTS], wx2[MAXPOINTS], wy2[MAXPOINTS]; static short point2[MAXPOINTS], slist[MAXPOINTS], sectorofwall[MAXPOINTS]; typedef struct { short wallptr, wallnum; int ceilingz, floorz; short ceilingstat, floorstat; short ceilingpicnum, ceilingheinum; signed char ceilingshade; char ceilingpal, ceilingxpanning, ceilingypanning; short floorpicnum, floorheinum; signed char floorshade; char floorpal, floorxpanning, floorypanning; char visibility, filler; short lotag, hitag, extra; } sectortype; typedef struct { int x, y; short point2, nextwall, nextsector, cstat; short picnum, overpicnum; signed char shade; char pal, xrepeat, yrepeat, xpanning, ypanning; short lotag, hitag, extra; } walltype; typedef struct { int x, y, z; short cstat, picnum; signed char shade; char pal, clipdist, filler; unsigned char xrepeat, yrepeat; signed char xoffset, yoffset; short sectnum, statnum; short ang, owner, xvel, yvel, zvel; short lotag, hitag, extra; } spritetype; static sectortype sector[MAXSECTORS]; static walltype wall[MAXWALLS]; static spritetype sprite[MAXSPRITES]; static char tempbuf[16384]; static short tempshort[4096]; //SCRIPT parsing variables: static char scriptname[16]; static char filebuf[16384]; static int filhandle, filpos, fileng; static char definemode = 0, define[16384], *defineptr[4096]; static int defineval[16384], definecnt = 0, numdefines = 0; static char thingtypemode = 0; static int thingnum[1024], thingnum2[1024], thingoff[1024], numthings = 0; static short thingfield[4096]; static char thingop[4096]; static int thingval[4096], thingopnum = 0; static char texturelookupmode = 0; static short texturelookup[4096]; static char tagtypemode = 0; static int tagnum[1024], tagnum2[1024], tagoff[1024], numtags = 0; static char tagop[4096]; static short tagfield[4096]; static int tagval[4096], tagopnum = 0; static char sectypemode = 0; static int secnum[1024], secnum2[1024], secoff[1024], numsecs = 0; static short secfield[4096]; static char secop[4096]; static int secval[4096], secopnum = 0; #define THINGLISTNUM 123 static short thinglookup[MAXTHINGTYPES]; typedef struct { short num; char name[8]; } thinglisttype; static thinglisttype thinglist[THINGLISTNUM] = {{1,"PLAYA1"},{2,"PLAYA1"},{3,"PLAYA1"},{4,"PLAYA1"},{11,"PLAYA1"},{14,""},{3004,"POSSA1"}, {84,"SSWVA1"},{9,"SPOSA1"},{65,"CPOSA1"},{3001,"TROOA1"},{3002,"SARGA1"},{58,"SARGA1"}, {3006,"SKULA1"},{3005,"HEADA1"},{69,"BOS2A1C1"},{3003,"BOSSA1"},{68,"BSPIA1D1"}, {71,"PAINA1"},{66,"SKELA1D1"},{67,"FATTA1"},{64,"VILEA1D1"},{7,"SPIDA1D1"},{16,"CYBRA1"}, {88,""},{89,""},{87,""},{2005,"CSAWA0"},{2001,"SHOTA0"},{82,"SGN2A0"},{2002,"MGUNA0"}, {2003,"LAUNA0"},{2004,"PLASA0"},{2006,"BFUGA0"},{2007,"CLIPA0"},{2008,"SHELA0"}, {2010,"ROCKA0"},{2047,"CELLA0"},{2048,"AMMOA0"},{2049,"SBOXA0"},{2046,"BROKA0"}, {17,"CELPA0"},{8,"BPAKA0"},{2011,"STIMA0"},{2012,"MEDIA0"},{2014,"BON1A0"}, {2015,"BON2A0"},{2018,"ARM1A0"},{2019,"ARM2A0"},{83,"MEGAA0"},{2013,"SOULA0"}, {2022,"PINVA0"},{2023,"PSTRA0"},{2024,"PINSA0"},{2025,"SUITA0"},{2026,"PMAPA0"}, {2045,"PVISA0"},{5,"BKEYA0"},{40,"BSKUA0"},{13,"RKEYA0"},{38,"RSKUA0"},{6,"YKEYA0"}, {39,"YSKUA0"},{2035,"BAR1A0"},{72,"KEENA0"},{48,"ELECA0"},{30,"COL1A0"},{32,"COL3A0"}, {31,"COL2A0"},{36,"COL5A0"},{33,"COL4A0"},{37,"COL6A0"},{47,"SMITA0"},{43,"TRE1A0"}, {54,"TRE2A0"},{2028,"COLUA0"},{85,"TLMPA0"},{86,"TLP2A0"},{34,"CANDA0"},{35,"CBRAA0"}, {44,"TBLUA0"},{45,"TGRNA0"},{46,"TREDA0"},{55,"SMBTA0"},{56,"SMGTA0"},{57,"SMRTA0"}, {70,"FCANA0"},{41,"CEYEA0"},{42,"FSKUA0"},{49,"GOR1A0"},{63,"GOR1A0"},{50,"GOR2A0"}, {59,"GOR2A0"},{52,"GOR4A0"},{60,"GOR4A0"},{51,"GOR5A0"},{61,"GOR5A0"},{53,"HDB1A0"}, {62,"HDB2A0"},{73,"GOR3A0"},{74,"GOR3A0"},{75,"HDB3A0"},{76,"HDB4A0"},{77,"HDB5A0"}, {78,"HDB6A0"},{25,"POL1A0"},{26,"BBRNA0"},{27,"POL4A0"},{28,"POL2A0"},{29,"POL3A0"}, {10,"PLAYW0"},{12,"PLAYW0"},{24,"POB1A0"},{79,"POB2A0"},{80,"POB2A0"},{81,"BRS1A0"}, {15,"PLAYN0"},{18,"POSSL0"},{19,"SPOSL0"},{20,"TROOM0"},{21,"SARGN0"},{22,"HEADL0"}, {23,""}}; // These three were nicked from Build's engine.c. static inline unsigned int ksqrtasm(unsigned int a) { unsigned short c; if (a & 0xff000000) c = shlookup[(a >> 24) + 4096]; else c = shlookup[a >> 12]; a >>= c&0xff; a = (a&0xffff0000)|(sqrtable[a]); a >>= ((c&0xff00) >> 8); return a; } static inline int msqrtasm(unsigned int c) { unsigned int a,b; a = 0x40000000l; b = 0x20000000l; do { if (c >= a) { c -= a; a += b*4; } a -= b; a >>= 1; b >>= 2; } while (b); if (c >= a) a++; a >>= 1; return a; } static void initksqrt(void) { int i, j, k; j = 1; k = 0; for(i=0;i<4096;i++) { if (i >= j) { j <<= 2; k++; } sqrtable[i] = (unsigned short)(msqrtasm((i<<18)+131072)<<1); shlookup[i] = (k<<1)+((10-k)<<8); if (i < 256) shlookup[i+4096] = ((k+6)<<1)+((10-(k+6))<<8); } } int inside(int x, int y, short sectnum) { walltype *wal; int i, x1, y1, x2, y2; char cnt; cnt = 0; wal = &wall[sector[sectnum].wallptr]; for(i=sector[sectnum].wallnum;i>0;i--) { y1 = wal->y-y; y2 = wall[wal->point2].y-y; if ((y1^y2) < 0) { x1 = wal->x-x; x2 = wall[wal->point2].x-x; if ((x1^x2) < 0) cnt ^= (x1*y2= 0) cnt ^= 1; } wal++; } return(cnt); } int readbyte(void) { if (filpos >= fileng) return(-1); if ((filpos&16383) == 0) Bread(filhandle,filebuf,16384); filpos++; return((int)filebuf[(filpos-1)&16383]); } int readline(void) { int i, ch; do { do { ch = readbyte(); if (ch < 0) return(0); } while ((ch == 13) || (ch == 10)); i = 0; tempbuf[0] = 0; while ((ch != 13) && (ch != 10)) { if (ch < 0) return(0); if (ch == ';') { do { if (ch < 0) return(0); ch = readbyte(); } while ((ch != 13) && (ch != 10)); break; } if ((ch == 32) || (ch == 9)) ch = ','; if ((ch != ',') || (i == 0) || (tempbuf[i-1] != ',')) { tempbuf[i++] = ch; tempbuf[i] = 0; } ch = readbyte(); } if ((i > 0) && (tempbuf[i-1] == ',')) tempbuf[i-1] = 0; } while (i <= 0); return(i); } void parsescript(void) { int i, j, k, l, lasti, breakout, tstart, tend, textnum = 0, frontbackstat; int spritenumstat, slen; char ch; clearbufbyte(§spri[0], sizeof(short) * MAXSECTS * 8, 0xffffffff); if (scriptname[0] == 0) { for(i=0;i<4096;i++) texturelookup[i] = i; return; } if ((filhandle = Bopen(scriptname,BO_BINARY|BO_RDONLY,BS_IREAD)) == -1) { printf("Could not find %s\n",scriptname); exit(0); } filpos = 0; fileng = Bfilelength(filhandle); while (readline() != 0) { i = 0; j = 0; lasti = 0; while (1) { if ((tempbuf[i] == ',') || (tempbuf[i] == 0)) { if (tempbuf[i] == 0) { breakout = 1; } else { breakout = 0, tempbuf[i] = 0; } if (j == 0) { if (tempbuf[lasti] == '[') { definemode = 0; thingtypemode = 0; texturelookupmode = 0; tagtypemode = 0; sectypemode = 0; } if (Bstrcasecmp(&tempbuf[lasti],"#define") == 0) definemode = 1; if (thingtypemode == 1) { thingoff[numthings] = thingopnum; k = lasti; while ((tempbuf[k] != 0) && (tempbuf[k] != '-')) k++; if (tempbuf[k] == '-') { tempbuf[k] = 0; thingnum[numthings] = atol(&tempbuf[lasti]); thingnum2[numthings] = atol(&tempbuf[k+1]); } else { thingnum[numthings] = atol(&tempbuf[lasti]); thingnum2[numthings] = thingnum[numthings]; } numthings++; } else if (Bstrcasecmp(&tempbuf[lasti],"[THINGTYPES]") == 0) thingtypemode = 1; if (texturelookupmode == 1) { textnum = 0; if ((tempbuf[lasti] >= 48) && (tempbuf[lasti] <= 57)) { k = lasti; while ((tempbuf[k] != 0) && (tempbuf[k] != '-')) k++; if (tempbuf[k] == '-') { tempbuf[k] = 0; tstart = atol(&tempbuf[lasti]); tend = atol(&tempbuf[k+1]); for(k=tstart;k<=tend;k++) tempshort[textnum++] = k; } else tempshort[textnum++] = atol(&tempbuf[lasti]); } else { slen = 0; while (tempbuf[lasti+slen] != 0) { ch = tempbuf[lasti+slen]; if ((ch >= 97) && (ch <= 122)) tempbuf[lasti+slen] -= 32; slen++; } if (slen > 0) for(k=inumwads-1;k>=0;k--) if ((iwadata[k][slen] == 0) || (iwadata[k][slen] == 32)) if ((iwadata[k][slen-1] != 0) && (iwadata[k][slen-1] != 32)) { for(l=slen-1;l>=0;l--) if (tempbuf[lasti+l] != '?') { ch = iwadata[k][l]; if ((ch >= 97) && (ch <= 122)) ch -= 32; if (tempbuf[lasti+l] != ch) break; } if (l < 0) tempshort[textnum++] = k; } } } else if (Bstrcasecmp(&tempbuf[lasti],"[TEXTURELOOKUPS]") == 0) texturelookupmode = 1; if (tagtypemode == 1) { tagoff[numtags] = tagopnum; k = lasti; while ((tempbuf[k] != 0) && (tempbuf[k] != '-')) k++; if (tempbuf[k] == '-') { tempbuf[k] = 0; tagnum[numtags] = atol(&tempbuf[lasti]); tagnum2[numtags] = atol(&tempbuf[k+1]); } else { tagnum[numtags] = atol(&tempbuf[lasti]); tagnum2[numtags] = tagnum[numtags]; } numtags++; } else if (Bstrcasecmp(&tempbuf[lasti],"[TAGCONVERSIONS]") == 0) tagtypemode = 1; if (sectypemode == 1) { secoff[numsecs] = secopnum; k = lasti; while ((tempbuf[k] != 0) && (tempbuf[k] != '-')) k++; if (tempbuf[k] == '-') { tempbuf[k] = 0; secnum[numsecs] = atol(&tempbuf[lasti]); secnum2[numsecs] = atol(&tempbuf[k+1]); } else { secnum[numsecs] = atol(&tempbuf[lasti]); secnum2[numsecs] = secnum[numsecs]; } numsecs++; } else if (Bstrcasecmp(&tempbuf[lasti],"[SECTORCONVERSIONS]") == 0) sectypemode = 1; } else if (j > 0) { if (definemode == 1) { defineptr[numdefines] = (char *)(&define[definecnt]); for(k=lasti;k= 48) && (tempbuf[k+1] <= 57)) thingval[thingopnum] = atol(&tempbuf[k+1]); else { for(l=0;l= 48) && (tempbuf[lasti] <= 57)) l = atol(&tempbuf[lasti]); else { for(l=0;l=0;k--) texturelookup[tempshort[k]] = l; } if (tagtypemode == 1) { for(k=lasti;k= 48) && (tempbuf[lasti] <= 57)) //1 DIGIT ONLY! { spritenumstat = tempbuf[lasti]-48; lasti++; } if (Bstrcasecmp(&tempbuf[lasti],"sprite.x") == 0) tagfield[tagopnum] = 0; if (Bstrcasecmp(&tempbuf[lasti],"sprite.y") == 0) tagfield[tagopnum] = 1; if (Bstrcasecmp(&tempbuf[lasti],"sprite.z") == 0) tagfield[tagopnum] = 2; if (Bstrcasecmp(&tempbuf[lasti],"sprite.cstat") == 0) tagfield[tagopnum] = 3; if (Bstrcasecmp(&tempbuf[lasti],"sprite.shade") == 0) tagfield[tagopnum] = 4; if (Bstrcasecmp(&tempbuf[lasti],"sprite.pal") == 0) tagfield[tagopnum] = 5; if (Bstrcasecmp(&tempbuf[lasti],"sprite.clipdist") == 0) tagfield[tagopnum] = 6; if (Bstrcasecmp(&tempbuf[lasti],"sprite.xrepeat") == 0) tagfield[tagopnum] = 7; if (Bstrcasecmp(&tempbuf[lasti],"sprite.yrepeat") == 0) tagfield[tagopnum] = 8; if (Bstrcasecmp(&tempbuf[lasti],"sprite.xoffset") == 0) tagfield[tagopnum] = 9; if (Bstrcasecmp(&tempbuf[lasti],"sprite.yoffset") == 0) tagfield[tagopnum] = 10; if (Bstrcasecmp(&tempbuf[lasti],"sprite.picnum") == 0) tagfield[tagopnum] = 11; if (Bstrcasecmp(&tempbuf[lasti],"sprite.ang") == 0) tagfield[tagopnum] = 12; if (Bstrcasecmp(&tempbuf[lasti],"sprite.xvel") == 0) tagfield[tagopnum] = 13; if (Bstrcasecmp(&tempbuf[lasti],"sprite.yvel") == 0) tagfield[tagopnum] = 14; if (Bstrcasecmp(&tempbuf[lasti],"sprite.zvel") == 0) tagfield[tagopnum] = 15; if (Bstrcasecmp(&tempbuf[lasti],"sprite.owner") == 0) tagfield[tagopnum] = 16; if (Bstrcasecmp(&tempbuf[lasti],"sprite.sectnum") == 0) tagfield[tagopnum] = 17; if (Bstrcasecmp(&tempbuf[lasti],"sprite.statnum") == 0) tagfield[tagopnum] = 18; if (Bstrcasecmp(&tempbuf[lasti],"sprite.lotag") == 0) tagfield[tagopnum] = 19; if (Bstrcasecmp(&tempbuf[lasti],"sprite.hitag") == 0) tagfield[tagopnum] = 20; if (Bstrcasecmp(&tempbuf[lasti],"sprite.extra") == 0) tagfield[tagopnum] = 21; if (Bstrcasecmp(&tempbuf[lasti],"sector.wallptr") == 0) tagfield[tagopnum] = 32; if (Bstrcasecmp(&tempbuf[lasti],"sector.wallnum") == 0) tagfield[tagopnum] = 33; if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingpicnum") == 0) tagfield[tagopnum] = 34; if (Bstrcasecmp(&tempbuf[lasti],"sector.floorpicnum") == 0) tagfield[tagopnum] = 35; if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingheinum") == 0) tagfield[tagopnum] = 36; if (Bstrcasecmp(&tempbuf[lasti],"sector.floorheinum") == 0) tagfield[tagopnum] = 37; if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingz") == 0) tagfield[tagopnum] = 38; if (Bstrcasecmp(&tempbuf[lasti],"sector.floorz") == 0) tagfield[tagopnum] = 39; if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingshade") == 0) tagfield[tagopnum] = 40; if (Bstrcasecmp(&tempbuf[lasti],"sector.floorshade") == 0) tagfield[tagopnum] = 41; if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingxpanning") == 0) tagfield[tagopnum] = 42; if (Bstrcasecmp(&tempbuf[lasti],"sector.floorxpanning") == 0) tagfield[tagopnum] = 43; if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingypanning") == 0) tagfield[tagopnum] = 44; if (Bstrcasecmp(&tempbuf[lasti],"sector.floorypanning") == 0) tagfield[tagopnum] = 45; if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingstat") == 0) tagfield[tagopnum] = 46; if (Bstrcasecmp(&tempbuf[lasti],"sector.floorstat") == 0) tagfield[tagopnum] = 47; if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingpal") == 0) tagfield[tagopnum] = 48; if (Bstrcasecmp(&tempbuf[lasti],"sector.floorpal") == 0) tagfield[tagopnum] = 49; if (Bstrcasecmp(&tempbuf[lasti],"sector.visibility") == 0) tagfield[tagopnum] = 50; if (Bstrcasecmp(&tempbuf[lasti],"sector.lotag") == 0) tagfield[tagopnum] = 51; if (Bstrcasecmp(&tempbuf[lasti],"sector.hitag") == 0) tagfield[tagopnum] = 52; if (Bstrcasecmp(&tempbuf[lasti],"sector.extra") == 0) tagfield[tagopnum] = 53; if (Bstrcasecmp(&tempbuf[lasti],"wall.x") == 0) tagfield[tagopnum] = 64; if (Bstrcasecmp(&tempbuf[lasti],"wall.y") == 0) tagfield[tagopnum] = 65; if (Bstrcasecmp(&tempbuf[lasti],"wall.point2") == 0) tagfield[tagopnum] = 66; if (Bstrcasecmp(&tempbuf[lasti],"wall.nextsector") == 0) tagfield[tagopnum] = 67; if (Bstrcasecmp(&tempbuf[lasti],"wall.nextwall") == 0) tagfield[tagopnum] = 68; if (Bstrcasecmp(&tempbuf[lasti],"wall.picnum") == 0) tagfield[tagopnum] = 69; if (Bstrcasecmp(&tempbuf[lasti],"wall.overpicnum") == 0) tagfield[tagopnum] = 70; if (Bstrcasecmp(&tempbuf[lasti],"wall.shade") == 0) tagfield[tagopnum] = 71; if (Bstrcasecmp(&tempbuf[lasti],"wall.pal") == 0) tagfield[tagopnum] = 72; if (Bstrcasecmp(&tempbuf[lasti],"wall.cstat") == 0) tagfield[tagopnum] = 73; if (Bstrcasecmp(&tempbuf[lasti],"wall.xrepeat") == 0) tagfield[tagopnum] = 74; if (Bstrcasecmp(&tempbuf[lasti],"wall.yrepeat") == 0) tagfield[tagopnum] = 75; if (Bstrcasecmp(&tempbuf[lasti],"wall.xpanning") == 0) tagfield[tagopnum] = 76; if (Bstrcasecmp(&tempbuf[lasti],"wall.ypanning") == 0) tagfield[tagopnum] = 77; if (Bstrcasecmp(&tempbuf[lasti],"wall.lotag") == 0) tagfield[tagopnum] = 78; if (Bstrcasecmp(&tempbuf[lasti],"wall.hitag") == 0) tagfield[tagopnum] = 79; if (Bstrcasecmp(&tempbuf[lasti],"wall.extra") == 0) tagfield[tagopnum] = 80; tagfield[tagopnum] += (frontbackstat<<7) + (spritenumstat<<8); if ((tempbuf[k+1] >= 48) && (tempbuf[k+1] <= 57)) tagval[tagopnum] = atol(&tempbuf[k+1]); else if (Bstrcasecmp("tag",&tempbuf[k+1]) == 0) tagval[tagopnum] = INT32_MIN; else { for(l=0;l= 48) && (tempbuf[lasti] <= 57)) //1 DIGIT ONLY! { spritenumstat = tempbuf[lasti]-48; lasti++; } if (Bstrcasecmp(&tempbuf[lasti],"sprite.x") == 0) secfield[secopnum] = 0; if (Bstrcasecmp(&tempbuf[lasti],"sprite.y") == 0) secfield[secopnum] = 1; if (Bstrcasecmp(&tempbuf[lasti],"sprite.z") == 0) secfield[secopnum] = 2; if (Bstrcasecmp(&tempbuf[lasti],"sprite.cstat") == 0) secfield[secopnum] = 3; if (Bstrcasecmp(&tempbuf[lasti],"sprite.shade") == 0) secfield[secopnum] = 4; if (Bstrcasecmp(&tempbuf[lasti],"sprite.pal") == 0) secfield[secopnum] = 5; if (Bstrcasecmp(&tempbuf[lasti],"sprite.clipdist") == 0) secfield[secopnum] = 6; if (Bstrcasecmp(&tempbuf[lasti],"sprite.xrepeat") == 0) secfield[secopnum] = 7; if (Bstrcasecmp(&tempbuf[lasti],"sprite.yrepeat") == 0) secfield[secopnum] = 8; if (Bstrcasecmp(&tempbuf[lasti],"sprite.xoffset") == 0) secfield[secopnum] = 9; if (Bstrcasecmp(&tempbuf[lasti],"sprite.yoffset") == 0) secfield[secopnum] = 10; if (Bstrcasecmp(&tempbuf[lasti],"sprite.picnum") == 0) secfield[secopnum] = 11; if (Bstrcasecmp(&tempbuf[lasti],"sprite.ang") == 0) secfield[secopnum] = 12; if (Bstrcasecmp(&tempbuf[lasti],"sprite.xvel") == 0) secfield[secopnum] = 13; if (Bstrcasecmp(&tempbuf[lasti],"sprite.yvel") == 0) secfield[secopnum] = 14; if (Bstrcasecmp(&tempbuf[lasti],"sprite.zvel") == 0) secfield[secopnum] = 15; if (Bstrcasecmp(&tempbuf[lasti],"sprite.owner") == 0) secfield[secopnum] = 16; if (Bstrcasecmp(&tempbuf[lasti],"sprite.sectnum") == 0) secfield[secopnum] = 17; if (Bstrcasecmp(&tempbuf[lasti],"sprite.statnum") == 0) secfield[secopnum] = 18; if (Bstrcasecmp(&tempbuf[lasti],"sprite.lotag") == 0) secfield[secopnum] = 19; if (Bstrcasecmp(&tempbuf[lasti],"sprite.hitag") == 0) secfield[secopnum] = 20; if (Bstrcasecmp(&tempbuf[lasti],"sprite.extra") == 0) secfield[secopnum] = 21; if (Bstrcasecmp(&tempbuf[lasti],"sector.wallptr") == 0) secfield[secopnum] = 32; if (Bstrcasecmp(&tempbuf[lasti],"sector.wallnum") == 0) secfield[secopnum] = 33; if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingpicnum") == 0) secfield[secopnum] = 34; if (Bstrcasecmp(&tempbuf[lasti],"sector.floorpicnum") == 0) secfield[secopnum] = 35; if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingheinum") == 0) secfield[secopnum] = 36; if (Bstrcasecmp(&tempbuf[lasti],"sector.floorheinum") == 0) secfield[secopnum] = 37; if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingz") == 0) secfield[secopnum] = 38; if (Bstrcasecmp(&tempbuf[lasti],"sector.floorz") == 0) secfield[secopnum] = 39; if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingshade") == 0) secfield[secopnum] = 40; if (Bstrcasecmp(&tempbuf[lasti],"sector.floorshade") == 0) secfield[secopnum] = 41; if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingxpanning") == 0) secfield[secopnum] = 42; if (Bstrcasecmp(&tempbuf[lasti],"sector.floorxpanning") == 0) secfield[secopnum] = 43; if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingypanning") == 0) secfield[secopnum] = 44; if (Bstrcasecmp(&tempbuf[lasti],"sector.floorypanning") == 0) secfield[secopnum] = 45; if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingstat") == 0) secfield[secopnum] = 46; if (Bstrcasecmp(&tempbuf[lasti],"sector.floorstat") == 0) secfield[secopnum] = 47; if (Bstrcasecmp(&tempbuf[lasti],"sector.ceilingpal") == 0) secfield[secopnum] = 48; if (Bstrcasecmp(&tempbuf[lasti],"sector.floorpal") == 0) secfield[secopnum] = 49; if (Bstrcasecmp(&tempbuf[lasti],"sector.visibility") == 0) secfield[secopnum] = 50; if (Bstrcasecmp(&tempbuf[lasti],"sector.lotag") == 0) secfield[secopnum] = 51; if (Bstrcasecmp(&tempbuf[lasti],"sector.hitag") == 0) secfield[secopnum] = 52; if (Bstrcasecmp(&tempbuf[lasti],"sector.extra") == 0) secfield[secopnum] = 53; secfield[secopnum] += (spritenumstat<<8); if ((tempbuf[k+1] >= 48) && (tempbuf[k+1] <= 57)) secval[secopnum] = atol(&tempbuf[k+1]); else if (Bstrcasecmp("tag",&tempbuf[k+1]) == 0) secval[secopnum] = INT32_MIN; else { for(l=0;l0;j>>=1) if (i+j < inumwads) if (Bstrcasecmp(iwadata[slist[i+j]],nam) <= 0) i += j; if (Bstrcasecmp(iwadata[slist[i]],nam) == 0) return(slist[i]); return(-1); } int main(int argc, char **argv) { char argstring[5][80]; char iwadfil[80], pwadfil[80], doommap[16], buildmap[16], picstr[16]; int w, numtexts, startnumtexts, danumtexts, numpnames; int x, y, z, zz, zzz, zzx, zx, cx, cy, gap, i, j, k, l, offs; int dnumpoints = 0, dnumlines = 0, dnumsides, dnumsectors, dnumthings; int minx, maxx, miny, maxy, numwalls, wadtype; int startnumwalls, l1, l2, startpoint2; int fil, ifil, pfil, x1, y1, x2, y2, startwall, endwall; int mapversion, posx, posy, posz, boardwadindex; short ang, cursectnum; printf("Wad2Map! Copyright 1995 by Ken Silverman\n"); if ((argc < 3) || (argc > 5)) { printf("Command line parameters: Wad2Map (PWADName) IWADName MapName (ScriptName)\n"); printf(" Ex #1: wad2map c:\\doom\\doom.wad e1m1\n"); printf(" Ex #2: wad2map c:\\doom\\doom.wad e1m1 kenbuild.txt\n"); printf(" Ex #3: wad2map c:\\doom\\mypwad.wad c:\\doom\\doom.wad e1m1\n"); printf(" Ex #4: wad2map c:\\doom\\mypwad.wad c:\\doom\\doom.wad e1m1 kenbuild.txt\n"); exit(0); } for(i=1;i>1);gap>0;gap>>=1) for(z=0;z=0;zz-=gap) { if (Bstrcasecmp(iwadata[slist[zz]],iwadata[slist[zz+gap]]) <= 0) break; i = slist[zz]; slist[zz] = slist[zz+gap]; slist[zz+gap] = i; } if (ifil != pfil) { Bread(pfil,&pnumwads,4); Bread(pfil,&pwadstart,4); Blseek(pfil,pwadstart,SEEK_SET); for(z=0;z= 0) { Blseek(ifil,iwadplc[w],BSEEK_SET); startnumtexts = numtexts; Bread(ifil,&danumtexts,4); numtexts += danumtexts; Bread(ifil,&textoffs[startnumtexts],(numtexts-startnumtexts)*sizeof(int)); for(z=startnumtexts;z=boardwadindex;w--) { Blseek(pfil,pwadplc[w],BSEEK_SET); if (Bstrcasecmp(pwadata[w],"VERTEXES") == 0) { dnumpoints = (pwadlen[w]>>2); Bread(pfil,tempbuf,pwadlen[w]); offs = 0; for(z=0;z maxx) maxx = x; if (y < miny) miny = y; if (y > maxy) maxy = y; } cx = (((minx+maxx)>>1)&0xffffffc0); cy = (((miny+maxy)>>1)&0xffffffc0); numwalls = 0; for(z=0;z= 0) && (z == side[line[zz].side2].sect)) { wx[numwalls] = px[line[zz].p2]; wy[numwalls] = py[line[zz].p2]; wx2[numwalls] = px[line[zz].p1]; wy2[numwalls] = py[line[zz].p1]; picindex[numwalls] = line[zz].side2; linindex[numwalls++] = zz; } } startpoint2 = startnumwalls; for(zz=startnumwalls;zz 0)) j = 2; else if ((wx2[zz+1]-x)*(wy2[zzz]-y) > (wy2[zz+1]-y)*(wx2[zzz]-x)) j = 2; if (j == 2) { i = wx[zz+1]; wx[zz+1] = wx[zzz]; wx[zzz] = i; i = wy[zz+1]; wy[zz+1] = wy[zzz]; wy[zzz] = i; i = wx2[zz+1]; wx2[zz+1] = wx2[zzz]; wx2[zzz] = i; i = wy2[zz+1]; wy2[zz+1] = wy2[zzz]; wy2[zzz] = i; i = picindex[zz+1]; picindex[zz+1] = picindex[zzz]; picindex[zzz] = i; i = linindex[zz+1]; linindex[zz+1] = linindex[zzz]; linindex[zzz] = i; } } point2[zz] = zz+1; } if (j == 0) point2[zz] = startpoint2, startpoint2 = zz+1; } sector[z].wallptr = startnumwalls; sector[z].wallnum = numwalls-startnumwalls; } //Collect sectors for(z=0;z>3); if ((sector[z].ceilingstat&1) == 0) sector[z].ceilingshade = j; if ((sector[z].floorstat&1) == 0) sector[z].floorshade = j; for(i=startwall;i>1);gap>0;gap>>=1) for(z=0;z=0;zz-=gap) { if (wx[slist[zz]] <= wx[slist[zz+gap]]) break; i = slist[zz]; slist[zz] = slist[zz+gap]; slist[zz+gap] = i; } for(z=0;z>= 1; if ((zz+zzz < numwalls) && (wx[slist[zz+zzz]] < x2)) zz += zzz; zzz >>= 1; } while (zzz > 0); do { zzx = slist[zz]; if (wx[zzx] > x2) break; if (wy[zzx] == y2) if ((wx[point2[zzx]] == x1) && (wy[point2[zzx]] == y1)) { wall[z].nextwall = zzx; wall[z].nextsector = sectorofwall[zzx]; break; } zz++; } while (zz < numwalls); if (wall[z].nextwall < 0) { wall[z].picnum = sidemidpic[picindex[z]]; wall[z].overpicnum = 0; } else { wall[z].picnum = sidetoppic[picindex[z]]; if (wall[z].picnum <= 0) wall[z].picnum = sidebotpic[picindex[z]]; if ((wall[z].picnum <= 0) && (wall[z].nextwall >= 0)) { zx = picindex[wall[z].nextwall]; wall[z].picnum = sidetoppic[zx]; if (wall[z].picnum <= 0) wall[z].picnum = sidebotpic[zx]; } wall[z].overpicnum = sidemidpic[picindex[z]]; if (wall[z].overpicnum >= 0) wall[z].cstat |= (1+4+16); } wall[z].xrepeat = 8; wall[z].yrepeat = 8; wall[z].xpanning = (char)((-side[picindex[z]].xoffset)&255); wall[z].ypanning = (char)(((side[picindex[z]].yoffset<<1))&255); if (line[linindex[z]].flags&1) wall[z].cstat |= 1; //if (wall[z].nextwall >= 0) wall[z].cstat |= 4; //if ((line[linindex[z]].flags&24) && (wall[z].nextwall >= 0)) // wall[z].cstat |= 4; } for(z=0;z= thingnum[i]) && (thing[z].type <= thingnum2[i])) for(j=thingoff[i];j tagnum2[i])) continue; for(j=tagoff[i];j= 0) if ((tagfield[j]&128) ^ (picindex[zx] == line[z].side1)) l = wall[zx].nextsector; zzz = sectspri[l][(tagfield[j]>>8)&7]; if (zzz < 0) { zzz = dnumthings++; sectspri[l][(tagfield[j]>>8)&7] = zzz; zzx = sector[l].wallptr; x1 = wall[zzx].x; y1 = wall[zzx].y; zzx = wall[zzx].point2; x2 = wall[zzx].x; y2 = wall[zzx].y; sprite[zzz].x = ((x1+x2)>>1) + ksgn(y1-y2); sprite[zzz].y = ((y1+y2)>>1) + ksgn(x2-x1); sprite[zzz].sectnum = l; sprite[zzz].z = sector[l].floorz; sprite[zzz].clipdist = 32; sprite[zzz].xrepeat = 64; sprite[zzz].yrepeat = 64; } switch(tagop[j]) { case 0: setspritefield(zzz,k,zz); break; case 1: setspritefield(zzz,k,getspritefield(zzz,k)+zz); break; case 2: setspritefield(zzz,k,getspritefield(zzz,k)-zz); break; case 3: setspritefield(zzz,k,getspritefield(zzz,k)|zz); break; case 4: setspritefield(zzz,k,getspritefield(zzz,k)&zz); break; case 5: setspritefield(zzz,k,getspritefield(zzz,k)^zz); break; } } else if (k < 64) { l = sectorofwall[zx]; if (wall[zx].nextsector >= 0) if ((tagfield[j]&128) ^ (picindex[zx] == line[z].side1)) l = wall[zx].nextsector; switch(tagop[j]) { case 0: setsectorfield(l,k,zz); break; case 1: setsectorfield(l,k,getsectorfield(l,k)+zz); break; case 2: setsectorfield(l,k,getsectorfield(l,k)-zz); break; case 3: setsectorfield(l,k,getsectorfield(l,k)|zz); break; case 4: setsectorfield(l,k,getsectorfield(l,k)&zz); break; case 5: setsectorfield(l,k,getsectorfield(l,k)^zz); break; } } else if (k < 96) { l = zx; if (wall[zx].nextwall >= 0) if ((tagfield[j]&128) ^ (picindex[zx] == line[z].side1)) l = wall[zx].nextwall; switch(tagop[j]) { case 0: setwallfield(l,k,zz); break; case 1: setwallfield(l,k,getwallfield(l,k)+zz); break; case 2: setwallfield(l,k,getwallfield(l,k)-zz); break; case 3: setwallfield(l,k,getwallfield(l,k)|zz); break; case 4: setwallfield(l,k,getwallfield(l,k)&zz); break; case 5: setwallfield(l,k,getwallfield(l,k)^zz); break; } } } } } for(l=0;l= secnum[i]) && (sect[l].type <= secnum2[i])) { for(j=secoff[i];j>8)&7]; if (zzz < 0) { zzz = dnumthings++; sectspri[l][(secfield[j]>>8)&7] = zzz; zzx = sector[l].wallptr; x1 = wall[zzx].x; y1 = wall[zzx].y; zzx = wall[zzx].point2; x2 = wall[zzx].x; y2 = wall[zzx].y; sprite[zzz].x = ((x1+x2)>>1) + ksgn(y1-y2); sprite[zzz].y = ((y1+y2)>>1) + ksgn(x2-x1); sprite[zzz].sectnum = l; sprite[zzz].z = sector[l].floorz; sprite[zzz].clipdist = 32; sprite[zzz].xrepeat = 64; sprite[zzz].yrepeat = 64; } switch(secop[j]) { case 0: setspritefield(zzz,k,zz); break; case 1: setspritefield(zzz,k,getspritefield(zzz,k)+zz); break; case 2: setspritefield(zzz,k,getspritefield(zzz,k)-zz); break; case 3: setspritefield(zzz,k,getspritefield(zzz,k)|zz); break; case 4: setspritefield(zzz,k,getspritefield(zzz,k)&zz); break; case 5: setspritefield(zzz,k,getspritefield(zzz,k)^zz); break; } } else if (k < 64) { switch(secop[j]) { case 0: setsectorfield(l,k,zz); break; case 1: setsectorfield(l,k,getsectorfield(l,k)+zz); break; case 2: setsectorfield(l,k,getsectorfield(l,k)-zz); break; case 3: setsectorfield(l,k,getsectorfield(l,k)|zz); break; case 4: setsectorfield(l,k,getsectorfield(l,k)&zz); break; case 5: setsectorfield(l,k,getsectorfield(l,k)^zz); break; } } } } for(z=0;z= 32768) || (klabs(y) >= 32768)) wall[z].xrepeat = 255; else { zx = mulscale10(ksqrtasm(x*x+y*y),wall[z].yrepeat); wall[z].xrepeat = (char)min(max(zx,1),255); } wall[z].picnum = texturelookup[wall[z].picnum]; wall[z].overpicnum = texturelookup[wall[z].overpicnum]; } mapversion = 7; posx = 0; posy = 0; posz = 0; ang = 1536; cursectnum = 0; //WATCH OUT THAT FOR DNUMTHINGS BEING HIGHER THAN NUMBER ON DOOM MAP! for(i=0;i