diff --git a/polymer/build/Makefile b/polymer/build/Makefile index 20684ea53..7f27b7187 100644 --- a/polymer/build/Makefile +++ b/polymer/build/Makefile @@ -195,7 +195,7 @@ $(OBJ)$(EDITORLIB): $(EDITOROBJS) $(RANLIB) $@ game$(EXESUFFIX): $(GAMEEXEOBJS) - $(CC) $(CFLAGS) $(OURCFLAGS) -o $@ $^ $(LIBS) $(GAMELIBS) $(STDCPPLIB) + $(CC) $(CFLAGS) $(OURCFLAGS) -o $@ $^ $(GAMELIBS) $(LIBS) $(STDCPPLIB) build$(EXESUFFIX): $(EDITOREXEOBJS) $(CC) $(CFLAGS) $(OURCFLAGS) -o $@ $^ $(LIBS) diff --git a/polymer/build/Makefile.shared b/polymer/build/Makefile.shared index 268e99b59..4956d06de 100644 --- a/polymer/build/Makefile.shared +++ b/polymer/build/Makefile.shared @@ -157,4 +157,3 @@ ifneq (0,$(SETSPRITEZ)) BUILDCFLAGS+= -DSETSPRITEZ endif - diff --git a/polymer/build/src/a-c.c b/polymer/build/src/a-c.c index bd59fca92..bc45cae91 100644 --- a/polymer/build/src/a-c.c +++ b/polymer/build/src/a-c.c @@ -1,298 +1,298 @@ -// A.ASM replacement using C -// Mainly by Ken Silverman, with things melded with my port by -// Jonathon Fowler (jonof@edgenetwork.org) -// -// "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. - -#include "a.h" - -#ifndef ENGINE_USING_A_C -# error A.H has indicated that optimized code has been requested. This means a-c.c is being compiled \ - when USE_A_C has not been defined. -#endif - -long krecip(long num); // from engine.c - -#define BITSOFPRECISION 3 -#define BITSOFPRECISIONPOW 8 - -extern long asm1, asm2, asm3, asm4, fpuasm, globalx3, globaly3; -extern void *reciptable; - -static long bpl, transmode = 0; -static long glogx, glogy, gbxinc, gbyinc, gpinc; -static char *gbuf, *gpal, *ghlinepal, *gtrans; - - //Global variable functions -void setvlinebpl(long dabpl) { bpl = dabpl; } -void fixtransluscence(long datransoff) { gtrans = (char *)datransoff; } -void settransnormal(void) { transmode = 0; } -void settransreverse(void) { transmode = 1; } - - - //Ceiling/floor horizontal line functions -void sethlinesizes(long logx, long logy, long bufplc) - { glogx = logx; glogy = logy; gbuf = (char *)bufplc; } -void setpalookupaddress(char *paladdr) { ghlinepal = paladdr; } -void setuphlineasm4(long bxinc, long byinc) { gbxinc = bxinc; gbyinc = byinc; } -void hlineasm4(long cnt, long skiploadincs, long paloffs, unsigned long by, unsigned long bx, long p) -{ - char *palptr; - - palptr = (char *)&ghlinepal[paloffs]; - if (!skiploadincs) { gbxinc = asm1; gbyinc = asm2; } - for(;cnt>=0;cnt--) - { - *((char *)p) = palptr[gbuf[((bx>>(32-glogx))<>(32-glogy))]]; - bx -= gbxinc; - by -= gbyinc; - p--; - } -} - - - //Sloped ceiling/floor vertical line functions -void setupslopevlin(long logylogx, long bufplc, long pinc) -{ - glogx = (logylogx&255); glogy = (logylogx>>8); - gbuf = (char *)bufplc; gpinc = pinc; -} -void slopevlin(long p, long i, long slopaloffs, long cnt, long bx, long by) -{ - long *slopalptr, bz, bzinc; - unsigned long u, v; - - bz = asm3; bzinc = (asm1>>3); - slopalptr = (long *)slopaloffs; - for(;cnt>0;cnt--) - { - i = krecip(bz>>6); bz += bzinc; - u = bx+globalx3*i; - v = by+globaly3*i; - (*(char *)p) = *(char *)(slopalptr[0]+gbuf[((u>>(32-glogx))<>(32-glogy))]); - slopalptr--; - p += gpinc; - } -} - - - //Wall,face sprite/wall sprite vertical line functions -void setupvlineasm(long neglogy) { glogy = neglogy; } -void vlineasm1(long vinc, long paloffs, long cnt, unsigned long vplc, long bufplc, long p) -{ - gbuf = (char *)bufplc; - gpal = (char *)paloffs; - for(;cnt>=0;cnt--) - { - *((char *)p) = gpal[gbuf[vplc>>glogy]]; - p += bpl; - vplc += vinc; - } -} - -void setupmvlineasm(long neglogy) { glogy = neglogy; } -void mvlineasm1(long vinc, long paloffs, long cnt, unsigned long vplc, long bufplc, long p) -{ - char ch; - - gbuf = (char *)bufplc; - gpal = (char *)paloffs; - for(;cnt>=0;cnt--) - { - ch = gbuf[vplc>>glogy]; if (ch != 255) *((char *)p) = gpal[ch]; - p += bpl; - vplc += vinc; - } -} - -void setuptvlineasm(long neglogy) { glogy = neglogy; } -void tvlineasm1(long vinc, long paloffs, long cnt, unsigned long vplc, long bufplc, long p) -{ - char ch; - - gbuf = (char *)bufplc; - gpal = (char *)paloffs; - if (transmode) - { - for(;cnt>=0;cnt--) - { - ch = gbuf[vplc>>glogy]; - if (ch != 255) *((char *)p) = gtrans[(*((char *)p))+(gpal[ch]<<8)]; - p += bpl; - vplc += vinc; - } - } - else - { - for(;cnt>=0;cnt--) - { - ch = gbuf[vplc>>glogy]; - if (ch != 255) *((char *)p) = gtrans[((*((char *)p))<<8)+gpal[ch]]; - p += bpl; - vplc += vinc; - } - } -} - - //Floor sprite horizontal line functions -void msethlineshift(long logx, long logy) { glogx = logx; glogy = logy; } -void mhline(long bufplc, unsigned long bx, long cntup16, long junk, unsigned long by, long p) -{ - char ch; - - gbuf = (char *)bufplc; - gpal = (char *)asm3; - for(cntup16>>=16;cntup16>0;cntup16--) - { - ch = gbuf[((bx>>(32-glogx))<>(32-glogy))]; - if (ch != 255) *((char *)p) = gpal[ch]; - bx += asm1; - by += asm2; - p++; - } -} - -void tsethlineshift(long logx, long logy) { glogx = logx; glogy = logy; } -void thline(long bufplc, unsigned long bx, long cntup16, long junk, unsigned long by, long p) -{ - char ch; - - gbuf = (char *)bufplc; - gpal = (char *)asm3; - if (transmode) - { - for(cntup16>>=16;cntup16>0;cntup16--) - { - ch = gbuf[((bx>>(32-glogx))<>(32-glogy))]; - if (ch != 255) *((char *)p) = gtrans[(*((char *)p))+(gpal[ch]<<8)]; - bx += asm1; - by += asm2; - p++; - } - } - else - { - for(cntup16>>=16;cntup16>0;cntup16--) - { - ch = gbuf[((bx>>(32-glogx))<>(32-glogy))]; - if (ch != 255) *((char *)p) = gtrans[((*((char *)p))<<8)+gpal[ch]]; - bx += asm1; - by += asm2; - p++; - } - } -} - - - //Rotatesprite vertical line functions -void setupspritevline(long paloffs, long bxinc, long byinc, long ysiz) -{ - gpal = (char *)paloffs; - gbxinc = bxinc; - gbyinc = byinc; - glogy = ysiz; -} -void spritevline(long bx, long by, long cnt, long bufplc, long p) -{ - gbuf = (char *)bufplc; - for(;cnt>1;cnt--) - { - (*(char *)p) = gpal[gbuf[(bx>>16)*glogy+(by>>16)]]; - bx += gbxinc; - by += gbyinc; - p += bpl; - } -} - - //Rotatesprite vertical line functions -void msetupspritevline(long paloffs, long bxinc, long byinc, long ysiz) -{ - gpal = (char *)paloffs; - gbxinc = bxinc; - gbyinc = byinc; - glogy = ysiz; -} -void mspritevline(long bx, long by, long cnt, long bufplc, long p) -{ - char ch; - - gbuf = (char *)bufplc; - for(;cnt>1;cnt--) - { - ch = gbuf[(bx>>16)*glogy+(by>>16)]; - if (ch != 255) (*(char *)p) = gpal[ch]; - bx += gbxinc; - by += gbyinc; - p += bpl; - } -} - -void tsetupspritevline(long paloffs, long bxinc, long byinc, long ysiz) -{ - gpal = (char *)paloffs; - gbxinc = bxinc; - gbyinc = byinc; - glogy = ysiz; -} -void tspritevline(long bx, long by, long cnt, long bufplc, long p) -{ - char ch; - - gbuf = (char *)bufplc; - if (transmode) - { - for(;cnt>1;cnt--) - { - ch = gbuf[(bx>>16)*glogy+(by>>16)]; - if (ch != 255) *((char *)p) = gtrans[(*((char *)p))+(gpal[ch]<<8)]; - bx += gbxinc; - by += gbyinc; - p += bpl; - } - } - else - { - for(;cnt>1;cnt--) - { - ch = gbuf[(bx>>16)*glogy+(by>>16)]; - if (ch != 255) *((char *)p) = gtrans[((*((char *)p))<<8)+gpal[ch]]; - bx += gbxinc; - by += gbyinc; - p += bpl; - } - } -} - -void setupdrawslab (long dabpl, long pal) - { bpl = dabpl; gpal = (char *)pal; } - -void drawslab (long dx, long v, long dy, long vi, long vptr, long p) -{ - long x; - - while (dy > 0) - { - for(x=0;x>16)+vptr))]; - p += bpl; v += vi; dy--; - } -} - -void stretchhline (long p0, long u, long cnt, long uinc, long rptr, long p) -{ - p0 = p-(cnt<<2); - do - { - p--; - *(char *)p = *(char *)((u>>16)+rptr); u -= uinc; - } while (p > p0); -} - - -void mmxoverlay() { } - -/* - * vim:ts=4: - */ - +// A.ASM replacement using C +// Mainly by Ken Silverman, with things melded with my port by +// Jonathon Fowler (jonof@edgenetwork.org) +// +// "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. + +#include "a.h" + +#ifndef ENGINE_USING_A_C +# error A.H has indicated that optimized code has been requested. This means a-c.c is being compiled \ + when USE_A_C has not been defined. +#endif + +long krecip(long num); // from engine.c + +#define BITSOFPRECISION 3 +#define BITSOFPRECISIONPOW 8 + +extern long asm1, asm2, asm3, asm4, fpuasm, globalx3, globaly3; +extern void *reciptable; + +static long bpl, transmode = 0; +static long glogx, glogy, gbxinc, gbyinc, gpinc; +static char *gbuf, *gpal, *ghlinepal, *gtrans; + + //Global variable functions +void setvlinebpl(long dabpl) { bpl = dabpl; } +void fixtransluscence(long datransoff) { gtrans = (char *)datransoff; } +void settransnormal(void) { transmode = 0; } +void settransreverse(void) { transmode = 1; } + + + //Ceiling/floor horizontal line functions +void sethlinesizes(long logx, long logy, long bufplc) + { glogx = logx; glogy = logy; gbuf = (char *)bufplc; } +void setpalookupaddress(char *paladdr) { ghlinepal = paladdr; } +void setuphlineasm4(long bxinc, long byinc) { gbxinc = bxinc; gbyinc = byinc; } +void hlineasm4(long cnt, long skiploadincs, long paloffs, unsigned long by, unsigned long bx, long p) +{ + char *palptr; + + palptr = (char *)&ghlinepal[paloffs]; + if (!skiploadincs) { gbxinc = asm1; gbyinc = asm2; } + for(;cnt>=0;cnt--) + { + *((char *)p) = palptr[gbuf[((bx>>(32-glogx))<>(32-glogy))]]; + bx -= gbxinc; + by -= gbyinc; + p--; + } +} + + + //Sloped ceiling/floor vertical line functions +void setupslopevlin(long logylogx, long bufplc, long pinc) +{ + glogx = (logylogx&255); glogy = (logylogx>>8); + gbuf = (char *)bufplc; gpinc = pinc; +} +void slopevlin(long p, long i, long slopaloffs, long cnt, long bx, long by) +{ + long *slopalptr, bz, bzinc; + unsigned long u, v; + + bz = asm3; bzinc = (asm1>>3); + slopalptr = (long *)slopaloffs; + for(;cnt>0;cnt--) + { + i = krecip(bz>>6); bz += bzinc; + u = bx+globalx3*i; + v = by+globaly3*i; + (*(char *)p) = *(char *)(slopalptr[0]+gbuf[((u>>(32-glogx))<>(32-glogy))]); + slopalptr--; + p += gpinc; + } +} + + + //Wall,face sprite/wall sprite vertical line functions +void setupvlineasm(long neglogy) { glogy = neglogy; } +void vlineasm1(long vinc, long paloffs, long cnt, unsigned long vplc, long bufplc, long p) +{ + gbuf = (char *)bufplc; + gpal = (char *)paloffs; + for(;cnt>=0;cnt--) + { + *((char *)p) = gpal[gbuf[vplc>>glogy]]; + p += bpl; + vplc += vinc; + } +} + +void setupmvlineasm(long neglogy) { glogy = neglogy; } +void mvlineasm1(long vinc, long paloffs, long cnt, unsigned long vplc, long bufplc, long p) +{ + char ch; + + gbuf = (char *)bufplc; + gpal = (char *)paloffs; + for(;cnt>=0;cnt--) + { + ch = gbuf[vplc>>glogy]; if (ch != 255) *((char *)p) = gpal[ch]; + p += bpl; + vplc += vinc; + } +} + +void setuptvlineasm(long neglogy) { glogy = neglogy; } +void tvlineasm1(long vinc, long paloffs, long cnt, unsigned long vplc, long bufplc, long p) +{ + char ch; + + gbuf = (char *)bufplc; + gpal = (char *)paloffs; + if (transmode) + { + for(;cnt>=0;cnt--) + { + ch = gbuf[vplc>>glogy]; + if (ch != 255) *((char *)p) = gtrans[(*((char *)p))+(gpal[ch]<<8)]; + p += bpl; + vplc += vinc; + } + } + else + { + for(;cnt>=0;cnt--) + { + ch = gbuf[vplc>>glogy]; + if (ch != 255) *((char *)p) = gtrans[((*((char *)p))<<8)+gpal[ch]]; + p += bpl; + vplc += vinc; + } + } +} + + //Floor sprite horizontal line functions +void msethlineshift(long logx, long logy) { glogx = logx; glogy = logy; } +void mhline(long bufplc, unsigned long bx, long cntup16, long junk, unsigned long by, long p) +{ + char ch; + + gbuf = (char *)bufplc; + gpal = (char *)asm3; + for(cntup16>>=16;cntup16>0;cntup16--) + { + ch = gbuf[((bx>>(32-glogx))<>(32-glogy))]; + if (ch != 255) *((char *)p) = gpal[ch]; + bx += asm1; + by += asm2; + p++; + } +} + +void tsethlineshift(long logx, long logy) { glogx = logx; glogy = logy; } +void thline(long bufplc, unsigned long bx, long cntup16, long junk, unsigned long by, long p) +{ + char ch; + + gbuf = (char *)bufplc; + gpal = (char *)asm3; + if (transmode) + { + for(cntup16>>=16;cntup16>0;cntup16--) + { + ch = gbuf[((bx>>(32-glogx))<>(32-glogy))]; + if (ch != 255) *((char *)p) = gtrans[(*((char *)p))+(gpal[ch]<<8)]; + bx += asm1; + by += asm2; + p++; + } + } + else + { + for(cntup16>>=16;cntup16>0;cntup16--) + { + ch = gbuf[((bx>>(32-glogx))<>(32-glogy))]; + if (ch != 255) *((char *)p) = gtrans[((*((char *)p))<<8)+gpal[ch]]; + bx += asm1; + by += asm2; + p++; + } + } +} + + + //Rotatesprite vertical line functions +void setupspritevline(long paloffs, long bxinc, long byinc, long ysiz) +{ + gpal = (char *)paloffs; + gbxinc = bxinc; + gbyinc = byinc; + glogy = ysiz; +} +void spritevline(long bx, long by, long cnt, long bufplc, long p) +{ + gbuf = (char *)bufplc; + for(;cnt>1;cnt--) + { + (*(char *)p) = gpal[gbuf[(bx>>16)*glogy+(by>>16)]]; + bx += gbxinc; + by += gbyinc; + p += bpl; + } +} + + //Rotatesprite vertical line functions +void msetupspritevline(long paloffs, long bxinc, long byinc, long ysiz) +{ + gpal = (char *)paloffs; + gbxinc = bxinc; + gbyinc = byinc; + glogy = ysiz; +} +void mspritevline(long bx, long by, long cnt, long bufplc, long p) +{ + char ch; + + gbuf = (char *)bufplc; + for(;cnt>1;cnt--) + { + ch = gbuf[(bx>>16)*glogy+(by>>16)]; + if (ch != 255) (*(char *)p) = gpal[ch]; + bx += gbxinc; + by += gbyinc; + p += bpl; + } +} + +void tsetupspritevline(long paloffs, long bxinc, long byinc, long ysiz) +{ + gpal = (char *)paloffs; + gbxinc = bxinc; + gbyinc = byinc; + glogy = ysiz; +} +void tspritevline(long bx, long by, long cnt, long bufplc, long p) +{ + char ch; + + gbuf = (char *)bufplc; + if (transmode) + { + for(;cnt>1;cnt--) + { + ch = gbuf[(bx>>16)*glogy+(by>>16)]; + if (ch != 255) *((char *)p) = gtrans[(*((char *)p))+(gpal[ch]<<8)]; + bx += gbxinc; + by += gbyinc; + p += bpl; + } + } + else + { + for(;cnt>1;cnt--) + { + ch = gbuf[(bx>>16)*glogy+(by>>16)]; + if (ch != 255) *((char *)p) = gtrans[((*((char *)p))<<8)+gpal[ch]]; + bx += gbxinc; + by += gbyinc; + p += bpl; + } + } +} + +void setupdrawslab (long dabpl, long pal) + { bpl = dabpl; gpal = (char *)pal; } + +void drawslab (long dx, long v, long dy, long vi, long vptr, long p) +{ + long x; + + while (dy > 0) + { + for(x=0;x>16)+vptr))]; + p += bpl; v += vi; dy--; + } +} + +void stretchhline (long p0, long u, long cnt, long uinc, long rptr, long p) +{ + p0 = p-(cnt<<2); + do + { + p--; + *(char *)p = *(char *)((u>>16)+rptr); u -= uinc; + } while (p > p0); +} + + +void mmxoverlay() { } + +/* + * vim:ts=4: + */ + diff --git a/polymer/build/src/baselayer.c b/polymer/build/src/baselayer.c index 66e567bf1..52d4a0480 100644 --- a/polymer/build/src/baselayer.c +++ b/polymer/build/src/baselayer.c @@ -1,206 +1,206 @@ -#include "compat.h" -#include "osd.h" -#include "build.h" -#include "engineinfo.h" -#include "baselayer.h" - -#ifdef RENDERTYPEWIN -#include "winlayer.h" -#endif - -#ifdef USE_OPENGL -struct glinfo glinfo = { - "Unknown", // vendor - "Unknown", // renderer - "0.0.0", // version - "", // extensions - - 1.0, // max anisotropy - 0, // brga texture format - 0, // clamp-to-edge support - 0, // texture compression - 0, // non-power-of-two textures - 0, // multisampling - 0, // nvidia multisampling hint -}; -#endif - -static int osdfunc_dumpbuildinfo(const osdfuncparm_t *parm) -{ - OSD_Printf( - "Build engine compilation:\n" - " CFLAGS: %s\n" - " LIBS: %s\n" - " Host: %s\n" - " Compiler: %s\n" - " Built: %s\n", - _engine_cflags, - _engine_libs, - _engine_uname, - _engine_compiler, - _engine_date); - - return OSDCMD_OK; -} - -static void onvideomodechange(int newmode) { } -void (*baselayer_onvideomodechange)(int) = onvideomodechange; - -static int osdfunc_setrendermode(const osdfuncparm_t *parm) -{ - int m; - char *p; - - char *modestrs[] = { - "classic software", "polygonal flat-shaded software", - "polygonal textured software", "polygonal OpenGL" - }; - - if (parm->numparms != 1) return OSDCMD_SHOWHELP; - m = Bstrtol(parm->parms[0], &p, 10); - - if (m < 0 || m > 3) return OSDCMD_SHOWHELP; - - setrendermode(m); - OSD_Printf("Rendering method changed to %s\n", modestrs[ getrendermode() ] ); - - return OSDCMD_OK; -} - -#if defined(POLYMOST) && defined(USE_OPENGL) -#ifdef DEBUGGINGAIDS -static int osdcmd_hicsetpalettetint(const osdfuncparm_t *parm) -{ - long pal, cols[3], eff; - char *p; - - if (parm->numparms != 5) return OSDCMD_SHOWHELP; - - pal = Batol(parm->parms[0]); - cols[0] = Batol(parm->parms[1]); - cols[1] = Batol(parm->parms[2]); - cols[2] = Batol(parm->parms[3]); - eff = Batol(parm->parms[4]); - - hicsetpalettetint(pal,cols[0],cols[1],cols[2],eff); - - return OSDCMD_OK; -} -#endif - -static int osdcmd_glinfo(const osdfuncparm_t *parm) -{ - char *s,*t,*u,i; - - if (bpp == 8) { - OSD_Printf("glinfo: Not in OpenGL mode.\n"); - return OSDCMD_OK; - } - - OSD_Printf("OpenGL Information:\n" - " Version: %s\n" - " Vendor: %s\n" - " Renderer: %s\n" - " Maximum anisotropy: %.1f%s\n" - " BGRA textures: %s\n" - " Non-x^2 textures: %s\n" - " Texure compression: %s\n" - " Clamp-to-edge: %s\n" - " Multisampling: %s\n" - " Nvidia multisample hint: %s\n" - " Extensions:\n", - glinfo.version, - glinfo.vendor, - glinfo.renderer, - glinfo.maxanisotropy, glinfo.maxanisotropy>1.0?"":" (no anisotropic filtering)", - glinfo.bgra ? "supported": "not supported", - glinfo.texnpot ? "supported": "not supported", - glinfo.texcompr ? "supported": "not supported", - glinfo.clamptoedge ? "supported": "not supported", - glinfo.multisample ? "supported": "not supported", - glinfo.nvmultisamplehint ? "supported": "not supported" - ); - - s = Bstrdup(glinfo.extensions); - if (!s) OSD_Printf(glinfo.extensions); - else { - i = 0; t = u = s; - while (*t) { - if (*t == ' ') { - if (i&1) { - *t = 0; - OSD_Printf(" %s\n",u); - u = t+1; - } - i++; - } - t++; - } - if (i&1) OSD_Printf(" %s\n",u); - Bfree(s); - } - - return OSDCMD_OK; -} -#endif - -static int osdcmd_vars(const osdfuncparm_t *parm) -{ - int showval = (parm->numparms < 1); - - if (!Bstrcasecmp(parm->name, "screencaptureformat")) { - const char *fmts[2][2] = { {"TGA", "PCX"}, {"0", "1"} }; - if (showval) { OSD_Printf("captureformat is %s\n", fmts[captureformat]); } - else { - int i,j; - for (j=0; j<2; j++) - for (i=0; i<2; i++) - if (!Bstrcasecmp(parm->parms[0], fmts[j][i])) break; - if (j == 2) return OSDCMD_SHOWHELP; - captureformat = i; - } - return OSDCMD_OK; - } -#ifdef SUPERBUILD - else if (!Bstrcasecmp(parm->name, "novoxmips")) { - if (showval) { OSD_Printf("novoxmips is %d\n", novoxmips); } - else { novoxmips = (atoi(parm->parms[0]) != 0); } - } - else if (!Bstrcasecmp(parm->name, "usevoxels")) { - if (showval) { OSD_Printf("usevoxels is %d\n", usevoxels); } - else { usevoxels = (atoi(parm->parms[0]) != 0); } - } -#endif - return OSDCMD_SHOWHELP; -} - -int baselayer_init(void) -{ -#ifdef POLYMOST - OSD_RegisterFunction("setrendermode","setrendermode : sets the engine's rendering mode.\n" - "Mode numbers are:\n" - " 0 - Classic Build software\n" - " 1 - Polygonal flat-shaded software\n" - " 2 - Polygonal textured software\n" -#ifdef USE_OPENGL - " 3 - Polygonal OpenGL\n" -#endif - , - osdfunc_setrendermode); -#endif - OSD_RegisterFunction("dumpbuildinfo","dumpbuildinfo: outputs engine compilation information",osdfunc_dumpbuildinfo); - OSD_RegisterFunction("screencaptureformat","screencaptureformat: sets the output format for screenshots (TGA or PCX)",osdcmd_vars); -#ifdef SUPERBUILD - OSD_RegisterFunction("novoxmips","novoxmips: turn off/on the use of mipmaps when rendering 8-bit voxels",osdcmd_vars); - OSD_RegisterFunction("usevoxels","usevoxels: enable/disable automatic sprite->voxel rendering",osdcmd_vars); -#endif -#if defined(POLYMOST) && defined(USE_OPENGL) -#ifdef DEBUGGINGAIDS - OSD_RegisterFunction("hicsetpalettetint","hicsetpalettetint: sets palette tinting values",osdcmd_hicsetpalettetint); -#endif - OSD_RegisterFunction("glinfo","glinfo: shows OpenGL information about the current OpenGL mode",osdcmd_glinfo); -#endif - - return 0; -} - +#include "compat.h" +#include "osd.h" +#include "build.h" +#include "engineinfo.h" +#include "baselayer.h" + +#ifdef RENDERTYPEWIN +#include "winlayer.h" +#endif + +#ifdef USE_OPENGL +struct glinfo glinfo = { + "Unknown", // vendor + "Unknown", // renderer + "0.0.0", // version + "", // extensions + + 1.0, // max anisotropy + 0, // brga texture format + 0, // clamp-to-edge support + 0, // texture compression + 0, // non-power-of-two textures + 0, // multisampling + 0, // nvidia multisampling hint +}; +#endif + +static int osdfunc_dumpbuildinfo(const osdfuncparm_t *parm) +{ + OSD_Printf( + "Build engine compilation:\n" + " CFLAGS: %s\n" + " LIBS: %s\n" + " Host: %s\n" + " Compiler: %s\n" + " Built: %s\n", + _engine_cflags, + _engine_libs, + _engine_uname, + _engine_compiler, + _engine_date); + + return OSDCMD_OK; +} + +static void onvideomodechange(int newmode) { } +void (*baselayer_onvideomodechange)(int) = onvideomodechange; + +static int osdfunc_setrendermode(const osdfuncparm_t *parm) +{ + int m; + char *p; + + char *modestrs[] = { + "classic software", "polygonal flat-shaded software", + "polygonal textured software", "polygonal OpenGL" + }; + + if (parm->numparms != 1) return OSDCMD_SHOWHELP; + m = Bstrtol(parm->parms[0], &p, 10); + + if (m < 0 || m > 3) return OSDCMD_SHOWHELP; + + setrendermode(m); + OSD_Printf("Rendering method changed to %s\n", modestrs[ getrendermode() ] ); + + return OSDCMD_OK; +} + +#if defined(POLYMOST) && defined(USE_OPENGL) +#ifdef DEBUGGINGAIDS +static int osdcmd_hicsetpalettetint(const osdfuncparm_t *parm) +{ + long pal, cols[3], eff; + char *p; + + if (parm->numparms != 5) return OSDCMD_SHOWHELP; + + pal = Batol(parm->parms[0]); + cols[0] = Batol(parm->parms[1]); + cols[1] = Batol(parm->parms[2]); + cols[2] = Batol(parm->parms[3]); + eff = Batol(parm->parms[4]); + + hicsetpalettetint(pal,cols[0],cols[1],cols[2],eff); + + return OSDCMD_OK; +} +#endif + +static int osdcmd_glinfo(const osdfuncparm_t *parm) +{ + char *s,*t,*u,i; + + if (bpp == 8) { + OSD_Printf("glinfo: Not in OpenGL mode.\n"); + return OSDCMD_OK; + } + + OSD_Printf("OpenGL Information:\n" + " Version: %s\n" + " Vendor: %s\n" + " Renderer: %s\n" + " Maximum anisotropy: %.1f%s\n" + " BGRA textures: %s\n" + " Non-x^2 textures: %s\n" + " Texure compression: %s\n" + " Clamp-to-edge: %s\n" + " Multisampling: %s\n" + " Nvidia multisample hint: %s\n" + " Extensions:\n", + glinfo.version, + glinfo.vendor, + glinfo.renderer, + glinfo.maxanisotropy, glinfo.maxanisotropy>1.0?"":" (no anisotropic filtering)", + glinfo.bgra ? "supported": "not supported", + glinfo.texnpot ? "supported": "not supported", + glinfo.texcompr ? "supported": "not supported", + glinfo.clamptoedge ? "supported": "not supported", + glinfo.multisample ? "supported": "not supported", + glinfo.nvmultisamplehint ? "supported": "not supported" + ); + + s = Bstrdup(glinfo.extensions); + if (!s) OSD_Printf(glinfo.extensions); + else { + i = 0; t = u = s; + while (*t) { + if (*t == ' ') { + if (i&1) { + *t = 0; + OSD_Printf(" %s\n",u); + u = t+1; + } + i++; + } + t++; + } + if (i&1) OSD_Printf(" %s\n",u); + Bfree(s); + } + + return OSDCMD_OK; +} +#endif + +static int osdcmd_vars(const osdfuncparm_t *parm) +{ + int showval = (parm->numparms < 1); + + if (!Bstrcasecmp(parm->name, "screencaptureformat")) { + const char *fmts[2][2] = { {"TGA", "PCX"}, {"0", "1"} }; + if (showval) { OSD_Printf("captureformat is %s\n", fmts[captureformat]); } + else { + int i,j; + for (j=0; j<2; j++) + for (i=0; i<2; i++) + if (!Bstrcasecmp(parm->parms[0], fmts[j][i])) break; + if (j == 2) return OSDCMD_SHOWHELP; + captureformat = i; + } + return OSDCMD_OK; + } +#ifdef SUPERBUILD + else if (!Bstrcasecmp(parm->name, "novoxmips")) { + if (showval) { OSD_Printf("novoxmips is %d\n", novoxmips); } + else { novoxmips = (atoi(parm->parms[0]) != 0); } + } + else if (!Bstrcasecmp(parm->name, "usevoxels")) { + if (showval) { OSD_Printf("usevoxels is %d\n", usevoxels); } + else { usevoxels = (atoi(parm->parms[0]) != 0); } + } +#endif + return OSDCMD_SHOWHELP; +} + +int baselayer_init(void) +{ +#ifdef POLYMOST + OSD_RegisterFunction("setrendermode","setrendermode : sets the engine's rendering mode.\n" + "Mode numbers are:\n" + " 0 - Classic Build software\n" + " 1 - Polygonal flat-shaded software\n" + " 2 - Polygonal textured software\n" +#ifdef USE_OPENGL + " 3 - Polygonal OpenGL\n" +#endif + , + osdfunc_setrendermode); +#endif + OSD_RegisterFunction("dumpbuildinfo","dumpbuildinfo: outputs engine compilation information",osdfunc_dumpbuildinfo); + OSD_RegisterFunction("screencaptureformat","screencaptureformat: sets the output format for screenshots (TGA or PCX)",osdcmd_vars); +#ifdef SUPERBUILD + OSD_RegisterFunction("novoxmips","novoxmips: turn off/on the use of mipmaps when rendering 8-bit voxels",osdcmd_vars); + OSD_RegisterFunction("usevoxels","usevoxels: enable/disable automatic sprite->voxel rendering",osdcmd_vars); +#endif +#if defined(POLYMOST) && defined(USE_OPENGL) +#ifdef DEBUGGINGAIDS + OSD_RegisterFunction("hicsetpalettetint","hicsetpalettetint: sets palette tinting values",osdcmd_hicsetpalettetint); +#endif + OSD_RegisterFunction("glinfo","glinfo: shows OpenGL information about the current OpenGL mode",osdcmd_glinfo); +#endif + + return 0; +} + diff --git a/polymer/build/src/bstub.c b/polymer/build/src/bstub.c index 41c89f872..566be10a4 100644 --- a/polymer/build/src/bstub.c +++ b/polymer/build/src/bstub.c @@ -1,574 +1,574 @@ -// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman -// Ken Silverman's official web site: "http://www.advsys.net/ken" -// See the included license file "BUILDLIC.TXT" for license info. -// -// This file has been modified from Ken Silverman's original release -// by Jonathon Fowler (jonof@edgenetwk.com) - -#include "compat.h" -#include "a.h" -#include "build.h" -#include "editor.h" -#include "pragmas.h" -#include "baselayer.h" -#include "names.h" -#include "osd.h" -#include "cache1d.h" - - -static char tempbuf[256]; - -#define NUMOPTIONS 9 -char option[NUMOPTIONS] = {0,0,0,0,0,0,1,0,0}; -char keys[NUMBUILDKEYS] = -{ - 0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39, - 0x1e,0x2c,0xd1,0xc9,0x33,0x34, - 0x9c,0x1c,0xd,0xc,0xf,0x45 -}; - - - -//static long hang = 0; -//static long rollangle = 0; - -//Detecting 2D / 3D mode: -// qsetmode is 200 in 3D mode -// qsetmode is 350/480 in 2D mode -// -//You can read these variables when F5-F8 is pressed in 3D mode only: -// -// If (searchstat == 0) WALL searchsector=sector, searchwall=wall -// If (searchstat == 1) CEILING searchsector=sector -// If (searchstat == 2) FLOOR searchsector=sector -// If (searchstat == 3) SPRITE searchsector=sector, searchwall=sprite -// If (searchstat == 4) MASKED WALL searchsector=sector, searchwall=wall -// -// searchsector is the sector of the selected item for all 5 searchstat's -// -// searchwall is undefined if searchstat is 1 or 2 -// searchwall is the wall if searchstat = 0 or 4 -// searchwall is the sprite if searchstat = 3 (Yeah, I know - it says wall, -// but trust me, it's the sprite number) - -long averagefps; -#define AVERAGEFRAMES 32 -static unsigned long frameval[AVERAGEFRAMES]; -static long framecnt = 0; - -char *defsfilename = "kenbuild.def"; -char *startwin_labeltext = "Starting Build Editor..."; -int nextvoxid = 0; - -int ExtPreInit(int *argc,char ***argv) -{ - return 0; -} - -int ExtInit(void) -{ - long i, rv = 0; - - /*printf("------------------------------------------------------------------------------\n"); - printf(" BUILD.EXE copyright(c) 1996 by Ken Silverman. You are granted the\n"); - printf(" right to use this software for your personal use only. This is a\n"); - printf(" special version to be used with \"Happy Fun KenBuild\" and may not work\n"); - printf(" properly with other Build engine games. Please refer to license.doc\n"); - printf(" for distribution rights\n"); - printf("------------------------------------------------------------------------------\n"); - getch(); - */ - - initgroupfile("stuff.dat"); - bpp = 8; - if (loadsetup("build.cfg") < 0) initprintf("Configuration file not found, using defaults.\n"), rv = 1; - Bmemcpy((void *)buildkeys,(void *)keys,NUMBUILDKEYS); //Trick to make build use setup.dat keys - if (option[4] > 0) option[4] = 0; - if (initengine()) { - wm_msgbox("Build Engine Initialisation Error", - "There was a problem initialising the Build engine: %s", engineerrstr); - return -1; - } - initinput(); - initmouse(); - - //You can load your own palette lookup tables here if you just - //copy the right code! - for(i=0;i<256;i++) - tempbuf[i] = ((i+32)&255); //remap colors for screwy palette sectors - makepalookup(16,tempbuf,0,0,0,1); - - kensplayerheight = 32; - zmode = 0; - defaultspritecstat = 0; - pskyoff[0] = 0; pskyoff[1] = 0; pskybits = 1; - -#ifdef SUPERBUILD - tiletovox[PLAYER] = nextvoxid++; - tiletovox[BROWNMONSTER] = nextvoxid++; -#endif - -#ifdef _WIN32 -// allowtaskswitching(0); -#endif - return rv; -} - -void ExtUnInit(void) -{ - uninitgroupfile(); - writesetup("build.cfg"); -} - -void ExtSetupSpecialSpriteCols(void) -{ - return; -} - -//static long daviewingrange, daaspect, horizval1, horizval2; -void ExtPreCheckKeys(void) -{ - long /*cosang, sinang, dx, dy, mindx,*/ i, j, k; - - if (keystatus[0x3e]) //F4 - screen re-size - { - keystatus[0x3e] = 0; - - //cycle through all vesa modes, then screen-buffer mode - if (keystatus[0x2a]|keystatus[0x36]) { - setgamemode(!fullscreen, xdim, ydim, bpp); - } else { - - //cycle through all modes - j=-1; - - // work out a mask to select the mode - for (i=0; i> 3) + (xdim >> 4) + (xdim >> 6)) & (~7); - dy = (ydim + (ydim >> 3) + (ydim >> 4) + (ydim >> 6)) & (~7); - i = scale(320,ydim,xdim); - - if (waloff[4094] == 0) allocache(&waloff[4094],/*240L*384L*/dx*dy,&walock[4094]); - setviewtotile(4094,/*240L,384L*/dy,dx); - - cosang = sintable[(hang+512)&2047]; - sinang = sintable[hang&2047]; - - dx = dmulscale1(320,cosang,i,sinang); mindx = dx; - dy = dmulscale1(-i,cosang,320,sinang); - horizval1 = dy*(320>>1)/dx-1; - - dx = dmulscale1(320,cosang,-i,sinang); mindx = min(dx,mindx); - dy = dmulscale1(i,cosang,320,sinang); - horizval2 = dy*(320>>1)/dx+1; - - daviewingrange = scale(65536,16384*(xdim>>1),mindx-16); - daaspect = scale(daviewingrange,scale(320,tilesizx[4094],tilesizy[4094]),horizval2+6-horizval1); - setaspect(daviewingrange,scale(daaspect,ydim*320,xdim*i)); - horiz = 100-divscale15(horizval1+horizval2,daviewingrange); - } -#endif -} - -#ifdef SUPERBUILD -#define MAXVOXMIPS 5 -extern char *voxoff[][MAXVOXMIPS]; -void ExtAnalyzeSprites(void) -{ - long i, *longptr; - spritetype *tspr; - - for(i=0,tspr=&tsprite[0];ipicnum] >= 0) - { - switch(tspr->picnum) - { - case PLAYER: - if (!voxoff[ tiletovox[PLAYER] ][0]) { - if (qloadkvx(tiletovox[PLAYER],"voxel000.kvx")) { - tiletovox[PLAYER] = -1; - break; - } - } - //tspr->cstat |= 48; tspr->picnum = tiletovox[tspr->picnum]; - longptr = (long *)voxoff[ tiletovox[PLAYER] ][0]; - tspr->xrepeat = scale(tspr->xrepeat,56,longptr[2]); - tspr->yrepeat = scale(tspr->yrepeat,56,longptr[2]); - tspr->shade -= 6; - break; - case BROWNMONSTER: - if (!voxoff[ tiletovox[BROWNMONSTER] ][0]) { - if (qloadkvx(tiletovox[BROWNMONSTER],"voxel001.kvx")) { - tiletovox[BROWNMONSTER] = -1; - break; - } - } - //tspr->cstat |= 48; tspr->picnum = tiletovox[tspr->picnum]; - break; - } - } - - tspr->shade += 6; - if (sector[tspr->sectnum].ceilingstat&1) - tspr->shade += sector[tspr->sectnum].ceilingshade; - else - tspr->shade += sector[tspr->sectnum].floorshade; - } -} -#endif - -void ExtCheckKeys(void) -{ - long i;//, p, y, dx, dy, cosang, sinang, bufplc, tsizy, tsizyup15; - long j; - - if (qsetmode == 200) //In 3D mode - { -#if 0 - if (hang != 0) - { - bufplc = waloff[4094]+(mulscale16(horiz-100,xdimenscale)+(tilesizx[4094]>>1))*tilesizy[4094]; - setviewback(); - cosang = sintable[(hang+512)&2047]; - sinang = sintable[hang&2047]; - dx = dmulscale1(xdim,cosang,ydim,sinang); - dy = dmulscale1(-ydim,cosang,xdim,sinang); - - begindrawing(); - tsizy = tilesizy[4094]; - tsizyup15 = (tsizy<<15); - dx = mulscale14(dx,daviewingrange); - dy = mulscale14(dy,daaspect); - sinang = mulscale14(sinang,daviewingrange); - cosang = mulscale14(cosang,daaspect); - p = ylookup[windowy1]+frameplace+windowx2+1; - for(y=windowy1;y<=windowy2;y++) - { - i = divscale16(tsizyup15,dx); - stretchhline(0,(xdim>>1)*i+tsizyup15,xdim>>2,i,mulscale32(i,dy)*tsizy+bufplc,p); - dx -= sinang; dy += cosang; p += ylookup[1]; - } - walock[4094] = 1; - - Bsprintf(tempbuf,"%d",(hang*180)>>10); - printext256(0L,8L,31,-1,tempbuf,1); - enddrawing(); - } -#endif - if (keystatus[0xa]) setaspect(viewingrange+(viewingrange>>8),yxaspect+(yxaspect>>8)); - if (keystatus[0xb]) setaspect(viewingrange-(viewingrange>>8),yxaspect-(yxaspect>>8)); - if (keystatus[0xc]) setaspect(viewingrange,yxaspect-(yxaspect>>8)); - if (keystatus[0xd]) setaspect(viewingrange,yxaspect+(yxaspect>>8)); - //if (keystatus[0x38]) setrollangle(rollangle+=((keystatus[0x2a]|keystatus[0x36])*6+2)); - //if (keystatus[0xb8]) setrollangle(rollangle-=((keystatus[0x2a]|keystatus[0x36])*6+2)); - //if (keystatus[0x1d]|keystatus[0x9d]) setrollangle(rollangle=0); - - begindrawing(); - - i = frameval[framecnt&(AVERAGEFRAMES-1)]; - j = frameval[framecnt&(AVERAGEFRAMES-1)] = getticks(); framecnt++; - if (i != j) averagefps = ((mul3(averagefps)+((AVERAGEFRAMES*1000)/(j-i)) )>>2); - Bsprintf(tempbuf,"%ld",averagefps); - printext256(0L,0L,31,-1,tempbuf,1); - - enddrawing(); - editinput(); - } - else - { - } -} - -void ExtCleanUp(void) -{ -} - -void ExtPreLoadMap(void) -{ -} - -void ExtLoadMap(const char *mapname) -{ - char title[256]; - Bsprintf(title, "BUILD by Ken Silverman - %s", mapname); - wm_setapptitle(title); -} - -void ExtPreSaveMap(void) -{ -} - -void ExtSaveMap(const char *mapname) -{ -} - -const char *ExtGetSectorCaption(short sectnum) -{ - if ((sector[sectnum].lotag|sector[sectnum].hitag) == 0) - { - tempbuf[0] = 0; - } - else - { - Bsprintf(tempbuf,"%hu,%hu",(unsigned short)sector[sectnum].hitag, - (unsigned short)sector[sectnum].lotag); - } - return(tempbuf); -} - -const char *ExtGetWallCaption(short wallnum) -{ - if ((wall[wallnum].lotag|wall[wallnum].hitag) == 0) - { - tempbuf[0] = 0; - } - else - { - Bsprintf(tempbuf,"%hu,%hu",(unsigned short)wall[wallnum].hitag, - (unsigned short)wall[wallnum].lotag); - } - return(tempbuf); -} - -const char *ExtGetSpriteCaption(short spritenum) -{ - if ((sprite[spritenum].lotag|sprite[spritenum].hitag) == 0) - { - tempbuf[0] = 0; - } - else - { - Bsprintf(tempbuf,"%hu,%hu",(unsigned short)sprite[spritenum].hitag, - (unsigned short)sprite[spritenum].lotag); - } - return(tempbuf); -} - -//printext16 parameters: -//printext16(long xpos, long ypos, short col, short backcol, -// char name[82], char fontsize) -// xpos 0-639 (top left) -// ypos 0-479 (top left) -// col 0-15 -// backcol 0-15, -1 is transparent background -// name -// fontsize 0=8*8, 1=3*5 - -//drawline16 parameters: -// drawline16(long x1, long y1, long x2, long y2, char col) -// x1, x2 0-639 -// y1, y2 0-143 (status bar is 144 high, origin is top-left of STATUS BAR) -// col 0-15 - -void ExtShowSectorData(short sectnum) //F5 -{ - int i; - if (qsetmode == 200) //In 3D mode - { - } - else - { - begindrawing(); - clearmidstatbar16(); //Clear middle of status bar - - Bsprintf(tempbuf,"Sector %d",sectnum); - printext16(8,ydim16+32,11,-1,tempbuf,0); - - printext16(8,ydim16+48,11,-1,"8*8 font: ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789",0); - printext16(8,ydim16+56,11,-1,"3*5 font: ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789",1); - - i=ydim16; ydim16=ydim; - drawline16(320,i+68,344,i+80,4); //Draw house - drawline16(344,i+80,344,i+116,4); - drawline16(344,i+116,296,i+116,4); - drawline16(296,i+116,296,i+80,4); - drawline16(296,i+80,320,i+68,4); - ydim16=i; - enddrawing(); - } -} - -void ExtShowWallData(short wallnum) //F6 -{ - if (qsetmode == 200) //In 3D mode - { - } - else - { - begindrawing(); - clearmidstatbar16(); //Clear middle of status bar - - Bsprintf(tempbuf,"Wall %d",wallnum); - printext16(8,ydim16+32,11,-1,tempbuf,0); - enddrawing(); - } -} - -void ExtShowSpriteData(short spritenum) //F6 -{ - if (qsetmode == 200) //In 3D mode - { - } - else - { - begindrawing(); - clearmidstatbar16(); //Clear middle of status bar - - Bsprintf(tempbuf,"Sprite %d",spritenum); - printext16(8,ydim16+32,11,-1,tempbuf,0); - enddrawing(); - } -} - -void ExtEditSectorData(short sectnum) //F7 -{ - short nickdata; - - if (qsetmode == 200) //In 3D mode - { - //Ceiling - if (searchstat == 1) - sector[searchsector].ceilingpicnum++; //Just a stupid example - - //Floor - if (searchstat == 2) - sector[searchsector].floorshade++; //Just a stupid example - } - else //In 2D mode - { - Bsprintf(tempbuf,"Sector (%d) Nick's variable: ",sectnum); - nickdata = 0; - nickdata = getnumber16(tempbuf,nickdata,65536L,0); - - printmessage16(""); //Clear message box (top right of status bar) - ExtShowSectorData(sectnum); - } -} - -void ExtEditWallData(short wallnum) //F8 -{ - short nickdata; - - if (qsetmode == 200) //In 3D mode - { - } - else - { - Bsprintf(tempbuf,"Wall (%d) Nick's variable: ",wallnum); - nickdata = 0; - nickdata = getnumber16(tempbuf,nickdata,65536L,0); - - printmessage16(""); //Clear message box (top right of status bar) - ExtShowWallData(wallnum); - } -} - -void ExtEditSpriteData(short spritenum) //F8 -{ - short nickdata; - - if (qsetmode == 200) //In 3D mode - { - } - else - { - Bsprintf(tempbuf,"Sprite (%d) Nick's variable: ",spritenum); - nickdata = 0; - nickdata = getnumber16(tempbuf,nickdata,65536L,0); - printmessage16(""); - - printmessage16(""); //Clear message box (top right of status bar) - ExtShowSpriteData(spritenum); - } -} - -void faketimerhandler(void) -{ - sampletimer(); -} - - //Just thought you might want my getnumber16 code -/* -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)) //Enter, ESC - { - sprintf(&buffer,"%s%ld_ ",namestart,danum); - printmessage16(buffer); - - for(j=2;j<=11;j++) //Scan numbers 0-9 - 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) //L. enter - { - oldnum = danum; - keystatus[0x1c] = 2; - asksave = 1; - } - } - keystatus[0x1c] = 0; - keystatus[0x1] = 0; - return((short)oldnum); -} -*/ - -/* - * vim:ts=4: - */ - +// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman +// Ken Silverman's official web site: "http://www.advsys.net/ken" +// See the included license file "BUILDLIC.TXT" for license info. +// +// This file has been modified from Ken Silverman's original release +// by Jonathon Fowler (jonof@edgenetwk.com) + +#include "compat.h" +#include "a.h" +#include "build.h" +#include "editor.h" +#include "pragmas.h" +#include "baselayer.h" +#include "names.h" +#include "osd.h" +#include "cache1d.h" + + +static char tempbuf[256]; + +#define NUMOPTIONS 9 +char option[NUMOPTIONS] = {0,0,0,0,0,0,1,0,0}; +char keys[NUMBUILDKEYS] = +{ + 0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39, + 0x1e,0x2c,0xd1,0xc9,0x33,0x34, + 0x9c,0x1c,0xd,0xc,0xf,0x45 +}; + + + +//static long hang = 0; +//static long rollangle = 0; + +//Detecting 2D / 3D mode: +// qsetmode is 200 in 3D mode +// qsetmode is 350/480 in 2D mode +// +//You can read these variables when F5-F8 is pressed in 3D mode only: +// +// If (searchstat == 0) WALL searchsector=sector, searchwall=wall +// If (searchstat == 1) CEILING searchsector=sector +// If (searchstat == 2) FLOOR searchsector=sector +// If (searchstat == 3) SPRITE searchsector=sector, searchwall=sprite +// If (searchstat == 4) MASKED WALL searchsector=sector, searchwall=wall +// +// searchsector is the sector of the selected item for all 5 searchstat's +// +// searchwall is undefined if searchstat is 1 or 2 +// searchwall is the wall if searchstat = 0 or 4 +// searchwall is the sprite if searchstat = 3 (Yeah, I know - it says wall, +// but trust me, it's the sprite number) + +long averagefps; +#define AVERAGEFRAMES 32 +static unsigned long frameval[AVERAGEFRAMES]; +static long framecnt = 0; + +char *defsfilename = "kenbuild.def"; +char *startwin_labeltext = "Starting Build Editor..."; +int nextvoxid = 0; + +int ExtPreInit(int *argc,char ***argv) +{ + return 0; +} + +int ExtInit(void) +{ + long i, rv = 0; + + /*printf("------------------------------------------------------------------------------\n"); + printf(" BUILD.EXE copyright(c) 1996 by Ken Silverman. You are granted the\n"); + printf(" right to use this software for your personal use only. This is a\n"); + printf(" special version to be used with \"Happy Fun KenBuild\" and may not work\n"); + printf(" properly with other Build engine games. Please refer to license.doc\n"); + printf(" for distribution rights\n"); + printf("------------------------------------------------------------------------------\n"); + getch(); + */ + + initgroupfile("stuff.dat"); + bpp = 8; + if (loadsetup("build.cfg") < 0) initprintf("Configuration file not found, using defaults.\n"), rv = 1; + Bmemcpy((void *)buildkeys,(void *)keys,NUMBUILDKEYS); //Trick to make build use setup.dat keys + if (option[4] > 0) option[4] = 0; + if (initengine()) { + wm_msgbox("Build Engine Initialisation Error", + "There was a problem initialising the Build engine: %s", engineerrstr); + return -1; + } + initinput(); + initmouse(); + + //You can load your own palette lookup tables here if you just + //copy the right code! + for(i=0;i<256;i++) + tempbuf[i] = ((i+32)&255); //remap colors for screwy palette sectors + makepalookup(16,tempbuf,0,0,0,1); + + kensplayerheight = 32; + zmode = 0; + defaultspritecstat = 0; + pskyoff[0] = 0; pskyoff[1] = 0; pskybits = 1; + +#ifdef SUPERBUILD + tiletovox[PLAYER] = nextvoxid++; + tiletovox[BROWNMONSTER] = nextvoxid++; +#endif + +#ifdef _WIN32 +// allowtaskswitching(0); +#endif + return rv; +} + +void ExtUnInit(void) +{ + uninitgroupfile(); + writesetup("build.cfg"); +} + +void ExtSetupSpecialSpriteCols(void) +{ + return; +} + +//static long daviewingrange, daaspect, horizval1, horizval2; +void ExtPreCheckKeys(void) +{ + long /*cosang, sinang, dx, dy, mindx,*/ i, j, k; + + if (keystatus[0x3e]) //F4 - screen re-size + { + keystatus[0x3e] = 0; + + //cycle through all vesa modes, then screen-buffer mode + if (keystatus[0x2a]|keystatus[0x36]) { + setgamemode(!fullscreen, xdim, ydim, bpp); + } else { + + //cycle through all modes + j=-1; + + // work out a mask to select the mode + for (i=0; i> 3) + (xdim >> 4) + (xdim >> 6)) & (~7); + dy = (ydim + (ydim >> 3) + (ydim >> 4) + (ydim >> 6)) & (~7); + i = scale(320,ydim,xdim); + + if (waloff[4094] == 0) allocache(&waloff[4094],/*240L*384L*/dx*dy,&walock[4094]); + setviewtotile(4094,/*240L,384L*/dy,dx); + + cosang = sintable[(hang+512)&2047]; + sinang = sintable[hang&2047]; + + dx = dmulscale1(320,cosang,i,sinang); mindx = dx; + dy = dmulscale1(-i,cosang,320,sinang); + horizval1 = dy*(320>>1)/dx-1; + + dx = dmulscale1(320,cosang,-i,sinang); mindx = min(dx,mindx); + dy = dmulscale1(i,cosang,320,sinang); + horizval2 = dy*(320>>1)/dx+1; + + daviewingrange = scale(65536,16384*(xdim>>1),mindx-16); + daaspect = scale(daviewingrange,scale(320,tilesizx[4094],tilesizy[4094]),horizval2+6-horizval1); + setaspect(daviewingrange,scale(daaspect,ydim*320,xdim*i)); + horiz = 100-divscale15(horizval1+horizval2,daviewingrange); + } +#endif +} + +#ifdef SUPERBUILD +#define MAXVOXMIPS 5 +extern char *voxoff[][MAXVOXMIPS]; +void ExtAnalyzeSprites(void) +{ + long i, *longptr; + spritetype *tspr; + + for(i=0,tspr=&tsprite[0];ipicnum] >= 0) + { + switch(tspr->picnum) + { + case PLAYER: + if (!voxoff[ tiletovox[PLAYER] ][0]) { + if (qloadkvx(tiletovox[PLAYER],"voxel000.kvx")) { + tiletovox[PLAYER] = -1; + break; + } + } + //tspr->cstat |= 48; tspr->picnum = tiletovox[tspr->picnum]; + longptr = (long *)voxoff[ tiletovox[PLAYER] ][0]; + tspr->xrepeat = scale(tspr->xrepeat,56,longptr[2]); + tspr->yrepeat = scale(tspr->yrepeat,56,longptr[2]); + tspr->shade -= 6; + break; + case BROWNMONSTER: + if (!voxoff[ tiletovox[BROWNMONSTER] ][0]) { + if (qloadkvx(tiletovox[BROWNMONSTER],"voxel001.kvx")) { + tiletovox[BROWNMONSTER] = -1; + break; + } + } + //tspr->cstat |= 48; tspr->picnum = tiletovox[tspr->picnum]; + break; + } + } + + tspr->shade += 6; + if (sector[tspr->sectnum].ceilingstat&1) + tspr->shade += sector[tspr->sectnum].ceilingshade; + else + tspr->shade += sector[tspr->sectnum].floorshade; + } +} +#endif + +void ExtCheckKeys(void) +{ + long i;//, p, y, dx, dy, cosang, sinang, bufplc, tsizy, tsizyup15; + long j; + + if (qsetmode == 200) //In 3D mode + { +#if 0 + if (hang != 0) + { + bufplc = waloff[4094]+(mulscale16(horiz-100,xdimenscale)+(tilesizx[4094]>>1))*tilesizy[4094]; + setviewback(); + cosang = sintable[(hang+512)&2047]; + sinang = sintable[hang&2047]; + dx = dmulscale1(xdim,cosang,ydim,sinang); + dy = dmulscale1(-ydim,cosang,xdim,sinang); + + begindrawing(); + tsizy = tilesizy[4094]; + tsizyup15 = (tsizy<<15); + dx = mulscale14(dx,daviewingrange); + dy = mulscale14(dy,daaspect); + sinang = mulscale14(sinang,daviewingrange); + cosang = mulscale14(cosang,daaspect); + p = ylookup[windowy1]+frameplace+windowx2+1; + for(y=windowy1;y<=windowy2;y++) + { + i = divscale16(tsizyup15,dx); + stretchhline(0,(xdim>>1)*i+tsizyup15,xdim>>2,i,mulscale32(i,dy)*tsizy+bufplc,p); + dx -= sinang; dy += cosang; p += ylookup[1]; + } + walock[4094] = 1; + + Bsprintf(tempbuf,"%d",(hang*180)>>10); + printext256(0L,8L,31,-1,tempbuf,1); + enddrawing(); + } +#endif + if (keystatus[0xa]) setaspect(viewingrange+(viewingrange>>8),yxaspect+(yxaspect>>8)); + if (keystatus[0xb]) setaspect(viewingrange-(viewingrange>>8),yxaspect-(yxaspect>>8)); + if (keystatus[0xc]) setaspect(viewingrange,yxaspect-(yxaspect>>8)); + if (keystatus[0xd]) setaspect(viewingrange,yxaspect+(yxaspect>>8)); + //if (keystatus[0x38]) setrollangle(rollangle+=((keystatus[0x2a]|keystatus[0x36])*6+2)); + //if (keystatus[0xb8]) setrollangle(rollangle-=((keystatus[0x2a]|keystatus[0x36])*6+2)); + //if (keystatus[0x1d]|keystatus[0x9d]) setrollangle(rollangle=0); + + begindrawing(); + + i = frameval[framecnt&(AVERAGEFRAMES-1)]; + j = frameval[framecnt&(AVERAGEFRAMES-1)] = getticks(); framecnt++; + if (i != j) averagefps = ((mul3(averagefps)+((AVERAGEFRAMES*1000)/(j-i)) )>>2); + Bsprintf(tempbuf,"%ld",averagefps); + printext256(0L,0L,31,-1,tempbuf,1); + + enddrawing(); + editinput(); + } + else + { + } +} + +void ExtCleanUp(void) +{ +} + +void ExtPreLoadMap(void) +{ +} + +void ExtLoadMap(const char *mapname) +{ + char title[256]; + Bsprintf(title, "BUILD by Ken Silverman - %s", mapname); + wm_setapptitle(title); +} + +void ExtPreSaveMap(void) +{ +} + +void ExtSaveMap(const char *mapname) +{ +} + +const char *ExtGetSectorCaption(short sectnum) +{ + if ((sector[sectnum].lotag|sector[sectnum].hitag) == 0) + { + tempbuf[0] = 0; + } + else + { + Bsprintf(tempbuf,"%hu,%hu",(unsigned short)sector[sectnum].hitag, + (unsigned short)sector[sectnum].lotag); + } + return(tempbuf); +} + +const char *ExtGetWallCaption(short wallnum) +{ + if ((wall[wallnum].lotag|wall[wallnum].hitag) == 0) + { + tempbuf[0] = 0; + } + else + { + Bsprintf(tempbuf,"%hu,%hu",(unsigned short)wall[wallnum].hitag, + (unsigned short)wall[wallnum].lotag); + } + return(tempbuf); +} + +const char *ExtGetSpriteCaption(short spritenum) +{ + if ((sprite[spritenum].lotag|sprite[spritenum].hitag) == 0) + { + tempbuf[0] = 0; + } + else + { + Bsprintf(tempbuf,"%hu,%hu",(unsigned short)sprite[spritenum].hitag, + (unsigned short)sprite[spritenum].lotag); + } + return(tempbuf); +} + +//printext16 parameters: +//printext16(long xpos, long ypos, short col, short backcol, +// char name[82], char fontsize) +// xpos 0-639 (top left) +// ypos 0-479 (top left) +// col 0-15 +// backcol 0-15, -1 is transparent background +// name +// fontsize 0=8*8, 1=3*5 + +//drawline16 parameters: +// drawline16(long x1, long y1, long x2, long y2, char col) +// x1, x2 0-639 +// y1, y2 0-143 (status bar is 144 high, origin is top-left of STATUS BAR) +// col 0-15 + +void ExtShowSectorData(short sectnum) //F5 +{ + int i; + if (qsetmode == 200) //In 3D mode + { + } + else + { + begindrawing(); + clearmidstatbar16(); //Clear middle of status bar + + Bsprintf(tempbuf,"Sector %d",sectnum); + printext16(8,ydim16+32,11,-1,tempbuf,0); + + printext16(8,ydim16+48,11,-1,"8*8 font: ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789",0); + printext16(8,ydim16+56,11,-1,"3*5 font: ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789",1); + + i=ydim16; ydim16=ydim; + drawline16(320,i+68,344,i+80,4); //Draw house + drawline16(344,i+80,344,i+116,4); + drawline16(344,i+116,296,i+116,4); + drawline16(296,i+116,296,i+80,4); + drawline16(296,i+80,320,i+68,4); + ydim16=i; + enddrawing(); + } +} + +void ExtShowWallData(short wallnum) //F6 +{ + if (qsetmode == 200) //In 3D mode + { + } + else + { + begindrawing(); + clearmidstatbar16(); //Clear middle of status bar + + Bsprintf(tempbuf,"Wall %d",wallnum); + printext16(8,ydim16+32,11,-1,tempbuf,0); + enddrawing(); + } +} + +void ExtShowSpriteData(short spritenum) //F6 +{ + if (qsetmode == 200) //In 3D mode + { + } + else + { + begindrawing(); + clearmidstatbar16(); //Clear middle of status bar + + Bsprintf(tempbuf,"Sprite %d",spritenum); + printext16(8,ydim16+32,11,-1,tempbuf,0); + enddrawing(); + } +} + +void ExtEditSectorData(short sectnum) //F7 +{ + short nickdata; + + if (qsetmode == 200) //In 3D mode + { + //Ceiling + if (searchstat == 1) + sector[searchsector].ceilingpicnum++; //Just a stupid example + + //Floor + if (searchstat == 2) + sector[searchsector].floorshade++; //Just a stupid example + } + else //In 2D mode + { + Bsprintf(tempbuf,"Sector (%d) Nick's variable: ",sectnum); + nickdata = 0; + nickdata = getnumber16(tempbuf,nickdata,65536L,0); + + printmessage16(""); //Clear message box (top right of status bar) + ExtShowSectorData(sectnum); + } +} + +void ExtEditWallData(short wallnum) //F8 +{ + short nickdata; + + if (qsetmode == 200) //In 3D mode + { + } + else + { + Bsprintf(tempbuf,"Wall (%d) Nick's variable: ",wallnum); + nickdata = 0; + nickdata = getnumber16(tempbuf,nickdata,65536L,0); + + printmessage16(""); //Clear message box (top right of status bar) + ExtShowWallData(wallnum); + } +} + +void ExtEditSpriteData(short spritenum) //F8 +{ + short nickdata; + + if (qsetmode == 200) //In 3D mode + { + } + else + { + Bsprintf(tempbuf,"Sprite (%d) Nick's variable: ",spritenum); + nickdata = 0; + nickdata = getnumber16(tempbuf,nickdata,65536L,0); + printmessage16(""); + + printmessage16(""); //Clear message box (top right of status bar) + ExtShowSpriteData(spritenum); + } +} + +void faketimerhandler(void) +{ + sampletimer(); +} + + //Just thought you might want my getnumber16 code +/* +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)) //Enter, ESC + { + sprintf(&buffer,"%s%ld_ ",namestart,danum); + printmessage16(buffer); + + for(j=2;j<=11;j++) //Scan numbers 0-9 + 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) //L. enter + { + oldnum = danum; + keystatus[0x1c] = 2; + asksave = 1; + } + } + keystatus[0x1c] = 0; + keystatus[0x1] = 0; + return((short)oldnum); +} +*/ + +/* + * vim:ts=4: + */ + diff --git a/polymer/build/src/cache1d.c b/polymer/build/src/cache1d.c index abe2902c2..8133a97e4 100644 --- a/polymer/build/src/cache1d.c +++ b/polymer/build/src/cache1d.c @@ -1,1301 +1,1301 @@ -// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman -// Ken Silverman's official web site: "http://www.advsys.net/ken" -// See the included license file "BUILDLIC.TXT" for license info. -// -// This file has been modified from Ken Silverman's original release -// by Jonathon Fowler (jonof@edgenetwk.com) - -#define WITHKPLIB - -#include "compat.h" -#include "cache1d.h" -#include "pragmas.h" -#include "baselayer.h" - -#ifdef WITHKPLIB -#include "kplib.h" - - //Insert '|' in front of filename - //Doing this tells kzopen to load the file only if inside a .ZIP file -static long kzipopen(char *filnam) -{ - unsigned int i; - char newst[BMAX_PATH+4]; - - newst[0] = '|'; - for(i=0;filnam[i] && (i < sizeof(newst)-2);i++) newst[i+1] = filnam[i]; - newst[i+1] = 0; - return(kzopen(newst)); -} - -#endif - - -// This module keeps track of a standard linear cacheing system. -// To use this module, here's all you need to do: -// -// Step 1: Allocate a nice BIG buffer, like from 1MB-4MB and -// Call initcache(long cachestart, long cachesize) where -// -// cachestart = (long)(pointer to start of BIG buffer) -// cachesize = length of BIG buffer -// -// Step 2: Call allocache(long *bufptr, long bufsiz, char *lockptr) -// whenever you need to allocate a buffer, where: -// -// *bufptr = pointer to 4-byte pointer to buffer -// Confused? Using this method, cache2d can remove -// previously allocated things from the cache safely by -// setting the 4-byte pointer to 0. -// bufsiz = number of bytes to allocate -// *lockptr = pointer to locking char which tells whether -// the region can be removed or not. If *lockptr = 0 then -// the region is not locked else its locked. -// -// Step 3: If you need to remove everything from the cache, or every -// unlocked item from the cache, you can call uninitcache(); -// Call uninitcache(0) to remove all unlocked items, or -// Call uninitcache(1) to remove everything. -// After calling uninitcache, it is still ok to call allocache -// without first calling initcache. - -#define MAXCACHEOBJECTS 9216 - -static long cachesize = 0; -long cachecount = 0; -char zerochar = 0; -long cachestart = 0, cacnum = 0, agecount = 0; -typedef struct { long *hand, leng; char *lock; } cactype; -cactype cac[MAXCACHEOBJECTS]; -static long lockrecip[200]; - -static char toupperlookup[256]; - -extern void *kmalloc(size_t); -extern void kfree(void *); - -static void reportandexit(char *errormessage); - -extern char pow2char[8]; - - -void initcache(long dacachestart, long dacachesize) -{ - long i; - - for(i=1;i<200;i++) lockrecip[i] = (1<<28)/(200-i); - - cachestart = dacachestart; - cachesize = dacachesize; - - cac[0].leng = cachesize; - cac[0].lock = &zerochar; - cacnum = 1; - - initprintf("initcache(): Initialised with %d bytes\n", dacachesize); -} - -void allocache(long *newhandle, long newbytes, char *newlockptr) -{ - long i, /*j,*/ z, zz, bestz=0, daval, bestval, besto=0, o1, o2, sucklen, suckz; - - newbytes = ((newbytes+15)&0xfffffff0); - - if ((unsigned)newbytes > (unsigned)cachesize) - { - Bprintf("Cachesize: %ld\n",cachesize); - Bprintf("*Newhandle: 0x%lx, Newbytes: %ld, *Newlock: %d\n",(long)newhandle,newbytes,*newlockptr); - reportandexit("BUFFER TOO BIG TO FIT IN CACHE!"); - } - - if (*newlockptr == 0) - { - reportandexit("ALLOCACHE CALLED WITH LOCK OF 0!"); - } - - //Find best place - bestval = 0x7fffffff; o1 = cachesize; - for(z=cacnum-1;z>=0;z--) - { - o1 -= cac[z].leng; - o2 = o1+newbytes; if (o2 > cachesize) continue; - - daval = 0; - for(i=o1,zz=z;i= 200) { daval = 0x7fffffff; break; } - daval += mulscale32(cac[zz].leng+65536,lockrecip[*cac[zz].lock]); - if (daval >= bestval) break; - } - if (daval < bestval) - { - bestval = daval; besto = o1; bestz = z; - if (bestval == 0) break; - } - } - - //printf("%ld %ld %ld\n",besto,newbytes,*newlockptr); - - if (bestval == 0x7fffffff) - reportandexit("CACHE SPACE ALL LOCKED UP!"); - - //Suck things out - for(sucklen=-newbytes,suckz=bestz;sucklen<0;sucklen+=cac[suckz++].leng) - if (*cac[suckz].lock) *cac[suckz].hand = 0; - - //Remove all blocks except 1 - suckz -= (bestz+1); cacnum -= suckz; - copybufbyte(&cac[bestz+suckz],&cac[bestz],(cacnum-bestz)*sizeof(cactype)); - cac[bestz].hand = newhandle; *newhandle = cachestart+besto; - cac[bestz].leng = newbytes; - cac[bestz].lock = newlockptr; - cachecount++; - - //Add new empty block if necessary - if (sucklen <= 0) return; - - bestz++; - if (bestz == cacnum) - { - cacnum++; if (cacnum > MAXCACHEOBJECTS) reportandexit("Too many objects in cache! (cacnum > MAXCACHEOBJECTS)"); - cac[bestz].leng = sucklen; - cac[bestz].lock = &zerochar; - return; - } - - if (*cac[bestz].lock == 0) { cac[bestz].leng += sucklen; return; } - - cacnum++; if (cacnum > MAXCACHEOBJECTS) reportandexit("Too many objects in cache! (cacnum > MAXCACHEOBJECTS)"); - for(z=cacnum-1;z>bestz;z--) cac[z] = cac[z-1]; - cac[bestz].leng = sucklen; - cac[bestz].lock = &zerochar; -} - -void suckcache(long *suckptr) -{ - long i; - - //Can't exit early, because invalid pointer might be same even though lock = 0 - for(i=0;i 0) && (*cac[i-1].lock == 0)) - { - cac[i-1].leng += cac[i].leng; - cacnum--; copybuf(&cac[i+1],&cac[i],(cacnum-i)*sizeof(cactype)); - } - else if ((i < cacnum-1) && (*cac[i+1].lock == 0)) - { - cac[i+1].leng += cac[i].leng; - cacnum--; copybuf(&cac[i+1],&cac[i],(cacnum-i)*sizeof(cactype)); - } - } -} - -void agecache(void) -{ - long cnt; - char ch; - - if (agecount >= cacnum) agecount = cacnum-1; - if (agecount < 0) return; - for(cnt=(cacnum>>4);cnt>=0;cnt--) - { - ch = (*cac[agecount].lock); - if (((ch-2)&255) < 198) - (*cac[agecount].lock) = ch-1; - - agecount--; if (agecount < 0) agecount = cacnum-1; - } -} - -static void reportandexit(char *errormessage) -{ - long i, j; - - //setvmode(0x3); - j = 0; - for(i=0;i - -typedef struct _searchpath { - struct _searchpath *next; - char *path; - size_t pathlen; // to save repeated calls to strlen() -} searchpath_t; -static searchpath_t *searchpathhead = NULL; -static size_t maxsearchpathlen = 0; -int pathsearchmode = 0; - -int addsearchpath(const char *p) -{ - struct stat st; - char *s; - searchpath_t *srch; - int i; - - if (Bstat(p, &st) < 0) { - if (errno == ENOENT) return -2; - return -1; - } - if (!(st.st_mode & BS_IFDIR)) return -1; - - srch = (searchpath_t*)malloc(sizeof(searchpath_t)); - if (!srch) return -1; - - srch->next = searchpathhead; - srch->pathlen = strlen(p)+1; - srch->path = (char*)malloc(srch->pathlen + 1); - if (!srch->path) { - free(srch); - return -1; - } - strcpy(srch->path, p); - for (s=srch->path; *s; s++) ; s--; if (spath || toupperlookup[*s] != '/') strcat(srch->path, "/"); - - searchpathhead = srch; - if (srch->pathlen > maxsearchpathlen) maxsearchpathlen = srch->pathlen; - initprintf("addsearchpath(): Added %s\n", srch->path); - - return 0; -} - -int findfrompath(const char *fn, char **where) -{ - searchpath_t *sp; - char *pfn, *ffn; - int allocsiz; - - // pathsearchmode == 0: tests current dir and then the dirs of the path stack - // pathsearchmode == 1: tests fn without modification, then like for pathsearchmode == 0 - - if (pathsearchmode) { - // test unmolested filename first - if (access(fn, F_OK) >= 0) { - *where = strdup(fn); - return 0; - } - } - - for (pfn = (char*)fn; toupperlookup[*pfn] == '/'; pfn++); - ffn = strdup(pfn); - if (!ffn) return -1; - Bcorrectfilename(ffn,0); // compress relative paths - - allocsiz = max(maxsearchpathlen, 2); // "./" (aka. curdir) - allocsiz += strlen(ffn); - allocsiz += 1; // a nul - - pfn = (char *)malloc(allocsiz); - if (!pfn) { free(ffn); return -1; } - - strcpy(pfn, "./"); - strcat(pfn, ffn); - if (access(pfn, F_OK) >= 0) { - *where = pfn; - free(ffn); - return 0; - } - - for (sp = searchpathhead; sp; sp = sp->next) { - strcpy(pfn, sp->path); - strcat(pfn, ffn); - //initprintf("Trying %s\n", pfn); - if (access(pfn, F_OK) >= 0) { - *where = pfn; - free(ffn); - return 0; - } - } - free(pfn); free(ffn); - return -1; -} - -int openfrompath(const char *fn, int flags, int mode) -{ - char *pfn; - int h; - - if (findfrompath(fn, &pfn) < 0) return -1; - h = Bopen(pfn, flags, mode); - free(pfn); - - return h; -} - -BFILE* fopenfrompath(const char *fn, const char *mode) -{ - int fh; - BFILE *h; - int bmode = 0, smode = 0; - const char *c; - - for (c=mode; c[0]; ) { - if (c[0] == 'r' && c[1] == '+') { bmode = BO_RDWR; smode = BS_IREAD|BS_IWRITE; c+=2; } - else if (c[0] == 'r') { bmode = BO_RDONLY; smode = BS_IREAD; c+=1; } - else if (c[0] == 'w' && c[1] == '+') { bmode = BO_RDWR|BO_CREAT|BO_TRUNC; smode = BS_IREAD|BS_IWRITE; c+=2; } - else if (c[0] == 'w') { bmode = BO_WRONLY|BO_CREAT|BO_TRUNC; smode = BS_IREAD|BS_IWRITE; c+=2; } - else if (c[0] == 'a' && c[1] == '+') { bmode = BO_RDWR|BO_CREAT; smode=BS_IREAD|BS_IWRITE; c+=2; } - else if (c[0] == 'a') { bmode = BO_WRONLY|BO_CREAT; smode=BS_IREAD|BS_IWRITE; c+=1; } - else if (c[0] == 'b') { bmode |= BO_BINARY; c+=1; } - else if (c[1] == 't') { bmode |= BO_TEXT; c+=1; } - else c++; - } - fh = openfrompath(fn,bmode,smode); - if (fh < 0) return NULL; - - h = fdopen(fh,mode); - if (!h) close(fh); - - return h; -} - - -#define MAXGROUPFILES 4 //Warning: Fix groupfil if this is changed -#define MAXOPENFILES 64 //Warning: Fix filehan if this is changed - -static char toupperlookup[256] = -{ - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, - 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, - 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, - 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, - 0x60,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, - 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x7b,0x7c,0x7d,0x7e,0x7f, - 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, - 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf, - 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, - 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf, - 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf, - 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef, - 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff -}; - -static long numgroupfiles = 0; -static long gnumfiles[MAXGROUPFILES]; -static long groupfil[MAXGROUPFILES] = {-1,-1,-1,-1}; -static long groupfilpos[MAXGROUPFILES]; -static char *gfilelist[MAXGROUPFILES]; -static long *gfileoffs[MAXGROUPFILES]; - -static char filegrp[MAXOPENFILES]; -static long filepos[MAXOPENFILES]; -static long filehan[MAXOPENFILES] = -{ - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 -}; -#ifdef WITHKPLIB -static char filenamsav[MAXOPENFILES][260]; -static long kzcurhand = -1; -#endif - -long initgroupfile(char *filename) -{ - char buf[16]; - long i, j, k; -#ifdef WITHKPLIB - char *zfn; - searchpath_t *sp = NULL; -#endif - -#ifdef _WIN32 - // on Windows, translate all backslashes (0x5c) to forward slashes (0x2f) - toupperlookup[0x5c] = 0x2f; -#endif - -#ifdef WITHKPLIB - if (findfrompath(filename, &zfn) < 0) return -1; - - // check to see if the file passed is a ZIP and pass it on to kplib if it is - i = Bopen(zfn,BO_BINARY|BO_RDONLY,BS_IREAD); - if (i < 0) { free(zfn); return -1; } - - Bread(i, buf, 4); - if (buf[0] == 0x50 && buf[1] == 0x4B && buf[2] == 0x03 && buf[3] == 0x04) { - Bclose(i); - j = kzaddstack(zfn); - free(zfn); - return j; - } - free(zfn); - - if (numgroupfiles >= MAXGROUPFILES) return(-1); - - Blseek(i,0,BSEEK_SET); - groupfil[numgroupfiles] = i; -#else - groupfil[numgroupfiles] = openfrompath(filename,BO_BINARY|BO_RDONLY,BS_IREAD); - if (groupfil[numgroupfiles] != -1) -#endif - { - groupfilpos[numgroupfiles] = 0; - Bread(groupfil[numgroupfiles],buf,16); - if ((buf[0] != 'K') || (buf[1] != 'e') || (buf[2] != 'n') || - (buf[3] != 'S') || (buf[4] != 'i') || (buf[5] != 'l') || - (buf[6] != 'v') || (buf[7] != 'e') || (buf[8] != 'r') || - (buf[9] != 'm') || (buf[10] != 'a') || (buf[11] != 'n')) - { - Bclose(groupfil[numgroupfiles]); - groupfil[numgroupfiles] = -1; - return(-1); - } - gnumfiles[numgroupfiles] = B_LITTLE32(*((long *)&buf[12])); - - if ((gfilelist[numgroupfiles] = (char *)kmalloc(gnumfiles[numgroupfiles]<<4)) == 0) - { Bprintf("Not enough memory for file grouping system\n"); exit(0); } - if ((gfileoffs[numgroupfiles] = (long *)kmalloc((gnumfiles[numgroupfiles]+1)<<2)) == 0) - { Bprintf("Not enough memory for file grouping system\n"); exit(0); } - - Bread(groupfil[numgroupfiles],gfilelist[numgroupfiles],gnumfiles[numgroupfiles]<<4); - - j = 0; - for(i=0;i=0;i--) - if (groupfil[i] != -1 && groupfil[i] == grphandle) - { - kfree(gfilelist[i]); - kfree(gfileoffs[i]); - Bclose(groupfil[i]); - groupfil[i] = -1; - grpnum = i; - break; - } - - if (grpnum == -1) return; - - // JBF 20040111 - numgroupfiles--; - - // move any group files following this one back - for (i=grpnum+1; i= 254) // external file (255) or ZIPped file (254) - continue; - else if (filegrp[i] == grpnum) // close file in group we closed - filehan[i] = -1; - else if (filegrp[i] > grpnum) // move back a file in a group after the one we closed - filegrp[i]--; - } -} - -void uninitgroupfile(void) -{ - long i; - - for(i=numgroupfiles-1;i>=0;i--) - if (groupfil[i] != -1) - { - kfree(gfilelist[i]); - kfree(gfileoffs[i]); - Bclose(groupfil[i]); - groupfil[i] = -1; - } - numgroupfiles = 0; - - // JBF 20040111: "close" any files open in groups - for(i=0;i= 0) - { - filegrp[newhandle] = 255; - filehan[newhandle] = fil; - filepos[newhandle] = 0; - return(newhandle); - } - - for (; toupperlookup[*filename] == '/'; filename++); - -#ifdef WITHKPLIB - if ((kzcurhand != newhandle) && (kztell() >= 0)) - { - if (kzcurhand >= 0) filepos[kzcurhand] = kztell(); - kzclose(); - } - if (searchfirst != 1 && (i = kzipopen(filename)) != 0) { - kzcurhand = newhandle; - filegrp[newhandle] = 254; - filehan[newhandle] = i; - filepos[newhandle] = 0; - strcpy(filenamsav[newhandle],filename); - return newhandle; - } -#endif - - for(k=numgroupfiles-1;k>=0;k--) - { - if (searchfirst == 1) k = 0; - if (groupfil[k] >= 0) - { - for(i=gnumfiles[k]-1;i>=0;i--) - { - gfileptr = (char *)&gfilelist[k][i<<4]; - - bad = 0; - for(j=0;j<13;j++) - { - if (!filename[j]) break; - if (toupperlookup[filename[j]] != toupperlookup[gfileptr[j]]) - { bad = 1; break; } - } - if (bad) continue; - if (j<13 && gfileptr[j]) continue; // JBF: because e1l1.map might exist before e1l1 - if (j==13 && filename[j]) continue; // JBF: long file name - - filegrp[newhandle] = k; - filehan[newhandle] = i; - filepos[newhandle] = 0; - return(newhandle); - } - } - } - return(-1); -} - -long kread(long handle, void *buffer, long leng) -{ - long i, filenum, groupnum; - - filenum = filehan[handle]; - groupnum = filegrp[handle]; - if (groupnum == 255) return(Bread(filenum,buffer,leng)); -#ifdef WITHKPLIB - else if (groupnum == 254) - { - if (kzcurhand != handle) - { - if (kztell() >= 0) { filepos[kzcurhand] = kztell(); kzclose(); } - kzcurhand = handle; - kzipopen(filenamsav[handle]); - kzseek(filepos[handle],SEEK_SET); - } - return(kzread(buffer,leng)); - } -#endif - - if (groupfil[groupnum] != -1) - { - i = gfileoffs[groupnum][filenum]+filepos[handle]; - if (i != groupfilpos[groupnum]) - { - Blseek(groupfil[groupnum],i+((gnumfiles[groupnum]+1)<<4),BSEEK_SET); - groupfilpos[groupnum] = i; - } - leng = min(leng,(gfileoffs[groupnum][filenum+1]-gfileoffs[groupnum][filenum])-filepos[handle]); - leng = Bread(groupfil[groupnum],buffer,leng); - filepos[handle] += leng; - groupfilpos[groupnum] += leng; - return(leng); - } - - return(0); -} - -long klseek(long handle, long offset, long whence) -{ - long i, groupnum; - - groupnum = filegrp[handle]; - - if (groupnum == 255) return(Blseek(filehan[handle],offset,whence)); -#ifdef WITHKPLIB - else if (groupnum == 254) - { - if (kzcurhand != handle) - { - if (kztell() >= 0) { filepos[kzcurhand] = kztell(); kzclose(); } - kzcurhand = handle; - kzipopen(filenamsav[handle]); - kzseek(filepos[handle],SEEK_SET); - } - return(kzseek(offset,whence)); - } -#endif - - if (groupfil[groupnum] != -1) - { - switch(whence) - { - case BSEEK_SET: filepos[handle] = offset; break; - case BSEEK_END: i = filehan[handle]; - filepos[handle] = (gfileoffs[groupnum][i+1]-gfileoffs[groupnum][i])+offset; - break; - case BSEEK_CUR: filepos[handle] += offset; break; - } - return(filepos[handle]); - } - return(-1); -} - -long kfilelength(long handle) -{ - long i, groupnum; - - groupnum = filegrp[handle]; - if (groupnum == 255) { - // return(filelength(filehan[handle])) - return Bfilelength(filehan[handle]); - } -#ifdef WITHKPLIB - else if (groupnum == 254) - { - if (kzcurhand != handle) - { - if (kztell() >= 0) { filepos[kzcurhand] = kztell(); kzclose(); } - kzcurhand = handle; - kzipopen(filenamsav[handle]); - kzseek(filepos[handle],SEEK_SET); - } - return kzfilelength(); - } -#endif - i = filehan[handle]; - return(gfileoffs[groupnum][i+1]-gfileoffs[groupnum][i]); -} - -long ktell(long handle) -{ - long i, groupnum; - - groupnum = filegrp[handle]; - - if (groupnum == 255) return(Blseek(filehan[handle],0,BSEEK_CUR)); -#ifdef WITHKPLIB - else if (groupnum == 254) - { - if (kzcurhand != handle) - { - if (kztell() >= 0) { filepos[kzcurhand] = kztell(); kzclose(); } - kzcurhand = handle; - kzipopen(filenamsav[handle]); - kzseek(filepos[handle],SEEK_SET); - } - return kztell(); - } -#endif - if (groupfil[groupnum] != -1) - return filepos[handle]; - return(-1); -} - -void kclose(long handle) -{ - if (handle < 0) return; - if (filegrp[handle] == 255) Bclose(filehan[handle]); -#ifdef WITHKPLIB - else if (filegrp[handle] == 254) - { - kzclose(); - kzcurhand = -1; - } -#endif - filehan[handle] = -1; -} - -static int klistaddentry(CACHE1D_FIND_REC **rec, char *name, int type, int source) -{ - CACHE1D_FIND_REC *r = NULL, *attach = NULL; - - if (*rec) { - int insensitive, v; - CACHE1D_FIND_REC *last = NULL; - - for (attach = *rec; attach; last = attach, attach = attach->next) { - if (type == CACHE1D_FIND_DRIVE) continue; // we just want to get to the end for drives -#ifdef _WIN32 - insensitive = 1; -#else - if (source == CACHE1D_SOURCE_GRP || attach->source == CACHE1D_SOURCE_GRP) - insensitive = 1; - else if (source == CACHE1D_SOURCE_ZIP || attach->source == CACHE1D_SOURCE_ZIP) - insensitive = 1; - else - insensitive = 0; -#endif - if (insensitive) v = Bstrcasecmp(name, attach->name); - else v = Bstrcmp(name, attach->name); - - // sorted list - if (v > 0) continue; // item to add is bigger than the current one - // so look for something bigger than us - if (v < 0) { // item to add is smaller than the current one - attach = NULL; // so wedge it between the current item and the one before - break; - } - - // matched - if (source >= attach->source) return 1; // item to add is of lower priority - r = attach; - break; - } - - // wasn't found in the list, so attach to the end - if (!attach) attach = last; - } - - if (r) { - r->type = type; - r->source = source; - return 0; - } - - r = (CACHE1D_FIND_REC *)malloc(sizeof(CACHE1D_FIND_REC)+strlen(name)+1); - if (!r) return -1; - r->name = (char*)r + sizeof(CACHE1D_FIND_REC); strcpy(r->name, name); - r->type = type; - r->source = source; - r->usera = r->userb = NULL; - - if (!attach) { // we are the first item - r->prev = NULL; - r->next = *rec; - if (*rec) (*rec)->prev = r; - *rec = r; - } else { - r->prev = attach; - r->next = attach->next; - if (attach->next) attach->next->prev = r; - attach->next = r; - } - - return 0; -} - -void klistfree(CACHE1D_FIND_REC *rec) -{ - CACHE1D_FIND_REC *n; - - while (rec) { - n = rec->next; - free(rec); - rec = n; - } -} - -CACHE1D_FIND_REC *klistpath(const char *_path, const char *mask, int type) -{ - CACHE1D_FIND_REC *rec = NULL; - char *path; - - // pathsearchmode == 0: enumerates a path in the virtual filesystem - // pathsearchmode == 1: enumerates the system filesystem path passed in - - path = strdup(_path); - if (!path) return NULL; - - // we don't need any leading dots and slashes or trailing slashes either - { - int i,j; - for (i=0; path[i] == '.' || toupperlookup[path[i]] == '/'; ) i++; - for (j=0; path[j] = path[i]; j++,i++) ; - while (j>0 && toupperlookup[path[j-1]] == '/') j--; - path[j] = 0; - //initprintf("Cleaned up path = \"%s\"\n",path); - } - - if (*path && (type & CACHE1D_FIND_DIR)) { - if (klistaddentry(&rec, "..", CACHE1D_FIND_DIR, CACHE1D_SOURCE_CURDIR) < 0) goto failure; - } - - if (!(type & CACHE1D_OPT_NOSTACK)) { // current directory and paths in the search stack - searchpath_t *search = NULL; - BDIR *dir; - struct Bdirent *dirent; - const char *d = "."; - int stackdepth = CACHE1D_SOURCE_CURDIR; - char buf[BMAX_PATH]; - - if (pathsearchmode) d = _path; - - do { - if (!pathsearchmode) { - strcpy(buf, path); - if (*path) strcat(buf, "/"); - strcat(buf, d); - } else strcpy(buf, d); - dir = Bopendir(buf); - if (dir) { - while ((dirent = Breaddir(dir))) { - if ((dirent->name[0] == '.' && dirent->name[1] == 0) || - (dirent->name[0] == '.' && dirent->name[1] == '.' && dirent->name[2] == 0)) - continue; - if ((type & CACHE1D_FIND_DIR) && !(dirent->mode & BS_IFDIR)) continue; - if ((type & CACHE1D_FIND_FILE) && (dirent->mode & BS_IFDIR)) continue; - if (!Bwildmatch(dirent->name, mask)) continue; - switch (klistaddentry(&rec, dirent->name, - (dirent->mode & BS_IFDIR) ? CACHE1D_FIND_DIR : CACHE1D_FIND_FILE, - stackdepth)) { - case -1: goto failure; - //case 1: initprintf("%s:%s dropped for lower priority\n", d,dirent->name); break; - //case 0: initprintf("%s:%s accepted\n", d,dirent->name); break; - default: break; - } - } - Bclosedir(dir); - } - - if (pathsearchmode) break; - - if (!search) { - search = searchpathhead; - stackdepth = CACHE1D_SOURCE_PATH; - } else { - search = search->next; - stackdepth++; - } - if (search) d = search->path; - } while (search); - } - - if (!pathsearchmode) { // next, zip files - char buf[BMAX_PATH], *p; - int i, j, ftype; - strcpy(buf,path); - if (*path) strcat(buf,"/"); - strcat(buf,mask); - for (kzfindfilestart(buf); kzfindfile(buf); ) { - if (buf[0] != '|') continue; // local files we don't need - - // scan for the end of the string and shift - // everything left a char in the process - for (i=1; (buf[i-1]=buf[i]); i++) ; i-=2; - - // if there's a slash at the end, this is a directory entry - if (toupperlookup[buf[i]] == '/') { ftype = CACHE1D_FIND_DIR; buf[i] = 0; } - else ftype = CACHE1D_FIND_FILE; - - // skip over the common characters at the beginning of the base path and the zip entry - for (j=0; buf[j] && path[j]; j++) { - if (toupperlookup[ path[j] ] == toupperlookup[ buf[j] ]) continue; - break; - } - // we've now hopefully skipped the common path component at the beginning. - // if that's true, we should be staring at a null byte in path and either any character in buf - // if j==0, or a slash if j>0 - if ((!path[0] && buf[j]) || (!path[j] && toupperlookup[ buf[j] ] == '/')) { - if (j>0) j++; - - // yep, so now we shift what follows back to the start of buf and while we do that, - // keep an eye out for any more slashes which would mean this entry has sub-entities - // and is useless to us. - for (i = 0; (buf[i] = buf[j]) && toupperlookup[buf[j]] != '/'; i++,j++) ; - if (toupperlookup[buf[j]] == '/') continue; // damn, try next entry - } else { - // if we're here it means we have a situation where: - // path = foo - // buf = foobar... - // or - // path = foobar - // buf = foo... - // which would mean the entry is higher up in the directory tree and is also useless - continue; - } - - if ((type & CACHE1D_FIND_DIR) && ftype != CACHE1D_FIND_DIR) continue; - if ((type & CACHE1D_FIND_FILE) && ftype != CACHE1D_FIND_FILE) continue; - - // the entry is in the clear - switch (klistaddentry(&rec, buf, ftype, CACHE1D_SOURCE_ZIP)) { - case -1: goto failure; - //case 1: initprintf(":%s dropped for lower priority\n", buf); break; - //case 0: initprintf(":%s accepted\n", buf); break; - default: break; - } - } - } - - // then, grp files - if (!pathsearchmode && !*path && (type & CACHE1D_FIND_FILE)) { - char buf[13]; - int i,j; - buf[12] = 0; - for (i=0;i=0;j--) - { - Bmemcpy(buf,&gfilelist[i][j<<4],12); - if (!Bwildmatch(buf,mask)) continue; - switch (klistaddentry(&rec, buf, CACHE1D_FIND_FILE, CACHE1D_SOURCE_GRP)) { - case -1: goto failure; - //case 1: initprintf(":%s dropped for lower priority\n", workspace); break; - //case 0: initprintf(":%s accepted\n", workspace); break; - default: break; - } - } - } - } - - if (pathsearchmode && (type & CACHE1D_FIND_DRIVE)) { - char *drives, *drp; - drives = Bgetsystemdrives(); - if (drives) { - for (drp=drives; *drp; drp+=strlen(drp)+1) { - if (klistaddentry(&rec, drp, CACHE1D_FIND_DRIVE, CACHE1D_SOURCE_DRIVE) < 0) { - free(drives); - goto failure; - } - } - free(drives); - } - } - - free(path); - return rec; -failure: - free(path); - klistfree(rec); - return NULL; -} - - //Internal LZW variables -#define LZWSIZE 16384 //Watch out for shorts! -static char *lzwbuf1, *lzwbuf4, *lzwbuf5, lzwbuflock[5]; -static short *lzwbuf2, *lzwbuf3; - -static long lzwcompress(char *lzwinbuf, long uncompleng, char *lzwoutbuf); -static long lzwuncompress(char *lzwinbuf, long compleng, char *lzwoutbuf); - -int kdfread(void *buffer, bsize_t dasizeof, bsize_t count, long fil) -{ - unsigned long i, j, k, kgoal; - short leng; - char *ptr; - - lzwbuflock[0] = lzwbuflock[1] = lzwbuflock[2] = lzwbuflock[3] = lzwbuflock[4] = 200; - if (lzwbuf1 == NULL) allocache((long *)&lzwbuf1,LZWSIZE+(LZWSIZE>>4),&lzwbuflock[0]); - if (lzwbuf2 == NULL) allocache((long *)&lzwbuf2,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[1]); - if (lzwbuf3 == NULL) allocache((long *)&lzwbuf3,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[2]); - if (lzwbuf4 == NULL) allocache((long *)&lzwbuf4,LZWSIZE,&lzwbuflock[3]); - if (lzwbuf5 == NULL) allocache((long *)&lzwbuf5,LZWSIZE+(LZWSIZE>>4),&lzwbuflock[4]); - - if (dasizeof > LZWSIZE) { count *= dasizeof; dasizeof = 1; } - ptr = (char *)buffer; - - if (kread(fil,&leng,2) != 2) return -1; leng = B_LITTLE16(leng); - if (kread(fil,lzwbuf5,(long)leng) != leng) return -1; - k = 0; kgoal = lzwuncompress(lzwbuf5,(long)leng,lzwbuf4); - - copybufbyte(lzwbuf4,ptr,(long)dasizeof); - k += (long)dasizeof; - - for(i=1;i= kgoal) - { - if (kread(fil,&leng,2) != 2) return -1; leng = B_LITTLE16(leng); - if (kread(fil,lzwbuf5,(long)leng) != leng) return -1; - k = 0; kgoal = lzwuncompress(lzwbuf5,(long)leng,lzwbuf4); - } - for(j=0;j>4),&lzwbuflock[0]); - if (lzwbuf2 == NULL) allocache((long *)&lzwbuf2,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[1]); - if (lzwbuf3 == NULL) allocache((long *)&lzwbuf3,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[2]); - if (lzwbuf4 == NULL) allocache((long *)&lzwbuf4,LZWSIZE,&lzwbuflock[3]); - if (lzwbuf5 == NULL) allocache((long *)&lzwbuf5,LZWSIZE+(LZWSIZE>>4),&lzwbuflock[4]); - - if (dasizeof > LZWSIZE) { count *= dasizeof; dasizeof = 1; } - ptr = (char *)buffer; - - if (Bfread(&leng,2,1,fil) != 1) return -1; leng = B_LITTLE16(leng); - if (Bfread(lzwbuf5,(long)leng,1,fil) != 1) return -1; - k = 0; kgoal = lzwuncompress(lzwbuf5,(long)leng,lzwbuf4); - - copybufbyte(lzwbuf4,ptr,(long)dasizeof); - k += (long)dasizeof; - - for(i=1;i= kgoal) - { - if (Bfread(&leng,2,1,fil) != 1) return -1; leng = B_LITTLE16(leng); - if (Bfread(lzwbuf5,(long)leng,1,fil) != 1) return -1; - k = 0; kgoal = lzwuncompress(lzwbuf5,(long)leng,lzwbuf4); - } - for(j=0;j>4),&lzwbuflock[0]); - if (lzwbuf2 == NULL) allocache((long *)&lzwbuf2,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[1]); - if (lzwbuf3 == NULL) allocache((long *)&lzwbuf3,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[2]); - if (lzwbuf4 == NULL) allocache((long *)&lzwbuf4,LZWSIZE,&lzwbuflock[3]); - if (lzwbuf5 == NULL) allocache((long *)&lzwbuf5,LZWSIZE+(LZWSIZE>>4),&lzwbuflock[4]); - - if (dasizeof > LZWSIZE) { count *= dasizeof; dasizeof = 1; } - ptr = (char *)buffer; - - copybufbyte(ptr,lzwbuf4,(long)dasizeof); - k = dasizeof; - - if (k > LZWSIZE-dasizeof) - { - leng = (short)lzwcompress(lzwbuf4,k,lzwbuf5); k = 0; swleng = B_LITTLE16(leng); - Bwrite(fil,&swleng,2); Bwrite(fil,lzwbuf5,(long)leng); - } - - for(i=1;i LZWSIZE-dasizeof) - { - leng = (short)lzwcompress(lzwbuf4,k,lzwbuf5); k = 0; swleng = B_LITTLE16(leng); - Bwrite(fil,&swleng,2); Bwrite(fil,lzwbuf5,(long)leng); - } - ptr += dasizeof; - } - if (k > 0) - { - leng = (short)lzwcompress(lzwbuf4,k,lzwbuf5); swleng = B_LITTLE16(leng); - Bwrite(fil,&swleng,2); Bwrite(fil,lzwbuf5,(long)leng); - } - lzwbuflock[0] = lzwbuflock[1] = lzwbuflock[2] = lzwbuflock[3] = lzwbuflock[4] = 1; -} - -void dfwrite(void *buffer, bsize_t dasizeof, bsize_t count, BFILE *fil) -{ - unsigned long i, j, k; - short leng, swleng; - char *ptr; - - lzwbuflock[0] = lzwbuflock[1] = lzwbuflock[2] = lzwbuflock[3] = lzwbuflock[4] = 200; - if (lzwbuf1 == NULL) allocache((long *)&lzwbuf1,LZWSIZE+(LZWSIZE>>4),&lzwbuflock[0]); - if (lzwbuf2 == NULL) allocache((long *)&lzwbuf2,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[1]); - if (lzwbuf3 == NULL) allocache((long *)&lzwbuf3,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[2]); - if (lzwbuf4 == NULL) allocache((long *)&lzwbuf4,LZWSIZE,&lzwbuflock[3]); - if (lzwbuf5 == NULL) allocache((long *)&lzwbuf5,LZWSIZE+(LZWSIZE>>4),&lzwbuflock[4]); - - if (dasizeof > LZWSIZE) { count *= dasizeof; dasizeof = 1; } - ptr = (char *)buffer; - - copybufbyte(ptr,lzwbuf4,(long)dasizeof); - k = dasizeof; - - if (k > LZWSIZE-dasizeof) - { - leng = (short)lzwcompress(lzwbuf4,k,lzwbuf5); k = 0; swleng = B_LITTLE16(leng); - Bfwrite(&swleng,2,1,fil); Bfwrite(lzwbuf5,(long)leng,1,fil); - } - - for(i=1;i LZWSIZE-dasizeof) - { - leng = (short)lzwcompress(lzwbuf4,k,lzwbuf5); k = 0; swleng = B_LITTLE16(leng); - Bfwrite(&swleng,2,1,fil); Bfwrite(lzwbuf5,(long)leng,1,fil); - } - ptr += dasizeof; - } - if (k > 0) - { - leng = (short)lzwcompress(lzwbuf4,k,lzwbuf5); swleng = B_LITTLE16(leng); - Bfwrite(&swleng,2,1,fil); Bfwrite(lzwbuf5,(long)leng,1,fil); - } - lzwbuflock[0] = lzwbuflock[1] = lzwbuflock[2] = lzwbuflock[3] = lzwbuflock[4] = 1; -} - -static long lzwcompress(char *lzwinbuf, long uncompleng, char *lzwoutbuf) -{ - long i, addr, newaddr, addrcnt, zx, *intptr; - long bytecnt1, bitcnt, numbits, oneupnumbits; - short *shortptr; - - for(i=255;i>=0;i--) { lzwbuf1[i] = i; lzwbuf3[i] = (i+1)&255; } - clearbuf(lzwbuf2,256>>1,0xffffffff); - clearbuf(lzwoutbuf,((uncompleng+15)+3)>>2,0L); - - addrcnt = 256; bytecnt1 = 0; bitcnt = (4<<3); - numbits = 8; oneupnumbits = (1<<8); - do - { - addr = lzwinbuf[bytecnt1]; - do - { - bytecnt1++; - if (bytecnt1 == uncompleng) break; - if (lzwbuf2[addr] < 0) {lzwbuf2[addr] = addrcnt; break;} - newaddr = lzwbuf2[addr]; - while (lzwbuf1[newaddr] != lzwinbuf[bytecnt1]) - { - zx = lzwbuf3[newaddr]; - if (zx < 0) {lzwbuf3[newaddr] = addrcnt; break;} - newaddr = zx; - } - if (lzwbuf3[newaddr] == addrcnt) break; - addr = newaddr; - } while (addr >= 0); - lzwbuf1[addrcnt] = lzwinbuf[bytecnt1]; - lzwbuf2[addrcnt] = -1; - lzwbuf3[addrcnt] = -1; - - intptr = (long *)&lzwoutbuf[bitcnt>>3]; - intptr[0] |= B_LITTLE32(addr<<(bitcnt&7)); - bitcnt += numbits; - if ((addr&((oneupnumbits>>1)-1)) > ((addrcnt-1)&((oneupnumbits>>1)-1))) - bitcnt--; - - addrcnt++; - if (addrcnt > oneupnumbits) { numbits++; oneupnumbits <<= 1; } - } while ((bytecnt1 < uncompleng) && (bitcnt < (uncompleng<<3))); - - intptr = (long *)&lzwoutbuf[bitcnt>>3]; - intptr[0] |= B_LITTLE32(addr<<(bitcnt&7)); - bitcnt += numbits; - if ((addr&((oneupnumbits>>1)-1)) > ((addrcnt-1)&((oneupnumbits>>1)-1))) - bitcnt--; - - shortptr = (short *)lzwoutbuf; - shortptr[0] = B_LITTLE16((short)uncompleng); - if (((bitcnt+7)>>3) < uncompleng) - { - shortptr[1] = B_LITTLE16((short)addrcnt); - return((bitcnt+7)>>3); - } - shortptr[1] = (short)0; - for(i=0;i>2); - return((long)B_LITTLE16(shortptr[0])); //uncompleng - } - for(i=255;i>=0;i--) { lzwbuf2[i] = i; lzwbuf3[i] = i; } - currstr = 256; bitcnt = (4<<3); outbytecnt = 0; - numbits = 8; oneupnumbits = (1<<8); - do - { - intptr = (long *)&lzwinbuf[bitcnt>>3]; - dat = ((B_LITTLE32(intptr[0])>>(bitcnt&7)) & (oneupnumbits-1)); - bitcnt += numbits; - if ((dat&((oneupnumbits>>1)-1)) > ((currstr-1)&((oneupnumbits>>1)-1))) - { dat &= ((oneupnumbits>>1)-1); bitcnt--; } - - lzwbuf3[currstr] = dat; - - for(leng=0;dat>=256;leng++,dat=lzwbuf3[dat]) - lzwbuf1[leng] = lzwbuf2[dat]; - - lzwoutbuf[outbytecnt++] = dat; - for(i=leng-1;i>=0;i--) lzwoutbuf[outbytecnt++] = lzwbuf1[i]; - - lzwbuf2[currstr-1] = dat; lzwbuf2[currstr] = dat; - currstr++; - if (currstr > oneupnumbits) { numbits++; oneupnumbits <<= 1; } - } while (currstr < strtot); - return((long)B_LITTLE16(shortptr[0])); //uncompleng -} - -/* - * vim:ts=4:sw=4: - */ +// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman +// Ken Silverman's official web site: "http://www.advsys.net/ken" +// See the included license file "BUILDLIC.TXT" for license info. +// +// This file has been modified from Ken Silverman's original release +// by Jonathon Fowler (jonof@edgenetwk.com) + +#define WITHKPLIB + +#include "compat.h" +#include "cache1d.h" +#include "pragmas.h" +#include "baselayer.h" + +#ifdef WITHKPLIB +#include "kplib.h" + + //Insert '|' in front of filename + //Doing this tells kzopen to load the file only if inside a .ZIP file +static long kzipopen(char *filnam) +{ + unsigned int i; + char newst[BMAX_PATH+4]; + + newst[0] = '|'; + for(i=0;filnam[i] && (i < sizeof(newst)-2);i++) newst[i+1] = filnam[i]; + newst[i+1] = 0; + return(kzopen(newst)); +} + +#endif + + +// This module keeps track of a standard linear cacheing system. +// To use this module, here's all you need to do: +// +// Step 1: Allocate a nice BIG buffer, like from 1MB-4MB and +// Call initcache(long cachestart, long cachesize) where +// +// cachestart = (long)(pointer to start of BIG buffer) +// cachesize = length of BIG buffer +// +// Step 2: Call allocache(long *bufptr, long bufsiz, char *lockptr) +// whenever you need to allocate a buffer, where: +// +// *bufptr = pointer to 4-byte pointer to buffer +// Confused? Using this method, cache2d can remove +// previously allocated things from the cache safely by +// setting the 4-byte pointer to 0. +// bufsiz = number of bytes to allocate +// *lockptr = pointer to locking char which tells whether +// the region can be removed or not. If *lockptr = 0 then +// the region is not locked else its locked. +// +// Step 3: If you need to remove everything from the cache, or every +// unlocked item from the cache, you can call uninitcache(); +// Call uninitcache(0) to remove all unlocked items, or +// Call uninitcache(1) to remove everything. +// After calling uninitcache, it is still ok to call allocache +// without first calling initcache. + +#define MAXCACHEOBJECTS 9216 + +static long cachesize = 0; +long cachecount = 0; +char zerochar = 0; +long cachestart = 0, cacnum = 0, agecount = 0; +typedef struct { long *hand, leng; char *lock; } cactype; +cactype cac[MAXCACHEOBJECTS]; +static long lockrecip[200]; + +static char toupperlookup[256]; + +extern void *kmalloc(size_t); +extern void kfree(void *); + +static void reportandexit(char *errormessage); + +extern char pow2char[8]; + + +void initcache(long dacachestart, long dacachesize) +{ + long i; + + for(i=1;i<200;i++) lockrecip[i] = (1<<28)/(200-i); + + cachestart = dacachestart; + cachesize = dacachesize; + + cac[0].leng = cachesize; + cac[0].lock = &zerochar; + cacnum = 1; + + initprintf("initcache(): Initialised with %d bytes\n", dacachesize); +} + +void allocache(long *newhandle, long newbytes, char *newlockptr) +{ + long i, /*j,*/ z, zz, bestz=0, daval, bestval, besto=0, o1, o2, sucklen, suckz; + + newbytes = ((newbytes+15)&0xfffffff0); + + if ((unsigned)newbytes > (unsigned)cachesize) + { + Bprintf("Cachesize: %ld\n",cachesize); + Bprintf("*Newhandle: 0x%lx, Newbytes: %ld, *Newlock: %d\n",(long)newhandle,newbytes,*newlockptr); + reportandexit("BUFFER TOO BIG TO FIT IN CACHE!"); + } + + if (*newlockptr == 0) + { + reportandexit("ALLOCACHE CALLED WITH LOCK OF 0!"); + } + + //Find best place + bestval = 0x7fffffff; o1 = cachesize; + for(z=cacnum-1;z>=0;z--) + { + o1 -= cac[z].leng; + o2 = o1+newbytes; if (o2 > cachesize) continue; + + daval = 0; + for(i=o1,zz=z;i= 200) { daval = 0x7fffffff; break; } + daval += mulscale32(cac[zz].leng+65536,lockrecip[*cac[zz].lock]); + if (daval >= bestval) break; + } + if (daval < bestval) + { + bestval = daval; besto = o1; bestz = z; + if (bestval == 0) break; + } + } + + //printf("%ld %ld %ld\n",besto,newbytes,*newlockptr); + + if (bestval == 0x7fffffff) + reportandexit("CACHE SPACE ALL LOCKED UP!"); + + //Suck things out + for(sucklen=-newbytes,suckz=bestz;sucklen<0;sucklen+=cac[suckz++].leng) + if (*cac[suckz].lock) *cac[suckz].hand = 0; + + //Remove all blocks except 1 + suckz -= (bestz+1); cacnum -= suckz; + copybufbyte(&cac[bestz+suckz],&cac[bestz],(cacnum-bestz)*sizeof(cactype)); + cac[bestz].hand = newhandle; *newhandle = cachestart+besto; + cac[bestz].leng = newbytes; + cac[bestz].lock = newlockptr; + cachecount++; + + //Add new empty block if necessary + if (sucklen <= 0) return; + + bestz++; + if (bestz == cacnum) + { + cacnum++; if (cacnum > MAXCACHEOBJECTS) reportandexit("Too many objects in cache! (cacnum > MAXCACHEOBJECTS)"); + cac[bestz].leng = sucklen; + cac[bestz].lock = &zerochar; + return; + } + + if (*cac[bestz].lock == 0) { cac[bestz].leng += sucklen; return; } + + cacnum++; if (cacnum > MAXCACHEOBJECTS) reportandexit("Too many objects in cache! (cacnum > MAXCACHEOBJECTS)"); + for(z=cacnum-1;z>bestz;z--) cac[z] = cac[z-1]; + cac[bestz].leng = sucklen; + cac[bestz].lock = &zerochar; +} + +void suckcache(long *suckptr) +{ + long i; + + //Can't exit early, because invalid pointer might be same even though lock = 0 + for(i=0;i 0) && (*cac[i-1].lock == 0)) + { + cac[i-1].leng += cac[i].leng; + cacnum--; copybuf(&cac[i+1],&cac[i],(cacnum-i)*sizeof(cactype)); + } + else if ((i < cacnum-1) && (*cac[i+1].lock == 0)) + { + cac[i+1].leng += cac[i].leng; + cacnum--; copybuf(&cac[i+1],&cac[i],(cacnum-i)*sizeof(cactype)); + } + } +} + +void agecache(void) +{ + long cnt; + char ch; + + if (agecount >= cacnum) agecount = cacnum-1; + if (agecount < 0) return; + for(cnt=(cacnum>>4);cnt>=0;cnt--) + { + ch = (*cac[agecount].lock); + if (((ch-2)&255) < 198) + (*cac[agecount].lock) = ch-1; + + agecount--; if (agecount < 0) agecount = cacnum-1; + } +} + +static void reportandexit(char *errormessage) +{ + long i, j; + + //setvmode(0x3); + j = 0; + for(i=0;i + +typedef struct _searchpath { + struct _searchpath *next; + char *path; + size_t pathlen; // to save repeated calls to strlen() +} searchpath_t; +static searchpath_t *searchpathhead = NULL; +static size_t maxsearchpathlen = 0; +int pathsearchmode = 0; + +int addsearchpath(const char *p) +{ + struct stat st; + char *s; + searchpath_t *srch; + int i; + + if (Bstat(p, &st) < 0) { + if (errno == ENOENT) return -2; + return -1; + } + if (!(st.st_mode & BS_IFDIR)) return -1; + + srch = (searchpath_t*)malloc(sizeof(searchpath_t)); + if (!srch) return -1; + + srch->next = searchpathhead; + srch->pathlen = strlen(p)+1; + srch->path = (char*)malloc(srch->pathlen + 1); + if (!srch->path) { + free(srch); + return -1; + } + strcpy(srch->path, p); + for (s=srch->path; *s; s++) ; s--; if (spath || toupperlookup[*s] != '/') strcat(srch->path, "/"); + + searchpathhead = srch; + if (srch->pathlen > maxsearchpathlen) maxsearchpathlen = srch->pathlen; + initprintf("addsearchpath(): Added %s\n", srch->path); + + return 0; +} + +int findfrompath(const char *fn, char **where) +{ + searchpath_t *sp; + char *pfn, *ffn; + int allocsiz; + + // pathsearchmode == 0: tests current dir and then the dirs of the path stack + // pathsearchmode == 1: tests fn without modification, then like for pathsearchmode == 0 + + if (pathsearchmode) { + // test unmolested filename first + if (access(fn, F_OK) >= 0) { + *where = strdup(fn); + return 0; + } + } + + for (pfn = (char*)fn; toupperlookup[*pfn] == '/'; pfn++); + ffn = strdup(pfn); + if (!ffn) return -1; + Bcorrectfilename(ffn,0); // compress relative paths + + allocsiz = max(maxsearchpathlen, 2); // "./" (aka. curdir) + allocsiz += strlen(ffn); + allocsiz += 1; // a nul + + pfn = (char *)malloc(allocsiz); + if (!pfn) { free(ffn); return -1; } + + strcpy(pfn, "./"); + strcat(pfn, ffn); + if (access(pfn, F_OK) >= 0) { + *where = pfn; + free(ffn); + return 0; + } + + for (sp = searchpathhead; sp; sp = sp->next) { + strcpy(pfn, sp->path); + strcat(pfn, ffn); + //initprintf("Trying %s\n", pfn); + if (access(pfn, F_OK) >= 0) { + *where = pfn; + free(ffn); + return 0; + } + } + free(pfn); free(ffn); + return -1; +} + +int openfrompath(const char *fn, int flags, int mode) +{ + char *pfn; + int h; + + if (findfrompath(fn, &pfn) < 0) return -1; + h = Bopen(pfn, flags, mode); + free(pfn); + + return h; +} + +BFILE* fopenfrompath(const char *fn, const char *mode) +{ + int fh; + BFILE *h; + int bmode = 0, smode = 0; + const char *c; + + for (c=mode; c[0]; ) { + if (c[0] == 'r' && c[1] == '+') { bmode = BO_RDWR; smode = BS_IREAD|BS_IWRITE; c+=2; } + else if (c[0] == 'r') { bmode = BO_RDONLY; smode = BS_IREAD; c+=1; } + else if (c[0] == 'w' && c[1] == '+') { bmode = BO_RDWR|BO_CREAT|BO_TRUNC; smode = BS_IREAD|BS_IWRITE; c+=2; } + else if (c[0] == 'w') { bmode = BO_WRONLY|BO_CREAT|BO_TRUNC; smode = BS_IREAD|BS_IWRITE; c+=2; } + else if (c[0] == 'a' && c[1] == '+') { bmode = BO_RDWR|BO_CREAT; smode=BS_IREAD|BS_IWRITE; c+=2; } + else if (c[0] == 'a') { bmode = BO_WRONLY|BO_CREAT; smode=BS_IREAD|BS_IWRITE; c+=1; } + else if (c[0] == 'b') { bmode |= BO_BINARY; c+=1; } + else if (c[1] == 't') { bmode |= BO_TEXT; c+=1; } + else c++; + } + fh = openfrompath(fn,bmode,smode); + if (fh < 0) return NULL; + + h = fdopen(fh,mode); + if (!h) close(fh); + + return h; +} + + +#define MAXGROUPFILES 4 //Warning: Fix groupfil if this is changed +#define MAXOPENFILES 64 //Warning: Fix filehan if this is changed + +static char toupperlookup[256] = +{ + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, + 0x60,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x7b,0x7c,0x7d,0x7e,0x7f, + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, + 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf, + 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, + 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf, + 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf, + 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef, + 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff +}; + +static long numgroupfiles = 0; +static long gnumfiles[MAXGROUPFILES]; +static long groupfil[MAXGROUPFILES] = {-1,-1,-1,-1}; +static long groupfilpos[MAXGROUPFILES]; +static char *gfilelist[MAXGROUPFILES]; +static long *gfileoffs[MAXGROUPFILES]; + +static char filegrp[MAXOPENFILES]; +static long filepos[MAXOPENFILES]; +static long filehan[MAXOPENFILES] = +{ + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 +}; +#ifdef WITHKPLIB +static char filenamsav[MAXOPENFILES][260]; +static long kzcurhand = -1; +#endif + +long initgroupfile(char *filename) +{ + char buf[16]; + long i, j, k; +#ifdef WITHKPLIB + char *zfn; + searchpath_t *sp = NULL; +#endif + +#ifdef _WIN32 + // on Windows, translate all backslashes (0x5c) to forward slashes (0x2f) + toupperlookup[0x5c] = 0x2f; +#endif + +#ifdef WITHKPLIB + if (findfrompath(filename, &zfn) < 0) return -1; + + // check to see if the file passed is a ZIP and pass it on to kplib if it is + i = Bopen(zfn,BO_BINARY|BO_RDONLY,BS_IREAD); + if (i < 0) { free(zfn); return -1; } + + Bread(i, buf, 4); + if (buf[0] == 0x50 && buf[1] == 0x4B && buf[2] == 0x03 && buf[3] == 0x04) { + Bclose(i); + j = kzaddstack(zfn); + free(zfn); + return j; + } + free(zfn); + + if (numgroupfiles >= MAXGROUPFILES) return(-1); + + Blseek(i,0,BSEEK_SET); + groupfil[numgroupfiles] = i; +#else + groupfil[numgroupfiles] = openfrompath(filename,BO_BINARY|BO_RDONLY,BS_IREAD); + if (groupfil[numgroupfiles] != -1) +#endif + { + groupfilpos[numgroupfiles] = 0; + Bread(groupfil[numgroupfiles],buf,16); + if ((buf[0] != 'K') || (buf[1] != 'e') || (buf[2] != 'n') || + (buf[3] != 'S') || (buf[4] != 'i') || (buf[5] != 'l') || + (buf[6] != 'v') || (buf[7] != 'e') || (buf[8] != 'r') || + (buf[9] != 'm') || (buf[10] != 'a') || (buf[11] != 'n')) + { + Bclose(groupfil[numgroupfiles]); + groupfil[numgroupfiles] = -1; + return(-1); + } + gnumfiles[numgroupfiles] = B_LITTLE32(*((long *)&buf[12])); + + if ((gfilelist[numgroupfiles] = (char *)kmalloc(gnumfiles[numgroupfiles]<<4)) == 0) + { Bprintf("Not enough memory for file grouping system\n"); exit(0); } + if ((gfileoffs[numgroupfiles] = (long *)kmalloc((gnumfiles[numgroupfiles]+1)<<2)) == 0) + { Bprintf("Not enough memory for file grouping system\n"); exit(0); } + + Bread(groupfil[numgroupfiles],gfilelist[numgroupfiles],gnumfiles[numgroupfiles]<<4); + + j = 0; + for(i=0;i=0;i--) + if (groupfil[i] != -1 && groupfil[i] == grphandle) + { + kfree(gfilelist[i]); + kfree(gfileoffs[i]); + Bclose(groupfil[i]); + groupfil[i] = -1; + grpnum = i; + break; + } + + if (grpnum == -1) return; + + // JBF 20040111 + numgroupfiles--; + + // move any group files following this one back + for (i=grpnum+1; i= 254) // external file (255) or ZIPped file (254) + continue; + else if (filegrp[i] == grpnum) // close file in group we closed + filehan[i] = -1; + else if (filegrp[i] > grpnum) // move back a file in a group after the one we closed + filegrp[i]--; + } +} + +void uninitgroupfile(void) +{ + long i; + + for(i=numgroupfiles-1;i>=0;i--) + if (groupfil[i] != -1) + { + kfree(gfilelist[i]); + kfree(gfileoffs[i]); + Bclose(groupfil[i]); + groupfil[i] = -1; + } + numgroupfiles = 0; + + // JBF 20040111: "close" any files open in groups + for(i=0;i= 0) + { + filegrp[newhandle] = 255; + filehan[newhandle] = fil; + filepos[newhandle] = 0; + return(newhandle); + } + + for (; toupperlookup[*filename] == '/'; filename++); + +#ifdef WITHKPLIB + if ((kzcurhand != newhandle) && (kztell() >= 0)) + { + if (kzcurhand >= 0) filepos[kzcurhand] = kztell(); + kzclose(); + } + if (searchfirst != 1 && (i = kzipopen(filename)) != 0) { + kzcurhand = newhandle; + filegrp[newhandle] = 254; + filehan[newhandle] = i; + filepos[newhandle] = 0; + strcpy(filenamsav[newhandle],filename); + return newhandle; + } +#endif + + for(k=numgroupfiles-1;k>=0;k--) + { + if (searchfirst == 1) k = 0; + if (groupfil[k] >= 0) + { + for(i=gnumfiles[k]-1;i>=0;i--) + { + gfileptr = (char *)&gfilelist[k][i<<4]; + + bad = 0; + for(j=0;j<13;j++) + { + if (!filename[j]) break; + if (toupperlookup[filename[j]] != toupperlookup[gfileptr[j]]) + { bad = 1; break; } + } + if (bad) continue; + if (j<13 && gfileptr[j]) continue; // JBF: because e1l1.map might exist before e1l1 + if (j==13 && filename[j]) continue; // JBF: long file name + + filegrp[newhandle] = k; + filehan[newhandle] = i; + filepos[newhandle] = 0; + return(newhandle); + } + } + } + return(-1); +} + +long kread(long handle, void *buffer, long leng) +{ + long i, filenum, groupnum; + + filenum = filehan[handle]; + groupnum = filegrp[handle]; + if (groupnum == 255) return(Bread(filenum,buffer,leng)); +#ifdef WITHKPLIB + else if (groupnum == 254) + { + if (kzcurhand != handle) + { + if (kztell() >= 0) { filepos[kzcurhand] = kztell(); kzclose(); } + kzcurhand = handle; + kzipopen(filenamsav[handle]); + kzseek(filepos[handle],SEEK_SET); + } + return(kzread(buffer,leng)); + } +#endif + + if (groupfil[groupnum] != -1) + { + i = gfileoffs[groupnum][filenum]+filepos[handle]; + if (i != groupfilpos[groupnum]) + { + Blseek(groupfil[groupnum],i+((gnumfiles[groupnum]+1)<<4),BSEEK_SET); + groupfilpos[groupnum] = i; + } + leng = min(leng,(gfileoffs[groupnum][filenum+1]-gfileoffs[groupnum][filenum])-filepos[handle]); + leng = Bread(groupfil[groupnum],buffer,leng); + filepos[handle] += leng; + groupfilpos[groupnum] += leng; + return(leng); + } + + return(0); +} + +long klseek(long handle, long offset, long whence) +{ + long i, groupnum; + + groupnum = filegrp[handle]; + + if (groupnum == 255) return(Blseek(filehan[handle],offset,whence)); +#ifdef WITHKPLIB + else if (groupnum == 254) + { + if (kzcurhand != handle) + { + if (kztell() >= 0) { filepos[kzcurhand] = kztell(); kzclose(); } + kzcurhand = handle; + kzipopen(filenamsav[handle]); + kzseek(filepos[handle],SEEK_SET); + } + return(kzseek(offset,whence)); + } +#endif + + if (groupfil[groupnum] != -1) + { + switch(whence) + { + case BSEEK_SET: filepos[handle] = offset; break; + case BSEEK_END: i = filehan[handle]; + filepos[handle] = (gfileoffs[groupnum][i+1]-gfileoffs[groupnum][i])+offset; + break; + case BSEEK_CUR: filepos[handle] += offset; break; + } + return(filepos[handle]); + } + return(-1); +} + +long kfilelength(long handle) +{ + long i, groupnum; + + groupnum = filegrp[handle]; + if (groupnum == 255) { + // return(filelength(filehan[handle])) + return Bfilelength(filehan[handle]); + } +#ifdef WITHKPLIB + else if (groupnum == 254) + { + if (kzcurhand != handle) + { + if (kztell() >= 0) { filepos[kzcurhand] = kztell(); kzclose(); } + kzcurhand = handle; + kzipopen(filenamsav[handle]); + kzseek(filepos[handle],SEEK_SET); + } + return kzfilelength(); + } +#endif + i = filehan[handle]; + return(gfileoffs[groupnum][i+1]-gfileoffs[groupnum][i]); +} + +long ktell(long handle) +{ + long i, groupnum; + + groupnum = filegrp[handle]; + + if (groupnum == 255) return(Blseek(filehan[handle],0,BSEEK_CUR)); +#ifdef WITHKPLIB + else if (groupnum == 254) + { + if (kzcurhand != handle) + { + if (kztell() >= 0) { filepos[kzcurhand] = kztell(); kzclose(); } + kzcurhand = handle; + kzipopen(filenamsav[handle]); + kzseek(filepos[handle],SEEK_SET); + } + return kztell(); + } +#endif + if (groupfil[groupnum] != -1) + return filepos[handle]; + return(-1); +} + +void kclose(long handle) +{ + if (handle < 0) return; + if (filegrp[handle] == 255) Bclose(filehan[handle]); +#ifdef WITHKPLIB + else if (filegrp[handle] == 254) + { + kzclose(); + kzcurhand = -1; + } +#endif + filehan[handle] = -1; +} + +static int klistaddentry(CACHE1D_FIND_REC **rec, char *name, int type, int source) +{ + CACHE1D_FIND_REC *r = NULL, *attach = NULL; + + if (*rec) { + int insensitive, v; + CACHE1D_FIND_REC *last = NULL; + + for (attach = *rec; attach; last = attach, attach = attach->next) { + if (type == CACHE1D_FIND_DRIVE) continue; // we just want to get to the end for drives +#ifdef _WIN32 + insensitive = 1; +#else + if (source == CACHE1D_SOURCE_GRP || attach->source == CACHE1D_SOURCE_GRP) + insensitive = 1; + else if (source == CACHE1D_SOURCE_ZIP || attach->source == CACHE1D_SOURCE_ZIP) + insensitive = 1; + else + insensitive = 0; +#endif + if (insensitive) v = Bstrcasecmp(name, attach->name); + else v = Bstrcmp(name, attach->name); + + // sorted list + if (v > 0) continue; // item to add is bigger than the current one + // so look for something bigger than us + if (v < 0) { // item to add is smaller than the current one + attach = NULL; // so wedge it between the current item and the one before + break; + } + + // matched + if (source >= attach->source) return 1; // item to add is of lower priority + r = attach; + break; + } + + // wasn't found in the list, so attach to the end + if (!attach) attach = last; + } + + if (r) { + r->type = type; + r->source = source; + return 0; + } + + r = (CACHE1D_FIND_REC *)malloc(sizeof(CACHE1D_FIND_REC)+strlen(name)+1); + if (!r) return -1; + r->name = (char*)r + sizeof(CACHE1D_FIND_REC); strcpy(r->name, name); + r->type = type; + r->source = source; + r->usera = r->userb = NULL; + + if (!attach) { // we are the first item + r->prev = NULL; + r->next = *rec; + if (*rec) (*rec)->prev = r; + *rec = r; + } else { + r->prev = attach; + r->next = attach->next; + if (attach->next) attach->next->prev = r; + attach->next = r; + } + + return 0; +} + +void klistfree(CACHE1D_FIND_REC *rec) +{ + CACHE1D_FIND_REC *n; + + while (rec) { + n = rec->next; + free(rec); + rec = n; + } +} + +CACHE1D_FIND_REC *klistpath(const char *_path, const char *mask, int type) +{ + CACHE1D_FIND_REC *rec = NULL; + char *path; + + // pathsearchmode == 0: enumerates a path in the virtual filesystem + // pathsearchmode == 1: enumerates the system filesystem path passed in + + path = strdup(_path); + if (!path) return NULL; + + // we don't need any leading dots and slashes or trailing slashes either + { + int i,j; + for (i=0; path[i] == '.' || toupperlookup[path[i]] == '/'; ) i++; + for (j=0; (path[j] = path[i]); j++,i++) ; + while (j>0 && toupperlookup[path[j-1]] == '/') j--; + path[j] = 0; + //initprintf("Cleaned up path = \"%s\"\n",path); + } + + if (*path && (type & CACHE1D_FIND_DIR)) { + if (klistaddentry(&rec, "..", CACHE1D_FIND_DIR, CACHE1D_SOURCE_CURDIR) < 0) goto failure; + } + + if (!(type & CACHE1D_OPT_NOSTACK)) { // current directory and paths in the search stack + searchpath_t *search = NULL; + BDIR *dir; + struct Bdirent *dirent; + const char *d = "."; + int stackdepth = CACHE1D_SOURCE_CURDIR; + char buf[BMAX_PATH]; + + if (pathsearchmode) d = _path; + + do { + if (!pathsearchmode) { + strcpy(buf, path); + if (*path) strcat(buf, "/"); + strcat(buf, d); + } else strcpy(buf, d); + dir = Bopendir(buf); + if (dir) { + while ((dirent = Breaddir(dir))) { + if ((dirent->name[0] == '.' && dirent->name[1] == 0) || + (dirent->name[0] == '.' && dirent->name[1] == '.' && dirent->name[2] == 0)) + continue; + if ((type & CACHE1D_FIND_DIR) && !(dirent->mode & BS_IFDIR)) continue; + if ((type & CACHE1D_FIND_FILE) && (dirent->mode & BS_IFDIR)) continue; + if (!Bwildmatch(dirent->name, mask)) continue; + switch (klistaddentry(&rec, dirent->name, + (dirent->mode & BS_IFDIR) ? CACHE1D_FIND_DIR : CACHE1D_FIND_FILE, + stackdepth)) { + case -1: goto failure; + //case 1: initprintf("%s:%s dropped for lower priority\n", d,dirent->name); break; + //case 0: initprintf("%s:%s accepted\n", d,dirent->name); break; + default: break; + } + } + Bclosedir(dir); + } + + if (pathsearchmode) break; + + if (!search) { + search = searchpathhead; + stackdepth = CACHE1D_SOURCE_PATH; + } else { + search = search->next; + stackdepth++; + } + if (search) d = search->path; + } while (search); + } + + if (!pathsearchmode) { // next, zip files + char buf[BMAX_PATH], *p; + int i, j, ftype; + strcpy(buf,path); + if (*path) strcat(buf,"/"); + strcat(buf,mask); + for (kzfindfilestart(buf); kzfindfile(buf); ) { + if (buf[0] != '|') continue; // local files we don't need + + // scan for the end of the string and shift + // everything left a char in the process + for (i=1; (buf[i-1]=buf[i]); i++) ; i-=2; + + // if there's a slash at the end, this is a directory entry + if (toupperlookup[buf[i]] == '/') { ftype = CACHE1D_FIND_DIR; buf[i] = 0; } + else ftype = CACHE1D_FIND_FILE; + + // skip over the common characters at the beginning of the base path and the zip entry + for (j=0; buf[j] && path[j]; j++) { + if (toupperlookup[ path[j] ] == toupperlookup[ buf[j] ]) continue; + break; + } + // we've now hopefully skipped the common path component at the beginning. + // if that's true, we should be staring at a null byte in path and either any character in buf + // if j==0, or a slash if j>0 + if ((!path[0] && buf[j]) || (!path[j] && toupperlookup[ buf[j] ] == '/')) { + if (j>0) j++; + + // yep, so now we shift what follows back to the start of buf and while we do that, + // keep an eye out for any more slashes which would mean this entry has sub-entities + // and is useless to us. + for (i = 0; (buf[i] = buf[j]) && toupperlookup[buf[j]] != '/'; i++,j++) ; + if (toupperlookup[buf[j]] == '/') continue; // damn, try next entry + } else { + // if we're here it means we have a situation where: + // path = foo + // buf = foobar... + // or + // path = foobar + // buf = foo... + // which would mean the entry is higher up in the directory tree and is also useless + continue; + } + + if ((type & CACHE1D_FIND_DIR) && ftype != CACHE1D_FIND_DIR) continue; + if ((type & CACHE1D_FIND_FILE) && ftype != CACHE1D_FIND_FILE) continue; + + // the entry is in the clear + switch (klistaddentry(&rec, buf, ftype, CACHE1D_SOURCE_ZIP)) { + case -1: goto failure; + //case 1: initprintf(":%s dropped for lower priority\n", buf); break; + //case 0: initprintf(":%s accepted\n", buf); break; + default: break; + } + } + } + + // then, grp files + if (!pathsearchmode && !*path && (type & CACHE1D_FIND_FILE)) { + char buf[13]; + int i,j; + buf[12] = 0; + for (i=0;i=0;j--) + { + Bmemcpy(buf,&gfilelist[i][j<<4],12); + if (!Bwildmatch(buf,mask)) continue; + switch (klistaddentry(&rec, buf, CACHE1D_FIND_FILE, CACHE1D_SOURCE_GRP)) { + case -1: goto failure; + //case 1: initprintf(":%s dropped for lower priority\n", workspace); break; + //case 0: initprintf(":%s accepted\n", workspace); break; + default: break; + } + } + } + } + + if (pathsearchmode && (type & CACHE1D_FIND_DRIVE)) { + char *drives, *drp; + drives = Bgetsystemdrives(); + if (drives) { + for (drp=drives; *drp; drp+=strlen(drp)+1) { + if (klistaddentry(&rec, drp, CACHE1D_FIND_DRIVE, CACHE1D_SOURCE_DRIVE) < 0) { + free(drives); + goto failure; + } + } + free(drives); + } + } + + free(path); + return rec; +failure: + free(path); + klistfree(rec); + return NULL; +} + + //Internal LZW variables +#define LZWSIZE 16384 //Watch out for shorts! +static char *lzwbuf1, *lzwbuf4, *lzwbuf5, lzwbuflock[5]; +static short *lzwbuf2, *lzwbuf3; + +static long lzwcompress(char *lzwinbuf, long uncompleng, char *lzwoutbuf); +static long lzwuncompress(char *lzwinbuf, long compleng, char *lzwoutbuf); + +int kdfread(void *buffer, bsize_t dasizeof, bsize_t count, long fil) +{ + unsigned long i, j, k, kgoal; + short leng; + char *ptr; + + lzwbuflock[0] = lzwbuflock[1] = lzwbuflock[2] = lzwbuflock[3] = lzwbuflock[4] = 200; + if (lzwbuf1 == NULL) allocache((long *)&lzwbuf1,LZWSIZE+(LZWSIZE>>4),&lzwbuflock[0]); + if (lzwbuf2 == NULL) allocache((long *)&lzwbuf2,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[1]); + if (lzwbuf3 == NULL) allocache((long *)&lzwbuf3,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[2]); + if (lzwbuf4 == NULL) allocache((long *)&lzwbuf4,LZWSIZE,&lzwbuflock[3]); + if (lzwbuf5 == NULL) allocache((long *)&lzwbuf5,LZWSIZE+(LZWSIZE>>4),&lzwbuflock[4]); + + if (dasizeof > LZWSIZE) { count *= dasizeof; dasizeof = 1; } + ptr = (char *)buffer; + + if (kread(fil,&leng,2) != 2) return -1; leng = B_LITTLE16(leng); + if (kread(fil,lzwbuf5,(long)leng) != leng) return -1; + k = 0; kgoal = lzwuncompress(lzwbuf5,(long)leng,lzwbuf4); + + copybufbyte(lzwbuf4,ptr,(long)dasizeof); + k += (long)dasizeof; + + for(i=1;i= kgoal) + { + if (kread(fil,&leng,2) != 2) return -1; leng = B_LITTLE16(leng); + if (kread(fil,lzwbuf5,(long)leng) != leng) return -1; + k = 0; kgoal = lzwuncompress(lzwbuf5,(long)leng,lzwbuf4); + } + for(j=0;j>4),&lzwbuflock[0]); + if (lzwbuf2 == NULL) allocache((long *)&lzwbuf2,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[1]); + if (lzwbuf3 == NULL) allocache((long *)&lzwbuf3,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[2]); + if (lzwbuf4 == NULL) allocache((long *)&lzwbuf4,LZWSIZE,&lzwbuflock[3]); + if (lzwbuf5 == NULL) allocache((long *)&lzwbuf5,LZWSIZE+(LZWSIZE>>4),&lzwbuflock[4]); + + if (dasizeof > LZWSIZE) { count *= dasizeof; dasizeof = 1; } + ptr = (char *)buffer; + + if (Bfread(&leng,2,1,fil) != 1) return -1; leng = B_LITTLE16(leng); + if (Bfread(lzwbuf5,(long)leng,1,fil) != 1) return -1; + k = 0; kgoal = lzwuncompress(lzwbuf5,(long)leng,lzwbuf4); + + copybufbyte(lzwbuf4,ptr,(long)dasizeof); + k += (long)dasizeof; + + for(i=1;i= kgoal) + { + if (Bfread(&leng,2,1,fil) != 1) return -1; leng = B_LITTLE16(leng); + if (Bfread(lzwbuf5,(long)leng,1,fil) != 1) return -1; + k = 0; kgoal = lzwuncompress(lzwbuf5,(long)leng,lzwbuf4); + } + for(j=0;j>4),&lzwbuflock[0]); + if (lzwbuf2 == NULL) allocache((long *)&lzwbuf2,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[1]); + if (lzwbuf3 == NULL) allocache((long *)&lzwbuf3,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[2]); + if (lzwbuf4 == NULL) allocache((long *)&lzwbuf4,LZWSIZE,&lzwbuflock[3]); + if (lzwbuf5 == NULL) allocache((long *)&lzwbuf5,LZWSIZE+(LZWSIZE>>4),&lzwbuflock[4]); + + if (dasizeof > LZWSIZE) { count *= dasizeof; dasizeof = 1; } + ptr = (char *)buffer; + + copybufbyte(ptr,lzwbuf4,(long)dasizeof); + k = dasizeof; + + if (k > LZWSIZE-dasizeof) + { + leng = (short)lzwcompress(lzwbuf4,k,lzwbuf5); k = 0; swleng = B_LITTLE16(leng); + Bwrite(fil,&swleng,2); Bwrite(fil,lzwbuf5,(long)leng); + } + + for(i=1;i LZWSIZE-dasizeof) + { + leng = (short)lzwcompress(lzwbuf4,k,lzwbuf5); k = 0; swleng = B_LITTLE16(leng); + Bwrite(fil,&swleng,2); Bwrite(fil,lzwbuf5,(long)leng); + } + ptr += dasizeof; + } + if (k > 0) + { + leng = (short)lzwcompress(lzwbuf4,k,lzwbuf5); swleng = B_LITTLE16(leng); + Bwrite(fil,&swleng,2); Bwrite(fil,lzwbuf5,(long)leng); + } + lzwbuflock[0] = lzwbuflock[1] = lzwbuflock[2] = lzwbuflock[3] = lzwbuflock[4] = 1; +} + +void dfwrite(void *buffer, bsize_t dasizeof, bsize_t count, BFILE *fil) +{ + unsigned long i, j, k; + short leng, swleng; + char *ptr; + + lzwbuflock[0] = lzwbuflock[1] = lzwbuflock[2] = lzwbuflock[3] = lzwbuflock[4] = 200; + if (lzwbuf1 == NULL) allocache((long *)&lzwbuf1,LZWSIZE+(LZWSIZE>>4),&lzwbuflock[0]); + if (lzwbuf2 == NULL) allocache((long *)&lzwbuf2,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[1]); + if (lzwbuf3 == NULL) allocache((long *)&lzwbuf3,(LZWSIZE+(LZWSIZE>>4))*2,&lzwbuflock[2]); + if (lzwbuf4 == NULL) allocache((long *)&lzwbuf4,LZWSIZE,&lzwbuflock[3]); + if (lzwbuf5 == NULL) allocache((long *)&lzwbuf5,LZWSIZE+(LZWSIZE>>4),&lzwbuflock[4]); + + if (dasizeof > LZWSIZE) { count *= dasizeof; dasizeof = 1; } + ptr = (char *)buffer; + + copybufbyte(ptr,lzwbuf4,(long)dasizeof); + k = dasizeof; + + if (k > LZWSIZE-dasizeof) + { + leng = (short)lzwcompress(lzwbuf4,k,lzwbuf5); k = 0; swleng = B_LITTLE16(leng); + Bfwrite(&swleng,2,1,fil); Bfwrite(lzwbuf5,(long)leng,1,fil); + } + + for(i=1;i LZWSIZE-dasizeof) + { + leng = (short)lzwcompress(lzwbuf4,k,lzwbuf5); k = 0; swleng = B_LITTLE16(leng); + Bfwrite(&swleng,2,1,fil); Bfwrite(lzwbuf5,(long)leng,1,fil); + } + ptr += dasizeof; + } + if (k > 0) + { + leng = (short)lzwcompress(lzwbuf4,k,lzwbuf5); swleng = B_LITTLE16(leng); + Bfwrite(&swleng,2,1,fil); Bfwrite(lzwbuf5,(long)leng,1,fil); + } + lzwbuflock[0] = lzwbuflock[1] = lzwbuflock[2] = lzwbuflock[3] = lzwbuflock[4] = 1; +} + +static long lzwcompress(char *lzwinbuf, long uncompleng, char *lzwoutbuf) +{ + long i, addr, newaddr, addrcnt, zx, *intptr; + long bytecnt1, bitcnt, numbits, oneupnumbits; + short *shortptr; + + for(i=255;i>=0;i--) { lzwbuf1[i] = i; lzwbuf3[i] = (i+1)&255; } + clearbuf(lzwbuf2,256>>1,0xffffffff); + clearbuf(lzwoutbuf,((uncompleng+15)+3)>>2,0L); + + addrcnt = 256; bytecnt1 = 0; bitcnt = (4<<3); + numbits = 8; oneupnumbits = (1<<8); + do + { + addr = lzwinbuf[bytecnt1]; + do + { + bytecnt1++; + if (bytecnt1 == uncompleng) break; + if (lzwbuf2[addr] < 0) {lzwbuf2[addr] = addrcnt; break;} + newaddr = lzwbuf2[addr]; + while (lzwbuf1[newaddr] != lzwinbuf[bytecnt1]) + { + zx = lzwbuf3[newaddr]; + if (zx < 0) {lzwbuf3[newaddr] = addrcnt; break;} + newaddr = zx; + } + if (lzwbuf3[newaddr] == addrcnt) break; + addr = newaddr; + } while (addr >= 0); + lzwbuf1[addrcnt] = lzwinbuf[bytecnt1]; + lzwbuf2[addrcnt] = -1; + lzwbuf3[addrcnt] = -1; + + intptr = (long *)&lzwoutbuf[bitcnt>>3]; + intptr[0] |= B_LITTLE32(addr<<(bitcnt&7)); + bitcnt += numbits; + if ((addr&((oneupnumbits>>1)-1)) > ((addrcnt-1)&((oneupnumbits>>1)-1))) + bitcnt--; + + addrcnt++; + if (addrcnt > oneupnumbits) { numbits++; oneupnumbits <<= 1; } + } while ((bytecnt1 < uncompleng) && (bitcnt < (uncompleng<<3))); + + intptr = (long *)&lzwoutbuf[bitcnt>>3]; + intptr[0] |= B_LITTLE32(addr<<(bitcnt&7)); + bitcnt += numbits; + if ((addr&((oneupnumbits>>1)-1)) > ((addrcnt-1)&((oneupnumbits>>1)-1))) + bitcnt--; + + shortptr = (short *)lzwoutbuf; + shortptr[0] = B_LITTLE16((short)uncompleng); + if (((bitcnt+7)>>3) < uncompleng) + { + shortptr[1] = B_LITTLE16((short)addrcnt); + return((bitcnt+7)>>3); + } + shortptr[1] = (short)0; + for(i=0;i>2); + return((long)B_LITTLE16(shortptr[0])); //uncompleng + } + for(i=255;i>=0;i--) { lzwbuf2[i] = i; lzwbuf3[i] = i; } + currstr = 256; bitcnt = (4<<3); outbytecnt = 0; + numbits = 8; oneupnumbits = (1<<8); + do + { + intptr = (long *)&lzwinbuf[bitcnt>>3]; + dat = ((B_LITTLE32(intptr[0])>>(bitcnt&7)) & (oneupnumbits-1)); + bitcnt += numbits; + if ((dat&((oneupnumbits>>1)-1)) > ((currstr-1)&((oneupnumbits>>1)-1))) + { dat &= ((oneupnumbits>>1)-1); bitcnt--; } + + lzwbuf3[currstr] = dat; + + for(leng=0;dat>=256;leng++,dat=lzwbuf3[dat]) + lzwbuf1[leng] = lzwbuf2[dat]; + + lzwoutbuf[outbytecnt++] = dat; + for(i=leng-1;i>=0;i--) lzwoutbuf[outbytecnt++] = lzwbuf1[i]; + + lzwbuf2[currstr-1] = dat; lzwbuf2[currstr] = dat; + currstr++; + if (currstr > oneupnumbits) { numbits++; oneupnumbits <<= 1; } + } while (currstr < strtot); + return((long)B_LITTLE16(shortptr[0])); //uncompleng +} + +/* + * vim:ts=4:sw=4: + */ diff --git a/polymer/build/src/compat.c b/polymer/build/src/compat.c index 0b9454d4d..d8341fe43 100644 --- a/polymer/build/src/compat.c +++ b/polymer/build/src/compat.c @@ -1,716 +1,716 @@ -/* - * Playing-field leveller for Build - * by Jonathon Fowler - * - * A note about this: - * 1. There is some kind of problem somewhere in the functions below because - * compiling with __compat_h_macrodef__ disabled makes stupid things happen. - * 2. The functions below, aside from the ones which aren't trivial, were never - * really intended to be used for anything except tracking anr removing ties - * to the standard C library from games. Using the Bxx versions of functions - * means we can redefine those names to link up with different runtime library - * names. - */ - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#define _WIN32_IE 0x0400 -#include -#include -#endif - -#include -#include -#include -#include -#include -#include - -#if defined(__WATCOMC__) -# include -#elif defined(_MSC_VER) -# include -#else -# include -#endif - -#include "compat.h" - - -#ifndef __compat_h_macrodef__ - -int Brand(void) -{ - return rand(); -} - -void *Bmalloc(bsize_t size) -{ - return malloc(size); -} - -void Bfree(void *ptr) -{ - free(ptr); -} - -int Bopen(const char *pathname, int flags, unsigned mode) -{ - int n=0,o=0; - - if (flags&BO_BINARY) n|=O_BINARY; else n|=O_TEXT; - if ((flags&BO_RDWR)==BO_RDWR) n|=O_RDWR; - else if ((flags&BO_RDWR)==BO_WRONLY) n|=O_WRONLY; - else if ((flags&BO_RDWR)==BO_RDONLY) n|=O_RDONLY; - if (flags&BO_APPEND) n|=O_APPEND; - if (flags&BO_CREAT) n|=O_CREAT; - if (flags&BO_TRUNC) n|=O_TRUNC; - if (mode&BS_IREAD) o|=S_IREAD; - if (mode&BS_IWRITE) o|=S_IWRITE; - if (mode&BS_IEXEC) o|=S_IEXEC; - - return open(pathname,n,o); -} - -int Bclose(int fd) -{ - return close(fd); -} - -bssize_t Bwrite(int fd, const void *buf, bsize_t count) -{ - return write(fd,buf,count); -} - -bssize_t Bread(int fd, void *buf, bsize_t count) -{ - return read(fd,buf,count); -} - -int Blseek(int fildes, int offset, int whence) -{ - switch (whence) { - case BSEEK_SET: whence=SEEK_SET; break; - case BSEEK_CUR: whence=SEEK_CUR; break; - case BSEEK_END: whence=SEEK_END; break; - } - return lseek(fildes,offset,whence); -} - -BFILE *Bfopen(const char *path, const char *mode) -{ - return (BFILE*)fopen(path,mode); -} - -int Bfclose(BFILE *stream) -{ - return fclose((FILE*)stream); -} - -void Brewind(BFILE *stream) -{ - rewind((FILE*)stream); -} - -int Bfgetc(BFILE *stream) -{ - return fgetc((FILE*)stream); -} - -char *Bfgets(char *s, int size, BFILE *stream) -{ - return fgets(s,size,(FILE*)stream); -} - -int Bfputc(int c, BFILE *stream) -{ - return fputc(c,(FILE*)stream); -} - -int Bfputs(const char *s, BFILE *stream) -{ - return fputs(s,(FILE*)stream); -} - -bsize_t Bfread(void *ptr, bsize_t size, bsize_t nmemb, BFILE *stream) -{ - return fread(ptr,size,nmemb,(FILE*)stream); -} - -bsize_t Bfwrite(const void *ptr, bsize_t size, bsize_t nmemb, BFILE *stream) -{ - return fwrite(ptr,size,nmemb,(FILE*)stream); -} - - -char *Bstrdup(const char *s) -{ - return strdup(s); -} - -char *Bstrcpy(char *dest, const char *src) -{ - return strcpy(dest,src); -} - -char *Bstrncpy(char *dest, const char *src, bsize_t n) -{ - return strncpy(dest,src,n); -} - -int Bstrcmp(const char *s1, const char *s2) -{ - return strcmp(s1,s2); -} - -int Bstrncmp(const char *s1, const char *s2, bsize_t n) -{ - return strncmp(s1,s2,n); -} - -int Bstrcasecmp(const char *s1, const char *s2) -{ -#ifdef _MSC_VER - return stricmp(s1,s2); -#else - return strcasecmp(s1,s2); -#endif -} - -int Bstrncasecmp(const char *s1, const char *s2, bsize_t n) -{ -#ifdef _MSC_VER - return strnicmp(s1,s2,n); -#else - return strncasecmp(s1,s2,n); -#endif -} - -char *Bstrcat(char *dest, const char *src) -{ - return strcat(dest,src); -} - -char *Bstrncat(char *dest, const char *src, bsize_t n) -{ - return strncat(dest,src,n); -} - -bsize_t Bstrlen(const char *s) -{ - return strlen(s); -} - -char *Bstrchr(const char *s, int c) -{ - return strchr(s,c); -} - -char *Bstrrchr(const char *s, int c) -{ - return strrchr(s,c); -} - -int Batoi(const char *nptr) -{ - return atoi(nptr); -} - -long Batol(const char *nptr) -{ - return atol(nptr); -} - -long int Bstrtol(const char *nptr, char **endptr, int base) -{ - return strtol(nptr,endptr,base); -} - -unsigned long int Bstrtoul(const char *nptr, char **endptr, int base) -{ - return strtoul(nptr,endptr,base); -} - -void *Bmemcpy(void *dest, const void *src, bsize_t n) -{ - return memcpy(dest,src,n); -} - -void *Bmemmove(void *dest, const void *src, bsize_t n) -{ - return memmove(dest,src,n); -} - -void *Bmemchr(const void *s, int c, bsize_t n) -{ - return memchr(s,c,n); -} - -void *Bmemset(void *s, int c, bsize_t n) -{ - return memset(s,c,n); -} - -int Bprintf(const char *format, ...) -{ - va_list ap; - int r; - - va_start(ap,format); -#ifdef _MSC_VER - r = _vprintf(format,ap); -#else - r = vprintf(format,ap); -#endif - va_end(ap); - return r; -} - -int Bsprintf(char *str, const char *format, ...) -{ - va_list ap; - int r; - - va_start(ap,format); -#ifdef _MSC_VER - r = _vsprintf(str,format,ap); -#else - r = vsprintf(str,format,ap); -#endif - va_end(ap); - return r; -} - -int Bsnprintf(char *str, bsize_t size, const char *format, ...) -{ - va_list ap; - int r; - - va_start(ap,format); -#ifdef _MSC_VER - r = _vsnprintf(str,size,format,ap); -#else - r = vsnprintf(str,size,format,ap); -#endif - va_end(ap); - return r; -} - -int Bvsnprintf(char *str, bsize_t size, const char *format, va_list ap) -{ -#ifdef _MSC_VER - return _vsnprintf(str,size,format,ap); -#else - return vsnprintf(str,size,format,ap); -#endif -} - -char *Bgetenv(const char *name) -{ - return getenv(name); -} - -char *Bgetcwd(char *buf, bsize_t size) -{ - return getcwd(buf,size); -} - -#endif // __compat_h_macrodef__ - - -// -// Stuff which must be a function -// - -char *Bgethomedir(void) -{ -#ifdef _WIN32 - TCHAR appdata[MAX_PATH]; - -//# if defined SHGetFolderPath -// if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_APPDATA, NULL, 0, appdata))) -//# if defined SHGetSpecialFolderPath - if (SUCCEEDED(SHGetSpecialFolderPathA(NULL, appdata, CSIDL_APPDATA, FALSE))) -//# else -//# error Cannot find SHGetFolderPath or SHGetSpecialFolderPath. Perhaps your shlobj.h is ancient? -//# endif - return strdup(appdata); - return NULL; -#else - char *e = getenv("HOME"); - if (!e) return NULL; - return strdup(e); -#endif -} - -int Bcorrectfilename(char *filename, int removefn) -{ - char *fn; - char *tokarr[64], *first, *next, *token; - int i, ntok = 0, leadslash = 0, trailslash = 0; - - fn = strdup(filename); - if (!fn) return -1; - - for (first=fn; *first; first++) { -#ifdef _WIN32 - if (*first == '\\') *first = '/'; -#endif - } - leadslash = (*fn == '/'); - trailslash = (first>fn && first[-1] == '/'); - - first = fn; - do { - token = Bstrtoken(first, "/", &next, 1); - first = NULL; - if (!token) break; - else if (token[0] == 0) continue; - else if (token[0] == '.' && token[1] == 0) continue; - else if (token[0] == '.' && token[1] == '.' && token[2] == 0) ntok = max(0,ntok-1); - else tokarr[ntok++] = token; - } while (1); - - if (!trailslash && removefn) { ntok = max(0,ntok-1); trailslash = 1; } - if (ntok == 0 && trailslash && leadslash) trailslash = 0; - - first = filename; - if (leadslash) *(first++) = '/'; - for (i=0; i0) *(first++) = '/'; - for (token=tokarr[i]; *token; token++) - *(first++) = *token; - } - if (trailslash) *(first++) = '/'; - *(first++) = 0; - - return 0; -} - -int Bcanonicalisefilename(char *filename, int removefn) -{ - char cwd[BMAX_PATH], fn[BMAX_PATH], *p; - char *fnp = filename; -#ifdef _WIN32 - int drv = 0; -#endif - -#ifdef _WIN32 - { - if (filename[0] && filename[1] == ':') { - // filename is prefixed with a drive - drv = toupper(filename[0])-'A' + 1; - fnp += 2; - } - if (!_getdcwd(drv, cwd, sizeof(cwd))) return -1; - for (p=cwd; *p; p++) if (*p == '\\') *p = '/'; - } -#else - if (!getcwd(cwd,sizeof(cwd))) return -1; -#endif - p = strrchr(cwd,'/'); if (!p || p[1]) strcat(cwd, "/"); - - strcpy(fn, fnp); -#ifdef _WIN32 - for (p=fn; *p; p++) if (*p == '\\') *p = '/'; -#endif - - if (fn[0] != '/') { - // we are dealing with a path relative to the current directory - strcpy(filename, cwd); - strcat(filename, fn); - } else { -#ifdef _WIN32 - filename[0] = cwd[0]; - filename[1] = ':'; - filename[2] = 0; -#else - filename[0] = 0; -#endif - strcat(filename, fn); - } - fnp = filename; -#ifdef _WIN32 - fnp += 2; // skip the drive -#endif - - return Bcorrectfilename(fnp,1); -} - -char *Bgetsystemdrives(void) -{ -#ifdef _WIN32 - char *str, *p; - DWORD drv, mask; - int number=0; - - drv = GetLogicalDrives(); - if (drv == 0) return NULL; - - for (mask=1; mask<0x8000000l; mask<<=1) { - if ((drv&mask) == 0) continue; - number++; - } - - str = p = (char *)malloc(1 + (3*number)); - if (!str) return NULL; - - number = 0; - for (mask=1; mask<0x8000000l; mask<<=1, number++) { - if ((drv&mask) == 0) continue; - *(p++) = 'A' + number; - *(p++) = ':'; - *(p++) = 0; - } - *(p++) = 0; - - return str; -#else - // Perhaps have Unix OS's put /, /home/user, and /mnt/* in the "drives" list? - return NULL; -#endif -} - - -long Bfilelength(int fd) -{ - struct stat st; - if (fstat(fd, &st) < 0) return -1; - return(long)(st.st_size); -} - - -typedef struct { -#ifdef _MSC_VER - long dir; - struct _finddata_t fid; -#else - DIR *dir; -#endif - struct Bdirent info; - int status; - char name[1]; -} BDIR_real; - -BDIR* Bopendir(const char *name) -{ - BDIR_real *dirr; -#ifdef _MSC_VER - char *t,*tt; - t = (char*)malloc(strlen(name)+1+4); - if (!t) return NULL; -#endif - - dirr = (BDIR_real*)malloc(sizeof(BDIR_real) + strlen(name)); - if (!dirr) { -#ifdef _MSC_VER - free(t); -#endif - return NULL; - } - -#ifdef _MSC_VER - strcpy(t,name); - tt = t+strlen(name)-1; - while (*tt == ' ' && tt>t) tt--; - if (*tt != '/' && *tt != '\\') *(++tt) = '/'; - *(++tt) = '*'; - *(++tt) = '.'; - *(++tt) = '*'; - *(++tt) = 0; - - dirr->dir = _findfirst(t,&dirr->fid); - free(t); - if (dirr->dir == -1) { - free(dirr); - return NULL; - } -#else - dirr->dir = opendir(name); - if (dirr->dir == NULL) { - free(dirr); - return NULL; - } -#endif - - dirr->status = 0; - strcpy(dirr->name, name); - - return (BDIR*)dirr; -} - -struct Bdirent* Breaddir(BDIR *dir) -{ - BDIR_real *dirr = (BDIR_real*)dir; - struct dirent *de; - struct stat st; - char *fn; - -#ifdef _MSC_VER - if (dirr->status > 0) { - if (_findnext(dirr->dir,&dirr->fid) != 0) { - dirr->status = -1; - return NULL; - } - } - dirr->info.namlen = strlen(dirr->fid.name); - dirr->info.name = dirr->fid.name; - dirr->status++; -#else - de = readdir(dirr->dir); - if (de == NULL) { - dirr->status = -1; - return NULL; - } else { - dirr->status++; - } -//# if defined(__WATCOMC__) || defined(__linux) || defined(__BEOS__) || defined(__QNX__) || defined(SKYOS) - dirr->info.namlen = strlen(de->d_name); -//# else -// dirr->info.namlen = de->d_namlen; -//# endif - dirr->info.name = de->d_name; -#endif - dirr->info.mode = 0; - dirr->info.size = 0; - dirr->info.mtime = 0; - - fn = (char *)malloc(strlen(dirr->name) + 1 + dirr->info.namlen + 1); - if (fn) { - sprintf(fn,"%s/%s",dirr->name,dirr->info.name); - if (!stat(fn, &st)) { - dirr->info.mode = st.st_mode; - dirr->info.size = st.st_size; - dirr->info.mtime = st.st_mtime; - } - free(fn); - } - - return &dirr->info; -} - -int Bclosedir(BDIR *dir) -{ - BDIR_real *dirr = (BDIR_real*)dir; - -#ifdef _MSC_VER - _findclose(dirr->dir); -#else - closedir(dirr->dir); -#endif - free(dirr); - - return 0; -} - - -char *Bstrtoken(char *s, char *delim, char **ptrptr, int chop) -{ - char *p, *start; - - if (!ptrptr) return NULL; - - if (s) p = s; - else p = *ptrptr; - - if (!p) return NULL; - - while (*p != 0 && strchr(delim, *p)) p++; - if (*p == 0) { - *ptrptr = NULL; - return NULL; - } - start = p; - while (*p != 0 && !strchr(delim, *p)) p++; - if (*p == 0) *ptrptr = NULL; - else { - if (chop) *(p++) = 0; - *ptrptr = p; - } - - return start; -} - - - //Brute-force case-insensitive, slash-insensitive, * and ? wildcard matcher - //Given: string i and string j. string j can have wildcards - //Returns: 1:matches, 0:doesn't match -long Bwildmatch (const char *i, const char *j) -{ - const char *k; - char c0, c1; - - if (!*j) return(1); - do - { - if (*j == '*') - { - for(k=i,j++;*k;k++) if (Bwildmatch(k,j)) return(1); - continue; - } - if (!*i) return(0); - if (*j == '?') { i++; j++; continue; } - c0 = *i; if ((c0 >= 'a') && (c0 <= 'z')) c0 -= 32; - c1 = *j; if ((c1 >= 'a') && (c1 <= 'z')) c1 -= 32; -#ifdef _WIN32 - if (c0 == '/') c0 = '\\'; - if (c1 == '/') c1 = '\\'; -#endif - if (c0 != c1) return(0); - i++; j++; - } while (*j); - return(!*i); -} - -#if !defined(_WIN32) -char *Bstrlwr(char *s) -{ - char *t = s; - if (!s) return s; - while (*t) { *t = Btolower(*t); t++; } - return s; -} - -char *Bstrupr(char *s) -{ - char *t = s; - if (!s) return s; - while (*t) { *t = Btoupper(*t); t++; } - return s; -} -#endif - - -// -// getsysmemsize() -- gets the amount of system memory in the machine -// -unsigned int Bgetsysmemsize(void) -{ -#ifdef _WIN32 - MEMORYSTATUS memst; - GlobalMemoryStatus(&memst); - return (unsigned int)memst.dwTotalPhys; -#elif (defined(_SC_PAGE_SIZE) || defined(_SC_PAGESIZE)) && defined(_SC_PHYS_PAGES) - unsigned int siz = 0x7fffffff; - long scpagesiz, scphyspages; - -#ifdef _SC_PAGE_SIZE - scpagesiz = sysconf(_SC_PAGE_SIZE); -#else - scpagesiz = sysconf(_SC_PAGESIZE); -#endif - scphyspages = sysconf(_SC_PHYS_PAGES); - if (scpagesiz >= 0 && scphyspages >= 0) - siz = (unsigned int)min(longlong(0x7fffffff), (int64)scpagesiz * (int64)scphyspages); - - //initprintf("Bgetsysmemsize(): %d pages of %d bytes, %d bytes of system memory\n", - // scphyspages, scpagesiz, siz); - - return siz; -#else - return 0x7fffffff; -#endif -} - - - +/* + * Playing-field leveller for Build + * by Jonathon Fowler + * + * A note about this: + * 1. There is some kind of problem somewhere in the functions below because + * compiling with __compat_h_macrodef__ disabled makes stupid things happen. + * 2. The functions below, aside from the ones which aren't trivial, were never + * really intended to be used for anything except tracking anr removing ties + * to the standard C library from games. Using the Bxx versions of functions + * means we can redefine those names to link up with different runtime library + * names. + */ + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#define _WIN32_IE 0x0400 +#include +#include +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(__WATCOMC__) +# include +#elif defined(_MSC_VER) +# include +#else +# include +#endif + +#include "compat.h" + + +#ifndef __compat_h_macrodef__ + +int Brand(void) +{ + return rand(); +} + +void *Bmalloc(bsize_t size) +{ + return malloc(size); +} + +void Bfree(void *ptr) +{ + free(ptr); +} + +int Bopen(const char *pathname, int flags, unsigned mode) +{ + int n=0,o=0; + + if (flags&BO_BINARY) n|=O_BINARY; else n|=O_TEXT; + if ((flags&BO_RDWR)==BO_RDWR) n|=O_RDWR; + else if ((flags&BO_RDWR)==BO_WRONLY) n|=O_WRONLY; + else if ((flags&BO_RDWR)==BO_RDONLY) n|=O_RDONLY; + if (flags&BO_APPEND) n|=O_APPEND; + if (flags&BO_CREAT) n|=O_CREAT; + if (flags&BO_TRUNC) n|=O_TRUNC; + if (mode&BS_IREAD) o|=S_IREAD; + if (mode&BS_IWRITE) o|=S_IWRITE; + if (mode&BS_IEXEC) o|=S_IEXEC; + + return open(pathname,n,o); +} + +int Bclose(int fd) +{ + return close(fd); +} + +bssize_t Bwrite(int fd, const void *buf, bsize_t count) +{ + return write(fd,buf,count); +} + +bssize_t Bread(int fd, void *buf, bsize_t count) +{ + return read(fd,buf,count); +} + +int Blseek(int fildes, int offset, int whence) +{ + switch (whence) { + case BSEEK_SET: whence=SEEK_SET; break; + case BSEEK_CUR: whence=SEEK_CUR; break; + case BSEEK_END: whence=SEEK_END; break; + } + return lseek(fildes,offset,whence); +} + +BFILE *Bfopen(const char *path, const char *mode) +{ + return (BFILE*)fopen(path,mode); +} + +int Bfclose(BFILE *stream) +{ + return fclose((FILE*)stream); +} + +void Brewind(BFILE *stream) +{ + rewind((FILE*)stream); +} + +int Bfgetc(BFILE *stream) +{ + return fgetc((FILE*)stream); +} + +char *Bfgets(char *s, int size, BFILE *stream) +{ + return fgets(s,size,(FILE*)stream); +} + +int Bfputc(int c, BFILE *stream) +{ + return fputc(c,(FILE*)stream); +} + +int Bfputs(const char *s, BFILE *stream) +{ + return fputs(s,(FILE*)stream); +} + +bsize_t Bfread(void *ptr, bsize_t size, bsize_t nmemb, BFILE *stream) +{ + return fread(ptr,size,nmemb,(FILE*)stream); +} + +bsize_t Bfwrite(const void *ptr, bsize_t size, bsize_t nmemb, BFILE *stream) +{ + return fwrite(ptr,size,nmemb,(FILE*)stream); +} + + +char *Bstrdup(const char *s) +{ + return strdup(s); +} + +char *Bstrcpy(char *dest, const char *src) +{ + return strcpy(dest,src); +} + +char *Bstrncpy(char *dest, const char *src, bsize_t n) +{ + return strncpy(dest,src,n); +} + +int Bstrcmp(const char *s1, const char *s2) +{ + return strcmp(s1,s2); +} + +int Bstrncmp(const char *s1, const char *s2, bsize_t n) +{ + return strncmp(s1,s2,n); +} + +int Bstrcasecmp(const char *s1, const char *s2) +{ +#ifdef _MSC_VER + return stricmp(s1,s2); +#else + return strcasecmp(s1,s2); +#endif +} + +int Bstrncasecmp(const char *s1, const char *s2, bsize_t n) +{ +#ifdef _MSC_VER + return strnicmp(s1,s2,n); +#else + return strncasecmp(s1,s2,n); +#endif +} + +char *Bstrcat(char *dest, const char *src) +{ + return strcat(dest,src); +} + +char *Bstrncat(char *dest, const char *src, bsize_t n) +{ + return strncat(dest,src,n); +} + +bsize_t Bstrlen(const char *s) +{ + return strlen(s); +} + +char *Bstrchr(const char *s, int c) +{ + return strchr(s,c); +} + +char *Bstrrchr(const char *s, int c) +{ + return strrchr(s,c); +} + +int Batoi(const char *nptr) +{ + return atoi(nptr); +} + +long Batol(const char *nptr) +{ + return atol(nptr); +} + +long int Bstrtol(const char *nptr, char **endptr, int base) +{ + return strtol(nptr,endptr,base); +} + +unsigned long int Bstrtoul(const char *nptr, char **endptr, int base) +{ + return strtoul(nptr,endptr,base); +} + +void *Bmemcpy(void *dest, const void *src, bsize_t n) +{ + return memcpy(dest,src,n); +} + +void *Bmemmove(void *dest, const void *src, bsize_t n) +{ + return memmove(dest,src,n); +} + +void *Bmemchr(const void *s, int c, bsize_t n) +{ + return memchr(s,c,n); +} + +void *Bmemset(void *s, int c, bsize_t n) +{ + return memset(s,c,n); +} + +int Bprintf(const char *format, ...) +{ + va_list ap; + int r; + + va_start(ap,format); +#ifdef _MSC_VER + r = _vprintf(format,ap); +#else + r = vprintf(format,ap); +#endif + va_end(ap); + return r; +} + +int Bsprintf(char *str, const char *format, ...) +{ + va_list ap; + int r; + + va_start(ap,format); +#ifdef _MSC_VER + r = _vsprintf(str,format,ap); +#else + r = vsprintf(str,format,ap); +#endif + va_end(ap); + return r; +} + +int Bsnprintf(char *str, bsize_t size, const char *format, ...) +{ + va_list ap; + int r; + + va_start(ap,format); +#ifdef _MSC_VER + r = _vsnprintf(str,size,format,ap); +#else + r = vsnprintf(str,size,format,ap); +#endif + va_end(ap); + return r; +} + +int Bvsnprintf(char *str, bsize_t size, const char *format, va_list ap) +{ +#ifdef _MSC_VER + return _vsnprintf(str,size,format,ap); +#else + return vsnprintf(str,size,format,ap); +#endif +} + +char *Bgetenv(const char *name) +{ + return getenv(name); +} + +char *Bgetcwd(char *buf, bsize_t size) +{ + return getcwd(buf,size); +} + +#endif // __compat_h_macrodef__ + + +// +// Stuff which must be a function +// + +char *Bgethomedir(void) +{ +#ifdef _WIN32 + TCHAR appdata[MAX_PATH]; + +//# if defined SHGetFolderPath +// if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_APPDATA, NULL, 0, appdata))) +//# if defined SHGetSpecialFolderPath + if (SUCCEEDED(SHGetSpecialFolderPathA(NULL, appdata, CSIDL_APPDATA, FALSE))) +//# else +//# error Cannot find SHGetFolderPath or SHGetSpecialFolderPath. Perhaps your shlobj.h is ancient? +//# endif + return strdup(appdata); + return NULL; +#else + char *e = getenv("HOME"); + if (!e) return NULL; + return strdup(e); +#endif +} + +int Bcorrectfilename(char *filename, int removefn) +{ + char *fn; + char *tokarr[64], *first, *next, *token; + int i, ntok = 0, leadslash = 0, trailslash = 0; + + fn = strdup(filename); + if (!fn) return -1; + + for (first=fn; *first; first++) { +#ifdef _WIN32 + if (*first == '\\') *first = '/'; +#endif + } + leadslash = (*fn == '/'); + trailslash = (first>fn && first[-1] == '/'); + + first = fn; + do { + token = Bstrtoken(first, "/", &next, 1); + first = NULL; + if (!token) break; + else if (token[0] == 0) continue; + else if (token[0] == '.' && token[1] == 0) continue; + else if (token[0] == '.' && token[1] == '.' && token[2] == 0) ntok = max(0,ntok-1); + else tokarr[ntok++] = token; + } while (1); + + if (!trailslash && removefn) { ntok = max(0,ntok-1); trailslash = 1; } + if (ntok == 0 && trailslash && leadslash) trailslash = 0; + + first = filename; + if (leadslash) *(first++) = '/'; + for (i=0; i0) *(first++) = '/'; + for (token=tokarr[i]; *token; token++) + *(first++) = *token; + } + if (trailslash) *(first++) = '/'; + *(first++) = 0; + + return 0; +} + +int Bcanonicalisefilename(char *filename, int removefn) +{ + char cwd[BMAX_PATH], fn[BMAX_PATH], *p; + char *fnp = filename; +#ifdef _WIN32 + int drv = 0; +#endif + +#ifdef _WIN32 + { + if (filename[0] && filename[1] == ':') { + // filename is prefixed with a drive + drv = toupper(filename[0])-'A' + 1; + fnp += 2; + } + if (!_getdcwd(drv, cwd, sizeof(cwd))) return -1; + for (p=cwd; *p; p++) if (*p == '\\') *p = '/'; + } +#else + if (!getcwd(cwd,sizeof(cwd))) return -1; +#endif + p = strrchr(cwd,'/'); if (!p || p[1]) strcat(cwd, "/"); + + strcpy(fn, fnp); +#ifdef _WIN32 + for (p=fn; *p; p++) if (*p == '\\') *p = '/'; +#endif + + if (fn[0] != '/') { + // we are dealing with a path relative to the current directory + strcpy(filename, cwd); + strcat(filename, fn); + } else { +#ifdef _WIN32 + filename[0] = cwd[0]; + filename[1] = ':'; + filename[2] = 0; +#else + filename[0] = 0; +#endif + strcat(filename, fn); + } + fnp = filename; +#ifdef _WIN32 + fnp += 2; // skip the drive +#endif + + return Bcorrectfilename(fnp,1); +} + +char *Bgetsystemdrives(void) +{ +#ifdef _WIN32 + char *str, *p; + DWORD drv, mask; + int number=0; + + drv = GetLogicalDrives(); + if (drv == 0) return NULL; + + for (mask=1; mask<0x8000000l; mask<<=1) { + if ((drv&mask) == 0) continue; + number++; + } + + str = p = (char *)malloc(1 + (3*number)); + if (!str) return NULL; + + number = 0; + for (mask=1; mask<0x8000000l; mask<<=1, number++) { + if ((drv&mask) == 0) continue; + *(p++) = 'A' + number; + *(p++) = ':'; + *(p++) = 0; + } + *(p++) = 0; + + return str; +#else + // Perhaps have Unix OS's put /, /home/user, and /mnt/* in the "drives" list? + return NULL; +#endif +} + + +long Bfilelength(int fd) +{ + struct stat st; + if (fstat(fd, &st) < 0) return -1; + return(long)(st.st_size); +} + + +typedef struct { +#ifdef _MSC_VER + long dir; + struct _finddata_t fid; +#else + DIR *dir; +#endif + struct Bdirent info; + int status; + char name[1]; +} BDIR_real; + +BDIR* Bopendir(const char *name) +{ + BDIR_real *dirr; +#ifdef _MSC_VER + char *t,*tt; + t = (char*)malloc(strlen(name)+1+4); + if (!t) return NULL; +#endif + + dirr = (BDIR_real*)malloc(sizeof(BDIR_real) + strlen(name)); + if (!dirr) { +#ifdef _MSC_VER + free(t); +#endif + return NULL; + } + +#ifdef _MSC_VER + strcpy(t,name); + tt = t+strlen(name)-1; + while (*tt == ' ' && tt>t) tt--; + if (*tt != '/' && *tt != '\\') *(++tt) = '/'; + *(++tt) = '*'; + *(++tt) = '.'; + *(++tt) = '*'; + *(++tt) = 0; + + dirr->dir = _findfirst(t,&dirr->fid); + free(t); + if (dirr->dir == -1) { + free(dirr); + return NULL; + } +#else + dirr->dir = opendir(name); + if (dirr->dir == NULL) { + free(dirr); + return NULL; + } +#endif + + dirr->status = 0; + strcpy(dirr->name, name); + + return (BDIR*)dirr; +} + +struct Bdirent* Breaddir(BDIR *dir) +{ + BDIR_real *dirr = (BDIR_real*)dir; + struct dirent *de; + struct stat st; + char *fn; + +#ifdef _MSC_VER + if (dirr->status > 0) { + if (_findnext(dirr->dir,&dirr->fid) != 0) { + dirr->status = -1; + return NULL; + } + } + dirr->info.namlen = strlen(dirr->fid.name); + dirr->info.name = dirr->fid.name; + dirr->status++; +#else + de = readdir(dirr->dir); + if (de == NULL) { + dirr->status = -1; + return NULL; + } else { + dirr->status++; + } +//# if defined(__WATCOMC__) || defined(__linux) || defined(__BEOS__) || defined(__QNX__) || defined(SKYOS) + dirr->info.namlen = strlen(de->d_name); +//# else +// dirr->info.namlen = de->d_namlen; +//# endif + dirr->info.name = de->d_name; +#endif + dirr->info.mode = 0; + dirr->info.size = 0; + dirr->info.mtime = 0; + + fn = (char *)malloc(strlen(dirr->name) + 1 + dirr->info.namlen + 1); + if (fn) { + sprintf(fn,"%s/%s",dirr->name,dirr->info.name); + if (!stat(fn, &st)) { + dirr->info.mode = st.st_mode; + dirr->info.size = st.st_size; + dirr->info.mtime = st.st_mtime; + } + free(fn); + } + + return &dirr->info; +} + +int Bclosedir(BDIR *dir) +{ + BDIR_real *dirr = (BDIR_real*)dir; + +#ifdef _MSC_VER + _findclose(dirr->dir); +#else + closedir(dirr->dir); +#endif + free(dirr); + + return 0; +} + + +char *Bstrtoken(char *s, char *delim, char **ptrptr, int chop) +{ + char *p, *start; + + if (!ptrptr) return NULL; + + if (s) p = s; + else p = *ptrptr; + + if (!p) return NULL; + + while (*p != 0 && strchr(delim, *p)) p++; + if (*p == 0) { + *ptrptr = NULL; + return NULL; + } + start = p; + while (*p != 0 && !strchr(delim, *p)) p++; + if (*p == 0) *ptrptr = NULL; + else { + if (chop) *(p++) = 0; + *ptrptr = p; + } + + return start; +} + + + //Brute-force case-insensitive, slash-insensitive, * and ? wildcard matcher + //Given: string i and string j. string j can have wildcards + //Returns: 1:matches, 0:doesn't match +long Bwildmatch (const char *i, const char *j) +{ + const char *k; + char c0, c1; + + if (!*j) return(1); + do + { + if (*j == '*') + { + for(k=i,j++;*k;k++) if (Bwildmatch(k,j)) return(1); + continue; + } + if (!*i) return(0); + if (*j == '?') { i++; j++; continue; } + c0 = *i; if ((c0 >= 'a') && (c0 <= 'z')) c0 -= 32; + c1 = *j; if ((c1 >= 'a') && (c1 <= 'z')) c1 -= 32; +#ifdef _WIN32 + if (c0 == '/') c0 = '\\'; + if (c1 == '/') c1 = '\\'; +#endif + if (c0 != c1) return(0); + i++; j++; + } while (*j); + return(!*i); +} + +#if !defined(_WIN32) +char *Bstrlwr(char *s) +{ + char *t = s; + if (!s) return s; + while (*t) { *t = Btolower(*t); t++; } + return s; +} + +char *Bstrupr(char *s) +{ + char *t = s; + if (!s) return s; + while (*t) { *t = Btoupper(*t); t++; } + return s; +} +#endif + + +// +// getsysmemsize() -- gets the amount of system memory in the machine +// +unsigned int Bgetsysmemsize(void) +{ +#ifdef _WIN32 + MEMORYSTATUS memst; + GlobalMemoryStatus(&memst); + return (unsigned int)memst.dwTotalPhys; +#elif (defined(_SC_PAGE_SIZE) || defined(_SC_PAGESIZE)) && defined(_SC_PHYS_PAGES) + unsigned int siz = 0x7fffffff; + long scpagesiz, scphyspages; + +#ifdef _SC_PAGE_SIZE + scpagesiz = sysconf(_SC_PAGE_SIZE); +#else + scpagesiz = sysconf(_SC_PAGESIZE); +#endif + scphyspages = sysconf(_SC_PHYS_PAGES); + if (scpagesiz >= 0 && scphyspages >= 0) + siz = (unsigned int)min(longlong(0x7fffffff), (int64)scpagesiz * (int64)scphyspages); + + //initprintf("Bgetsysmemsize(): %d pages of %d bytes, %d bytes of system memory\n", + // scphyspages, scpagesiz, siz); + + return siz; +#else + return 0x7fffffff; +#endif +} + + + diff --git a/polymer/build/src/config.c b/polymer/build/src/config.c index 642f9707f..a56d2898b 100644 --- a/polymer/build/src/config.c +++ b/polymer/build/src/config.c @@ -1,307 +1,307 @@ -// Evil and Nasty Configuration File Reader for KenBuild -// by Jonathon Fowler - -#include "compat.h" -#include "build.h" -#include "editor.h" -#include "osd.h" - -#ifdef RENDERTYPEWIN -#include "winlayer.h" -#endif -#include "baselayer.h" - -static long vesares[13][2] = {{320,200},{360,200},{320,240},{360,240},{320,400}, - {360,400},{640,350},{640,400},{640,480},{800,600}, - {1024,768},{1280,1024},{1600,1200}}; - -static int readconfig(BFILE *fp, const char *key, char *value, unsigned len) -{ - char buf[1000], *k, *v, *eq; - int x=0; - - if (len < 1) return 0; - - Brewind(fp); - - while (1) { - if (!Bfgets(buf, 1000, fp)) return 0; - - if (buf[0] == ';') continue; - - eq = Bstrchr(buf, '='); - if (!eq) continue; - - k = buf; - v = eq+1; - - while (*k == ' ' || *k == '\t') k++; - *(eq--) = 0; - while ((*eq == ' ' || *eq == '\t') && eq>=k) *(eq--) = 0; - - if (Bstrcasecmp(k, key)) continue; - - while (*v == ' ' || *k == '\t') v++; - eq = v + Bstrlen(v)-1; - - while ((*eq == ' ' || *eq == '\t' || *eq == '\r' || *eq == '\n') && eq>=v) *(eq--) = 0; - - value[--len] = 0; - do value[x] = v[x]; while (v[x++] != 0 && len-- > 0); - - return x-1; - } -} - -extern short brightness; -extern long fullscreen; -extern char option[8]; -extern char keys[NUMBUILDKEYS]; -extern double msens; - -/* - * SETUP.DAT - * 0 = video mode (0:chained 1:vesa 2:screen buffered 3/4/5:tseng/paradise/s3 6:red-blue) - * 1 = sound (0:none) - * 2 = music (0:none) - * 3 = input (0:keyboard 1:+mouse) - * 4 = multiplayer (0:single 1-4:com 5-11:ipx) - * 5&0xf0 = com speed - * 5&0x0f = com irq - * 6&0xf0 = chained y-res - * 6&0x0f = chained x-res or vesa mode - * 7&0xf0 = sound samplerate - * 7&0x01 = sound quality - * 7&0x02 = 8/16 bit - * 7&0x04 = mono/stereo - * - * bytes 8 to 26 are key settings: - * 0 = Forward (0xc8) - * 1 = Backward (0xd0) - * 2 = Turn left (0xcb) - * 3 = Turn right (0xcd) - * 4 = Run (0x2a) - * 5 = Strafe (0x9d) - * 6 = Fire (0x1d) - * 7 = Use (0x39) - * 8 = Stand high (0x1e) - * 9 = Stand low (0x2c) - * 10 = Look up (0xd1) - * 11 = Look down (0xc9) - * 12 = Strafe left (0x33) - * 13 = Strafe right (0x34) - * 14 = 2D/3D switch (0x9c) - * 15 = View cycle (0x1c) - * 16 = 2D Zoom in (0xd) - * 17 = 2D Zoom out (0xc) - * 18 = Chat (0xf) - */ - -int loadsetup(const char *fn) -{ - BFILE *fp; -#define VL 32 - char val[VL]; - int i; - - if ((fp = Bfopen(fn, "rt")) == NULL) return -1; - - if (readconfig(fp, "fullscreen", val, VL) > 0) { if (Batoi(val) != 0) fullscreen = 1; else fullscreen = 0; } - if (readconfig(fp, "resolution", val, VL) > 0) { - i = Batoi(val) & 0x0f; - if ((unsigned)i<13) { xdimgame = xdim2d = vesares[i][0]; ydimgame = ydim2d = vesares[i][1]; } - } - if (readconfig(fp, "2dresolution", val, VL) > 0) { - i = Batoi(val) & 0x0f; - if ((unsigned)i<13) { xdim2d = vesares[i][0]; ydim2d = vesares[i][1]; } - } - if (readconfig(fp, "xdim2d", val, VL) > 0) xdim2d = Batoi(val); - if (readconfig(fp, "ydim2d", val, VL) > 0) ydim2d = Batoi(val); - if (readconfig(fp, "xdim3d", val, VL) > 0) xdimgame = Batoi(val); - if (readconfig(fp, "ydim3d", val, VL) > 0) ydimgame = Batoi(val); - if (readconfig(fp, "samplerate", val, VL) > 0) option[7] = (Batoi(val) & 0x0f) << 4; - if (readconfig(fp, "music", val, VL) > 0) { if (Batoi(val) != 0) option[2] = 1; else option[2] = 0; } - if (readconfig(fp, "mouse", val, VL) > 0) { if (Batoi(val) != 0) option[3] = 1; else option[3] = 0; } - if (readconfig(fp, "bpp", val, VL) > 0) bppgame = Batoi(val); - if (readconfig(fp, "renderer", val, VL) > 0) { i = Batoi(val); setrendermode(i); } - if (readconfig(fp, "brightness", val, VL) > 0) brightness = min(max(Batoi(val),0),15); - -#ifdef RENDERTYPEWIN - if (readconfig(fp, "maxrefreshfreq", val, VL) > 0) maxrefreshfreq = Batoi(val); -#endif - glusetexcache = glusetexcachecompression = -1; - if (readconfig(fp, "glusetexcache", val, VL) > 0) { - if (Batoi(val) != 0) glusetexcache = 1; - else glusetexcache = 0; - } - if (readconfig(fp, "glusetexcachecompression", val, VL) > 0) { - if (Batoi(val) != 0) glusetexcachecompression = 1; - else glusetexcachecompression = 0; - } - if(glusetexcache == -1 && glusetexcachecompression == -1) - { - i=wm_ynbox("Texture caching", - "Would you like to enable the on-disk texture cache? " - "This feature may use up to 200 megabytes of disk " - "space if you have a great deal of high resolution " - "textures and skins, but textures will load exponentially " - "faster after the first time they are loaded."); - if (i) i = 'y'; - if(i == 'y' || i == 'Y' ) - glusetexcompr = glusetexcache = glusetexcachecompression = 1; - else glusetexcache = glusetexcachecompression = 0; - } - - option[0] = 1; // vesa all the way... - option[1] = 1; // sound all the way... - option[4] = 0; // no multiplayer - option[5] = 0; - - if (readconfig(fp, "keyforward", val, VL) > 0) keys[0] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keybackward", val, VL) > 0) keys[1] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keyturnleft", val, VL) > 0) keys[2] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keyturnright", val, VL) > 0) keys[3] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keyrun", val, VL) > 0) keys[4] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keystrafe", val, VL) > 0) keys[5] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keyfire", val, VL) > 0) keys[6] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keyuse", val, VL) > 0) keys[7] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keystandhigh", val, VL) > 0) keys[8] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keystandlow", val, VL) > 0) keys[9] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keylookup", val, VL) > 0) keys[10] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keylookdown", val, VL) > 0) keys[11] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keystrafeleft", val, VL) > 0) keys[12] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keystraferight", val, VL) > 0) keys[13] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "key2dmode", val, VL) > 0) keys[14] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keyviewcycle", val, VL) > 0) keys[15] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "key2dzoomin", val, VL) > 0) keys[16] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "key2dzoomout", val, VL) > 0) keys[17] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keychat", val, VL) > 0) keys[18] = Bstrtol(val, NULL, 16); - if (readconfig(fp, "keyconsole", val, VL) > 0) { keys[19] = Bstrtol(val, NULL, 16); OSD_CaptureKey(keys[19]); } - - if (readconfig(fp, "mousesensitivity", val, VL) > 0) msens = Bstrtod(val, NULL); - - Bfclose(fp); - - return 0; -} - -int writesetup(const char *fn) -{ - BFILE *fp; - - fp = Bfopen(fn,"wt"); - if (!fp) return -1; - - Bfprintf(fp, - "; Video mode selection\n" - "; 0 - Windowed\n" - "; 1 - Fullscreen\n" - "fullscreen = %ld\n" - "\n" - "; Video resolution\n" - "xdim2d = %ld\n" - "ydim2d = %ld\n" - "xdim3d = %ld\n" - "ydim3d = %ld\n" - "\n" - "; 3D-mode colour depth\n" - "bpp = %ld\n" - "\n" - "; OpenGL mode options\n" - "glusetexcache = %ld\n" - "glusetexcachecompression = %ld\n" - "\n" -#ifdef RENDERTYPEWIN - "; Maximum OpenGL mode refresh rate (Windows only, in Hertz)\n" - "maxrefreshfreq = %d\n" - "\n" -#endif - "; 3D mode brightness setting\n" - "; 0 - lowest\n" - "; 15 - highest\n" - "brightness = %d\n" - "\n" - "; Sound sample frequency\n" - "; 0 - 6 KHz\n" - "; 1 - 8 KHz\n" - "; 2 - 11.025 KHz\n" - "; 3 - 16 KHz\n" - "; 4 - 22.05 KHz\n" - "; 5 - 32 KHz\n" - "; 6 - 44.1 KHz\n" - "samplerate = %d\n" - "\n" - "; Music playback\n" - "; 0 - Off\n" - "; 1 - On\n" - "music = %d\n" - "\n" - "; Enable mouse\n" - "; 0 - No\n" - "; 1 - Yes\n" - "mouse = %d\n" - "\n" - "; Mouse sensitivity\n" - "mousesensitivity = %g\n" - "\n" - "; Key Settings\n" - "; Here's a map of all the keyboard scan codes: NOTE: values are listed in hex!\n" - "; +---------------------------------------------------------------------------------------------+\n" - "; | 01 3B 3C 3D 3E 3F 40 41 42 43 44 57 58 46 |\n" - "; |ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 SCROLL |\n" - "; | |\n" - "; |29 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E D2 C7 C9 45 B5 37 4A |\n" - "; | ` '1' '2' '3' '4' '5' '6' '7' '8' '9' '0' - = BACK INS HOME PGUP NUMLK KP/ KP* KP- |\n" - "; | |\n" - "; | 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 2B D3 CF D1 47 48 49 4E |\n" - "; |TAB Q W E R T Y U I O P [ ] \\ DEL END PGDN KP7 KP8 KP9 KP+ |\n" - "; | |\n" - "; | 3A 1E 1F 20 21 22 23 24 25 26 27 28 1C 4B 4C 4D |\n" - "; |CAPS A S D F G H J K L ; ' ENTER KP4 KP5 KP6 9C |\n" - "; | KPENTER|\n" - "; | 2A 2C 2D 2E 2F 30 31 32 33 34 35 36 C8 4F 50 51 |\n" - "; |LSHIFT Z X C V B N M , . / RSHIFT UP KP1 KP2 KP3 |\n" - "; | |\n" - "; | 1D 38 39 B8 9D CB D0 CD 52 53 |\n" - "; |LCTRL LALT SPACE RALT RCTRL LEFT DOWN RIGHT KP0 KP. |\n" - "; +---------------------------------------------------------------------------------------------+\n" - "\n" - "keyforward = %X\n" - "keybackward = %X\n" - "keyturnleft = %X\n" - "keyturnright = %X\n" - "keyrun = %X\n" - "keystrafe = %X\n" - "keyfire = %X\n" - "keyuse = %X\n" - "keystandhigh = %X\n" - "keystandlow = %X\n" - "keylookup = %X\n" - "keylookdown = %X\n" - "keystrafeleft = %X\n" - "keystraferight = %X\n" - "key2dmode = %X\n" - "keyviewcycle = %X\n" - "key2dzoomin = %X\n" - "key2dzoomout = %X\n" - "keychat = %X\n" - "keyconsole = %X\n" - "\n", - - fullscreen, xdim2d, ydim2d, xdimgame, ydimgame, bppgame, - glusetexcache, glusetexcachecompression, -#ifdef RENDERTYPEWIN - maxrefreshfreq, -#endif - brightness, option[7]>>4, option[2], - option[3], msens, - keys[0], keys[1], keys[2], keys[3], keys[4], keys[5], - keys[6], keys[7], keys[8], keys[9], keys[10], keys[11], - keys[12], keys[13], keys[14], keys[15], keys[16], keys[17], - keys[18], keys[19] - ); - - Bfclose(fp); - - return 0; -} +// Evil and Nasty Configuration File Reader for KenBuild +// by Jonathon Fowler + +#include "compat.h" +#include "build.h" +#include "editor.h" +#include "osd.h" + +#ifdef RENDERTYPEWIN +#include "winlayer.h" +#endif +#include "baselayer.h" + +static long vesares[13][2] = {{320,200},{360,200},{320,240},{360,240},{320,400}, + {360,400},{640,350},{640,400},{640,480},{800,600}, + {1024,768},{1280,1024},{1600,1200}}; + +static int readconfig(BFILE *fp, const char *key, char *value, unsigned len) +{ + char buf[1000], *k, *v, *eq; + int x=0; + + if (len < 1) return 0; + + Brewind(fp); + + while (1) { + if (!Bfgets(buf, 1000, fp)) return 0; + + if (buf[0] == ';') continue; + + eq = Bstrchr(buf, '='); + if (!eq) continue; + + k = buf; + v = eq+1; + + while (*k == ' ' || *k == '\t') k++; + *(eq--) = 0; + while ((*eq == ' ' || *eq == '\t') && eq>=k) *(eq--) = 0; + + if (Bstrcasecmp(k, key)) continue; + + while (*v == ' ' || *k == '\t') v++; + eq = v + Bstrlen(v)-1; + + while ((*eq == ' ' || *eq == '\t' || *eq == '\r' || *eq == '\n') && eq>=v) *(eq--) = 0; + + value[--len] = 0; + do value[x] = v[x]; while (v[x++] != 0 && len-- > 0); + + return x-1; + } +} + +extern short brightness; +extern long fullscreen; +extern char option[8]; +extern char keys[NUMBUILDKEYS]; +extern double msens; + +/* + * SETUP.DAT + * 0 = video mode (0:chained 1:vesa 2:screen buffered 3/4/5:tseng/paradise/s3 6:red-blue) + * 1 = sound (0:none) + * 2 = music (0:none) + * 3 = input (0:keyboard 1:+mouse) + * 4 = multiplayer (0:single 1-4:com 5-11:ipx) + * 5&0xf0 = com speed + * 5&0x0f = com irq + * 6&0xf0 = chained y-res + * 6&0x0f = chained x-res or vesa mode + * 7&0xf0 = sound samplerate + * 7&0x01 = sound quality + * 7&0x02 = 8/16 bit + * 7&0x04 = mono/stereo + * + * bytes 8 to 26 are key settings: + * 0 = Forward (0xc8) + * 1 = Backward (0xd0) + * 2 = Turn left (0xcb) + * 3 = Turn right (0xcd) + * 4 = Run (0x2a) + * 5 = Strafe (0x9d) + * 6 = Fire (0x1d) + * 7 = Use (0x39) + * 8 = Stand high (0x1e) + * 9 = Stand low (0x2c) + * 10 = Look up (0xd1) + * 11 = Look down (0xc9) + * 12 = Strafe left (0x33) + * 13 = Strafe right (0x34) + * 14 = 2D/3D switch (0x9c) + * 15 = View cycle (0x1c) + * 16 = 2D Zoom in (0xd) + * 17 = 2D Zoom out (0xc) + * 18 = Chat (0xf) + */ + +int loadsetup(const char *fn) +{ + BFILE *fp; +#define VL 32 + char val[VL]; + int i; + + if ((fp = Bfopen(fn, "rt")) == NULL) return -1; + + if (readconfig(fp, "fullscreen", val, VL) > 0) { if (Batoi(val) != 0) fullscreen = 1; else fullscreen = 0; } + if (readconfig(fp, "resolution", val, VL) > 0) { + i = Batoi(val) & 0x0f; + if ((unsigned)i<13) { xdimgame = xdim2d = vesares[i][0]; ydimgame = ydim2d = vesares[i][1]; } + } + if (readconfig(fp, "2dresolution", val, VL) > 0) { + i = Batoi(val) & 0x0f; + if ((unsigned)i<13) { xdim2d = vesares[i][0]; ydim2d = vesares[i][1]; } + } + if (readconfig(fp, "xdim2d", val, VL) > 0) xdim2d = Batoi(val); + if (readconfig(fp, "ydim2d", val, VL) > 0) ydim2d = Batoi(val); + if (readconfig(fp, "xdim3d", val, VL) > 0) xdimgame = Batoi(val); + if (readconfig(fp, "ydim3d", val, VL) > 0) ydimgame = Batoi(val); + if (readconfig(fp, "samplerate", val, VL) > 0) option[7] = (Batoi(val) & 0x0f) << 4; + if (readconfig(fp, "music", val, VL) > 0) { if (Batoi(val) != 0) option[2] = 1; else option[2] = 0; } + if (readconfig(fp, "mouse", val, VL) > 0) { if (Batoi(val) != 0) option[3] = 1; else option[3] = 0; } + if (readconfig(fp, "bpp", val, VL) > 0) bppgame = Batoi(val); + if (readconfig(fp, "renderer", val, VL) > 0) { i = Batoi(val); setrendermode(i); } + if (readconfig(fp, "brightness", val, VL) > 0) brightness = min(max(Batoi(val),0),15); + +#ifdef RENDERTYPEWIN + if (readconfig(fp, "maxrefreshfreq", val, VL) > 0) maxrefreshfreq = Batoi(val); +#endif + glusetexcache = glusetexcachecompression = -1; + if (readconfig(fp, "glusetexcache", val, VL) > 0) { + if (Batoi(val) != 0) glusetexcache = 1; + else glusetexcache = 0; + } + if (readconfig(fp, "glusetexcachecompression", val, VL) > 0) { + if (Batoi(val) != 0) glusetexcachecompression = 1; + else glusetexcachecompression = 0; + } + if(glusetexcache == -1 && glusetexcachecompression == -1) + { + i=wm_ynbox("Texture caching", + "Would you like to enable the on-disk texture cache? " + "This feature may use up to 200 megabytes of disk " + "space if you have a great deal of high resolution " + "textures and skins, but textures will load exponentially " + "faster after the first time they are loaded."); + if (i) i = 'y'; + if(i == 'y' || i == 'Y' ) + glusetexcompr = glusetexcache = glusetexcachecompression = 1; + else glusetexcache = glusetexcachecompression = 0; + } + + option[0] = 1; // vesa all the way... + option[1] = 1; // sound all the way... + option[4] = 0; // no multiplayer + option[5] = 0; + + if (readconfig(fp, "keyforward", val, VL) > 0) keys[0] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keybackward", val, VL) > 0) keys[1] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keyturnleft", val, VL) > 0) keys[2] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keyturnright", val, VL) > 0) keys[3] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keyrun", val, VL) > 0) keys[4] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keystrafe", val, VL) > 0) keys[5] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keyfire", val, VL) > 0) keys[6] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keyuse", val, VL) > 0) keys[7] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keystandhigh", val, VL) > 0) keys[8] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keystandlow", val, VL) > 0) keys[9] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keylookup", val, VL) > 0) keys[10] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keylookdown", val, VL) > 0) keys[11] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keystrafeleft", val, VL) > 0) keys[12] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keystraferight", val, VL) > 0) keys[13] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "key2dmode", val, VL) > 0) keys[14] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keyviewcycle", val, VL) > 0) keys[15] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "key2dzoomin", val, VL) > 0) keys[16] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "key2dzoomout", val, VL) > 0) keys[17] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keychat", val, VL) > 0) keys[18] = Bstrtol(val, NULL, 16); + if (readconfig(fp, "keyconsole", val, VL) > 0) { keys[19] = Bstrtol(val, NULL, 16); OSD_CaptureKey(keys[19]); } + + if (readconfig(fp, "mousesensitivity", val, VL) > 0) msens = Bstrtod(val, NULL); + + Bfclose(fp); + + return 0; +} + +int writesetup(const char *fn) +{ + BFILE *fp; + + fp = Bfopen(fn,"wt"); + if (!fp) return -1; + + Bfprintf(fp, + "; Video mode selection\n" + "; 0 - Windowed\n" + "; 1 - Fullscreen\n" + "fullscreen = %ld\n" + "\n" + "; Video resolution\n" + "xdim2d = %ld\n" + "ydim2d = %ld\n" + "xdim3d = %ld\n" + "ydim3d = %ld\n" + "\n" + "; 3D-mode colour depth\n" + "bpp = %ld\n" + "\n" + "; OpenGL mode options\n" + "glusetexcache = %ld\n" + "glusetexcachecompression = %ld\n" + "\n" +#ifdef RENDERTYPEWIN + "; Maximum OpenGL mode refresh rate (Windows only, in Hertz)\n" + "maxrefreshfreq = %d\n" + "\n" +#endif + "; 3D mode brightness setting\n" + "; 0 - lowest\n" + "; 15 - highest\n" + "brightness = %d\n" + "\n" + "; Sound sample frequency\n" + "; 0 - 6 KHz\n" + "; 1 - 8 KHz\n" + "; 2 - 11.025 KHz\n" + "; 3 - 16 KHz\n" + "; 4 - 22.05 KHz\n" + "; 5 - 32 KHz\n" + "; 6 - 44.1 KHz\n" + "samplerate = %d\n" + "\n" + "; Music playback\n" + "; 0 - Off\n" + "; 1 - On\n" + "music = %d\n" + "\n" + "; Enable mouse\n" + "; 0 - No\n" + "; 1 - Yes\n" + "mouse = %d\n" + "\n" + "; Mouse sensitivity\n" + "mousesensitivity = %g\n" + "\n" + "; Key Settings\n" + "; Here's a map of all the keyboard scan codes: NOTE: values are listed in hex!\n" + "; +---------------------------------------------------------------------------------------------+\n" + "; | 01 3B 3C 3D 3E 3F 40 41 42 43 44 57 58 46 |\n" + "; |ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 SCROLL |\n" + "; | |\n" + "; |29 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E D2 C7 C9 45 B5 37 4A |\n" + "; | ` '1' '2' '3' '4' '5' '6' '7' '8' '9' '0' - = BACK INS HOME PGUP NUMLK KP/ KP* KP- |\n" + "; | |\n" + "; | 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 2B D3 CF D1 47 48 49 4E |\n" + "; |TAB Q W E R T Y U I O P [ ] \\ DEL END PGDN KP7 KP8 KP9 KP+ |\n" + "; | |\n" + "; | 3A 1E 1F 20 21 22 23 24 25 26 27 28 1C 4B 4C 4D |\n" + "; |CAPS A S D F G H J K L ; ' ENTER KP4 KP5 KP6 9C |\n" + "; | KPENTER|\n" + "; | 2A 2C 2D 2E 2F 30 31 32 33 34 35 36 C8 4F 50 51 |\n" + "; |LSHIFT Z X C V B N M , . / RSHIFT UP KP1 KP2 KP3 |\n" + "; | |\n" + "; | 1D 38 39 B8 9D CB D0 CD 52 53 |\n" + "; |LCTRL LALT SPACE RALT RCTRL LEFT DOWN RIGHT KP0 KP. |\n" + "; +---------------------------------------------------------------------------------------------+\n" + "\n" + "keyforward = %X\n" + "keybackward = %X\n" + "keyturnleft = %X\n" + "keyturnright = %X\n" + "keyrun = %X\n" + "keystrafe = %X\n" + "keyfire = %X\n" + "keyuse = %X\n" + "keystandhigh = %X\n" + "keystandlow = %X\n" + "keylookup = %X\n" + "keylookdown = %X\n" + "keystrafeleft = %X\n" + "keystraferight = %X\n" + "key2dmode = %X\n" + "keyviewcycle = %X\n" + "key2dzoomin = %X\n" + "key2dzoomout = %X\n" + "keychat = %X\n" + "keyconsole = %X\n" + "\n", + + fullscreen, xdim2d, ydim2d, xdimgame, ydimgame, bppgame, + glusetexcache, glusetexcachecompression, +#ifdef RENDERTYPEWIN + maxrefreshfreq, +#endif + brightness, option[7]>>4, option[2], + option[3], msens, + keys[0], keys[1], keys[2], keys[3], keys[4], keys[5], + keys[6], keys[7], keys[8], keys[9], keys[10], keys[11], + keys[12], keys[13], keys[14], keys[15], keys[16], keys[17], + keys[18], keys[19] + ); + + Bfclose(fp); + + return 0; +} diff --git a/polymer/build/src/crc32.c b/polymer/build/src/crc32.c index 5966dcfd3..6cfa1dfa4 100644 --- a/polymer/build/src/crc32.c +++ b/polymer/build/src/crc32.c @@ -1,104 +1,104 @@ -#include "crc32.h" - -/* -// this table of numbers is borrowed from the InfoZip source. -static unsigned long crc32table[256] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL -}; -*/ - -static unsigned long crc32table[256]; - -void initcrc32table(void) -{ - unsigned long i,j,k; - - // algorithm and polynomial same as that used by infozip's zip - for (i=0; i<256; i++) { - j = i; - for (k=8; k; k--) - j = (j&1) ? (0xedb88320L ^ (j>>1)) : (j>>1); - crc32table[i] = j; - } -} - - -unsigned long crc32once(unsigned char *blk, unsigned long len) -{ - unsigned long crc; - - crc32init(&crc); - crc32block(&crc, blk, len); - return crc32finish(&crc); -} - -void crc32init(unsigned long *crcvar) -{ - if (!crcvar) return; - *crcvar = 0xffffffffl; -} - -void crc32block(unsigned long *crcvar, unsigned char *blk, unsigned long len) -{ - unsigned long crc = *crcvar; - while (len--) crc = crc32table[(crc ^ *(blk++)) & 0xffl] ^ (crc >> 8); - *crcvar = crc; -} - -unsigned long crc32finish(unsigned long *crcvar) -{ - *crcvar = *crcvar ^ 0xffffffffl; - return *crcvar; -} - +#include "crc32.h" + +/* +// this table of numbers is borrowed from the InfoZip source. +static unsigned long crc32table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; +*/ + +static unsigned long crc32table[256]; + +void initcrc32table(void) +{ + unsigned long i,j,k; + + // algorithm and polynomial same as that used by infozip's zip + for (i=0; i<256; i++) { + j = i; + for (k=8; k; k--) + j = (j&1) ? (0xedb88320L ^ (j>>1)) : (j>>1); + crc32table[i] = j; + } +} + + +unsigned long crc32once(unsigned char *blk, unsigned long len) +{ + unsigned long crc; + + crc32init(&crc); + crc32block(&crc, blk, len); + return crc32finish(&crc); +} + +void crc32init(unsigned long *crcvar) +{ + if (!crcvar) return; + *crcvar = 0xffffffffl; +} + +void crc32block(unsigned long *crcvar, unsigned char *blk, unsigned long len) +{ + unsigned long crc = *crcvar; + while (len--) crc = crc32table[(crc ^ *(blk++)) & 0xffl] ^ (crc >> 8); + *crcvar = crc; +} + +unsigned long crc32finish(unsigned long *crcvar) +{ + *crcvar = *crcvar ^ 0xffffffffl; + return *crcvar; +} + diff --git a/polymer/build/src/defs.c b/polymer/build/src/defs.c index 40511a2c6..bd17bac52 100644 --- a/polymer/build/src/defs.c +++ b/polymer/build/src/defs.c @@ -1,1077 +1,1077 @@ -/* - * Definitions file parser for Build - * by Jonathon Fowler (jonof@edgenetwork.org) - * Remixed substantially by Ken Silverman - * See the included license file "BUILDLIC.TXT" for license info. - */ - -#include "build.h" -#include "compat.h" -#include "baselayer.h" -#include "scriptfile.h" +/* + * Definitions file parser for Build + * by Jonathon Fowler (jonof@edgenetwork.org) + * Remixed substantially by Ken Silverman + * See the included license file "BUILDLIC.TXT" for license info. + */ + +#include "build.h" +#include "compat.h" +#include "baselayer.h" +#include "scriptfile.h" #include "cache1d.h" -enum { - T_EOF = -2, - T_ERROR = -1, - T_INCLUDE = 0, - T_DEFINE, - T_DEFINETEXTURE, - T_DEFINESKYBOX, - T_DEFINETINT, - T_DEFINEMODEL, - T_DEFINEMODELFRAME, - T_DEFINEMODELANIM, - T_DEFINEMODELSKIN, - T_SELECTMODELSKIN, - T_DEFINEVOXEL, - T_DEFINEVOXELTILES, - T_MODEL, - T_FILE, - T_SCALE, - T_SHADE, - T_FRAME, - T_ANIM, - T_SKIN, - T_SURF, - T_TILE, - T_TILE0, - T_TILE1, - T_FRAME0, - T_FRAME1, - T_FPS, - T_FLAGS, - T_PAL, - T_HUD, - T_XADD, - T_YADD, - T_ZADD, - T_ANGADD, - T_FLIPPED, - T_HIDE, - T_NOBOB, - T_NODEPTH, - T_VOXEL, - T_SKYBOX, - T_FRONT,T_RIGHT,T_BACK,T_LEFT,T_TOP,T_BOTTOM, - T_TINT,T_RED,T_GREEN,T_BLUE, - T_TEXTURE,T_ALPHACUT,T_NOCOMPRESS, - T_UNDEFMODEL,T_UNDEFMODELRANGE,T_UNDEFMODELOF,T_UNDEFTEXTURE,T_UNDEFTEXTURERANGE, +enum { + T_EOF = -2, + T_ERROR = -1, + T_INCLUDE = 0, + T_DEFINE, + T_DEFINETEXTURE, + T_DEFINESKYBOX, + T_DEFINETINT, + T_DEFINEMODEL, + T_DEFINEMODELFRAME, + T_DEFINEMODELANIM, + T_DEFINEMODELSKIN, + T_SELECTMODELSKIN, + T_DEFINEVOXEL, + T_DEFINEVOXELTILES, + T_MODEL, + T_FILE, + T_SCALE, + T_SHADE, + T_FRAME, + T_ANIM, + T_SKIN, + T_SURF, + T_TILE, + T_TILE0, + T_TILE1, + T_FRAME0, + T_FRAME1, + T_FPS, + T_FLAGS, + T_PAL, + T_HUD, + T_XADD, + T_YADD, + T_ZADD, + T_ANGADD, + T_FLIPPED, + T_HIDE, + T_NOBOB, + T_NODEPTH, + T_VOXEL, + T_SKYBOX, + T_FRONT,T_RIGHT,T_BACK,T_LEFT,T_TOP,T_BOTTOM, + T_TINT,T_RED,T_GREEN,T_BLUE, + T_TEXTURE,T_ALPHACUT,T_NOCOMPRESS, + T_UNDEFMODEL,T_UNDEFMODELRANGE,T_UNDEFMODELOF,T_UNDEFTEXTURE,T_UNDEFTEXTURERANGE, T_ALPHAHACK,T_ALPHAHACKRANGE, T_SPRITECOL,T_2DCOL, T_FOGPAL, T_LOADGRP, -}; - -typedef struct { char *text; int tokenid; } tokenlist; -static tokenlist basetokens[] = -{ - { "include", T_INCLUDE }, - { "#include", T_INCLUDE }, - { "define", T_DEFINE }, - { "#define", T_DEFINE }, - - // deprecated style - { "definetexture", T_DEFINETEXTURE }, - { "defineskybox", T_DEFINESKYBOX }, - { "definetint", T_DEFINETINT }, - { "definemodel", T_DEFINEMODEL }, - { "definemodelframe",T_DEFINEMODELFRAME }, - { "definemodelanim", T_DEFINEMODELANIM }, - { "definemodelskin", T_DEFINEMODELSKIN }, - { "selectmodelskin", T_SELECTMODELSKIN }, - { "definevoxel", T_DEFINEVOXEL }, - { "definevoxeltiles",T_DEFINEVOXELTILES }, - - // new style +}; - { "model", T_MODEL }, - { "voxel", T_VOXEL }, - { "skybox", T_SKYBOX }, - { "tint", T_TINT }, - { "texture", T_TEXTURE }, +typedef struct { char *text; int tokenid; } tokenlist; +static tokenlist basetokens[] = +{ + { "include", T_INCLUDE }, + { "#include", T_INCLUDE }, + { "define", T_DEFINE }, + { "#define", T_DEFINE }, + + // deprecated style + { "definetexture", T_DEFINETEXTURE }, + { "defineskybox", T_DEFINESKYBOX }, + { "definetint", T_DEFINETINT }, + { "definemodel", T_DEFINEMODEL }, + { "definemodelframe",T_DEFINEMODELFRAME }, + { "definemodelanim", T_DEFINEMODELANIM }, + { "definemodelskin", T_DEFINEMODELSKIN }, + { "selectmodelskin", T_SELECTMODELSKIN }, + { "definevoxel", T_DEFINEVOXEL }, + { "definevoxeltiles",T_DEFINEVOXELTILES }, + + // new style + + { "model", T_MODEL }, + { "voxel", T_VOXEL }, + { "skybox", T_SKYBOX }, + { "tint", T_TINT }, + { "texture", T_TEXTURE }, { "tile", T_TEXTURE }, - // other stuff - { "undefmodel", T_UNDEFMODEL }, - { "undefmodelrange", T_UNDEFMODELRANGE }, - { "undefmodelof", T_UNDEFMODELOF }, + // other stuff + { "undefmodel", T_UNDEFMODEL }, + { "undefmodelrange", T_UNDEFMODELRANGE }, + { "undefmodelof", T_UNDEFMODELOF }, { "undeftexture", T_UNDEFTEXTURE }, - { "undeftexturerange", T_UNDEFTEXTURERANGE }, + { "undeftexturerange", T_UNDEFTEXTURERANGE }, { "alphahack", T_ALPHAHACK }, { "alphahackrange", T_ALPHAHACKRANGE }, { "spritecol", T_SPRITECOL }, { "2dcol", T_2DCOL }, { "fogpal", T_FOGPAL }, { "loadgrp", T_LOADGRP }, -}; - -static tokenlist modeltokens[] = { - { "scale", T_SCALE }, - { "shade", T_SHADE }, - { "zadd", T_ZADD }, - { "frame", T_FRAME }, - { "anim", T_ANIM }, - { "skin", T_SKIN }, - { "hud", T_HUD }, -}; - -static tokenlist modelframetokens[] = { - { "frame", T_FRAME }, - { "name", T_FRAME }, - { "tile", T_TILE }, - { "tile0", T_TILE0 }, - { "tile1", T_TILE1 }, -}; - -static tokenlist modelanimtokens[] = { - { "frame0", T_FRAME0 }, - { "frame1", T_FRAME1 }, - { "fps", T_FPS }, - { "flags", T_FLAGS }, -}; - -static tokenlist modelskintokens[] = { - { "pal", T_PAL }, - { "file", T_FILE }, - { "surf", T_SURF }, - { "surface",T_SURF }, -}; - -static tokenlist modelhudtokens[] = { - { "tile", T_TILE }, - { "tile0", T_TILE0 }, - { "tile1", T_TILE1 }, - { "xadd", T_XADD }, - { "yadd", T_YADD }, - { "zadd", T_ZADD }, - { "angadd", T_ANGADD }, - { "hide", T_HIDE }, - { "nobob", T_NOBOB }, - { "flipped",T_FLIPPED}, - { "nodepth",T_NODEPTH}, -}; - -static tokenlist voxeltokens[] = { - { "tile", T_TILE }, - { "tile0", T_TILE0 }, - { "tile1", T_TILE1 }, - { "scale", T_SCALE }, -}; - -static tokenlist skyboxtokens[] = { - { "tile" ,T_TILE }, - { "pal" ,T_PAL }, - { "ft" ,T_FRONT },{ "front" ,T_FRONT },{ "forward",T_FRONT }, - { "rt" ,T_RIGHT },{ "right" ,T_RIGHT }, - { "bk" ,T_BACK },{ "back" ,T_BACK }, - { "lf" ,T_LEFT },{ "left" ,T_LEFT },{ "lt" ,T_LEFT }, - { "up" ,T_TOP },{ "top" ,T_TOP },{ "ceiling",T_TOP },{ "ceil" ,T_TOP }, - { "dn" ,T_BOTTOM },{ "bottom" ,T_BOTTOM },{ "floor" ,T_BOTTOM },{ "down" ,T_BOTTOM } -}; - -static tokenlist tinttokens[] = { - { "pal", T_PAL }, - { "red", T_RED },{ "r", T_RED }, - { "green", T_GREEN },{ "g", T_GREEN }, - { "blue", T_BLUE },{ "b", T_BLUE }, - { "flags", T_FLAGS } -}; - -static tokenlist texturetokens[] = { - { "pal", T_PAL }, -}; -static tokenlist texturetokens_pal[] = { - { "file", T_FILE },{ "name", T_FILE }, - { "alphacut", T_ALPHACUT }, - { "nocompress",T_NOCOMPRESS }, -}; - -static int getatoken(scriptfile *sf, tokenlist *tl, int ntokens) -{ - char *tok; - int i; - - if (!sf) return T_ERROR; - tok = scriptfile_gettoken(sf); - if (!tok) return T_EOF; - - for(i=0;iltextptr; - switch (tokn) { - case T_ERROR: - initprintf("Error on line %s:%d.\n", script->filename,scriptfile_getlinum(script,cmdtokptr)); - break; - case T_EOF: - return(0); - case T_INCLUDE: - { - char *fn; - if (!scriptfile_getstring(script,&fn)) { - scriptfile *included; - - included = scriptfile_fromfile(fn); - if (!included) { - initprintf("Warning: Failed including %s on line %s:%d\n", - fn, script->filename,scriptfile_getlinum(script,cmdtokptr)); - } else { - defsparser(included); - scriptfile_close(included); - } - } - break; - } - case T_DEFINE: - { - char *name; - int number; - - if (scriptfile_getstring(script,&name)) break; - if (scriptfile_getsymbol(script,&number)) break; - - if (scriptfile_addsymbolvalue(name,number) < 0) - initprintf("Warning: Symbol %s was NOT redefined to %d on line %s:%d\n", - name,number,script->filename,scriptfile_getlinum(script,cmdtokptr)); - break; - } - - // OLD (DEPRECATED) DEFINITION SYNTAX - case T_DEFINETEXTURE: - { - int tile,pal,fnoo; - char *fn; - - if (scriptfile_getsymbol(script,&tile)) break; - if (scriptfile_getsymbol(script,&pal)) break; - if (scriptfile_getnumber(script,&fnoo)) break; //x-center - if (scriptfile_getnumber(script,&fnoo)) break; //y-center - if (scriptfile_getnumber(script,&fnoo)) break; //x-size - if (scriptfile_getnumber(script,&fnoo)) break; //y-size - if (scriptfile_getstring(script,&fn)) break; - hicsetsubsttex(tile,pal,fn,-1.0,0); - } - break; - case T_DEFINESKYBOX: - { - int tile,pal,i; - char *fn[6]; - - if (scriptfile_getsymbol(script,&tile)) break; - if (scriptfile_getsymbol(script,&pal)) break; - if (scriptfile_getsymbol(script,&i)) break; //future expansion - for (i=0;i<6;i++) if (scriptfile_getstring(script,&fn[i])) break; //grab the 6 faces - if (i < 6) break; - hicsetskybox(tile,pal,fn); - } - break; - case T_DEFINETINT: - { - int pal, r,g,b,f; - - if (scriptfile_getsymbol(script,&pal)) break; - if (scriptfile_getnumber(script,&r)) break; - if (scriptfile_getnumber(script,&g)) break; - if (scriptfile_getnumber(script,&b)) break; - if (scriptfile_getnumber(script,&f)) break; //effects - hicsetpalettetint(pal,r,g,b,f); - } - break; - case T_ALPHAHACK: - { - int tile; - double alpha; - - if (scriptfile_getsymbol(script,&tile)) break; - if (scriptfile_getdouble(script,&alpha)) break; - if ((unsigned long)tile < MAXTILES) alphahackarray[tile] = alpha; - } +static const char *skyfaces[6] = { + "front face", "right face", "back face", + "left face", "top face", "bottom face" +}; + +static int defsparser(scriptfile *script) +{ + int tokn; + char *cmdtokptr; + while (1) { + tokn = getatoken(script,basetokens,sizeof(basetokens)/sizeof(tokenlist)); + cmdtokptr = script->ltextptr; + switch (tokn) { + case T_ERROR: + initprintf("Error on line %s:%d.\n", script->filename,scriptfile_getlinum(script,cmdtokptr)); break; - case T_ALPHAHACKRANGE: - { - int tilenume1,tilenume2,i; - double alpha; - - if (scriptfile_getsymbol(script,&tilenume1)) break; - if (scriptfile_getsymbol(script,&tilenume2)) break; + case T_EOF: + return(0); + case T_INCLUDE: + { + char *fn; + if (!scriptfile_getstring(script,&fn)) { + scriptfile *included; + + included = scriptfile_fromfile(fn); + if (!included) { + initprintf("Warning: Failed including %s on line %s:%d\n", + fn, script->filename,scriptfile_getlinum(script,cmdtokptr)); + } else { + defsparser(included); + scriptfile_close(included); + } + } + break; + } + case T_DEFINE: + { + char *name; + int number; + + if (scriptfile_getstring(script,&name)) break; + if (scriptfile_getsymbol(script,&number)) break; + + if (scriptfile_addsymbolvalue(name,number) < 0) + initprintf("Warning: Symbol %s was NOT redefined to %d on line %s:%d\n", + name,number,script->filename,scriptfile_getlinum(script,cmdtokptr)); + break; + } + + // OLD (DEPRECATED) DEFINITION SYNTAX + case T_DEFINETEXTURE: + { + int tile,pal,fnoo; + char *fn; + + if (scriptfile_getsymbol(script,&tile)) break; + if (scriptfile_getsymbol(script,&pal)) break; + if (scriptfile_getnumber(script,&fnoo)) break; //x-center + if (scriptfile_getnumber(script,&fnoo)) break; //y-center + if (scriptfile_getnumber(script,&fnoo)) break; //x-size + if (scriptfile_getnumber(script,&fnoo)) break; //y-size + if (scriptfile_getstring(script,&fn)) break; + hicsetsubsttex(tile,pal,fn,-1.0,0); + } + break; + case T_DEFINESKYBOX: + { + int tile,pal,i; + char *fn[6]; + + if (scriptfile_getsymbol(script,&tile)) break; + if (scriptfile_getsymbol(script,&pal)) break; + if (scriptfile_getsymbol(script,&i)) break; //future expansion + for (i=0;i<6;i++) if (scriptfile_getstring(script,&fn[i])) break; //grab the 6 faces + if (i < 6) break; + hicsetskybox(tile,pal,fn); + } + break; + case T_DEFINETINT: + { + int pal, r,g,b,f; + + if (scriptfile_getsymbol(script,&pal)) break; + if (scriptfile_getnumber(script,&r)) break; + if (scriptfile_getnumber(script,&g)) break; + if (scriptfile_getnumber(script,&b)) break; + if (scriptfile_getnumber(script,&f)) break; //effects + hicsetpalettetint(pal,r,g,b,f); + } + break; + case T_ALPHAHACK: + { + int tile; + double alpha; + + if (scriptfile_getsymbol(script,&tile)) break; if (scriptfile_getdouble(script,&alpha)) break; - if (tilenume2 < tilenume1) { + if ((unsigned long)tile < MAXTILES) alphahackarray[tile] = alpha; + } + break; + case T_ALPHAHACKRANGE: + { + int tilenume1,tilenume2,i; + double alpha; + + if (scriptfile_getsymbol(script,&tilenume1)) break; + if (scriptfile_getsymbol(script,&tilenume2)) break; + if (scriptfile_getdouble(script,&alpha)) break; + if (tilenume2 < tilenume1) { initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); - i = tilenume2; - tilenume2 = tilenume1; - tilenume1 = i; + i = tilenume2; + tilenume2 = tilenume1; + tilenume1 = i; } if ((tilenume1 >= 0 && tilenume1 < MAXTILES) && (tilenume2 >= 0 && tilenume2 < MAXTILES)) { for (i=tilenume1;i<=tilenume2;i++) - { + { if ((unsigned long)i < MAXTILES) alphahackarray[i] = alpha; } } - } - break; - case T_SPRITECOL: - { + } + break; + case T_SPRITECOL: + { int tile,col,type; - - if (scriptfile_getsymbol(script,&tile)) break; + + if (scriptfile_getsymbol(script,&tile)) break; if (scriptfile_getnumber(script,&col)) break; - if (scriptfile_getnumber(script,&type)) break; - if ((unsigned long)tile < MAXTILES) spritecol2d[tile][type] = col; - } - break; - case T_2DCOL: - { + if (scriptfile_getnumber(script,&type)) break; + if ((unsigned long)tile < MAXTILES) spritecol2d[tile][type] = col; + } + break; + case T_2DCOL: + { int col,b,g,r; - + if (scriptfile_getnumber(script,&col)) break; - if (scriptfile_getnumber(script,&r)) break; - if (scriptfile_getnumber(script,&g)) break; - if (scriptfile_getnumber(script,&b)) break; - + if (scriptfile_getnumber(script,&r)) break; + if (scriptfile_getnumber(script,&g)) break; + if (scriptfile_getnumber(script,&b)) break; + if (col < 256) { vgapal16[col*4+0] = b; // blue vgapal16[col*4+1] = g; // green vgapal16[col*4+2] = r; // red - } - } + } + } break; - case T_FOGPAL: - { + case T_FOGPAL: + { int p,r,g,b,j; char tempbuf[256]; if (scriptfile_getnumber(script,&p)) break; - if (scriptfile_getnumber(script,&r)) break; - if (scriptfile_getnumber(script,&g)) break; + if (scriptfile_getnumber(script,&r)) break; + if (scriptfile_getnumber(script,&g)) break; if (scriptfile_getnumber(script,&b)) break; for (j = 0; j < 256; j++) tempbuf[j] = j; makepalookup(p, tempbuf, r, g, b, 1); - } + } break; - case T_LOADGRP: - { - char *bs; + case T_LOADGRP: + { + char *bs; scriptfile_getstring(script,&bs); - } - break; - case T_DEFINEMODEL: - { - char *modelfn; - double scale; - int shadeoffs; - - if (scriptfile_getstring(script,&modelfn)) break; - if (scriptfile_getdouble(script,&scale)) break; - if (scriptfile_getnumber(script,&shadeoffs)) break; - -#if defined(POLYMOST) && defined(USE_OPENGL) - lastmodelid = md_loadmodel(modelfn); - if (lastmodelid < 0) { - initprintf("Failure loading MD2/MD3 model \"%s\"\n", modelfn); - break; - } - md_setmisc(lastmodelid,(float)scale, shadeoffs,0.0); -#endif - modelskin = lastmodelskin = 0; - seenframe = 0; - } - break; - case T_DEFINEMODELFRAME: - { - char *framename, happy=1; - int ftilenume, ltilenume, tilex; - - if (scriptfile_getstring(script,&framename)) break; - if (scriptfile_getnumber(script,&ftilenume)) break; //first tile number - if (scriptfile_getnumber(script,<ilenume)) break; //last tile number (inclusive) - if (ltilenume < ftilenume) { - initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); - tilex = ftilenume; - ftilenume = ltilenume; - ltilenume = tilex; - } - - if (lastmodelid < 0) { - initprintf("Warning: Ignoring frame definition.\n"); - break; - } -#if defined(POLYMOST) && defined(USE_OPENGL) - for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++) { - switch (md_defineframe(lastmodelid, framename, tilex, max(0,modelskin))) { - case 0: break; - case -1: happy = 0; break; // invalid model id!? - case -2: initprintf("Invalid tile number on line %s:%d\n", - script->filename, scriptfile_getlinum(script,cmdtokptr)); - happy = 0; - break; - case -3: initprintf("Invalid frame name on line %s:%d\n", - script->filename, scriptfile_getlinum(script,cmdtokptr)); - happy = 0; - break; - } - } -#endif - seenframe = 1; - } - break; - case T_DEFINEMODELANIM: - { - char *startframe, *endframe; - int flags; - double dfps; - - if (scriptfile_getstring(script,&startframe)) break; - if (scriptfile_getstring(script,&endframe)) break; - if (scriptfile_getdouble(script,&dfps)) break; //animation frame rate - if (scriptfile_getnumber(script,&flags)) break; - - if (lastmodelid < 0) { - initprintf("Warning: Ignoring animation definition.\n"); - break; - } -#if defined(POLYMOST) && defined(USE_OPENGL) - switch (md_defineanimation(lastmodelid, startframe, endframe, (int)(dfps*(65536.0*.001)), flags)) { - case 0: break; - case -1: break; // invalid model id!? - case -2: initprintf("Invalid starting frame name on line %s:%d\n", - script->filename, scriptfile_getlinum(script,cmdtokptr)); - break; - case -3: initprintf("Invalid ending frame name on line %s:%d\n", - script->filename, scriptfile_getlinum(script,cmdtokptr)); - break; - case -4: initprintf("Out of memory on line %s:%d\n", - script->filename, scriptfile_getlinum(script,cmdtokptr)); - break; - } -#endif - } - break; - case T_DEFINEMODELSKIN: - { - int palnum, palnumer; - char *skinfn; - - if (scriptfile_getsymbol(script,&palnum)) break; - if (scriptfile_getstring(script,&skinfn)) break; //skin filename - - // if we see a sequence of definemodelskin, then a sequence of definemodelframe, - // and then a definemodelskin, we need to increment the skin counter. - // - // definemodel "mymodel.md2" 1 1 - // definemodelskin 0 "normal.png" // skin 0 - // definemodelskin 21 "normal21.png" - // definemodelframe "foo" 1000 1002 // these use skin 0 - // definemodelskin 0 "wounded.png" // skin 1 - // definemodelskin 21 "wounded21.png" - // definemodelframe "foo2" 1003 1004 // these use skin 1 - // selectmodelskin 0 // resets to skin 0 - // definemodelframe "foo3" 1005 1006 // these use skin 0 - if (seenframe) { modelskin = ++lastmodelskin; } - seenframe = 0; - -#if defined(POLYMOST) && defined(USE_OPENGL) - switch (md_defineskin(lastmodelid, skinfn, palnum, max(0,modelskin), 0)) { - case 0: break; - case -1: break; // invalid model id!? - case -2: initprintf("Invalid skin filename on line %s:%d\n", - script->filename, scriptfile_getlinum(script,cmdtokptr)); - break; - case -3: initprintf("Invalid palette number on line %s:%d\n", - script->filename, scriptfile_getlinum(script,cmdtokptr)); - break; - case -4: initprintf("Out of memory on line %s:%d\n", - script->filename, scriptfile_getlinum(script,cmdtokptr)); - break; - } -#endif - } - break; - case T_SELECTMODELSKIN: - { - if (scriptfile_getsymbol(script,&modelskin)) break; - } - break; - case T_DEFINEVOXEL: - { - char *fn; - - if (scriptfile_getstring(script,&fn)) break; //voxel filename - - if (nextvoxid == MAXVOXELS) { - initprintf("Maximum number of voxels already defined.\n"); - break; - } - -#ifdef SUPERBUILD - if (qloadkvx(nextvoxid, fn)) { - initprintf("Failure loading voxel file \"%s\"\n",fn); - break; - } - - lastvoxid = nextvoxid++; -#endif - } - break; - case T_DEFINEVOXELTILES: - { - int ftilenume, ltilenume, tilex; - - if (scriptfile_getnumber(script,&ftilenume)) break; //1st tile # - if (scriptfile_getnumber(script,<ilenume)) break; //last tile # - - if (ltilenume < ftilenume) { - initprintf("Warning: backwards tile range on line %s:%d\n", - script->filename, scriptfile_getlinum(script,cmdtokptr)); - tilex = ftilenume; - ftilenume = ltilenume; - ltilenume = tilex; - } - if (ltilenume < 0 || ftilenume >= MAXTILES) { - initprintf("Invalid tile range on line %s:%d\n", - script->filename, scriptfile_getlinum(script,cmdtokptr)); - break; - } - - if (lastvoxid < 0) { - initprintf("Warning: Ignoring voxel tiles definition.\n"); - break; - } -#ifdef SUPERBUILD - for (tilex = ftilenume; tilex <= ltilenume; tilex++) { - tiletovox[tilex] = lastvoxid; - } -#endif - } - break; - - // NEW (ENCOURAGED) DEFINITION SYNTAX - case T_MODEL: - { - char *modelend, *modelfn; - double scale=1.0, mzadd=0.0; - int shadeoffs=0; - - modelskin = lastmodelskin = 0; - seenframe = 0; - - if (scriptfile_getstring(script,&modelfn)) break; - -#if defined(POLYMOST) && defined(USE_OPENGL) - lastmodelid = md_loadmodel(modelfn); - if (lastmodelid < 0) { - initprintf("Failure loading MD2/MD3 model \"%s\"\n", modelfn); - break; - } -#endif - if (scriptfile_getbraces(script,&modelend)) break; - while (script->textptr < modelend) { - switch (getatoken(script,modeltokens,sizeof(modeltokens)/sizeof(tokenlist))) { - //case T_ERROR: initprintf("Error on line %s:%d in model tokens\n", script->filename,script->linenum); break; - case T_SCALE: scriptfile_getdouble(script,&scale); break; - case T_SHADE: scriptfile_getnumber(script,&shadeoffs); break; - case T_ZADD: scriptfile_getdouble(script,&mzadd); break; - case T_FRAME: - { - char *frametokptr = script->ltextptr; - char *frameend, *framename = 0, happy=1; - int ftilenume = -1, ltilenume = -1, tilex = 0; - - if (scriptfile_getbraces(script,&frameend)) break; - while (script->textptr < frameend) { - switch(getatoken(script,modelframetokens,sizeof(modelframetokens)/sizeof(tokenlist))) { - case T_FRAME: scriptfile_getstring(script,&framename); break; - case T_TILE: scriptfile_getsymbol(script,&ftilenume); ltilenume = ftilenume; break; - case T_TILE0: scriptfile_getsymbol(script,&ftilenume); break; //first tile number - case T_TILE1: scriptfile_getsymbol(script,<ilenume); break; //last tile number (inclusive) - } - } - - if (ftilenume < 0) initprintf("Error: missing 'first tile number' for frame definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,frametokptr)), happy = 0; - if (ltilenume < 0) initprintf("Error: missing 'last tile number' for frame definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,frametokptr)), happy = 0; - if (!happy) break; - - if (ltilenume < ftilenume) { - initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,frametokptr)); - tilex = ftilenume; - ftilenume = ltilenume; - ltilenume = tilex; - } - - if (lastmodelid < 0) { - initprintf("Warning: Ignoring frame definition.\n"); - break; - } -#if defined(POLYMOST) && defined(USE_OPENGL) - for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++) { - switch (md_defineframe(lastmodelid, framename, tilex, max(0,modelskin))) { - case 0: break; - case -1: happy = 0; break; // invalid model id!? - case -2: initprintf("Invalid tile number on line %s:%d\n", - script->filename, scriptfile_getlinum(script,frametokptr)); - happy = 0; - break; - case -3: initprintf("Invalid frame name on line %s:%d\n", - script->filename, scriptfile_getlinum(script,frametokptr)); - happy = 0; - break; - } - } -#endif - seenframe = 1; - } - break; - case T_ANIM: - { - char *animtokptr = script->ltextptr; - char *animend, *startframe = 0, *endframe = 0, happy=1; - int flags = 0; - double dfps = 1.0; - - if (scriptfile_getbraces(script,&animend)) break; - while (script->textptr < animend) { - switch(getatoken(script,modelanimtokens,sizeof(modelanimtokens)/sizeof(tokenlist))) { - case T_FRAME0: scriptfile_getstring(script,&startframe); break; - case T_FRAME1: scriptfile_getstring(script,&endframe); break; - case T_FPS: scriptfile_getdouble(script,&dfps); break; //animation frame rate - case T_FLAGS: scriptfile_getsymbol(script,&flags); break; - } - } - - if (!startframe) initprintf("Error: missing 'start frame' for anim definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,animtokptr)), happy = 0; - if (!endframe) initprintf("Error: missing 'end frame' for anim definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,animtokptr)), happy = 0; - if (!happy) break; - - if (lastmodelid < 0) { - initprintf("Warning: Ignoring animation definition.\n"); - break; - } -#if defined(POLYMOST) && defined(USE_OPENGL) - switch (md_defineanimation(lastmodelid, startframe, endframe, (int)(dfps*(65536.0*.001)), flags)) { - case 0: break; - case -1: break; // invalid model id!? - case -2: initprintf("Invalid starting frame name on line %s:%d\n", - script->filename, scriptfile_getlinum(script,animtokptr)); - break; - case -3: initprintf("Invalid ending frame name on line %s:%d\n", - script->filename, scriptfile_getlinum(script,animtokptr)); - break; - case -4: initprintf("Out of memory on line %s:%d\n", - script->filename, scriptfile_getlinum(script,animtokptr)); - break; - } -#endif - } break; - case T_SKIN: - { - char *skintokptr = script->ltextptr; - char *skinend, *skinfn = 0; - int palnum = 0, surfnum = 0; - - if (scriptfile_getbraces(script,&skinend)) break; - while (script->textptr < skinend) { - switch(getatoken(script,modelskintokens,sizeof(modelskintokens)/sizeof(tokenlist))) { - case T_PAL: scriptfile_getsymbol(script,&palnum); break; - case T_FILE: scriptfile_getstring(script,&skinfn); break; //skin filename - case T_SURF: scriptfile_getnumber(script,&surfnum); break; - } - } - - if (!skinfn) { - initprintf("Error: missing 'skin filename' for skin definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,skintokptr)); - break; - } - - if (seenframe) { modelskin = ++lastmodelskin; } - seenframe = 0; - -#if defined(POLYMOST) && defined(USE_OPENGL) - switch (md_defineskin(lastmodelid, skinfn, palnum, max(0,modelskin), surfnum)) { - case 0: break; - case -1: break; // invalid model id!? - case -2: initprintf("Invalid skin filename on line %s:%d\n", - script->filename, scriptfile_getlinum(script,skintokptr)); - break; - case -3: initprintf("Invalid palette number on line %s:%d\n", - script->filename, scriptfile_getlinum(script,skintokptr)); - break; - case -4: initprintf("Out of memory on line %s:%d\n", - script->filename, scriptfile_getlinum(script,skintokptr)); - break; - } -#endif - } break; - case T_HUD: - { - char *hudtokptr = script->ltextptr; - char happy=1, *frameend; - int ftilenume = -1, ltilenume = -1, tilex = 0, flags = 0; - double xadd = 0.0, yadd = 0.0, zadd = 0.0, angadd = 0.0; - - if (scriptfile_getbraces(script,&frameend)) break; - while (script->textptr < frameend) { - switch(getatoken(script,modelhudtokens,sizeof(modelhudtokens)/sizeof(tokenlist))) { - case T_TILE: scriptfile_getsymbol(script,&ftilenume); ltilenume = ftilenume; break; - case T_TILE0: scriptfile_getsymbol(script,&ftilenume); break; //first tile number - case T_TILE1: scriptfile_getsymbol(script,<ilenume); break; //last tile number (inclusive) - case T_XADD: scriptfile_getdouble(script,&xadd); break; - case T_YADD: scriptfile_getdouble(script,&yadd); break; - case T_ZADD: scriptfile_getdouble(script,&zadd); break; - case T_ANGADD:scriptfile_getdouble(script,&angadd); break; - case T_HIDE: flags |= 1; break; - case T_NOBOB: flags |= 2; break; - case T_FLIPPED: flags |= 4; break; - case T_NODEPTH: flags |= 8; break; - } - } - - if (ftilenume < 0) initprintf("Error: missing 'first tile number' for hud definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,hudtokptr)), happy = 0; - if (ltilenume < 0) initprintf("Error: missing 'last tile number' for hud definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,hudtokptr)), happy = 0; - if (!happy) break; - - if (ltilenume < ftilenume) { - initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,hudtokptr)); - tilex = ftilenume; - ftilenume = ltilenume; - ltilenume = tilex; - } - - if (lastmodelid < 0) { - initprintf("Warning: Ignoring frame definition.\n"); - break; - } -#if defined(POLYMOST) && defined(USE_OPENGL) - for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++) { - switch (md_definehud(lastmodelid, tilex, xadd, yadd, zadd, angadd, flags)) { - case 0: break; - case -1: happy = 0; break; // invalid model id!? - case -2: initprintf("Invalid tile number on line %s:%d\n", - script->filename, scriptfile_getlinum(script,hudtokptr)); - happy = 0; - break; - case -3: initprintf("Invalid frame name on line %s:%d\n", - script->filename, scriptfile_getlinum(script,hudtokptr)); - happy = 0; - break; - } - } -#endif - } break; - } - } - -#if defined(POLYMOST) && defined(USE_OPENGL) - md_setmisc(lastmodelid,(float)scale,shadeoffs,(float)mzadd); -#endif - - modelskin = lastmodelskin = 0; - seenframe = 0; - - } - break; - case T_VOXEL: - { - char *voxeltokptr = script->ltextptr; - char *fn, *modelend; - int tile0 = MAXTILES, tile1 = -1, tilex = -1; - - if (scriptfile_getstring(script,&fn)) break; //voxel filename - if (nextvoxid == MAXVOXELS) { initprintf("Maximum number of voxels already defined.\n"); break; } -#ifdef SUPERBUILD - if (qloadkvx(nextvoxid, fn)) { initprintf("Failure loading voxel file \"%s\"\n",fn); break; } - lastvoxid = nextvoxid++; -#endif - - if (scriptfile_getbraces(script,&modelend)) break; - while (script->textptr < modelend) { - switch (getatoken(script,voxeltokens,sizeof(voxeltokens)/sizeof(tokenlist))) { - //case T_ERROR: initprintf("Error on line %s:%d in voxel tokens\n", script->filename,linenum); break; - case T_TILE: - scriptfile_getsymbol(script,&tilex); -#ifdef SUPERBUILD - if ((unsigned long)tilex < MAXTILES) tiletovox[tilex] = lastvoxid; - else initprintf("Invalid tile number on line %s:%d\n",script->filename, scriptfile_getlinum(script,voxeltokptr)); -#endif - break; - case T_TILE0: - scriptfile_getsymbol(script,&tile0); break; //1st tile # - case T_TILE1: - scriptfile_getsymbol(script,&tile1); - if (tile0 > tile1) - { - initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,voxeltokptr)); - tilex = tile0; tile0 = tile1; tile1 = tilex; - } - if ((tile1 < 0) || (tile0 >= MAXTILES)) - { initprintf("Invalid tile range on line %s:%d\n",script->filename, scriptfile_getlinum(script,voxeltokptr)); break; } -#ifdef SUPERBUILD - for(tilex=tile0;tilex<=tile1;tilex++) tiletovox[tilex] = lastvoxid; -#endif - break; //last tile number (inclusive) - case T_SCALE: { - double scale=1.0; - scriptfile_getdouble(script,&scale); -#ifdef SUPERBUILD - voxscale[lastvoxid] = 65536*scale; -#endif - break; - } - } - } - lastvoxid = -1; - } - break; - case T_SKYBOX: - { - char *skyboxtokptr = script->ltextptr; - char *fn[6] = {0,0,0,0,0,0}, *modelend, happy=1; - int i, tile = -1, pal = 0; - - if (scriptfile_getbraces(script,&modelend)) break; - while (script->textptr < modelend) { - switch (getatoken(script,skyboxtokens,sizeof(skyboxtokens)/sizeof(tokenlist))) { - //case T_ERROR: initprintf("Error on line %s:%d in skybox tokens\n",script->filename,linenum); break; - case T_TILE: scriptfile_getsymbol(script,&tile ); break; - case T_PAL: scriptfile_getsymbol(script,&pal ); break; - case T_FRONT: scriptfile_getstring(script,&fn[0]); break; - case T_RIGHT: scriptfile_getstring(script,&fn[1]); break; - case T_BACK: scriptfile_getstring(script,&fn[2]); break; - case T_LEFT: scriptfile_getstring(script,&fn[3]); break; - case T_TOP: scriptfile_getstring(script,&fn[4]); break; - case T_BOTTOM:scriptfile_getstring(script,&fn[5]); break; - } - } - - if (tile < 0) initprintf("Error: missing 'tile number' for skybox definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,skyboxtokptr)), happy=0; - for (i=0;i<6;i++) { - if (!fn[i]) initprintf("Error: missing '%s filename' for skybox definition near line %s:%d\n", skyfaces[i], script->filename, scriptfile_getlinum(script,skyboxtokptr)), happy = 0; - } - - if (!happy) break; - - hicsetskybox(tile,pal,fn); - } - break; - case T_TINT: - { - char *tinttokptr = script->ltextptr; - int red=255, green=255, blue=255, pal=-1, flags=0; - char *tintend; - - if (scriptfile_getbraces(script,&tintend)) break; - while (script->textptr < tintend) { - switch (getatoken(script,tinttokens,sizeof(tinttokens)/sizeof(tokenlist))) { - case T_PAL: scriptfile_getsymbol(script,&pal); break; - case T_RED: scriptfile_getnumber(script,&red); red = min(255,max(0,red)); break; - case T_GREEN: scriptfile_getnumber(script,&green); green = min(255,max(0,green)); break; - case T_BLUE: scriptfile_getnumber(script,&blue); blue = min(255,max(0,blue)); break; - case T_FLAGS: scriptfile_getsymbol(script,&flags); break; - } - } - - if (pal < 0) { - initprintf("Error: missing 'palette number' for tint definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,tinttokptr)); - break; - } - - hicsetpalettetint(pal,red,green,blue,flags); - } - break; - case T_TEXTURE: - { - char *texturetokptr = script->ltextptr, *textureend; - int tile=-1; - - if (scriptfile_getsymbol(script,&tile)) break; - if (scriptfile_getbraces(script,&textureend)) break; - while (script->textptr < textureend) { - switch (getatoken(script,texturetokens,sizeof(texturetokens)/sizeof(tokenlist))) { - case T_PAL: { - char *paltokptr = script->ltextptr, *palend; - int pal=-1; - char *fn = NULL; - double alphacut = -1.0; - char flags = 0; - - if (scriptfile_getsymbol(script,&pal)) break; - if (scriptfile_getbraces(script,&palend)) break; - while (script->textptr < palend) { - switch (getatoken(script,texturetokens_pal,sizeof(texturetokens_pal)/sizeof(tokenlist))) { - case T_FILE: scriptfile_getstring(script,&fn); break; - case T_ALPHACUT: scriptfile_getdouble(script,&alphacut); break; - case T_NOCOMPRESS: flags |= 1; break; - default: break; - } - } - - if ((unsigned)tile > (unsigned)MAXTILES) break; // message is printed later - if ((unsigned)pal > (unsigned)MAXPALOOKUPS) { - initprintf("Error: missing or invalid 'palette number' for texture definition near " - "line %s:%d\n", script->filename, scriptfile_getlinum(script,paltokptr)); - break; - } - if (!fn) { - initprintf("Error: missing 'file name' for texture definition near line %s:%d\n", - script->filename, scriptfile_getlinum(script,paltokptr)); - break; - } - hicsetsubsttex(tile,pal,fn,alphacut,flags); - } break; - default: break; - } - } - - if ((unsigned)tile >= (unsigned)MAXTILES) { - initprintf("Error: missing or invalid 'tile number' for texture definition near line %s:%d\n", - script->filename, scriptfile_getlinum(script,texturetokptr)); - break; - } - } - break; - - case T_UNDEFMODEL: - case T_UNDEFMODELRANGE: - { - int r0,r1; - - if (scriptfile_getsymbol(script,&r0)) break; - if (tokn == T_UNDEFMODELRANGE) { - if (scriptfile_getsymbol(script,&r1)) break; - if (r1 < r0) { - int t = r1; - r1 = r0; - r0 = t; - initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); - } - if (r0 < 0 || r1 >= MAXTILES) { - initprintf("Error: invalid tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); - break; - } - } else { - r1 = r0; - if ((unsigned)r0 >= (unsigned)MAXTILES) { - initprintf("Error: invalid tile number on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); - break; - } - } -#if defined(POLYMOST) && defined(USE_OPENGL) - for (; r0 <= r1; r0++) md_undefinetile(r0); -#endif - } - break; - - case T_UNDEFMODELOF: - { - int mid,r0; - - if (scriptfile_getsymbol(script,&r0)) break; - if ((unsigned)r0 >= (unsigned)MAXTILES) { - initprintf("Error: invalid tile number on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); - break; - } - -#if defined(POLYMOST) && defined(USE_OPENGL) - mid = md_tilehasmodel(r0); - if (mid < 0) break; - - md_undefinemodel(mid); -#endif - } - break; - - case T_UNDEFTEXTURE: - case T_UNDEFTEXTURERANGE: - { - int r0,r1,i; - - if (scriptfile_getsymbol(script,&r0)) break; - if (tokn == T_UNDEFTEXTURERANGE) { - if (scriptfile_getsymbol(script,&r1)) break; - if (r1 < r0) { - int t = r1; - r1 = r0; - r0 = t; - initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); - } - if (r0 < 0 || r1 >= MAXTILES) { - initprintf("Error: invalid tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); - break; - } - } else { - r1 = r0; - if ((unsigned)r0 >= (unsigned)MAXTILES) { - initprintf("Error: invalid tile number on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); - break; - } - } - - for (; r0 <= r1; r0++) - for (i=MAXPALOOKUPS-1; i>=0; i--) - hicclearsubst(r0,i); - } - break; - - default: - initprintf("Unknown token.\n"); break; - } - } - return 0; -} - - -int loaddefinitionsfile(char *fn) -{ - scriptfile *script; - - script = scriptfile_fromfile(fn); - if (!script) return -1; - - defsparser(script); - - scriptfile_close(script); - scriptfile_clearsymbols(); - - return 0; -} - -static int defsparserpassone(scriptfile *script) -{ - int tokn; - char *cmdtokptr; - while (1) { - tokn = getatoken(script,basetokens,sizeof(basetokens)/sizeof(tokenlist)); - cmdtokptr = script->ltextptr; - switch (tokn) { - case T_LOADGRP: - { - char *fn; + } + break; + case T_DEFINEMODEL: + { + char *modelfn; + double scale; + int shadeoffs; + + if (scriptfile_getstring(script,&modelfn)) break; + if (scriptfile_getdouble(script,&scale)) break; + if (scriptfile_getnumber(script,&shadeoffs)) break; + +#if defined(POLYMOST) && defined(USE_OPENGL) + lastmodelid = md_loadmodel(modelfn); + if (lastmodelid < 0) { + initprintf("Failure loading MD2/MD3 model \"%s\"\n", modelfn); + break; + } + md_setmisc(lastmodelid,(float)scale, shadeoffs,0.0); +#endif + modelskin = lastmodelskin = 0; + seenframe = 0; + } + break; + case T_DEFINEMODELFRAME: + { + char *framename, happy=1; + int ftilenume, ltilenume, tilex; + + if (scriptfile_getstring(script,&framename)) break; + if (scriptfile_getnumber(script,&ftilenume)) break; //first tile number + if (scriptfile_getnumber(script,<ilenume)) break; //last tile number (inclusive) + if (ltilenume < ftilenume) { + initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); + tilex = ftilenume; + ftilenume = ltilenume; + ltilenume = tilex; + } + + if (lastmodelid < 0) { + initprintf("Warning: Ignoring frame definition.\n"); + break; + } +#if defined(POLYMOST) && defined(USE_OPENGL) + for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++) { + switch (md_defineframe(lastmodelid, framename, tilex, max(0,modelskin))) { + case 0: break; + case -1: happy = 0; break; // invalid model id!? + case -2: initprintf("Invalid tile number on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + happy = 0; + break; + case -3: initprintf("Invalid frame name on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + happy = 0; + break; + } + } +#endif + seenframe = 1; + } + break; + case T_DEFINEMODELANIM: + { + char *startframe, *endframe; + int flags; + double dfps; + + if (scriptfile_getstring(script,&startframe)) break; + if (scriptfile_getstring(script,&endframe)) break; + if (scriptfile_getdouble(script,&dfps)) break; //animation frame rate + if (scriptfile_getnumber(script,&flags)) break; + + if (lastmodelid < 0) { + initprintf("Warning: Ignoring animation definition.\n"); + break; + } +#if defined(POLYMOST) && defined(USE_OPENGL) + switch (md_defineanimation(lastmodelid, startframe, endframe, (int)(dfps*(65536.0*.001)), flags)) { + case 0: break; + case -1: break; // invalid model id!? + case -2: initprintf("Invalid starting frame name on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + case -3: initprintf("Invalid ending frame name on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + case -4: initprintf("Out of memory on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } +#endif + } + break; + case T_DEFINEMODELSKIN: + { + int palnum, palnumer; + char *skinfn; + + if (scriptfile_getsymbol(script,&palnum)) break; + if (scriptfile_getstring(script,&skinfn)) break; //skin filename + + // if we see a sequence of definemodelskin, then a sequence of definemodelframe, + // and then a definemodelskin, we need to increment the skin counter. + // + // definemodel "mymodel.md2" 1 1 + // definemodelskin 0 "normal.png" // skin 0 + // definemodelskin 21 "normal21.png" + // definemodelframe "foo" 1000 1002 // these use skin 0 + // definemodelskin 0 "wounded.png" // skin 1 + // definemodelskin 21 "wounded21.png" + // definemodelframe "foo2" 1003 1004 // these use skin 1 + // selectmodelskin 0 // resets to skin 0 + // definemodelframe "foo3" 1005 1006 // these use skin 0 + if (seenframe) { modelskin = ++lastmodelskin; } + seenframe = 0; + +#if defined(POLYMOST) && defined(USE_OPENGL) + switch (md_defineskin(lastmodelid, skinfn, palnum, max(0,modelskin), 0)) { + case 0: break; + case -1: break; // invalid model id!? + case -2: initprintf("Invalid skin filename on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + case -3: initprintf("Invalid palette number on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + case -4: initprintf("Out of memory on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } +#endif + } + break; + case T_SELECTMODELSKIN: + { + if (scriptfile_getsymbol(script,&modelskin)) break; + } + break; + case T_DEFINEVOXEL: + { + char *fn; + + if (scriptfile_getstring(script,&fn)) break; //voxel filename + + if (nextvoxid == MAXVOXELS) { + initprintf("Maximum number of voxels already defined.\n"); + break; + } + +#ifdef SUPERBUILD + if (qloadkvx(nextvoxid, fn)) { + initprintf("Failure loading voxel file \"%s\"\n",fn); + break; + } + + lastvoxid = nextvoxid++; +#endif + } + break; + case T_DEFINEVOXELTILES: + { + int ftilenume, ltilenume, tilex; + + if (scriptfile_getnumber(script,&ftilenume)) break; //1st tile # + if (scriptfile_getnumber(script,<ilenume)) break; //last tile # + + if (ltilenume < ftilenume) { + initprintf("Warning: backwards tile range on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + tilex = ftilenume; + ftilenume = ltilenume; + ltilenume = tilex; + } + if (ltilenume < 0 || ftilenume >= MAXTILES) { + initprintf("Invalid tile range on line %s:%d\n", + script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } + + if (lastvoxid < 0) { + initprintf("Warning: Ignoring voxel tiles definition.\n"); + break; + } +#ifdef SUPERBUILD + for (tilex = ftilenume; tilex <= ltilenume; tilex++) { + tiletovox[tilex] = lastvoxid; + } +#endif + } + break; + + // NEW (ENCOURAGED) DEFINITION SYNTAX + case T_MODEL: + { + char *modelend, *modelfn; + double scale=1.0, mzadd=0.0; + int shadeoffs=0; + + modelskin = lastmodelskin = 0; + seenframe = 0; + + if (scriptfile_getstring(script,&modelfn)) break; + +#if defined(POLYMOST) && defined(USE_OPENGL) + lastmodelid = md_loadmodel(modelfn); + if (lastmodelid < 0) { + initprintf("Failure loading MD2/MD3 model \"%s\"\n", modelfn); + break; + } +#endif + if (scriptfile_getbraces(script,&modelend)) break; + while (script->textptr < modelend) { + switch (getatoken(script,modeltokens,sizeof(modeltokens)/sizeof(tokenlist))) { + //case T_ERROR: initprintf("Error on line %s:%d in model tokens\n", script->filename,script->linenum); break; + case T_SCALE: scriptfile_getdouble(script,&scale); break; + case T_SHADE: scriptfile_getnumber(script,&shadeoffs); break; + case T_ZADD: scriptfile_getdouble(script,&mzadd); break; + case T_FRAME: + { + char *frametokptr = script->ltextptr; + char *frameend, *framename = 0, happy=1; + int ftilenume = -1, ltilenume = -1, tilex = 0; + + if (scriptfile_getbraces(script,&frameend)) break; + while (script->textptr < frameend) { + switch(getatoken(script,modelframetokens,sizeof(modelframetokens)/sizeof(tokenlist))) { + case T_FRAME: scriptfile_getstring(script,&framename); break; + case T_TILE: scriptfile_getsymbol(script,&ftilenume); ltilenume = ftilenume; break; + case T_TILE0: scriptfile_getsymbol(script,&ftilenume); break; //first tile number + case T_TILE1: scriptfile_getsymbol(script,<ilenume); break; //last tile number (inclusive) + } + } + + if (ftilenume < 0) initprintf("Error: missing 'first tile number' for frame definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,frametokptr)), happy = 0; + if (ltilenume < 0) initprintf("Error: missing 'last tile number' for frame definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,frametokptr)), happy = 0; + if (!happy) break; + + if (ltilenume < ftilenume) { + initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,frametokptr)); + tilex = ftilenume; + ftilenume = ltilenume; + ltilenume = tilex; + } + + if (lastmodelid < 0) { + initprintf("Warning: Ignoring frame definition.\n"); + break; + } +#if defined(POLYMOST) && defined(USE_OPENGL) + for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++) { + switch (md_defineframe(lastmodelid, framename, tilex, max(0,modelskin))) { + case 0: break; + case -1: happy = 0; break; // invalid model id!? + case -2: initprintf("Invalid tile number on line %s:%d\n", + script->filename, scriptfile_getlinum(script,frametokptr)); + happy = 0; + break; + case -3: initprintf("Invalid frame name on line %s:%d\n", + script->filename, scriptfile_getlinum(script,frametokptr)); + happy = 0; + break; + } + } +#endif + seenframe = 1; + } + break; + case T_ANIM: + { + char *animtokptr = script->ltextptr; + char *animend, *startframe = 0, *endframe = 0, happy=1; + int flags = 0; + double dfps = 1.0; + + if (scriptfile_getbraces(script,&animend)) break; + while (script->textptr < animend) { + switch(getatoken(script,modelanimtokens,sizeof(modelanimtokens)/sizeof(tokenlist))) { + case T_FRAME0: scriptfile_getstring(script,&startframe); break; + case T_FRAME1: scriptfile_getstring(script,&endframe); break; + case T_FPS: scriptfile_getdouble(script,&dfps); break; //animation frame rate + case T_FLAGS: scriptfile_getsymbol(script,&flags); break; + } + } + + if (!startframe) initprintf("Error: missing 'start frame' for anim definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,animtokptr)), happy = 0; + if (!endframe) initprintf("Error: missing 'end frame' for anim definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,animtokptr)), happy = 0; + if (!happy) break; + + if (lastmodelid < 0) { + initprintf("Warning: Ignoring animation definition.\n"); + break; + } +#if defined(POLYMOST) && defined(USE_OPENGL) + switch (md_defineanimation(lastmodelid, startframe, endframe, (int)(dfps*(65536.0*.001)), flags)) { + case 0: break; + case -1: break; // invalid model id!? + case -2: initprintf("Invalid starting frame name on line %s:%d\n", + script->filename, scriptfile_getlinum(script,animtokptr)); + break; + case -3: initprintf("Invalid ending frame name on line %s:%d\n", + script->filename, scriptfile_getlinum(script,animtokptr)); + break; + case -4: initprintf("Out of memory on line %s:%d\n", + script->filename, scriptfile_getlinum(script,animtokptr)); + break; + } +#endif + } break; + case T_SKIN: + { + char *skintokptr = script->ltextptr; + char *skinend, *skinfn = 0; + int palnum = 0, surfnum = 0; + + if (scriptfile_getbraces(script,&skinend)) break; + while (script->textptr < skinend) { + switch(getatoken(script,modelskintokens,sizeof(modelskintokens)/sizeof(tokenlist))) { + case T_PAL: scriptfile_getsymbol(script,&palnum); break; + case T_FILE: scriptfile_getstring(script,&skinfn); break; //skin filename + case T_SURF: scriptfile_getnumber(script,&surfnum); break; + } + } + + if (!skinfn) { + initprintf("Error: missing 'skin filename' for skin definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,skintokptr)); + break; + } + + if (seenframe) { modelskin = ++lastmodelskin; } + seenframe = 0; + +#if defined(POLYMOST) && defined(USE_OPENGL) + switch (md_defineskin(lastmodelid, skinfn, palnum, max(0,modelskin), surfnum)) { + case 0: break; + case -1: break; // invalid model id!? + case -2: initprintf("Invalid skin filename on line %s:%d\n", + script->filename, scriptfile_getlinum(script,skintokptr)); + break; + case -3: initprintf("Invalid palette number on line %s:%d\n", + script->filename, scriptfile_getlinum(script,skintokptr)); + break; + case -4: initprintf("Out of memory on line %s:%d\n", + script->filename, scriptfile_getlinum(script,skintokptr)); + break; + } +#endif + } break; + case T_HUD: + { + char *hudtokptr = script->ltextptr; + char happy=1, *frameend; + int ftilenume = -1, ltilenume = -1, tilex = 0, flags = 0; + double xadd = 0.0, yadd = 0.0, zadd = 0.0, angadd = 0.0; + + if (scriptfile_getbraces(script,&frameend)) break; + while (script->textptr < frameend) { + switch(getatoken(script,modelhudtokens,sizeof(modelhudtokens)/sizeof(tokenlist))) { + case T_TILE: scriptfile_getsymbol(script,&ftilenume); ltilenume = ftilenume; break; + case T_TILE0: scriptfile_getsymbol(script,&ftilenume); break; //first tile number + case T_TILE1: scriptfile_getsymbol(script,<ilenume); break; //last tile number (inclusive) + case T_XADD: scriptfile_getdouble(script,&xadd); break; + case T_YADD: scriptfile_getdouble(script,&yadd); break; + case T_ZADD: scriptfile_getdouble(script,&zadd); break; + case T_ANGADD:scriptfile_getdouble(script,&angadd); break; + case T_HIDE: flags |= 1; break; + case T_NOBOB: flags |= 2; break; + case T_FLIPPED: flags |= 4; break; + case T_NODEPTH: flags |= 8; break; + } + } + + if (ftilenume < 0) initprintf("Error: missing 'first tile number' for hud definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,hudtokptr)), happy = 0; + if (ltilenume < 0) initprintf("Error: missing 'last tile number' for hud definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,hudtokptr)), happy = 0; + if (!happy) break; + + if (ltilenume < ftilenume) { + initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,hudtokptr)); + tilex = ftilenume; + ftilenume = ltilenume; + ltilenume = tilex; + } + + if (lastmodelid < 0) { + initprintf("Warning: Ignoring frame definition.\n"); + break; + } +#if defined(POLYMOST) && defined(USE_OPENGL) + for (tilex = ftilenume; tilex <= ltilenume && happy; tilex++) { + switch (md_definehud(lastmodelid, tilex, xadd, yadd, zadd, angadd, flags)) { + case 0: break; + case -1: happy = 0; break; // invalid model id!? + case -2: initprintf("Invalid tile number on line %s:%d\n", + script->filename, scriptfile_getlinum(script,hudtokptr)); + happy = 0; + break; + case -3: initprintf("Invalid frame name on line %s:%d\n", + script->filename, scriptfile_getlinum(script,hudtokptr)); + happy = 0; + break; + } + } +#endif + } break; + } + } + +#if defined(POLYMOST) && defined(USE_OPENGL) + md_setmisc(lastmodelid,(float)scale,shadeoffs,(float)mzadd); +#endif + + modelskin = lastmodelskin = 0; + seenframe = 0; + + } + break; + case T_VOXEL: + { + char *voxeltokptr = script->ltextptr; + char *fn, *modelend; + int tile0 = MAXTILES, tile1 = -1, tilex = -1; + + if (scriptfile_getstring(script,&fn)) break; //voxel filename + if (nextvoxid == MAXVOXELS) { initprintf("Maximum number of voxels already defined.\n"); break; } +#ifdef SUPERBUILD + if (qloadkvx(nextvoxid, fn)) { initprintf("Failure loading voxel file \"%s\"\n",fn); break; } + lastvoxid = nextvoxid++; +#endif + + if (scriptfile_getbraces(script,&modelend)) break; + while (script->textptr < modelend) { + switch (getatoken(script,voxeltokens,sizeof(voxeltokens)/sizeof(tokenlist))) { + //case T_ERROR: initprintf("Error on line %s:%d in voxel tokens\n", script->filename,linenum); break; + case T_TILE: + scriptfile_getsymbol(script,&tilex); +#ifdef SUPERBUILD + if ((unsigned long)tilex < MAXTILES) tiletovox[tilex] = lastvoxid; + else initprintf("Invalid tile number on line %s:%d\n",script->filename, scriptfile_getlinum(script,voxeltokptr)); +#endif + break; + case T_TILE0: + scriptfile_getsymbol(script,&tile0); break; //1st tile # + case T_TILE1: + scriptfile_getsymbol(script,&tile1); + if (tile0 > tile1) + { + initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,voxeltokptr)); + tilex = tile0; tile0 = tile1; tile1 = tilex; + } + if ((tile1 < 0) || (tile0 >= MAXTILES)) + { initprintf("Invalid tile range on line %s:%d\n",script->filename, scriptfile_getlinum(script,voxeltokptr)); break; } +#ifdef SUPERBUILD + for(tilex=tile0;tilex<=tile1;tilex++) tiletovox[tilex] = lastvoxid; +#endif + break; //last tile number (inclusive) + case T_SCALE: { + double scale=1.0; + scriptfile_getdouble(script,&scale); +#ifdef SUPERBUILD + voxscale[lastvoxid] = 65536*scale; +#endif + break; + } + } + } + lastvoxid = -1; + } + break; + case T_SKYBOX: + { + char *skyboxtokptr = script->ltextptr; + char *fn[6] = {0,0,0,0,0,0}, *modelend, happy=1; + int i, tile = -1, pal = 0; + + if (scriptfile_getbraces(script,&modelend)) break; + while (script->textptr < modelend) { + switch (getatoken(script,skyboxtokens,sizeof(skyboxtokens)/sizeof(tokenlist))) { + //case T_ERROR: initprintf("Error on line %s:%d in skybox tokens\n",script->filename,linenum); break; + case T_TILE: scriptfile_getsymbol(script,&tile ); break; + case T_PAL: scriptfile_getsymbol(script,&pal ); break; + case T_FRONT: scriptfile_getstring(script,&fn[0]); break; + case T_RIGHT: scriptfile_getstring(script,&fn[1]); break; + case T_BACK: scriptfile_getstring(script,&fn[2]); break; + case T_LEFT: scriptfile_getstring(script,&fn[3]); break; + case T_TOP: scriptfile_getstring(script,&fn[4]); break; + case T_BOTTOM:scriptfile_getstring(script,&fn[5]); break; + } + } + + if (tile < 0) initprintf("Error: missing 'tile number' for skybox definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,skyboxtokptr)), happy=0; + for (i=0;i<6;i++) { + if (!fn[i]) initprintf("Error: missing '%s filename' for skybox definition near line %s:%d\n", skyfaces[i], script->filename, scriptfile_getlinum(script,skyboxtokptr)), happy = 0; + } + + if (!happy) break; + + hicsetskybox(tile,pal,fn); + } + break; + case T_TINT: + { + char *tinttokptr = script->ltextptr; + int red=255, green=255, blue=255, pal=-1, flags=0; + char *tintend; + + if (scriptfile_getbraces(script,&tintend)) break; + while (script->textptr < tintend) { + switch (getatoken(script,tinttokens,sizeof(tinttokens)/sizeof(tokenlist))) { + case T_PAL: scriptfile_getsymbol(script,&pal); break; + case T_RED: scriptfile_getnumber(script,&red); red = min(255,max(0,red)); break; + case T_GREEN: scriptfile_getnumber(script,&green); green = min(255,max(0,green)); break; + case T_BLUE: scriptfile_getnumber(script,&blue); blue = min(255,max(0,blue)); break; + case T_FLAGS: scriptfile_getsymbol(script,&flags); break; + } + } + + if (pal < 0) { + initprintf("Error: missing 'palette number' for tint definition near line %s:%d\n", script->filename, scriptfile_getlinum(script,tinttokptr)); + break; + } + + hicsetpalettetint(pal,red,green,blue,flags); + } + break; + case T_TEXTURE: + { + char *texturetokptr = script->ltextptr, *textureend; + int tile=-1; + + if (scriptfile_getsymbol(script,&tile)) break; + if (scriptfile_getbraces(script,&textureend)) break; + while (script->textptr < textureend) { + switch (getatoken(script,texturetokens,sizeof(texturetokens)/sizeof(tokenlist))) { + case T_PAL: { + char *paltokptr = script->ltextptr, *palend; + int pal=-1; + char *fn = NULL; + double alphacut = -1.0; + char flags = 0; + + if (scriptfile_getsymbol(script,&pal)) break; + if (scriptfile_getbraces(script,&palend)) break; + while (script->textptr < palend) { + switch (getatoken(script,texturetokens_pal,sizeof(texturetokens_pal)/sizeof(tokenlist))) { + case T_FILE: scriptfile_getstring(script,&fn); break; + case T_ALPHACUT: scriptfile_getdouble(script,&alphacut); break; + case T_NOCOMPRESS: flags |= 1; break; + default: break; + } + } + + if ((unsigned)tile > (unsigned)MAXTILES) break; // message is printed later + if ((unsigned)pal > (unsigned)MAXPALOOKUPS) { + initprintf("Error: missing or invalid 'palette number' for texture definition near " + "line %s:%d\n", script->filename, scriptfile_getlinum(script,paltokptr)); + break; + } + if (!fn) { + initprintf("Error: missing 'file name' for texture definition near line %s:%d\n", + script->filename, scriptfile_getlinum(script,paltokptr)); + break; + } + hicsetsubsttex(tile,pal,fn,alphacut,flags); + } break; + default: break; + } + } + + if ((unsigned)tile >= (unsigned)MAXTILES) { + initprintf("Error: missing or invalid 'tile number' for texture definition near line %s:%d\n", + script->filename, scriptfile_getlinum(script,texturetokptr)); + break; + } + } + break; + + case T_UNDEFMODEL: + case T_UNDEFMODELRANGE: + { + int r0,r1; + + if (scriptfile_getsymbol(script,&r0)) break; + if (tokn == T_UNDEFMODELRANGE) { + if (scriptfile_getsymbol(script,&r1)) break; + if (r1 < r0) { + int t = r1; + r1 = r0; + r0 = t; + initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); + } + if (r0 < 0 || r1 >= MAXTILES) { + initprintf("Error: invalid tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } + } else { + r1 = r0; + if ((unsigned)r0 >= (unsigned)MAXTILES) { + initprintf("Error: invalid tile number on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } + } +#if defined(POLYMOST) && defined(USE_OPENGL) + for (; r0 <= r1; r0++) md_undefinetile(r0); +#endif + } + break; + + case T_UNDEFMODELOF: + { + int mid,r0; + + if (scriptfile_getsymbol(script,&r0)) break; + if ((unsigned)r0 >= (unsigned)MAXTILES) { + initprintf("Error: invalid tile number on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } + +#if defined(POLYMOST) && defined(USE_OPENGL) + mid = md_tilehasmodel(r0); + if (mid < 0) break; + + md_undefinemodel(mid); +#endif + } + break; + + case T_UNDEFTEXTURE: + case T_UNDEFTEXTURERANGE: + { + int r0,r1,i; + + if (scriptfile_getsymbol(script,&r0)) break; + if (tokn == T_UNDEFTEXTURERANGE) { + if (scriptfile_getsymbol(script,&r1)) break; + if (r1 < r0) { + int t = r1; + r1 = r0; + r0 = t; + initprintf("Warning: backwards tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); + } + if (r0 < 0 || r1 >= MAXTILES) { + initprintf("Error: invalid tile range on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } + } else { + r1 = r0; + if ((unsigned)r0 >= (unsigned)MAXTILES) { + initprintf("Error: invalid tile number on line %s:%d\n", script->filename, scriptfile_getlinum(script,cmdtokptr)); + break; + } + } + + for (; r0 <= r1; r0++) + for (i=MAXPALOOKUPS-1; i>=0; i--) + hicclearsubst(r0,i); + } + break; + + default: + initprintf("Unknown token.\n"); break; + } + } + return 0; +} + + +int loaddefinitionsfile(char *fn) +{ + scriptfile *script; + + script = scriptfile_fromfile(fn); + if (!script) return -1; + + defsparser(script); + + scriptfile_close(script); + scriptfile_clearsymbols(); + + return 0; +} + +static int defsparserpassone(scriptfile *script) +{ + int tokn; + char *cmdtokptr; + while (1) { + tokn = getatoken(script,basetokens,sizeof(basetokens)/sizeof(tokenlist)); + cmdtokptr = script->ltextptr; + switch (tokn) { + case T_LOADGRP: + { + char *fn; if (!scriptfile_getstring(script,&fn)) { int j = initgroupfile(fn); @@ -1080,31 +1080,31 @@ static int defsparserpassone(scriptfile *script) initprintf("Could not find GRP file %s.\n",fn); else initprintf("Using GRP file %s.\n",fn); - } + } } break; - case T_EOF: - return(0); + case T_EOF: + return(0); default: - break; - } - } - return 0; -} + break; + } + } + return 0; +} -int loadgroupfiles(char *fn) -{ - scriptfile *script; - - script = scriptfile_fromfile(fn); - if (!script) return -1; - - defsparserpassone(script); - - scriptfile_close(script); - scriptfile_clearsymbols(); - - return 0; -} - -// vim:ts=4: +int loadgroupfiles(char *fn) +{ + scriptfile *script; + + script = scriptfile_fromfile(fn); + if (!script) return -1; + + defsparserpassone(script); + + scriptfile_close(script); + scriptfile_clearsymbols(); + + return 0; +} + +// vim:ts=4: diff --git a/polymer/build/src/engine.c b/polymer/build/src/engine.c index 5b5fa3d01..dd7d614fe 100644 --- a/polymer/build/src/engine.c +++ b/polymer/build/src/engine.c @@ -698,7 +698,7 @@ int hicclearsubst(long picnum, long palnum) { return 0; } long polymost_drawtilescreen (long tilex, long tiley, long wallnum, long dimen) { return -1; } #endif //============================================================================= //POLYMOST ENDS - + #include "polymer.c" // @@ -5662,11 +5662,11 @@ void drawrooms(long daposx, long daposy, long daposz, } while (i != 0); umost[0] = shortptr1[0]-windowy1; dmost[0] = shortptr2[0]-windowy1; - - if (0) - { - polymer_drawrooms(); - return; + + if (0) + { + polymer_drawrooms(); + return; } //============================================================================= //POLYMOST BEGINS #ifdef POLYMOST @@ -7356,7 +7356,11 @@ long loadpics(char *filename, long askedsize) //try dpmi_DETERMINEMAXREALALLOC! - cachesize = min((long)((Bgetsysmemsize()/100)*60),max(artsize,askedsize)); + //cachesize = min((long)((Bgetsysmemsize()/100)*60),max(artsize,askedsize)); + if (Bgetsysmemsize() <= (unsigned long)askedsize) + cachesize = (Bgetsysmemsize()/100)*60; + else + cachesize = askedsize; while ((pic = kkmalloc(cachesize)) == NULL) { cachesize -= 65536L; diff --git a/polymer/build/src/game.c b/polymer/build/src/game.c index 2c86eacb8..a8c4747c1 100644 --- a/polymer/build/src/game.c +++ b/polymer/build/src/game.c @@ -1,6297 +1,6297 @@ -// Ken Silverman's official web site: "http://www.advsys.net/ken" -// See the included license file "BUILDLIC.TXT" for license info. -// -// This file has been modified from Ken Silverman's original release -// by Jonathon Fowler (jonof@edgenetwk.com) - -#include "compat.h" -#include "build.h" -#include "names.h" -#include "pragmas.h" -#include "cache1d.h" -#include "game.h" -#include "osd.h" -#include "mmulti.h" - -#include "baselayer.h" - -#define TIMERINTSPERSECOND 140 //280 -#define MOVESPERSECOND 40 -#define TICSPERFRAME 3 -#define MOVEFIFOSIZ 256 -#define EYEHEIGHT (32<<8) //Normally (32<<8), (51<<8) to make mirrors happy - -// declared in sound.c -void initsb(char,char,long,char,char,char,char); -void uninitsb(void); -void setears(long,long,long,long); -void wsayfollow(char *,long,long,long *,long *,char); -void wsay(char *,long,long,long); -void loadwaves(void); -void loadsong(char *); -void musicon(void); -void musicoff(void); -void refreshaudio(void); - -// declared in config.c -int loadsetup(const char *); -int writesetup(const char *); - - -/*************************************************************************** - KEN'S TAG DEFINITIONS: (Please define your own tags for your games) - - sector[?].lotag = 0 Normal sector - sector[?].lotag = 1 If you are on a sector with this tag, then all sectors - with same hi tag as this are operated. Once. - sector[?].lotag = 2 Same as sector[?].tag = 1 but this is retriggable. - sector[?].lotag = 3 A really stupid sector that really does nothing now. - sector[?].lotag = 4 A sector where you are put closer to the floor - (such as the slime in DOOM1.DAT) - sector[?].lotag = 5 A really stupid sector that really does nothing now. - sector[?].lotag = 6 A normal door - instead of pressing D, you tag the - sector with a 6. The reason I make you edit doors - this way is so that can program the doors - yourself. - sector[?].lotag = 7 A door the goes down to open. - sector[?].lotag = 8 A door that opens horizontally in the middle. - sector[?].lotag = 9 A sliding door that opens vertically in the middle. - -Example of the advantages of not using BSP tree. - sector[?].lotag = 10 A warping sector with floor and walls that shade. - sector[?].lotag = 11 A sector with all walls that do X-panning. - sector[?].lotag = 12 A sector with walls using the dragging function. - sector[?].lotag = 13 A sector with some swinging doors in it. - sector[?].lotag = 14 A revolving door sector. - sector[?].lotag = 15 A subway track. - sector[?].lotag = 16 A true double-sliding door. - - wall[?].lotag = 0 Normal wall - wall[?].lotag = 1 Y-panning wall - wall[?].lotag = 2 Switch - If you flip it, then all sectors with same hi - tag as this are operated. - wall[?].lotag = 3 Marked wall to detemine starting dir. (sector tag 12) - wall[?].lotag = 4 Mark on the shorter wall closest to the pivot point - of a swinging door. (sector tag 13) - wall[?].lotag = 5 Mark where a subway should stop. (sector tag 15) - wall[?].lotag = 6 Mark for true double-sliding doors (sector tag 16) - wall[?].lotag = 7 Water fountain - wall[?].lotag = 8 Bouncy wall! - - sprite[?].lotag = 0 Normal sprite - sprite[?].lotag = 1 If you press space bar on an AL, and the AL is tagged - with a 1, he will turn evil. - sprite[?].lotag = 2 When this sprite is operated, a bomb is shot at its - position. - sprite[?].lotag = 3 Rotating sprite. - sprite[?].lotag = 4 Sprite switch. - sprite[?].lotag = 5 Basketball hoop score. - -KEN'S STATUS DEFINITIONS: (Please define your own statuses for your games) - status = 0 Inactive sprite - status = 1 Active monster sprite - status = 2 Monster that becomes active only when it sees you - status = 3 Smoke on the wall for chainguns - status = 4 Splashing sprites (When you shoot slime) - status = 5 Explosion! - status = 6 Travelling bullet - status = 7 Bomb sprial-out explosion - status = 8 Player! - status = 9 EVILALGRAVE shrinking list - status = 10 EVILAL list - status = 11 Sprite respawning list - status = 12 Sprite which does not respawn (Andy's addition) - status = MAXSTATUS Non-existent sprite (this will be true for your - code also) -**************************************************************************/ - -typedef struct -{ - long x, y, z; -} point3d; - -typedef struct -{ - signed char fvel, svel, avel; - short bits; -} input; - -static long screentilt = 0, oscreentilt = 0; - - -static long fvel, svel, avel; -static long fvel2, svel2, avel2; - -#define NUMOPTIONS 8 -#define NUMKEYS 19 -char option[NUMOPTIONS] = {0,0,0,0,0,0,1,0}; -char keys[NUMKEYS] = -{ - 0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39, - 0x1e,0x2c,0xd1,0xc9,0x33,0x34, - 0x9c,0x1c,0xd,0xc,0xf -}; -long xdimgame = 320, ydimgame = 200, bppgame = 8, xdim2d = 640, ydim2d = 480; // JBF 20050318: config.c expects to find these - -static long digihz[8] = {6000,8000,11025,16000,22050,32000,44100,48000}; - -static char frame2draw[MAXPLAYERS]; -static long frameskipcnt[MAXPLAYERS]; - -#define LAVASIZ 128 -#define LAVALOGSIZ 7 -#define LAVAMAXDROPS 32 -static char lavabakpic[(LAVASIZ+4)*(LAVASIZ+4)], lavainc[LAVASIZ]; -static long lavanumdrops, lavanumframes; -static long lavadropx[LAVAMAXDROPS], lavadropy[LAVAMAXDROPS]; -static long lavadropsiz[LAVAMAXDROPS], lavadropsizlookup[LAVAMAXDROPS]; -static long lavaradx[24][96], lavarady[24][96], lavaradcnt[32]; - - //Shared player variables -static long posx[MAXPLAYERS], posy[MAXPLAYERS], posz[MAXPLAYERS]; -static long horiz[MAXPLAYERS], zoom[MAXPLAYERS], hvel[MAXPLAYERS]; -static short ang[MAXPLAYERS], cursectnum[MAXPLAYERS], ocursectnum[MAXPLAYERS]; -static short playersprite[MAXPLAYERS], deaths[MAXPLAYERS]; -static long lastchaingun[MAXPLAYERS]; -static long health[MAXPLAYERS], flytime[MAXPLAYERS]; -static short oflags[MAXPLAYERS]; -static short numbombs[MAXPLAYERS]; -static short numgrabbers[MAXPLAYERS]; // Andy did this -static short nummissiles[MAXPLAYERS]; // Andy did this -static char dimensionmode[MAXPLAYERS]; -static char revolvedoorstat[MAXPLAYERS]; -static short revolvedoorang[MAXPLAYERS], revolvedoorrotang[MAXPLAYERS]; -static long revolvedoorx[MAXPLAYERS], revolvedoory[MAXPLAYERS]; - - //ENGINE CONTROLLED MULTIPLAYER VARIABLES: -extern long numplayers, myconnectindex; -extern long connecthead, connectpoint2[MAXPLAYERS]; //Player linked list variables (indeces, not connection numbers) - -static long nummoves; -// Bug: NUMSTATS used to be equal to the greatest tag number, -// so that the last statrate[] entry was random memory junk -// because stats 0-NUMSTATS required NUMSTATS+1 bytes. -Andy -#define NUMSTATS 13 -static signed char statrate[NUMSTATS] = {-1,0,-1,0,0,0,1,3,0,3,15,-1,-1}; - - //Input structures -static char networkmode; //0 is 2(n-1) mode, 1 is n(n-1) mode -static long locselectedgun, locselectedgun2; -static input loc, oloc, loc2; -static input ffsync[MAXPLAYERS], osync[MAXPLAYERS], ssync[MAXPLAYERS]; - //Input faketimerhandler -> movethings fifo -static long movefifoplc, movefifoend[MAXPLAYERS]; -static input baksync[MOVEFIFOSIZ][MAXPLAYERS]; - //Game recording variables -static long reccnt, recstat = 1; -static input recsync[16384][2]; - -//static long myminlag[MAXPLAYERS], mymaxlag, otherminlag, bufferjitter = 1; -static signed char otherlag[MAXPLAYERS] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; -static long averagelag[MAXPLAYERS] = {512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512}; - -static long fakemovefifoplc; -static long myx, myy, myz, omyx, omyy, omyz, myzvel; -static long myhoriz, omyhoriz; -static short myang, omyang, mycursectnum; -static long myxbak[MOVEFIFOSIZ], myybak[MOVEFIFOSIZ], myzbak[MOVEFIFOSIZ]; -static long myhorizbak[MOVEFIFOSIZ]; -static short myangbak[MOVEFIFOSIZ]; - - //MULTI.OBJ sync state variables -extern char syncstate; - //GAME.C sync state variables -static char syncstat, syncval[MOVEFIFOSIZ], othersyncval[MOVEFIFOSIZ]; -static long syncvaltottail, syncvalhead, othersyncvalhead, syncvaltail; - -static char detailmode = 0, ready2send = 0; -static long ototalclock = 0, gotlastpacketclock = 0, smoothratio; -static long oposx[MAXPLAYERS], oposy[MAXPLAYERS], oposz[MAXPLAYERS]; -static long ohoriz[MAXPLAYERS], ozoom[MAXPLAYERS]; -static short oang[MAXPLAYERS]; - -static point3d osprite[MAXSPRITES]; - -#define MAXINTERPOLATIONS 1024 -static long numinterpolations = 0, startofdynamicinterpolations = 0; -static long oldipos[MAXINTERPOLATIONS]; -static long bakipos[MAXINTERPOLATIONS]; -static long *curipos[MAXINTERPOLATIONS]; - -extern long cachecount; - -static char playerreadyflag[MAXPLAYERS]; - - //Miscellaneous variables -static char packbuf[MAXXDIM]; -static char tempbuf[MAXXDIM], boardfilename[80]; -static short tempshort[MAXSECTORS]; -static short screenpeek = 0, oldmousebstatus = 0; -short brightness = 0; -static short screensize, screensizeflag = 0; -static short neartagsector, neartagwall, neartagsprite; -static long lockclock, neartagdist, neartaghitdist; -extern long pageoffset, ydim16; -static long globhiz, globloz, globhihit, globlohit; - - //Over the shoulder mode variables -static long cameradist = -1, cameraang = 0, cameraclock = 0; - - //Board animation variables -#define MAXMIRRORS 64 -static short mirrorwall[MAXMIRRORS], mirrorsector[MAXMIRRORS], mirrorcnt; -static short floormirrorsector[64], floormirrorcnt; -static short turnspritelist[16], turnspritecnt; -static short warpsectorlist[64], warpsectorcnt; -static short xpanningsectorlist[16], xpanningsectorcnt; -static short ypanningwalllist[64], ypanningwallcnt; -static short floorpanninglist[64], floorpanningcnt; -static short dragsectorlist[16], dragxdir[16], dragydir[16], dragsectorcnt; -static long dragx1[16], dragy1[16], dragx2[16], dragy2[16], dragfloorz[16]; -static short swingcnt, swingwall[32][5], swingsector[32]; -static short swingangopen[32], swingangclosed[32], swingangopendir[32]; -static short swingang[32], swinganginc[32]; -static long swingx[32][8], swingy[32][8]; -static short revolvesector[4], revolveang[4], revolvecnt; -static long revolvex[4][16], revolvey[4][16]; -static long revolvepivotx[4], revolvepivoty[4]; -static short subwaytracksector[4][128], subwaynumsectors[4], subwaytrackcnt; -static long subwaystop[4][8], subwaystopcnt[4]; -static long subwaytrackx1[4], subwaytracky1[4]; -static long subwaytrackx2[4], subwaytracky2[4]; -static long subwayx[4], subwaygoalstop[4], subwayvel[4], subwaypausetime[4]; -static short waterfountainwall[MAXPLAYERS], waterfountaincnt[MAXPLAYERS]; -static short slimesoundcnt[MAXPLAYERS]; - - //Variables that let you type messages to other player -static char getmessage[162], getmessageleng; -static long getmessagetimeoff; -static char typemessage[162], typemessageleng = 0, typemode = 0; -/* -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, -}; -*/ - - //These variables are for animating x, y, or z-coordinates of sectors, - //walls, or sprites (They are NOT to be used for changing the [].picnum's) - //See the setanimation(), and getanimategoal() functions for more details. -#define MAXANIMATES 512 -static long *animateptr[MAXANIMATES], animategoal[MAXANIMATES]; -static long animatevel[MAXANIMATES], animateacc[MAXANIMATES], animatecnt = 0; - -#if defined(POLYMOST) && defined(USE_OPENGL) - //These parameters are in exact order of sprite structure in BUILD.H -#define spawnsprite(newspriteindex2,x2,y2,z2,cstat2,shade2,pal2, \ - clipdist2,xrepeat2,yrepeat2,xoffset2,yoffset2,picnum2,ang2, \ - xvel2,yvel2,zvel2,owner2,sectnum2,statnum2,lotag2,hitag2,extra2) \ -{ \ - spritetype *spr2; \ - newspriteindex2 = insertsprite(sectnum2,statnum2); \ - spr2 = &sprite[newspriteindex2]; \ - spr2->x = x2; spr2->y = y2; spr2->z = z2; \ - spr2->cstat = cstat2; spr2->shade = shade2; \ - spr2->pal = pal2; spr2->clipdist = clipdist2; \ - spr2->xrepeat = xrepeat2; spr2->yrepeat = yrepeat2; \ - spr2->xoffset = xoffset2; spr2->yoffset = yoffset2; \ - spr2->picnum = picnum2; spr2->ang = ang2; \ - spr2->xvel = xvel2; spr2->yvel = yvel2; spr2->zvel = zvel2; \ - spr2->owner = owner2; \ - spr2->lotag = lotag2; spr2->hitag = hitag2; spr2->extra = extra2; \ - copybuf(&spr2->x,&osprite[newspriteindex2].x,3); \ - show2dsprite[newspriteindex2>>3] &= ~(1<<(newspriteindex2&7)); \ - if (show2dsector[sectnum2>>3]&(1<<(sectnum2&7))) \ - show2dsprite[newspriteindex2>>3] |= (1<<(newspriteindex2&7)); \ - clearbufbyte(&spriteext[newspriteindex2], sizeof(spriteexttype), 0); \ -} -#else -#define spawnsprite(newspriteindex2,x2,y2,z2,cstat2,shade2,pal2, \ - clipdist2,xrepeat2,yrepeat2,xoffset2,yoffset2,picnum2,ang2, \ - xvel2,yvel2,zvel2,owner2,sectnum2,statnum2,lotag2,hitag2,extra2) \ -{ \ - spritetype *spr2; \ - newspriteindex2 = insertsprite(sectnum2,statnum2); \ - spr2 = &sprite[newspriteindex2]; \ - spr2->x = x2; spr2->y = y2; spr2->z = z2; \ - spr2->cstat = cstat2; spr2->shade = shade2; \ - spr2->pal = pal2; spr2->clipdist = clipdist2; \ - spr2->xrepeat = xrepeat2; spr2->yrepeat = yrepeat2; \ - spr2->xoffset = xoffset2; spr2->yoffset = yoffset2; \ - spr2->picnum = picnum2; spr2->ang = ang2; \ - spr2->xvel = xvel2; spr2->yvel = yvel2; spr2->zvel = zvel2; \ - spr2->owner = owner2; \ - spr2->lotag = lotag2; spr2->hitag = hitag2; spr2->extra = extra2; \ - copybuf(&spr2->x,&osprite[newspriteindex2].x,3); \ - show2dsprite[newspriteindex2>>3] &= ~(1<<(newspriteindex2&7)); \ - if (show2dsector[sectnum2>>3]&(1<<(sectnum2&7))) \ - show2dsprite[newspriteindex2>>3] |= (1<<(newspriteindex2&7)); \ -} -#endif - -int nextvoxid = 0; - -static int osdcmd_restartvid(const osdfuncparm_t *parm) -{ - resetvideomode(); - if (setgamemode(fullscreen,xdim,ydim,bpp)) - OSD_Printf("restartvid: Reset failed...\n"); - - return OSDCMD_OK; -} - -static int osdcmd_vidmode(const osdfuncparm_t *parm) -{ - long newx = xdim, newy = ydim, newbpp = bpp, newfullscreen = fullscreen; - - if (parm->numparms < 1 || parm->numparms > 4) return OSDCMD_SHOWHELP; - - switch (parm->numparms) { - case 1: // bpp switch - newbpp = Batol(parm->parms[0]); - break; - case 2: // res switch - newx = Batol(parm->parms[0]); - newy = Batol(parm->parms[1]); - break; - case 3: // res & bpp switch - case 4: - newx = Batol(parm->parms[0]); - newy = Batol(parm->parms[1]); - newbpp = Batol(parm->parms[2]); - if (parm->numparms == 4) - newfullscreen = (Batol(parm->parms[3]) != 0); - break; - } - - if (setgamemode(newfullscreen,newx,newy,newbpp)) - OSD_Printf("vidmode: Mode change failed!\n"); - screensize = xdim+1; - return OSDCMD_OK; -} - -#ifdef RENDERTYPEWIN -int DoLaunchWindow(void); // gamestartwin.c -#endif - -char *startwin_labeltext = "Starting KenBuild..."; - -long app_main(long argc, char *argv[]) -{ - long i, j, k, l, fil, waitplayers, x1, y1, x2, y2; - long other, packleng, netparm; - -#ifdef USE_OPENGL - OSD_RegisterFunction("restartvid","restartvid: reinitialise the video mode",osdcmd_restartvid); - OSD_RegisterFunction("vidmode","vidmode [xdim ydim] [bpp] [fullscreen]: immediately change the video mode",osdcmd_vidmode); -#endif - - wm_setapptitle("KenBuild by Ken Silverman"); - - Bstrcpy(boardfilename, "nukeland.map"); - j = 0; netparm = argc; - for (i=1;i= 2); - - pskyoff[0] = 0; pskyoff[1] = 0; pskybits = 1; - - loadpics("tiles000.art",1048576); //Load artwork -#ifdef SUPERBUILD - if (!qloadkvx(nextvoxid,"voxel000.kvx")) - tiletovox[PLAYER] = nextvoxid++; - if (!qloadkvx(nextvoxid,"voxel001.kvx")) - tiletovox[BROWNMONSTER] = nextvoxid++; -#endif - if (!loaddefinitionsfile("kenbuild.def")) initprintf("Definitions file loaded.\n"); - - //Here's an example of TRUE ornamented walls - //The allocatepermanenttile should be called right after loadpics - //Since it resets the tile cache for each call. - if (allocatepermanenttile(SLIME,128,128) == 0) //If enough memory - { - printf("Not enough memory for slime!\n"); - exit(0); - } - if (allocatepermanenttile(MAXTILES-1,64,64) != 0) //If enough memory - { - //My face with an explosion written over it - copytilepiece(KENPICTURE,0,0,64,64,MAXTILES-1,0,0); - copytilepiece(EXPLOSION,0,0,64,64,MAXTILES-1,0,0); - } - - initlava(); - - for(j=0;j<256;j++) - tempbuf[j] = ((j+32)&255); //remap colors for screwy palette sectors - makepalookup(16,tempbuf,0,0,0,1); - - for(j=0;j<256;j++) tempbuf[j] = j; - makepalookup(17,tempbuf,24,24,24,1); - - for(j=0;j<256;j++) tempbuf[j] = j; //(j&31)+32; - makepalookup(18,tempbuf,8,8,48,1); - - prepareboard(boardfilename); //Load board - - initsb(option[1],option[2],digihz[option[7]>>4],((option[7]&4)>0)+1,((option[7]&2)>0)+1,60,option[7]&1); - //if (Bstrcmp(boardfilename,"klab.map") == 0) - // loadsong("klabsong.kdm"); - //else - loadsong("neatsong.ogg"); - musicon(); - - /* - if (option[4] > 0) - { - x1 = ((xdim-screensize)>>1); - x2 = x1+screensize-1; - y1 = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); - y2 = y1 + scale(screensize,ydim-32,xdim)-1; - - drawtilebackground(0L,0L,BACKGROUND,8,x1,y1,x2,y2,0); - - sendlogon(); - - if (option[4] < 5) waitplayers = 2; else waitplayers = option[4]-3; - while (numplayers < waitplayers) - { - sprintf(tempbuf,"%ld of %ld players in...",numplayers,waitplayers); - printext256(68L,84L,31,0,tempbuf,0); - nextpage(); - - if (getpacket(&other,packbuf) > 0) - if (packbuf[0] == 255) - keystatus[1] = 1; - - if (handleevents()) { - if (quitevent) { - keystatus[1] = 1; - quitevent = 0; - } - } - - if (keystatus[1]) - { - sendlogoff(); //Signing off - musicoff(); - uninitmultiplayers(); - uninittimer(); - uninitinput(); - uninitengine(); - uninitsb(); - uninitgroupfile(); - exit(0); - } - } - screenpeek = myconnectindex; - - if (numplayers <= 3) - networkmode = 1; - else - networkmode = 0; - - j = 1; - for(i=connecthead;i>=0;i=connectpoint2[i]) - { - if (myconnectindex == i) break; - j++; - } - sprintf(getmessage,"Player %ld",j); - if (networkmode == 0) - { - if (j == 1) Bstrcat(getmessage," (Master)"); - else Bstrcat(getmessage," (Slave)"); - } else - Bstrcat(getmessage," (Even)"); - getmessageleng = Bstrlen(getmessage); - getmessagetimeoff = totalclock+120; - } - */ - screenpeek = myconnectindex; - reccnt = 0; - for(i=connecthead;i>=0;i=connectpoint2[i]) initplayersprite((short)i); - - waitforeverybody(); - totalclock = ototalclock = 0; gotlastpacketclock = 0; nummoves = 0; - - ready2send = 1; - drawscreen(screenpeek,65536L); - - while (!keystatus[1]) //Main loop starts here - { - if (handleevents()) { - if (quitevent) { - keystatus[1] = 1; - quitevent = 0; - } - } - - refreshaudio(); - OSD_DispatchQueued(); - - // backslash (useful only with KDM) -// if (keystatus[0x2b]) { keystatus[0x2b] = 0; preparesndbuf(); } - - if ((networkmode == 1) || (myconnectindex != connecthead)) - while (fakemovefifoplc != movefifoend[myconnectindex]) fakedomovethings(); - - getpackets(); - - if (typemode == 0) //if normal game keys active - { - if ((keystatus[0x2a]&keystatus[0x36]&keystatus[0x13]) > 0) //Sh.Sh.R (replay) - { - keystatus[0x13] = 0; - playback(); - } - - if (keystatus[0x26]&(keystatus[0x1d]|keystatus[0x9d])) //Load game - { - keystatus[0x26] = 0; - loadgame(); - drawstatusbar(screenpeek); // Andy did this - } - - if (keystatus[0x1f]&(keystatus[0x1d]|keystatus[0x9d])) //Save game - { - keystatus[0x1f] = 0; - savegame(); - } - } - - if ((networkmode == 0) || (option[4] == 0)) - { - while (movefifoplc != movefifoend[0]) domovethings(); - } - else - { - j = connecthead; - if (j == myconnectindex) j = connectpoint2[j]; - averagelag[j] = ((averagelag[j]*7+(((movefifoend[myconnectindex]-movefifoend[j]+otherlag[j]+2)&255)<<8))>>3); - j = max(averagelag[j]>>9,1); - while (((movefifoend[myconnectindex]-movefifoplc)&(MOVEFIFOSIZ-1)) > j) - { - for(i=connecthead;i>=0;i=connectpoint2[i]) - if (movefifoplc == movefifoend[i]) break; - if (i >= 0) break; - if (myconnectindex != connecthead) - { - k = ((movefifoend[myconnectindex]-movefifoend[connecthead]-otherlag[connecthead]+128)&255); - if (k > 128+1) ototalclock++; - if (k < 128-1) ototalclock--; - } - domovethings(); - } - } - i = (totalclock-gotlastpacketclock)*(65536/(TIMERINTSPERSECOND/MOVESPERSECOND)); - - drawscreen(screenpeek,i); - } - - sendlogoff(); //Signing off - musicoff(); - uninitmultiplayers(); - uninittimer(); - uninitinput(); - uninitengine(); - uninitsb(); - uninitgroupfile(); - - return(0); -} - -void operatesector(short dasector) -{ //Door code - long i, j, k, s, nexti, good, cnt, datag; - long dax, day, daz, dax2, day2, daz2, centx, centy; - short startwall, endwall, wallfind[2]; - - datag = sector[dasector].lotag; - - startwall = sector[dasector].wallptr; - endwall = startwall + sector[dasector].wallnum; - centx = 0L, centy = 0L; - for(i=startwall;i= 0) //If door already moving, reverse its direction - { - if (datag == 8) - daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1); - else - daz = sector[dasector].floorz; - - if (animategoal[i] == daz) - animategoal[i] = sector[nextsectorneighborz(dasector,sector[dasector].floorz,-1,-1)].ceilingz; - else - animategoal[i] = daz; - animatevel[i] = 0; - } - else //else insert the door's ceiling on the animation list - { - if (sector[dasector].ceilingz == sector[dasector].floorz) - daz = sector[nextsectorneighborz(dasector,sector[dasector].floorz,-1,-1)].ceilingz; - else - { - if (datag == 8) - daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1); - else - daz = sector[dasector].floorz; - } - if ((j = setanimation(§or[dasector].ceilingz,daz,6L,6L)) >= 0) - wsayfollow("updowndr.wav",4096L+(krand()&255)-128,256L,¢x,¢y,0); - } - } - //Simple door that moves down - if ((datag == 7) || (datag == 8)) //If the sector in front's elevator - { - i = getanimationgoal((long)§or[dasector].floorz); - if (i >= 0) //If elevator already moving, reverse its direction - { - if (datag == 8) - daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1); - else - daz = sector[dasector].ceilingz; - - if (animategoal[i] == daz) - animategoal[i] = sector[nextsectorneighborz(dasector,sector[dasector].ceilingz,1,1)].floorz; - else - animategoal[i] = daz; - animatevel[i] = 0; - } - else //else insert the elevator's ceiling on the animation list - { - if (sector[dasector].floorz == sector[dasector].ceilingz) - daz = sector[nextsectorneighborz(dasector,sector[dasector].ceilingz,1,1)].floorz; - else - { - if (datag == 8) - daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1); - else - daz = sector[dasector].ceilingz; - } - if ((j = setanimation(§or[dasector].floorz,daz,6L,6L)) >= 0) - wsayfollow("updowndr.wav",4096L+(krand()&255)-128,256L,¢x,¢y,0); - } - } - - if (datag == 9) //Smooshy-wall sideways double-door - { - //find any points with either same x or same y coordinate - // as center (centx, centy) - should be 2 points found. - wallfind[0] = -1; - wallfind[1] = -1; - for(i=startwall;i>1)-wall[wallfind[j]].x; - day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y; - if (dax2 != 0) - { - dax2 = wall[wall[wall[wallfind[j]].point2].point2].x; - dax2 -= wall[wall[wallfind[j]].point2].x; - setanimation(&wall[wallfind[j]].x,wall[wallfind[j]].x+dax2,4L,0L); - setanimation(&wall[i].x,wall[i].x+dax2,4L,0L); - setanimation(&wall[wall[wallfind[j]].point2].x,wall[wall[wallfind[j]].point2].x+dax2,4L,0L); - } - else if (day2 != 0) - { - day2 = wall[wall[wall[wallfind[j]].point2].point2].y; - day2 -= wall[wall[wallfind[j]].point2].y; - setanimation(&wall[wallfind[j]].y,wall[wallfind[j]].y+day2,4L,0L); - setanimation(&wall[i].y,wall[i].y+day2,4L,0L); - setanimation(&wall[wall[wallfind[j]].point2].y,wall[wall[wallfind[j]].point2].y+day2,4L,0L); - } - } - else - { - i = wallfind[j]-1; if (i < startwall) i = endwall-1; - dax2 = ((wall[i].x+wall[wall[wallfind[j]].point2].x)>>1)-wall[wallfind[j]].x; - day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y; - if (dax2 != 0) - { - setanimation(&wall[wallfind[j]].x,centx,4L,0L); - setanimation(&wall[i].x,centx+dax2,4L,0L); - setanimation(&wall[wall[wallfind[j]].point2].x,centx+dax2,4L,0L); - } - else if (day2 != 0) - { - setanimation(&wall[wallfind[j]].y,centy,4L,0L); - setanimation(&wall[i].y,centy+day2,4L,0L); - setanimation(&wall[wall[wallfind[j]].point2].y,centy+day2,4L,0L); - } - } - } - wsayfollow("updowndr.wav",4096L-256L,256L,¢x,¢y,0); - wsayfollow("updowndr.wav",4096L+256L,256L,¢x,¢y,0); - } - - if (datag == 13) //Swinging door - { - for(i=0;i>1) == centx) && (((wall[wallfind[j]].y+wall[wall[wallfind[j]].point2].y)>>1) == centy)) - { //door was closed - //find what direction door should open - i = wallfind[j]-1; if (i < startwall) i = endwall-1; - dax2 = wall[i].x-wall[wallfind[j]].x; - day2 = wall[i].y-wall[wallfind[j]].y; - if (dax2 != 0) - { - dax2 = wall[wall[wall[wall[wallfind[j]].point2].point2].point2].x; - dax2 -= wall[wall[wall[wallfind[j]].point2].point2].x; - setanimation(&wall[wallfind[j]].x,wall[wallfind[j]].x+dax2,4L,0L); - setanimation(&wall[i].x,wall[i].x+dax2,4L,0L); - setanimation(&wall[wall[wallfind[j]].point2].x,wall[wall[wallfind[j]].point2].x+dax2,4L,0L); - setanimation(&wall[wall[wall[wallfind[j]].point2].point2].x,wall[wall[wall[wallfind[j]].point2].point2].x+dax2,4L,0L); - } - else if (day2 != 0) - { - day2 = wall[wall[wall[wall[wallfind[j]].point2].point2].point2].y; - day2 -= wall[wall[wall[wallfind[j]].point2].point2].y; - setanimation(&wall[wallfind[j]].y,wall[wallfind[j]].y+day2,4L,0L); - setanimation(&wall[i].y,wall[i].y+day2,4L,0L); - setanimation(&wall[wall[wallfind[j]].point2].y,wall[wall[wallfind[j]].point2].y+day2,4L,0L); - setanimation(&wall[wall[wall[wallfind[j]].point2].point2].y,wall[wall[wall[wallfind[j]].point2].point2].y+day2,4L,0L); - } - } - else - { //door was not closed - i = wallfind[j]-1; if (i < startwall) i = endwall-1; - dax2 = wall[i].x-wall[wallfind[j]].x; - day2 = wall[i].y-wall[wallfind[j]].y; - if (dax2 != 0) - { - setanimation(&wall[wallfind[j]].x,centx,4L,0L); - setanimation(&wall[i].x,centx+dax2,4L,0L); - setanimation(&wall[wall[wallfind[j]].point2].x,centx,4L,0L); - setanimation(&wall[wall[wall[wallfind[j]].point2].point2].x,centx+dax2,4L,0L); - } - else if (day2 != 0) - { - setanimation(&wall[wallfind[j]].y,centy,4L,0L); - setanimation(&wall[i].y,centy+day2,4L,0L); - setanimation(&wall[wall[wallfind[j]].point2].y,centy,4L,0L); - setanimation(&wall[wall[wall[wallfind[j]].point2].point2].y,centy+day2,4L,0L); - } - } - } - wsayfollow("updowndr.wav",4096L-64L,256L,¢x,¢y,0); - wsayfollow("updowndr.wav",4096L+64L,256L,¢x,¢y,0); - } -} - -void operatesprite(short dasprite) -{ - long datag; - - datag = sprite[dasprite].lotag; - - if (datag == 2) //A sprite that shoots a bomb - { - shootgun(dasprite, - sprite[dasprite].x,sprite[dasprite].y,sprite[dasprite].z, - sprite[dasprite].ang,100L,sprite[dasprite].sectnum,2); - } -} - -long changehealth(short snum, short deltahealth) -{ - long dax, day; - short good, k, startwall, endwall, s; - - if (health[snum] > 0) - { - health[snum] += deltahealth; - if (health[snum] > 999) health[snum] = 999; - - if (health[snum] <= 0) - { - health[snum] = -1; - wsayfollow("death.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); - sprite[playersprite[snum]].picnum = SKELETON; - } - - if ((snum == screenpeek) && (screensize <= xdim)) - { - if (health[snum] > 0) - sprintf(tempbuf,"Health:%3ld",health[snum]); - else - sprintf(tempbuf,"YOU STINK!"); - - printext((xdim>>1)-(Bstrlen(tempbuf)<<2),ydim-24,tempbuf,ALPHABET,80); - } - } - return(health[snum] <= 0); //You were just injured -} - -void changenumbombs(short snum, short deltanumbombs) { // Andy did this - numbombs[snum] += deltanumbombs; - if (numbombs[snum] > 999) numbombs[snum] = 999; - if (numbombs[snum] <= 0) { - wsayfollow("doh.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); - numbombs[snum] = 0; - } - - if ((snum == screenpeek) && (screensize <= xdim)) { - sprintf(tempbuf,"B:%3d",numbombs[snum]); - printext(8L,(ydim - 28L),tempbuf,ALPHABET,80); - } -} - -void changenummissiles(short snum, short deltanummissiles) { // Andy did this - nummissiles[snum] += deltanummissiles; - if (nummissiles[snum] > 999) nummissiles[snum] = 999; - if (nummissiles[snum] <= 0) { - wsayfollow("doh.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); - nummissiles[snum] = 0; - } - - if ((snum == screenpeek) && (screensize <= xdim)) { - sprintf(tempbuf,"M:%3d",nummissiles[snum]); - printext(8L,(ydim - 20L),tempbuf,ALPHABET,80); - } -} - -void changenumgrabbers(short snum, short deltanumgrabbers) { // Andy did this - numgrabbers[snum] += deltanumgrabbers; - if (numgrabbers[snum] > 999) numgrabbers[snum] = 999; - if (numgrabbers[snum] <= 0) { - wsayfollow("doh.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); - numgrabbers[snum] = 0; - } - - if ((snum == screenpeek) && (screensize <= xdim)) { - sprintf(tempbuf,"G:%3d",numgrabbers[snum]); - printext(8L,(ydim - 12L),tempbuf,ALPHABET,80); - } -} - -static long ostatusflytime = 0x80000000; -void drawstatusflytime(short snum) { // Andy did this - long nstatusflytime; - - if ((snum == screenpeek) && (screensize <= xdim)) { - nstatusflytime = (((flytime[snum] + 119) - lockclock) / 120); - if (nstatusflytime > 1000) nstatusflytime = 1000; - else if (nstatusflytime < 0) nstatusflytime = 0; - if (nstatusflytime != ostatusflytime) { - if (nstatusflytime > 999) sprintf(tempbuf,"FT:BIG"); - else sprintf(tempbuf,"FT:%3ld",nstatusflytime); - printext((xdim - 56L),(ydim - 20L),tempbuf,ALPHABET,80); - ostatusflytime = nstatusflytime; - } - } -} - -void drawstatusbar(short snum) { // Andy did this - long nstatusflytime; - - if ((snum == screenpeek) && (screensize <= xdim)) { - Bsprintf(tempbuf,"Deaths:%d",deaths[snum]); - printext((xdim>>1)-(Bstrlen(tempbuf)<<2),ydim-16,tempbuf,ALPHABET,80); - Bsprintf(tempbuf,"Health:%3ld",health[snum]); - printext((xdim>>1)-(Bstrlen(tempbuf)<<2),ydim-24,tempbuf,ALPHABET,80); - - Bsprintf(tempbuf,"B:%3d",numbombs[snum]); - printext(8L,(ydim - 28L),tempbuf,ALPHABET,80); - Bsprintf(tempbuf,"M:%3d",nummissiles[snum]); - printext(8L,(ydim - 20L),tempbuf,ALPHABET,80); - Bsprintf(tempbuf,"G:%3d",numgrabbers[snum]); - printext(8L,(ydim - 12L),tempbuf,ALPHABET,80); - - nstatusflytime = (((flytime[snum] + 119) - lockclock) / 120); - if (nstatusflytime < 0) { - Bsprintf(tempbuf,"FT: 0"); - ostatusflytime = 0; - } - else if (nstatusflytime > 999) { - Bsprintf(tempbuf,"FT:BIG"); - ostatusflytime = 999; - } - else { - Bsprintf(tempbuf,"FT:%3ld",nstatusflytime); - ostatusflytime = nstatusflytime; - } - printext((xdim - 56L),(ydim - 20L),tempbuf,ALPHABET,80); - } -} - -void prepareboard(char *daboardfilename) -{ - short startwall, endwall, dasector; - long i, j, k=0, s, dax, day, daz, dax2, day2; - - getmessageleng = 0; - typemessageleng = 0; - - randomseed = 17L; - - //Clear (do)animation's list - animatecnt = 0; - typemode = 0; - locselectedgun = 0; - locselectedgun2 = 0; - - if (loadboard(daboardfilename,0,&posx[0],&posy[0],&posz[0],&ang[0],&cursectnum[0]) == -1) - { - musicoff(); - uninitmultiplayers(); - uninittimer(); - uninitinput(); - uninitengine(); - uninitsb(); - uninitgroupfile(); - printf("Board not found\n"); - exit(0); - } else { - char *fp; - - strcpy(tempbuf, daboardfilename); - fp = strrchr(tempbuf,'.'); - if (fp) *fp = 0; - strcat(tempbuf,".mhk"); - - loadmaphack(tempbuf); - } - - setup3dscreen(); - - for(i=0;i dax2) dax2 = wall[j].x; - if (wall[j].y > day2) day2 = wall[j].y; - if (wall[j].lotag == 3) k = j; - } - if (wall[k].x == dax) dragxdir[dragsectorcnt] = -16; - if (wall[k].y == day) dragydir[dragsectorcnt] = -16; - if (wall[k].x == dax2) dragxdir[dragsectorcnt] = 16; - if (wall[k].y == day2) dragydir[dragsectorcnt] = 16; - - dasector = wall[startwall].nextsector; - dragx1[dragsectorcnt] = 0x7fffffff; - dragy1[dragsectorcnt] = 0x7fffffff; - dragx2[dragsectorcnt] = 0x80000000; - dragy2[dragsectorcnt] = 0x80000000; - startwall = sector[dasector].wallptr; - endwall = startwall+sector[dasector].wallnum; - for(j=startwall;j dragx2[dragsectorcnt]) dragx2[dragsectorcnt] = wall[j].x; - if (wall[j].y > dragy2[dragsectorcnt]) dragy2[dragsectorcnt] = wall[j].y; - - setinterpolation(§or[dasector].floorz); - setinterpolation(&wall[j].x); - setinterpolation(&wall[j].y); - setinterpolation(&wall[wall[j].nextwall].x); - setinterpolation(&wall[wall[j].nextwall].y); - } - - dragx1[dragsectorcnt] += (wall[sector[i].wallptr].x-dax); - dragy1[dragsectorcnt] += (wall[sector[i].wallptr].y-day); - dragx2[dragsectorcnt] -= (dax2-wall[sector[i].wallptr].x); - dragy2[dragsectorcnt] -= (day2-wall[sector[i].wallptr].y); - - dragfloorz[dragsectorcnt] = sector[i].floorz; - - dragsectorlist[dragsectorcnt++] = i; - break; - case 13: - startwall = sector[i].wallptr; - endwall = startwall+sector[i].wallnum; - for(j=startwall;j dax2) dax2 = wall[j].x; - if (wall[j].y > day2) day2 = wall[j].y; - } - for(j=startwall;j dax) && (wall[j].y > day) && (wall[j].x < dax2) && (wall[j].y < day2)) - { - subwayx[subwaytrackcnt] = wall[j].x; - } - else - { - subwaystop[subwaytrackcnt][subwaystopcnt[subwaytrackcnt]] = wall[j].x; - subwaystopcnt[subwaytrackcnt]++; - } - } - } - - for(j=1;j subwaytrackx1[subwaytrackcnt]) - if (wall[startwall].y > subwaytracky1[subwaytrackcnt]) - if (wall[startwall].x < subwaytrackx2[subwaytrackcnt]) - if (wall[startwall].y < subwaytracky2[subwaytrackcnt]) - { - if (sector[j].floorz != sector[i].floorz) - { - sector[j].ceilingstat |= 64; - sector[j].floorstat |= 64; - } - subwaytracksector[subwaytrackcnt][subwaynumsectors[subwaytrackcnt]] = j; - subwaynumsectors[subwaytrackcnt]++; - } - } - - subwayvel[subwaytrackcnt] = 64; - subwaypausetime[subwaytrackcnt] = 720; - - startwall = sector[i].wallptr; - endwall = startwall+sector[i].wallnum; - for(k=startwall;k subwaytrackx1[subwaytrackcnt]) - if (wall[k].y > subwaytracky1[subwaytrackcnt]) - if (wall[k].x < subwaytrackx2[subwaytrackcnt]) - if (wall[k].y < subwaytracky2[subwaytrackcnt]) - setinterpolation(&wall[k].x); - - for(j=1;j=0;k=nextspritesect[k]) - if (statrate[sprite[k].statnum] < 0) - setinterpolation(&sprite[k].x); - } - - - subwaytrackcnt++; - break; - } - if (sector[i].floorpicnum == FLOORMIRROR) - floormirrorsector[mirrorcnt++] = i; - //if (sector[i].ceilingpicnum == FLOORMIRROR) floormirrorsector[mirrorcnt++] = i; //SOS - } - - //Scan wall tags - - mirrorcnt = 0; - tilesizx[MIRROR] = 0; - tilesizy[MIRROR] = 0; - for(i=0;i= 0) && (wall[i].overpicnum == MIRROR) && (wall[i].cstat&32)) - { - if ((sector[s].floorstat&1) == 0) - { - wall[i].overpicnum = MIRRORLABEL+mirrorcnt; - sector[s].ceilingpicnum = MIRRORLABEL+mirrorcnt; - sector[s].floorpicnum = MIRRORLABEL+mirrorcnt; - sector[s].floorstat |= 1; - mirrorwall[mirrorcnt] = i; - mirrorsector[mirrorcnt] = s; - mirrorcnt++; - } - else - wall[i].overpicnum = sector[s].ceilingpicnum; - } - } - - //Invalidate textures in sector behind mirror - for(i=0;i=0;i--) copybuf(&sprite[i].x,&osprite[i].x,3); - - searchmap(cursectnum[connecthead]); - - lockclock = 0; - ototalclock = 0; - gotlastpacketclock = 0; - - screensize = xdim; - dax = ((xdim-screensize)>>1); - dax2 = dax+screensize-1; - day = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); - day2 = day + scale(screensize,ydim-32,xdim)-1; - setview(dax,day,dax2,day2); - - startofdynamicinterpolations = numinterpolations; - - /* - for(i=connecthead;i>=0;i=connectpoint2[i]) myminlag[i] = 0; - otherminlag = mymaxlag = 0; - */ -} - -void checktouchsprite(short snum, short sectnum) -{ - long i, nexti; - - if ((sectnum < 0) || (sectnum >= numsectors)) return; - - for(i=headspritesect[sectnum];i>=0;i=nexti) - { - nexti = nextspritesect[i]; - if (sprite[i].cstat&0x8000) continue; - if ((klabs(posx[snum]-sprite[i].x)+klabs(posy[snum]-sprite[i].y) < 512) && (klabs((posz[snum]>>8)-((sprite[i].z>>8)-(tilesizy[sprite[i].picnum]>>1))) <= 40)) - { - switch(sprite[i].picnum) - { - case COIN: - wsayfollow("getstuff.wav",4096L+(krand()&127)-64,192L,&sprite[i].x,&sprite[i].y,0); - changehealth(snum,5); - if (sprite[i].statnum == 12) deletesprite((short)i); - else { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*60; - changespritestat((short)i,11); - } - break; - case DIAMONDS: - wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - changehealth(snum,15); - if (sprite[i].statnum == 12) deletesprite((short)i); - else { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*120; - changespritestat((short)i,11); - } - break; - case COINSTACK: - wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - changehealth(snum,25); - if (sprite[i].statnum == 12) deletesprite((short)i); - else { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*180; - changespritestat((short)i,11); - } - break; - case GIFTBOX: - wsayfollow("getstuff.wav",4096L+(krand()&127)+256-mulscale4(sprite[i].xrepeat,sprite[i].yrepeat),208L,&sprite[i].x,&sprite[i].y,0); - changehealth(snum,max(mulscale8(sprite[i].xrepeat,sprite[i].yrepeat),1)); - if (sprite[i].statnum == 12) deletesprite((short)i); - else { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 90*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - case CANNON: - wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - if (snum == myconnectindex) keystatus[4] = 1; - changenumbombs(snum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); - if (sprite[i].statnum == 12) deletesprite((short)i); - else { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 60*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - case LAUNCHER: - wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - if (snum == myconnectindex) keystatus[5] = 1; - changenummissiles(snum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); - if (sprite[i].statnum == 12) deletesprite((short)i); - else { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 90*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - case GRABCANNON: - wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - if (snum == myconnectindex) keystatus[6] = 1; - changenumgrabbers(snum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); - if (sprite[i].statnum == 12) deletesprite((short)i); - else { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - case AIRPLANE: - wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - if (flytime[snum] < lockclock) flytime[snum] = lockclock; - flytime[snum] += 60*(sprite[i].xrepeat+sprite[i].yrepeat); - drawstatusflytime(snum); - if (sprite[i].statnum == 12) deletesprite((short)i); - else { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - } - } - } -} - -void checkgrabbertouchsprite(short snum, short sectnum) // Andy did this -{ - long i, nexti; - short onum; - - if ((sectnum < 0) || (sectnum >= numsectors)) return; - onum = (sprite[snum].owner & (MAXSPRITES - 1)); - - for(i=headspritesect[sectnum];i>=0;i=nexti) - { - nexti = nextspritesect[i]; - if (sprite[i].cstat&0x8000) continue; - if ((klabs(sprite[snum].x-sprite[i].x)+klabs(sprite[snum].y-sprite[i].y) < 512) && (klabs((sprite[snum].z>>8)-((sprite[i].z>>8)-(tilesizy[sprite[i].picnum]>>1))) <= 40)) - { - switch(sprite[i].picnum) - { - case COIN: - wsayfollow("getstuff.wav",4096L+(krand()&127)-64,192L,&sprite[i].x,&sprite[i].y,0); - changehealth(onum,5); - if (sprite[i].statnum == 12) deletesprite((short)i); - else { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*60; - changespritestat((short)i,11); - } - break; - case DIAMONDS: - wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - changehealth(onum,15); - if (sprite[i].statnum == 12) deletesprite((short)i); - else { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*120; - changespritestat((short)i,11); - } - break; - case COINSTACK: - wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - changehealth(onum,25); - if (sprite[i].statnum == 12) deletesprite((short)i); - else { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*180; - changespritestat((short)i,11); - } - break; - case GIFTBOX: - wsayfollow("getstuff.wav",4096L+(krand()&127)+256-mulscale4(sprite[i].xrepeat,sprite[i].yrepeat),208L,&sprite[i].x,&sprite[i].y,0); - changehealth(onum,max(mulscale8(sprite[i].xrepeat,sprite[i].yrepeat),1)); - if (sprite[i].statnum == 12) deletesprite((short)i); - else { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 90*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - case CANNON: - wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - if (onum == myconnectindex) keystatus[4] = 1; - changenumbombs(onum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); - if (sprite[i].statnum == 12) deletesprite((short)i); - else { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 60*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - case LAUNCHER: - wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - if (onum == myconnectindex) keystatus[5] = 1; - changenummissiles(onum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); - if (sprite[i].statnum == 12) deletesprite((short)i); - else { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 90*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - case GRABCANNON: - wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - if (onum == myconnectindex) keystatus[6] = 1; - changenumgrabbers(onum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); - if (sprite[i].statnum == 12) deletesprite((short)i); - else { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - case AIRPLANE: - wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - if (flytime[snum] < lockclock) flytime[snum] = lockclock; - flytime[onum] += 60*(sprite[i].xrepeat+sprite[i].yrepeat); - drawstatusflytime(onum); - if (sprite[i].statnum == 12) deletesprite((short)i); - else { - sprite[i].cstat |= 0x8000; - sprite[i].extra = 120*(sprite[i].xrepeat+sprite[i].yrepeat); - changespritestat((short)i,11); - } - break; - } - } - } -} - -void shootgun(short snum, long x, long y, long z, - short daang, long dahoriz, short dasectnum, char guntype) -{ - short hitsect, hitwall, hitsprite, daang2; - long i, j, daz2, hitx, hity, hitz; - - switch(guntype) - { - case 0: //Shoot chain gun - daang2 = ((daang + (krand()&31)-16)&2047); - daz2 = ((100-dahoriz)*2000) + ((krand()-32768)>>1); - - hitscan(x,y,z,dasectnum, //Start position - sintable[(daang2+512)&2047], //X vector of 3D ang - sintable[daang2&2047], //Y vector of 3D ang - daz2, //Z vector of 3D ang - &hitsect,&hitwall,&hitsprite,&hitx,&hity,&hitz,CLIPMASK1); - - if (wall[hitwall].picnum == KENPICTURE) - { - if (waloff[MAXTILES-1] != 0) wall[hitwall].picnum = MAXTILES-1; - wsayfollow("hello.wav",4096L+(krand()&127)-64,256L,&wall[hitwall].x,&wall[hitwall].y,0); - } - else if (((hitwall < 0) && (hitsprite < 0) && (hitz >= z) && ((sector[hitsect].floorpicnum == SLIME) || (sector[hitsect].floorpicnum == FLOORMIRROR))) || ((hitwall >= 0) && (wall[hitwall].picnum == SLIME))) - { //If you shoot slime, make a splash - wsayfollow("splash.wav",4096L+(krand()&511)-256,256L,&hitx,&hity,0); - spawnsprite(j,hitx,hity,hitz,2,0,0,32,64,64,0,0,SPLASH,daang, - 0,0,0,snum+4096,hitsect,4,63,0,0); //63=time left for splash - } - else - { - wsayfollow("shoot.wav",4096L+(krand()&127)-64,256L,&hitx,&hity,0); - - if ((hitsprite >= 0) && (sprite[hitsprite].statnum < MAXSTATUS)) - switch(sprite[hitsprite].picnum) - { - case BROWNMONSTER: - if (sprite[hitsprite].lotag > 0) sprite[hitsprite].lotag -= 10; - if (sprite[hitsprite].lotag > 0) - { - wsayfollow("hurt.wav",4096L+(krand()&511)-256,256L,&hitx,&hity,0); - if (sprite[hitsprite].lotag <= 25) - sprite[hitsprite].cstat |= 2; - } - else - { - wsayfollow("mondie.wav",4096L+(krand()&127)-64,256L,&hitx,&hity,0); - sprite[hitsprite].z += ((tilesizy[sprite[hitsprite].picnum]*sprite[hitsprite].yrepeat)<<1); - sprite[hitsprite].picnum = GIFTBOX; - sprite[hitsprite].cstat &= ~0x83; //Should not clip, foot-z - changespritestat(hitsprite,12); - - spawnsprite(j,hitx,hity,hitz+(32<<8),0,-4,0,32,64,64, - 0,0,EXPLOSION,daang,0,0,0,snum+4096, - hitsect,5,31,0,0); - } - break; - case EVILAL: - wsayfollow("blowup.wav",4096L+(krand()&127)-64,256L,&hitx,&hity,0); - sprite[hitsprite].picnum = EVILALGRAVE; - sprite[hitsprite].cstat = 0; - sprite[hitsprite].xvel = (krand()&255)-128; - sprite[hitsprite].yvel = (krand()&255)-128; - sprite[hitsprite].zvel = (krand()&4095)-3072; - changespritestat(hitsprite,9); - - spawnsprite(j,hitx,hity,hitz+(32<<8),0,-4,0,32,64,64,0, - 0,EXPLOSION,daang,0,0,0,snum+4096,hitsect,5,31,0,0); - //31=time left for explosion - - break; - case PLAYER: - for(j=connecthead;j>=0;j=connectpoint2[j]) - if (playersprite[j] == hitsprite) - { - wsayfollow("ouch.wav",4096L+(krand()&127)-64,256L,&hitx,&hity,0); - changehealth(j,-10); - break; - } - break; - } - - spawnsprite(j,hitx,hity,hitz+(8<<8),2,-4,0,32,16,16,0,0, - EXPLOSION,daang,0,0,0,snum+4096,hitsect,3,63,0,0); - - //Sprite starts out with center exactly on wall. - //This moves it back enough to see it at all angles. - movesprite((short)j,-(((long)sintable[(512+daang)&2047]*TICSPERFRAME)<<4),-(((long)sintable[daang]*TICSPERFRAME)<<4),0L,4L<<8,4L<<8,CLIPMASK1); - } - break; - case 1: //Shoot silver sphere bullet - spawnsprite(j,x,y,z,1+128,0,0,16,64,64,0,0,BULLET,daang, - sintable[(daang+512)&2047]>>5,sintable[daang&2047]>>5, - (100-dahoriz)<<6,snum+4096,dasectnum,6,0,0,0); - wsayfollow("shoot2.wav",4096L+(krand()&127)-64,128L,&sprite[j].x,&sprite[j].y,1); - break; - case 2: //Shoot bomb - spawnsprite(j,x,y,z,128,0,0,12,16,16,0,0,BOMB,daang, - sintable[(daang+512)&2047]*5>>8,sintable[daang&2047]*5>>8, - (80-dahoriz)<<6,snum+4096,dasectnum,6,0,0,0); - wsayfollow("shoot3.wav",4096L+(krand()&127)-64,192L,&sprite[j].x,&sprite[j].y,1); - break; - case 3: //Shoot missile (Andy did this) - spawnsprite(j,x,y,z,1+128,0,0,16,32,32,0,0,MISSILE,daang, - sintable[(daang+512)&2047]>>4,sintable[daang&2047]>>4, - (100-dahoriz)<<7,snum+4096,dasectnum,6,0,0,0); - wsayfollow("shoot3.wav",4096L+(krand()&127)-64,192L,&sprite[j].x,&sprite[j].y,1); - break; - case 4: //Shoot grabber (Andy did this) - spawnsprite(j,x,y,z,1+128,0,0,16,64,64,0,0,GRABBER,daang, - sintable[(daang+512)&2047]>>5,sintable[daang&2047]>>5, - (100-dahoriz)<<6,snum+4096,dasectnum,6,0,0,0); - wsayfollow("shoot4.wav",4096L+(krand()&127)-64,128L,&sprite[j].x,&sprite[j].y,1); - break; - } -} - -#define MAXVOXMIPS 5 -extern char *voxoff[][MAXVOXMIPS]; -void analyzesprites(long dax, long day) -{ - long i, j=0, k, *intptr; - point3d *ospr; - spritetype *tspr; - - //This function is called between drawrooms() and drawmasks() - //It has a list of possible sprites that may be drawn on this frame - - for(i=0,tspr=&tsprite[0];ipicnum] >= 0) - switch(tspr->picnum) - { - case PLAYER: - // //Get which of the 8 angles of the sprite to draw (0-7) - // //k ranges from 0-7 - //k = getangle(tspr->x-dax,tspr->y-day); - //k = (((tspr->ang+3072+128-k)&2047)>>8)&7; - // //This guy has only 5 pictures for 8 angles (3 are x-flipped) - //if (k <= 4) - //{ - // tspr->picnum += (k<<2); - // tspr->cstat &= ~4; //clear x-flipping bit - //} - //else - //{ - // tspr->picnum += ((8-k)<<2); - // tspr->cstat |= 4; //set x-flipping bit - //} - - if ((tspr->cstat&2) == 0) - { - //tspr->cstat |= 48; tspr->picnum = tiletovox[tspr->picnum]; - intptr = (long *)voxoff[ tiletovox[PLAYER] ][0]; - tspr->xrepeat = scale(tspr->xrepeat,56,intptr[2]); - tspr->yrepeat = scale(tspr->yrepeat,56,intptr[2]); - tspr->shade -= 6; - } - break; - case BROWNMONSTER: - //tspr->cstat |= 48; tspr->picnum = tiletovox[tspr->picnum]; - break; - } -#endif - - k = statrate[tspr->statnum]; - if (k >= 0) //Interpolate moving sprite - { - ospr = &osprite[tspr->owner]; - switch(k) - { - case 0: j = smoothratio; break; - case 1: j = (smoothratio>>1)+(((nummoves-tspr->owner)&1)<<15); break; - case 3: j = (smoothratio>>2)+(((nummoves-tspr->owner)&3)<<14); break; - case 7: j = (smoothratio>>3)+(((nummoves-tspr->owner)&7)<<13); break; - case 15: j = (smoothratio>>4)+(((nummoves-tspr->owner)&15)<<12); break; - } - k = tspr->x-ospr->x; tspr->x = ospr->x; - if (k != 0) tspr->x += mulscale16(k,j); - k = tspr->y-ospr->y; tspr->y = ospr->y; - if (k != 0) tspr->y += mulscale16(k,j); - k = tspr->z-ospr->z; tspr->z = ospr->z; - if (k != 0) tspr->z += mulscale16(k,j); - } - - //Don't allow close explosion sprites to be transluscent - k = tspr->statnum; - if ((k == 3) || (k == 4) || (k == 5) || (k == 7)) - if (klabs(dax-tspr->x) < 256) - if (klabs(day-tspr->y) < 256) - tspr->cstat &= ~2; - - tspr->shade += 6; - if (sector[tspr->sectnum].ceilingstat&1) - tspr->shade += sector[tspr->sectnum].ceilingshade; - else - tspr->shade += sector[tspr->sectnum].floorshade; - } -} - -void tagcode(void) -{ - long i, nexti, j, k, l, s, dax, day, daz, dax2, day2, cnt, good; - short startwall, endwall, dasector, p, oldang; - - for(p=connecthead;p>=0;p=connectpoint2[p]) - { - if (sector[cursectnum[p]].lotag == 1) - { - activatehitag(sector[cursectnum[p]].hitag); - sector[cursectnum[p]].lotag = 0; - sector[cursectnum[p]].hitag = 0; - } - if ((sector[cursectnum[p]].lotag == 2) && (cursectnum[p] != ocursectnum[p])) - activatehitag(sector[cursectnum[p]].hitag); - } - - for(i=0;i>2); - if (j >= 16) j = 31-j; - { - sector[dasector].ceilingshade = j; - sector[dasector].floorshade = j; - startwall = sector[dasector].wallptr; - endwall = startwall+sector[dasector].wallnum; - for(s=startwall;s=0;p=connectpoint2[p]) - if (sector[cursectnum[p]].lotag == 10) //warp sector - { - if (cursectnum[p] != ocursectnum[p]) - { - warpsprite(playersprite[p]); - posx[p] = sprite[playersprite[p]].x; - posy[p] = sprite[playersprite[p]].y; - posz[p] = sprite[playersprite[p]].z; - ang[p] = sprite[playersprite[p]].ang; - cursectnum[p] = sprite[playersprite[p]].sectnum; - - sprite[playersprite[p]].z += EYEHEIGHT; - - //warp(&posx[p],&posy[p],&posz[p],&ang[p],&cursectnum[p]); - //Update sprite representation of player - //setsprite(playersprite[p],posx[p],posy[p],posz[p]+EYEHEIGHT); - //sprite[playersprite[p]].ang = ang[p]; - } - } - - for(i=0;i>2)&255); - } - - for(i=0;i>2)&255); - sector[floorpanninglist[i]].floorypanning = ((lockclock>>2)&255); - } - - for(i=0;i dragx2[i]) dragxdir[i] = -16; - if (wall[startwall].y+dragydir[i] > dragy2[i]) dragydir[i] = -16; - - for(j=startwall;j>3); - - for(p=connecthead;p>=0;p=connectpoint2[p]) - if (cursectnum[p] == dasector) - { - posx[p] += dragxdir[i]; - posy[p] += dragydir[i]; - if (p == myconnectindex) - { myx += dragxdir[i]; myy += dragydir[i]; } - //posz[p] += (sector[dasector].floorz-j); - - //Update sprite representation of player - setsprite(playersprite[p],posx[p],posy[p],posz[p]+EYEHEIGHT); - sprite[playersprite[p]].ang = ang[p]; - } - } - - for(i=0;i=0;p=connectpoint2[p]) - if ((cursectnum[p] == swingsector[i]) || (testneighborsectors(cursectnum[p],swingsector[i]) == 1)) - { - cnt = 256; - do - { - good = 1; - - //swingangopendir is -1 if forwards, 1 is backwards - l = (swingangopendir[i] > 0); - for(k=l+3;k>=l;k--) - if (clipinsidebox(posx[p],posy[p],swingwall[i][k],128L) != 0) - { - good = 0; - break; - } - if (good == 0) - { - if (cnt == 256) - { - swinganginc[i] = -swinganginc[i]; - swingang[i] = oldang; - } - else - { - swingang[i] = ((swingang[i]-swinganginc[i])&2047); - } - for(k=1;k<=3;k++) - rotatepoint(swingx[i][0],swingy[i][0],swingx[i][k],swingy[i][k],swingang[i],&wall[swingwall[i][k]].x,&wall[swingwall[i][k]].y); - if (swingang[i] == swingangclosed[i]) - { - wsayfollow("closdoor.wav",4096L+(krand()&511)-256,256L,&swingx[i][0],&swingy[i][0],0); - swinganginc[i] = 0; - break; - } - if (swingang[i] == swingangopen[i]) - { - swinganginc[i] = 0; - break; - } - cnt--; - } - } while ((good == 0) && (cnt > 0)); - } - } - } - if (swinganginc[i] == 0) - for(j=1;j<=3;j++) - { - stopinterpolation(&wall[swingwall[i][j]].x); - stopinterpolation(&wall[swingwall[i][j]].y); - } - } - - for(i=0;i 2)) - { - dasector = subwaytracksector[i][0]; - startwall = sector[dasector].wallptr; - endwall = startwall+sector[dasector].wallnum; - for(k=startwall;k subwaytrackx1[i]) - if (wall[k].y > subwaytracky1[i]) - if (wall[k].x < subwaytrackx2[i]) - if (wall[k].y < subwaytracky2[i]) - wall[k].x += subwayvel[i]; - - for(j=1;j=0;s=nextspritesect[s]) - sprite[s].x += subwayvel[i]; - } - - for(p=connecthead;p>=0;p=connectpoint2[p]) - if (cursectnum[p] != subwaytracksector[i][0]) - if (sector[cursectnum[p]].floorz != sector[subwaytracksector[i][0]].floorz) - if (posx[p] > subwaytrackx1[i]) - if (posy[p] > subwaytracky1[i]) - if (posx[p] < subwaytrackx2[i]) - if (posy[p] < subwaytracky2[i]) - { - posx[p] += subwayvel[i]; - if (p == myconnectindex) - { myx += subwayvel[i]; } - - //Update sprite representation of player - setsprite(playersprite[p],posx[p],posy[p],posz[p]+EYEHEIGHT); - sprite[playersprite[p]].ang = ang[p]; - } - - subwayx[i] += subwayvel[i]; - } - - j = subwayvel[i]; - k = subwaystop[i][subwaygoalstop[i]] - subwayx[i]; - if (k > 0) - { - if (k > 4096) - { - if (subwayvel[i] < 256) subwayvel[i]++; - } - else - subwayvel[i] = (k>>4)+1; - } - else if (k < 0) - { - if (k < -4096) - { - if (subwayvel[i] > -256) subwayvel[i]--; - } - else - subwayvel[i] = (k>>4)-1; - } - if ((j < 0) && (subwayvel[i] >= 0)) subwayvel[i] = -1; - if ((j > 0) && (subwayvel[i] <= 0)) subwayvel[i] = 1; - - if ((subwayvel[i] <= 2) && (subwayvel[i] >= -2) && (klabs(k) < 2048)) - { - //Open / close doors - if ((subwaypausetime[i] == 720) || ((subwaypausetime[i] >= 120) && (subwaypausetime[i]-TICSPERFRAME < 120))) - activatehitag(sector[subwaytracksector[i][0]].hitag); - - subwaypausetime[i] -= TICSPERFRAME; - if (subwaypausetime[i] < 0) - { - subwaypausetime[i] = 720; - if (subwayvel[i] < 0) - { - subwaygoalstop[i]--; - if (subwaygoalstop[i] < 0) - { - subwaygoalstop[i] = 1; - subwayvel[i] = 1; - } - } - else if (subwayvel[i] > 0) - { - subwaygoalstop[i]++; - if (subwaygoalstop[i] >= subwaystopcnt[i]) - { - subwaygoalstop[i] = subwaystopcnt[i]-2; - subwayvel[i] = -1; - } - } - } - } - } -} - -void statuslistcode(void) -{ - short p, target, hitobject, daang, osectnum, movestat; - long i, nexti, j, nextj, k, l, dax, day, daz, dist, ox, oy, mindist; - long doubvel, xvect, yvect; - - //Go through active BROWNMONSTER list - for(i=headspritestat[1];i>=0;i=nexti) - { - nexti = nextspritestat[i]; - - k = krand(); - - //Choose a target player - mindist = 0x7fffffff; target = connecthead; - for(p=connecthead;p>=0;p=connectpoint2[p]) - { - dist = klabs(sprite[i].x-posx[p])+klabs(sprite[i].y-posy[p]); - if (dist < mindist) mindist = dist, target = p; - } - - //brown monster decides to shoot bullet - if ((k&63) == 23) - { - if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[target],posy[target],posz[target],cursectnum[target]) == 0) - { - if ((k&0xf00) == 0xb00) changespritestat(i,2); - } - else - { - wsayfollow("monshoot.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1); - - doubvel = (TICSPERFRAME<<((ssync[target].bits&256)>0)); - xvect = 0, yvect = 0; - if (ssync[target].fvel != 0) - { - xvect += ((((long)ssync[target].fvel)*doubvel*(long)sintable[(ang[target]+512)&2047])>>3); - yvect += ((((long)ssync[target].fvel)*doubvel*(long)sintable[ang[target]&2047])>>3); - } - if (ssync[target].svel != 0) - { - xvect += ((((long)ssync[target].svel)*doubvel*(long)sintable[ang[target]&2047])>>3); - yvect += ((((long)ssync[target].svel)*doubvel*(long)sintable[(ang[target]+1536)&2047])>>3); - } - - ox = posx[target]; oy = posy[target]; - - //distance is j - j = ksqrt((ox-sprite[i].x)*(ox-sprite[i].x)+(oy-sprite[i].y)*(oy-sprite[i].y)); - - switch((sprite[i].extra>>11)&3) - { - case 1: j = -(j>>1); break; - case 3: j = 0; break; - case 0: case 2: break; - } - sprite[i].extra += 2048; - - //rate is (TICSPERFRAME<<19) - xvect = scale(xvect,j,TICSPERFRAME<<19); - yvect = scale(yvect,j,TICSPERFRAME<<19); - clipmove(&ox,&oy,&posz[target],&cursectnum[target],xvect<<14,yvect<<14,128L,4<<8,4<<8,CLIPMASK0); - ox -= sprite[i].x; - oy -= sprite[i].y; - - daang = ((getangle(ox,oy)+(krand()&7)-4)&2047); - - dax = (sintable[(daang+512)&2047]>>6); - day = (sintable[daang&2047]>>6); - daz = 0; - if (ox != 0) - daz = scale(dax,posz[target]+(8<<8)-sprite[i].z,ox); - else if (oy != 0) - daz = scale(day,posz[target]+(8<<8)-sprite[i].z,oy); - - spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z,128,0,0, - 16,sprite[i].xrepeat,sprite[i].yrepeat,0,0,BULLET,daang,dax,day,daz,i,sprite[i].sectnum,6,0,0,0); - - sprite[i].extra &= (~2047); - } - } - - //Move brown monster - dax = sprite[i].x; //Back up old x&y if stepping off cliff - day = sprite[i].y; - - doubvel = max(mulscale7(sprite[i].xrepeat,sprite[i].yrepeat),4); - - osectnum = sprite[i].sectnum; - movestat = movesprite((short)i,(long)sintable[(sprite[i].ang+512)&2047]*doubvel,(long)sintable[sprite[i].ang]*doubvel,0L,4L<<8,4L<<8,CLIPMASK0); - if (globloz > sprite[i].z+(48<<8)) - { sprite[i].x = dax; sprite[i].y = day; movestat = 1; } - else - sprite[i].z = globloz-((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1); - - if ((sprite[i].sectnum != osectnum) && (sector[sprite[i].sectnum].lotag == 10)) - { warpsprite((short)i); movestat = 0; } - - if ((movestat != 0) || ((k&63) == 1)) - { - if (sprite[i].ang == (sprite[i].extra&2047)) - { - daang = (getangle(posx[target]-sprite[i].x,posy[target]-sprite[i].y)&2047); - daang = ((daang+(krand()&1023)-512)&2047); - sprite[i].extra = ((sprite[i].extra&(~2047))|daang); - } - if ((sprite[i].extra-sprite[i].ang)&1024) - { - sprite[i].ang = ((sprite[i].ang-32)&2047); - if (!((sprite[i].extra-sprite[i].ang)&1024)) sprite[i].ang = (sprite[i].extra&2047); - } - else - { - sprite[i].ang = ((sprite[i].ang+32)&2047); - if (((sprite[i].extra-sprite[i].ang)&1024)) sprite[i].ang = (sprite[i].extra&2047); - } - } - } - - for(i=headspritestat[10];i>=0;i=nexti) //EVILAL list - { - nexti = nextspritestat[i]; - - if (sprite[i].yrepeat < 38) continue; - if (sprite[i].yrepeat < 64) - { - sprite[i].xrepeat++; - sprite[i].yrepeat++; - continue; - } - - if ((nummoves-i)&statrate[10]) continue; - - //Choose a target player - mindist = 0x7fffffff; target = connecthead; - for(p=connecthead;p>=0;p=connectpoint2[p]) - { - dist = klabs(sprite[i].x-posx[p])+klabs(sprite[i].y-posy[p]); - if (dist < mindist) mindist = dist, target = p; - } - - k = (krand()&255); - - if ((sprite[i].lotag&32) && (k < 48)) //Al decides to reproduce - { - l = 0; - if ((sprite[i].lotag&64) && (k < 2)) //Give him a chance to reproduce without seeing you - l = 1; - else if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[target],posy[target],posz[target],cursectnum[target]) == 1) - l = 1; - if (l != 0) - { - spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].cstat,sprite[i].shade,sprite[i].pal, - sprite[i].clipdist,38,38,sprite[i].xoffset,sprite[i].yoffset,sprite[i].picnum,krand()&2047,0,0,0,i, - sprite[i].sectnum,10,sprite[i].lotag,sprite[i].hitag,sprite[i].extra); - switch(krand()&31) //Mutations! - { - case 0: sprite[i].cstat ^= 2; break; - case 1: sprite[i].cstat ^= 512; break; - case 2: sprite[i].shade++; break; - case 3: sprite[i].shade--; break; - case 4: sprite[i].pal ^= 16; break; - case 5: case 6: case 7: sprite[i].lotag ^= (1<<(krand()&7)); break; - case 8: sprite[i].lotag = (krand()&255); break; - } - } - } - if (k >= 208+((sprite[i].lotag&128)>>2)) //Al decides to shoot bullet - { - if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[target],posy[target],posz[target],cursectnum[target]) == 1) - { - wsayfollow("zipguns.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1); - - spawnsprite(j,sprite[i].x,sprite[i].y, - sector[sprite[i].sectnum].floorz-(24<<8), - 0,0,0,16,32,32,0,0,BULLET, - (getangle(posx[target]-sprite[j].x, - posy[target]-sprite[j].y)+(krand()&15)-8)&2047, - sintable[(sprite[j].ang+512)&2047]>>6, - sintable[sprite[j].ang&2047]>>6, - ((posz[target]+(8<<8)-sprite[j].z)<<8) / - (ksqrt((posx[target]-sprite[j].x) * - (posx[target]-sprite[j].x) + - (posy[target]-sprite[j].y) * - (posy[target]-sprite[j].y))+1), - i,sprite[i].sectnum,6,0,0,0); - } - } - - //Move Al - l = (((sprite[i].lotag&3)+2)<<8); - if (sprite[i].lotag&4) l = -l; - dax = sintable[(sprite[i].ang+512)&2047]*l; - day = sintable[sprite[i].ang]*l; - - osectnum = sprite[i].sectnum; - movestat = movesprite((short)i,dax,day,0L,-8L<<8,-8L<<8,CLIPMASK0); - sprite[i].z = globloz; - if ((sprite[i].sectnum != osectnum) && (sector[sprite[i].sectnum].lotag == 10)) - { - warpsprite((short)i); - movestat = 0; - } - - if (sprite[i].lotag&16) - { - if (((k&124) >= 120) && (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[target],posy[target],posz[target],cursectnum[target]) == 1)) - sprite[i].ang = getangle(posx[target]-sprite[i].x,posy[target]-sprite[i].y); - else - sprite[i].ang = (krand()&2047); - } - - if (movestat != 0) - { - if ((k&2) && (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[target],posy[target],posz[target],cursectnum[target]) == 1)) - sprite[i].ang = getangle(posx[target]-sprite[i].x,posy[target]-sprite[i].y); - else - sprite[i].ang = (krand()&2047); - - if ((movestat&49152) == 49152) - if (sprite[movestat&16383].picnum == EVILAL) - if ((k&31) >= 30) - { - wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - sprite[i].picnum = EVILALGRAVE; - sprite[i].cstat = 0; - sprite[i].xvel = (krand()&255)-128; - sprite[i].yvel = (krand()&255)-128; - sprite[i].zvel = (krand()&4095)-3072; - changespritestat(i,9); - } - - if (sprite[i].lotag&8) - if ((k&31) >= 30) - { - wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - sprite[i].picnum = EVILALGRAVE; - sprite[i].cstat = 0; - sprite[i].xvel = (krand()&255)-128; - sprite[i].yvel = (krand()&255)-128; - sprite[i].zvel = (krand()&4095)-3072; - changespritestat(i,9); - } - - if (movestat == -1) - { - wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - sprite[i].picnum = EVILALGRAVE; - sprite[i].cstat = 0; - sprite[i].xvel = (krand()&255)-128; - sprite[i].yvel = (krand()&255)-128; - sprite[i].zvel = (krand()&4095)-3072; - changespritestat(i,9); - } - } - } - - //Go through travelling bullet sprites - for(i=headspritestat[6];i>=0;i=nexti) - { - nexti = nextspritestat[i]; - - if ((nummoves-i)&statrate[6]) continue; - - //If the sprite is a bullet then... - if ((sprite[i].picnum == BULLET) || (sprite[i].picnum == GRABBER) || (sprite[i].picnum == MISSILE) || (sprite[i].picnum == BOMB)) - { - dax = ((((long)sprite[i].xvel)*TICSPERFRAME)<<12); - day = ((((long)sprite[i].yvel)*TICSPERFRAME)<<12); - daz = ((((long)sprite[i].zvel)*TICSPERFRAME)>>2); - if (sprite[i].picnum == BOMB) daz = 0; - - osectnum = sprite[i].sectnum; - hitobject = movesprite((short)i,dax,day,daz,4L<<8,4L<<8,CLIPMASK1); - if ((sprite[i].sectnum != osectnum) && (sector[sprite[i].sectnum].lotag == 10)) - { - warpsprite((short)i); - hitobject = 0; - } - - if (sprite[i].picnum == GRABBER) { // Andy did this (& Ken) !Homing! - checkgrabbertouchsprite(i,sprite[i].sectnum); - l = 0x7fffffff; - for (j = connecthead; j >= 0; j = connectpoint2[j]) // Players - if (j != (sprite[i].owner & (MAXSPRITES - 1))) - if (cansee(sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].sectnum,posx[j],posy[j],posz[j],cursectnum[j])) { - k = ksqrt(sqr(posx[j] - sprite[i].x) + sqr(posy[j] - sprite[i].y) + (sqr(posz[j] - sprite[i].z) >> 8)); - if (k < l) { - l = k; - dax = (posx[j] - sprite[i].x); - day = (posy[j] - sprite[i].y); - daz = (posz[j] - sprite[i].z); - } - } - for(j = headspritestat[1]; j >= 0; j = nextj) { // Active monsters - nextj = nextspritestat[j]; - if (cansee(sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].sectnum,sprite[j].x,sprite[j].y,sprite[j].z,sprite[j].sectnum)) { - k = ksqrt(sqr(sprite[j].x - sprite[i].x) + sqr(sprite[j].y - sprite[i].y) + (sqr(sprite[j].z - sprite[i].z) >> 8)); - if (k < l) { - l = k; - dax = (sprite[j].x - sprite[i].x); - day = (sprite[j].y - sprite[i].y); - daz = (sprite[j].z - sprite[i].z); - } - } - } - for(j = headspritestat[2]; j >= 0; j = nextj) { // Inactive monsters - nextj = nextspritestat[j]; - if (cansee(sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].sectnum,sprite[j].x,sprite[j].y,sprite[j].z,sprite[j].sectnum)) { - k = ksqrt(sqr(sprite[j].x - sprite[i].x) + sqr(sprite[j].y - sprite[i].y) + (sqr(sprite[j].z - sprite[i].z) >> 8)); - if (k < l) { - l = k; - dax = (sprite[j].x - sprite[i].x); - day = (sprite[j].y - sprite[i].y); - daz = (sprite[j].z - sprite[i].z); - } - } - } - if (l != 0x7fffffff) { - sprite[i].xvel = (divscale7(dax,l) + sprite[i].xvel); // 1/5 of velocity is homing, 4/5 is momentum - sprite[i].yvel = (divscale7(day,l) + sprite[i].yvel); // 1/5 of velocity is homing, 4/5 is momentum - sprite[i].zvel = (divscale7(daz,l) + sprite[i].zvel); // 1/5 of velocity is homing, 4/5 is momentum - l = ksqrt((sprite[i].xvel * sprite[i].xvel) + (sprite[i].yvel * sprite[i].yvel) + ((sprite[i].zvel * sprite[i].zvel) >> 8)); - sprite[i].xvel = divscale9(sprite[i].xvel,l); - sprite[i].yvel = divscale9(sprite[i].yvel,l); - sprite[i].zvel = divscale9(sprite[i].zvel,l); - sprite[i].ang = getangle(sprite[i].xvel,sprite[i].yvel); - } - } - - if (sprite[i].picnum == BOMB) - { - j = sprite[i].sectnum; - if ((sector[j].floorstat&2) && (sprite[i].z > globloz-(8<<8))) - { - k = sector[j].wallptr; - daang = getangle(wall[wall[k].point2].x-wall[k].x,wall[wall[k].point2].y-wall[k].y); - sprite[i].xvel += mulscale22(sintable[(daang+1024)&2047],sector[j].floorheinum); - sprite[i].yvel += mulscale22(sintable[(daang+512)&2047],sector[j].floorheinum); - } - } - - if (sprite[i].picnum == BOMB) - { - sprite[i].z += sprite[i].zvel; - sprite[i].zvel += (TICSPERFRAME<<7); - if (sprite[i].z < globhiz+(tilesizy[BOMB]<<6)) - { - sprite[i].z = globhiz+(tilesizy[BOMB]<<6); - sprite[i].zvel = -(sprite[i].zvel>>1); - } - if (sprite[i].z > globloz-(tilesizy[BOMB]<<6)) - { - sprite[i].z = globloz-(tilesizy[BOMB]<<6); - sprite[i].zvel = -(sprite[i].zvel>>1); - } - dax = sprite[i].xvel; day = sprite[i].yvel; - dist = dax*dax+day*day; - if (dist < 512) - { - bombexplode(i); - goto bulletisdeletedskip; - } - if (dist < 4096) - { - sprite[i].xrepeat = ((4096+2048)*16) / (dist+2048); - sprite[i].yrepeat = sprite[i].xrepeat; - sprite[i].xoffset = (krand()&15)-8; - sprite[i].yoffset = (krand()&15)-8; - } - if (mulscale30(krand(),dist) == 0) - { - sprite[i].xvel -= ksgn(sprite[i].xvel); - sprite[i].yvel -= ksgn(sprite[i].yvel); - sprite[i].zvel -= ksgn(sprite[i].zvel); - } - } - - //Check for bouncy objects before killing bullet - if ((hitobject&0xc000) == 16384) //Bullet hit a ceiling/floor - { - k = sector[hitobject&(MAXSECTORS-1)].wallptr; l = wall[k].point2; - daang = getangle(wall[l].x-wall[k].x,wall[l].y-wall[k].y); - - getzsofslope(hitobject&(MAXSECTORS-1),sprite[i].x,sprite[i].y,&k,&l); - if (sprite[i].z < ((k+l)>>1)) k = sector[hitobject&(MAXSECTORS-1)].ceilingheinum; - else k = sector[hitobject&(MAXSECTORS-1)].floorheinum; - - dax = mulscale14(k,sintable[(daang)&2047]); - day = mulscale14(k,sintable[(daang+1536)&2047]); - daz = 4096; - - k = sprite[i].xvel*dax+sprite[i].yvel*day+mulscale4(sprite[i].zvel,daz); - l = dax*dax+day*day+daz*daz; - if ((klabs(k)>>14) < l) - { - k = divscale17(k,l); - sprite[i].xvel -= mulscale16(dax,k); - sprite[i].yvel -= mulscale16(day,k); - sprite[i].zvel -= mulscale12(daz,k); - } - wsayfollow("bouncy.wav",4096L+(krand()&127)-64,255,&sprite[i].x,&sprite[i].y,1); - hitobject = 0; - sprite[i].owner = -1; //Bullet turns evil! - } - else if ((hitobject&0xc000) == 32768) //Bullet hit a wall - { - if (wall[hitobject&4095].lotag == 8) - { - dax = sprite[i].xvel; day = sprite[i].yvel; - if ((sprite[i].picnum != BOMB) || (dax*dax+day*day >= 512)) - { - k = (hitobject&4095); l = wall[k].point2; - j = getangle(wall[l].x-wall[k].x,wall[l].y-wall[k].y)+512; - - //k = cos(ang) * sin(ang) * 2 - k = mulscale13(sintable[(j+512)&2047],sintable[j&2047]); - //l = cos(ang * 2) - l = sintable[((j<<1)+512)&2047]; - - ox = sprite[i].xvel; oy = sprite[i].yvel; - dax = -ox; day = -oy; - sprite[i].xvel = dmulscale14(day,k,dax,l); - sprite[i].yvel = dmulscale14(dax,k,-day,l); - - if (sprite[i].picnum == BOMB) - { - sprite[i].xvel -= (sprite[i].xvel>>3); - sprite[i].yvel -= (sprite[i].yvel>>3); - sprite[i].zvel -= (sprite[i].zvel>>3); - } - ox -= sprite[i].xvel; oy -= sprite[i].yvel; - dist = ((ox*ox+oy*oy)>>8); - wsayfollow("bouncy.wav",4096L+(krand()&127)-64,min(dist,256),&sprite[i].x,&sprite[i].y,1); - hitobject = 0; - sprite[i].owner = -1; //Bullet turns evil! - } - } - } - else if ((hitobject&0xc000) == 49152) //Bullet hit a sprite - { - if (sprite[hitobject&4095].picnum == BOUNCYMAT) - { - if ((sprite[hitobject&4095].cstat&48) == 0) - { - sprite[i].xvel = -sprite[i].xvel; - sprite[i].yvel = -sprite[i].yvel; - sprite[i].zvel = -sprite[i].zvel; - dist = 255; - } - else if ((sprite[hitobject&4095].cstat&48) == 16) - { - j = sprite[hitobject&4095].ang; - - //k = cos(ang) * sin(ang) * 2 - k = mulscale13(sintable[(j+512)&2047],sintable[j&2047]); - //l = cos(ang * 2) - l = sintable[((j<<1)+512)&2047]; - - ox = sprite[i].xvel; oy = sprite[i].yvel; - dax = -ox; day = -oy; - sprite[i].xvel = dmulscale14(day,k,dax,l); - sprite[i].yvel = dmulscale14(dax,k,-day,l); - - ox -= sprite[i].xvel; oy -= sprite[i].yvel; - dist = ((ox*ox+oy*oy)>>8); - } - sprite[i].owner = -1; //Bullet turns evil! - wsayfollow("bouncy.wav",4096L+(krand()&127)-64,min(dist,256),&sprite[i].x,&sprite[i].y,1); - hitobject = 0; - } - } - - if (hitobject != 0) - { - if ((sprite[i].picnum == MISSILE) || (sprite[i].picnum == BOMB)) - { - if ((hitobject&0xc000) == 49152) - if (sprite[hitobject&4095].lotag == 5) //Basketball hoop - { - wsayfollow("niceshot.wav",3840L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - deletesprite((short)i); - goto bulletisdeletedskip; - } - - bombexplode(i); - goto bulletisdeletedskip; - } - - if ((hitobject&0xc000) == 16384) //Hits a ceiling / floor - { - wsayfollow("bullseye.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - deletesprite((short)i); - goto bulletisdeletedskip; - } - else if ((hitobject&0xc000) == 32768) //Bullet hit a wall - { - if (wall[hitobject&4095].picnum == KENPICTURE) - { - if (waloff[MAXTILES-1] != 0) - wall[hitobject&4095].picnum = MAXTILES-1; - wsayfollow("hello.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); //Ken says, "Hello... how are you today!" - } - else - wsayfollow("bullseye.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - - deletesprite((short)i); - goto bulletisdeletedskip; - } - else if ((hitobject&0xc000) == 49152) //Bullet hit a sprite - { - if ((sprite[hitobject&4095].lotag == 5) && (sprite[i].picnum == GRABBER)) { // Basketball hoop (Andy's addition) - wsayfollow("niceshot.wav",3840L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - switch (krand() & 63) { - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: - sprite[i].picnum = COIN; break; - case 10: case 11: case 12: case 13: case 14: case 15: case 16: - sprite[i].picnum = DIAMONDS; break; - case 17: case 18: case 19: - sprite[i].picnum = COINSTACK; break; - case 20: case 21: case 22: case 23: - sprite[i].picnum = GIFTBOX; break; - case 24: case 25: - sprite[i].picnum = GRABCANNON; break; - case 26: case 27: - sprite[i].picnum = LAUNCHER; break; - case 28: case 29: case 30: - sprite[i].picnum = CANNON; break; - case 31: - sprite[i].picnum = AIRPLANE; break; - default: - deletesprite((short)i); - goto bulletisdeletedskip; - } - sprite[i].xvel = sprite[i].yvel = sprite[i].zvel = 0; - sprite[i].cstat &= ~0x83; //Should not clip, foot-z - changespritestat(i,12); - goto bulletisdeletedskip; - } - - //Check if bullet hit a player & find which player it was... - if (sprite[hitobject&4095].picnum == PLAYER) - for(j=connecthead;j>=0;j=connectpoint2[j]) - if (sprite[i].owner != j+4096) - if (playersprite[j] == (hitobject&4095)) - { - wsayfollow("ouch.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - if (sprite[i].picnum == GRABBER) { // Andy did this - k = ((sprite[i].xrepeat * sprite[i].yrepeat) * 3) >> 9; - changehealth((sprite[i].owner - 4096),k); - changehealth(j,-k); - } - else changehealth(j,-mulscale8(sprite[i].xrepeat,sprite[i].yrepeat)); - deletesprite((short)i); - goto bulletisdeletedskip; - } - - //Check if bullet hit any monsters... - j = (hitobject&4095); //j is the spritenum that the bullet (spritenum i) hit - if (sprite[i].owner != j) - { - switch(sprite[j].picnum) - { - case BROWNMONSTER: - if (sprite[j].lotag > 0) { - if (sprite[i].picnum == GRABBER) { // Andy did this - k = ((sprite[i].xrepeat * sprite[i].yrepeat) * 3) >> 9; - changehealth((sprite[i].owner - 4096),k); - sprite[j].lotag -= k; - } - sprite[j].lotag -= mulscale8(sprite[i].xrepeat,sprite[i].yrepeat); - } - if (sprite[j].lotag > 0) - { - if (sprite[j].lotag <= 25) sprite[j].cstat |= 2; - wsayfollow("hurt.wav",4096L+(krand()&511)-256,256L,&sprite[i].x,&sprite[i].y,1); - } - else - { - wsayfollow("mondie.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - sprite[j].z += ((tilesizy[sprite[j].picnum]*sprite[j].yrepeat)<<1); - sprite[j].picnum = GIFTBOX; - sprite[j].cstat &= ~0x83; //Should not clip, foot-z - - spawnsprite(k,sprite[j].x,sprite[j].y,sprite[j].z, - 0,-4,0,32,64,64,0,0,EXPLOSION,sprite[j].ang, - 0,0,0,j,sprite[j].sectnum,5,31,0,0); - //31=Time left for explosion to stay - - changespritestat(j,12); - } - deletesprite((short)i); - goto bulletisdeletedskip; - case EVILAL: - wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - sprite[j].picnum = EVILALGRAVE; - sprite[j].cstat = 0; - sprite[j].xvel = (krand()&255)-128; - sprite[j].yvel = (krand()&255)-128; - sprite[j].zvel = (krand()&4095)-3072; - changespritestat(j,9); - - deletesprite((short)i); - goto bulletisdeletedskip; - case AL: - wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - sprite[j].xrepeat += 2; - sprite[j].yrepeat += 2; - if (sprite[j].yrepeat >= 38) - { - sprite[j].picnum = EVILAL; - //sprite[j].cstat |= 2; //Make him transluscent - changespritestat(j,10); - } - deletesprite((short)i); - goto bulletisdeletedskip; - default: - wsayfollow("bullseye.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - deletesprite((short)i); - goto bulletisdeletedskip; - } - } - } - } - } -bulletisdeletedskip: continue; - } - - //Go through monster waiting for you list - for(i=headspritestat[2];i>=0;i=nexti) - { - nexti = nextspritestat[i]; - - if ((nummoves-i)&15) continue; - - //Use dot product to see if monster's angle is towards a player - for(p=connecthead;p>=0;p=connectpoint2[p]) - if (sintable[(sprite[i].ang+512)&2047]*(posx[p]-sprite[i].x) + sintable[sprite[i].ang&2047]*(posy[p]-sprite[i].y) >= 0) - if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[p],posy[p],posz[p],cursectnum[p]) == 1) - { - changespritestat(i,1); - //if (sprite[i].lotag == 100) - //{ - wsayfollow("iseeyou.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1); - // sprite[i].lotag = 99; - //} - } - } - - //Go through smoke sprites - for(i=headspritestat[3];i>=0;i=nexti) - { - nexti = nextspritestat[i]; - - sprite[i].z -= (TICSPERFRAME<<6); - sprite[i].lotag -= TICSPERFRAME; - if (sprite[i].lotag < 0) deletesprite(i); - } - - //Go through splash sprites - for(i=headspritestat[4];i>=0;i=nexti) - { - nexti = nextspritestat[i]; - - sprite[i].lotag -= TICSPERFRAME; - sprite[i].picnum = SPLASH + ((63-sprite[i].lotag)>>4); - if (sprite[i].lotag < 0) deletesprite(i); - } - - //Go through explosion sprites - for(i=headspritestat[5];i>=0;i=nexti) - { - nexti = nextspritestat[i]; - - sprite[i].lotag -= TICSPERFRAME; - if (sprite[i].lotag < 0) deletesprite(i); - } - - //Go through bomb spriral-explosion sprites - for(i=headspritestat[7];i>=0;i=nexti) - { - nexti = nextspritestat[i]; - - sprite[i].xrepeat = (sprite[i].lotag>>2); - sprite[i].yrepeat = (sprite[i].lotag>>2); - sprite[i].lotag -= (TICSPERFRAME<<2); - if (sprite[i].lotag < 0) { deletesprite(i); continue; } - - if ((nummoves-i)&statrate[7]) continue; - - sprite[i].x += ((sprite[i].xvel*TICSPERFRAME)>>2); - sprite[i].y += ((sprite[i].yvel*TICSPERFRAME)>>2); - sprite[i].z += ((sprite[i].zvel*TICSPERFRAME)>>2); - - sprite[i].zvel += (TICSPERFRAME<<9); - if (sprite[i].z < sector[sprite[i].sectnum].ceilingz+(4<<8)) - { - sprite[i].z = sector[sprite[i].sectnum].ceilingz+(4<<8); - sprite[i].zvel = -(sprite[i].zvel>>1); - } - if (sprite[i].z > sector[sprite[i].sectnum].floorz-(4<<8)) - { - sprite[i].z = sector[sprite[i].sectnum].floorz-(4<<8); - sprite[i].zvel = -(sprite[i].zvel>>1); - } - } - - //EVILALGRAVE shrinking list - for(i=headspritestat[9];i>=0;i=nexti) - { - nexti = nextspritestat[i]; - - sprite[i].xrepeat = (sprite[i].lotag>>2); - sprite[i].yrepeat = (sprite[i].lotag>>2); - sprite[i].lotag -= TICSPERFRAME; - if (sprite[i].lotag < 0) { deletesprite(i); continue; } - - if ((nummoves-i)&statrate[9]) continue; - - sprite[i].x += (sprite[i].xvel*TICSPERFRAME); - sprite[i].y += (sprite[i].yvel*TICSPERFRAME); - sprite[i].z += (sprite[i].zvel*TICSPERFRAME); - - sprite[i].zvel += (TICSPERFRAME<<8); - if (sprite[i].z < sector[sprite[i].sectnum].ceilingz) - { - sprite[i].z = sector[sprite[i].sectnum].ceilingz; - sprite[i].xvel -= (sprite[i].xvel>>2); - sprite[i].yvel -= (sprite[i].yvel>>2); - sprite[i].zvel = -(sprite[i].zvel>>1); - } - if (sprite[i].z > sector[sprite[i].sectnum].floorz) - { - sprite[i].z = sector[sprite[i].sectnum].floorz; - sprite[i].xvel -= (sprite[i].xvel>>2); - sprite[i].yvel -= (sprite[i].yvel>>2); - sprite[i].zvel = -(sprite[i].zvel>>1); - } - } - - //Re-spawning sprite list - for(i=headspritestat[11];i>=0;i=nexti) - { - nexti = nextspritestat[i]; - - sprite[i].extra -= TICSPERFRAME; - if (sprite[i].extra < 0) - { - wsayfollow("warp.wav",6144L+(krand()&127)-64,128L,&sprite[i].x,&sprite[i].y,0); - sprite[i].cstat &= ~0x8000; - sprite[i].extra = -1; - changespritestat((short)i,0); - } - } -} - -void activatehitag(short dahitag) -{ - long i, nexti; - - for(i=0;i=0;i=nexti) - { - nexti = nextspritestat[i]; - if (sprite[i].hitag == dahitag) operatesprite(i); - } -} - -void bombexplode(long i) -{ - long j, nextj, k, daang, dax, day, dist; - - spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z,0,-4,0, - 32,64,64,0,0,EXPLOSION,sprite[i].ang, - 0,0,0,sprite[i].owner,sprite[i].sectnum,5,31,0,0); - //31=Time left for explosion to stay - - for(k=0;k<12;k++) - { - spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z+(8<<8),2,-4,0, - 32,24,24,0,0,EXPLOSION,sprite[i].ang, - (krand()>>7)-256,(krand()>>7)-256,(krand()>>2)-8192, - sprite[i].owner,sprite[i].sectnum,7,96,0,0); - //96=Time left for smoke to be alive - } - - for(j=connecthead;j>=0;j=connectpoint2[j]) - { - dist = (posx[j]-sprite[i].x)*(posx[j]-sprite[i].x); - dist += (posy[j]-sprite[i].y)*(posy[j]-sprite[i].y); - dist += ((posz[j]-sprite[i].z)>>4)*((posz[j]-sprite[i].z)>>4); - if (dist < 4194304) - if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[j],posy[j],posz[j],cursectnum[j]) == 1) - { - k = ((32768/((dist>>16)+4))>>5); - if (j == myconnectindex) - { - daang = getangle(posx[j]-sprite[i].x,posy[j]-sprite[i].y); - dax = ((k*sintable[(daang+512)&2047])>>14); - day = ((k*sintable[daang&2047])>>14); - fvel += ((dax*sintable[(ang[j]+512)&2047]+day*sintable[ang[j]&2047])>>14); - svel += ((day*sintable[(ang[j]+512)&2047]-dax*sintable[ang[j]&2047])>>14); - } - changehealth(j,-k); //if changehealth returns 1, you're dead - } - } - - for(k=1;k<=2;k++) //Check for hurting monsters - { - for(j=headspritestat[k];j>=0;j=nextj) - { - nextj = nextspritestat[j]; - - dist = (sprite[j].x-sprite[i].x)*(sprite[j].x-sprite[i].x); - dist += (sprite[j].y-sprite[i].y)*(sprite[j].y-sprite[i].y); - dist += ((sprite[j].z-sprite[i].z)>>4)*((sprite[j].z-sprite[i].z)>>4); - if (dist >= 4194304) continue; - if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,sprite[j].x,sprite[j].y,sprite[j].z-(tilesizy[sprite[j].picnum]<<7),sprite[j].sectnum) == 0) - continue; - if (sprite[j].picnum == BROWNMONSTER) - { - sprite[j].z += ((tilesizy[sprite[j].picnum]*sprite[j].yrepeat)<<1); - sprite[j].picnum = GIFTBOX; - sprite[j].cstat &= ~0x83; //Should not clip, foot-z - changespritestat(j,12); - } - } - } - - for(j=headspritestat[10];j>=0;j=nextj) //Check for EVILAL's - { - nextj = nextspritestat[j]; - - dist = (sprite[j].x-sprite[i].x)*(sprite[j].x-sprite[i].x); - dist += (sprite[j].y-sprite[i].y)*(sprite[j].y-sprite[i].y); - dist += ((sprite[j].z-sprite[i].z)>>4)*((sprite[j].z-sprite[i].z)>>4); - if (dist >= 4194304) continue; - if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,sprite[j].x,sprite[j].y,sprite[j].z-(tilesizy[sprite[j].picnum]<<7),sprite[j].sectnum) == 0) - continue; - - sprite[j].picnum = EVILALGRAVE; - sprite[j].cstat = 0; - sprite[j].xvel = (krand()&255)-128; - sprite[j].yvel = (krand()&255)-128; - sprite[j].zvel = (krand()&4095)-3072; - changespritestat(j,9); - } - - wsayfollow("blowup.wav",3840L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); - deletesprite((short)i); -} - -void processinput(short snum) -{ - long oldposx, oldposy, nexti; - long i, j, k, doubvel, xvect, yvect, goalz; - long dax, day, dax2, day2, odax, oday, odax2, oday2; - short startwall, endwall; - char *ptr; - - //SHARED KEYS: - //Movement code - if ((ssync[snum].fvel|ssync[snum].svel) != 0) - { - doubvel = (TICSPERFRAME<<((ssync[snum].bits&256)>0)); - - xvect = 0, yvect = 0; - if (ssync[snum].fvel != 0) - { - xvect += ((((long)ssync[snum].fvel)*doubvel*(long)sintable[(ang[snum]+512)&2047])>>3); - yvect += ((((long)ssync[snum].fvel)*doubvel*(long)sintable[ang[snum]&2047])>>3); - } - if (ssync[snum].svel != 0) - { - xvect += ((((long)ssync[snum].svel)*doubvel*(long)sintable[ang[snum]&2047])>>3); - yvect += ((((long)ssync[snum].svel)*doubvel*(long)sintable[(ang[snum]+1536)&2047])>>3); - } - if (flytime[snum] > lockclock) { xvect += xvect; yvect += yvect; } // DOuble flying speed - clipmove(&posx[snum],&posy[snum],&posz[snum],&cursectnum[snum],xvect,yvect,128L,4<<8,4<<8,CLIPMASK0); - revolvedoorstat[snum] = 1; - } - else - { - revolvedoorstat[snum] = 0; - } - - sprite[playersprite[snum]].cstat &= ~1; - //Push player away from walls if clipmove doesn't work - if (pushmove(&posx[snum],&posy[snum],&posz[snum],&cursectnum[snum],128L,4<<8,4<<8,CLIPMASK0) < 0) - changehealth(snum,-1000); //If this screws up, then instant death!!! - - // Getzrange returns the highest and lowest z's for an entire box, - // NOT just a point. This prevents you from falling off cliffs - // when you step only slightly over the cliff. - getzrange(posx[snum],posy[snum],posz[snum],cursectnum[snum],&globhiz,&globhihit,&globloz,&globlohit,128L,CLIPMASK0); - sprite[playersprite[snum]].cstat |= 1; - - if (ssync[snum].avel != 0) //ang += avel * constant - { //ENGINE calculates avel for you - doubvel = TICSPERFRAME; - if ((ssync[snum].bits&256) > 0) //Lt. shift makes turn velocity 50% faster - doubvel += (TICSPERFRAME>>1); - ang[snum] += ((((long)ssync[snum].avel)*doubvel)>>4); - ang[snum] &= 2047; - } - - if (health[snum] < 0) - { - health[snum] -= TICSPERFRAME; - if (health[snum] <= -160) - { - hvel[snum] = 0; - if (snum == myconnectindex) - fvel = 0, svel = 0, avel = 0, keystatus[3] = 1; - - deaths[snum]++; - health[snum] = 100; - numbombs[snum] = 0; - numgrabbers[snum] = 0; - nummissiles[snum] = 0; - flytime[snum] = 0; - - findrandomspot(&posx[snum],&posy[snum],&cursectnum[snum]); - posz[snum] = getflorzofslope(cursectnum[snum],posx[snum],posy[snum])-(1<<8); - horiz[snum] = 100; - ang[snum] = (krand()&2047); - - sprite[playersprite[snum]].x = posx[snum]; - sprite[playersprite[snum]].y = posy[snum]; - sprite[playersprite[snum]].z = posz[snum]+EYEHEIGHT; - sprite[playersprite[snum]].picnum = PLAYER; - sprite[playersprite[snum]].ang = ang[snum]; - sprite[playersprite[snum]].xrepeat = 64; - sprite[playersprite[snum]].yrepeat = 64; - changespritesect(playersprite[snum],cursectnum[snum]); - - drawstatusbar(snum); // Andy did this - - i = playersprite[snum]; - wsayfollow("zipguns.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1); - for(k=0;k<16;k++) - { - spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z+(8<<8),2,-4,0, - 32,24,24,0,0,EXPLOSION,sprite[i].ang, - (krand()&511)-256,(krand()&511)-256,(krand()&16384)-8192, - sprite[i].owner,sprite[i].sectnum,7,96,0,0); - //96=Time left for smoke to be alive - } - } - else - { - sprite[playersprite[snum]].xrepeat = max(((128+health[snum])>>1),0); - sprite[playersprite[snum]].yrepeat = max(((128+health[snum])>>1),0); - - hvel[snum] += (TICSPERFRAME<<2); - horiz[snum] = max(horiz[snum]-4,0); - posz[snum] += hvel[snum]; - if (posz[snum] > globloz-(4<<8)) - { - posz[snum] = globloz-(4<<8); - horiz[snum] = min(horiz[snum]+5,200); - hvel[snum] = 0; - } - } - } - - if (((ssync[snum].bits&8) > 0) && (horiz[snum] > 100-(200>>1))) horiz[snum] -= 4; //- - if (((ssync[snum].bits&4) > 0) && (horiz[snum] < 100+(200>>1))) horiz[snum] += 4; //+ - - goalz = globloz-EYEHEIGHT; - if (sector[cursectnum[snum]].lotag == 4) //slime sector - if ((globlohit&0xc000) != 49152) //You're not on a sprite - { - goalz = globloz-(8<<8); - if (posz[snum] >= goalz-(2<<8)) - { - clipmove(&posx[snum],&posy[snum],&posz[snum],&cursectnum[snum],-TICSPERFRAME<<14,-TICSPERFRAME<<14,128L,4<<8,4<<8,CLIPMASK0); - - if (slimesoundcnt[snum] >= 0) - { - slimesoundcnt[snum] -= TICSPERFRAME; - while (slimesoundcnt[snum] < 0) - { - slimesoundcnt[snum] += 120; - wsayfollow("slime.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); - } - } - } - } - if (goalz < globhiz+(16<<8)) //ceiling&floor too close - goalz = ((globloz+globhiz)>>1); - //goalz += mousz; - if (health[snum] >= 0) - { - if ((ssync[snum].bits&1) > 0) //A (stand high) - { - if (flytime[snum] <= lockclock) - { - if (posz[snum] >= globloz-(32<<8)) - { - goalz -= (16<<8); - if (ssync[snum].bits&256) goalz -= (24<<8); - } - } - else - { - hvel[snum] -= 192; - if (ssync[snum].bits&256) hvel[snum] -= 192; - } - } - if ((ssync[snum].bits&2) > 0) //Z (stand low) - { - if (flytime[snum] <= lockclock) - { - goalz += (12<<8); - if (ssync[snum].bits&256) goalz += (12<<8); - } - else - { - hvel[snum] += 192; - if (ssync[snum].bits&256) hvel[snum] += 192; - } - } - } - - if (flytime[snum] <= lockclock) - { - if (posz[snum] < goalz) - hvel[snum] += (TICSPERFRAME<<4); - else - hvel[snum] = (((goalz-posz[snum])*TICSPERFRAME)>>5); - } - else - { - hvel[snum] -= (hvel[snum]>>2); - hvel[snum] -= ksgn(hvel[snum]); - } - - posz[snum] += hvel[snum]; - if (posz[snum] > globloz-(4<<8)) posz[snum] = globloz-(4<<8), hvel[snum] = 0; - if (posz[snum] < globhiz+(4<<8)) posz[snum] = globhiz+(4<<8), hvel[snum] = 0; - - if (dimensionmode[snum] != 3) - { - if (((ssync[snum].bits&32) > 0) && (zoom[snum] > 48)) zoom[snum] -= (zoom[snum]>>4); - if (((ssync[snum].bits&16) > 0) && (zoom[snum] < 4096)) zoom[snum] += (zoom[snum]>>4); - } - - //Update sprite representation of player - // -should be after movement, but before shooting code - setsprite(playersprite[snum],posx[snum],posy[snum],posz[snum]+EYEHEIGHT); - sprite[playersprite[snum]].ang = ang[snum]; - - if (health[snum] >= 0) - { - if ((cursectnum[snum] < 0) || (cursectnum[snum] >= numsectors)) - { //How did you get in the wrong sector? - wsayfollow("ouch.wav",4096L+(krand()&127)-64,64L,&posx[snum],&posy[snum],1); - changehealth(snum,-TICSPERFRAME); - } - else if (globhiz+(8<<8) > globloz) - { //Ceiling and floor are smooshing you! - wsayfollow("ouch.wav",4096L+(krand()&127)-64,64L,&posx[snum],&posy[snum],1); - changehealth(snum,-TICSPERFRAME); - } - } - - if ((waterfountainwall[snum] >= 0) && (health[snum] >= 0)) - if ((wall[neartagwall].lotag != 7) || ((ssync[snum].bits&1024) == 0)) - { - i = waterfountainwall[snum]; - if (wall[i].overpicnum == USEWATERFOUNTAIN) - wall[i].overpicnum = WATERFOUNTAIN; - else if (wall[i].picnum == USEWATERFOUNTAIN) - wall[i].picnum = WATERFOUNTAIN; - - waterfountainwall[snum] = -1; - } - - if ((ssync[snum].bits&1024) > 0) //Space bar - { - //Continuous triggers... - - neartag(posx[snum],posy[snum],posz[snum],cursectnum[snum],ang[snum],&neartagsector,&neartagwall,&neartagsprite,&neartaghitdist,1024L,3); - if (neartagsector == -1) - { - i = cursectnum[snum]; - if ((sector[i].lotag|sector[i].hitag) != 0) - neartagsector = i; - } - - if (wall[neartagwall].lotag == 7) //Water fountain - { - if (wall[neartagwall].overpicnum == WATERFOUNTAIN) - { - wsayfollow("water.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); - wall[neartagwall].overpicnum = USEWATERFOUNTAIN; - waterfountainwall[snum] = neartagwall; - } - else if (wall[neartagwall].picnum == WATERFOUNTAIN) - { - wsayfollow("water.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); - wall[neartagwall].picnum = USEWATERFOUNTAIN; - waterfountainwall[snum] = neartagwall; - } - - if (waterfountainwall[snum] >= 0) - { - waterfountaincnt[snum] -= TICSPERFRAME; - while (waterfountaincnt[snum] < 0) - { - waterfountaincnt[snum] += 120; - wsayfollow("water.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); - changehealth(snum,2); - } - } - } - - //1-time triggers... - if ((oflags[snum]&1024) == 0) - { - if (neartagsector >= 0) - if (sector[neartagsector].hitag == 0) - operatesector(neartagsector); - - if (neartagwall >= 0) - if (wall[neartagwall].lotag == 2) //Switch - { - activatehitag(wall[neartagwall].hitag); - - j = wall[neartagwall].overpicnum; - if (j == SWITCH1ON) //1-time switch - { - wall[neartagwall].overpicnum = GIFTBOX; - wall[neartagwall].lotag = 0; - wall[neartagwall].hitag = 0; - } - if (j == GIFTBOX) //1-time switch - { - wall[neartagwall].overpicnum = SWITCH1ON; - wall[neartagwall].lotag = 0; - wall[neartagwall].hitag = 0; - } - if (j == SWITCH2ON) wall[neartagwall].overpicnum = SWITCH2OFF; - if (j == SWITCH2OFF) wall[neartagwall].overpicnum = SWITCH2ON; - if (j == SWITCH3ON) wall[neartagwall].overpicnum = SWITCH3OFF; - if (j == SWITCH3OFF) wall[neartagwall].overpicnum = SWITCH3ON; - - i = wall[neartagwall].point2; - dax = ((wall[neartagwall].x+wall[i].x)>>1); - day = ((wall[neartagwall].y+wall[i].y)>>1); - wsayfollow("switch.wav",4096L+(krand()&255)-128,256L,&dax,&day,0); - } - - if (neartagsprite >= 0) - { - if (sprite[neartagsprite].lotag == 1) - { //if you're shoving innocent little AL around, he gets mad! - if (sprite[neartagsprite].picnum == AL) - { - sprite[neartagsprite].picnum = EVILAL; - sprite[neartagsprite].cstat |= 2; //Make him transluscent - sprite[neartagsprite].xrepeat = 38; - sprite[neartagsprite].yrepeat = 38; - changespritestat(neartagsprite,10); - } - } - if (sprite[neartagsprite].lotag == 4) - { - activatehitag(sprite[neartagsprite].hitag); - - j = sprite[neartagsprite].picnum; - if (j == SWITCH1ON) //1-time switch - { - sprite[neartagsprite].picnum = GIFTBOX; - sprite[neartagsprite].lotag = 0; - sprite[neartagsprite].hitag = 0; - } - if (j == GIFTBOX) //1-time switch - { - sprite[neartagsprite].picnum = SWITCH1ON; - sprite[neartagsprite].lotag = 0; - sprite[neartagsprite].hitag = 0; - } - if (j == SWITCH2ON) sprite[neartagsprite].picnum = SWITCH2OFF; - if (j == SWITCH2OFF) sprite[neartagsprite].picnum = SWITCH2ON; - if (j == SWITCH3ON) sprite[neartagsprite].picnum = SWITCH3OFF; - if (j == SWITCH3OFF) sprite[neartagsprite].picnum = SWITCH3ON; - - dax = sprite[neartagsprite].x; - day = sprite[neartagsprite].y; - wsayfollow("switch.wav",4096L+(krand()&255)-128,256L,&dax,&day,0); - } - } - } - } - - if ((ssync[snum].bits & 2048) > 0) { // Shoot a bullet - if ((numbombs[snum] == 0) && (((ssync[snum].bits >> 13) & 7) == 2) && (myconnectindex == snum)) - locselectedgun = 0; - if ((nummissiles[snum] == 0) && (((ssync[snum].bits >> 13) & 7) == 3) && (myconnectindex == snum)) - locselectedgun = 1; - if ((numgrabbers[snum] == 0) && (((ssync[snum].bits >> 13) & 7) == 4) && (myconnectindex == snum)) - locselectedgun = 1; - - if ((health[snum] >= 0) || ((krand() & 127) > -health[snum])) - switch((ssync[snum].bits >> 13) & 7) { - case 0: - if (lockclock > lastchaingun[snum]+8) { - lastchaingun[snum] = lockclock; - shootgun(snum,posx[snum],posy[snum],posz[snum],ang[snum],horiz[snum],cursectnum[snum],0); - } - break; - case 1: - if ((oflags[snum] & 2048) == 0) - shootgun(snum,posx[snum],posy[snum],posz[snum],ang[snum],horiz[snum],cursectnum[snum],1); - break; - case 2: - if ((oflags[snum] & 2048) == 0) - if (numbombs[snum] > 0) { - shootgun(snum,posx[snum],posy[snum],posz[snum],ang[snum],horiz[snum],cursectnum[snum],2); - changenumbombs(snum,-1); - } - break; - case 3: - if ((oflags[snum] & 2048) == 0) - if (nummissiles[snum] > 0) { - shootgun(snum,posx[snum],posy[snum],posz[snum],ang[snum],horiz[snum],cursectnum[snum],3); - changenummissiles(snum,-1); - } - break; - case 4: - if ((oflags[snum] & 2048) == 0) - if (numgrabbers[snum] > 0) { - shootgun(snum,posx[snum],posy[snum],posz[snum],ang[snum],horiz[snum],cursectnum[snum],4); - changenumgrabbers(snum,-1); - } - break; - } - } - - if ((ssync[snum].bits&4096) > (oflags[snum]&4096)) //Keypad enter - { - dimensionmode[snum]++; - if (dimensionmode[snum] > 3) dimensionmode[snum] = 1; - } - - oflags[snum] = ssync[snum].bits; -} - -void view(short snum, long *vx, long *vy, long *vz, short *vsectnum, short ang, long horiz) -{ - spritetype *sp; - long i, nx, ny, nz, hx, hy, hz, hitx, hity, hitz; - short bakcstat, hitsect, hitwall, hitsprite, daang; - - nx = (sintable[(ang+1536)&2047]>>4); - ny = (sintable[(ang+1024)&2047]>>4); - nz = (horiz-100)*128; - - sp = &sprite[snum]; - - bakcstat = sp->cstat; - sp->cstat &= (short)~0x101; - - updatesectorz(*vx,*vy,*vz,vsectnum); - hitscan(*vx,*vy,*vz,*vsectnum,nx,ny,nz,&hitsect,&hitwall,&hitsprite,&hitx,&hity,&hitz,CLIPMASK1); - hx = hitx-(*vx); hy = hity-(*vy); - if (klabs(nx)+klabs(ny) > klabs(hx)+klabs(hy)) - { - *vsectnum = hitsect; - if (hitwall >= 0) - { - daang = getangle(wall[wall[hitwall].point2].x-wall[hitwall].x, - wall[wall[hitwall].point2].y-wall[hitwall].y); - - i = nx*sintable[daang]+ny*sintable[(daang+1536)&2047]; - if (klabs(nx) > klabs(ny)) hx -= mulscale28(nx,i); - else hy -= mulscale28(ny,i); - } - else if (hitsprite < 0) - { - if (klabs(nx) > klabs(ny)) hx -= (nx>>5); - else hy -= (ny>>5); - } - if (klabs(nx) > klabs(ny)) i = divscale16(hx,nx); - else i = divscale16(hy,ny); - if (i < cameradist) cameradist = i; - } - *vx = (*vx)+mulscale16(nx,cameradist); - *vy = (*vy)+mulscale16(ny,cameradist); - *vz = (*vz)+mulscale16(nz,cameradist); - - updatesectorz(*vx,*vy,*vz,vsectnum); - - sp->cstat = bakcstat; -} - -#if 0 // JBF: now in the engine -void updatesectorz(long x, long y, long z, short *sectnum) -{ - walltype *wal; - long i, j, cz, fz; - - getzsofslope(*sectnum,x,y,&cz,&fz); - if ((z >= cz) && (z <= fz)) - if (inside(x,y,*sectnum) != 0) return; - - if ((*sectnum >= 0) && (*sectnum < numsectors)) - { - wal = &wall[sector[*sectnum].wallptr]; - j = sector[*sectnum].wallnum; - do - { - i = wal->nextsector; - if (i >= 0) - { - getzsofslope(i,x,y,&cz,&fz); - if ((z >= cz) && (z <= fz)) - if (inside(x,y,(short)i) == 1) - { *sectnum = i; return; } - } - wal++; j--; - } while (j != 0); - } - - for(i=numsectors-1;i>=0;i--) - { - getzsofslope(i,x,y,&cz,&fz); - if ((z >= cz) && (z <= fz)) - if (inside(x,y,(short)i) == 1) - { *sectnum = i; return; } - } - - *sectnum = -1; -} -#endif - -void drawscreen(short snum, long dasmoothratio) -{ - long i, j, k=0, l, charsperline, tempint; - long x1, y1, x2, y2, ox1, oy1, ox2, oy2, dist, maxdist; - long cposx, cposy, cposz, choriz, czoom, tposx, tposy; - long tiltlock, *intptr, ovisibility, oparallaxvisibility; - short cang, tang, csect; - char ch, *ptr, *ptr2, *ptr3, *ptr4; - spritetype *tspr; - - smoothratio = max(min(dasmoothratio,65536),0); - - dointerpolations(); - - if ((snum == myconnectindex) && ((networkmode == 1) || (myconnectindex != connecthead))) - { - cposx = omyx+mulscale16(myx-omyx,smoothratio); - cposy = omyy+mulscale16(myy-omyy,smoothratio); - cposz = omyz+mulscale16(myz-omyz,smoothratio); - choriz = omyhoriz+mulscale16(myhoriz-omyhoriz,smoothratio); - cang = omyang+mulscale16((long)(((myang+1024-omyang)&2047)-1024),smoothratio); - } - else - { - cposx = oposx[snum]+mulscale16(posx[snum]-oposx[snum],smoothratio); - cposy = oposy[snum]+mulscale16(posy[snum]-oposy[snum],smoothratio); - cposz = oposz[snum]+mulscale16(posz[snum]-oposz[snum],smoothratio); - choriz = ohoriz[snum]+mulscale16(horiz[snum]-ohoriz[snum],smoothratio); - cang = oang[snum]+mulscale16(((ang[snum]+1024-oang[snum])&2047)-1024,smoothratio); - } - czoom = ozoom[snum]+mulscale16(zoom[snum]-ozoom[snum],smoothratio); - - setears(cposx,cposy,(long)sintable[(cang+512)&2047]<<14,(long)sintable[cang&2047]<<14); - - if (dimensionmode[myconnectindex] == 3) - { - tempint = screensize; - - if (((loc.bits&32) > (screensizeflag&32)) && (screensize > 64)) - { - ox1 = ((xdim-screensize)>>1); - ox2 = ox1+screensize-1; - oy1 = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); - oy2 = oy1 + scale(screensize,ydim-32,xdim)-1; - screensize -= (screensize>>3); - - if (tempint > xdim) - { - screensize = xdim; - - flushperms(); - - rotatesprite((xdim-320)<<15,(ydim-32)<<16,65536L,0,STATUSBAR,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); - i = ((xdim-320)>>1); - while (i >= 8) i -= 8, rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL8,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); - if (i >= 4) i -= 4, rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL4,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); - i = ((xdim-320)>>1)+320; - while (i <= xdim-8) rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL8,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L), i += 8; - if (i <= xdim-4) rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL4,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L), i += 4; - - drawstatusbar(screenpeek); // Andy did this - } - - x1 = ((xdim-screensize)>>1); - x2 = x1+screensize-1; - y1 = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); - y2 = y1 + scale(screensize,ydim-32,xdim)-1; - setview(x1,y1,x2,y2); - - // (ox1,oy1)ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ - // ³ (x1,y1) ³ - // ³ ÚÄÄÄÄÄ¿ ³ - // ³ ³ ³ ³ - // ³ ÀÄÄÄÄÄÙ ³ - // ³ (x2,y2) ³ - // ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ(ox2,oy2) - - drawtilebackground(0L,0L,BACKGROUND,8,ox1,oy1,x1-1,oy2,0); - drawtilebackground(0L,0L,BACKGROUND,8,x2+1,oy1,ox2,oy2,0); - drawtilebackground(0L,0L,BACKGROUND,8,x1,oy1,x2,y1-1,0); - drawtilebackground(0L,0L,BACKGROUND,8,x1,y2+1,x2,oy2,0); - } - if (((loc.bits&16) > (screensizeflag&16)) && (screensize <= xdim)) - { - screensize += (screensize>>3); - if ((screensize > xdim) && (tempint == xdim)) - { - screensize = xdim+1; - x1 = 0; y1 = 0; - x2 = xdim-1; y2 = ydim-1; - } - else - { - if (screensize > xdim) screensize = xdim; - x1 = ((xdim-screensize)>>1); - x2 = x1+screensize-1; - y1 = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); - y2 = y1 + scale(screensize,ydim-32,xdim)-1; - } - setview(x1,y1,x2,y2); - } - screensizeflag = loc.bits; - } - - if (dimensionmode[snum] != 2) - { - if ((numplayers > 1) && (option[4] == 0)) - { - //Do not draw other views constantly if they're staying still - //It's a shame this trick will only work in screen-buffer mode - //At least screen-buffer mode covers all the HI hi-res modes - //if (vidoption == 2) - //{ - for(i=connecthead;i>=0;i=connectpoint2[i]) frame2draw[i] = 0; - frame2draw[snum] = 1; - - //2-1,3-1,4-2 - //5-2,6-2,7-2,8-3,9-3,10-3,11-3,12-4,13-4,14-4,15-4,16-5 - x1 = posx[snum]; y1 = posy[snum]; - for(j=(numplayers>>2)+1;j>0;j--) - { - maxdist = 0x80000000; - for(i=connecthead;i>=0;i=connectpoint2[i]) - if (frame2draw[i] == 0) - { - x2 = posx[i]-x1; y2 = posy[i]-y1; - dist = dmulscale12(x2,x2,y2,y2); - - if (dist < 64) dist = 16384; - else if (dist > 16384) dist = 64; - else dist = 1048576 / dist; - - dist *= frameskipcnt[i]; - - //Increase frame rate if screen is moving - if ((posx[i] != oposx[i]) || (posy[i] != oposy[i]) || - (posz[i] != oposz[i]) || (ang[i] != oang[i]) || - (horiz[i] != ohoriz[i])) dist += dist; - - if (dist > maxdist) maxdist = dist, k = i; - } - - for(i=connecthead;i>=0;i=connectpoint2[i]) - frameskipcnt[i] += (frameskipcnt[i]>>3)+1; - frameskipcnt[k] = 0; - - frame2draw[k] = 1; - } - //} - //else - //{ - // for(i=connecthead;i>=0;i=connectpoint2[i]) frame2draw[i] = 1; - //} - - for(i=connecthead,j=0;i>=0;i=connectpoint2[i],j++) - if (frame2draw[i] != 0) - { - if (numplayers <= 4) - { - switch(j) - { - case 0: setview(0,0,(xdim>>1)-1,(ydim>>1)-1); break; - case 1: setview((xdim>>1),0,xdim-1,(ydim>>1)-1); break; - case 2: setview(0,(ydim>>1),(xdim>>1)-1,ydim-1); break; - case 3: setview((xdim>>1),(ydim>>1),xdim-1,ydim-1); break; - } - } - else - { - switch(j) - { - case 0: setview(0,0,(xdim>>2)-1,(ydim>>2)-1); break; - case 1: setview(xdim>>2,0,(xdim>>1)-1,(ydim>>2)-1); break; - case 2: setview(xdim>>1,0,xdim-(xdim>>2)-1,(ydim>>2)-1); break; - case 3: setview(xdim-(xdim>>2),0,xdim-1,(ydim>>2)-1); break; - case 4: setview(0,ydim>>2,(xdim>>2)-1,(ydim>>1)-1); break; - case 5: setview(xdim>>2,ydim>>2,(xdim>>1)-1,(ydim>>1)-1); break; - case 6: setview(xdim>>1,ydim>>2,xdim-(xdim>>2)-1,(ydim>>1)-1); break; - case 7: setview(xdim-(xdim>>2),ydim>>2,xdim-1,(ydim>>1)-1); break; - case 8: setview(0,ydim>>1,(xdim>>2)-1,ydim-(ydim>>2)-1); break; - case 9: setview(xdim>>2,ydim>>1,(xdim>>1)-1,ydim-(ydim>>2)-1); break; - case 10: setview(xdim>>1,ydim>>1,xdim-(xdim>>2)-1,ydim-(ydim>>2)-1); break; - case 11: setview(xdim-(xdim>>2),ydim>>1,xdim-1,ydim-(ydim>>2)-1); break; - case 12: setview(0,ydim-(ydim>>2),(xdim>>2)-1,ydim-1); break; - case 13: setview(xdim>>2,ydim-(ydim>>2),(xdim>>1)-1,ydim-1); break; - case 14: setview(xdim>>1,ydim-(ydim>>2),xdim-(xdim>>2)-1,ydim-1); break; - case 15: setview(xdim-(xdim>>2),ydim-(ydim>>2),xdim-1,ydim-1); break; - } - } - - if (i == snum) - { - sprite[playersprite[snum]].cstat |= 0x8000; - drawrooms(cposx,cposy,cposz,cang,choriz,cursectnum[i]); - sprite[playersprite[snum]].cstat &= ~0x8000; - analyzesprites(cposx,cposy); - } - else - { - sprite[playersprite[i]].cstat |= 0x8000; - drawrooms(posx[i],posy[i],posz[i],ang[i],horiz[i],cursectnum[i]); - sprite[playersprite[i]].cstat &= ~0x8000; - analyzesprites(posx[i],posy[i]); - } - drawmasks(); - if ((numgrabbers[i] > 0) || (nummissiles[i] > 0) || (numbombs[i] > 0)) - rotatesprite(160<<16,184L<<16,65536,0,GUNONBOTTOM,sector[cursectnum[i]].floorshade,0,2,windowx1,windowy1,windowx2,windowy2); - - if (lockclock < 384) - { - if (lockclock < 128) - rotatesprite(320<<15,200<<15,lockclock<<9,lockclock<<4,DEMOSIGN,(128-lockclock)>>2,0,1+2,windowx1,windowy1,windowx2,windowy2); - else if (lockclock < 256) - rotatesprite(320<<15,200<<15,65536,0,DEMOSIGN,0,0,2,windowx1,windowy1,windowx2,windowy2); - else - rotatesprite(320<<15,200<<15,(384-lockclock)<<9,lockclock<<4,DEMOSIGN,(lockclock-256)>>2,0,1+2,windowx1,windowy1,windowx2,windowy2); - } - - if (health[i] <= 0) - rotatesprite(320<<15,200<<15,(-health[i])<<11,(-health[i])<<5,NO,0,0,2,windowx1,windowy1,windowx2,windowy2); - } - } - else - { - //Init for screen rotation - if (getrendermode() == 0) { // JBF 20031220 - tiltlock = screentilt; - if ((tiltlock) || (detailmode)) - { - walock[MAXTILES-2] = 255; - if (waloff[MAXTILES-2] == 0) - allocache(&waloff[MAXTILES-2],320L*320L,&walock[MAXTILES-2]); - if ((tiltlock&1023) == 0) - setviewtotile(MAXTILES-2,200L>>detailmode,320L>>detailmode); - else - setviewtotile(MAXTILES-2,320L>>detailmode,320L>>detailmode); - if ((tiltlock&1023) == 512) - { //Block off unscreen section of 90ø tilted screen - j = ((320-60)>>detailmode); - for(i=(60>>detailmode)-1;i>=0;i--) - { - startumost[i] = 1; startumost[i+j] = 1; - startdmost[i] = 0; startdmost[i+j] = 0; - } - } - - i = (tiltlock&511); if (i > 256) i = 512-i; - i = sintable[i+512]*8 + sintable[i]*5L; - setaspect(i>>1,yxaspect); - } - } else { - tiltlock = screentilt; - // Ken loves to interpolate - setrollangle(oscreentilt + mulscale16(((screentilt-oscreentilt+1024)&2047)-1024,smoothratio)); - } - - if ((gotpic[FLOORMIRROR>>3]&(1<<(FLOORMIRROR&7))) > 0) - { - dist = 0x7fffffff; i = 0; - for(k=floormirrorcnt-1;k>=0;k--) - { - j = klabs(wall[sector[floormirrorsector[k]].wallptr].x-cposx); - j += klabs(wall[sector[floormirrorsector[k]].wallptr].y-cposy); - if (j < dist) dist = j, i = k; - } - - //if (cposz > sector[floormirrorsector[i]].ceilingz) i = 1-i; //SOS - - j = floormirrorsector[i]; - - if (cameradist < 0) sprite[playersprite[snum]].cstat |= 0x8000; - drawrooms(cposx,cposy,(sector[j].floorz<<1)-cposz,cang,201-choriz,j); //SOS - //drawrooms(cposx,cposy,cposz,cang,choriz,j+MAXSECTORS); //SOS - sprite[playersprite[snum]].cstat &= ~0x8000; - analyzesprites(cposx,cposy); - drawmasks(); - - //Temp horizon - if (getrendermode() == 0) { - l = scale(choriz-100,windowx2-windowx1,320)+((windowy1+windowy2)>>1); - begindrawing(); //{{{ - for(y1=windowy1,y2=windowy2;y1>2,31)<<8); - ptr4 = palookup[18]; - ptr4 += (min(klabs(y2-l)>>2,31)<<8); - - j = sintable[((y2+totalclock)<<6)&2047]; - j += sintable[((y2-totalclock)<<7)&2047]; - j >>= 14; - - //ptr2 += j; - - //for(x1=windowx1;x1<=windowx2;x1++) - // { ch = ptr[x1]; ptr[x1] = ptr3[ptr2[x1]]; ptr2[x1] = ptr4[ch]; } - - ox1 = windowx1-min(j,0); - ox2 = windowx2-max(j,0); - - for(x1=windowx1;x1>3] &= ~(1<<(FLOORMIRROR&7)); - } - - if (gotpic[DAYSKY>>3]&(1<<(DAYSKY&7))) - { - gotpic[DAYSKY>>3] &= ~(1<<(DAYSKY&7)); - pskyoff[0] = 0; pskyoff[1] = 0; pskybits = 1; - } - else if (gotpic[NIGHTSKY>>3]&(1<<(NIGHTSKY&7))) - { - gotpic[NIGHTSKY>>3] &= ~(1<<(NIGHTSKY&7)); - pskyoff[0] = 0; pskyoff[1] = 0; pskyoff[2] = 0; pskyoff[3] = 0; - pskyoff[4] = 0; pskyoff[5] = 0; pskyoff[6] = 0; pskyoff[7] = 0; - pskybits = 3; - } - - - //Over the shoulder mode - csect = cursectnum[snum]; - if (cameradist >= 0) - { - cang += cameraang; - view(playersprite[snum],&cposx,&cposy,&cposz,&csect,cang,choriz); - } - - //WARNING! Assuming (MIRRORLABEL&31) = 0 and MAXMIRRORS = 64 - intptr = (long *)&gotpic[MIRRORLABEL>>3]; // CHECK! - if (intptr[0]|intptr[1]) - for(i=MAXMIRRORS-1;i>=0;i--) - if (gotpic[(i+MIRRORLABEL)>>3]&(1<<(i&7))) - { - gotpic[(i+MIRRORLABEL)>>3] &= ~(1<<(i&7)); - - //Prepare drawrooms for drawing mirror and calculate reflected - //position into tposx, tposy, and tang (tposz == cposz) - //Must call preparemirror before drawrooms and - // completemirror after drawrooms - preparemirror(cposx,cposy,cposz,cang,choriz, - mirrorwall[i],mirrorsector[i],&tposx,&tposy,&tang); - - ovisibility = visibility; - oparallaxvisibility = parallaxvisibility; - visibility <<= 1; - parallaxvisibility <<= 1; - ptr = palookup[0]; palookup[0] = palookup[17]; palookup[17] = ptr; - - drawrooms(tposx,tposy,cposz,tang,choriz,mirrorsector[i]|MAXSECTORS); - for(j=0,tspr=&tsprite[0];jcstat&48) == 0) tspr->cstat |= 4; - analyzesprites(tposx,tposy); - drawmasks(); - - ptr = palookup[0]; palookup[0] = palookup[17]; palookup[17] = ptr; - visibility = ovisibility; - parallaxvisibility = oparallaxvisibility; - - completemirror(); //Reverse screen x-wise in this function - - break; - } - - if (cameradist < 0) sprite[playersprite[snum]].cstat |= 0x8000; - drawrooms(cposx,cposy,cposz,cang,choriz,csect); - sprite[playersprite[snum]].cstat &= ~0x8000; - analyzesprites(cposx,cposy); - drawmasks(); - - //Finish for screen rotation - if (getrendermode() == 0) { // JBF 20031220 - if ((tiltlock) || (detailmode)) - { - setviewback(); - i = (tiltlock&511); if (i > 256) i = 512-i; - i = sintable[i+512]*8 + sintable[i]*5L; - if (detailmode == 0) i >>= 1; - rotatesprite(320<<15,200<<15,i,tiltlock+512,MAXTILES-2,0,0,2+4+64,windowx1,windowy1,windowx2,windowy2); - walock[MAXTILES-2] = 1; - } - } - - if (((numgrabbers[screenpeek] > 0) || (nummissiles[screenpeek] > 0) || (numbombs[screenpeek] > 0)) && (cameradist < 0)) - { - //Reset startdmost to bottom of screen - if ((windowx1 == 0) && (windowx2 == 319) && (yxaspect == 65536) && (tiltlock == 0)) - { - x1 = 160L-(tilesizx[GUNONBOTTOM]>>1); y1 = windowy2+1; - for(i=0;i>2,0,1+2,windowx1,windowy1,windowx2,windowy2); - else if (lockclock < 256) - rotatesprite(320<<15,200<<15,65536,0,DEMOSIGN,0,0,2,windowx1,windowy1,windowx2,windowy2); - else - rotatesprite(320<<15,200<<15,(384-lockclock)<<9,lockclock<<4,DEMOSIGN,(lockclock-256)>>2,0,1+2,windowx1,windowy1,windowx2,windowy2); - } - - if (health[screenpeek] <= 0) - rotatesprite(320<<15,200<<15,(-health[screenpeek])<<11,(-health[screenpeek])<<5,NO,0,0,2,windowx1,windowy1,windowx2,windowy2); - } - } - - //Only animate lava if its picnum is on screen - //gotpic is a bit array where the tile number's bit is set - //whenever it is drawn (ceilings, walls, sprites, etc.) - if ((gotpic[SLIME>>3]&(1<<(SLIME&7))) > 0) - { - gotpic[SLIME>>3] &= ~(1<<(SLIME&7)); - if (waloff[SLIME] != 0) { - movelava((char *)waloff[SLIME]); - invalidatetile(SLIME,0,1); // JBF 20031228 - } - } - - if ((show2dsector[cursectnum[snum]>>3]&(1<<(cursectnum[snum]&7))) == 0) - searchmap(cursectnum[snum]); - - if (dimensionmode[snum] != 3) - { - //Move back pivot point - i = scale(czoom,screensize,320); - if (dimensionmode[snum] == 2) - { - clearview(0L); //Clear screen to specified color - drawmapview(cposx,cposy,i,cang); - } - drawoverheadmap(cposx,cposy,i,cang); - } - - if (typemode != 0) - { - charsperline = 40; - //if (dimensionmode[snum] == 2) charsperline = 80; - - for(i=0;i<=typemessageleng;i+=charsperline) - { - for(j=0;j 0) - { - charsperline = 40; - //if (dimensionmode[snum] == 2) charsperline = 80; - - for(i=0;i<=getmessageleng;i+=charsperline) - { - for(j=0;j getmessagetimeoff) - getmessageleng = 0; - } - if ((numplayers >= 2) && (screenpeek != myconnectindex)) - { - j = 1; - for(i=connecthead;i>=0;i=connectpoint2[i]) - { - if (i == screenpeek) break; - j++; - } - Bsprintf(tempbuf,"(Player %ld's view)",j); - printext256((xdim>>1)-(Bstrlen(tempbuf)<<2),0,24,-1,tempbuf,0); - } - - if (syncstat != 0) printext256(68L,84L,31,0,"OUT OF SYNC!",0); - if (syncstate != 0) printext256(68L,92L,31,0,"Missed Network packet!",0); - -// //Uncomment this to test cache locks -//extern long cacnum; -//typedef struct { long *hand, leng; char *lock; } cactype; -//extern cactype cac[]; -// -// j = 0; -// for(i=0;i= 200) -// { -// Bsprintf(tempbuf,"Locked- %ld: Leng:%ld, Lock:%ld",i,cac[i].leng,*cac[i].lock); -// printext256(0L,j,31,-1,tempbuf,1); j += 6; -// } - - nextpage(); // send completed frame to display - - while (totalclock >= ototalclock+(TIMERINTSPERSECOND/MOVESPERSECOND)) - faketimerhandler(); - - if (keystatus[0x3f]) //F5 - { - keystatus[0x3f] = 0; - detailmode ^= 1; - //setrendermode(3); - } - if (keystatus[0x58]) //F12 - { - keystatus[0x58] = 0; - screencapture("captxxxx.tga",keystatus[0x2a]|keystatus[0x36]); - } - if (keystatus[0x3e]) //F4 - screen re-size - { - keystatus[0x3e] = 0; - - if (keystatus[0x2a]|keystatus[0x36]) { - setgamemode(!fullscreen, xdim, ydim, bpp); - } else { - - //cycle through all modes - j=-1; - - // work out a mask to select the mode - for (i=0; i 8) brightness = 0; - setbrightness(brightness,(char *)&palette[0],0); - } - - if (option[4] == 0) //Single player only keys - { - if (keystatus[0xd2]) //Insert - Insert player - { - keystatus[0xd2] = 0; - if (numplayers < MAXPLAYERS) - { - connectpoint2[numplayers-1] = numplayers; - connectpoint2[numplayers] = -1; - - movefifoend[numplayers] = movefifoend[0]; //HACK 01/05/2000 - - initplayersprite(numplayers); - - clearallviews(0L); //Clear screen to specified color - - numplayers++; - } - } - if (keystatus[0xd3]) //Delete - Delete player - { - keystatus[0xd3] = 0; - if (numplayers > 1) - { - numplayers--; - connectpoint2[numplayers-1] = -1; - - deletesprite(playersprite[numplayers]); - playersprite[numplayers] = -1; - - if (myconnectindex >= numplayers) myconnectindex = 0; - if (screenpeek >= numplayers) screenpeek = 0; - - if (numplayers < 2) - setup3dscreen(); - else - clearallviews(0L); //Clear screen to specified color - } - } - if (keystatus[0x46]) //Scroll Lock - { - keystatus[0x46] = 0; - - myconnectindex = connectpoint2[myconnectindex]; - if (myconnectindex < 0) myconnectindex = connecthead; - screenpeek = myconnectindex; - } - } - - restoreinterpolations(); -} - -void movethings(void) -{ - long i; - - gotlastpacketclock = totalclock; - for(i=connecthead;i>=0;i=connectpoint2[i]) - { - copybufbyte(&ffsync[i],&baksync[movefifoend[i]][i],sizeof(input)); - movefifoend[i] = ((movefifoend[i]+1)&(MOVEFIFOSIZ-1)); - } -} - -void fakedomovethings(void) -{ - input *syn; - long i, j, k, doubvel, xvect, yvect, goalz; - short bakcstat; - - syn = (input *)&baksync[fakemovefifoplc][myconnectindex]; - - omyx = myx; - omyy = myy; - omyz = myz; - omyang = myang; - omyhoriz = myhoriz; - - bakcstat = sprite[playersprite[myconnectindex]].cstat; - sprite[playersprite[myconnectindex]].cstat &= ~0x101; - - if ((syn->fvel|syn->svel) != 0) - { - doubvel = (TICSPERFRAME<<((syn->bits&256)>0)); - - xvect = 0, yvect = 0; - if (syn->fvel != 0) - { - xvect += ((((long)syn->fvel)*doubvel*(long)sintable[(myang+512)&2047])>>3); - yvect += ((((long)syn->fvel)*doubvel*(long)sintable[myang&2047])>>3); - } - if (syn->svel != 0) - { - xvect += ((((long)syn->svel)*doubvel*(long)sintable[myang&2047])>>3); - yvect += ((((long)syn->svel)*doubvel*(long)sintable[(myang+1536)&2047])>>3); - } - if (flytime[myconnectindex] > lockclock) { xvect += xvect; yvect += yvect; } // DOuble flying speed - clipmove(&myx,&myy,&myz,&mycursectnum,xvect,yvect,128L,4<<8,4<<8,CLIPMASK0); - } - - pushmove(&myx,&myy,&myz,&mycursectnum,128L,4<<8,4<<8,CLIPMASK0); - getzrange(myx,myy,myz,mycursectnum,&globhiz,&globhihit,&globloz,&globlohit,128L,CLIPMASK0); - - if (syn->avel != 0) //ang += avel * constant - { //ENGINE calculates avel for you - doubvel = TICSPERFRAME; - if ((syn->bits&256) > 0) //Lt. shift makes turn velocity 50% faster - doubvel += (TICSPERFRAME>>1); - myang += ((((long)syn->avel)*doubvel)>>4); - myang &= 2047; - } - - if (((syn->bits&8) > 0) && (myhoriz > 100-(200>>1))) myhoriz -= 4; //- - if (((syn->bits&4) > 0) && (myhoriz < 100+(200>>1))) myhoriz += 4; //+ - - goalz = globloz-EYEHEIGHT; - if (sector[mycursectnum].lotag == 4) //slime sector - if ((globlohit&0xc000) != 49152) //You're not on a sprite - { - goalz = globloz-(8<<8); - if (myz >= goalz-(2<<8)) - clipmove(&myx,&myy,&myz,&mycursectnum,-TICSPERFRAME<<14,-TICSPERFRAME<<14,128L,4<<8,4<<8,CLIPMASK0); - } - if (goalz < globhiz+(16<<8)) //ceiling&floor too close - goalz = ((globloz+globhiz)>>1); - - if (health[myconnectindex] >= 0) - { - if ((syn->bits&1) > 0) //A (stand high) - { - if (flytime[myconnectindex] <= lockclock) - { - if (myz >= globloz-(32<<8)) - { - goalz -= (16<<8); - if (syn->bits&256) goalz -= (24<<8); - } - } - else - { - myzvel -= 192; - if (syn->bits&256) myzvel -= 192; - } - } - if ((syn->bits&2) > 0) //Z (stand low) - { - if (flytime[myconnectindex] <= lockclock) - { - goalz += (12<<8); - if (syn->bits&256) goalz += (12<<8); - } - else - { - myzvel += 192; - if (syn->bits&256) myzvel += 192; - } - } - } - - if (flytime[myconnectindex] <= lockclock) - { - if (myz < goalz) - myzvel += (TICSPERFRAME<<4); - else - myzvel = (((goalz-myz)*TICSPERFRAME)>>5); - } - else - { - myzvel -= (myzvel>>2); - myzvel -= ksgn(myzvel); - } - - myz += myzvel; - if (myz > globloz-(4<<8)) myz = globloz-(4<<8), myzvel = 0; - if (myz < globhiz+(4<<8)) myz = globhiz+(4<<8), myzvel = 0; - - sprite[playersprite[myconnectindex]].cstat = bakcstat; - - myxbak[fakemovefifoplc] = myx; - myybak[fakemovefifoplc] = myy; - myzbak[fakemovefifoplc] = myz; - myangbak[fakemovefifoplc] = myang; - myhorizbak[fakemovefifoplc] = myhoriz; - fakemovefifoplc = (fakemovefifoplc+1)&(MOVEFIFOSIZ-1); -} - - //Prediction correction -void fakedomovethingscorrect(void) -{ - long i; - - if ((networkmode == 0) && (myconnectindex == connecthead)) return; - - i = ((movefifoplc-1)&(MOVEFIFOSIZ-1)); - - if ((posx[myconnectindex] == myxbak[i]) && - (posy[myconnectindex] == myybak[i]) && - (posz[myconnectindex] == myzbak[i]) && - (horiz[myconnectindex] == myhorizbak[i]) && - (ang[myconnectindex] == myangbak[i])) - return; - - //Re-start fakedomovethings back to place of error - myx = omyx = posx[myconnectindex]; - myy = omyy = posy[myconnectindex]; - myz = omyz = posz[myconnectindex]; myzvel = hvel[myconnectindex]; - myang = omyang = ang[myconnectindex]; - mycursectnum = mycursectnum; - myhoriz = omyhoriz = horiz[myconnectindex]; - - fakemovefifoplc = movefifoplc; - while (fakemovefifoplc != movefifoend[myconnectindex]) fakedomovethings(); -} - -void domovethings(void) -{ - short i, j, startwall, endwall; - spritetype *spr; - walltype *wal; - point3d *ospr; - - nummoves++; - - for(i=connecthead;i>=0;i=connectpoint2[i]) - copybufbyte(&baksync[movefifoplc][i],&ssync[i],sizeof(input)); - movefifoplc = ((movefifoplc+1)&(MOVEFIFOSIZ-1)); - - if (option[4] != 0) - { - syncval[syncvalhead] = (char)(randomseed&255); - syncvalhead = ((syncvalhead+1)&(MOVEFIFOSIZ-1)); - } - - for(i=connecthead;i>=0;i=connectpoint2[i]) - { - oposx[i] = posx[i]; - oposy[i] = posy[i]; - oposz[i] = posz[i]; - ohoriz[i] = horiz[i]; - ozoom[i] = zoom[i]; - oang[i] = ang[i]; - } - - for(i=NUMSTATS-1;i>=0;i--) - if (statrate[i] >= 0) - for(j=headspritestat[i];j>=0;j=nextspritestat[j]) - if (((nummoves-j)&statrate[i]) == 0) - copybuf(&sprite[j].x,&osprite[j].x,3); - - for(i=connecthead;i>=0;i=connectpoint2[i]) - ocursectnum[i] = cursectnum[i]; - - updateinterpolations(); - - if ((numplayers <= 2) && (recstat == 1)) - { - j = 0; - for(i=connecthead;i>=0;i=connectpoint2[i]) - { - copybufbyte(&ssync[i],&recsync[reccnt][j],sizeof(input)); - j++; - } - reccnt++; if (reccnt > 16383) reccnt = 16383; - } - - lockclock += TICSPERFRAME; - drawstatusflytime(screenpeek); // Andy did this - - if (cameradist >= 0) - { - cameradist = min(cameradist+((totalclock-cameraclock)<<10),65536); - if (keystatus[0x52]) //0 - cameraang -= ((totalclock-cameraclock)<<(2+(keystatus[0x2a]|keystatus[0x36]))); - if (keystatus[0x53]) //. - cameraang += ((totalclock-cameraclock)<<(2+(keystatus[0x2a]|keystatus[0x36]))); - cameraclock = totalclock; - } - - for(i=connecthead;i>=0;i=connectpoint2[i]) - { - processinput(i); //Move player - - checktouchsprite(i,cursectnum[i]); //Pick up coins - startwall = sector[cursectnum[i]].wallptr; - endwall = startwall + sector[cursectnum[i]].wallnum; - for(j=startwall,wal=&wall[j];jnextsector >= 0) checktouchsprite(i,wal->nextsector); - } - - doanimations(); - tagcode(); //Door code, moving sector code, other stuff - statuslistcode(); //Monster / bullet code / explosions - - fakedomovethingscorrect(); - - checkmasterslaveswitch(); -} - -void getinput(void) -{ - char ch, keystate, *ptr; - long i, j, k; - long mousx, mousy, bstatus; - - if (typemode == 0) //if normal game keys active - { - if (keystatus[keys[15]]) - { - keystatus[keys[15]] = 0; - - screenpeek = connectpoint2[screenpeek]; - if (screenpeek < 0) screenpeek = connecthead; - drawstatusbar(screenpeek); // Andy did this - } - - for(i=7;i>=0;i--) - if (keystatus[i+2]) - { keystatus[i+2] = 0; locselectedgun = i; break; } - } - - - //KEYTIMERSTUFF - if (!keystatus[keys[5]]) - { - if (keystatus[keys[2]]) avel = max(avel-16*TICSPERFRAME,-128); - if (keystatus[keys[3]]) avel = min(avel+16*TICSPERFRAME,127); - } - else - { - if (keystatus[keys[2]]) svel = min(svel+8*TICSPERFRAME,127); - if (keystatus[keys[3]]) svel = max(svel-8*TICSPERFRAME,-128); - } - if (keystatus[keys[0]]) fvel = min(fvel+8*TICSPERFRAME,127); - if (keystatus[keys[1]]) fvel = max(fvel-8*TICSPERFRAME,-128); - if (keystatus[keys[12]]) svel = min(svel+8*TICSPERFRAME,127); - if (keystatus[keys[13]]) svel = max(svel-8*TICSPERFRAME,-128); - - if (avel < 0) avel = min(avel+12*TICSPERFRAME,0); - if (avel > 0) avel = max(avel-12*TICSPERFRAME,0); - if (svel < 0) svel = min(svel+2*TICSPERFRAME,0); - if (svel > 0) svel = max(svel-2*TICSPERFRAME,0); - if (fvel < 0) fvel = min(fvel+2*TICSPERFRAME,0); - if (fvel > 0) fvel = max(fvel-2*TICSPERFRAME,0); - - if ((option[4] == 0) && (numplayers >= 2)) - { - if (!keystatus[0x4f]) - { - if (keystatus[0x4b]) avel2 = max(avel2-16*TICSPERFRAME,-128); - if (keystatus[0x4d]) avel2 = min(avel2+16*TICSPERFRAME,127); - } - else - { - if (keystatus[0x4b]) svel2 = min(svel2+8*TICSPERFRAME,127); - if (keystatus[0x4d]) svel2 = max(svel2-8*TICSPERFRAME,-128); - } - if (keystatus[0x48]) fvel2 = min(fvel2+8*TICSPERFRAME,127); - if (keystatus[0x4c]) fvel2 = max(fvel2-8*TICSPERFRAME,-128); - - if (avel2 < 0) avel2 = min(avel2+12*TICSPERFRAME,0); - if (avel2 > 0) avel2 = max(avel2-12*TICSPERFRAME,0); - if (svel2 < 0) svel2 = min(svel2+2*TICSPERFRAME,0); - if (svel2 > 0) svel2 = max(svel2-2*TICSPERFRAME,0); - if (fvel2 < 0) fvel2 = min(fvel2+2*TICSPERFRAME,0); - if (fvel2 > 0) fvel2 = max(fvel2-2*TICSPERFRAME,0); - } - - oscreentilt = screentilt; - if (keystatus[0x1a]) screentilt += ((4*TICSPERFRAME)<<(keystatus[0x2a]|keystatus[0x36])); - if (keystatus[0x1b]) screentilt -= ((4*TICSPERFRAME)<<(keystatus[0x2a]|keystatus[0x36])); - - i = (TICSPERFRAME<<1); - while ((screentilt != 0) && (i > 0)) - { screentilt = ((screentilt+ksgn(screentilt-1024))&2047); i--; } - if (keystatus[0x28]) screentilt = 1536; - - - loc.fvel = min(max(fvel,-128+8),127-8); - loc.svel = min(max(svel,-128+8),127-8); - loc.avel = min(max(avel,-128+16),127-16); - - getmousevalues(&mousx,&mousy,&bstatus); - loc.avel = min(max(loc.avel+(mousx<<3),-128),127); - loc.fvel = min(max(loc.fvel-(mousy<<3),-128),127); - - loc.bits = (locselectedgun<<13); - if (typemode == 0) //if normal game keys active - { - loc.bits |= (keystatus[0x32]<<9); //M (be master) - loc.bits |= ((keystatus[keys[14]]==1)<<12); //Map mode - } - loc.bits |= keystatus[keys[8]]; //Stand high - loc.bits |= (keystatus[keys[9]]<<1); //Stand low - loc.bits |= (keystatus[keys[16]]<<4); //Zoom in - loc.bits |= (keystatus[keys[17]]<<5); //Zoom out - loc.bits |= (keystatus[keys[4]]<<8); //Run - loc.bits |= (keystatus[keys[10]]<<2); //Look up - loc.bits |= (keystatus[keys[11]]<<3); //Look down - loc.bits |= ((keystatus[keys[7]]==1)<<10); //Space - loc.bits |= ((keystatus[keys[6]]==1)<<11); //Shoot - loc.bits |= (((bstatus&6)>(oldmousebstatus&6))<<10); //Space - loc.bits |= (((bstatus&1)>(oldmousebstatus&1))<<11); //Shoot - - oldmousebstatus = bstatus; - if (((loc.bits&2048) > 0) && (locselectedgun == 0)) - oldmousebstatus &= ~1; //Allow continous fire with mouse for chain gun - - //PRIVATE KEYS: -/* if (keystatus[0xb7]) //Printscreen - { - keystatus[0xb7] = 0; - printscreeninterrupt(); - } -*/ - if (keystatus[0x2f]) //V - { - keystatus[0x2f] = 0; - if (cameradist < 0) cameradist = 0; else cameradist = -1; - cameraang = 0; - } - - if (typemode == 0) //if normal game keys active - { - if (keystatus[0x19]) //P - { - keystatus[0x19] = 0; - parallaxtype++; - if (parallaxtype > 2) parallaxtype = 0; - } - if (keystatus[0x38]|keystatus[0xb8]) //ALT - { - if (keystatus[0x4a]) // Keypad - - visibility = min(visibility+(visibility>>3),16384); - if (keystatus[0x4e]) // Keypad + - visibility = max(visibility-(visibility>>3),128); - } - - if (keystatus[keys[18]]) //Typing mode - { - keystatus[keys[18]] = 0; - typemode = 1; - bflushchars(); - keyfifoplc = keyfifoend; //Reset keyboard fifo - } - } - else - { - while ((ch = bgetchar())) - { - if (ch == 8) //Backspace - { - if (typemessageleng == 0) { typemode = 0; break; } - typemessageleng--; - } - else if (ch == 9) // tab - { - keystatus[0xf] = 0; - typemode = 0; - break; - } - else if (ch == 13) //Either ENTER - { - keystatus[0x1c] = 0; keystatus[0x9c] = 0; - if (typemessageleng > 0) - { - packbuf[0] = 2; //Sending text is message type 4 - for(j=typemessageleng-1;j>=0;j--) - packbuf[j+1] = typemessage[j]; - - for(i=connecthead;i>=0;i=connectpoint2[i]) - if (i != myconnectindex) - sendpacket(i,packbuf,typemessageleng+1); - - typemessageleng = 0; - } - typemode = 0; - break; - } - else if ((typemessageleng < 159) && (ch >= 32) && (ch < 128)) - { - typemessage[typemessageleng++] = ch; - } - } - } -} - -void initplayersprite(short snum) -{ - long i; - - if (playersprite[snum] >= 0) return; - - spawnsprite(playersprite[snum],posx[snum],posy[snum],posz[snum]+EYEHEIGHT, - 1+256,0,snum,32,64,64,0,0,PLAYER,ang[snum],0,0,0,snum+4096, - cursectnum[snum],8,0,0,0); - - switch(snum) - { - case 1: for(i=0;i<32;i++) tempbuf[i+192] = i+128; break; //green->red - case 2: for(i=0;i<32;i++) tempbuf[i+192] = i+32; break; //green->blue - case 3: for(i=0;i<32;i++) tempbuf[i+192] = i+224; break; //green->pink - case 4: for(i=0;i<32;i++) tempbuf[i+192] = i+64; break; //green->brown - case 5: for(i=0;i<32;i++) tempbuf[i+192] = i+96; break; - case 6: for(i=0;i<32;i++) tempbuf[i+192] = i+160; break; - case 7: for(i=0;i<32;i++) tempbuf[i+192] = i+192; break; - default: for(i=0;i<256;i++) tempbuf[i] = i; break; - } - makepalookup(snum,tempbuf,0,0,0,1); -} - -void playback(void) -{ - long i, j, k; - - ready2send = 0; - recstat = 0; i = reccnt; - while (!keystatus[1]) - { - if (handleevents()) { - if (quitevent) { - keystatus[1] = 1; - quitevent = 0; - } - } - - refreshaudio(); - - while (totalclock >= lockclock+TICSPERFRAME) - { - sampletimer(); - if (i >= reccnt) - { - prepareboard(boardfilename); - for(i=connecthead;i>=0;i=connectpoint2[i]) - initplayersprite((short)i); - totalclock = 0; - i = 0; - } - - k = 0; - for(j=connecthead;j>=0;j=connectpoint2[j]) - { - copybufbyte(&recsync[i][k],&ffsync[j],sizeof(input)); - k++; - } - movethings(); domovethings(); - i++; - } - drawscreen(screenpeek,(totalclock-gotlastpacketclock)*(65536/(TIMERINTSPERSECOND/MOVESPERSECOND))); - - if (keystatus[keys[15]]) - { - keystatus[keys[15]] = 0; - screenpeek = connectpoint2[screenpeek]; - if (screenpeek < 0) screenpeek = connecthead; - drawstatusbar(screenpeek); // Andy did this - } - if (keystatus[keys[14]]) - { - keystatus[keys[14]] = 0; - dimensionmode[screenpeek]++; - if (dimensionmode[screenpeek] > 3) dimensionmode[screenpeek] = 1; - } - } - - musicoff(); - uninitmultiplayers(); - uninittimer(); - uninitinput(); - uninitengine(); - uninitsb(); - uninitgroupfile(); - exit(0); -} - -void setup3dscreen(void) -{ - long i, dax, day, dax2, day2; - - i = setgamemode(fullscreen,xdimgame,ydimgame,bppgame); - if (i < 0) - { - printf("Error setting video mode.\n"); - sendlogoff(); - musicoff(); - uninitmultiplayers(); - uninittimer(); - uninitinput(); - uninitengine(); - uninitsb(); - uninitgroupfile(); - exit(0); - } - - //Make that ugly pink into black in case it ever shows up! - i = 0L; - setpalette(255,1,(char *)&i); - //outp(0x3c8,255); outp(0x3c9,0); outp(0x3c9,0); outp(0x3c9,0); - - screensize = xdim; - if (screensize > xdim) - { - dax = 0; day = 0; - dax2 = xdim-1; day2 = ydim-1; - } - else - { - dax = ((xdim-screensize)>>1); - dax2 = dax+screensize-1; - day = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); - day2 = day + scale(screensize,ydim-32,xdim)-1; - setview(dax,day,dax2,day2); - } - - flushperms(); - - if (screensize < xdim) - drawtilebackground(0L,0L,BACKGROUND,8,0L,0L,xdim-1L,ydim-1L,0); //Draw background - - if (screensize <= xdim) - { - rotatesprite((xdim-320)<<15,(ydim-32)<<16,65536L,0,STATUSBAR,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); - i = ((xdim-320)>>1); - while (i >= 8) i -= 8, rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL8,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); - if (i >= 4) i -= 4, rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL4,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); - i = ((xdim-320)>>1)+320; - while (i <= xdim-8) rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL8,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L), i += 8; - if (i <= xdim-4) rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL4,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L), i += 4; - - drawstatusbar(screenpeek); // Andy did this - } -} - -void findrandomspot(long *x, long *y, short *sectnum) -{ - short startwall, endwall, s, dasector; - long dax, day, daz, minx, maxx, miny, maxy, cnt; - - for(cnt=256;cnt>=0;cnt--) - { - do - { - dasector = mulscale16(krand(),numsectors); - } while ((sector[dasector].ceilingz+(8<<8) >= sector[dasector].floorz) || ((sector[dasector].lotag|sector[dasector].hitag) != 0) || ((sector[dasector].floorstat&1) != 0)); - - startwall = sector[dasector].wallptr; - endwall = startwall+sector[dasector].wallnum; - if (endwall <= startwall) continue; - - dax = 0L; - day = 0L; - minx = 0x7fffffff; maxx = 0x80000000; - miny = 0x7fffffff; maxy = 0x80000000; - - for(s=startwall;s maxx) maxx = wall[s].x; - if (wall[s].y < miny) miny = wall[s].y; - if (wall[s].y > maxy) maxy = wall[s].y; - } - - if ((maxx-minx <= 256) || (maxy-miny <= 256)) continue; - - dax /= (endwall-startwall); - day /= (endwall-startwall); - - if (inside(dax,day,dasector) == 0) continue; - - daz = sector[dasector].floorz-(32<<8); - if (pushmove(&dax,&day,&daz,&dasector,128L,4<<8,4<<8,CLIPMASK0) < 0) continue; - - *x = dax; *y = day; *sectnum = dasector; - return; - } -} - -void warp(long *x, long *y, long *z, short *daang, short *dasector) -{ - short startwall, endwall, s; - long i, j, dax, day, ox, oy; - - ox = *x; oy = *y; - - for(i=0;i= warpsectorcnt) i = 0; - } while (sector[warpsectorlist[i]].hitag != j); - *dasector = warpsectorlist[i]; - break; - } - - //Find center of sector - startwall = sector[*dasector].wallptr; - endwall = startwall+sector[*dasector].wallnum; - dax = 0L, day = 0L; - for(s=startwall;s= 0) - i = s; - } - *x = dax / (endwall-startwall); - *y = day / (endwall-startwall); - *z = sector[*dasector].floorz-(32<<8); - updatesector(*x,*y,dasector); - dax = ((wall[i].x+wall[wall[i].point2].x)>>1); - day = ((wall[i].y+wall[wall[i].point2].y)>>1); - *daang = getangle(dax-*x,day-*y); - - wsayfollow("warp.wav",3072L+(krand()&127)-64,192L,&ox,&oy,0); - wsayfollow("warp.wav",4096L+(krand()&127)-64,256L,x,y,0); -} - -void warpsprite(short spritenum) -{ - short dasectnum; - - dasectnum = sprite[spritenum].sectnum; - warp(&sprite[spritenum].x,&sprite[spritenum].y,&sprite[spritenum].z, - &sprite[spritenum].ang,&dasectnum); - - copybuf(&sprite[spritenum].x,&osprite[spritenum].x,3); - changespritesect(spritenum,dasectnum); - - show2dsprite[spritenum>>3] &= ~(1<<(spritenum&7)); - if (show2dsector[dasectnum>>3]&(1<<(dasectnum&7))) - show2dsprite[spritenum>>3] |= (1<<(spritenum&7)); -} - -void initlava(void) -{ - long x, y, z, r; - - for(z=0;z<32;z++) lavaradcnt[z] = 0; - for(x=-16;x<=16;x++) - for(y=-16;y<=16;y++) - { - r = ksqrt(x*x + y*y); - lavaradx[r][lavaradcnt[r]] = x; - lavarady[r][lavaradcnt[r]] = y; - lavaradcnt[r]++; - } - - for(z=0;z<16;z++) - lavadropsizlookup[z] = 8 / (ksqrt(z)+1); - - for(z=0;z>4)&7)-4)+12; - - lavanumdrops = 0; - lavanumframes = 0; -} - -#if defined(NOASM) -inline long addlava(long bx) -{ - char *b = (char *)bx; - return b[-133] + b[-132] + b[-131] + b[1] + b[-1] + b[131] + b[132]; -} -#elif defined(__WATCOMC__) -#pragma aux addlava =\ - "mov al, byte ptr [ebx-133]",\ - "mov dl, byte ptr [ebx-1]",\ - "add al, byte ptr [ebx-132]",\ - "add dl, byte ptr [ebx+131]",\ - "add al, byte ptr [ebx-131]",\ - "add dl, byte ptr [ebx+132]",\ - "add al, byte ptr [ebx+1]",\ - "add al, dl",\ - parm [ebx]\ - modify exact [eax edx] -long addlava(long); -#elif defined(_MSC_VER) -inline long addlava(long b) -{ - _asm { - mov ebx, b - mov al, byte ptr [ebx-133] - mov dl, byte ptr [ebx-1] - add al, byte ptr [ebx-132] - add dl, byte ptr [ebx+131] - add al, byte ptr [ebx-131] - add dl, byte ptr [ebx+132] - add al, byte ptr [ebx+1] - add al, dl - } -} -#elif defined(__GNUC__) && defined(__i386__) -inline long addlava(long b) -{ - long r; - __asm__ __volatile__ ( - "movb -133(%%ebx), %%al\n\t" - "movb -1(%%ebx), %%dl\n\t" - "addb -132(%%ebx), %%al\n\t" - "addb 131(%%ebx), %%dl\n\t" - "addb -131(%%ebx), %%al\n\t" - "addb 132(%%ebx), %%dl\n\t" - "addb 1(%%ebx), %%al\n\t" - "addb %%dl, %%al" - : "=a" (r) : "b" (b) - : "dx" - ); - return r; -} -#else -#error Unsupported compiler or architecture -#endif - -void movelava(char *dapic) -{ - long i, j, x, y, z, zz, dalavadropsiz, dadropsizlookup; - long dalavax, dalavay, *ptr, *ptr2; - - for(z=min(LAVAMAXDROPS-lavanumdrops-1,3);z>=0;z--) - { - lavadropx[lavanumdrops] = (Brand()&(LAVASIZ-1)); - lavadropy[lavanumdrops] = (Brand()&(LAVASIZ-1)); - lavadropsiz[lavanumdrops] = 1; - lavanumdrops++; - } - - for(z=lavanumdrops-1;z>=0;z--) - { - dadropsizlookup = lavadropsizlookup[lavadropsiz[z]]*(((z&1)<<1)-1); - dalavadropsiz = lavadropsiz[z]; - dalavax = lavadropx[z]; dalavay = lavadropy[z]; - for(zz=lavaradcnt[lavadropsiz[z]]-1;zz>=0;zz--) - { - i = (((lavaradx[dalavadropsiz][zz]+dalavax)&(LAVASIZ-1))< 10) - { - lavanumdrops--; - lavadropx[z] = lavadropx[lavanumdrops]; - lavadropy[z] = lavadropy[lavanumdrops]; - lavadropsiz[z] = lavadropsiz[lavanumdrops]; - } - } - - //Back up dapic with 1 pixel extra on each boundary - //(to prevent anding for wrap-around) - ptr = (long *)dapic; - ptr2 = (long *)((LAVASIZ+4)+1+((long)lavabakpic)); - for(x=0;x>2);y>0;y--) *ptr2++ = ((*ptr++)&0x1f1f1f1f); - ptr2++; - } - for(y=0;y>3)+ - ((addlava(y+1)&0xf8)<<5)+ - ((addlava(y+2)&0xf8)<<13)+ - ((addlava(y+3)&0xf8)<<21)+ - 0xc2c2c2c2; - } - } - - lavanumframes++; -} - -void doanimations(void) -{ - long i, j; - - for(i=animatecnt-1;i>=0;i--) - { - j = *animateptr[i]; - - if (j < animategoal[i]) - j = min(j+animatevel[i]*TICSPERFRAME,animategoal[i]); - else - j = max(j-animatevel[i]*TICSPERFRAME,animategoal[i]); - animatevel[i] += animateacc[i]; - - *animateptr[i] = j; - - if (j == animategoal[i]) - { - animatecnt--; - if (i != animatecnt) - { - stopinterpolation(animateptr[i]); - animateptr[i] = animateptr[animatecnt]; - animategoal[i] = animategoal[animatecnt]; - animatevel[i] = animatevel[animatecnt]; - animateacc[i] = animateacc[animatecnt]; - } - } - } -} - -long getanimationgoal(long animptr) -{ - long i; - - for(i=animatecnt-1;i>=0;i--) - if ((long *)animptr == animateptr[i]) return(i); - return(-1); -} - -long setanimation(long *animptr, long thegoal, long thevel, long theacc) -{ - long i, j; - - if (animatecnt >= MAXANIMATES) return(-1); - - j = animatecnt; - for(i=animatecnt-1;i>=0;i--) - if (animptr == animateptr[i]) - { j = i; break; } - - setinterpolation(animptr); - - animateptr[j] = animptr; - animategoal[j] = thegoal; - animatevel[j] = thevel; - animateacc[j] = theacc; - if (j == animatecnt) animatecnt++; - return(j); -} - -void checkmasterslaveswitch(void) -{ - long i, j; - - if (option[4] == 0) return; - - j = 0; - for(i=connecthead;i>=0;i=connectpoint2[i]) - if (ssync[i].bits&512) j++; - if (j != 1) return; - - i = connecthead; - for(j=connectpoint2[i];j>=0;j=connectpoint2[j]) - { - if (ssync[j].bits&512) - { - connectpoint2[i] = connectpoint2[j]; - connectpoint2[j] = connecthead; - connecthead = (short)j; - - oloc.fvel = loc.fvel+1; - oloc.svel = loc.svel+1; - oloc.avel = loc.avel+1; - oloc.bits = loc.bits+1; - for(i=0;i=0;i=connectpoint2[i]) - { - if (myconnectindex == i) break; - j++; - } - if (j == 1) - Bstrcpy(getmessage,"Player 1 (Master)"); - else - Bsprintf(getmessage,"Player %ld (Slave)",j); - getmessageleng = Bstrlen(getmessage); - getmessagetimeoff = totalclock+120; - - return; - } - i = j; - } -} - - -long testneighborsectors(short sect1, short sect2) -{ - short i, startwall, num1, num2; - - num1 = sector[sect1].wallnum; - num2 = sector[sect2].wallnum; - if (num1 < num2) //Traverse walls of sector with fewest walls (for speed) - { - startwall = sector[sect1].wallptr; - for(i=num1-1;i>=0;i--) - if (wall[i+startwall].nextsector == sect2) - return(1); - } - else - { - startwall = sector[sect2].wallptr; - for(i=num2-1;i>=0;i--) - if (wall[i+startwall].nextsector == sect1) - return(1); - } - return(0); -} - -long loadgame(void) -{ - long i; - long fil; - - if ((fil = kopen4load("save0000.gam",0)) == -1) return(-1); - - kdfread(&numplayers,4,1,fil); - kdfread(&myconnectindex,4,1,fil); - kdfread(&connecthead,4,1,fil); - kdfread(connectpoint2,4,MAXPLAYERS,fil); - - //Make sure palookups get set, sprites will get overwritten later - for(i=connecthead;i>=0;i=connectpoint2[i]) initplayersprite((short)i); - - kdfread(posx,4,MAXPLAYERS,fil); - kdfread(posy,4,MAXPLAYERS,fil); - kdfread(posz,4,MAXPLAYERS,fil); - kdfread(horiz,4,MAXPLAYERS,fil); - kdfread(zoom,4,MAXPLAYERS,fil); - kdfread(hvel,4,MAXPLAYERS,fil); - kdfread(ang,2,MAXPLAYERS,fil); - kdfread(cursectnum,2,MAXPLAYERS,fil); - kdfread(ocursectnum,2,MAXPLAYERS,fil); - kdfread(playersprite,2,MAXPLAYERS,fil); - kdfread(deaths,2,MAXPLAYERS,fil); - kdfread(lastchaingun,4,MAXPLAYERS,fil); - kdfread(health,4,MAXPLAYERS,fil); - kdfread(numgrabbers,2,MAXPLAYERS,fil); - kdfread(nummissiles,2,MAXPLAYERS,fil); - kdfread(numbombs,2,MAXPLAYERS,fil); - kdfread(flytime,4,MAXPLAYERS,fil); - kdfread(oflags,2,MAXPLAYERS,fil); - kdfread(dimensionmode,1,MAXPLAYERS,fil); - kdfread(revolvedoorstat,1,MAXPLAYERS,fil); - kdfread(revolvedoorang,2,MAXPLAYERS,fil); - kdfread(revolvedoorrotang,2,MAXPLAYERS,fil); - kdfread(revolvedoorx,4,MAXPLAYERS,fil); - kdfread(revolvedoory,4,MAXPLAYERS,fil); - - kdfread(&numsectors,2,1,fil); - kdfread(sector,sizeof(sectortype),numsectors,fil); - kdfread(&numwalls,2,1,fil); - kdfread(wall,sizeof(walltype),numwalls,fil); - //Store all sprites (even holes) to preserve indeces - kdfread(sprite,sizeof(spritetype),MAXSPRITES,fil); - kdfread(headspritesect,2,MAXSECTORS+1,fil); - kdfread(prevspritesect,2,MAXSPRITES,fil); - kdfread(nextspritesect,2,MAXSPRITES,fil); - kdfread(headspritestat,2,MAXSTATUS+1,fil); - kdfread(prevspritestat,2,MAXSPRITES,fil); - kdfread(nextspritestat,2,MAXSPRITES,fil); - - kdfread(&fvel,4,1,fil); - kdfread(&svel,4,1,fil); - kdfread(&avel,4,1,fil); - - kdfread(&locselectedgun,4,1,fil); - kdfread(&loc.fvel,1,1,fil); - kdfread(&oloc.fvel,1,1,fil); - kdfread(&loc.svel,1,1,fil); - kdfread(&oloc.svel,1,1,fil); - kdfread(&loc.avel,1,1,fil); - kdfread(&oloc.avel,1,1,fil); - kdfread(&loc.bits,2,1,fil); - kdfread(&oloc.bits,2,1,fil); - - kdfread(&locselectedgun2,4,1,fil); - kdfread(&loc2.fvel,sizeof(input),1,fil); - - kdfread(ssync,sizeof(input),MAXPLAYERS,fil); - kdfread(osync,sizeof(input),MAXPLAYERS,fil); - - kdfread(boardfilename,1,80,fil); - kdfread(&screenpeek,2,1,fil); - kdfread(&oldmousebstatus,2,1,fil); - kdfread(&brightness,2,1,fil); - kdfread(&neartagsector,2,1,fil); - kdfread(&neartagwall,2,1,fil); - kdfread(&neartagsprite,2,1,fil); - kdfread(&lockclock,4,1,fil); - kdfread(&neartagdist,4,1,fil); - kdfread(&neartaghitdist,4,1,fil); - - kdfread(turnspritelist,2,16,fil); - kdfread(&turnspritecnt,2,1,fil); - kdfread(warpsectorlist,2,16,fil); - kdfread(&warpsectorcnt,2,1,fil); - kdfread(xpanningsectorlist,2,16,fil); - kdfread(&xpanningsectorcnt,2,1,fil); - kdfread(ypanningwalllist,2,64,fil); - kdfread(&ypanningwallcnt,2,1,fil); - kdfread(floorpanninglist,2,64,fil); - kdfread(&floorpanningcnt,2,1,fil); - kdfread(dragsectorlist,2,16,fil); - kdfread(dragxdir,2,16,fil); - kdfread(dragydir,2,16,fil); - kdfread(&dragsectorcnt,2,1,fil); - kdfread(dragx1,4,16,fil); - kdfread(dragy1,4,16,fil); - kdfread(dragx2,4,16,fil); - kdfread(dragy2,4,16,fil); - kdfread(dragfloorz,4,16,fil); - kdfread(&swingcnt,2,1,fil); - kdfread(swingwall,2,32*5,fil); - kdfread(swingsector,2,32,fil); - kdfread(swingangopen,2,32,fil); - kdfread(swingangclosed,2,32,fil); - kdfread(swingangopendir,2,32,fil); - kdfread(swingang,2,32,fil); - kdfread(swinganginc,2,32,fil); - kdfread(swingx,4,32*8,fil); - kdfread(swingy,4,32*8,fil); - kdfread(revolvesector,2,4,fil); - kdfread(revolveang,2,4,fil); - kdfread(&revolvecnt,2,1,fil); - kdfread(revolvex,4,4*16,fil); - kdfread(revolvey,4,4*16,fil); - kdfread(revolvepivotx,4,4,fil); - kdfread(revolvepivoty,4,4,fil); - kdfread(subwaytracksector,2,4*128,fil); - kdfread(subwaynumsectors,2,4,fil); - kdfread(&subwaytrackcnt,2,1,fil); - kdfread(subwaystop,4,4*8,fil); - kdfread(subwaystopcnt,4,4,fil); - kdfread(subwaytrackx1,4,4,fil); - kdfread(subwaytracky1,4,4,fil); - kdfread(subwaytrackx2,4,4,fil); - kdfread(subwaytracky2,4,4,fil); - kdfread(subwayx,4,4,fil); - kdfread(subwaygoalstop,4,4,fil); - kdfread(subwayvel,4,4,fil); - kdfread(subwaypausetime,4,4,fil); - kdfread(waterfountainwall,2,MAXPLAYERS,fil); - kdfread(waterfountaincnt,2,MAXPLAYERS,fil); - kdfread(slimesoundcnt,2,MAXPLAYERS,fil); - - //Warning: only works if all pointers are in sector structures! - kdfread(animateptr,4,MAXANIMATES,fil); - for(i=MAXANIMATES-1;i>=0;i--) - animateptr[i] = (long *)(animateptr[i]+((long)sector)); - - kdfread(animategoal,4,MAXANIMATES,fil); - kdfread(animatevel,4,MAXANIMATES,fil); - kdfread(animateacc,4,MAXANIMATES,fil); - kdfread(&animatecnt,4,1,fil); - - kdfread(&totalclock,4,1,fil); - kdfread(&numframes,4,1,fil); - kdfread(&randomseed,4,1,fil); - kdfread(&numpalookups,2,1,fil); - - kdfread(&visibility,4,1,fil); - kdfread(¶llaxvisibility,4,1,fil); - kdfread(¶llaxtype,1,1,fil); - kdfread(¶llaxyoffs,4,1,fil); - kdfread(pskyoff,2,MAXPSKYTILES,fil); - kdfread(&pskybits,2,1,fil); - - kdfread(&mirrorcnt,2,1,fil); - kdfread(mirrorwall,2,mirrorcnt,fil); - kdfread(mirrorsector,2,mirrorcnt,fil); - - //I should save off interpolation list, but they're pointers :( - numinterpolations = 0; - startofdynamicinterpolations = 0; - - kclose(fil); - - for(i=connecthead;i>=0;i=connectpoint2[i]) initplayersprite((short)i); - - totalclock = lockclock; - ototalclock = lockclock; - - Bstrcpy(getmessage,"Game loaded."); - getmessageleng = Bstrlen(getmessage); - getmessagetimeoff = totalclock+360+(getmessageleng<<4); - return(0); -} - -long savegame(void) -{ - long i; - BFILE *fil; - - if ((fil = Bfopen("save0000.gam","wb")) == 0) return(-1); - - dfwrite(&numplayers,4,1,fil); - dfwrite(&myconnectindex,4,1,fil); - dfwrite(&connecthead,4,1,fil); - dfwrite(connectpoint2,4,MAXPLAYERS,fil); - - dfwrite(posx,4,MAXPLAYERS,fil); - dfwrite(posy,4,MAXPLAYERS,fil); - dfwrite(posz,4,MAXPLAYERS,fil); - dfwrite(horiz,4,MAXPLAYERS,fil); - dfwrite(zoom,4,MAXPLAYERS,fil); - dfwrite(hvel,4,MAXPLAYERS,fil); - dfwrite(ang,2,MAXPLAYERS,fil); - dfwrite(cursectnum,2,MAXPLAYERS,fil); - dfwrite(ocursectnum,2,MAXPLAYERS,fil); - dfwrite(playersprite,2,MAXPLAYERS,fil); - dfwrite(deaths,2,MAXPLAYERS,fil); - dfwrite(lastchaingun,4,MAXPLAYERS,fil); - dfwrite(health,4,MAXPLAYERS,fil); - dfwrite(numgrabbers,2,MAXPLAYERS,fil); - dfwrite(nummissiles,2,MAXPLAYERS,fil); - dfwrite(numbombs,2,MAXPLAYERS,fil); - dfwrite(flytime,4,MAXPLAYERS,fil); - dfwrite(oflags,2,MAXPLAYERS,fil); - dfwrite(dimensionmode,1,MAXPLAYERS,fil); - dfwrite(revolvedoorstat,1,MAXPLAYERS,fil); - dfwrite(revolvedoorang,2,MAXPLAYERS,fil); - dfwrite(revolvedoorrotang,2,MAXPLAYERS,fil); - dfwrite(revolvedoorx,4,MAXPLAYERS,fil); - dfwrite(revolvedoory,4,MAXPLAYERS,fil); - - dfwrite(&numsectors,2,1,fil); - dfwrite(sector,sizeof(sectortype),numsectors,fil); - dfwrite(&numwalls,2,1,fil); - dfwrite(wall,sizeof(walltype),numwalls,fil); - //Store all sprites (even holes) to preserve indeces - dfwrite(sprite,sizeof(spritetype),MAXSPRITES,fil); - dfwrite(headspritesect,2,MAXSECTORS+1,fil); - dfwrite(prevspritesect,2,MAXSPRITES,fil); - dfwrite(nextspritesect,2,MAXSPRITES,fil); - dfwrite(headspritestat,2,MAXSTATUS+1,fil); - dfwrite(prevspritestat,2,MAXSPRITES,fil); - dfwrite(nextspritestat,2,MAXSPRITES,fil); - - dfwrite(&fvel,4,1,fil); - dfwrite(&svel,4,1,fil); - dfwrite(&avel,4,1,fil); - - dfwrite(&locselectedgun,4,1,fil); - dfwrite(&loc.fvel,1,1,fil); - dfwrite(&oloc.fvel,1,1,fil); - dfwrite(&loc.svel,1,1,fil); - dfwrite(&oloc.svel,1,1,fil); - dfwrite(&loc.avel,1,1,fil); - dfwrite(&oloc.avel,1,1,fil); - dfwrite(&loc.bits,2,1,fil); - dfwrite(&oloc.bits,2,1,fil); - - dfwrite(&locselectedgun2,4,1,fil); - dfwrite(&loc2.fvel,sizeof(input),1,fil); - - dfwrite(ssync,sizeof(input),MAXPLAYERS,fil); - dfwrite(osync,sizeof(input),MAXPLAYERS,fil); - - dfwrite(boardfilename,1,80,fil); - dfwrite(&screenpeek,2,1,fil); - dfwrite(&oldmousebstatus,2,1,fil); - dfwrite(&brightness,2,1,fil); - dfwrite(&neartagsector,2,1,fil); - dfwrite(&neartagwall,2,1,fil); - dfwrite(&neartagsprite,2,1,fil); - dfwrite(&lockclock,4,1,fil); - dfwrite(&neartagdist,4,1,fil); - dfwrite(&neartaghitdist,4,1,fil); - - dfwrite(turnspritelist,2,16,fil); - dfwrite(&turnspritecnt,2,1,fil); - dfwrite(warpsectorlist,2,16,fil); - dfwrite(&warpsectorcnt,2,1,fil); - dfwrite(xpanningsectorlist,2,16,fil); - dfwrite(&xpanningsectorcnt,2,1,fil); - dfwrite(ypanningwalllist,2,64,fil); - dfwrite(&ypanningwallcnt,2,1,fil); - dfwrite(floorpanninglist,2,64,fil); - dfwrite(&floorpanningcnt,2,1,fil); - dfwrite(dragsectorlist,2,16,fil); - dfwrite(dragxdir,2,16,fil); - dfwrite(dragydir,2,16,fil); - dfwrite(&dragsectorcnt,2,1,fil); - dfwrite(dragx1,4,16,fil); - dfwrite(dragy1,4,16,fil); - dfwrite(dragx2,4,16,fil); - dfwrite(dragy2,4,16,fil); - dfwrite(dragfloorz,4,16,fil); - dfwrite(&swingcnt,2,1,fil); - dfwrite(swingwall,2,32*5,fil); - dfwrite(swingsector,2,32,fil); - dfwrite(swingangopen,2,32,fil); - dfwrite(swingangclosed,2,32,fil); - dfwrite(swingangopendir,2,32,fil); - dfwrite(swingang,2,32,fil); - dfwrite(swinganginc,2,32,fil); - dfwrite(swingx,4,32*8,fil); - dfwrite(swingy,4,32*8,fil); - dfwrite(revolvesector,2,4,fil); - dfwrite(revolveang,2,4,fil); - dfwrite(&revolvecnt,2,1,fil); - dfwrite(revolvex,4,4*16,fil); - dfwrite(revolvey,4,4*16,fil); - dfwrite(revolvepivotx,4,4,fil); - dfwrite(revolvepivoty,4,4,fil); - dfwrite(subwaytracksector,2,4*128,fil); - dfwrite(subwaynumsectors,2,4,fil); - dfwrite(&subwaytrackcnt,2,1,fil); - dfwrite(subwaystop,4,4*8,fil); - dfwrite(subwaystopcnt,4,4,fil); - dfwrite(subwaytrackx1,4,4,fil); - dfwrite(subwaytracky1,4,4,fil); - dfwrite(subwaytrackx2,4,4,fil); - dfwrite(subwaytracky2,4,4,fil); - dfwrite(subwayx,4,4,fil); - dfwrite(subwaygoalstop,4,4,fil); - dfwrite(subwayvel,4,4,fil); - dfwrite(subwaypausetime,4,4,fil); - dfwrite(waterfountainwall,2,MAXPLAYERS,fil); - dfwrite(waterfountaincnt,2,MAXPLAYERS,fil); - dfwrite(slimesoundcnt,2,MAXPLAYERS,fil); - - //Warning: only works if all pointers are in sector structures! - for(i=MAXANIMATES-1;i>=0;i--) - animateptr[i] = (long *)(animateptr[i]-((long)sector)); - dfwrite(animateptr,4,MAXANIMATES,fil); - for(i=MAXANIMATES-1;i>=0;i--) - animateptr[i] = (long *)(animateptr[i]+((long)sector)); - - dfwrite(animategoal,4,MAXANIMATES,fil); - dfwrite(animatevel,4,MAXANIMATES,fil); - dfwrite(animateacc,4,MAXANIMATES,fil); - dfwrite(&animatecnt,4,1,fil); - - dfwrite(&totalclock,4,1,fil); - dfwrite(&numframes,4,1,fil); - dfwrite(&randomseed,4,1,fil); - dfwrite(&numpalookups,2,1,fil); - - dfwrite(&visibility,4,1,fil); - dfwrite(¶llaxvisibility,4,1,fil); - dfwrite(¶llaxtype,1,1,fil); - dfwrite(¶llaxyoffs,4,1,fil); - dfwrite(pskyoff,2,MAXPSKYTILES,fil); - dfwrite(&pskybits,2,1,fil); - - dfwrite(&mirrorcnt,2,1,fil); - dfwrite(mirrorwall,2,mirrorcnt,fil); - dfwrite(mirrorsector,2,mirrorcnt,fil); - - Bfclose(fil); - - Bstrcpy(getmessage,"Game saved."); - getmessageleng = Bstrlen(getmessage); - getmessagetimeoff = totalclock+360+(getmessageleng<<4); - return(0); -} - -void faketimerhandler(void) -{ - short other, packbufleng; - long i, j, k, l; - - sampletimer(); - if ((totalclock < ototalclock+(TIMERINTSPERSECOND/MOVESPERSECOND)) || (ready2send == 0)) return; - ototalclock += (TIMERINTSPERSECOND/MOVESPERSECOND); - - getpackets(); - if (getoutputcirclesize() >= 16) return; - getinput(); - - /* - for(i=connecthead;i>=0;i=connectpoint2[i]) - if (i != myconnectindex) - { - k = (movefifoend[myconnectindex]-1)-movefifoend[i]; - myminlag[i] = min(myminlag[i],k); - mymaxlag = max(mymaxlag,k); - } - - if (((movefifoend[myconnectindex]-1)&(TIMERUPDATESIZ-1)) == 0) - { - i = mymaxlag-bufferjitter; mymaxlag = 0; - if (i > 0) bufferjitter += ((2+i)>>2); - else if (i < 0) bufferjitter -= ((2-i)>>2); - } - */ - - if (networkmode == 1) - { - packbuf[2] = 0; j = 3; - if (loc.fvel != oloc.fvel) packbuf[j++] = loc.fvel, packbuf[2] |= 1; - if (loc.svel != oloc.svel) packbuf[j++] = loc.svel, packbuf[2] |= 2; - if (loc.avel != oloc.avel) packbuf[j++] = loc.avel, packbuf[2] |= 4; - if ((loc.bits^oloc.bits)&0x00ff) packbuf[j++] = (loc.bits&255), packbuf[2] |= 8; - if ((loc.bits^oloc.bits)&0xff00) packbuf[j++] = ((loc.bits>>8)&255), packbuf[2] |= 16; - copybufbyte(&loc,&oloc,sizeof(input)); - - copybufbyte(&loc,&baksync[movefifoend[myconnectindex]][myconnectindex],sizeof(input)); - movefifoend[myconnectindex] = ((movefifoend[myconnectindex]+1)&(MOVEFIFOSIZ-1)); - - for(i=connecthead;i>=0;i=connectpoint2[i]) - if (i != myconnectindex) - { - packbuf[0] = 17; - packbuf[1] = (char)((movefifoend[myconnectindex]-movefifoend[i])&(MOVEFIFOSIZ-1)); - - k = j; - if ((myconnectindex == connecthead) || ((i == connecthead) && (myconnectindex == connectpoint2[connecthead]))) - { - while (syncvalhead != syncvaltail) - { - packbuf[j++] = syncval[syncvaltail]; - syncvaltail = ((syncvaltail+1)&(MOVEFIFOSIZ-1)); - } - } - sendpacket(i,packbuf,j); - j = k; - } - - gotlastpacketclock = totalclock; - return; - } - - //MASTER (or 1 player game) - if ((myconnectindex == connecthead) || (option[4] == 0)) - { - copybufbyte(&loc,&ffsync[myconnectindex],sizeof(input)); - - if (option[4] != 0) - { - packbuf[0] = 0; - j = ((numplayers+1)>>1)+1; - for(k=1;k=0;i=connectpoint2[i]) - { - l = 0; - if (ffsync[i].fvel != osync[i].fvel) packbuf[j++] = ffsync[i].fvel, l |= 1; - if (ffsync[i].svel != osync[i].svel) packbuf[j++] = ffsync[i].svel, l |= 2; - if (ffsync[i].avel != osync[i].avel) packbuf[j++] = ffsync[i].avel, l |= 4; - if (ffsync[i].bits != osync[i].bits) - { - packbuf[j++] = (ffsync[i].bits&255); - packbuf[j++] = ((ffsync[i].bits>>8)&255); - l |= 8; - } - packbuf[k>>3] |= (l<<(k&7)); - k += 4; - - copybufbyte(&ffsync[i],&osync[i],sizeof(input)); - } - - while (syncvalhead != syncvaltail) - { - packbuf[j++] = syncval[syncvaltail]; - syncvaltail = ((syncvaltail+1)&(MOVEFIFOSIZ-1)); - } - - for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) - sendpacket(i,packbuf,j); - } - else if (numplayers >= 2) - { - if (keystatus[0xb5]) - { - keystatus[0xb5] = 0; - locselectedgun2++; if (locselectedgun2 >= 3) locselectedgun2 = 0; - } - - //Second player on 1 computer mode - loc2.fvel = min(max(fvel2,-128+8),127-8); - loc2.svel = min(max(svel2,-128+8),127-8); - loc2.avel = min(max(avel2,-128+16),127-16); - loc2.bits = (locselectedgun2<<13); - loc2.bits |= keystatus[0x45]; //Stand high - loc2.bits |= (keystatus[0x47]<<1); //Stand low - loc2.bits |= (1<<8); //Run - loc2.bits |= (keystatus[0x49]<<2); //Look up - loc2.bits |= (keystatus[0x37]<<3); //Look down - loc2.bits |= (keystatus[0x50]<<10); //Space - loc2.bits |= (keystatus[0x52]<<11); //Shoot - - other = connectpoint2[myconnectindex]; - if (other < 0) other = connecthead; - - copybufbyte(&loc2,&ffsync[other],sizeof(input)); - } - movethings(); //Move EVERYTHING (you too!) - } - else //I am a SLAVE - { - packbuf[0] = 1; packbuf[1] = 0; j = 2; - if (loc.fvel != oloc.fvel) packbuf[j++] = loc.fvel, packbuf[1] |= 1; - if (loc.svel != oloc.svel) packbuf[j++] = loc.svel, packbuf[1] |= 2; - if (loc.avel != oloc.avel) packbuf[j++] = loc.avel, packbuf[1] |= 4; - if ((loc.bits^oloc.bits)&0x00ff) packbuf[j++] = (loc.bits&255), packbuf[1] |= 8; - if ((loc.bits^oloc.bits)&0xff00) packbuf[j++] = ((loc.bits>>8)&255), packbuf[1] |= 16; - copybufbyte(&loc,&oloc,sizeof(input)); - sendpacket(connecthead,packbuf,j); - } -} - -void getpackets(void) -{ - long i, j, k, l; - long other, packbufleng, movecnt; - - if (option[4] == 0) return; - - movecnt = 0; - while ((packbufleng = getpacket(&other,packbuf)) > 0) - { - switch(packbuf[0]) - { - case 0: //[0] (receive master sync buffer) - j = ((numplayers+1)>>1)+1; k = (1<<3); - for(i=connecthead;i>=0;i=connectpoint2[i]) - { - l = (packbuf[k>>3]>>(k&7)); - if (l&1) ffsync[i].fvel = packbuf[j++]; - if (l&2) ffsync[i].svel = packbuf[j++]; - if (l&4) ffsync[i].avel = packbuf[j++]; - if (l&8) - { - ffsync[i].bits = ((short)packbuf[j])+(((short)packbuf[j+1])<<8); - j += 2; - } - k += 4; - } - - while (j != packbufleng) - { - othersyncval[othersyncvalhead] = packbuf[j++]; - othersyncvalhead = ((othersyncvalhead+1)&(MOVEFIFOSIZ-1)); - } - if ((syncvalhead != syncvaltottail) && (othersyncvalhead != syncvaltottail)) - { - syncstat = 0; - do - { - syncstat |= (syncval[syncvaltottail]^othersyncval[syncvaltottail]); - syncvaltottail = ((syncvaltottail+1)&(MOVEFIFOSIZ-1)); - } while ((syncvalhead != syncvaltottail) && (othersyncvalhead != syncvaltottail)); - } - - movethings(); //Move all players and sprites - movecnt++; - break; - case 1: //[1] (receive slave sync buffer) - j = 2; k = packbuf[1]; - if (k&1) ffsync[other].fvel = packbuf[j++]; - if (k&2) ffsync[other].svel = packbuf[j++]; - if (k&4) ffsync[other].avel = packbuf[j++]; - if (k&8) ffsync[other].bits = ((ffsync[other].bits&0xff00)|((short)packbuf[j++])); - if (k&16) ffsync[other].bits = ((ffsync[other].bits&0x00ff)|(((short)packbuf[j++])<<8)); - break; - case 2: - getmessageleng = packbufleng-1; - for(j=getmessageleng-1;j>=0;j--) getmessage[j] = packbuf[j+1]; - getmessagetimeoff = totalclock+360+(getmessageleng<<4); - wsay("getstuff.wav",8192L,63L,63L); //Added 12/2004 - break; - case 3: - wsay("getstuff.wav",4096L,63L,63L); - break; - /* - case 5: - playerreadyflag[other] = packbuf[1]; - if ((other == connecthead) && (packbuf[1] == 2)) - sendpacket(connecthead,packbuf,2); - break; - */ - case 250: - playerreadyflag[other]++; - break; - case 17: - j = 3; k = packbuf[2]; - if (k&1) ffsync[other].fvel = packbuf[j++]; - if (k&2) ffsync[other].svel = packbuf[j++]; - if (k&4) ffsync[other].avel = packbuf[j++]; - if (k&8) ffsync[other].bits = ((ffsync[other].bits&0xff00)|((short)packbuf[j++])); - if (k&16) ffsync[other].bits = ((ffsync[other].bits&0x00ff)|(((short)packbuf[j++])<<8)); - otherlag[other] = packbuf[1]; - - copybufbyte(&ffsync[other],&baksync[movefifoend[other]][other],sizeof(input)); - movefifoend[other] = ((movefifoend[other]+1)&(MOVEFIFOSIZ-1)); - - while (j != packbufleng) - { - othersyncval[othersyncvalhead] = packbuf[j++]; - othersyncvalhead = ((othersyncvalhead+1)&(MOVEFIFOSIZ-1)); - } - if ((syncvalhead != syncvaltottail) && (othersyncvalhead != syncvaltottail)) - { - syncstat = 0; - do - { - syncstat |= (syncval[syncvaltottail]^othersyncval[syncvaltottail]); - syncvaltottail = ((syncvaltottail+1)&(MOVEFIFOSIZ-1)); - } while ((syncvalhead != syncvaltottail) && (othersyncvalhead != syncvaltottail)); - } - - break; - case 255: //[255] (logout) - keystatus[1] = 1; - break; - } - } - if ((networkmode == 0) && (myconnectindex != connecthead) && ((movecnt&1) == 0)) - { - if (rand()&1) ototalclock += (TICSPERFRAME>>1); - else ototalclock -= (TICSPERFRAME>>1); - } -} - -void drawoverheadmap(long cposx, long cposy, long czoom, short cang) -{ - long i, j, k, l=0, x1, y1, x2=0, y2=0, x3, y3, x4, y4, ox, oy, xoff, yoff; - long dax, day, cosang, sinang, xspan, yspan, sprx, spry; - long xrepeat, yrepeat, z1, z2, startwall, endwall, tilenum, daang; - long xvect, yvect, xvect2, yvect2; - char col; - walltype *wal, *wal2; - spritetype *spr; - - xvect = sintable[(-cang)&2047] * czoom; - yvect = sintable[(1536-cang)&2047] * czoom; - xvect2 = mulscale16(xvect,yxaspect); - yvect2 = mulscale16(yvect,yxaspect); - - //Draw red lines - for(i=0;inextwall; if (k < 0) continue; - - if ((show2dwall[j>>3]&(1<<(j&7))) == 0) continue; - if ((k > j) && ((show2dwall[k>>3]&(1<<(k&7))) > 0)) continue; - - if (sector[wal->nextsector].ceilingz == z1) - if (sector[wal->nextsector].floorz == z2) - if (((wal->cstat|wall[wal->nextwall].cstat)&(16+32)) == 0) continue; - - col = 152; - - if (dimensionmode[screenpeek] == 2) - { - if (sector[i].floorz != sector[i].ceilingz) - if (sector[wal->nextsector].floorz != sector[wal->nextsector].ceilingz) - if (((wal->cstat|wall[wal->nextwall].cstat)&(16+32)) == 0) - if (sector[i].floorz == sector[wal->nextsector].floorz) continue; - if (sector[i].floorpicnum != sector[wal->nextsector].floorpicnum) continue; - if (sector[i].floorshade != sector[wal->nextsector].floorshade) continue; - col = 12; - } - - ox = wal->x-cposx; oy = wal->y-cposy; - x1 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); - y1 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); - - wal2 = &wall[wal->point2]; - ox = wal2->x-cposx; oy = wal2->y-cposy; - x2 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); - y2 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); - - drawline256(x1,y1,x2,y2,col); - } - } - - //Draw sprites - k = playersprite[screenpeek]; - for(i=0;i=0;j=nextspritesect[j]) - if ((show2dsprite[j>>3]&(1<<(j&7))) > 0) - { - spr = &sprite[j]; if (spr->cstat&0x8000) continue; - col = 56; - if (spr->cstat&1) col = 248; - if (j == k) col = 31; - - k = statrate[spr->statnum]; - sprx = spr->x; - spry = spr->y; - if (k >= 0) - { - switch(k) - { - case 0: l = smoothratio; break; - case 1: l = (smoothratio>>1)+(((nummoves-j)&1)<<15); break; - case 3: l = (smoothratio>>2)+(((nummoves-j)&3)<<14); break; - case 7: l = (smoothratio>>3)+(((nummoves-j)&7)<<13); break; - case 15: l = (smoothratio>>4)+(((nummoves-j)&15)<<12); break; - } - sprx = osprite[j].x+mulscale16(sprx-osprite[j].x,l); - spry = osprite[j].y+mulscale16(spry-osprite[j].y,l); - } - - switch (spr->cstat&48) - { - case 0: - ox = sprx-cposx; oy = spry-cposy; - x1 = dmulscale16(ox,xvect,-oy,yvect); - y1 = dmulscale16(oy,xvect2,ox,yvect2); - - if (dimensionmode[screenpeek] == 1) - { - ox = (sintable[(spr->ang+512)&2047]>>7); - oy = (sintable[(spr->ang)&2047]>>7); - x2 = dmulscale16(ox,xvect,-oy,yvect); - y2 = dmulscale16(oy,xvect,ox,yvect); - - if (j == playersprite[screenpeek]) - { - x2 = 0L; - y2 = -(czoom<<5); - } - - x3 = mulscale16(x2,yxaspect); - y3 = mulscale16(y2,yxaspect); - - drawline256(x1-x2+(xdim<<11),y1-y3+(ydim<<11), - x1+x2+(xdim<<11),y1+y3+(ydim<<11),col); - drawline256(x1-y2+(xdim<<11),y1+x3+(ydim<<11), - x1+x2+(xdim<<11),y1+y3+(ydim<<11),col); - drawline256(x1+y2+(xdim<<11),y1-x3+(ydim<<11), - x1+x2+(xdim<<11),y1+y3+(ydim<<11),col); - } - else - { - if (((gotsector[i>>3]&(1<<(i&7))) > 0) && (czoom > 96)) - { - daang = (spr->ang-cang)&2047; - if (j == playersprite[screenpeek]) { x1 = 0; y1 = 0; daang = 0; } - rotatesprite((x1<<4)+(xdim<<15),(y1<<4)+(ydim<<15),mulscale16(czoom*spr->yrepeat,yxaspect),daang,spr->picnum,spr->shade,spr->pal,(spr->cstat&2)>>1,windowx1,windowy1,windowx2,windowy2); - } - } - break; - case 16: - x1 = sprx; y1 = spry; - tilenum = spr->picnum; - xoff = (long)((signed char)((picanm[tilenum]>>8)&255))+((long)spr->xoffset); - if ((spr->cstat&4) > 0) xoff = -xoff; - k = spr->ang; l = spr->xrepeat; - dax = sintable[k&2047]*l; day = sintable[(k+1536)&2047]*l; - l = tilesizx[tilenum]; k = (l>>1)+xoff; - x1 -= mulscale16(dax,k); x2 = x1+mulscale16(dax,l); - y1 -= mulscale16(day,k); y2 = y1+mulscale16(day,l); - - ox = x1-cposx; oy = y1-cposy; - x1 = dmulscale16(ox,xvect,-oy,yvect); - y1 = dmulscale16(oy,xvect2,ox,yvect2); - - ox = x2-cposx; oy = y2-cposy; - x2 = dmulscale16(ox,xvect,-oy,yvect); - y2 = dmulscale16(oy,xvect2,ox,yvect2); - - drawline256(x1+(xdim<<11),y1+(ydim<<11), - x2+(xdim<<11),y2+(ydim<<11),col); - - break; - case 32: - if (dimensionmode[screenpeek] == 1) - { - tilenum = spr->picnum; - xoff = (long)((signed char)((picanm[tilenum]>>8)&255))+((long)spr->xoffset); - yoff = (long)((signed char)((picanm[tilenum]>>16)&255))+((long)spr->yoffset); - if ((spr->cstat&4) > 0) xoff = -xoff; - if ((spr->cstat&8) > 0) yoff = -yoff; - - k = spr->ang; - cosang = sintable[(k+512)&2047]; sinang = sintable[k]; - xspan = tilesizx[tilenum]; xrepeat = spr->xrepeat; - yspan = tilesizy[tilenum]; yrepeat = spr->yrepeat; - - dax = ((xspan>>1)+xoff)*xrepeat; day = ((yspan>>1)+yoff)*yrepeat; - x1 = sprx + dmulscale16(sinang,dax,cosang,day); - y1 = spry + dmulscale16(sinang,day,-cosang,dax); - l = xspan*xrepeat; - x2 = x1 - mulscale16(sinang,l); - y2 = y1 + mulscale16(cosang,l); - l = yspan*yrepeat; - k = -mulscale16(cosang,l); x3 = x2+k; x4 = x1+k; - k = -mulscale16(sinang,l); y3 = y2+k; y4 = y1+k; - - ox = x1-cposx; oy = y1-cposy; - x1 = dmulscale16(ox,xvect,-oy,yvect); - y1 = dmulscale16(oy,xvect2,ox,yvect2); - - ox = x2-cposx; oy = y2-cposy; - x2 = dmulscale16(ox,xvect,-oy,yvect); - y2 = dmulscale16(oy,xvect2,ox,yvect2); - - ox = x3-cposx; oy = y3-cposy; - x3 = dmulscale16(ox,xvect,-oy,yvect); - y3 = dmulscale16(oy,xvect2,ox,yvect2); - - ox = x4-cposx; oy = y4-cposy; - x4 = dmulscale16(ox,xvect,-oy,yvect); - y4 = dmulscale16(oy,xvect2,ox,yvect2); - - drawline256(x1+(xdim<<11),y1+(ydim<<11), - x2+(xdim<<11),y2+(ydim<<11),col); - - drawline256(x2+(xdim<<11),y2+(ydim<<11), - x3+(xdim<<11),y3+(ydim<<11),col); - - drawline256(x3+(xdim<<11),y3+(ydim<<11), - x4+(xdim<<11),y4+(ydim<<11),col); - - drawline256(x4+(xdim<<11),y4+(ydim<<11), - x1+(xdim<<11),y1+(ydim<<11),col); - - } - break; - } - } - - //Draw white lines - for(i=0;inextwall >= 0) continue; - - if ((show2dwall[j>>3]&(1<<(j&7))) == 0) continue; - - if (tilesizx[wal->picnum] == 0) continue; - if (tilesizy[wal->picnum] == 0) continue; - - if (j == k) - { x1 = x2; y1 = y2; } - else - { - ox = wal->x-cposx; oy = wal->y-cposy; - x1 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); - y1 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); - } - - k = wal->point2; wal2 = &wall[k]; - ox = wal2->x-cposx; oy = wal2->y-cposy; - x2 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); - y2 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); - - drawline256(x1,y1,x2,y2,24); - } - } -} - - //New movesprite using getzrange. Note that I made the getzrange - //parameters global (&globhiz,&globhihit,&globloz,&globlohit) so they - //don't need to be passed everywhere. Also this should make this - //movesprite function compatible with the older movesprite functions. -long movesprite(short spritenum, long dx, long dy, long dz, long ceildist, long flordist, long clipmask) -{ - long daz, zoffs, tempint; - short retval, dasectnum, datempshort; - spritetype *spr; - - spr = &sprite[spritenum]; - - if ((spr->cstat&128) == 0) - zoffs = -((tilesizy[spr->picnum]*spr->yrepeat)<<1); - else - zoffs = 0; - - dasectnum = spr->sectnum; //Can't modify sprite sectors directly becuase of linked lists - daz = spr->z+zoffs; //Must do this if not using the new centered centering (of course) - retval = clipmove(&spr->x,&spr->y,&daz,&dasectnum,dx,dy, - ((long)spr->clipdist)<<2,ceildist,flordist,clipmask); - - if (dasectnum < 0) retval = -1; - - if ((dasectnum != spr->sectnum) && (dasectnum >= 0)) - changespritesect(spritenum,dasectnum); - - //Set the blocking bit to 0 temporarly so getzrange doesn't pick up - //its own sprite - datempshort = spr->cstat; spr->cstat &= ~1; - getzrange(spr->x,spr->y,spr->z-1,spr->sectnum, - &globhiz,&globhihit,&globloz,&globlohit, - ((long)spr->clipdist)<<2,clipmask); - spr->cstat = datempshort; - - daz = spr->z+zoffs + dz; - if ((daz <= globhiz) || (daz > globloz)) - { - if (retval != 0) return(retval); - return(16384+dasectnum); - } - spr->z = daz-zoffs; - return(retval); -} - - -void waitforeverybody () -{ - long i; - if (numplayers < 2) return; - packbuf[0] = 250; - for(i=connecthead;i>=0;i=connectpoint2[i]) - { - if (i != myconnectindex) sendpacket(i,packbuf,1); - if ((!networkmode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master - } - playerreadyflag[myconnectindex]++; - while (1) - { - handleevents(); - refreshaudio(); - - drawrooms(posx[myconnectindex],posy[myconnectindex],posz[myconnectindex],ang[myconnectindex],horiz[myconnectindex],cursectnum[myconnectindex]); - if (!networkmode) Bsprintf(tempbuf,"Master/slave mode"); - else Bsprintf(tempbuf,"Peer-peer mode"); - printext256((xdim>>1)-(strlen(tempbuf)<<2),(ydim>>1)-24,31,0,tempbuf,0); - Bsprintf(tempbuf,"Waiting for players"); - printext256((xdim>>1)-(strlen(tempbuf)<<2),(ydim>>1)-16,31,0,tempbuf,0); - for(i=connecthead;i>=0;i=connectpoint2[i]) - { - if (playerreadyflag[i] < playerreadyflag[myconnectindex]) - { - //slaves in M/S mode only wait for master - if ((!networkmode) && (myconnectindex != connecthead) && (i != connecthead)) - { - Bsprintf(tempbuf,"Player %ld",i); - printext256((xdim>>1)-(16<<2),(ydim>>1)+i*8,15,0,tempbuf,0); - } - else - { - Bsprintf(tempbuf,"Player %ld NOT ready",i); - printext256((xdim>>1)-(16<<2),(ydim>>1)+i*8,127,0,tempbuf,0); - } - } - else - { - Bsprintf(tempbuf,"Player %ld ready",i); - printext256((xdim>>1)-(16<<2),(ydim>>1)+i*8,31,0,tempbuf,0); - } - if (i == myconnectindex) - { - Bsprintf(tempbuf,"You->"); - printext256((xdim>>1)-(26<<2),(ydim>>1)+i*8,95,0,tempbuf,0); - } - } - nextpage(); - - - if (quitevent || keystatus[1]) { - sendlogoff(); //Signing off - musicoff(); - uninitmultiplayers(); - uninittimer(); - uninitinput(); - uninitengine(); - uninitsb(); - uninitgroupfile(); - exit(0); - } - - getpackets(); - - for(i=connecthead;i>=0;i=connectpoint2[i]) - { - if (playerreadyflag[i] < playerreadyflag[myconnectindex]) break; - if ((!networkmode) && (myconnectindex != connecthead)) { i = -1; break; } //slaves in M/S mode only wait for master - } - if (i < 0) return; - } -} - - -void searchmap(short startsector) -{ - long i, j, dasect, splc, send, startwall, endwall; - short dapic; - walltype *wal; - - if ((startsector < 0) || (startsector >= numsectors)) return; - for(i=0;i<(MAXSECTORS>>3);i++) show2dsector[i] = 0; - for(i=0;i<(MAXWALLS>>3);i++) show2dwall[i] = 0; - for(i=0;i<(MAXSPRITES>>3);i++) show2dsprite[i] = 0; - - automapping = 0; - - //Search your area recursively & set all show2dsector/show2dwalls - tempshort[0] = startsector; - show2dsector[startsector>>3] |= (1<<(startsector&7)); - dapic = sector[startsector].ceilingpicnum; - if (waloff[dapic] == 0) loadtile(dapic); - dapic = sector[startsector].floorpicnum; - if (waloff[dapic] == 0) loadtile(dapic); - for(splc=0,send=1;splc>3] |= (1<<(i&7)); - dapic = wall[i].picnum; - if (waloff[dapic] == 0) loadtile(dapic); - dapic = wall[i].overpicnum; - if (((dapic&0xfffff000) == 0) && (waloff[dapic] == 0)) loadtile(dapic); - - j = wal->nextsector; - if ((j >= 0) && ((show2dsector[j>>3]&(1<<(j&7))) == 0)) - { - show2dsector[j>>3] |= (1<<(j&7)); - - dapic = sector[j].ceilingpicnum; - if (waloff[dapic] == 0) loadtile(dapic); - dapic = sector[j].floorpicnum; - if (waloff[dapic] == 0) loadtile(dapic); - - tempshort[send++] = (short)j; - } - } - - for(i=headspritesect[dasect];i>=0;i=nextspritesect[i]) - { - show2dsprite[i>>3] |= (1<<(i&7)); - dapic = sprite[i].picnum; - if (waloff[dapic] == 0) loadtile(dapic); - } - } -} - -void setinterpolation(long *posptr) -{ - long i; - - if (numinterpolations >= MAXINTERPOLATIONS) return; - for(i=numinterpolations-1;i>=0;i--) - if (curipos[i] == posptr) return; - curipos[numinterpolations] = posptr; - oldipos[numinterpolations] = *posptr; - numinterpolations++; -} - -void stopinterpolation(long *posptr) -{ - long i; - - for(i=numinterpolations-1;i>=startofdynamicinterpolations;i--) - if (curipos[i] == posptr) - { - numinterpolations--; - oldipos[i] = oldipos[numinterpolations]; - bakipos[i] = bakipos[numinterpolations]; - curipos[i] = curipos[numinterpolations]; - } -} - -void updateinterpolations(void) //Stick at beginning of domovethings -{ - long i; - - for(i=numinterpolations-1;i>=0;i--) oldipos[i] = *curipos[i]; -} - -void dointerpolations(void) //Stick at beginning of drawscreen -{ - long i, j, odelta, ndelta; - - ndelta = 0; j = 0; - for(i=numinterpolations-1;i>=0;i--) - { - bakipos[i] = *curipos[i]; - odelta = ndelta; ndelta = (*curipos[i])-oldipos[i]; - if (odelta != ndelta) j = mulscale16(ndelta,smoothratio); - *curipos[i] = oldipos[i]+j; - } -} - -void restoreinterpolations(void) //Stick at end of drawscreen -{ - long i; - - for(i=numinterpolations-1;i>=0;i--) *curipos[i] = bakipos[i]; -} - -void printext(long x, long y, char *buffer, short tilenum, char invisiblecol) -{ - long i; - char ch; - - for(i=0;buffer[i]!=0;i++) - { - ch = buffer[i]; - rotatesprite((x-((8&15)<<3))<<16,(y-((8>>4)<<3))<<16,65536L,0,tilenum,0,0,8+16+64+128,x,y,x+7,y+7); - rotatesprite((x-((ch&15)<<3))<<16,(y-((ch>>4)<<3))<<16,65536L,0,tilenum,0,0,8+16+128,x,y,x+7,y+7); - x += 8; - } -} - -void drawtilebackground (long thex, long they, short tilenum, - signed char shade, long cx1, long cy1, - long cx2, long cy2, char dapalnum) -{ - long x, y, xsiz, ysiz, tx1, ty1, tx2, ty2; - - xsiz = tilesizx[tilenum]; tx1 = cx1/xsiz; tx2 = cx2/xsiz; - ysiz = tilesizy[tilenum]; ty1 = cy1/ysiz; ty2 = cy2/ysiz; - - for(x=tx1;x<=tx2;x++) - for(y=ty1;y<=ty2;y++) - rotatesprite(x*xsiz<<16,y*ysiz<<16,65536L,0,tilenum,shade,dapalnum,8+16+64+128,cx1,cy1,cx2,cy2); -} - - -/* - * vim:ts=4:sw=4: - */ +// Ken Silverman's official web site: "http://www.advsys.net/ken" +// See the included license file "BUILDLIC.TXT" for license info. +// +// This file has been modified from Ken Silverman's original release +// by Jonathon Fowler (jonof@edgenetwk.com) + +#include "compat.h" +#include "build.h" +#include "names.h" +#include "pragmas.h" +#include "cache1d.h" +#include "game.h" +#include "osd.h" +#include "mmulti.h" + +#include "baselayer.h" + +#define TIMERINTSPERSECOND 140 //280 +#define MOVESPERSECOND 40 +#define TICSPERFRAME 3 +#define MOVEFIFOSIZ 256 +#define EYEHEIGHT (32<<8) //Normally (32<<8), (51<<8) to make mirrors happy + +// declared in sound.c +void initsb(char,char,long,char,char,char,char); +void uninitsb(void); +void setears(long,long,long,long); +void wsayfollow(char *,long,long,long *,long *,char); +void wsay(char *,long,long,long); +void loadwaves(void); +void loadsong(char *); +void musicon(void); +void musicoff(void); +void refreshaudio(void); + +// declared in config.c +int loadsetup(const char *); +int writesetup(const char *); + + +/*************************************************************************** + KEN'S TAG DEFINITIONS: (Please define your own tags for your games) + + sector[?].lotag = 0 Normal sector + sector[?].lotag = 1 If you are on a sector with this tag, then all sectors + with same hi tag as this are operated. Once. + sector[?].lotag = 2 Same as sector[?].tag = 1 but this is retriggable. + sector[?].lotag = 3 A really stupid sector that really does nothing now. + sector[?].lotag = 4 A sector where you are put closer to the floor + (such as the slime in DOOM1.DAT) + sector[?].lotag = 5 A really stupid sector that really does nothing now. + sector[?].lotag = 6 A normal door - instead of pressing D, you tag the + sector with a 6. The reason I make you edit doors + this way is so that can program the doors + yourself. + sector[?].lotag = 7 A door the goes down to open. + sector[?].lotag = 8 A door that opens horizontally in the middle. + sector[?].lotag = 9 A sliding door that opens vertically in the middle. + -Example of the advantages of not using BSP tree. + sector[?].lotag = 10 A warping sector with floor and walls that shade. + sector[?].lotag = 11 A sector with all walls that do X-panning. + sector[?].lotag = 12 A sector with walls using the dragging function. + sector[?].lotag = 13 A sector with some swinging doors in it. + sector[?].lotag = 14 A revolving door sector. + sector[?].lotag = 15 A subway track. + sector[?].lotag = 16 A true double-sliding door. + + wall[?].lotag = 0 Normal wall + wall[?].lotag = 1 Y-panning wall + wall[?].lotag = 2 Switch - If you flip it, then all sectors with same hi + tag as this are operated. + wall[?].lotag = 3 Marked wall to detemine starting dir. (sector tag 12) + wall[?].lotag = 4 Mark on the shorter wall closest to the pivot point + of a swinging door. (sector tag 13) + wall[?].lotag = 5 Mark where a subway should stop. (sector tag 15) + wall[?].lotag = 6 Mark for true double-sliding doors (sector tag 16) + wall[?].lotag = 7 Water fountain + wall[?].lotag = 8 Bouncy wall! + + sprite[?].lotag = 0 Normal sprite + sprite[?].lotag = 1 If you press space bar on an AL, and the AL is tagged + with a 1, he will turn evil. + sprite[?].lotag = 2 When this sprite is operated, a bomb is shot at its + position. + sprite[?].lotag = 3 Rotating sprite. + sprite[?].lotag = 4 Sprite switch. + sprite[?].lotag = 5 Basketball hoop score. + +KEN'S STATUS DEFINITIONS: (Please define your own statuses for your games) + status = 0 Inactive sprite + status = 1 Active monster sprite + status = 2 Monster that becomes active only when it sees you + status = 3 Smoke on the wall for chainguns + status = 4 Splashing sprites (When you shoot slime) + status = 5 Explosion! + status = 6 Travelling bullet + status = 7 Bomb sprial-out explosion + status = 8 Player! + status = 9 EVILALGRAVE shrinking list + status = 10 EVILAL list + status = 11 Sprite respawning list + status = 12 Sprite which does not respawn (Andy's addition) + status = MAXSTATUS Non-existent sprite (this will be true for your + code also) +**************************************************************************/ + +typedef struct +{ + long x, y, z; +} point3d; + +typedef struct +{ + signed char fvel, svel, avel; + short bits; +} input; + +static long screentilt = 0, oscreentilt = 0; + + +static long fvel, svel, avel; +static long fvel2, svel2, avel2; + +#define NUMOPTIONS 8 +#define NUMKEYS 19 +char option[NUMOPTIONS] = {0,0,0,0,0,0,1,0}; +char keys[NUMKEYS] = +{ + 0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39, + 0x1e,0x2c,0xd1,0xc9,0x33,0x34, + 0x9c,0x1c,0xd,0xc,0xf +}; +long xdimgame = 320, ydimgame = 200, bppgame = 8, xdim2d = 640, ydim2d = 480; // JBF 20050318: config.c expects to find these + +static long digihz[8] = {6000,8000,11025,16000,22050,32000,44100,48000}; + +static char frame2draw[MAXPLAYERS]; +static long frameskipcnt[MAXPLAYERS]; + +#define LAVASIZ 128 +#define LAVALOGSIZ 7 +#define LAVAMAXDROPS 32 +static char lavabakpic[(LAVASIZ+4)*(LAVASIZ+4)], lavainc[LAVASIZ]; +static long lavanumdrops, lavanumframes; +static long lavadropx[LAVAMAXDROPS], lavadropy[LAVAMAXDROPS]; +static long lavadropsiz[LAVAMAXDROPS], lavadropsizlookup[LAVAMAXDROPS]; +static long lavaradx[24][96], lavarady[24][96], lavaradcnt[32]; + + //Shared player variables +static long posx[MAXPLAYERS], posy[MAXPLAYERS], posz[MAXPLAYERS]; +static long horiz[MAXPLAYERS], zoom[MAXPLAYERS], hvel[MAXPLAYERS]; +static short ang[MAXPLAYERS], cursectnum[MAXPLAYERS], ocursectnum[MAXPLAYERS]; +static short playersprite[MAXPLAYERS], deaths[MAXPLAYERS]; +static long lastchaingun[MAXPLAYERS]; +static long health[MAXPLAYERS], flytime[MAXPLAYERS]; +static short oflags[MAXPLAYERS]; +static short numbombs[MAXPLAYERS]; +static short numgrabbers[MAXPLAYERS]; // Andy did this +static short nummissiles[MAXPLAYERS]; // Andy did this +static char dimensionmode[MAXPLAYERS]; +static char revolvedoorstat[MAXPLAYERS]; +static short revolvedoorang[MAXPLAYERS], revolvedoorrotang[MAXPLAYERS]; +static long revolvedoorx[MAXPLAYERS], revolvedoory[MAXPLAYERS]; + + //ENGINE CONTROLLED MULTIPLAYER VARIABLES: +extern long numplayers, myconnectindex; +extern long connecthead, connectpoint2[MAXPLAYERS]; //Player linked list variables (indeces, not connection numbers) + +static long nummoves; +// Bug: NUMSTATS used to be equal to the greatest tag number, +// so that the last statrate[] entry was random memory junk +// because stats 0-NUMSTATS required NUMSTATS+1 bytes. -Andy +#define NUMSTATS 13 +static signed char statrate[NUMSTATS] = {-1,0,-1,0,0,0,1,3,0,3,15,-1,-1}; + + //Input structures +static char networkmode; //0 is 2(n-1) mode, 1 is n(n-1) mode +static long locselectedgun, locselectedgun2; +static input loc, oloc, loc2; +static input ffsync[MAXPLAYERS], osync[MAXPLAYERS], ssync[MAXPLAYERS]; + //Input faketimerhandler -> movethings fifo +static long movefifoplc, movefifoend[MAXPLAYERS]; +static input baksync[MOVEFIFOSIZ][MAXPLAYERS]; + //Game recording variables +static long reccnt, recstat = 1; +static input recsync[16384][2]; + +//static long myminlag[MAXPLAYERS], mymaxlag, otherminlag, bufferjitter = 1; +static signed char otherlag[MAXPLAYERS] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; +static long averagelag[MAXPLAYERS] = {512,512,512,512,512,512,512,512,512,512,512,512,512,512,512,512}; + +static long fakemovefifoplc; +static long myx, myy, myz, omyx, omyy, omyz, myzvel; +static long myhoriz, omyhoriz; +static short myang, omyang, mycursectnum; +static long myxbak[MOVEFIFOSIZ], myybak[MOVEFIFOSIZ], myzbak[MOVEFIFOSIZ]; +static long myhorizbak[MOVEFIFOSIZ]; +static short myangbak[MOVEFIFOSIZ]; + + //MULTI.OBJ sync state variables +extern char syncstate; + //GAME.C sync state variables +static char syncstat, syncval[MOVEFIFOSIZ], othersyncval[MOVEFIFOSIZ]; +static long syncvaltottail, syncvalhead, othersyncvalhead, syncvaltail; + +static char detailmode = 0, ready2send = 0; +static long ototalclock = 0, gotlastpacketclock = 0, smoothratio; +static long oposx[MAXPLAYERS], oposy[MAXPLAYERS], oposz[MAXPLAYERS]; +static long ohoriz[MAXPLAYERS], ozoom[MAXPLAYERS]; +static short oang[MAXPLAYERS]; + +static point3d osprite[MAXSPRITES]; + +#define MAXINTERPOLATIONS 1024 +static long numinterpolations = 0, startofdynamicinterpolations = 0; +static long oldipos[MAXINTERPOLATIONS]; +static long bakipos[MAXINTERPOLATIONS]; +static long *curipos[MAXINTERPOLATIONS]; + +extern long cachecount; + +static char playerreadyflag[MAXPLAYERS]; + + //Miscellaneous variables +static char packbuf[MAXXDIM]; +static char tempbuf[MAXXDIM], boardfilename[80]; +static short tempshort[MAXSECTORS]; +static short screenpeek = 0, oldmousebstatus = 0; +short brightness = 0; +static short screensize, screensizeflag = 0; +static short neartagsector, neartagwall, neartagsprite; +static long lockclock, neartagdist, neartaghitdist; +extern long pageoffset, ydim16; +static long globhiz, globloz, globhihit, globlohit; + + //Over the shoulder mode variables +static long cameradist = -1, cameraang = 0, cameraclock = 0; + + //Board animation variables +#define MAXMIRRORS 64 +static short mirrorwall[MAXMIRRORS], mirrorsector[MAXMIRRORS], mirrorcnt; +static short floormirrorsector[64], floormirrorcnt; +static short turnspritelist[16], turnspritecnt; +static short warpsectorlist[64], warpsectorcnt; +static short xpanningsectorlist[16], xpanningsectorcnt; +static short ypanningwalllist[64], ypanningwallcnt; +static short floorpanninglist[64], floorpanningcnt; +static short dragsectorlist[16], dragxdir[16], dragydir[16], dragsectorcnt; +static long dragx1[16], dragy1[16], dragx2[16], dragy2[16], dragfloorz[16]; +static short swingcnt, swingwall[32][5], swingsector[32]; +static short swingangopen[32], swingangclosed[32], swingangopendir[32]; +static short swingang[32], swinganginc[32]; +static long swingx[32][8], swingy[32][8]; +static short revolvesector[4], revolveang[4], revolvecnt; +static long revolvex[4][16], revolvey[4][16]; +static long revolvepivotx[4], revolvepivoty[4]; +static short subwaytracksector[4][128], subwaynumsectors[4], subwaytrackcnt; +static long subwaystop[4][8], subwaystopcnt[4]; +static long subwaytrackx1[4], subwaytracky1[4]; +static long subwaytrackx2[4], subwaytracky2[4]; +static long subwayx[4], subwaygoalstop[4], subwayvel[4], subwaypausetime[4]; +static short waterfountainwall[MAXPLAYERS], waterfountaincnt[MAXPLAYERS]; +static short slimesoundcnt[MAXPLAYERS]; + + //Variables that let you type messages to other player +static char getmessage[162], getmessageleng; +static long getmessagetimeoff; +static char typemessage[162], typemessageleng = 0, typemode = 0; +/* +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, +}; +*/ + + //These variables are for animating x, y, or z-coordinates of sectors, + //walls, or sprites (They are NOT to be used for changing the [].picnum's) + //See the setanimation(), and getanimategoal() functions for more details. +#define MAXANIMATES 512 +static long *animateptr[MAXANIMATES], animategoal[MAXANIMATES]; +static long animatevel[MAXANIMATES], animateacc[MAXANIMATES], animatecnt = 0; + +#if defined(POLYMOST) && defined(USE_OPENGL) + //These parameters are in exact order of sprite structure in BUILD.H +#define spawnsprite(newspriteindex2,x2,y2,z2,cstat2,shade2,pal2, \ + clipdist2,xrepeat2,yrepeat2,xoffset2,yoffset2,picnum2,ang2, \ + xvel2,yvel2,zvel2,owner2,sectnum2,statnum2,lotag2,hitag2,extra2) \ +{ \ + spritetype *spr2; \ + newspriteindex2 = insertsprite(sectnum2,statnum2); \ + spr2 = &sprite[newspriteindex2]; \ + spr2->x = x2; spr2->y = y2; spr2->z = z2; \ + spr2->cstat = cstat2; spr2->shade = shade2; \ + spr2->pal = pal2; spr2->clipdist = clipdist2; \ + spr2->xrepeat = xrepeat2; spr2->yrepeat = yrepeat2; \ + spr2->xoffset = xoffset2; spr2->yoffset = yoffset2; \ + spr2->picnum = picnum2; spr2->ang = ang2; \ + spr2->xvel = xvel2; spr2->yvel = yvel2; spr2->zvel = zvel2; \ + spr2->owner = owner2; \ + spr2->lotag = lotag2; spr2->hitag = hitag2; spr2->extra = extra2; \ + copybuf(&spr2->x,&osprite[newspriteindex2].x,3); \ + show2dsprite[newspriteindex2>>3] &= ~(1<<(newspriteindex2&7)); \ + if (show2dsector[sectnum2>>3]&(1<<(sectnum2&7))) \ + show2dsprite[newspriteindex2>>3] |= (1<<(newspriteindex2&7)); \ + clearbufbyte(&spriteext[newspriteindex2], sizeof(spriteexttype), 0); \ +} +#else +#define spawnsprite(newspriteindex2,x2,y2,z2,cstat2,shade2,pal2, \ + clipdist2,xrepeat2,yrepeat2,xoffset2,yoffset2,picnum2,ang2, \ + xvel2,yvel2,zvel2,owner2,sectnum2,statnum2,lotag2,hitag2,extra2) \ +{ \ + spritetype *spr2; \ + newspriteindex2 = insertsprite(sectnum2,statnum2); \ + spr2 = &sprite[newspriteindex2]; \ + spr2->x = x2; spr2->y = y2; spr2->z = z2; \ + spr2->cstat = cstat2; spr2->shade = shade2; \ + spr2->pal = pal2; spr2->clipdist = clipdist2; \ + spr2->xrepeat = xrepeat2; spr2->yrepeat = yrepeat2; \ + spr2->xoffset = xoffset2; spr2->yoffset = yoffset2; \ + spr2->picnum = picnum2; spr2->ang = ang2; \ + spr2->xvel = xvel2; spr2->yvel = yvel2; spr2->zvel = zvel2; \ + spr2->owner = owner2; \ + spr2->lotag = lotag2; spr2->hitag = hitag2; spr2->extra = extra2; \ + copybuf(&spr2->x,&osprite[newspriteindex2].x,3); \ + show2dsprite[newspriteindex2>>3] &= ~(1<<(newspriteindex2&7)); \ + if (show2dsector[sectnum2>>3]&(1<<(sectnum2&7))) \ + show2dsprite[newspriteindex2>>3] |= (1<<(newspriteindex2&7)); \ +} +#endif + +int nextvoxid = 0; + +static int osdcmd_restartvid(const osdfuncparm_t *parm) +{ + resetvideomode(); + if (setgamemode(fullscreen,xdim,ydim,bpp)) + OSD_Printf("restartvid: Reset failed...\n"); + + return OSDCMD_OK; +} + +static int osdcmd_vidmode(const osdfuncparm_t *parm) +{ + long newx = xdim, newy = ydim, newbpp = bpp, newfullscreen = fullscreen; + + if (parm->numparms < 1 || parm->numparms > 4) return OSDCMD_SHOWHELP; + + switch (parm->numparms) { + case 1: // bpp switch + newbpp = Batol(parm->parms[0]); + break; + case 2: // res switch + newx = Batol(parm->parms[0]); + newy = Batol(parm->parms[1]); + break; + case 3: // res & bpp switch + case 4: + newx = Batol(parm->parms[0]); + newy = Batol(parm->parms[1]); + newbpp = Batol(parm->parms[2]); + if (parm->numparms == 4) + newfullscreen = (Batol(parm->parms[3]) != 0); + break; + } + + if (setgamemode(newfullscreen,newx,newy,newbpp)) + OSD_Printf("vidmode: Mode change failed!\n"); + screensize = xdim+1; + return OSDCMD_OK; +} + +#ifdef RENDERTYPEWIN +int DoLaunchWindow(void); // gamestartwin.c +#endif + +char *startwin_labeltext = "Starting KenBuild..."; + +long app_main(long argc, char *argv[]) +{ + long i, j, k, l, fil, waitplayers, x1, y1, x2, y2; + long other, packleng, netparm; + +#ifdef USE_OPENGL + OSD_RegisterFunction("restartvid","restartvid: reinitialise the video mode",osdcmd_restartvid); + OSD_RegisterFunction("vidmode","vidmode [xdim ydim] [bpp] [fullscreen]: immediately change the video mode",osdcmd_vidmode); +#endif + + wm_setapptitle("KenBuild by Ken Silverman"); + + Bstrcpy(boardfilename, "nukeland.map"); + j = 0; netparm = argc; + for (i=1;i= 2); + + pskyoff[0] = 0; pskyoff[1] = 0; pskybits = 1; + + loadpics("tiles000.art",1048576); //Load artwork +#ifdef SUPERBUILD + if (!qloadkvx(nextvoxid,"voxel000.kvx")) + tiletovox[PLAYER] = nextvoxid++; + if (!qloadkvx(nextvoxid,"voxel001.kvx")) + tiletovox[BROWNMONSTER] = nextvoxid++; +#endif + if (!loaddefinitionsfile("kenbuild.def")) initprintf("Definitions file loaded.\n"); + + //Here's an example of TRUE ornamented walls + //The allocatepermanenttile should be called right after loadpics + //Since it resets the tile cache for each call. + if (allocatepermanenttile(SLIME,128,128) == 0) //If enough memory + { + printf("Not enough memory for slime!\n"); + exit(0); + } + if (allocatepermanenttile(MAXTILES-1,64,64) != 0) //If enough memory + { + //My face with an explosion written over it + copytilepiece(KENPICTURE,0,0,64,64,MAXTILES-1,0,0); + copytilepiece(EXPLOSION,0,0,64,64,MAXTILES-1,0,0); + } + + initlava(); + + for(j=0;j<256;j++) + tempbuf[j] = ((j+32)&255); //remap colors for screwy palette sectors + makepalookup(16,tempbuf,0,0,0,1); + + for(j=0;j<256;j++) tempbuf[j] = j; + makepalookup(17,tempbuf,24,24,24,1); + + for(j=0;j<256;j++) tempbuf[j] = j; //(j&31)+32; + makepalookup(18,tempbuf,8,8,48,1); + + prepareboard(boardfilename); //Load board + + initsb(option[1],option[2],digihz[option[7]>>4],((option[7]&4)>0)+1,((option[7]&2)>0)+1,60,option[7]&1); + //if (Bstrcmp(boardfilename,"klab.map") == 0) + // loadsong("klabsong.kdm"); + //else + loadsong("neatsong.ogg"); + musicon(); + + /* + if (option[4] > 0) + { + x1 = ((xdim-screensize)>>1); + x2 = x1+screensize-1; + y1 = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); + y2 = y1 + scale(screensize,ydim-32,xdim)-1; + + drawtilebackground(0L,0L,BACKGROUND,8,x1,y1,x2,y2,0); + + sendlogon(); + + if (option[4] < 5) waitplayers = 2; else waitplayers = option[4]-3; + while (numplayers < waitplayers) + { + sprintf(tempbuf,"%ld of %ld players in...",numplayers,waitplayers); + printext256(68L,84L,31,0,tempbuf,0); + nextpage(); + + if (getpacket(&other,packbuf) > 0) + if (packbuf[0] == 255) + keystatus[1] = 1; + + if (handleevents()) { + if (quitevent) { + keystatus[1] = 1; + quitevent = 0; + } + } + + if (keystatus[1]) + { + sendlogoff(); //Signing off + musicoff(); + uninitmultiplayers(); + uninittimer(); + uninitinput(); + uninitengine(); + uninitsb(); + uninitgroupfile(); + exit(0); + } + } + screenpeek = myconnectindex; + + if (numplayers <= 3) + networkmode = 1; + else + networkmode = 0; + + j = 1; + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if (myconnectindex == i) break; + j++; + } + sprintf(getmessage,"Player %ld",j); + if (networkmode == 0) + { + if (j == 1) Bstrcat(getmessage," (Master)"); + else Bstrcat(getmessage," (Slave)"); + } else + Bstrcat(getmessage," (Even)"); + getmessageleng = Bstrlen(getmessage); + getmessagetimeoff = totalclock+120; + } + */ + screenpeek = myconnectindex; + reccnt = 0; + for(i=connecthead;i>=0;i=connectpoint2[i]) initplayersprite((short)i); + + waitforeverybody(); + totalclock = ototalclock = 0; gotlastpacketclock = 0; nummoves = 0; + + ready2send = 1; + drawscreen(screenpeek,65536L); + + while (!keystatus[1]) //Main loop starts here + { + if (handleevents()) { + if (quitevent) { + keystatus[1] = 1; + quitevent = 0; + } + } + + refreshaudio(); + OSD_DispatchQueued(); + + // backslash (useful only with KDM) +// if (keystatus[0x2b]) { keystatus[0x2b] = 0; preparesndbuf(); } + + if ((networkmode == 1) || (myconnectindex != connecthead)) + while (fakemovefifoplc != movefifoend[myconnectindex]) fakedomovethings(); + + getpackets(); + + if (typemode == 0) //if normal game keys active + { + if ((keystatus[0x2a]&keystatus[0x36]&keystatus[0x13]) > 0) //Sh.Sh.R (replay) + { + keystatus[0x13] = 0; + playback(); + } + + if (keystatus[0x26]&(keystatus[0x1d]|keystatus[0x9d])) //Load game + { + keystatus[0x26] = 0; + loadgame(); + drawstatusbar(screenpeek); // Andy did this + } + + if (keystatus[0x1f]&(keystatus[0x1d]|keystatus[0x9d])) //Save game + { + keystatus[0x1f] = 0; + savegame(); + } + } + + if ((networkmode == 0) || (option[4] == 0)) + { + while (movefifoplc != movefifoend[0]) domovethings(); + } + else + { + j = connecthead; + if (j == myconnectindex) j = connectpoint2[j]; + averagelag[j] = ((averagelag[j]*7+(((movefifoend[myconnectindex]-movefifoend[j]+otherlag[j]+2)&255)<<8))>>3); + j = max(averagelag[j]>>9,1); + while (((movefifoend[myconnectindex]-movefifoplc)&(MOVEFIFOSIZ-1)) > j) + { + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (movefifoplc == movefifoend[i]) break; + if (i >= 0) break; + if (myconnectindex != connecthead) + { + k = ((movefifoend[myconnectindex]-movefifoend[connecthead]-otherlag[connecthead]+128)&255); + if (k > 128+1) ototalclock++; + if (k < 128-1) ototalclock--; + } + domovethings(); + } + } + i = (totalclock-gotlastpacketclock)*(65536/(TIMERINTSPERSECOND/MOVESPERSECOND)); + + drawscreen(screenpeek,i); + } + + sendlogoff(); //Signing off + musicoff(); + uninitmultiplayers(); + uninittimer(); + uninitinput(); + uninitengine(); + uninitsb(); + uninitgroupfile(); + + return(0); +} + +void operatesector(short dasector) +{ //Door code + long i, j, k, s, nexti, good, cnt, datag; + long dax, day, daz, dax2, day2, daz2, centx, centy; + short startwall, endwall, wallfind[2]; + + datag = sector[dasector].lotag; + + startwall = sector[dasector].wallptr; + endwall = startwall + sector[dasector].wallnum; + centx = 0L, centy = 0L; + for(i=startwall;i= 0) //If door already moving, reverse its direction + { + if (datag == 8) + daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1); + else + daz = sector[dasector].floorz; + + if (animategoal[i] == daz) + animategoal[i] = sector[nextsectorneighborz(dasector,sector[dasector].floorz,-1,-1)].ceilingz; + else + animategoal[i] = daz; + animatevel[i] = 0; + } + else //else insert the door's ceiling on the animation list + { + if (sector[dasector].ceilingz == sector[dasector].floorz) + daz = sector[nextsectorneighborz(dasector,sector[dasector].floorz,-1,-1)].ceilingz; + else + { + if (datag == 8) + daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1); + else + daz = sector[dasector].floorz; + } + if ((j = setanimation(§or[dasector].ceilingz,daz,6L,6L)) >= 0) + wsayfollow("updowndr.wav",4096L+(krand()&255)-128,256L,¢x,¢y,0); + } + } + //Simple door that moves down + if ((datag == 7) || (datag == 8)) //If the sector in front's elevator + { + i = getanimationgoal((long)§or[dasector].floorz); + if (i >= 0) //If elevator already moving, reverse its direction + { + if (datag == 8) + daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1); + else + daz = sector[dasector].ceilingz; + + if (animategoal[i] == daz) + animategoal[i] = sector[nextsectorneighborz(dasector,sector[dasector].ceilingz,1,1)].floorz; + else + animategoal[i] = daz; + animatevel[i] = 0; + } + else //else insert the elevator's ceiling on the animation list + { + if (sector[dasector].floorz == sector[dasector].ceilingz) + daz = sector[nextsectorneighborz(dasector,sector[dasector].ceilingz,1,1)].floorz; + else + { + if (datag == 8) + daz = ((sector[dasector].ceilingz+sector[dasector].floorz)>>1); + else + daz = sector[dasector].ceilingz; + } + if ((j = setanimation(§or[dasector].floorz,daz,6L,6L)) >= 0) + wsayfollow("updowndr.wav",4096L+(krand()&255)-128,256L,¢x,¢y,0); + } + } + + if (datag == 9) //Smooshy-wall sideways double-door + { + //find any points with either same x or same y coordinate + // as center (centx, centy) - should be 2 points found. + wallfind[0] = -1; + wallfind[1] = -1; + for(i=startwall;i>1)-wall[wallfind[j]].x; + day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y; + if (dax2 != 0) + { + dax2 = wall[wall[wall[wallfind[j]].point2].point2].x; + dax2 -= wall[wall[wallfind[j]].point2].x; + setanimation(&wall[wallfind[j]].x,wall[wallfind[j]].x+dax2,4L,0L); + setanimation(&wall[i].x,wall[i].x+dax2,4L,0L); + setanimation(&wall[wall[wallfind[j]].point2].x,wall[wall[wallfind[j]].point2].x+dax2,4L,0L); + } + else if (day2 != 0) + { + day2 = wall[wall[wall[wallfind[j]].point2].point2].y; + day2 -= wall[wall[wallfind[j]].point2].y; + setanimation(&wall[wallfind[j]].y,wall[wallfind[j]].y+day2,4L,0L); + setanimation(&wall[i].y,wall[i].y+day2,4L,0L); + setanimation(&wall[wall[wallfind[j]].point2].y,wall[wall[wallfind[j]].point2].y+day2,4L,0L); + } + } + else + { + i = wallfind[j]-1; if (i < startwall) i = endwall-1; + dax2 = ((wall[i].x+wall[wall[wallfind[j]].point2].x)>>1)-wall[wallfind[j]].x; + day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y; + if (dax2 != 0) + { + setanimation(&wall[wallfind[j]].x,centx,4L,0L); + setanimation(&wall[i].x,centx+dax2,4L,0L); + setanimation(&wall[wall[wallfind[j]].point2].x,centx+dax2,4L,0L); + } + else if (day2 != 0) + { + setanimation(&wall[wallfind[j]].y,centy,4L,0L); + setanimation(&wall[i].y,centy+day2,4L,0L); + setanimation(&wall[wall[wallfind[j]].point2].y,centy+day2,4L,0L); + } + } + } + wsayfollow("updowndr.wav",4096L-256L,256L,¢x,¢y,0); + wsayfollow("updowndr.wav",4096L+256L,256L,¢x,¢y,0); + } + + if (datag == 13) //Swinging door + { + for(i=0;i>1) == centx) && (((wall[wallfind[j]].y+wall[wall[wallfind[j]].point2].y)>>1) == centy)) + { //door was closed + //find what direction door should open + i = wallfind[j]-1; if (i < startwall) i = endwall-1; + dax2 = wall[i].x-wall[wallfind[j]].x; + day2 = wall[i].y-wall[wallfind[j]].y; + if (dax2 != 0) + { + dax2 = wall[wall[wall[wall[wallfind[j]].point2].point2].point2].x; + dax2 -= wall[wall[wall[wallfind[j]].point2].point2].x; + setanimation(&wall[wallfind[j]].x,wall[wallfind[j]].x+dax2,4L,0L); + setanimation(&wall[i].x,wall[i].x+dax2,4L,0L); + setanimation(&wall[wall[wallfind[j]].point2].x,wall[wall[wallfind[j]].point2].x+dax2,4L,0L); + setanimation(&wall[wall[wall[wallfind[j]].point2].point2].x,wall[wall[wall[wallfind[j]].point2].point2].x+dax2,4L,0L); + } + else if (day2 != 0) + { + day2 = wall[wall[wall[wall[wallfind[j]].point2].point2].point2].y; + day2 -= wall[wall[wall[wallfind[j]].point2].point2].y; + setanimation(&wall[wallfind[j]].y,wall[wallfind[j]].y+day2,4L,0L); + setanimation(&wall[i].y,wall[i].y+day2,4L,0L); + setanimation(&wall[wall[wallfind[j]].point2].y,wall[wall[wallfind[j]].point2].y+day2,4L,0L); + setanimation(&wall[wall[wall[wallfind[j]].point2].point2].y,wall[wall[wall[wallfind[j]].point2].point2].y+day2,4L,0L); + } + } + else + { //door was not closed + i = wallfind[j]-1; if (i < startwall) i = endwall-1; + dax2 = wall[i].x-wall[wallfind[j]].x; + day2 = wall[i].y-wall[wallfind[j]].y; + if (dax2 != 0) + { + setanimation(&wall[wallfind[j]].x,centx,4L,0L); + setanimation(&wall[i].x,centx+dax2,4L,0L); + setanimation(&wall[wall[wallfind[j]].point2].x,centx,4L,0L); + setanimation(&wall[wall[wall[wallfind[j]].point2].point2].x,centx+dax2,4L,0L); + } + else if (day2 != 0) + { + setanimation(&wall[wallfind[j]].y,centy,4L,0L); + setanimation(&wall[i].y,centy+day2,4L,0L); + setanimation(&wall[wall[wallfind[j]].point2].y,centy,4L,0L); + setanimation(&wall[wall[wall[wallfind[j]].point2].point2].y,centy+day2,4L,0L); + } + } + } + wsayfollow("updowndr.wav",4096L-64L,256L,¢x,¢y,0); + wsayfollow("updowndr.wav",4096L+64L,256L,¢x,¢y,0); + } +} + +void operatesprite(short dasprite) +{ + long datag; + + datag = sprite[dasprite].lotag; + + if (datag == 2) //A sprite that shoots a bomb + { + shootgun(dasprite, + sprite[dasprite].x,sprite[dasprite].y,sprite[dasprite].z, + sprite[dasprite].ang,100L,sprite[dasprite].sectnum,2); + } +} + +long changehealth(short snum, short deltahealth) +{ + long dax, day; + short good, k, startwall, endwall, s; + + if (health[snum] > 0) + { + health[snum] += deltahealth; + if (health[snum] > 999) health[snum] = 999; + + if (health[snum] <= 0) + { + health[snum] = -1; + wsayfollow("death.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); + sprite[playersprite[snum]].picnum = SKELETON; + } + + if ((snum == screenpeek) && (screensize <= xdim)) + { + if (health[snum] > 0) + sprintf(tempbuf,"Health:%3ld",health[snum]); + else + sprintf(tempbuf,"YOU STINK!"); + + printext((xdim>>1)-(Bstrlen(tempbuf)<<2),ydim-24,tempbuf,ALPHABET,80); + } + } + return(health[snum] <= 0); //You were just injured +} + +void changenumbombs(short snum, short deltanumbombs) { // Andy did this + numbombs[snum] += deltanumbombs; + if (numbombs[snum] > 999) numbombs[snum] = 999; + if (numbombs[snum] <= 0) { + wsayfollow("doh.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); + numbombs[snum] = 0; + } + + if ((snum == screenpeek) && (screensize <= xdim)) { + sprintf(tempbuf,"B:%3d",numbombs[snum]); + printext(8L,(ydim - 28L),tempbuf,ALPHABET,80); + } +} + +void changenummissiles(short snum, short deltanummissiles) { // Andy did this + nummissiles[snum] += deltanummissiles; + if (nummissiles[snum] > 999) nummissiles[snum] = 999; + if (nummissiles[snum] <= 0) { + wsayfollow("doh.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); + nummissiles[snum] = 0; + } + + if ((snum == screenpeek) && (screensize <= xdim)) { + sprintf(tempbuf,"M:%3d",nummissiles[snum]); + printext(8L,(ydim - 20L),tempbuf,ALPHABET,80); + } +} + +void changenumgrabbers(short snum, short deltanumgrabbers) { // Andy did this + numgrabbers[snum] += deltanumgrabbers; + if (numgrabbers[snum] > 999) numgrabbers[snum] = 999; + if (numgrabbers[snum] <= 0) { + wsayfollow("doh.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); + numgrabbers[snum] = 0; + } + + if ((snum == screenpeek) && (screensize <= xdim)) { + sprintf(tempbuf,"G:%3d",numgrabbers[snum]); + printext(8L,(ydim - 12L),tempbuf,ALPHABET,80); + } +} + +static long ostatusflytime = 0x80000000; +void drawstatusflytime(short snum) { // Andy did this + long nstatusflytime; + + if ((snum == screenpeek) && (screensize <= xdim)) { + nstatusflytime = (((flytime[snum] + 119) - lockclock) / 120); + if (nstatusflytime > 1000) nstatusflytime = 1000; + else if (nstatusflytime < 0) nstatusflytime = 0; + if (nstatusflytime != ostatusflytime) { + if (nstatusflytime > 999) sprintf(tempbuf,"FT:BIG"); + else sprintf(tempbuf,"FT:%3ld",nstatusflytime); + printext((xdim - 56L),(ydim - 20L),tempbuf,ALPHABET,80); + ostatusflytime = nstatusflytime; + } + } +} + +void drawstatusbar(short snum) { // Andy did this + long nstatusflytime; + + if ((snum == screenpeek) && (screensize <= xdim)) { + Bsprintf(tempbuf,"Deaths:%d",deaths[snum]); + printext((xdim>>1)-(Bstrlen(tempbuf)<<2),ydim-16,tempbuf,ALPHABET,80); + Bsprintf(tempbuf,"Health:%3ld",health[snum]); + printext((xdim>>1)-(Bstrlen(tempbuf)<<2),ydim-24,tempbuf,ALPHABET,80); + + Bsprintf(tempbuf,"B:%3d",numbombs[snum]); + printext(8L,(ydim - 28L),tempbuf,ALPHABET,80); + Bsprintf(tempbuf,"M:%3d",nummissiles[snum]); + printext(8L,(ydim - 20L),tempbuf,ALPHABET,80); + Bsprintf(tempbuf,"G:%3d",numgrabbers[snum]); + printext(8L,(ydim - 12L),tempbuf,ALPHABET,80); + + nstatusflytime = (((flytime[snum] + 119) - lockclock) / 120); + if (nstatusflytime < 0) { + Bsprintf(tempbuf,"FT: 0"); + ostatusflytime = 0; + } + else if (nstatusflytime > 999) { + Bsprintf(tempbuf,"FT:BIG"); + ostatusflytime = 999; + } + else { + Bsprintf(tempbuf,"FT:%3ld",nstatusflytime); + ostatusflytime = nstatusflytime; + } + printext((xdim - 56L),(ydim - 20L),tempbuf,ALPHABET,80); + } +} + +void prepareboard(char *daboardfilename) +{ + short startwall, endwall, dasector; + long i, j, k=0, s, dax, day, daz, dax2, day2; + + getmessageleng = 0; + typemessageleng = 0; + + randomseed = 17L; + + //Clear (do)animation's list + animatecnt = 0; + typemode = 0; + locselectedgun = 0; + locselectedgun2 = 0; + + if (loadboard(daboardfilename,0,&posx[0],&posy[0],&posz[0],&ang[0],&cursectnum[0]) == -1) + { + musicoff(); + uninitmultiplayers(); + uninittimer(); + uninitinput(); + uninitengine(); + uninitsb(); + uninitgroupfile(); + printf("Board not found\n"); + exit(0); + } else { + char *fp; + + strcpy(tempbuf, daboardfilename); + fp = strrchr(tempbuf,'.'); + if (fp) *fp = 0; + strcat(tempbuf,".mhk"); + + loadmaphack(tempbuf); + } + + setup3dscreen(); + + for(i=0;i dax2) dax2 = wall[j].x; + if (wall[j].y > day2) day2 = wall[j].y; + if (wall[j].lotag == 3) k = j; + } + if (wall[k].x == dax) dragxdir[dragsectorcnt] = -16; + if (wall[k].y == day) dragydir[dragsectorcnt] = -16; + if (wall[k].x == dax2) dragxdir[dragsectorcnt] = 16; + if (wall[k].y == day2) dragydir[dragsectorcnt] = 16; + + dasector = wall[startwall].nextsector; + dragx1[dragsectorcnt] = 0x7fffffff; + dragy1[dragsectorcnt] = 0x7fffffff; + dragx2[dragsectorcnt] = 0x80000000; + dragy2[dragsectorcnt] = 0x80000000; + startwall = sector[dasector].wallptr; + endwall = startwall+sector[dasector].wallnum; + for(j=startwall;j dragx2[dragsectorcnt]) dragx2[dragsectorcnt] = wall[j].x; + if (wall[j].y > dragy2[dragsectorcnt]) dragy2[dragsectorcnt] = wall[j].y; + + setinterpolation(§or[dasector].floorz); + setinterpolation(&wall[j].x); + setinterpolation(&wall[j].y); + setinterpolation(&wall[wall[j].nextwall].x); + setinterpolation(&wall[wall[j].nextwall].y); + } + + dragx1[dragsectorcnt] += (wall[sector[i].wallptr].x-dax); + dragy1[dragsectorcnt] += (wall[sector[i].wallptr].y-day); + dragx2[dragsectorcnt] -= (dax2-wall[sector[i].wallptr].x); + dragy2[dragsectorcnt] -= (day2-wall[sector[i].wallptr].y); + + dragfloorz[dragsectorcnt] = sector[i].floorz; + + dragsectorlist[dragsectorcnt++] = i; + break; + case 13: + startwall = sector[i].wallptr; + endwall = startwall+sector[i].wallnum; + for(j=startwall;j dax2) dax2 = wall[j].x; + if (wall[j].y > day2) day2 = wall[j].y; + } + for(j=startwall;j dax) && (wall[j].y > day) && (wall[j].x < dax2) && (wall[j].y < day2)) + { + subwayx[subwaytrackcnt] = wall[j].x; + } + else + { + subwaystop[subwaytrackcnt][subwaystopcnt[subwaytrackcnt]] = wall[j].x; + subwaystopcnt[subwaytrackcnt]++; + } + } + } + + for(j=1;j subwaytrackx1[subwaytrackcnt]) + if (wall[startwall].y > subwaytracky1[subwaytrackcnt]) + if (wall[startwall].x < subwaytrackx2[subwaytrackcnt]) + if (wall[startwall].y < subwaytracky2[subwaytrackcnt]) + { + if (sector[j].floorz != sector[i].floorz) + { + sector[j].ceilingstat |= 64; + sector[j].floorstat |= 64; + } + subwaytracksector[subwaytrackcnt][subwaynumsectors[subwaytrackcnt]] = j; + subwaynumsectors[subwaytrackcnt]++; + } + } + + subwayvel[subwaytrackcnt] = 64; + subwaypausetime[subwaytrackcnt] = 720; + + startwall = sector[i].wallptr; + endwall = startwall+sector[i].wallnum; + for(k=startwall;k subwaytrackx1[subwaytrackcnt]) + if (wall[k].y > subwaytracky1[subwaytrackcnt]) + if (wall[k].x < subwaytrackx2[subwaytrackcnt]) + if (wall[k].y < subwaytracky2[subwaytrackcnt]) + setinterpolation(&wall[k].x); + + for(j=1;j=0;k=nextspritesect[k]) + if (statrate[sprite[k].statnum] < 0) + setinterpolation(&sprite[k].x); + } + + + subwaytrackcnt++; + break; + } + if (sector[i].floorpicnum == FLOORMIRROR) + floormirrorsector[mirrorcnt++] = i; + //if (sector[i].ceilingpicnum == FLOORMIRROR) floormirrorsector[mirrorcnt++] = i; //SOS + } + + //Scan wall tags + + mirrorcnt = 0; + tilesizx[MIRROR] = 0; + tilesizy[MIRROR] = 0; + for(i=0;i= 0) && (wall[i].overpicnum == MIRROR) && (wall[i].cstat&32)) + { + if ((sector[s].floorstat&1) == 0) + { + wall[i].overpicnum = MIRRORLABEL+mirrorcnt; + sector[s].ceilingpicnum = MIRRORLABEL+mirrorcnt; + sector[s].floorpicnum = MIRRORLABEL+mirrorcnt; + sector[s].floorstat |= 1; + mirrorwall[mirrorcnt] = i; + mirrorsector[mirrorcnt] = s; + mirrorcnt++; + } + else + wall[i].overpicnum = sector[s].ceilingpicnum; + } + } + + //Invalidate textures in sector behind mirror + for(i=0;i=0;i--) copybuf(&sprite[i].x,&osprite[i].x,3); + + searchmap(cursectnum[connecthead]); + + lockclock = 0; + ototalclock = 0; + gotlastpacketclock = 0; + + screensize = xdim; + dax = ((xdim-screensize)>>1); + dax2 = dax+screensize-1; + day = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); + day2 = day + scale(screensize,ydim-32,xdim)-1; + setview(dax,day,dax2,day2); + + startofdynamicinterpolations = numinterpolations; + + /* + for(i=connecthead;i>=0;i=connectpoint2[i]) myminlag[i] = 0; + otherminlag = mymaxlag = 0; + */ +} + +void checktouchsprite(short snum, short sectnum) +{ + long i, nexti; + + if ((sectnum < 0) || (sectnum >= numsectors)) return; + + for(i=headspritesect[sectnum];i>=0;i=nexti) + { + nexti = nextspritesect[i]; + if (sprite[i].cstat&0x8000) continue; + if ((klabs(posx[snum]-sprite[i].x)+klabs(posy[snum]-sprite[i].y) < 512) && (klabs((posz[snum]>>8)-((sprite[i].z>>8)-(tilesizy[sprite[i].picnum]>>1))) <= 40)) + { + switch(sprite[i].picnum) + { + case COIN: + wsayfollow("getstuff.wav",4096L+(krand()&127)-64,192L,&sprite[i].x,&sprite[i].y,0); + changehealth(snum,5); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*60; + changespritestat((short)i,11); + } + break; + case DIAMONDS: + wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + changehealth(snum,15); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*120; + changespritestat((short)i,11); + } + break; + case COINSTACK: + wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + changehealth(snum,25); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*180; + changespritestat((short)i,11); + } + break; + case GIFTBOX: + wsayfollow("getstuff.wav",4096L+(krand()&127)+256-mulscale4(sprite[i].xrepeat,sprite[i].yrepeat),208L,&sprite[i].x,&sprite[i].y,0); + changehealth(snum,max(mulscale8(sprite[i].xrepeat,sprite[i].yrepeat),1)); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 90*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + case CANNON: + wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + if (snum == myconnectindex) keystatus[4] = 1; + changenumbombs(snum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 60*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + case LAUNCHER: + wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + if (snum == myconnectindex) keystatus[5] = 1; + changenummissiles(snum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 90*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + case GRABCANNON: + wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + if (snum == myconnectindex) keystatus[6] = 1; + changenumgrabbers(snum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + case AIRPLANE: + wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + if (flytime[snum] < lockclock) flytime[snum] = lockclock; + flytime[snum] += 60*(sprite[i].xrepeat+sprite[i].yrepeat); + drawstatusflytime(snum); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + } + } + } +} + +void checkgrabbertouchsprite(short snum, short sectnum) // Andy did this +{ + long i, nexti; + short onum; + + if ((sectnum < 0) || (sectnum >= numsectors)) return; + onum = (sprite[snum].owner & (MAXSPRITES - 1)); + + for(i=headspritesect[sectnum];i>=0;i=nexti) + { + nexti = nextspritesect[i]; + if (sprite[i].cstat&0x8000) continue; + if ((klabs(sprite[snum].x-sprite[i].x)+klabs(sprite[snum].y-sprite[i].y) < 512) && (klabs((sprite[snum].z>>8)-((sprite[i].z>>8)-(tilesizy[sprite[i].picnum]>>1))) <= 40)) + { + switch(sprite[i].picnum) + { + case COIN: + wsayfollow("getstuff.wav",4096L+(krand()&127)-64,192L,&sprite[i].x,&sprite[i].y,0); + changehealth(onum,5); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*60; + changespritestat((short)i,11); + } + break; + case DIAMONDS: + wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + changehealth(onum,15); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*120; + changespritestat((short)i,11); + } + break; + case COINSTACK: + wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + changehealth(onum,25); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*180; + changespritestat((short)i,11); + } + break; + case GIFTBOX: + wsayfollow("getstuff.wav",4096L+(krand()&127)+256-mulscale4(sprite[i].xrepeat,sprite[i].yrepeat),208L,&sprite[i].x,&sprite[i].y,0); + changehealth(onum,max(mulscale8(sprite[i].xrepeat,sprite[i].yrepeat),1)); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 90*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + case CANNON: + wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + if (onum == myconnectindex) keystatus[4] = 1; + changenumbombs(onum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 60*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + case LAUNCHER: + wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + if (onum == myconnectindex) keystatus[5] = 1; + changenummissiles(onum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 90*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + case GRABCANNON: + wsayfollow("getstuff.wav",3584L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + if (onum == myconnectindex) keystatus[6] = 1; + changenumgrabbers(onum,((sprite[i].xrepeat+sprite[i].yrepeat)>>1)); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + case AIRPLANE: + wsayfollow("getstuff.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + if (flytime[snum] < lockclock) flytime[snum] = lockclock; + flytime[onum] += 60*(sprite[i].xrepeat+sprite[i].yrepeat); + drawstatusflytime(onum); + if (sprite[i].statnum == 12) deletesprite((short)i); + else { + sprite[i].cstat |= 0x8000; + sprite[i].extra = 120*(sprite[i].xrepeat+sprite[i].yrepeat); + changespritestat((short)i,11); + } + break; + } + } + } +} + +void shootgun(short snum, long x, long y, long z, + short daang, long dahoriz, short dasectnum, char guntype) +{ + short hitsect, hitwall, hitsprite, daang2; + long i, j, daz2, hitx, hity, hitz; + + switch(guntype) + { + case 0: //Shoot chain gun + daang2 = ((daang + (krand()&31)-16)&2047); + daz2 = ((100-dahoriz)*2000) + ((krand()-32768)>>1); + + hitscan(x,y,z,dasectnum, //Start position + sintable[(daang2+512)&2047], //X vector of 3D ang + sintable[daang2&2047], //Y vector of 3D ang + daz2, //Z vector of 3D ang + &hitsect,&hitwall,&hitsprite,&hitx,&hity,&hitz,CLIPMASK1); + + if (wall[hitwall].picnum == KENPICTURE) + { + if (waloff[MAXTILES-1] != 0) wall[hitwall].picnum = MAXTILES-1; + wsayfollow("hello.wav",4096L+(krand()&127)-64,256L,&wall[hitwall].x,&wall[hitwall].y,0); + } + else if (((hitwall < 0) && (hitsprite < 0) && (hitz >= z) && ((sector[hitsect].floorpicnum == SLIME) || (sector[hitsect].floorpicnum == FLOORMIRROR))) || ((hitwall >= 0) && (wall[hitwall].picnum == SLIME))) + { //If you shoot slime, make a splash + wsayfollow("splash.wav",4096L+(krand()&511)-256,256L,&hitx,&hity,0); + spawnsprite(j,hitx,hity,hitz,2,0,0,32,64,64,0,0,SPLASH,daang, + 0,0,0,snum+4096,hitsect,4,63,0,0); //63=time left for splash + } + else + { + wsayfollow("shoot.wav",4096L+(krand()&127)-64,256L,&hitx,&hity,0); + + if ((hitsprite >= 0) && (sprite[hitsprite].statnum < MAXSTATUS)) + switch(sprite[hitsprite].picnum) + { + case BROWNMONSTER: + if (sprite[hitsprite].lotag > 0) sprite[hitsprite].lotag -= 10; + if (sprite[hitsprite].lotag > 0) + { + wsayfollow("hurt.wav",4096L+(krand()&511)-256,256L,&hitx,&hity,0); + if (sprite[hitsprite].lotag <= 25) + sprite[hitsprite].cstat |= 2; + } + else + { + wsayfollow("mondie.wav",4096L+(krand()&127)-64,256L,&hitx,&hity,0); + sprite[hitsprite].z += ((tilesizy[sprite[hitsprite].picnum]*sprite[hitsprite].yrepeat)<<1); + sprite[hitsprite].picnum = GIFTBOX; + sprite[hitsprite].cstat &= ~0x83; //Should not clip, foot-z + changespritestat(hitsprite,12); + + spawnsprite(j,hitx,hity,hitz+(32<<8),0,-4,0,32,64,64, + 0,0,EXPLOSION,daang,0,0,0,snum+4096, + hitsect,5,31,0,0); + } + break; + case EVILAL: + wsayfollow("blowup.wav",4096L+(krand()&127)-64,256L,&hitx,&hity,0); + sprite[hitsprite].picnum = EVILALGRAVE; + sprite[hitsprite].cstat = 0; + sprite[hitsprite].xvel = (krand()&255)-128; + sprite[hitsprite].yvel = (krand()&255)-128; + sprite[hitsprite].zvel = (krand()&4095)-3072; + changespritestat(hitsprite,9); + + spawnsprite(j,hitx,hity,hitz+(32<<8),0,-4,0,32,64,64,0, + 0,EXPLOSION,daang,0,0,0,snum+4096,hitsect,5,31,0,0); + //31=time left for explosion + + break; + case PLAYER: + for(j=connecthead;j>=0;j=connectpoint2[j]) + if (playersprite[j] == hitsprite) + { + wsayfollow("ouch.wav",4096L+(krand()&127)-64,256L,&hitx,&hity,0); + changehealth(j,-10); + break; + } + break; + } + + spawnsprite(j,hitx,hity,hitz+(8<<8),2,-4,0,32,16,16,0,0, + EXPLOSION,daang,0,0,0,snum+4096,hitsect,3,63,0,0); + + //Sprite starts out with center exactly on wall. + //This moves it back enough to see it at all angles. + movesprite((short)j,-(((long)sintable[(512+daang)&2047]*TICSPERFRAME)<<4),-(((long)sintable[daang]*TICSPERFRAME)<<4),0L,4L<<8,4L<<8,CLIPMASK1); + } + break; + case 1: //Shoot silver sphere bullet + spawnsprite(j,x,y,z,1+128,0,0,16,64,64,0,0,BULLET,daang, + sintable[(daang+512)&2047]>>5,sintable[daang&2047]>>5, + (100-dahoriz)<<6,snum+4096,dasectnum,6,0,0,0); + wsayfollow("shoot2.wav",4096L+(krand()&127)-64,128L,&sprite[j].x,&sprite[j].y,1); + break; + case 2: //Shoot bomb + spawnsprite(j,x,y,z,128,0,0,12,16,16,0,0,BOMB,daang, + sintable[(daang+512)&2047]*5>>8,sintable[daang&2047]*5>>8, + (80-dahoriz)<<6,snum+4096,dasectnum,6,0,0,0); + wsayfollow("shoot3.wav",4096L+(krand()&127)-64,192L,&sprite[j].x,&sprite[j].y,1); + break; + case 3: //Shoot missile (Andy did this) + spawnsprite(j,x,y,z,1+128,0,0,16,32,32,0,0,MISSILE,daang, + sintable[(daang+512)&2047]>>4,sintable[daang&2047]>>4, + (100-dahoriz)<<7,snum+4096,dasectnum,6,0,0,0); + wsayfollow("shoot3.wav",4096L+(krand()&127)-64,192L,&sprite[j].x,&sprite[j].y,1); + break; + case 4: //Shoot grabber (Andy did this) + spawnsprite(j,x,y,z,1+128,0,0,16,64,64,0,0,GRABBER,daang, + sintable[(daang+512)&2047]>>5,sintable[daang&2047]>>5, + (100-dahoriz)<<6,snum+4096,dasectnum,6,0,0,0); + wsayfollow("shoot4.wav",4096L+(krand()&127)-64,128L,&sprite[j].x,&sprite[j].y,1); + break; + } +} + +#define MAXVOXMIPS 5 +extern char *voxoff[][MAXVOXMIPS]; +void analyzesprites(long dax, long day) +{ + long i, j=0, k, *intptr; + point3d *ospr; + spritetype *tspr; + + //This function is called between drawrooms() and drawmasks() + //It has a list of possible sprites that may be drawn on this frame + + for(i=0,tspr=&tsprite[0];ipicnum] >= 0) + switch(tspr->picnum) + { + case PLAYER: + // //Get which of the 8 angles of the sprite to draw (0-7) + // //k ranges from 0-7 + //k = getangle(tspr->x-dax,tspr->y-day); + //k = (((tspr->ang+3072+128-k)&2047)>>8)&7; + // //This guy has only 5 pictures for 8 angles (3 are x-flipped) + //if (k <= 4) + //{ + // tspr->picnum += (k<<2); + // tspr->cstat &= ~4; //clear x-flipping bit + //} + //else + //{ + // tspr->picnum += ((8-k)<<2); + // tspr->cstat |= 4; //set x-flipping bit + //} + + if ((tspr->cstat&2) == 0) + { + //tspr->cstat |= 48; tspr->picnum = tiletovox[tspr->picnum]; + intptr = (long *)voxoff[ tiletovox[PLAYER] ][0]; + tspr->xrepeat = scale(tspr->xrepeat,56,intptr[2]); + tspr->yrepeat = scale(tspr->yrepeat,56,intptr[2]); + tspr->shade -= 6; + } + break; + case BROWNMONSTER: + //tspr->cstat |= 48; tspr->picnum = tiletovox[tspr->picnum]; + break; + } +#endif + + k = statrate[tspr->statnum]; + if (k >= 0) //Interpolate moving sprite + { + ospr = &osprite[tspr->owner]; + switch(k) + { + case 0: j = smoothratio; break; + case 1: j = (smoothratio>>1)+(((nummoves-tspr->owner)&1)<<15); break; + case 3: j = (smoothratio>>2)+(((nummoves-tspr->owner)&3)<<14); break; + case 7: j = (smoothratio>>3)+(((nummoves-tspr->owner)&7)<<13); break; + case 15: j = (smoothratio>>4)+(((nummoves-tspr->owner)&15)<<12); break; + } + k = tspr->x-ospr->x; tspr->x = ospr->x; + if (k != 0) tspr->x += mulscale16(k,j); + k = tspr->y-ospr->y; tspr->y = ospr->y; + if (k != 0) tspr->y += mulscale16(k,j); + k = tspr->z-ospr->z; tspr->z = ospr->z; + if (k != 0) tspr->z += mulscale16(k,j); + } + + //Don't allow close explosion sprites to be transluscent + k = tspr->statnum; + if ((k == 3) || (k == 4) || (k == 5) || (k == 7)) + if (klabs(dax-tspr->x) < 256) + if (klabs(day-tspr->y) < 256) + tspr->cstat &= ~2; + + tspr->shade += 6; + if (sector[tspr->sectnum].ceilingstat&1) + tspr->shade += sector[tspr->sectnum].ceilingshade; + else + tspr->shade += sector[tspr->sectnum].floorshade; + } +} + +void tagcode(void) +{ + long i, nexti, j, k, l, s, dax, day, daz, dax2, day2, cnt, good; + short startwall, endwall, dasector, p, oldang; + + for(p=connecthead;p>=0;p=connectpoint2[p]) + { + if (sector[cursectnum[p]].lotag == 1) + { + activatehitag(sector[cursectnum[p]].hitag); + sector[cursectnum[p]].lotag = 0; + sector[cursectnum[p]].hitag = 0; + } + if ((sector[cursectnum[p]].lotag == 2) && (cursectnum[p] != ocursectnum[p])) + activatehitag(sector[cursectnum[p]].hitag); + } + + for(i=0;i>2); + if (j >= 16) j = 31-j; + { + sector[dasector].ceilingshade = j; + sector[dasector].floorshade = j; + startwall = sector[dasector].wallptr; + endwall = startwall+sector[dasector].wallnum; + for(s=startwall;s=0;p=connectpoint2[p]) + if (sector[cursectnum[p]].lotag == 10) //warp sector + { + if (cursectnum[p] != ocursectnum[p]) + { + warpsprite(playersprite[p]); + posx[p] = sprite[playersprite[p]].x; + posy[p] = sprite[playersprite[p]].y; + posz[p] = sprite[playersprite[p]].z; + ang[p] = sprite[playersprite[p]].ang; + cursectnum[p] = sprite[playersprite[p]].sectnum; + + sprite[playersprite[p]].z += EYEHEIGHT; + + //warp(&posx[p],&posy[p],&posz[p],&ang[p],&cursectnum[p]); + //Update sprite representation of player + //setsprite(playersprite[p],posx[p],posy[p],posz[p]+EYEHEIGHT); + //sprite[playersprite[p]].ang = ang[p]; + } + } + + for(i=0;i>2)&255); + } + + for(i=0;i>2)&255); + sector[floorpanninglist[i]].floorypanning = ((lockclock>>2)&255); + } + + for(i=0;i dragx2[i]) dragxdir[i] = -16; + if (wall[startwall].y+dragydir[i] > dragy2[i]) dragydir[i] = -16; + + for(j=startwall;j>3); + + for(p=connecthead;p>=0;p=connectpoint2[p]) + if (cursectnum[p] == dasector) + { + posx[p] += dragxdir[i]; + posy[p] += dragydir[i]; + if (p == myconnectindex) + { myx += dragxdir[i]; myy += dragydir[i]; } + //posz[p] += (sector[dasector].floorz-j); + + //Update sprite representation of player + setsprite(playersprite[p],posx[p],posy[p],posz[p]+EYEHEIGHT); + sprite[playersprite[p]].ang = ang[p]; + } + } + + for(i=0;i=0;p=connectpoint2[p]) + if ((cursectnum[p] == swingsector[i]) || (testneighborsectors(cursectnum[p],swingsector[i]) == 1)) + { + cnt = 256; + do + { + good = 1; + + //swingangopendir is -1 if forwards, 1 is backwards + l = (swingangopendir[i] > 0); + for(k=l+3;k>=l;k--) + if (clipinsidebox(posx[p],posy[p],swingwall[i][k],128L) != 0) + { + good = 0; + break; + } + if (good == 0) + { + if (cnt == 256) + { + swinganginc[i] = -swinganginc[i]; + swingang[i] = oldang; + } + else + { + swingang[i] = ((swingang[i]-swinganginc[i])&2047); + } + for(k=1;k<=3;k++) + rotatepoint(swingx[i][0],swingy[i][0],swingx[i][k],swingy[i][k],swingang[i],&wall[swingwall[i][k]].x,&wall[swingwall[i][k]].y); + if (swingang[i] == swingangclosed[i]) + { + wsayfollow("closdoor.wav",4096L+(krand()&511)-256,256L,&swingx[i][0],&swingy[i][0],0); + swinganginc[i] = 0; + break; + } + if (swingang[i] == swingangopen[i]) + { + swinganginc[i] = 0; + break; + } + cnt--; + } + } while ((good == 0) && (cnt > 0)); + } + } + } + if (swinganginc[i] == 0) + for(j=1;j<=3;j++) + { + stopinterpolation(&wall[swingwall[i][j]].x); + stopinterpolation(&wall[swingwall[i][j]].y); + } + } + + for(i=0;i 2)) + { + dasector = subwaytracksector[i][0]; + startwall = sector[dasector].wallptr; + endwall = startwall+sector[dasector].wallnum; + for(k=startwall;k subwaytrackx1[i]) + if (wall[k].y > subwaytracky1[i]) + if (wall[k].x < subwaytrackx2[i]) + if (wall[k].y < subwaytracky2[i]) + wall[k].x += subwayvel[i]; + + for(j=1;j=0;s=nextspritesect[s]) + sprite[s].x += subwayvel[i]; + } + + for(p=connecthead;p>=0;p=connectpoint2[p]) + if (cursectnum[p] != subwaytracksector[i][0]) + if (sector[cursectnum[p]].floorz != sector[subwaytracksector[i][0]].floorz) + if (posx[p] > subwaytrackx1[i]) + if (posy[p] > subwaytracky1[i]) + if (posx[p] < subwaytrackx2[i]) + if (posy[p] < subwaytracky2[i]) + { + posx[p] += subwayvel[i]; + if (p == myconnectindex) + { myx += subwayvel[i]; } + + //Update sprite representation of player + setsprite(playersprite[p],posx[p],posy[p],posz[p]+EYEHEIGHT); + sprite[playersprite[p]].ang = ang[p]; + } + + subwayx[i] += subwayvel[i]; + } + + j = subwayvel[i]; + k = subwaystop[i][subwaygoalstop[i]] - subwayx[i]; + if (k > 0) + { + if (k > 4096) + { + if (subwayvel[i] < 256) subwayvel[i]++; + } + else + subwayvel[i] = (k>>4)+1; + } + else if (k < 0) + { + if (k < -4096) + { + if (subwayvel[i] > -256) subwayvel[i]--; + } + else + subwayvel[i] = (k>>4)-1; + } + if ((j < 0) && (subwayvel[i] >= 0)) subwayvel[i] = -1; + if ((j > 0) && (subwayvel[i] <= 0)) subwayvel[i] = 1; + + if ((subwayvel[i] <= 2) && (subwayvel[i] >= -2) && (klabs(k) < 2048)) + { + //Open / close doors + if ((subwaypausetime[i] == 720) || ((subwaypausetime[i] >= 120) && (subwaypausetime[i]-TICSPERFRAME < 120))) + activatehitag(sector[subwaytracksector[i][0]].hitag); + + subwaypausetime[i] -= TICSPERFRAME; + if (subwaypausetime[i] < 0) + { + subwaypausetime[i] = 720; + if (subwayvel[i] < 0) + { + subwaygoalstop[i]--; + if (subwaygoalstop[i] < 0) + { + subwaygoalstop[i] = 1; + subwayvel[i] = 1; + } + } + else if (subwayvel[i] > 0) + { + subwaygoalstop[i]++; + if (subwaygoalstop[i] >= subwaystopcnt[i]) + { + subwaygoalstop[i] = subwaystopcnt[i]-2; + subwayvel[i] = -1; + } + } + } + } + } +} + +void statuslistcode(void) +{ + short p, target, hitobject, daang, osectnum, movestat; + long i, nexti, j, nextj, k, l, dax, day, daz, dist, ox, oy, mindist; + long doubvel, xvect, yvect; + + //Go through active BROWNMONSTER list + for(i=headspritestat[1];i>=0;i=nexti) + { + nexti = nextspritestat[i]; + + k = krand(); + + //Choose a target player + mindist = 0x7fffffff; target = connecthead; + for(p=connecthead;p>=0;p=connectpoint2[p]) + { + dist = klabs(sprite[i].x-posx[p])+klabs(sprite[i].y-posy[p]); + if (dist < mindist) mindist = dist, target = p; + } + + //brown monster decides to shoot bullet + if ((k&63) == 23) + { + if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[target],posy[target],posz[target],cursectnum[target]) == 0) + { + if ((k&0xf00) == 0xb00) changespritestat(i,2); + } + else + { + wsayfollow("monshoot.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1); + + doubvel = (TICSPERFRAME<<((ssync[target].bits&256)>0)); + xvect = 0, yvect = 0; + if (ssync[target].fvel != 0) + { + xvect += ((((long)ssync[target].fvel)*doubvel*(long)sintable[(ang[target]+512)&2047])>>3); + yvect += ((((long)ssync[target].fvel)*doubvel*(long)sintable[ang[target]&2047])>>3); + } + if (ssync[target].svel != 0) + { + xvect += ((((long)ssync[target].svel)*doubvel*(long)sintable[ang[target]&2047])>>3); + yvect += ((((long)ssync[target].svel)*doubvel*(long)sintable[(ang[target]+1536)&2047])>>3); + } + + ox = posx[target]; oy = posy[target]; + + //distance is j + j = ksqrt((ox-sprite[i].x)*(ox-sprite[i].x)+(oy-sprite[i].y)*(oy-sprite[i].y)); + + switch((sprite[i].extra>>11)&3) + { + case 1: j = -(j>>1); break; + case 3: j = 0; break; + case 0: case 2: break; + } + sprite[i].extra += 2048; + + //rate is (TICSPERFRAME<<19) + xvect = scale(xvect,j,TICSPERFRAME<<19); + yvect = scale(yvect,j,TICSPERFRAME<<19); + clipmove(&ox,&oy,&posz[target],&cursectnum[target],xvect<<14,yvect<<14,128L,4<<8,4<<8,CLIPMASK0); + ox -= sprite[i].x; + oy -= sprite[i].y; + + daang = ((getangle(ox,oy)+(krand()&7)-4)&2047); + + dax = (sintable[(daang+512)&2047]>>6); + day = (sintable[daang&2047]>>6); + daz = 0; + if (ox != 0) + daz = scale(dax,posz[target]+(8<<8)-sprite[i].z,ox); + else if (oy != 0) + daz = scale(day,posz[target]+(8<<8)-sprite[i].z,oy); + + spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z,128,0,0, + 16,sprite[i].xrepeat,sprite[i].yrepeat,0,0,BULLET,daang,dax,day,daz,i,sprite[i].sectnum,6,0,0,0); + + sprite[i].extra &= (~2047); + } + } + + //Move brown monster + dax = sprite[i].x; //Back up old x&y if stepping off cliff + day = sprite[i].y; + + doubvel = max(mulscale7(sprite[i].xrepeat,sprite[i].yrepeat),4); + + osectnum = sprite[i].sectnum; + movestat = movesprite((short)i,(long)sintable[(sprite[i].ang+512)&2047]*doubvel,(long)sintable[sprite[i].ang]*doubvel,0L,4L<<8,4L<<8,CLIPMASK0); + if (globloz > sprite[i].z+(48<<8)) + { sprite[i].x = dax; sprite[i].y = day; movestat = 1; } + else + sprite[i].z = globloz-((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1); + + if ((sprite[i].sectnum != osectnum) && (sector[sprite[i].sectnum].lotag == 10)) + { warpsprite((short)i); movestat = 0; } + + if ((movestat != 0) || ((k&63) == 1)) + { + if (sprite[i].ang == (sprite[i].extra&2047)) + { + daang = (getangle(posx[target]-sprite[i].x,posy[target]-sprite[i].y)&2047); + daang = ((daang+(krand()&1023)-512)&2047); + sprite[i].extra = ((sprite[i].extra&(~2047))|daang); + } + if ((sprite[i].extra-sprite[i].ang)&1024) + { + sprite[i].ang = ((sprite[i].ang-32)&2047); + if (!((sprite[i].extra-sprite[i].ang)&1024)) sprite[i].ang = (sprite[i].extra&2047); + } + else + { + sprite[i].ang = ((sprite[i].ang+32)&2047); + if (((sprite[i].extra-sprite[i].ang)&1024)) sprite[i].ang = (sprite[i].extra&2047); + } + } + } + + for(i=headspritestat[10];i>=0;i=nexti) //EVILAL list + { + nexti = nextspritestat[i]; + + if (sprite[i].yrepeat < 38) continue; + if (sprite[i].yrepeat < 64) + { + sprite[i].xrepeat++; + sprite[i].yrepeat++; + continue; + } + + if ((nummoves-i)&statrate[10]) continue; + + //Choose a target player + mindist = 0x7fffffff; target = connecthead; + for(p=connecthead;p>=0;p=connectpoint2[p]) + { + dist = klabs(sprite[i].x-posx[p])+klabs(sprite[i].y-posy[p]); + if (dist < mindist) mindist = dist, target = p; + } + + k = (krand()&255); + + if ((sprite[i].lotag&32) && (k < 48)) //Al decides to reproduce + { + l = 0; + if ((sprite[i].lotag&64) && (k < 2)) //Give him a chance to reproduce without seeing you + l = 1; + else if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[target],posy[target],posz[target],cursectnum[target]) == 1) + l = 1; + if (l != 0) + { + spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].cstat,sprite[i].shade,sprite[i].pal, + sprite[i].clipdist,38,38,sprite[i].xoffset,sprite[i].yoffset,sprite[i].picnum,krand()&2047,0,0,0,i, + sprite[i].sectnum,10,sprite[i].lotag,sprite[i].hitag,sprite[i].extra); + switch(krand()&31) //Mutations! + { + case 0: sprite[i].cstat ^= 2; break; + case 1: sprite[i].cstat ^= 512; break; + case 2: sprite[i].shade++; break; + case 3: sprite[i].shade--; break; + case 4: sprite[i].pal ^= 16; break; + case 5: case 6: case 7: sprite[i].lotag ^= (1<<(krand()&7)); break; + case 8: sprite[i].lotag = (krand()&255); break; + } + } + } + if (k >= 208+((sprite[i].lotag&128)>>2)) //Al decides to shoot bullet + { + if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[target],posy[target],posz[target],cursectnum[target]) == 1) + { + wsayfollow("zipguns.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1); + + spawnsprite(j,sprite[i].x,sprite[i].y, + sector[sprite[i].sectnum].floorz-(24<<8), + 0,0,0,16,32,32,0,0,BULLET, + (getangle(posx[target]-sprite[j].x, + posy[target]-sprite[j].y)+(krand()&15)-8)&2047, + sintable[(sprite[j].ang+512)&2047]>>6, + sintable[sprite[j].ang&2047]>>6, + ((posz[target]+(8<<8)-sprite[j].z)<<8) / + (ksqrt((posx[target]-sprite[j].x) * + (posx[target]-sprite[j].x) + + (posy[target]-sprite[j].y) * + (posy[target]-sprite[j].y))+1), + i,sprite[i].sectnum,6,0,0,0); + } + } + + //Move Al + l = (((sprite[i].lotag&3)+2)<<8); + if (sprite[i].lotag&4) l = -l; + dax = sintable[(sprite[i].ang+512)&2047]*l; + day = sintable[sprite[i].ang]*l; + + osectnum = sprite[i].sectnum; + movestat = movesprite((short)i,dax,day,0L,-8L<<8,-8L<<8,CLIPMASK0); + sprite[i].z = globloz; + if ((sprite[i].sectnum != osectnum) && (sector[sprite[i].sectnum].lotag == 10)) + { + warpsprite((short)i); + movestat = 0; + } + + if (sprite[i].lotag&16) + { + if (((k&124) >= 120) && (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[target],posy[target],posz[target],cursectnum[target]) == 1)) + sprite[i].ang = getangle(posx[target]-sprite[i].x,posy[target]-sprite[i].y); + else + sprite[i].ang = (krand()&2047); + } + + if (movestat != 0) + { + if ((k&2) && (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[target],posy[target],posz[target],cursectnum[target]) == 1)) + sprite[i].ang = getangle(posx[target]-sprite[i].x,posy[target]-sprite[i].y); + else + sprite[i].ang = (krand()&2047); + + if ((movestat&49152) == 49152) + if (sprite[movestat&16383].picnum == EVILAL) + if ((k&31) >= 30) + { + wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + sprite[i].picnum = EVILALGRAVE; + sprite[i].cstat = 0; + sprite[i].xvel = (krand()&255)-128; + sprite[i].yvel = (krand()&255)-128; + sprite[i].zvel = (krand()&4095)-3072; + changespritestat(i,9); + } + + if (sprite[i].lotag&8) + if ((k&31) >= 30) + { + wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + sprite[i].picnum = EVILALGRAVE; + sprite[i].cstat = 0; + sprite[i].xvel = (krand()&255)-128; + sprite[i].yvel = (krand()&255)-128; + sprite[i].zvel = (krand()&4095)-3072; + changespritestat(i,9); + } + + if (movestat == -1) + { + wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + sprite[i].picnum = EVILALGRAVE; + sprite[i].cstat = 0; + sprite[i].xvel = (krand()&255)-128; + sprite[i].yvel = (krand()&255)-128; + sprite[i].zvel = (krand()&4095)-3072; + changespritestat(i,9); + } + } + } + + //Go through travelling bullet sprites + for(i=headspritestat[6];i>=0;i=nexti) + { + nexti = nextspritestat[i]; + + if ((nummoves-i)&statrate[6]) continue; + + //If the sprite is a bullet then... + if ((sprite[i].picnum == BULLET) || (sprite[i].picnum == GRABBER) || (sprite[i].picnum == MISSILE) || (sprite[i].picnum == BOMB)) + { + dax = ((((long)sprite[i].xvel)*TICSPERFRAME)<<12); + day = ((((long)sprite[i].yvel)*TICSPERFRAME)<<12); + daz = ((((long)sprite[i].zvel)*TICSPERFRAME)>>2); + if (sprite[i].picnum == BOMB) daz = 0; + + osectnum = sprite[i].sectnum; + hitobject = movesprite((short)i,dax,day,daz,4L<<8,4L<<8,CLIPMASK1); + if ((sprite[i].sectnum != osectnum) && (sector[sprite[i].sectnum].lotag == 10)) + { + warpsprite((short)i); + hitobject = 0; + } + + if (sprite[i].picnum == GRABBER) { // Andy did this (& Ken) !Homing! + checkgrabbertouchsprite(i,sprite[i].sectnum); + l = 0x7fffffff; + for (j = connecthead; j >= 0; j = connectpoint2[j]) // Players + if (j != (sprite[i].owner & (MAXSPRITES - 1))) + if (cansee(sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].sectnum,posx[j],posy[j],posz[j],cursectnum[j])) { + k = ksqrt(sqr(posx[j] - sprite[i].x) + sqr(posy[j] - sprite[i].y) + (sqr(posz[j] - sprite[i].z) >> 8)); + if (k < l) { + l = k; + dax = (posx[j] - sprite[i].x); + day = (posy[j] - sprite[i].y); + daz = (posz[j] - sprite[i].z); + } + } + for(j = headspritestat[1]; j >= 0; j = nextj) { // Active monsters + nextj = nextspritestat[j]; + if (cansee(sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].sectnum,sprite[j].x,sprite[j].y,sprite[j].z,sprite[j].sectnum)) { + k = ksqrt(sqr(sprite[j].x - sprite[i].x) + sqr(sprite[j].y - sprite[i].y) + (sqr(sprite[j].z - sprite[i].z) >> 8)); + if (k < l) { + l = k; + dax = (sprite[j].x - sprite[i].x); + day = (sprite[j].y - sprite[i].y); + daz = (sprite[j].z - sprite[i].z); + } + } + } + for(j = headspritestat[2]; j >= 0; j = nextj) { // Inactive monsters + nextj = nextspritestat[j]; + if (cansee(sprite[i].x,sprite[i].y,sprite[i].z,sprite[i].sectnum,sprite[j].x,sprite[j].y,sprite[j].z,sprite[j].sectnum)) { + k = ksqrt(sqr(sprite[j].x - sprite[i].x) + sqr(sprite[j].y - sprite[i].y) + (sqr(sprite[j].z - sprite[i].z) >> 8)); + if (k < l) { + l = k; + dax = (sprite[j].x - sprite[i].x); + day = (sprite[j].y - sprite[i].y); + daz = (sprite[j].z - sprite[i].z); + } + } + } + if (l != 0x7fffffff) { + sprite[i].xvel = (divscale7(dax,l) + sprite[i].xvel); // 1/5 of velocity is homing, 4/5 is momentum + sprite[i].yvel = (divscale7(day,l) + sprite[i].yvel); // 1/5 of velocity is homing, 4/5 is momentum + sprite[i].zvel = (divscale7(daz,l) + sprite[i].zvel); // 1/5 of velocity is homing, 4/5 is momentum + l = ksqrt((sprite[i].xvel * sprite[i].xvel) + (sprite[i].yvel * sprite[i].yvel) + ((sprite[i].zvel * sprite[i].zvel) >> 8)); + sprite[i].xvel = divscale9(sprite[i].xvel,l); + sprite[i].yvel = divscale9(sprite[i].yvel,l); + sprite[i].zvel = divscale9(sprite[i].zvel,l); + sprite[i].ang = getangle(sprite[i].xvel,sprite[i].yvel); + } + } + + if (sprite[i].picnum == BOMB) + { + j = sprite[i].sectnum; + if ((sector[j].floorstat&2) && (sprite[i].z > globloz-(8<<8))) + { + k = sector[j].wallptr; + daang = getangle(wall[wall[k].point2].x-wall[k].x,wall[wall[k].point2].y-wall[k].y); + sprite[i].xvel += mulscale22(sintable[(daang+1024)&2047],sector[j].floorheinum); + sprite[i].yvel += mulscale22(sintable[(daang+512)&2047],sector[j].floorheinum); + } + } + + if (sprite[i].picnum == BOMB) + { + sprite[i].z += sprite[i].zvel; + sprite[i].zvel += (TICSPERFRAME<<7); + if (sprite[i].z < globhiz+(tilesizy[BOMB]<<6)) + { + sprite[i].z = globhiz+(tilesizy[BOMB]<<6); + sprite[i].zvel = -(sprite[i].zvel>>1); + } + if (sprite[i].z > globloz-(tilesizy[BOMB]<<6)) + { + sprite[i].z = globloz-(tilesizy[BOMB]<<6); + sprite[i].zvel = -(sprite[i].zvel>>1); + } + dax = sprite[i].xvel; day = sprite[i].yvel; + dist = dax*dax+day*day; + if (dist < 512) + { + bombexplode(i); + goto bulletisdeletedskip; + } + if (dist < 4096) + { + sprite[i].xrepeat = ((4096+2048)*16) / (dist+2048); + sprite[i].yrepeat = sprite[i].xrepeat; + sprite[i].xoffset = (krand()&15)-8; + sprite[i].yoffset = (krand()&15)-8; + } + if (mulscale30(krand(),dist) == 0) + { + sprite[i].xvel -= ksgn(sprite[i].xvel); + sprite[i].yvel -= ksgn(sprite[i].yvel); + sprite[i].zvel -= ksgn(sprite[i].zvel); + } + } + + //Check for bouncy objects before killing bullet + if ((hitobject&0xc000) == 16384) //Bullet hit a ceiling/floor + { + k = sector[hitobject&(MAXSECTORS-1)].wallptr; l = wall[k].point2; + daang = getangle(wall[l].x-wall[k].x,wall[l].y-wall[k].y); + + getzsofslope(hitobject&(MAXSECTORS-1),sprite[i].x,sprite[i].y,&k,&l); + if (sprite[i].z < ((k+l)>>1)) k = sector[hitobject&(MAXSECTORS-1)].ceilingheinum; + else k = sector[hitobject&(MAXSECTORS-1)].floorheinum; + + dax = mulscale14(k,sintable[(daang)&2047]); + day = mulscale14(k,sintable[(daang+1536)&2047]); + daz = 4096; + + k = sprite[i].xvel*dax+sprite[i].yvel*day+mulscale4(sprite[i].zvel,daz); + l = dax*dax+day*day+daz*daz; + if ((klabs(k)>>14) < l) + { + k = divscale17(k,l); + sprite[i].xvel -= mulscale16(dax,k); + sprite[i].yvel -= mulscale16(day,k); + sprite[i].zvel -= mulscale12(daz,k); + } + wsayfollow("bouncy.wav",4096L+(krand()&127)-64,255,&sprite[i].x,&sprite[i].y,1); + hitobject = 0; + sprite[i].owner = -1; //Bullet turns evil! + } + else if ((hitobject&0xc000) == 32768) //Bullet hit a wall + { + if (wall[hitobject&4095].lotag == 8) + { + dax = sprite[i].xvel; day = sprite[i].yvel; + if ((sprite[i].picnum != BOMB) || (dax*dax+day*day >= 512)) + { + k = (hitobject&4095); l = wall[k].point2; + j = getangle(wall[l].x-wall[k].x,wall[l].y-wall[k].y)+512; + + //k = cos(ang) * sin(ang) * 2 + k = mulscale13(sintable[(j+512)&2047],sintable[j&2047]); + //l = cos(ang * 2) + l = sintable[((j<<1)+512)&2047]; + + ox = sprite[i].xvel; oy = sprite[i].yvel; + dax = -ox; day = -oy; + sprite[i].xvel = dmulscale14(day,k,dax,l); + sprite[i].yvel = dmulscale14(dax,k,-day,l); + + if (sprite[i].picnum == BOMB) + { + sprite[i].xvel -= (sprite[i].xvel>>3); + sprite[i].yvel -= (sprite[i].yvel>>3); + sprite[i].zvel -= (sprite[i].zvel>>3); + } + ox -= sprite[i].xvel; oy -= sprite[i].yvel; + dist = ((ox*ox+oy*oy)>>8); + wsayfollow("bouncy.wav",4096L+(krand()&127)-64,min(dist,256),&sprite[i].x,&sprite[i].y,1); + hitobject = 0; + sprite[i].owner = -1; //Bullet turns evil! + } + } + } + else if ((hitobject&0xc000) == 49152) //Bullet hit a sprite + { + if (sprite[hitobject&4095].picnum == BOUNCYMAT) + { + if ((sprite[hitobject&4095].cstat&48) == 0) + { + sprite[i].xvel = -sprite[i].xvel; + sprite[i].yvel = -sprite[i].yvel; + sprite[i].zvel = -sprite[i].zvel; + dist = 255; + } + else if ((sprite[hitobject&4095].cstat&48) == 16) + { + j = sprite[hitobject&4095].ang; + + //k = cos(ang) * sin(ang) * 2 + k = mulscale13(sintable[(j+512)&2047],sintable[j&2047]); + //l = cos(ang * 2) + l = sintable[((j<<1)+512)&2047]; + + ox = sprite[i].xvel; oy = sprite[i].yvel; + dax = -ox; day = -oy; + sprite[i].xvel = dmulscale14(day,k,dax,l); + sprite[i].yvel = dmulscale14(dax,k,-day,l); + + ox -= sprite[i].xvel; oy -= sprite[i].yvel; + dist = ((ox*ox+oy*oy)>>8); + } + sprite[i].owner = -1; //Bullet turns evil! + wsayfollow("bouncy.wav",4096L+(krand()&127)-64,min(dist,256),&sprite[i].x,&sprite[i].y,1); + hitobject = 0; + } + } + + if (hitobject != 0) + { + if ((sprite[i].picnum == MISSILE) || (sprite[i].picnum == BOMB)) + { + if ((hitobject&0xc000) == 49152) + if (sprite[hitobject&4095].lotag == 5) //Basketball hoop + { + wsayfollow("niceshot.wav",3840L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + deletesprite((short)i); + goto bulletisdeletedskip; + } + + bombexplode(i); + goto bulletisdeletedskip; + } + + if ((hitobject&0xc000) == 16384) //Hits a ceiling / floor + { + wsayfollow("bullseye.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + deletesprite((short)i); + goto bulletisdeletedskip; + } + else if ((hitobject&0xc000) == 32768) //Bullet hit a wall + { + if (wall[hitobject&4095].picnum == KENPICTURE) + { + if (waloff[MAXTILES-1] != 0) + wall[hitobject&4095].picnum = MAXTILES-1; + wsayfollow("hello.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); //Ken says, "Hello... how are you today!" + } + else + wsayfollow("bullseye.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + + deletesprite((short)i); + goto bulletisdeletedskip; + } + else if ((hitobject&0xc000) == 49152) //Bullet hit a sprite + { + if ((sprite[hitobject&4095].lotag == 5) && (sprite[i].picnum == GRABBER)) { // Basketball hoop (Andy's addition) + wsayfollow("niceshot.wav",3840L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + switch (krand() & 63) { + case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: + sprite[i].picnum = COIN; break; + case 10: case 11: case 12: case 13: case 14: case 15: case 16: + sprite[i].picnum = DIAMONDS; break; + case 17: case 18: case 19: + sprite[i].picnum = COINSTACK; break; + case 20: case 21: case 22: case 23: + sprite[i].picnum = GIFTBOX; break; + case 24: case 25: + sprite[i].picnum = GRABCANNON; break; + case 26: case 27: + sprite[i].picnum = LAUNCHER; break; + case 28: case 29: case 30: + sprite[i].picnum = CANNON; break; + case 31: + sprite[i].picnum = AIRPLANE; break; + default: + deletesprite((short)i); + goto bulletisdeletedskip; + } + sprite[i].xvel = sprite[i].yvel = sprite[i].zvel = 0; + sprite[i].cstat &= ~0x83; //Should not clip, foot-z + changespritestat(i,12); + goto bulletisdeletedskip; + } + + //Check if bullet hit a player & find which player it was... + if (sprite[hitobject&4095].picnum == PLAYER) + for(j=connecthead;j>=0;j=connectpoint2[j]) + if (sprite[i].owner != j+4096) + if (playersprite[j] == (hitobject&4095)) + { + wsayfollow("ouch.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + if (sprite[i].picnum == GRABBER) { // Andy did this + k = ((sprite[i].xrepeat * sprite[i].yrepeat) * 3) >> 9; + changehealth((sprite[i].owner - 4096),k); + changehealth(j,-k); + } + else changehealth(j,-mulscale8(sprite[i].xrepeat,sprite[i].yrepeat)); + deletesprite((short)i); + goto bulletisdeletedskip; + } + + //Check if bullet hit any monsters... + j = (hitobject&4095); //j is the spritenum that the bullet (spritenum i) hit + if (sprite[i].owner != j) + { + switch(sprite[j].picnum) + { + case BROWNMONSTER: + if (sprite[j].lotag > 0) { + if (sprite[i].picnum == GRABBER) { // Andy did this + k = ((sprite[i].xrepeat * sprite[i].yrepeat) * 3) >> 9; + changehealth((sprite[i].owner - 4096),k); + sprite[j].lotag -= k; + } + sprite[j].lotag -= mulscale8(sprite[i].xrepeat,sprite[i].yrepeat); + } + if (sprite[j].lotag > 0) + { + if (sprite[j].lotag <= 25) sprite[j].cstat |= 2; + wsayfollow("hurt.wav",4096L+(krand()&511)-256,256L,&sprite[i].x,&sprite[i].y,1); + } + else + { + wsayfollow("mondie.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + sprite[j].z += ((tilesizy[sprite[j].picnum]*sprite[j].yrepeat)<<1); + sprite[j].picnum = GIFTBOX; + sprite[j].cstat &= ~0x83; //Should not clip, foot-z + + spawnsprite(k,sprite[j].x,sprite[j].y,sprite[j].z, + 0,-4,0,32,64,64,0,0,EXPLOSION,sprite[j].ang, + 0,0,0,j,sprite[j].sectnum,5,31,0,0); + //31=Time left for explosion to stay + + changespritestat(j,12); + } + deletesprite((short)i); + goto bulletisdeletedskip; + case EVILAL: + wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + sprite[j].picnum = EVILALGRAVE; + sprite[j].cstat = 0; + sprite[j].xvel = (krand()&255)-128; + sprite[j].yvel = (krand()&255)-128; + sprite[j].zvel = (krand()&4095)-3072; + changespritestat(j,9); + + deletesprite((short)i); + goto bulletisdeletedskip; + case AL: + wsayfollow("blowup.wav",5144L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + sprite[j].xrepeat += 2; + sprite[j].yrepeat += 2; + if (sprite[j].yrepeat >= 38) + { + sprite[j].picnum = EVILAL; + //sprite[j].cstat |= 2; //Make him transluscent + changespritestat(j,10); + } + deletesprite((short)i); + goto bulletisdeletedskip; + default: + wsayfollow("bullseye.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + deletesprite((short)i); + goto bulletisdeletedskip; + } + } + } + } + } +bulletisdeletedskip: continue; + } + + //Go through monster waiting for you list + for(i=headspritestat[2];i>=0;i=nexti) + { + nexti = nextspritestat[i]; + + if ((nummoves-i)&15) continue; + + //Use dot product to see if monster's angle is towards a player + for(p=connecthead;p>=0;p=connectpoint2[p]) + if (sintable[(sprite[i].ang+512)&2047]*(posx[p]-sprite[i].x) + sintable[sprite[i].ang&2047]*(posy[p]-sprite[i].y) >= 0) + if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[p],posy[p],posz[p],cursectnum[p]) == 1) + { + changespritestat(i,1); + //if (sprite[i].lotag == 100) + //{ + wsayfollow("iseeyou.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1); + // sprite[i].lotag = 99; + //} + } + } + + //Go through smoke sprites + for(i=headspritestat[3];i>=0;i=nexti) + { + nexti = nextspritestat[i]; + + sprite[i].z -= (TICSPERFRAME<<6); + sprite[i].lotag -= TICSPERFRAME; + if (sprite[i].lotag < 0) deletesprite(i); + } + + //Go through splash sprites + for(i=headspritestat[4];i>=0;i=nexti) + { + nexti = nextspritestat[i]; + + sprite[i].lotag -= TICSPERFRAME; + sprite[i].picnum = SPLASH + ((63-sprite[i].lotag)>>4); + if (sprite[i].lotag < 0) deletesprite(i); + } + + //Go through explosion sprites + for(i=headspritestat[5];i>=0;i=nexti) + { + nexti = nextspritestat[i]; + + sprite[i].lotag -= TICSPERFRAME; + if (sprite[i].lotag < 0) deletesprite(i); + } + + //Go through bomb spriral-explosion sprites + for(i=headspritestat[7];i>=0;i=nexti) + { + nexti = nextspritestat[i]; + + sprite[i].xrepeat = (sprite[i].lotag>>2); + sprite[i].yrepeat = (sprite[i].lotag>>2); + sprite[i].lotag -= (TICSPERFRAME<<2); + if (sprite[i].lotag < 0) { deletesprite(i); continue; } + + if ((nummoves-i)&statrate[7]) continue; + + sprite[i].x += ((sprite[i].xvel*TICSPERFRAME)>>2); + sprite[i].y += ((sprite[i].yvel*TICSPERFRAME)>>2); + sprite[i].z += ((sprite[i].zvel*TICSPERFRAME)>>2); + + sprite[i].zvel += (TICSPERFRAME<<9); + if (sprite[i].z < sector[sprite[i].sectnum].ceilingz+(4<<8)) + { + sprite[i].z = sector[sprite[i].sectnum].ceilingz+(4<<8); + sprite[i].zvel = -(sprite[i].zvel>>1); + } + if (sprite[i].z > sector[sprite[i].sectnum].floorz-(4<<8)) + { + sprite[i].z = sector[sprite[i].sectnum].floorz-(4<<8); + sprite[i].zvel = -(sprite[i].zvel>>1); + } + } + + //EVILALGRAVE shrinking list + for(i=headspritestat[9];i>=0;i=nexti) + { + nexti = nextspritestat[i]; + + sprite[i].xrepeat = (sprite[i].lotag>>2); + sprite[i].yrepeat = (sprite[i].lotag>>2); + sprite[i].lotag -= TICSPERFRAME; + if (sprite[i].lotag < 0) { deletesprite(i); continue; } + + if ((nummoves-i)&statrate[9]) continue; + + sprite[i].x += (sprite[i].xvel*TICSPERFRAME); + sprite[i].y += (sprite[i].yvel*TICSPERFRAME); + sprite[i].z += (sprite[i].zvel*TICSPERFRAME); + + sprite[i].zvel += (TICSPERFRAME<<8); + if (sprite[i].z < sector[sprite[i].sectnum].ceilingz) + { + sprite[i].z = sector[sprite[i].sectnum].ceilingz; + sprite[i].xvel -= (sprite[i].xvel>>2); + sprite[i].yvel -= (sprite[i].yvel>>2); + sprite[i].zvel = -(sprite[i].zvel>>1); + } + if (sprite[i].z > sector[sprite[i].sectnum].floorz) + { + sprite[i].z = sector[sprite[i].sectnum].floorz; + sprite[i].xvel -= (sprite[i].xvel>>2); + sprite[i].yvel -= (sprite[i].yvel>>2); + sprite[i].zvel = -(sprite[i].zvel>>1); + } + } + + //Re-spawning sprite list + for(i=headspritestat[11];i>=0;i=nexti) + { + nexti = nextspritestat[i]; + + sprite[i].extra -= TICSPERFRAME; + if (sprite[i].extra < 0) + { + wsayfollow("warp.wav",6144L+(krand()&127)-64,128L,&sprite[i].x,&sprite[i].y,0); + sprite[i].cstat &= ~0x8000; + sprite[i].extra = -1; + changespritestat((short)i,0); + } + } +} + +void activatehitag(short dahitag) +{ + long i, nexti; + + for(i=0;i=0;i=nexti) + { + nexti = nextspritestat[i]; + if (sprite[i].hitag == dahitag) operatesprite(i); + } +} + +void bombexplode(long i) +{ + long j, nextj, k, daang, dax, day, dist; + + spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z,0,-4,0, + 32,64,64,0,0,EXPLOSION,sprite[i].ang, + 0,0,0,sprite[i].owner,sprite[i].sectnum,5,31,0,0); + //31=Time left for explosion to stay + + for(k=0;k<12;k++) + { + spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z+(8<<8),2,-4,0, + 32,24,24,0,0,EXPLOSION,sprite[i].ang, + (krand()>>7)-256,(krand()>>7)-256,(krand()>>2)-8192, + sprite[i].owner,sprite[i].sectnum,7,96,0,0); + //96=Time left for smoke to be alive + } + + for(j=connecthead;j>=0;j=connectpoint2[j]) + { + dist = (posx[j]-sprite[i].x)*(posx[j]-sprite[i].x); + dist += (posy[j]-sprite[i].y)*(posy[j]-sprite[i].y); + dist += ((posz[j]-sprite[i].z)>>4)*((posz[j]-sprite[i].z)>>4); + if (dist < 4194304) + if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,posx[j],posy[j],posz[j],cursectnum[j]) == 1) + { + k = ((32768/((dist>>16)+4))>>5); + if (j == myconnectindex) + { + daang = getangle(posx[j]-sprite[i].x,posy[j]-sprite[i].y); + dax = ((k*sintable[(daang+512)&2047])>>14); + day = ((k*sintable[daang&2047])>>14); + fvel += ((dax*sintable[(ang[j]+512)&2047]+day*sintable[ang[j]&2047])>>14); + svel += ((day*sintable[(ang[j]+512)&2047]-dax*sintable[ang[j]&2047])>>14); + } + changehealth(j,-k); //if changehealth returns 1, you're dead + } + } + + for(k=1;k<=2;k++) //Check for hurting monsters + { + for(j=headspritestat[k];j>=0;j=nextj) + { + nextj = nextspritestat[j]; + + dist = (sprite[j].x-sprite[i].x)*(sprite[j].x-sprite[i].x); + dist += (sprite[j].y-sprite[i].y)*(sprite[j].y-sprite[i].y); + dist += ((sprite[j].z-sprite[i].z)>>4)*((sprite[j].z-sprite[i].z)>>4); + if (dist >= 4194304) continue; + if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,sprite[j].x,sprite[j].y,sprite[j].z-(tilesizy[sprite[j].picnum]<<7),sprite[j].sectnum) == 0) + continue; + if (sprite[j].picnum == BROWNMONSTER) + { + sprite[j].z += ((tilesizy[sprite[j].picnum]*sprite[j].yrepeat)<<1); + sprite[j].picnum = GIFTBOX; + sprite[j].cstat &= ~0x83; //Should not clip, foot-z + changespritestat(j,12); + } + } + } + + for(j=headspritestat[10];j>=0;j=nextj) //Check for EVILAL's + { + nextj = nextspritestat[j]; + + dist = (sprite[j].x-sprite[i].x)*(sprite[j].x-sprite[i].x); + dist += (sprite[j].y-sprite[i].y)*(sprite[j].y-sprite[i].y); + dist += ((sprite[j].z-sprite[i].z)>>4)*((sprite[j].z-sprite[i].z)>>4); + if (dist >= 4194304) continue; + if (cansee(sprite[i].x,sprite[i].y,sprite[i].z-(tilesizy[sprite[i].picnum]<<7),sprite[i].sectnum,sprite[j].x,sprite[j].y,sprite[j].z-(tilesizy[sprite[j].picnum]<<7),sprite[j].sectnum) == 0) + continue; + + sprite[j].picnum = EVILALGRAVE; + sprite[j].cstat = 0; + sprite[j].xvel = (krand()&255)-128; + sprite[j].yvel = (krand()&255)-128; + sprite[j].zvel = (krand()&4095)-3072; + changespritestat(j,9); + } + + wsayfollow("blowup.wav",3840L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,0); + deletesprite((short)i); +} + +void processinput(short snum) +{ + long oldposx, oldposy, nexti; + long i, j, k, doubvel, xvect, yvect, goalz; + long dax, day, dax2, day2, odax, oday, odax2, oday2; + short startwall, endwall; + char *ptr; + + //SHARED KEYS: + //Movement code + if ((ssync[snum].fvel|ssync[snum].svel) != 0) + { + doubvel = (TICSPERFRAME<<((ssync[snum].bits&256)>0)); + + xvect = 0, yvect = 0; + if (ssync[snum].fvel != 0) + { + xvect += ((((long)ssync[snum].fvel)*doubvel*(long)sintable[(ang[snum]+512)&2047])>>3); + yvect += ((((long)ssync[snum].fvel)*doubvel*(long)sintable[ang[snum]&2047])>>3); + } + if (ssync[snum].svel != 0) + { + xvect += ((((long)ssync[snum].svel)*doubvel*(long)sintable[ang[snum]&2047])>>3); + yvect += ((((long)ssync[snum].svel)*doubvel*(long)sintable[(ang[snum]+1536)&2047])>>3); + } + if (flytime[snum] > lockclock) { xvect += xvect; yvect += yvect; } // DOuble flying speed + clipmove(&posx[snum],&posy[snum],&posz[snum],&cursectnum[snum],xvect,yvect,128L,4<<8,4<<8,CLIPMASK0); + revolvedoorstat[snum] = 1; + } + else + { + revolvedoorstat[snum] = 0; + } + + sprite[playersprite[snum]].cstat &= ~1; + //Push player away from walls if clipmove doesn't work + if (pushmove(&posx[snum],&posy[snum],&posz[snum],&cursectnum[snum],128L,4<<8,4<<8,CLIPMASK0) < 0) + changehealth(snum,-1000); //If this screws up, then instant death!!! + + // Getzrange returns the highest and lowest z's for an entire box, + // NOT just a point. This prevents you from falling off cliffs + // when you step only slightly over the cliff. + getzrange(posx[snum],posy[snum],posz[snum],cursectnum[snum],&globhiz,&globhihit,&globloz,&globlohit,128L,CLIPMASK0); + sprite[playersprite[snum]].cstat |= 1; + + if (ssync[snum].avel != 0) //ang += avel * constant + { //ENGINE calculates avel for you + doubvel = TICSPERFRAME; + if ((ssync[snum].bits&256) > 0) //Lt. shift makes turn velocity 50% faster + doubvel += (TICSPERFRAME>>1); + ang[snum] += ((((long)ssync[snum].avel)*doubvel)>>4); + ang[snum] &= 2047; + } + + if (health[snum] < 0) + { + health[snum] -= TICSPERFRAME; + if (health[snum] <= -160) + { + hvel[snum] = 0; + if (snum == myconnectindex) + fvel = 0, svel = 0, avel = 0, keystatus[3] = 1; + + deaths[snum]++; + health[snum] = 100; + numbombs[snum] = 0; + numgrabbers[snum] = 0; + nummissiles[snum] = 0; + flytime[snum] = 0; + + findrandomspot(&posx[snum],&posy[snum],&cursectnum[snum]); + posz[snum] = getflorzofslope(cursectnum[snum],posx[snum],posy[snum])-(1<<8); + horiz[snum] = 100; + ang[snum] = (krand()&2047); + + sprite[playersprite[snum]].x = posx[snum]; + sprite[playersprite[snum]].y = posy[snum]; + sprite[playersprite[snum]].z = posz[snum]+EYEHEIGHT; + sprite[playersprite[snum]].picnum = PLAYER; + sprite[playersprite[snum]].ang = ang[snum]; + sprite[playersprite[snum]].xrepeat = 64; + sprite[playersprite[snum]].yrepeat = 64; + changespritesect(playersprite[snum],cursectnum[snum]); + + drawstatusbar(snum); // Andy did this + + i = playersprite[snum]; + wsayfollow("zipguns.wav",4096L+(krand()&127)-64,256L,&sprite[i].x,&sprite[i].y,1); + for(k=0;k<16;k++) + { + spawnsprite(j,sprite[i].x,sprite[i].y,sprite[i].z+(8<<8),2,-4,0, + 32,24,24,0,0,EXPLOSION,sprite[i].ang, + (krand()&511)-256,(krand()&511)-256,(krand()&16384)-8192, + sprite[i].owner,sprite[i].sectnum,7,96,0,0); + //96=Time left for smoke to be alive + } + } + else + { + sprite[playersprite[snum]].xrepeat = max(((128+health[snum])>>1),0); + sprite[playersprite[snum]].yrepeat = max(((128+health[snum])>>1),0); + + hvel[snum] += (TICSPERFRAME<<2); + horiz[snum] = max(horiz[snum]-4,0); + posz[snum] += hvel[snum]; + if (posz[snum] > globloz-(4<<8)) + { + posz[snum] = globloz-(4<<8); + horiz[snum] = min(horiz[snum]+5,200); + hvel[snum] = 0; + } + } + } + + if (((ssync[snum].bits&8) > 0) && (horiz[snum] > 100-(200>>1))) horiz[snum] -= 4; //- + if (((ssync[snum].bits&4) > 0) && (horiz[snum] < 100+(200>>1))) horiz[snum] += 4; //+ + + goalz = globloz-EYEHEIGHT; + if (sector[cursectnum[snum]].lotag == 4) //slime sector + if ((globlohit&0xc000) != 49152) //You're not on a sprite + { + goalz = globloz-(8<<8); + if (posz[snum] >= goalz-(2<<8)) + { + clipmove(&posx[snum],&posy[snum],&posz[snum],&cursectnum[snum],-TICSPERFRAME<<14,-TICSPERFRAME<<14,128L,4<<8,4<<8,CLIPMASK0); + + if (slimesoundcnt[snum] >= 0) + { + slimesoundcnt[snum] -= TICSPERFRAME; + while (slimesoundcnt[snum] < 0) + { + slimesoundcnt[snum] += 120; + wsayfollow("slime.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); + } + } + } + } + if (goalz < globhiz+(16<<8)) //ceiling&floor too close + goalz = ((globloz+globhiz)>>1); + //goalz += mousz; + if (health[snum] >= 0) + { + if ((ssync[snum].bits&1) > 0) //A (stand high) + { + if (flytime[snum] <= lockclock) + { + if (posz[snum] >= globloz-(32<<8)) + { + goalz -= (16<<8); + if (ssync[snum].bits&256) goalz -= (24<<8); + } + } + else + { + hvel[snum] -= 192; + if (ssync[snum].bits&256) hvel[snum] -= 192; + } + } + if ((ssync[snum].bits&2) > 0) //Z (stand low) + { + if (flytime[snum] <= lockclock) + { + goalz += (12<<8); + if (ssync[snum].bits&256) goalz += (12<<8); + } + else + { + hvel[snum] += 192; + if (ssync[snum].bits&256) hvel[snum] += 192; + } + } + } + + if (flytime[snum] <= lockclock) + { + if (posz[snum] < goalz) + hvel[snum] += (TICSPERFRAME<<4); + else + hvel[snum] = (((goalz-posz[snum])*TICSPERFRAME)>>5); + } + else + { + hvel[snum] -= (hvel[snum]>>2); + hvel[snum] -= ksgn(hvel[snum]); + } + + posz[snum] += hvel[snum]; + if (posz[snum] > globloz-(4<<8)) posz[snum] = globloz-(4<<8), hvel[snum] = 0; + if (posz[snum] < globhiz+(4<<8)) posz[snum] = globhiz+(4<<8), hvel[snum] = 0; + + if (dimensionmode[snum] != 3) + { + if (((ssync[snum].bits&32) > 0) && (zoom[snum] > 48)) zoom[snum] -= (zoom[snum]>>4); + if (((ssync[snum].bits&16) > 0) && (zoom[snum] < 4096)) zoom[snum] += (zoom[snum]>>4); + } + + //Update sprite representation of player + // -should be after movement, but before shooting code + setsprite(playersprite[snum],posx[snum],posy[snum],posz[snum]+EYEHEIGHT); + sprite[playersprite[snum]].ang = ang[snum]; + + if (health[snum] >= 0) + { + if ((cursectnum[snum] < 0) || (cursectnum[snum] >= numsectors)) + { //How did you get in the wrong sector? + wsayfollow("ouch.wav",4096L+(krand()&127)-64,64L,&posx[snum],&posy[snum],1); + changehealth(snum,-TICSPERFRAME); + } + else if (globhiz+(8<<8) > globloz) + { //Ceiling and floor are smooshing you! + wsayfollow("ouch.wav",4096L+(krand()&127)-64,64L,&posx[snum],&posy[snum],1); + changehealth(snum,-TICSPERFRAME); + } + } + + if ((waterfountainwall[snum] >= 0) && (health[snum] >= 0)) + if ((wall[neartagwall].lotag != 7) || ((ssync[snum].bits&1024) == 0)) + { + i = waterfountainwall[snum]; + if (wall[i].overpicnum == USEWATERFOUNTAIN) + wall[i].overpicnum = WATERFOUNTAIN; + else if (wall[i].picnum == USEWATERFOUNTAIN) + wall[i].picnum = WATERFOUNTAIN; + + waterfountainwall[snum] = -1; + } + + if ((ssync[snum].bits&1024) > 0) //Space bar + { + //Continuous triggers... + + neartag(posx[snum],posy[snum],posz[snum],cursectnum[snum],ang[snum],&neartagsector,&neartagwall,&neartagsprite,&neartaghitdist,1024L,3); + if (neartagsector == -1) + { + i = cursectnum[snum]; + if ((sector[i].lotag|sector[i].hitag) != 0) + neartagsector = i; + } + + if (wall[neartagwall].lotag == 7) //Water fountain + { + if (wall[neartagwall].overpicnum == WATERFOUNTAIN) + { + wsayfollow("water.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); + wall[neartagwall].overpicnum = USEWATERFOUNTAIN; + waterfountainwall[snum] = neartagwall; + } + else if (wall[neartagwall].picnum == WATERFOUNTAIN) + { + wsayfollow("water.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); + wall[neartagwall].picnum = USEWATERFOUNTAIN; + waterfountainwall[snum] = neartagwall; + } + + if (waterfountainwall[snum] >= 0) + { + waterfountaincnt[snum] -= TICSPERFRAME; + while (waterfountaincnt[snum] < 0) + { + waterfountaincnt[snum] += 120; + wsayfollow("water.wav",4096L+(krand()&127)-64,256L,&posx[snum],&posy[snum],1); + changehealth(snum,2); + } + } + } + + //1-time triggers... + if ((oflags[snum]&1024) == 0) + { + if (neartagsector >= 0) + if (sector[neartagsector].hitag == 0) + operatesector(neartagsector); + + if (neartagwall >= 0) + if (wall[neartagwall].lotag == 2) //Switch + { + activatehitag(wall[neartagwall].hitag); + + j = wall[neartagwall].overpicnum; + if (j == SWITCH1ON) //1-time switch + { + wall[neartagwall].overpicnum = GIFTBOX; + wall[neartagwall].lotag = 0; + wall[neartagwall].hitag = 0; + } + if (j == GIFTBOX) //1-time switch + { + wall[neartagwall].overpicnum = SWITCH1ON; + wall[neartagwall].lotag = 0; + wall[neartagwall].hitag = 0; + } + if (j == SWITCH2ON) wall[neartagwall].overpicnum = SWITCH2OFF; + if (j == SWITCH2OFF) wall[neartagwall].overpicnum = SWITCH2ON; + if (j == SWITCH3ON) wall[neartagwall].overpicnum = SWITCH3OFF; + if (j == SWITCH3OFF) wall[neartagwall].overpicnum = SWITCH3ON; + + i = wall[neartagwall].point2; + dax = ((wall[neartagwall].x+wall[i].x)>>1); + day = ((wall[neartagwall].y+wall[i].y)>>1); + wsayfollow("switch.wav",4096L+(krand()&255)-128,256L,&dax,&day,0); + } + + if (neartagsprite >= 0) + { + if (sprite[neartagsprite].lotag == 1) + { //if you're shoving innocent little AL around, he gets mad! + if (sprite[neartagsprite].picnum == AL) + { + sprite[neartagsprite].picnum = EVILAL; + sprite[neartagsprite].cstat |= 2; //Make him transluscent + sprite[neartagsprite].xrepeat = 38; + sprite[neartagsprite].yrepeat = 38; + changespritestat(neartagsprite,10); + } + } + if (sprite[neartagsprite].lotag == 4) + { + activatehitag(sprite[neartagsprite].hitag); + + j = sprite[neartagsprite].picnum; + if (j == SWITCH1ON) //1-time switch + { + sprite[neartagsprite].picnum = GIFTBOX; + sprite[neartagsprite].lotag = 0; + sprite[neartagsprite].hitag = 0; + } + if (j == GIFTBOX) //1-time switch + { + sprite[neartagsprite].picnum = SWITCH1ON; + sprite[neartagsprite].lotag = 0; + sprite[neartagsprite].hitag = 0; + } + if (j == SWITCH2ON) sprite[neartagsprite].picnum = SWITCH2OFF; + if (j == SWITCH2OFF) sprite[neartagsprite].picnum = SWITCH2ON; + if (j == SWITCH3ON) sprite[neartagsprite].picnum = SWITCH3OFF; + if (j == SWITCH3OFF) sprite[neartagsprite].picnum = SWITCH3ON; + + dax = sprite[neartagsprite].x; + day = sprite[neartagsprite].y; + wsayfollow("switch.wav",4096L+(krand()&255)-128,256L,&dax,&day,0); + } + } + } + } + + if ((ssync[snum].bits & 2048) > 0) { // Shoot a bullet + if ((numbombs[snum] == 0) && (((ssync[snum].bits >> 13) & 7) == 2) && (myconnectindex == snum)) + locselectedgun = 0; + if ((nummissiles[snum] == 0) && (((ssync[snum].bits >> 13) & 7) == 3) && (myconnectindex == snum)) + locselectedgun = 1; + if ((numgrabbers[snum] == 0) && (((ssync[snum].bits >> 13) & 7) == 4) && (myconnectindex == snum)) + locselectedgun = 1; + + if ((health[snum] >= 0) || ((krand() & 127) > -health[snum])) + switch((ssync[snum].bits >> 13) & 7) { + case 0: + if (lockclock > lastchaingun[snum]+8) { + lastchaingun[snum] = lockclock; + shootgun(snum,posx[snum],posy[snum],posz[snum],ang[snum],horiz[snum],cursectnum[snum],0); + } + break; + case 1: + if ((oflags[snum] & 2048) == 0) + shootgun(snum,posx[snum],posy[snum],posz[snum],ang[snum],horiz[snum],cursectnum[snum],1); + break; + case 2: + if ((oflags[snum] & 2048) == 0) + if (numbombs[snum] > 0) { + shootgun(snum,posx[snum],posy[snum],posz[snum],ang[snum],horiz[snum],cursectnum[snum],2); + changenumbombs(snum,-1); + } + break; + case 3: + if ((oflags[snum] & 2048) == 0) + if (nummissiles[snum] > 0) { + shootgun(snum,posx[snum],posy[snum],posz[snum],ang[snum],horiz[snum],cursectnum[snum],3); + changenummissiles(snum,-1); + } + break; + case 4: + if ((oflags[snum] & 2048) == 0) + if (numgrabbers[snum] > 0) { + shootgun(snum,posx[snum],posy[snum],posz[snum],ang[snum],horiz[snum],cursectnum[snum],4); + changenumgrabbers(snum,-1); + } + break; + } + } + + if ((ssync[snum].bits&4096) > (oflags[snum]&4096)) //Keypad enter + { + dimensionmode[snum]++; + if (dimensionmode[snum] > 3) dimensionmode[snum] = 1; + } + + oflags[snum] = ssync[snum].bits; +} + +void view(short snum, long *vx, long *vy, long *vz, short *vsectnum, short ang, long horiz) +{ + spritetype *sp; + long i, nx, ny, nz, hx, hy, hz, hitx, hity, hitz; + short bakcstat, hitsect, hitwall, hitsprite, daang; + + nx = (sintable[(ang+1536)&2047]>>4); + ny = (sintable[(ang+1024)&2047]>>4); + nz = (horiz-100)*128; + + sp = &sprite[snum]; + + bakcstat = sp->cstat; + sp->cstat &= (short)~0x101; + + updatesectorz(*vx,*vy,*vz,vsectnum); + hitscan(*vx,*vy,*vz,*vsectnum,nx,ny,nz,&hitsect,&hitwall,&hitsprite,&hitx,&hity,&hitz,CLIPMASK1); + hx = hitx-(*vx); hy = hity-(*vy); + if (klabs(nx)+klabs(ny) > klabs(hx)+klabs(hy)) + { + *vsectnum = hitsect; + if (hitwall >= 0) + { + daang = getangle(wall[wall[hitwall].point2].x-wall[hitwall].x, + wall[wall[hitwall].point2].y-wall[hitwall].y); + + i = nx*sintable[daang]+ny*sintable[(daang+1536)&2047]; + if (klabs(nx) > klabs(ny)) hx -= mulscale28(nx,i); + else hy -= mulscale28(ny,i); + } + else if (hitsprite < 0) + { + if (klabs(nx) > klabs(ny)) hx -= (nx>>5); + else hy -= (ny>>5); + } + if (klabs(nx) > klabs(ny)) i = divscale16(hx,nx); + else i = divscale16(hy,ny); + if (i < cameradist) cameradist = i; + } + *vx = (*vx)+mulscale16(nx,cameradist); + *vy = (*vy)+mulscale16(ny,cameradist); + *vz = (*vz)+mulscale16(nz,cameradist); + + updatesectorz(*vx,*vy,*vz,vsectnum); + + sp->cstat = bakcstat; +} + +#if 0 // JBF: now in the engine +void updatesectorz(long x, long y, long z, short *sectnum) +{ + walltype *wal; + long i, j, cz, fz; + + getzsofslope(*sectnum,x,y,&cz,&fz); + if ((z >= cz) && (z <= fz)) + if (inside(x,y,*sectnum) != 0) return; + + if ((*sectnum >= 0) && (*sectnum < numsectors)) + { + wal = &wall[sector[*sectnum].wallptr]; + j = sector[*sectnum].wallnum; + do + { + i = wal->nextsector; + if (i >= 0) + { + getzsofslope(i,x,y,&cz,&fz); + if ((z >= cz) && (z <= fz)) + if (inside(x,y,(short)i) == 1) + { *sectnum = i; return; } + } + wal++; j--; + } while (j != 0); + } + + for(i=numsectors-1;i>=0;i--) + { + getzsofslope(i,x,y,&cz,&fz); + if ((z >= cz) && (z <= fz)) + if (inside(x,y,(short)i) == 1) + { *sectnum = i; return; } + } + + *sectnum = -1; +} +#endif + +void drawscreen(short snum, long dasmoothratio) +{ + long i, j, k=0, l, charsperline, tempint; + long x1, y1, x2, y2, ox1, oy1, ox2, oy2, dist, maxdist; + long cposx, cposy, cposz, choriz, czoom, tposx, tposy; + long tiltlock, *intptr, ovisibility, oparallaxvisibility; + short cang, tang, csect; + char ch, *ptr, *ptr2, *ptr3, *ptr4; + spritetype *tspr; + + smoothratio = max(min(dasmoothratio,65536),0); + + dointerpolations(); + + if ((snum == myconnectindex) && ((networkmode == 1) || (myconnectindex != connecthead))) + { + cposx = omyx+mulscale16(myx-omyx,smoothratio); + cposy = omyy+mulscale16(myy-omyy,smoothratio); + cposz = omyz+mulscale16(myz-omyz,smoothratio); + choriz = omyhoriz+mulscale16(myhoriz-omyhoriz,smoothratio); + cang = omyang+mulscale16((long)(((myang+1024-omyang)&2047)-1024),smoothratio); + } + else + { + cposx = oposx[snum]+mulscale16(posx[snum]-oposx[snum],smoothratio); + cposy = oposy[snum]+mulscale16(posy[snum]-oposy[snum],smoothratio); + cposz = oposz[snum]+mulscale16(posz[snum]-oposz[snum],smoothratio); + choriz = ohoriz[snum]+mulscale16(horiz[snum]-ohoriz[snum],smoothratio); + cang = oang[snum]+mulscale16(((ang[snum]+1024-oang[snum])&2047)-1024,smoothratio); + } + czoom = ozoom[snum]+mulscale16(zoom[snum]-ozoom[snum],smoothratio); + + setears(cposx,cposy,(long)sintable[(cang+512)&2047]<<14,(long)sintable[cang&2047]<<14); + + if (dimensionmode[myconnectindex] == 3) + { + tempint = screensize; + + if (((loc.bits&32) > (screensizeflag&32)) && (screensize > 64)) + { + ox1 = ((xdim-screensize)>>1); + ox2 = ox1+screensize-1; + oy1 = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); + oy2 = oy1 + scale(screensize,ydim-32,xdim)-1; + screensize -= (screensize>>3); + + if (tempint > xdim) + { + screensize = xdim; + + flushperms(); + + rotatesprite((xdim-320)<<15,(ydim-32)<<16,65536L,0,STATUSBAR,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); + i = ((xdim-320)>>1); + while (i >= 8) i -= 8, rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL8,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); + if (i >= 4) i -= 4, rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL4,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); + i = ((xdim-320)>>1)+320; + while (i <= xdim-8) rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL8,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L), i += 8; + if (i <= xdim-4) rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL4,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L), i += 4; + + drawstatusbar(screenpeek); // Andy did this + } + + x1 = ((xdim-screensize)>>1); + x2 = x1+screensize-1; + y1 = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); + y2 = y1 + scale(screensize,ydim-32,xdim)-1; + setview(x1,y1,x2,y2); + + // (ox1,oy1)ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + // ³ (x1,y1) ³ + // ³ ÚÄÄÄÄÄ¿ ³ + // ³ ³ ³ ³ + // ³ ÀÄÄÄÄÄÙ ³ + // ³ (x2,y2) ³ + // ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ(ox2,oy2) + + drawtilebackground(0L,0L,BACKGROUND,8,ox1,oy1,x1-1,oy2,0); + drawtilebackground(0L,0L,BACKGROUND,8,x2+1,oy1,ox2,oy2,0); + drawtilebackground(0L,0L,BACKGROUND,8,x1,oy1,x2,y1-1,0); + drawtilebackground(0L,0L,BACKGROUND,8,x1,y2+1,x2,oy2,0); + } + if (((loc.bits&16) > (screensizeflag&16)) && (screensize <= xdim)) + { + screensize += (screensize>>3); + if ((screensize > xdim) && (tempint == xdim)) + { + screensize = xdim+1; + x1 = 0; y1 = 0; + x2 = xdim-1; y2 = ydim-1; + } + else + { + if (screensize > xdim) screensize = xdim; + x1 = ((xdim-screensize)>>1); + x2 = x1+screensize-1; + y1 = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); + y2 = y1 + scale(screensize,ydim-32,xdim)-1; + } + setview(x1,y1,x2,y2); + } + screensizeflag = loc.bits; + } + + if (dimensionmode[snum] != 2) + { + if ((numplayers > 1) && (option[4] == 0)) + { + //Do not draw other views constantly if they're staying still + //It's a shame this trick will only work in screen-buffer mode + //At least screen-buffer mode covers all the HI hi-res modes + //if (vidoption == 2) + //{ + for(i=connecthead;i>=0;i=connectpoint2[i]) frame2draw[i] = 0; + frame2draw[snum] = 1; + + //2-1,3-1,4-2 + //5-2,6-2,7-2,8-3,9-3,10-3,11-3,12-4,13-4,14-4,15-4,16-5 + x1 = posx[snum]; y1 = posy[snum]; + for(j=(numplayers>>2)+1;j>0;j--) + { + maxdist = 0x80000000; + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (frame2draw[i] == 0) + { + x2 = posx[i]-x1; y2 = posy[i]-y1; + dist = dmulscale12(x2,x2,y2,y2); + + if (dist < 64) dist = 16384; + else if (dist > 16384) dist = 64; + else dist = 1048576 / dist; + + dist *= frameskipcnt[i]; + + //Increase frame rate if screen is moving + if ((posx[i] != oposx[i]) || (posy[i] != oposy[i]) || + (posz[i] != oposz[i]) || (ang[i] != oang[i]) || + (horiz[i] != ohoriz[i])) dist += dist; + + if (dist > maxdist) maxdist = dist, k = i; + } + + for(i=connecthead;i>=0;i=connectpoint2[i]) + frameskipcnt[i] += (frameskipcnt[i]>>3)+1; + frameskipcnt[k] = 0; + + frame2draw[k] = 1; + } + //} + //else + //{ + // for(i=connecthead;i>=0;i=connectpoint2[i]) frame2draw[i] = 1; + //} + + for(i=connecthead,j=0;i>=0;i=connectpoint2[i],j++) + if (frame2draw[i] != 0) + { + if (numplayers <= 4) + { + switch(j) + { + case 0: setview(0,0,(xdim>>1)-1,(ydim>>1)-1); break; + case 1: setview((xdim>>1),0,xdim-1,(ydim>>1)-1); break; + case 2: setview(0,(ydim>>1),(xdim>>1)-1,ydim-1); break; + case 3: setview((xdim>>1),(ydim>>1),xdim-1,ydim-1); break; + } + } + else + { + switch(j) + { + case 0: setview(0,0,(xdim>>2)-1,(ydim>>2)-1); break; + case 1: setview(xdim>>2,0,(xdim>>1)-1,(ydim>>2)-1); break; + case 2: setview(xdim>>1,0,xdim-(xdim>>2)-1,(ydim>>2)-1); break; + case 3: setview(xdim-(xdim>>2),0,xdim-1,(ydim>>2)-1); break; + case 4: setview(0,ydim>>2,(xdim>>2)-1,(ydim>>1)-1); break; + case 5: setview(xdim>>2,ydim>>2,(xdim>>1)-1,(ydim>>1)-1); break; + case 6: setview(xdim>>1,ydim>>2,xdim-(xdim>>2)-1,(ydim>>1)-1); break; + case 7: setview(xdim-(xdim>>2),ydim>>2,xdim-1,(ydim>>1)-1); break; + case 8: setview(0,ydim>>1,(xdim>>2)-1,ydim-(ydim>>2)-1); break; + case 9: setview(xdim>>2,ydim>>1,(xdim>>1)-1,ydim-(ydim>>2)-1); break; + case 10: setview(xdim>>1,ydim>>1,xdim-(xdim>>2)-1,ydim-(ydim>>2)-1); break; + case 11: setview(xdim-(xdim>>2),ydim>>1,xdim-1,ydim-(ydim>>2)-1); break; + case 12: setview(0,ydim-(ydim>>2),(xdim>>2)-1,ydim-1); break; + case 13: setview(xdim>>2,ydim-(ydim>>2),(xdim>>1)-1,ydim-1); break; + case 14: setview(xdim>>1,ydim-(ydim>>2),xdim-(xdim>>2)-1,ydim-1); break; + case 15: setview(xdim-(xdim>>2),ydim-(ydim>>2),xdim-1,ydim-1); break; + } + } + + if (i == snum) + { + sprite[playersprite[snum]].cstat |= 0x8000; + drawrooms(cposx,cposy,cposz,cang,choriz,cursectnum[i]); + sprite[playersprite[snum]].cstat &= ~0x8000; + analyzesprites(cposx,cposy); + } + else + { + sprite[playersprite[i]].cstat |= 0x8000; + drawrooms(posx[i],posy[i],posz[i],ang[i],horiz[i],cursectnum[i]); + sprite[playersprite[i]].cstat &= ~0x8000; + analyzesprites(posx[i],posy[i]); + } + drawmasks(); + if ((numgrabbers[i] > 0) || (nummissiles[i] > 0) || (numbombs[i] > 0)) + rotatesprite(160<<16,184L<<16,65536,0,GUNONBOTTOM,sector[cursectnum[i]].floorshade,0,2,windowx1,windowy1,windowx2,windowy2); + + if (lockclock < 384) + { + if (lockclock < 128) + rotatesprite(320<<15,200<<15,lockclock<<9,lockclock<<4,DEMOSIGN,(128-lockclock)>>2,0,1+2,windowx1,windowy1,windowx2,windowy2); + else if (lockclock < 256) + rotatesprite(320<<15,200<<15,65536,0,DEMOSIGN,0,0,2,windowx1,windowy1,windowx2,windowy2); + else + rotatesprite(320<<15,200<<15,(384-lockclock)<<9,lockclock<<4,DEMOSIGN,(lockclock-256)>>2,0,1+2,windowx1,windowy1,windowx2,windowy2); + } + + if (health[i] <= 0) + rotatesprite(320<<15,200<<15,(-health[i])<<11,(-health[i])<<5,NO,0,0,2,windowx1,windowy1,windowx2,windowy2); + } + } + else + { + //Init for screen rotation + if (getrendermode() == 0) { // JBF 20031220 + tiltlock = screentilt; + if ((tiltlock) || (detailmode)) + { + walock[MAXTILES-2] = 255; + if (waloff[MAXTILES-2] == 0) + allocache(&waloff[MAXTILES-2],320L*320L,&walock[MAXTILES-2]); + if ((tiltlock&1023) == 0) + setviewtotile(MAXTILES-2,200L>>detailmode,320L>>detailmode); + else + setviewtotile(MAXTILES-2,320L>>detailmode,320L>>detailmode); + if ((tiltlock&1023) == 512) + { //Block off unscreen section of 90ø tilted screen + j = ((320-60)>>detailmode); + for(i=(60>>detailmode)-1;i>=0;i--) + { + startumost[i] = 1; startumost[i+j] = 1; + startdmost[i] = 0; startdmost[i+j] = 0; + } + } + + i = (tiltlock&511); if (i > 256) i = 512-i; + i = sintable[i+512]*8 + sintable[i]*5L; + setaspect(i>>1,yxaspect); + } + } else { + tiltlock = screentilt; + // Ken loves to interpolate + setrollangle(oscreentilt + mulscale16(((screentilt-oscreentilt+1024)&2047)-1024,smoothratio)); + } + + if ((gotpic[FLOORMIRROR>>3]&(1<<(FLOORMIRROR&7))) > 0) + { + dist = 0x7fffffff; i = 0; + for(k=floormirrorcnt-1;k>=0;k--) + { + j = klabs(wall[sector[floormirrorsector[k]].wallptr].x-cposx); + j += klabs(wall[sector[floormirrorsector[k]].wallptr].y-cposy); + if (j < dist) dist = j, i = k; + } + + //if (cposz > sector[floormirrorsector[i]].ceilingz) i = 1-i; //SOS + + j = floormirrorsector[i]; + + if (cameradist < 0) sprite[playersprite[snum]].cstat |= 0x8000; + drawrooms(cposx,cposy,(sector[j].floorz<<1)-cposz,cang,201-choriz,j); //SOS + //drawrooms(cposx,cposy,cposz,cang,choriz,j+MAXSECTORS); //SOS + sprite[playersprite[snum]].cstat &= ~0x8000; + analyzesprites(cposx,cposy); + drawmasks(); + + //Temp horizon + if (getrendermode() == 0) { + l = scale(choriz-100,windowx2-windowx1,320)+((windowy1+windowy2)>>1); + begindrawing(); //{{{ + for(y1=windowy1,y2=windowy2;y1>2,31)<<8); + ptr4 = palookup[18]; + ptr4 += (min(klabs(y2-l)>>2,31)<<8); + + j = sintable[((y2+totalclock)<<6)&2047]; + j += sintable[((y2-totalclock)<<7)&2047]; + j >>= 14; + + //ptr2 += j; + + //for(x1=windowx1;x1<=windowx2;x1++) + // { ch = ptr[x1]; ptr[x1] = ptr3[ptr2[x1]]; ptr2[x1] = ptr4[ch]; } + + ox1 = windowx1-min(j,0); + ox2 = windowx2-max(j,0); + + for(x1=windowx1;x1>3] &= ~(1<<(FLOORMIRROR&7)); + } + + if (gotpic[DAYSKY>>3]&(1<<(DAYSKY&7))) + { + gotpic[DAYSKY>>3] &= ~(1<<(DAYSKY&7)); + pskyoff[0] = 0; pskyoff[1] = 0; pskybits = 1; + } + else if (gotpic[NIGHTSKY>>3]&(1<<(NIGHTSKY&7))) + { + gotpic[NIGHTSKY>>3] &= ~(1<<(NIGHTSKY&7)); + pskyoff[0] = 0; pskyoff[1] = 0; pskyoff[2] = 0; pskyoff[3] = 0; + pskyoff[4] = 0; pskyoff[5] = 0; pskyoff[6] = 0; pskyoff[7] = 0; + pskybits = 3; + } + + + //Over the shoulder mode + csect = cursectnum[snum]; + if (cameradist >= 0) + { + cang += cameraang; + view(playersprite[snum],&cposx,&cposy,&cposz,&csect,cang,choriz); + } + + //WARNING! Assuming (MIRRORLABEL&31) = 0 and MAXMIRRORS = 64 + intptr = (long *)&gotpic[MIRRORLABEL>>3]; // CHECK! + if (intptr[0]|intptr[1]) + for(i=MAXMIRRORS-1;i>=0;i--) + if (gotpic[(i+MIRRORLABEL)>>3]&(1<<(i&7))) + { + gotpic[(i+MIRRORLABEL)>>3] &= ~(1<<(i&7)); + + //Prepare drawrooms for drawing mirror and calculate reflected + //position into tposx, tposy, and tang (tposz == cposz) + //Must call preparemirror before drawrooms and + // completemirror after drawrooms + preparemirror(cposx,cposy,cposz,cang,choriz, + mirrorwall[i],mirrorsector[i],&tposx,&tposy,&tang); + + ovisibility = visibility; + oparallaxvisibility = parallaxvisibility; + visibility <<= 1; + parallaxvisibility <<= 1; + ptr = palookup[0]; palookup[0] = palookup[17]; palookup[17] = ptr; + + drawrooms(tposx,tposy,cposz,tang,choriz,mirrorsector[i]|MAXSECTORS); + for(j=0,tspr=&tsprite[0];jcstat&48) == 0) tspr->cstat |= 4; + analyzesprites(tposx,tposy); + drawmasks(); + + ptr = palookup[0]; palookup[0] = palookup[17]; palookup[17] = ptr; + visibility = ovisibility; + parallaxvisibility = oparallaxvisibility; + + completemirror(); //Reverse screen x-wise in this function + + break; + } + + if (cameradist < 0) sprite[playersprite[snum]].cstat |= 0x8000; + drawrooms(cposx,cposy,cposz,cang,choriz,csect); + sprite[playersprite[snum]].cstat &= ~0x8000; + analyzesprites(cposx,cposy); + drawmasks(); + + //Finish for screen rotation + if (getrendermode() == 0) { // JBF 20031220 + if ((tiltlock) || (detailmode)) + { + setviewback(); + i = (tiltlock&511); if (i > 256) i = 512-i; + i = sintable[i+512]*8 + sintable[i]*5L; + if (detailmode == 0) i >>= 1; + rotatesprite(320<<15,200<<15,i,tiltlock+512,MAXTILES-2,0,0,2+4+64,windowx1,windowy1,windowx2,windowy2); + walock[MAXTILES-2] = 1; + } + } + + if (((numgrabbers[screenpeek] > 0) || (nummissiles[screenpeek] > 0) || (numbombs[screenpeek] > 0)) && (cameradist < 0)) + { + //Reset startdmost to bottom of screen + if ((windowx1 == 0) && (windowx2 == 319) && (yxaspect == 65536) && (tiltlock == 0)) + { + x1 = 160L-(tilesizx[GUNONBOTTOM]>>1); y1 = windowy2+1; + for(i=0;i>2,0,1+2,windowx1,windowy1,windowx2,windowy2); + else if (lockclock < 256) + rotatesprite(320<<15,200<<15,65536,0,DEMOSIGN,0,0,2,windowx1,windowy1,windowx2,windowy2); + else + rotatesprite(320<<15,200<<15,(384-lockclock)<<9,lockclock<<4,DEMOSIGN,(lockclock-256)>>2,0,1+2,windowx1,windowy1,windowx2,windowy2); + } + + if (health[screenpeek] <= 0) + rotatesprite(320<<15,200<<15,(-health[screenpeek])<<11,(-health[screenpeek])<<5,NO,0,0,2,windowx1,windowy1,windowx2,windowy2); + } + } + + //Only animate lava if its picnum is on screen + //gotpic is a bit array where the tile number's bit is set + //whenever it is drawn (ceilings, walls, sprites, etc.) + if ((gotpic[SLIME>>3]&(1<<(SLIME&7))) > 0) + { + gotpic[SLIME>>3] &= ~(1<<(SLIME&7)); + if (waloff[SLIME] != 0) { + movelava((char *)waloff[SLIME]); + invalidatetile(SLIME,0,1); // JBF 20031228 + } + } + + if ((show2dsector[cursectnum[snum]>>3]&(1<<(cursectnum[snum]&7))) == 0) + searchmap(cursectnum[snum]); + + if (dimensionmode[snum] != 3) + { + //Move back pivot point + i = scale(czoom,screensize,320); + if (dimensionmode[snum] == 2) + { + clearview(0L); //Clear screen to specified color + drawmapview(cposx,cposy,i,cang); + } + drawoverheadmap(cposx,cposy,i,cang); + } + + if (typemode != 0) + { + charsperline = 40; + //if (dimensionmode[snum] == 2) charsperline = 80; + + for(i=0;i<=typemessageleng;i+=charsperline) + { + for(j=0;j 0) + { + charsperline = 40; + //if (dimensionmode[snum] == 2) charsperline = 80; + + for(i=0;i<=getmessageleng;i+=charsperline) + { + for(j=0;j getmessagetimeoff) + getmessageleng = 0; + } + if ((numplayers >= 2) && (screenpeek != myconnectindex)) + { + j = 1; + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if (i == screenpeek) break; + j++; + } + Bsprintf(tempbuf,"(Player %ld's view)",j); + printext256((xdim>>1)-(Bstrlen(tempbuf)<<2),0,24,-1,tempbuf,0); + } + + if (syncstat != 0) printext256(68L,84L,31,0,"OUT OF SYNC!",0); + if (syncstate != 0) printext256(68L,92L,31,0,"Missed Network packet!",0); + +// //Uncomment this to test cache locks +//extern long cacnum; +//typedef struct { long *hand, leng; char *lock; } cactype; +//extern cactype cac[]; +// +// j = 0; +// for(i=0;i= 200) +// { +// Bsprintf(tempbuf,"Locked- %ld: Leng:%ld, Lock:%ld",i,cac[i].leng,*cac[i].lock); +// printext256(0L,j,31,-1,tempbuf,1); j += 6; +// } + + nextpage(); // send completed frame to display + + while (totalclock >= ototalclock+(TIMERINTSPERSECOND/MOVESPERSECOND)) + faketimerhandler(); + + if (keystatus[0x3f]) //F5 + { + keystatus[0x3f] = 0; + detailmode ^= 1; + //setrendermode(3); + } + if (keystatus[0x58]) //F12 + { + keystatus[0x58] = 0; + screencapture("captxxxx.tga",keystatus[0x2a]|keystatus[0x36]); + } + if (keystatus[0x3e]) //F4 - screen re-size + { + keystatus[0x3e] = 0; + + if (keystatus[0x2a]|keystatus[0x36]) { + setgamemode(!fullscreen, xdim, ydim, bpp); + } else { + + //cycle through all modes + j=-1; + + // work out a mask to select the mode + for (i=0; i 8) brightness = 0; + setbrightness(brightness,(char *)&palette[0],0); + } + + if (option[4] == 0) //Single player only keys + { + if (keystatus[0xd2]) //Insert - Insert player + { + keystatus[0xd2] = 0; + if (numplayers < MAXPLAYERS) + { + connectpoint2[numplayers-1] = numplayers; + connectpoint2[numplayers] = -1; + + movefifoend[numplayers] = movefifoend[0]; //HACK 01/05/2000 + + initplayersprite(numplayers); + + clearallviews(0L); //Clear screen to specified color + + numplayers++; + } + } + if (keystatus[0xd3]) //Delete - Delete player + { + keystatus[0xd3] = 0; + if (numplayers > 1) + { + numplayers--; + connectpoint2[numplayers-1] = -1; + + deletesprite(playersprite[numplayers]); + playersprite[numplayers] = -1; + + if (myconnectindex >= numplayers) myconnectindex = 0; + if (screenpeek >= numplayers) screenpeek = 0; + + if (numplayers < 2) + setup3dscreen(); + else + clearallviews(0L); //Clear screen to specified color + } + } + if (keystatus[0x46]) //Scroll Lock + { + keystatus[0x46] = 0; + + myconnectindex = connectpoint2[myconnectindex]; + if (myconnectindex < 0) myconnectindex = connecthead; + screenpeek = myconnectindex; + } + } + + restoreinterpolations(); +} + +void movethings(void) +{ + long i; + + gotlastpacketclock = totalclock; + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + copybufbyte(&ffsync[i],&baksync[movefifoend[i]][i],sizeof(input)); + movefifoend[i] = ((movefifoend[i]+1)&(MOVEFIFOSIZ-1)); + } +} + +void fakedomovethings(void) +{ + input *syn; + long i, j, k, doubvel, xvect, yvect, goalz; + short bakcstat; + + syn = (input *)&baksync[fakemovefifoplc][myconnectindex]; + + omyx = myx; + omyy = myy; + omyz = myz; + omyang = myang; + omyhoriz = myhoriz; + + bakcstat = sprite[playersprite[myconnectindex]].cstat; + sprite[playersprite[myconnectindex]].cstat &= ~0x101; + + if ((syn->fvel|syn->svel) != 0) + { + doubvel = (TICSPERFRAME<<((syn->bits&256)>0)); + + xvect = 0, yvect = 0; + if (syn->fvel != 0) + { + xvect += ((((long)syn->fvel)*doubvel*(long)sintable[(myang+512)&2047])>>3); + yvect += ((((long)syn->fvel)*doubvel*(long)sintable[myang&2047])>>3); + } + if (syn->svel != 0) + { + xvect += ((((long)syn->svel)*doubvel*(long)sintable[myang&2047])>>3); + yvect += ((((long)syn->svel)*doubvel*(long)sintable[(myang+1536)&2047])>>3); + } + if (flytime[myconnectindex] > lockclock) { xvect += xvect; yvect += yvect; } // DOuble flying speed + clipmove(&myx,&myy,&myz,&mycursectnum,xvect,yvect,128L,4<<8,4<<8,CLIPMASK0); + } + + pushmove(&myx,&myy,&myz,&mycursectnum,128L,4<<8,4<<8,CLIPMASK0); + getzrange(myx,myy,myz,mycursectnum,&globhiz,&globhihit,&globloz,&globlohit,128L,CLIPMASK0); + + if (syn->avel != 0) //ang += avel * constant + { //ENGINE calculates avel for you + doubvel = TICSPERFRAME; + if ((syn->bits&256) > 0) //Lt. shift makes turn velocity 50% faster + doubvel += (TICSPERFRAME>>1); + myang += ((((long)syn->avel)*doubvel)>>4); + myang &= 2047; + } + + if (((syn->bits&8) > 0) && (myhoriz > 100-(200>>1))) myhoriz -= 4; //- + if (((syn->bits&4) > 0) && (myhoriz < 100+(200>>1))) myhoriz += 4; //+ + + goalz = globloz-EYEHEIGHT; + if (sector[mycursectnum].lotag == 4) //slime sector + if ((globlohit&0xc000) != 49152) //You're not on a sprite + { + goalz = globloz-(8<<8); + if (myz >= goalz-(2<<8)) + clipmove(&myx,&myy,&myz,&mycursectnum,-TICSPERFRAME<<14,-TICSPERFRAME<<14,128L,4<<8,4<<8,CLIPMASK0); + } + if (goalz < globhiz+(16<<8)) //ceiling&floor too close + goalz = ((globloz+globhiz)>>1); + + if (health[myconnectindex] >= 0) + { + if ((syn->bits&1) > 0) //A (stand high) + { + if (flytime[myconnectindex] <= lockclock) + { + if (myz >= globloz-(32<<8)) + { + goalz -= (16<<8); + if (syn->bits&256) goalz -= (24<<8); + } + } + else + { + myzvel -= 192; + if (syn->bits&256) myzvel -= 192; + } + } + if ((syn->bits&2) > 0) //Z (stand low) + { + if (flytime[myconnectindex] <= lockclock) + { + goalz += (12<<8); + if (syn->bits&256) goalz += (12<<8); + } + else + { + myzvel += 192; + if (syn->bits&256) myzvel += 192; + } + } + } + + if (flytime[myconnectindex] <= lockclock) + { + if (myz < goalz) + myzvel += (TICSPERFRAME<<4); + else + myzvel = (((goalz-myz)*TICSPERFRAME)>>5); + } + else + { + myzvel -= (myzvel>>2); + myzvel -= ksgn(myzvel); + } + + myz += myzvel; + if (myz > globloz-(4<<8)) myz = globloz-(4<<8), myzvel = 0; + if (myz < globhiz+(4<<8)) myz = globhiz+(4<<8), myzvel = 0; + + sprite[playersprite[myconnectindex]].cstat = bakcstat; + + myxbak[fakemovefifoplc] = myx; + myybak[fakemovefifoplc] = myy; + myzbak[fakemovefifoplc] = myz; + myangbak[fakemovefifoplc] = myang; + myhorizbak[fakemovefifoplc] = myhoriz; + fakemovefifoplc = (fakemovefifoplc+1)&(MOVEFIFOSIZ-1); +} + + //Prediction correction +void fakedomovethingscorrect(void) +{ + long i; + + if ((networkmode == 0) && (myconnectindex == connecthead)) return; + + i = ((movefifoplc-1)&(MOVEFIFOSIZ-1)); + + if ((posx[myconnectindex] == myxbak[i]) && + (posy[myconnectindex] == myybak[i]) && + (posz[myconnectindex] == myzbak[i]) && + (horiz[myconnectindex] == myhorizbak[i]) && + (ang[myconnectindex] == myangbak[i])) + return; + + //Re-start fakedomovethings back to place of error + myx = omyx = posx[myconnectindex]; + myy = omyy = posy[myconnectindex]; + myz = omyz = posz[myconnectindex]; myzvel = hvel[myconnectindex]; + myang = omyang = ang[myconnectindex]; + mycursectnum = mycursectnum; + myhoriz = omyhoriz = horiz[myconnectindex]; + + fakemovefifoplc = movefifoplc; + while (fakemovefifoplc != movefifoend[myconnectindex]) fakedomovethings(); +} + +void domovethings(void) +{ + short i, j, startwall, endwall; + spritetype *spr; + walltype *wal; + point3d *ospr; + + nummoves++; + + for(i=connecthead;i>=0;i=connectpoint2[i]) + copybufbyte(&baksync[movefifoplc][i],&ssync[i],sizeof(input)); + movefifoplc = ((movefifoplc+1)&(MOVEFIFOSIZ-1)); + + if (option[4] != 0) + { + syncval[syncvalhead] = (char)(randomseed&255); + syncvalhead = ((syncvalhead+1)&(MOVEFIFOSIZ-1)); + } + + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + oposx[i] = posx[i]; + oposy[i] = posy[i]; + oposz[i] = posz[i]; + ohoriz[i] = horiz[i]; + ozoom[i] = zoom[i]; + oang[i] = ang[i]; + } + + for(i=NUMSTATS-1;i>=0;i--) + if (statrate[i] >= 0) + for(j=headspritestat[i];j>=0;j=nextspritestat[j]) + if (((nummoves-j)&statrate[i]) == 0) + copybuf(&sprite[j].x,&osprite[j].x,3); + + for(i=connecthead;i>=0;i=connectpoint2[i]) + ocursectnum[i] = cursectnum[i]; + + updateinterpolations(); + + if ((numplayers <= 2) && (recstat == 1)) + { + j = 0; + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + copybufbyte(&ssync[i],&recsync[reccnt][j],sizeof(input)); + j++; + } + reccnt++; if (reccnt > 16383) reccnt = 16383; + } + + lockclock += TICSPERFRAME; + drawstatusflytime(screenpeek); // Andy did this + + if (cameradist >= 0) + { + cameradist = min(cameradist+((totalclock-cameraclock)<<10),65536); + if (keystatus[0x52]) //0 + cameraang -= ((totalclock-cameraclock)<<(2+(keystatus[0x2a]|keystatus[0x36]))); + if (keystatus[0x53]) //. + cameraang += ((totalclock-cameraclock)<<(2+(keystatus[0x2a]|keystatus[0x36]))); + cameraclock = totalclock; + } + + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + processinput(i); //Move player + + checktouchsprite(i,cursectnum[i]); //Pick up coins + startwall = sector[cursectnum[i]].wallptr; + endwall = startwall + sector[cursectnum[i]].wallnum; + for(j=startwall,wal=&wall[j];jnextsector >= 0) checktouchsprite(i,wal->nextsector); + } + + doanimations(); + tagcode(); //Door code, moving sector code, other stuff + statuslistcode(); //Monster / bullet code / explosions + + fakedomovethingscorrect(); + + checkmasterslaveswitch(); +} + +void getinput(void) +{ + char ch, keystate, *ptr; + long i, j, k; + long mousx, mousy, bstatus; + + if (typemode == 0) //if normal game keys active + { + if (keystatus[keys[15]]) + { + keystatus[keys[15]] = 0; + + screenpeek = connectpoint2[screenpeek]; + if (screenpeek < 0) screenpeek = connecthead; + drawstatusbar(screenpeek); // Andy did this + } + + for(i=7;i>=0;i--) + if (keystatus[i+2]) + { keystatus[i+2] = 0; locselectedgun = i; break; } + } + + + //KEYTIMERSTUFF + if (!keystatus[keys[5]]) + { + if (keystatus[keys[2]]) avel = max(avel-16*TICSPERFRAME,-128); + if (keystatus[keys[3]]) avel = min(avel+16*TICSPERFRAME,127); + } + else + { + if (keystatus[keys[2]]) svel = min(svel+8*TICSPERFRAME,127); + if (keystatus[keys[3]]) svel = max(svel-8*TICSPERFRAME,-128); + } + if (keystatus[keys[0]]) fvel = min(fvel+8*TICSPERFRAME,127); + if (keystatus[keys[1]]) fvel = max(fvel-8*TICSPERFRAME,-128); + if (keystatus[keys[12]]) svel = min(svel+8*TICSPERFRAME,127); + if (keystatus[keys[13]]) svel = max(svel-8*TICSPERFRAME,-128); + + if (avel < 0) avel = min(avel+12*TICSPERFRAME,0); + if (avel > 0) avel = max(avel-12*TICSPERFRAME,0); + if (svel < 0) svel = min(svel+2*TICSPERFRAME,0); + if (svel > 0) svel = max(svel-2*TICSPERFRAME,0); + if (fvel < 0) fvel = min(fvel+2*TICSPERFRAME,0); + if (fvel > 0) fvel = max(fvel-2*TICSPERFRAME,0); + + if ((option[4] == 0) && (numplayers >= 2)) + { + if (!keystatus[0x4f]) + { + if (keystatus[0x4b]) avel2 = max(avel2-16*TICSPERFRAME,-128); + if (keystatus[0x4d]) avel2 = min(avel2+16*TICSPERFRAME,127); + } + else + { + if (keystatus[0x4b]) svel2 = min(svel2+8*TICSPERFRAME,127); + if (keystatus[0x4d]) svel2 = max(svel2-8*TICSPERFRAME,-128); + } + if (keystatus[0x48]) fvel2 = min(fvel2+8*TICSPERFRAME,127); + if (keystatus[0x4c]) fvel2 = max(fvel2-8*TICSPERFRAME,-128); + + if (avel2 < 0) avel2 = min(avel2+12*TICSPERFRAME,0); + if (avel2 > 0) avel2 = max(avel2-12*TICSPERFRAME,0); + if (svel2 < 0) svel2 = min(svel2+2*TICSPERFRAME,0); + if (svel2 > 0) svel2 = max(svel2-2*TICSPERFRAME,0); + if (fvel2 < 0) fvel2 = min(fvel2+2*TICSPERFRAME,0); + if (fvel2 > 0) fvel2 = max(fvel2-2*TICSPERFRAME,0); + } + + oscreentilt = screentilt; + if (keystatus[0x1a]) screentilt += ((4*TICSPERFRAME)<<(keystatus[0x2a]|keystatus[0x36])); + if (keystatus[0x1b]) screentilt -= ((4*TICSPERFRAME)<<(keystatus[0x2a]|keystatus[0x36])); + + i = (TICSPERFRAME<<1); + while ((screentilt != 0) && (i > 0)) + { screentilt = ((screentilt+ksgn(screentilt-1024))&2047); i--; } + if (keystatus[0x28]) screentilt = 1536; + + + loc.fvel = min(max(fvel,-128+8),127-8); + loc.svel = min(max(svel,-128+8),127-8); + loc.avel = min(max(avel,-128+16),127-16); + + getmousevalues(&mousx,&mousy,&bstatus); + loc.avel = min(max(loc.avel+(mousx<<3),-128),127); + loc.fvel = min(max(loc.fvel-(mousy<<3),-128),127); + + loc.bits = (locselectedgun<<13); + if (typemode == 0) //if normal game keys active + { + loc.bits |= (keystatus[0x32]<<9); //M (be master) + loc.bits |= ((keystatus[keys[14]]==1)<<12); //Map mode + } + loc.bits |= keystatus[keys[8]]; //Stand high + loc.bits |= (keystatus[keys[9]]<<1); //Stand low + loc.bits |= (keystatus[keys[16]]<<4); //Zoom in + loc.bits |= (keystatus[keys[17]]<<5); //Zoom out + loc.bits |= (keystatus[keys[4]]<<8); //Run + loc.bits |= (keystatus[keys[10]]<<2); //Look up + loc.bits |= (keystatus[keys[11]]<<3); //Look down + loc.bits |= ((keystatus[keys[7]]==1)<<10); //Space + loc.bits |= ((keystatus[keys[6]]==1)<<11); //Shoot + loc.bits |= (((bstatus&6)>(oldmousebstatus&6))<<10); //Space + loc.bits |= (((bstatus&1)>(oldmousebstatus&1))<<11); //Shoot + + oldmousebstatus = bstatus; + if (((loc.bits&2048) > 0) && (locselectedgun == 0)) + oldmousebstatus &= ~1; //Allow continous fire with mouse for chain gun + + //PRIVATE KEYS: +/* if (keystatus[0xb7]) //Printscreen + { + keystatus[0xb7] = 0; + printscreeninterrupt(); + } +*/ + if (keystatus[0x2f]) //V + { + keystatus[0x2f] = 0; + if (cameradist < 0) cameradist = 0; else cameradist = -1; + cameraang = 0; + } + + if (typemode == 0) //if normal game keys active + { + if (keystatus[0x19]) //P + { + keystatus[0x19] = 0; + parallaxtype++; + if (parallaxtype > 2) parallaxtype = 0; + } + if (keystatus[0x38]|keystatus[0xb8]) //ALT + { + if (keystatus[0x4a]) // Keypad - + visibility = min(visibility+(visibility>>3),16384); + if (keystatus[0x4e]) // Keypad + + visibility = max(visibility-(visibility>>3),128); + } + + if (keystatus[keys[18]]) //Typing mode + { + keystatus[keys[18]] = 0; + typemode = 1; + bflushchars(); + keyfifoplc = keyfifoend; //Reset keyboard fifo + } + } + else + { + while ((ch = bgetchar())) + { + if (ch == 8) //Backspace + { + if (typemessageleng == 0) { typemode = 0; break; } + typemessageleng--; + } + else if (ch == 9) // tab + { + keystatus[0xf] = 0; + typemode = 0; + break; + } + else if (ch == 13) //Either ENTER + { + keystatus[0x1c] = 0; keystatus[0x9c] = 0; + if (typemessageleng > 0) + { + packbuf[0] = 2; //Sending text is message type 4 + for(j=typemessageleng-1;j>=0;j--) + packbuf[j+1] = typemessage[j]; + + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (i != myconnectindex) + sendpacket(i,packbuf,typemessageleng+1); + + typemessageleng = 0; + } + typemode = 0; + break; + } + else if ((typemessageleng < 159) && (ch >= 32) && (ch < 128)) + { + typemessage[typemessageleng++] = ch; + } + } + } +} + +void initplayersprite(short snum) +{ + long i; + + if (playersprite[snum] >= 0) return; + + spawnsprite(playersprite[snum],posx[snum],posy[snum],posz[snum]+EYEHEIGHT, + 1+256,0,snum,32,64,64,0,0,PLAYER,ang[snum],0,0,0,snum+4096, + cursectnum[snum],8,0,0,0); + + switch(snum) + { + case 1: for(i=0;i<32;i++) tempbuf[i+192] = i+128; break; //green->red + case 2: for(i=0;i<32;i++) tempbuf[i+192] = i+32; break; //green->blue + case 3: for(i=0;i<32;i++) tempbuf[i+192] = i+224; break; //green->pink + case 4: for(i=0;i<32;i++) tempbuf[i+192] = i+64; break; //green->brown + case 5: for(i=0;i<32;i++) tempbuf[i+192] = i+96; break; + case 6: for(i=0;i<32;i++) tempbuf[i+192] = i+160; break; + case 7: for(i=0;i<32;i++) tempbuf[i+192] = i+192; break; + default: for(i=0;i<256;i++) tempbuf[i] = i; break; + } + makepalookup(snum,tempbuf,0,0,0,1); +} + +void playback(void) +{ + long i, j, k; + + ready2send = 0; + recstat = 0; i = reccnt; + while (!keystatus[1]) + { + if (handleevents()) { + if (quitevent) { + keystatus[1] = 1; + quitevent = 0; + } + } + + refreshaudio(); + + while (totalclock >= lockclock+TICSPERFRAME) + { + sampletimer(); + if (i >= reccnt) + { + prepareboard(boardfilename); + for(i=connecthead;i>=0;i=connectpoint2[i]) + initplayersprite((short)i); + totalclock = 0; + i = 0; + } + + k = 0; + for(j=connecthead;j>=0;j=connectpoint2[j]) + { + copybufbyte(&recsync[i][k],&ffsync[j],sizeof(input)); + k++; + } + movethings(); domovethings(); + i++; + } + drawscreen(screenpeek,(totalclock-gotlastpacketclock)*(65536/(TIMERINTSPERSECOND/MOVESPERSECOND))); + + if (keystatus[keys[15]]) + { + keystatus[keys[15]] = 0; + screenpeek = connectpoint2[screenpeek]; + if (screenpeek < 0) screenpeek = connecthead; + drawstatusbar(screenpeek); // Andy did this + } + if (keystatus[keys[14]]) + { + keystatus[keys[14]] = 0; + dimensionmode[screenpeek]++; + if (dimensionmode[screenpeek] > 3) dimensionmode[screenpeek] = 1; + } + } + + musicoff(); + uninitmultiplayers(); + uninittimer(); + uninitinput(); + uninitengine(); + uninitsb(); + uninitgroupfile(); + exit(0); +} + +void setup3dscreen(void) +{ + long i, dax, day, dax2, day2; + + i = setgamemode(fullscreen,xdimgame,ydimgame,bppgame); + if (i < 0) + { + printf("Error setting video mode.\n"); + sendlogoff(); + musicoff(); + uninitmultiplayers(); + uninittimer(); + uninitinput(); + uninitengine(); + uninitsb(); + uninitgroupfile(); + exit(0); + } + + //Make that ugly pink into black in case it ever shows up! + i = 0L; + setpalette(255,1,(char *)&i); + //outp(0x3c8,255); outp(0x3c9,0); outp(0x3c9,0); outp(0x3c9,0); + + screensize = xdim; + if (screensize > xdim) + { + dax = 0; day = 0; + dax2 = xdim-1; day2 = ydim-1; + } + else + { + dax = ((xdim-screensize)>>1); + dax2 = dax+screensize-1; + day = (((ydim-32)-scale(screensize,ydim-32,xdim))>>1); + day2 = day + scale(screensize,ydim-32,xdim)-1; + setview(dax,day,dax2,day2); + } + + flushperms(); + + if (screensize < xdim) + drawtilebackground(0L,0L,BACKGROUND,8,0L,0L,xdim-1L,ydim-1L,0); //Draw background + + if (screensize <= xdim) + { + rotatesprite((xdim-320)<<15,(ydim-32)<<16,65536L,0,STATUSBAR,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); + i = ((xdim-320)>>1); + while (i >= 8) i -= 8, rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL8,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); + if (i >= 4) i -= 4, rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL4,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L); + i = ((xdim-320)>>1)+320; + while (i <= xdim-8) rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL8,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L), i += 8; + if (i <= xdim-4) rotatesprite(i<<16,(ydim-32)<<16,65536L,0,STATUSBARFILL4,0,0,8+16+64+128,0L,0L,xdim-1L,ydim-1L), i += 4; + + drawstatusbar(screenpeek); // Andy did this + } +} + +void findrandomspot(long *x, long *y, short *sectnum) +{ + short startwall, endwall, s, dasector; + long dax, day, daz, minx, maxx, miny, maxy, cnt; + + for(cnt=256;cnt>=0;cnt--) + { + do + { + dasector = mulscale16(krand(),numsectors); + } while ((sector[dasector].ceilingz+(8<<8) >= sector[dasector].floorz) || ((sector[dasector].lotag|sector[dasector].hitag) != 0) || ((sector[dasector].floorstat&1) != 0)); + + startwall = sector[dasector].wallptr; + endwall = startwall+sector[dasector].wallnum; + if (endwall <= startwall) continue; + + dax = 0L; + day = 0L; + minx = 0x7fffffff; maxx = 0x80000000; + miny = 0x7fffffff; maxy = 0x80000000; + + for(s=startwall;s maxx) maxx = wall[s].x; + if (wall[s].y < miny) miny = wall[s].y; + if (wall[s].y > maxy) maxy = wall[s].y; + } + + if ((maxx-minx <= 256) || (maxy-miny <= 256)) continue; + + dax /= (endwall-startwall); + day /= (endwall-startwall); + + if (inside(dax,day,dasector) == 0) continue; + + daz = sector[dasector].floorz-(32<<8); + if (pushmove(&dax,&day,&daz,&dasector,128L,4<<8,4<<8,CLIPMASK0) < 0) continue; + + *x = dax; *y = day; *sectnum = dasector; + return; + } +} + +void warp(long *x, long *y, long *z, short *daang, short *dasector) +{ + short startwall, endwall, s; + long i, j, dax, day, ox, oy; + + ox = *x; oy = *y; + + for(i=0;i= warpsectorcnt) i = 0; + } while (sector[warpsectorlist[i]].hitag != j); + *dasector = warpsectorlist[i]; + break; + } + + //Find center of sector + startwall = sector[*dasector].wallptr; + endwall = startwall+sector[*dasector].wallnum; + dax = 0L, day = 0L; + for(s=startwall;s= 0) + i = s; + } + *x = dax / (endwall-startwall); + *y = day / (endwall-startwall); + *z = sector[*dasector].floorz-(32<<8); + updatesector(*x,*y,dasector); + dax = ((wall[i].x+wall[wall[i].point2].x)>>1); + day = ((wall[i].y+wall[wall[i].point2].y)>>1); + *daang = getangle(dax-*x,day-*y); + + wsayfollow("warp.wav",3072L+(krand()&127)-64,192L,&ox,&oy,0); + wsayfollow("warp.wav",4096L+(krand()&127)-64,256L,x,y,0); +} + +void warpsprite(short spritenum) +{ + short dasectnum; + + dasectnum = sprite[spritenum].sectnum; + warp(&sprite[spritenum].x,&sprite[spritenum].y,&sprite[spritenum].z, + &sprite[spritenum].ang,&dasectnum); + + copybuf(&sprite[spritenum].x,&osprite[spritenum].x,3); + changespritesect(spritenum,dasectnum); + + show2dsprite[spritenum>>3] &= ~(1<<(spritenum&7)); + if (show2dsector[dasectnum>>3]&(1<<(dasectnum&7))) + show2dsprite[spritenum>>3] |= (1<<(spritenum&7)); +} + +void initlava(void) +{ + long x, y, z, r; + + for(z=0;z<32;z++) lavaradcnt[z] = 0; + for(x=-16;x<=16;x++) + for(y=-16;y<=16;y++) + { + r = ksqrt(x*x + y*y); + lavaradx[r][lavaradcnt[r]] = x; + lavarady[r][lavaradcnt[r]] = y; + lavaradcnt[r]++; + } + + for(z=0;z<16;z++) + lavadropsizlookup[z] = 8 / (ksqrt(z)+1); + + for(z=0;z>4)&7)-4)+12; + + lavanumdrops = 0; + lavanumframes = 0; +} + +#if defined(NOASM) +inline long addlava(long bx) +{ + char *b = (char *)bx; + return b[-133] + b[-132] + b[-131] + b[1] + b[-1] + b[131] + b[132]; +} +#elif defined(__WATCOMC__) +#pragma aux addlava =\ + "mov al, byte ptr [ebx-133]",\ + "mov dl, byte ptr [ebx-1]",\ + "add al, byte ptr [ebx-132]",\ + "add dl, byte ptr [ebx+131]",\ + "add al, byte ptr [ebx-131]",\ + "add dl, byte ptr [ebx+132]",\ + "add al, byte ptr [ebx+1]",\ + "add al, dl",\ + parm [ebx]\ + modify exact [eax edx] +long addlava(long); +#elif defined(_MSC_VER) +inline long addlava(long b) +{ + _asm { + mov ebx, b + mov al, byte ptr [ebx-133] + mov dl, byte ptr [ebx-1] + add al, byte ptr [ebx-132] + add dl, byte ptr [ebx+131] + add al, byte ptr [ebx-131] + add dl, byte ptr [ebx+132] + add al, byte ptr [ebx+1] + add al, dl + } +} +#elif defined(__GNUC__) && defined(__i386__) +inline long addlava(long b) +{ + long r; + __asm__ __volatile__ ( + "movb -133(%%ebx), %%al\n\t" + "movb -1(%%ebx), %%dl\n\t" + "addb -132(%%ebx), %%al\n\t" + "addb 131(%%ebx), %%dl\n\t" + "addb -131(%%ebx), %%al\n\t" + "addb 132(%%ebx), %%dl\n\t" + "addb 1(%%ebx), %%al\n\t" + "addb %%dl, %%al" + : "=a" (r) : "b" (b) + : "dx" + ); + return r; +} +#else +#error Unsupported compiler or architecture +#endif + +void movelava(char *dapic) +{ + long i, j, x, y, z, zz, dalavadropsiz, dadropsizlookup; + long dalavax, dalavay, *ptr, *ptr2; + + for(z=min(LAVAMAXDROPS-lavanumdrops-1,3);z>=0;z--) + { + lavadropx[lavanumdrops] = (Brand()&(LAVASIZ-1)); + lavadropy[lavanumdrops] = (Brand()&(LAVASIZ-1)); + lavadropsiz[lavanumdrops] = 1; + lavanumdrops++; + } + + for(z=lavanumdrops-1;z>=0;z--) + { + dadropsizlookup = lavadropsizlookup[lavadropsiz[z]]*(((z&1)<<1)-1); + dalavadropsiz = lavadropsiz[z]; + dalavax = lavadropx[z]; dalavay = lavadropy[z]; + for(zz=lavaradcnt[lavadropsiz[z]]-1;zz>=0;zz--) + { + i = (((lavaradx[dalavadropsiz][zz]+dalavax)&(LAVASIZ-1))< 10) + { + lavanumdrops--; + lavadropx[z] = lavadropx[lavanumdrops]; + lavadropy[z] = lavadropy[lavanumdrops]; + lavadropsiz[z] = lavadropsiz[lavanumdrops]; + } + } + + //Back up dapic with 1 pixel extra on each boundary + //(to prevent anding for wrap-around) + ptr = (long *)dapic; + ptr2 = (long *)((LAVASIZ+4)+1+((long)lavabakpic)); + for(x=0;x>2);y>0;y--) *ptr2++ = ((*ptr++)&0x1f1f1f1f); + ptr2++; + } + for(y=0;y>3)+ + ((addlava(y+1)&0xf8)<<5)+ + ((addlava(y+2)&0xf8)<<13)+ + ((addlava(y+3)&0xf8)<<21)+ + 0xc2c2c2c2; + } + } + + lavanumframes++; +} + +void doanimations(void) +{ + long i, j; + + for(i=animatecnt-1;i>=0;i--) + { + j = *animateptr[i]; + + if (j < animategoal[i]) + j = min(j+animatevel[i]*TICSPERFRAME,animategoal[i]); + else + j = max(j-animatevel[i]*TICSPERFRAME,animategoal[i]); + animatevel[i] += animateacc[i]; + + *animateptr[i] = j; + + if (j == animategoal[i]) + { + animatecnt--; + if (i != animatecnt) + { + stopinterpolation(animateptr[i]); + animateptr[i] = animateptr[animatecnt]; + animategoal[i] = animategoal[animatecnt]; + animatevel[i] = animatevel[animatecnt]; + animateacc[i] = animateacc[animatecnt]; + } + } + } +} + +long getanimationgoal(long animptr) +{ + long i; + + for(i=animatecnt-1;i>=0;i--) + if ((long *)animptr == animateptr[i]) return(i); + return(-1); +} + +long setanimation(long *animptr, long thegoal, long thevel, long theacc) +{ + long i, j; + + if (animatecnt >= MAXANIMATES) return(-1); + + j = animatecnt; + for(i=animatecnt-1;i>=0;i--) + if (animptr == animateptr[i]) + { j = i; break; } + + setinterpolation(animptr); + + animateptr[j] = animptr; + animategoal[j] = thegoal; + animatevel[j] = thevel; + animateacc[j] = theacc; + if (j == animatecnt) animatecnt++; + return(j); +} + +void checkmasterslaveswitch(void) +{ + long i, j; + + if (option[4] == 0) return; + + j = 0; + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (ssync[i].bits&512) j++; + if (j != 1) return; + + i = connecthead; + for(j=connectpoint2[i];j>=0;j=connectpoint2[j]) + { + if (ssync[j].bits&512) + { + connectpoint2[i] = connectpoint2[j]; + connectpoint2[j] = connecthead; + connecthead = (short)j; + + oloc.fvel = loc.fvel+1; + oloc.svel = loc.svel+1; + oloc.avel = loc.avel+1; + oloc.bits = loc.bits+1; + for(i=0;i=0;i=connectpoint2[i]) + { + if (myconnectindex == i) break; + j++; + } + if (j == 1) + Bstrcpy(getmessage,"Player 1 (Master)"); + else + Bsprintf(getmessage,"Player %ld (Slave)",j); + getmessageleng = Bstrlen(getmessage); + getmessagetimeoff = totalclock+120; + + return; + } + i = j; + } +} + + +long testneighborsectors(short sect1, short sect2) +{ + short i, startwall, num1, num2; + + num1 = sector[sect1].wallnum; + num2 = sector[sect2].wallnum; + if (num1 < num2) //Traverse walls of sector with fewest walls (for speed) + { + startwall = sector[sect1].wallptr; + for(i=num1-1;i>=0;i--) + if (wall[i+startwall].nextsector == sect2) + return(1); + } + else + { + startwall = sector[sect2].wallptr; + for(i=num2-1;i>=0;i--) + if (wall[i+startwall].nextsector == sect1) + return(1); + } + return(0); +} + +long loadgame(void) +{ + long i; + long fil; + + if ((fil = kopen4load("save0000.gam",0)) == -1) return(-1); + + kdfread(&numplayers,4,1,fil); + kdfread(&myconnectindex,4,1,fil); + kdfread(&connecthead,4,1,fil); + kdfread(connectpoint2,4,MAXPLAYERS,fil); + + //Make sure palookups get set, sprites will get overwritten later + for(i=connecthead;i>=0;i=connectpoint2[i]) initplayersprite((short)i); + + kdfread(posx,4,MAXPLAYERS,fil); + kdfread(posy,4,MAXPLAYERS,fil); + kdfread(posz,4,MAXPLAYERS,fil); + kdfread(horiz,4,MAXPLAYERS,fil); + kdfread(zoom,4,MAXPLAYERS,fil); + kdfread(hvel,4,MAXPLAYERS,fil); + kdfread(ang,2,MAXPLAYERS,fil); + kdfread(cursectnum,2,MAXPLAYERS,fil); + kdfread(ocursectnum,2,MAXPLAYERS,fil); + kdfread(playersprite,2,MAXPLAYERS,fil); + kdfread(deaths,2,MAXPLAYERS,fil); + kdfread(lastchaingun,4,MAXPLAYERS,fil); + kdfread(health,4,MAXPLAYERS,fil); + kdfread(numgrabbers,2,MAXPLAYERS,fil); + kdfread(nummissiles,2,MAXPLAYERS,fil); + kdfread(numbombs,2,MAXPLAYERS,fil); + kdfread(flytime,4,MAXPLAYERS,fil); + kdfread(oflags,2,MAXPLAYERS,fil); + kdfread(dimensionmode,1,MAXPLAYERS,fil); + kdfread(revolvedoorstat,1,MAXPLAYERS,fil); + kdfread(revolvedoorang,2,MAXPLAYERS,fil); + kdfread(revolvedoorrotang,2,MAXPLAYERS,fil); + kdfread(revolvedoorx,4,MAXPLAYERS,fil); + kdfread(revolvedoory,4,MAXPLAYERS,fil); + + kdfread(&numsectors,2,1,fil); + kdfread(sector,sizeof(sectortype),numsectors,fil); + kdfread(&numwalls,2,1,fil); + kdfread(wall,sizeof(walltype),numwalls,fil); + //Store all sprites (even holes) to preserve indeces + kdfread(sprite,sizeof(spritetype),MAXSPRITES,fil); + kdfread(headspritesect,2,MAXSECTORS+1,fil); + kdfread(prevspritesect,2,MAXSPRITES,fil); + kdfread(nextspritesect,2,MAXSPRITES,fil); + kdfread(headspritestat,2,MAXSTATUS+1,fil); + kdfread(prevspritestat,2,MAXSPRITES,fil); + kdfread(nextspritestat,2,MAXSPRITES,fil); + + kdfread(&fvel,4,1,fil); + kdfread(&svel,4,1,fil); + kdfread(&avel,4,1,fil); + + kdfread(&locselectedgun,4,1,fil); + kdfread(&loc.fvel,1,1,fil); + kdfread(&oloc.fvel,1,1,fil); + kdfread(&loc.svel,1,1,fil); + kdfread(&oloc.svel,1,1,fil); + kdfread(&loc.avel,1,1,fil); + kdfread(&oloc.avel,1,1,fil); + kdfread(&loc.bits,2,1,fil); + kdfread(&oloc.bits,2,1,fil); + + kdfread(&locselectedgun2,4,1,fil); + kdfread(&loc2.fvel,sizeof(input),1,fil); + + kdfread(ssync,sizeof(input),MAXPLAYERS,fil); + kdfread(osync,sizeof(input),MAXPLAYERS,fil); + + kdfread(boardfilename,1,80,fil); + kdfread(&screenpeek,2,1,fil); + kdfread(&oldmousebstatus,2,1,fil); + kdfread(&brightness,2,1,fil); + kdfread(&neartagsector,2,1,fil); + kdfread(&neartagwall,2,1,fil); + kdfread(&neartagsprite,2,1,fil); + kdfread(&lockclock,4,1,fil); + kdfread(&neartagdist,4,1,fil); + kdfread(&neartaghitdist,4,1,fil); + + kdfread(turnspritelist,2,16,fil); + kdfread(&turnspritecnt,2,1,fil); + kdfread(warpsectorlist,2,16,fil); + kdfread(&warpsectorcnt,2,1,fil); + kdfread(xpanningsectorlist,2,16,fil); + kdfread(&xpanningsectorcnt,2,1,fil); + kdfread(ypanningwalllist,2,64,fil); + kdfread(&ypanningwallcnt,2,1,fil); + kdfread(floorpanninglist,2,64,fil); + kdfread(&floorpanningcnt,2,1,fil); + kdfread(dragsectorlist,2,16,fil); + kdfread(dragxdir,2,16,fil); + kdfread(dragydir,2,16,fil); + kdfread(&dragsectorcnt,2,1,fil); + kdfread(dragx1,4,16,fil); + kdfread(dragy1,4,16,fil); + kdfread(dragx2,4,16,fil); + kdfread(dragy2,4,16,fil); + kdfread(dragfloorz,4,16,fil); + kdfread(&swingcnt,2,1,fil); + kdfread(swingwall,2,32*5,fil); + kdfread(swingsector,2,32,fil); + kdfread(swingangopen,2,32,fil); + kdfread(swingangclosed,2,32,fil); + kdfread(swingangopendir,2,32,fil); + kdfread(swingang,2,32,fil); + kdfread(swinganginc,2,32,fil); + kdfread(swingx,4,32*8,fil); + kdfread(swingy,4,32*8,fil); + kdfread(revolvesector,2,4,fil); + kdfread(revolveang,2,4,fil); + kdfread(&revolvecnt,2,1,fil); + kdfread(revolvex,4,4*16,fil); + kdfread(revolvey,4,4*16,fil); + kdfread(revolvepivotx,4,4,fil); + kdfread(revolvepivoty,4,4,fil); + kdfread(subwaytracksector,2,4*128,fil); + kdfread(subwaynumsectors,2,4,fil); + kdfread(&subwaytrackcnt,2,1,fil); + kdfread(subwaystop,4,4*8,fil); + kdfread(subwaystopcnt,4,4,fil); + kdfread(subwaytrackx1,4,4,fil); + kdfread(subwaytracky1,4,4,fil); + kdfread(subwaytrackx2,4,4,fil); + kdfread(subwaytracky2,4,4,fil); + kdfread(subwayx,4,4,fil); + kdfread(subwaygoalstop,4,4,fil); + kdfread(subwayvel,4,4,fil); + kdfread(subwaypausetime,4,4,fil); + kdfread(waterfountainwall,2,MAXPLAYERS,fil); + kdfread(waterfountaincnt,2,MAXPLAYERS,fil); + kdfread(slimesoundcnt,2,MAXPLAYERS,fil); + + //Warning: only works if all pointers are in sector structures! + kdfread(animateptr,4,MAXANIMATES,fil); + for(i=MAXANIMATES-1;i>=0;i--) + animateptr[i] = (long *)(animateptr[i]+((long)sector)); + + kdfread(animategoal,4,MAXANIMATES,fil); + kdfread(animatevel,4,MAXANIMATES,fil); + kdfread(animateacc,4,MAXANIMATES,fil); + kdfread(&animatecnt,4,1,fil); + + kdfread(&totalclock,4,1,fil); + kdfread(&numframes,4,1,fil); + kdfread(&randomseed,4,1,fil); + kdfread(&numpalookups,2,1,fil); + + kdfread(&visibility,4,1,fil); + kdfread(¶llaxvisibility,4,1,fil); + kdfread(¶llaxtype,1,1,fil); + kdfread(¶llaxyoffs,4,1,fil); + kdfread(pskyoff,2,MAXPSKYTILES,fil); + kdfread(&pskybits,2,1,fil); + + kdfread(&mirrorcnt,2,1,fil); + kdfread(mirrorwall,2,mirrorcnt,fil); + kdfread(mirrorsector,2,mirrorcnt,fil); + + //I should save off interpolation list, but they're pointers :( + numinterpolations = 0; + startofdynamicinterpolations = 0; + + kclose(fil); + + for(i=connecthead;i>=0;i=connectpoint2[i]) initplayersprite((short)i); + + totalclock = lockclock; + ototalclock = lockclock; + + Bstrcpy(getmessage,"Game loaded."); + getmessageleng = Bstrlen(getmessage); + getmessagetimeoff = totalclock+360+(getmessageleng<<4); + return(0); +} + +long savegame(void) +{ + long i; + BFILE *fil; + + if ((fil = Bfopen("save0000.gam","wb")) == 0) return(-1); + + dfwrite(&numplayers,4,1,fil); + dfwrite(&myconnectindex,4,1,fil); + dfwrite(&connecthead,4,1,fil); + dfwrite(connectpoint2,4,MAXPLAYERS,fil); + + dfwrite(posx,4,MAXPLAYERS,fil); + dfwrite(posy,4,MAXPLAYERS,fil); + dfwrite(posz,4,MAXPLAYERS,fil); + dfwrite(horiz,4,MAXPLAYERS,fil); + dfwrite(zoom,4,MAXPLAYERS,fil); + dfwrite(hvel,4,MAXPLAYERS,fil); + dfwrite(ang,2,MAXPLAYERS,fil); + dfwrite(cursectnum,2,MAXPLAYERS,fil); + dfwrite(ocursectnum,2,MAXPLAYERS,fil); + dfwrite(playersprite,2,MAXPLAYERS,fil); + dfwrite(deaths,2,MAXPLAYERS,fil); + dfwrite(lastchaingun,4,MAXPLAYERS,fil); + dfwrite(health,4,MAXPLAYERS,fil); + dfwrite(numgrabbers,2,MAXPLAYERS,fil); + dfwrite(nummissiles,2,MAXPLAYERS,fil); + dfwrite(numbombs,2,MAXPLAYERS,fil); + dfwrite(flytime,4,MAXPLAYERS,fil); + dfwrite(oflags,2,MAXPLAYERS,fil); + dfwrite(dimensionmode,1,MAXPLAYERS,fil); + dfwrite(revolvedoorstat,1,MAXPLAYERS,fil); + dfwrite(revolvedoorang,2,MAXPLAYERS,fil); + dfwrite(revolvedoorrotang,2,MAXPLAYERS,fil); + dfwrite(revolvedoorx,4,MAXPLAYERS,fil); + dfwrite(revolvedoory,4,MAXPLAYERS,fil); + + dfwrite(&numsectors,2,1,fil); + dfwrite(sector,sizeof(sectortype),numsectors,fil); + dfwrite(&numwalls,2,1,fil); + dfwrite(wall,sizeof(walltype),numwalls,fil); + //Store all sprites (even holes) to preserve indeces + dfwrite(sprite,sizeof(spritetype),MAXSPRITES,fil); + dfwrite(headspritesect,2,MAXSECTORS+1,fil); + dfwrite(prevspritesect,2,MAXSPRITES,fil); + dfwrite(nextspritesect,2,MAXSPRITES,fil); + dfwrite(headspritestat,2,MAXSTATUS+1,fil); + dfwrite(prevspritestat,2,MAXSPRITES,fil); + dfwrite(nextspritestat,2,MAXSPRITES,fil); + + dfwrite(&fvel,4,1,fil); + dfwrite(&svel,4,1,fil); + dfwrite(&avel,4,1,fil); + + dfwrite(&locselectedgun,4,1,fil); + dfwrite(&loc.fvel,1,1,fil); + dfwrite(&oloc.fvel,1,1,fil); + dfwrite(&loc.svel,1,1,fil); + dfwrite(&oloc.svel,1,1,fil); + dfwrite(&loc.avel,1,1,fil); + dfwrite(&oloc.avel,1,1,fil); + dfwrite(&loc.bits,2,1,fil); + dfwrite(&oloc.bits,2,1,fil); + + dfwrite(&locselectedgun2,4,1,fil); + dfwrite(&loc2.fvel,sizeof(input),1,fil); + + dfwrite(ssync,sizeof(input),MAXPLAYERS,fil); + dfwrite(osync,sizeof(input),MAXPLAYERS,fil); + + dfwrite(boardfilename,1,80,fil); + dfwrite(&screenpeek,2,1,fil); + dfwrite(&oldmousebstatus,2,1,fil); + dfwrite(&brightness,2,1,fil); + dfwrite(&neartagsector,2,1,fil); + dfwrite(&neartagwall,2,1,fil); + dfwrite(&neartagsprite,2,1,fil); + dfwrite(&lockclock,4,1,fil); + dfwrite(&neartagdist,4,1,fil); + dfwrite(&neartaghitdist,4,1,fil); + + dfwrite(turnspritelist,2,16,fil); + dfwrite(&turnspritecnt,2,1,fil); + dfwrite(warpsectorlist,2,16,fil); + dfwrite(&warpsectorcnt,2,1,fil); + dfwrite(xpanningsectorlist,2,16,fil); + dfwrite(&xpanningsectorcnt,2,1,fil); + dfwrite(ypanningwalllist,2,64,fil); + dfwrite(&ypanningwallcnt,2,1,fil); + dfwrite(floorpanninglist,2,64,fil); + dfwrite(&floorpanningcnt,2,1,fil); + dfwrite(dragsectorlist,2,16,fil); + dfwrite(dragxdir,2,16,fil); + dfwrite(dragydir,2,16,fil); + dfwrite(&dragsectorcnt,2,1,fil); + dfwrite(dragx1,4,16,fil); + dfwrite(dragy1,4,16,fil); + dfwrite(dragx2,4,16,fil); + dfwrite(dragy2,4,16,fil); + dfwrite(dragfloorz,4,16,fil); + dfwrite(&swingcnt,2,1,fil); + dfwrite(swingwall,2,32*5,fil); + dfwrite(swingsector,2,32,fil); + dfwrite(swingangopen,2,32,fil); + dfwrite(swingangclosed,2,32,fil); + dfwrite(swingangopendir,2,32,fil); + dfwrite(swingang,2,32,fil); + dfwrite(swinganginc,2,32,fil); + dfwrite(swingx,4,32*8,fil); + dfwrite(swingy,4,32*8,fil); + dfwrite(revolvesector,2,4,fil); + dfwrite(revolveang,2,4,fil); + dfwrite(&revolvecnt,2,1,fil); + dfwrite(revolvex,4,4*16,fil); + dfwrite(revolvey,4,4*16,fil); + dfwrite(revolvepivotx,4,4,fil); + dfwrite(revolvepivoty,4,4,fil); + dfwrite(subwaytracksector,2,4*128,fil); + dfwrite(subwaynumsectors,2,4,fil); + dfwrite(&subwaytrackcnt,2,1,fil); + dfwrite(subwaystop,4,4*8,fil); + dfwrite(subwaystopcnt,4,4,fil); + dfwrite(subwaytrackx1,4,4,fil); + dfwrite(subwaytracky1,4,4,fil); + dfwrite(subwaytrackx2,4,4,fil); + dfwrite(subwaytracky2,4,4,fil); + dfwrite(subwayx,4,4,fil); + dfwrite(subwaygoalstop,4,4,fil); + dfwrite(subwayvel,4,4,fil); + dfwrite(subwaypausetime,4,4,fil); + dfwrite(waterfountainwall,2,MAXPLAYERS,fil); + dfwrite(waterfountaincnt,2,MAXPLAYERS,fil); + dfwrite(slimesoundcnt,2,MAXPLAYERS,fil); + + //Warning: only works if all pointers are in sector structures! + for(i=MAXANIMATES-1;i>=0;i--) + animateptr[i] = (long *)(animateptr[i]-((long)sector)); + dfwrite(animateptr,4,MAXANIMATES,fil); + for(i=MAXANIMATES-1;i>=0;i--) + animateptr[i] = (long *)(animateptr[i]+((long)sector)); + + dfwrite(animategoal,4,MAXANIMATES,fil); + dfwrite(animatevel,4,MAXANIMATES,fil); + dfwrite(animateacc,4,MAXANIMATES,fil); + dfwrite(&animatecnt,4,1,fil); + + dfwrite(&totalclock,4,1,fil); + dfwrite(&numframes,4,1,fil); + dfwrite(&randomseed,4,1,fil); + dfwrite(&numpalookups,2,1,fil); + + dfwrite(&visibility,4,1,fil); + dfwrite(¶llaxvisibility,4,1,fil); + dfwrite(¶llaxtype,1,1,fil); + dfwrite(¶llaxyoffs,4,1,fil); + dfwrite(pskyoff,2,MAXPSKYTILES,fil); + dfwrite(&pskybits,2,1,fil); + + dfwrite(&mirrorcnt,2,1,fil); + dfwrite(mirrorwall,2,mirrorcnt,fil); + dfwrite(mirrorsector,2,mirrorcnt,fil); + + Bfclose(fil); + + Bstrcpy(getmessage,"Game saved."); + getmessageleng = Bstrlen(getmessage); + getmessagetimeoff = totalclock+360+(getmessageleng<<4); + return(0); +} + +void faketimerhandler(void) +{ + short other, packbufleng; + long i, j, k, l; + + sampletimer(); + if ((totalclock < ototalclock+(TIMERINTSPERSECOND/MOVESPERSECOND)) || (ready2send == 0)) return; + ototalclock += (TIMERINTSPERSECOND/MOVESPERSECOND); + + getpackets(); + if (getoutputcirclesize() >= 16) return; + getinput(); + + /* + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (i != myconnectindex) + { + k = (movefifoend[myconnectindex]-1)-movefifoend[i]; + myminlag[i] = min(myminlag[i],k); + mymaxlag = max(mymaxlag,k); + } + + if (((movefifoend[myconnectindex]-1)&(TIMERUPDATESIZ-1)) == 0) + { + i = mymaxlag-bufferjitter; mymaxlag = 0; + if (i > 0) bufferjitter += ((2+i)>>2); + else if (i < 0) bufferjitter -= ((2-i)>>2); + } + */ + + if (networkmode == 1) + { + packbuf[2] = 0; j = 3; + if (loc.fvel != oloc.fvel) packbuf[j++] = loc.fvel, packbuf[2] |= 1; + if (loc.svel != oloc.svel) packbuf[j++] = loc.svel, packbuf[2] |= 2; + if (loc.avel != oloc.avel) packbuf[j++] = loc.avel, packbuf[2] |= 4; + if ((loc.bits^oloc.bits)&0x00ff) packbuf[j++] = (loc.bits&255), packbuf[2] |= 8; + if ((loc.bits^oloc.bits)&0xff00) packbuf[j++] = ((loc.bits>>8)&255), packbuf[2] |= 16; + copybufbyte(&loc,&oloc,sizeof(input)); + + copybufbyte(&loc,&baksync[movefifoend[myconnectindex]][myconnectindex],sizeof(input)); + movefifoend[myconnectindex] = ((movefifoend[myconnectindex]+1)&(MOVEFIFOSIZ-1)); + + for(i=connecthead;i>=0;i=connectpoint2[i]) + if (i != myconnectindex) + { + packbuf[0] = 17; + packbuf[1] = (char)((movefifoend[myconnectindex]-movefifoend[i])&(MOVEFIFOSIZ-1)); + + k = j; + if ((myconnectindex == connecthead) || ((i == connecthead) && (myconnectindex == connectpoint2[connecthead]))) + { + while (syncvalhead != syncvaltail) + { + packbuf[j++] = syncval[syncvaltail]; + syncvaltail = ((syncvaltail+1)&(MOVEFIFOSIZ-1)); + } + } + sendpacket(i,packbuf,j); + j = k; + } + + gotlastpacketclock = totalclock; + return; + } + + //MASTER (or 1 player game) + if ((myconnectindex == connecthead) || (option[4] == 0)) + { + copybufbyte(&loc,&ffsync[myconnectindex],sizeof(input)); + + if (option[4] != 0) + { + packbuf[0] = 0; + j = ((numplayers+1)>>1)+1; + for(k=1;k=0;i=connectpoint2[i]) + { + l = 0; + if (ffsync[i].fvel != osync[i].fvel) packbuf[j++] = ffsync[i].fvel, l |= 1; + if (ffsync[i].svel != osync[i].svel) packbuf[j++] = ffsync[i].svel, l |= 2; + if (ffsync[i].avel != osync[i].avel) packbuf[j++] = ffsync[i].avel, l |= 4; + if (ffsync[i].bits != osync[i].bits) + { + packbuf[j++] = (ffsync[i].bits&255); + packbuf[j++] = ((ffsync[i].bits>>8)&255); + l |= 8; + } + packbuf[k>>3] |= (l<<(k&7)); + k += 4; + + copybufbyte(&ffsync[i],&osync[i],sizeof(input)); + } + + while (syncvalhead != syncvaltail) + { + packbuf[j++] = syncval[syncvaltail]; + syncvaltail = ((syncvaltail+1)&(MOVEFIFOSIZ-1)); + } + + for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) + sendpacket(i,packbuf,j); + } + else if (numplayers >= 2) + { + if (keystatus[0xb5]) + { + keystatus[0xb5] = 0; + locselectedgun2++; if (locselectedgun2 >= 3) locselectedgun2 = 0; + } + + //Second player on 1 computer mode + loc2.fvel = min(max(fvel2,-128+8),127-8); + loc2.svel = min(max(svel2,-128+8),127-8); + loc2.avel = min(max(avel2,-128+16),127-16); + loc2.bits = (locselectedgun2<<13); + loc2.bits |= keystatus[0x45]; //Stand high + loc2.bits |= (keystatus[0x47]<<1); //Stand low + loc2.bits |= (1<<8); //Run + loc2.bits |= (keystatus[0x49]<<2); //Look up + loc2.bits |= (keystatus[0x37]<<3); //Look down + loc2.bits |= (keystatus[0x50]<<10); //Space + loc2.bits |= (keystatus[0x52]<<11); //Shoot + + other = connectpoint2[myconnectindex]; + if (other < 0) other = connecthead; + + copybufbyte(&loc2,&ffsync[other],sizeof(input)); + } + movethings(); //Move EVERYTHING (you too!) + } + else //I am a SLAVE + { + packbuf[0] = 1; packbuf[1] = 0; j = 2; + if (loc.fvel != oloc.fvel) packbuf[j++] = loc.fvel, packbuf[1] |= 1; + if (loc.svel != oloc.svel) packbuf[j++] = loc.svel, packbuf[1] |= 2; + if (loc.avel != oloc.avel) packbuf[j++] = loc.avel, packbuf[1] |= 4; + if ((loc.bits^oloc.bits)&0x00ff) packbuf[j++] = (loc.bits&255), packbuf[1] |= 8; + if ((loc.bits^oloc.bits)&0xff00) packbuf[j++] = ((loc.bits>>8)&255), packbuf[1] |= 16; + copybufbyte(&loc,&oloc,sizeof(input)); + sendpacket(connecthead,packbuf,j); + } +} + +void getpackets(void) +{ + long i, j, k, l; + long other, packbufleng, movecnt; + + if (option[4] == 0) return; + + movecnt = 0; + while ((packbufleng = getpacket(&other,packbuf)) > 0) + { + switch(packbuf[0]) + { + case 0: //[0] (receive master sync buffer) + j = ((numplayers+1)>>1)+1; k = (1<<3); + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + l = (packbuf[k>>3]>>(k&7)); + if (l&1) ffsync[i].fvel = packbuf[j++]; + if (l&2) ffsync[i].svel = packbuf[j++]; + if (l&4) ffsync[i].avel = packbuf[j++]; + if (l&8) + { + ffsync[i].bits = ((short)packbuf[j])+(((short)packbuf[j+1])<<8); + j += 2; + } + k += 4; + } + + while (j != packbufleng) + { + othersyncval[othersyncvalhead] = packbuf[j++]; + othersyncvalhead = ((othersyncvalhead+1)&(MOVEFIFOSIZ-1)); + } + if ((syncvalhead != syncvaltottail) && (othersyncvalhead != syncvaltottail)) + { + syncstat = 0; + do + { + syncstat |= (syncval[syncvaltottail]^othersyncval[syncvaltottail]); + syncvaltottail = ((syncvaltottail+1)&(MOVEFIFOSIZ-1)); + } while ((syncvalhead != syncvaltottail) && (othersyncvalhead != syncvaltottail)); + } + + movethings(); //Move all players and sprites + movecnt++; + break; + case 1: //[1] (receive slave sync buffer) + j = 2; k = packbuf[1]; + if (k&1) ffsync[other].fvel = packbuf[j++]; + if (k&2) ffsync[other].svel = packbuf[j++]; + if (k&4) ffsync[other].avel = packbuf[j++]; + if (k&8) ffsync[other].bits = ((ffsync[other].bits&0xff00)|((short)packbuf[j++])); + if (k&16) ffsync[other].bits = ((ffsync[other].bits&0x00ff)|(((short)packbuf[j++])<<8)); + break; + case 2: + getmessageleng = packbufleng-1; + for(j=getmessageleng-1;j>=0;j--) getmessage[j] = packbuf[j+1]; + getmessagetimeoff = totalclock+360+(getmessageleng<<4); + wsay("getstuff.wav",8192L,63L,63L); //Added 12/2004 + break; + case 3: + wsay("getstuff.wav",4096L,63L,63L); + break; + /* + case 5: + playerreadyflag[other] = packbuf[1]; + if ((other == connecthead) && (packbuf[1] == 2)) + sendpacket(connecthead,packbuf,2); + break; + */ + case 250: + playerreadyflag[other]++; + break; + case 17: + j = 3; k = packbuf[2]; + if (k&1) ffsync[other].fvel = packbuf[j++]; + if (k&2) ffsync[other].svel = packbuf[j++]; + if (k&4) ffsync[other].avel = packbuf[j++]; + if (k&8) ffsync[other].bits = ((ffsync[other].bits&0xff00)|((short)packbuf[j++])); + if (k&16) ffsync[other].bits = ((ffsync[other].bits&0x00ff)|(((short)packbuf[j++])<<8)); + otherlag[other] = packbuf[1]; + + copybufbyte(&ffsync[other],&baksync[movefifoend[other]][other],sizeof(input)); + movefifoend[other] = ((movefifoend[other]+1)&(MOVEFIFOSIZ-1)); + + while (j != packbufleng) + { + othersyncval[othersyncvalhead] = packbuf[j++]; + othersyncvalhead = ((othersyncvalhead+1)&(MOVEFIFOSIZ-1)); + } + if ((syncvalhead != syncvaltottail) && (othersyncvalhead != syncvaltottail)) + { + syncstat = 0; + do + { + syncstat |= (syncval[syncvaltottail]^othersyncval[syncvaltottail]); + syncvaltottail = ((syncvaltottail+1)&(MOVEFIFOSIZ-1)); + } while ((syncvalhead != syncvaltottail) && (othersyncvalhead != syncvaltottail)); + } + + break; + case 255: //[255] (logout) + keystatus[1] = 1; + break; + } + } + if ((networkmode == 0) && (myconnectindex != connecthead) && ((movecnt&1) == 0)) + { + if (rand()&1) ototalclock += (TICSPERFRAME>>1); + else ototalclock -= (TICSPERFRAME>>1); + } +} + +void drawoverheadmap(long cposx, long cposy, long czoom, short cang) +{ + long i, j, k, l=0, x1, y1, x2=0, y2=0, x3, y3, x4, y4, ox, oy, xoff, yoff; + long dax, day, cosang, sinang, xspan, yspan, sprx, spry; + long xrepeat, yrepeat, z1, z2, startwall, endwall, tilenum, daang; + long xvect, yvect, xvect2, yvect2; + char col; + walltype *wal, *wal2; + spritetype *spr; + + xvect = sintable[(-cang)&2047] * czoom; + yvect = sintable[(1536-cang)&2047] * czoom; + xvect2 = mulscale16(xvect,yxaspect); + yvect2 = mulscale16(yvect,yxaspect); + + //Draw red lines + for(i=0;inextwall; if (k < 0) continue; + + if ((show2dwall[j>>3]&(1<<(j&7))) == 0) continue; + if ((k > j) && ((show2dwall[k>>3]&(1<<(k&7))) > 0)) continue; + + if (sector[wal->nextsector].ceilingz == z1) + if (sector[wal->nextsector].floorz == z2) + if (((wal->cstat|wall[wal->nextwall].cstat)&(16+32)) == 0) continue; + + col = 152; + + if (dimensionmode[screenpeek] == 2) + { + if (sector[i].floorz != sector[i].ceilingz) + if (sector[wal->nextsector].floorz != sector[wal->nextsector].ceilingz) + if (((wal->cstat|wall[wal->nextwall].cstat)&(16+32)) == 0) + if (sector[i].floorz == sector[wal->nextsector].floorz) continue; + if (sector[i].floorpicnum != sector[wal->nextsector].floorpicnum) continue; + if (sector[i].floorshade != sector[wal->nextsector].floorshade) continue; + col = 12; + } + + ox = wal->x-cposx; oy = wal->y-cposy; + x1 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); + y1 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); + + wal2 = &wall[wal->point2]; + ox = wal2->x-cposx; oy = wal2->y-cposy; + x2 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); + y2 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); + + drawline256(x1,y1,x2,y2,col); + } + } + + //Draw sprites + k = playersprite[screenpeek]; + for(i=0;i=0;j=nextspritesect[j]) + if ((show2dsprite[j>>3]&(1<<(j&7))) > 0) + { + spr = &sprite[j]; if (spr->cstat&0x8000) continue; + col = 56; + if (spr->cstat&1) col = 248; + if (j == k) col = 31; + + k = statrate[spr->statnum]; + sprx = spr->x; + spry = spr->y; + if (k >= 0) + { + switch(k) + { + case 0: l = smoothratio; break; + case 1: l = (smoothratio>>1)+(((nummoves-j)&1)<<15); break; + case 3: l = (smoothratio>>2)+(((nummoves-j)&3)<<14); break; + case 7: l = (smoothratio>>3)+(((nummoves-j)&7)<<13); break; + case 15: l = (smoothratio>>4)+(((nummoves-j)&15)<<12); break; + } + sprx = osprite[j].x+mulscale16(sprx-osprite[j].x,l); + spry = osprite[j].y+mulscale16(spry-osprite[j].y,l); + } + + switch (spr->cstat&48) + { + case 0: + ox = sprx-cposx; oy = spry-cposy; + x1 = dmulscale16(ox,xvect,-oy,yvect); + y1 = dmulscale16(oy,xvect2,ox,yvect2); + + if (dimensionmode[screenpeek] == 1) + { + ox = (sintable[(spr->ang+512)&2047]>>7); + oy = (sintable[(spr->ang)&2047]>>7); + x2 = dmulscale16(ox,xvect,-oy,yvect); + y2 = dmulscale16(oy,xvect,ox,yvect); + + if (j == playersprite[screenpeek]) + { + x2 = 0L; + y2 = -(czoom<<5); + } + + x3 = mulscale16(x2,yxaspect); + y3 = mulscale16(y2,yxaspect); + + drawline256(x1-x2+(xdim<<11),y1-y3+(ydim<<11), + x1+x2+(xdim<<11),y1+y3+(ydim<<11),col); + drawline256(x1-y2+(xdim<<11),y1+x3+(ydim<<11), + x1+x2+(xdim<<11),y1+y3+(ydim<<11),col); + drawline256(x1+y2+(xdim<<11),y1-x3+(ydim<<11), + x1+x2+(xdim<<11),y1+y3+(ydim<<11),col); + } + else + { + if (((gotsector[i>>3]&(1<<(i&7))) > 0) && (czoom > 96)) + { + daang = (spr->ang-cang)&2047; + if (j == playersprite[screenpeek]) { x1 = 0; y1 = 0; daang = 0; } + rotatesprite((x1<<4)+(xdim<<15),(y1<<4)+(ydim<<15),mulscale16(czoom*spr->yrepeat,yxaspect),daang,spr->picnum,spr->shade,spr->pal,(spr->cstat&2)>>1,windowx1,windowy1,windowx2,windowy2); + } + } + break; + case 16: + x1 = sprx; y1 = spry; + tilenum = spr->picnum; + xoff = (long)((signed char)((picanm[tilenum]>>8)&255))+((long)spr->xoffset); + if ((spr->cstat&4) > 0) xoff = -xoff; + k = spr->ang; l = spr->xrepeat; + dax = sintable[k&2047]*l; day = sintable[(k+1536)&2047]*l; + l = tilesizx[tilenum]; k = (l>>1)+xoff; + x1 -= mulscale16(dax,k); x2 = x1+mulscale16(dax,l); + y1 -= mulscale16(day,k); y2 = y1+mulscale16(day,l); + + ox = x1-cposx; oy = y1-cposy; + x1 = dmulscale16(ox,xvect,-oy,yvect); + y1 = dmulscale16(oy,xvect2,ox,yvect2); + + ox = x2-cposx; oy = y2-cposy; + x2 = dmulscale16(ox,xvect,-oy,yvect); + y2 = dmulscale16(oy,xvect2,ox,yvect2); + + drawline256(x1+(xdim<<11),y1+(ydim<<11), + x2+(xdim<<11),y2+(ydim<<11),col); + + break; + case 32: + if (dimensionmode[screenpeek] == 1) + { + tilenum = spr->picnum; + xoff = (long)((signed char)((picanm[tilenum]>>8)&255))+((long)spr->xoffset); + yoff = (long)((signed char)((picanm[tilenum]>>16)&255))+((long)spr->yoffset); + if ((spr->cstat&4) > 0) xoff = -xoff; + if ((spr->cstat&8) > 0) yoff = -yoff; + + k = spr->ang; + cosang = sintable[(k+512)&2047]; sinang = sintable[k]; + xspan = tilesizx[tilenum]; xrepeat = spr->xrepeat; + yspan = tilesizy[tilenum]; yrepeat = spr->yrepeat; + + dax = ((xspan>>1)+xoff)*xrepeat; day = ((yspan>>1)+yoff)*yrepeat; + x1 = sprx + dmulscale16(sinang,dax,cosang,day); + y1 = spry + dmulscale16(sinang,day,-cosang,dax); + l = xspan*xrepeat; + x2 = x1 - mulscale16(sinang,l); + y2 = y1 + mulscale16(cosang,l); + l = yspan*yrepeat; + k = -mulscale16(cosang,l); x3 = x2+k; x4 = x1+k; + k = -mulscale16(sinang,l); y3 = y2+k; y4 = y1+k; + + ox = x1-cposx; oy = y1-cposy; + x1 = dmulscale16(ox,xvect,-oy,yvect); + y1 = dmulscale16(oy,xvect2,ox,yvect2); + + ox = x2-cposx; oy = y2-cposy; + x2 = dmulscale16(ox,xvect,-oy,yvect); + y2 = dmulscale16(oy,xvect2,ox,yvect2); + + ox = x3-cposx; oy = y3-cposy; + x3 = dmulscale16(ox,xvect,-oy,yvect); + y3 = dmulscale16(oy,xvect2,ox,yvect2); + + ox = x4-cposx; oy = y4-cposy; + x4 = dmulscale16(ox,xvect,-oy,yvect); + y4 = dmulscale16(oy,xvect2,ox,yvect2); + + drawline256(x1+(xdim<<11),y1+(ydim<<11), + x2+(xdim<<11),y2+(ydim<<11),col); + + drawline256(x2+(xdim<<11),y2+(ydim<<11), + x3+(xdim<<11),y3+(ydim<<11),col); + + drawline256(x3+(xdim<<11),y3+(ydim<<11), + x4+(xdim<<11),y4+(ydim<<11),col); + + drawline256(x4+(xdim<<11),y4+(ydim<<11), + x1+(xdim<<11),y1+(ydim<<11),col); + + } + break; + } + } + + //Draw white lines + for(i=0;inextwall >= 0) continue; + + if ((show2dwall[j>>3]&(1<<(j&7))) == 0) continue; + + if (tilesizx[wal->picnum] == 0) continue; + if (tilesizy[wal->picnum] == 0) continue; + + if (j == k) + { x1 = x2; y1 = y2; } + else + { + ox = wal->x-cposx; oy = wal->y-cposy; + x1 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); + y1 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); + } + + k = wal->point2; wal2 = &wall[k]; + ox = wal2->x-cposx; oy = wal2->y-cposy; + x2 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11); + y2 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11); + + drawline256(x1,y1,x2,y2,24); + } + } +} + + //New movesprite using getzrange. Note that I made the getzrange + //parameters global (&globhiz,&globhihit,&globloz,&globlohit) so they + //don't need to be passed everywhere. Also this should make this + //movesprite function compatible with the older movesprite functions. +long movesprite(short spritenum, long dx, long dy, long dz, long ceildist, long flordist, long clipmask) +{ + long daz, zoffs, tempint; + short retval, dasectnum, datempshort; + spritetype *spr; + + spr = &sprite[spritenum]; + + if ((spr->cstat&128) == 0) + zoffs = -((tilesizy[spr->picnum]*spr->yrepeat)<<1); + else + zoffs = 0; + + dasectnum = spr->sectnum; //Can't modify sprite sectors directly becuase of linked lists + daz = spr->z+zoffs; //Must do this if not using the new centered centering (of course) + retval = clipmove(&spr->x,&spr->y,&daz,&dasectnum,dx,dy, + ((long)spr->clipdist)<<2,ceildist,flordist,clipmask); + + if (dasectnum < 0) retval = -1; + + if ((dasectnum != spr->sectnum) && (dasectnum >= 0)) + changespritesect(spritenum,dasectnum); + + //Set the blocking bit to 0 temporarly so getzrange doesn't pick up + //its own sprite + datempshort = spr->cstat; spr->cstat &= ~1; + getzrange(spr->x,spr->y,spr->z-1,spr->sectnum, + &globhiz,&globhihit,&globloz,&globlohit, + ((long)spr->clipdist)<<2,clipmask); + spr->cstat = datempshort; + + daz = spr->z+zoffs + dz; + if ((daz <= globhiz) || (daz > globloz)) + { + if (retval != 0) return(retval); + return(16384+dasectnum); + } + spr->z = daz-zoffs; + return(retval); +} + + +void waitforeverybody () +{ + long i; + if (numplayers < 2) return; + packbuf[0] = 250; + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if (i != myconnectindex) sendpacket(i,packbuf,1); + if ((!networkmode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master + } + playerreadyflag[myconnectindex]++; + while (1) + { + handleevents(); + refreshaudio(); + + drawrooms(posx[myconnectindex],posy[myconnectindex],posz[myconnectindex],ang[myconnectindex],horiz[myconnectindex],cursectnum[myconnectindex]); + if (!networkmode) Bsprintf(tempbuf,"Master/slave mode"); + else Bsprintf(tempbuf,"Peer-peer mode"); + printext256((xdim>>1)-(strlen(tempbuf)<<2),(ydim>>1)-24,31,0,tempbuf,0); + Bsprintf(tempbuf,"Waiting for players"); + printext256((xdim>>1)-(strlen(tempbuf)<<2),(ydim>>1)-16,31,0,tempbuf,0); + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if (playerreadyflag[i] < playerreadyflag[myconnectindex]) + { + //slaves in M/S mode only wait for master + if ((!networkmode) && (myconnectindex != connecthead) && (i != connecthead)) + { + Bsprintf(tempbuf,"Player %ld",i); + printext256((xdim>>1)-(16<<2),(ydim>>1)+i*8,15,0,tempbuf,0); + } + else + { + Bsprintf(tempbuf,"Player %ld NOT ready",i); + printext256((xdim>>1)-(16<<2),(ydim>>1)+i*8,127,0,tempbuf,0); + } + } + else + { + Bsprintf(tempbuf,"Player %ld ready",i); + printext256((xdim>>1)-(16<<2),(ydim>>1)+i*8,31,0,tempbuf,0); + } + if (i == myconnectindex) + { + Bsprintf(tempbuf,"You->"); + printext256((xdim>>1)-(26<<2),(ydim>>1)+i*8,95,0,tempbuf,0); + } + } + nextpage(); + + + if (quitevent || keystatus[1]) { + sendlogoff(); //Signing off + musicoff(); + uninitmultiplayers(); + uninittimer(); + uninitinput(); + uninitengine(); + uninitsb(); + uninitgroupfile(); + exit(0); + } + + getpackets(); + + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if (playerreadyflag[i] < playerreadyflag[myconnectindex]) break; + if ((!networkmode) && (myconnectindex != connecthead)) { i = -1; break; } //slaves in M/S mode only wait for master + } + if (i < 0) return; + } +} + + +void searchmap(short startsector) +{ + long i, j, dasect, splc, send, startwall, endwall; + short dapic; + walltype *wal; + + if ((startsector < 0) || (startsector >= numsectors)) return; + for(i=0;i<(MAXSECTORS>>3);i++) show2dsector[i] = 0; + for(i=0;i<(MAXWALLS>>3);i++) show2dwall[i] = 0; + for(i=0;i<(MAXSPRITES>>3);i++) show2dsprite[i] = 0; + + automapping = 0; + + //Search your area recursively & set all show2dsector/show2dwalls + tempshort[0] = startsector; + show2dsector[startsector>>3] |= (1<<(startsector&7)); + dapic = sector[startsector].ceilingpicnum; + if (waloff[dapic] == 0) loadtile(dapic); + dapic = sector[startsector].floorpicnum; + if (waloff[dapic] == 0) loadtile(dapic); + for(splc=0,send=1;splc>3] |= (1<<(i&7)); + dapic = wall[i].picnum; + if (waloff[dapic] == 0) loadtile(dapic); + dapic = wall[i].overpicnum; + if (((dapic&0xfffff000) == 0) && (waloff[dapic] == 0)) loadtile(dapic); + + j = wal->nextsector; + if ((j >= 0) && ((show2dsector[j>>3]&(1<<(j&7))) == 0)) + { + show2dsector[j>>3] |= (1<<(j&7)); + + dapic = sector[j].ceilingpicnum; + if (waloff[dapic] == 0) loadtile(dapic); + dapic = sector[j].floorpicnum; + if (waloff[dapic] == 0) loadtile(dapic); + + tempshort[send++] = (short)j; + } + } + + for(i=headspritesect[dasect];i>=0;i=nextspritesect[i]) + { + show2dsprite[i>>3] |= (1<<(i&7)); + dapic = sprite[i].picnum; + if (waloff[dapic] == 0) loadtile(dapic); + } + } +} + +void setinterpolation(long *posptr) +{ + long i; + + if (numinterpolations >= MAXINTERPOLATIONS) return; + for(i=numinterpolations-1;i>=0;i--) + if (curipos[i] == posptr) return; + curipos[numinterpolations] = posptr; + oldipos[numinterpolations] = *posptr; + numinterpolations++; +} + +void stopinterpolation(long *posptr) +{ + long i; + + for(i=numinterpolations-1;i>=startofdynamicinterpolations;i--) + if (curipos[i] == posptr) + { + numinterpolations--; + oldipos[i] = oldipos[numinterpolations]; + bakipos[i] = bakipos[numinterpolations]; + curipos[i] = curipos[numinterpolations]; + } +} + +void updateinterpolations(void) //Stick at beginning of domovethings +{ + long i; + + for(i=numinterpolations-1;i>=0;i--) oldipos[i] = *curipos[i]; +} + +void dointerpolations(void) //Stick at beginning of drawscreen +{ + long i, j, odelta, ndelta; + + ndelta = 0; j = 0; + for(i=numinterpolations-1;i>=0;i--) + { + bakipos[i] = *curipos[i]; + odelta = ndelta; ndelta = (*curipos[i])-oldipos[i]; + if (odelta != ndelta) j = mulscale16(ndelta,smoothratio); + *curipos[i] = oldipos[i]+j; + } +} + +void restoreinterpolations(void) //Stick at end of drawscreen +{ + long i; + + for(i=numinterpolations-1;i>=0;i--) *curipos[i] = bakipos[i]; +} + +void printext(long x, long y, char *buffer, short tilenum, char invisiblecol) +{ + long i; + char ch; + + for(i=0;buffer[i]!=0;i++) + { + ch = buffer[i]; + rotatesprite((x-((8&15)<<3))<<16,(y-((8>>4)<<3))<<16,65536L,0,tilenum,0,0,8+16+64+128,x,y,x+7,y+7); + rotatesprite((x-((ch&15)<<3))<<16,(y-((ch>>4)<<3))<<16,65536L,0,tilenum,0,0,8+16+128,x,y,x+7,y+7); + x += 8; + } +} + +void drawtilebackground (long thex, long they, short tilenum, + signed char shade, long cx1, long cy1, + long cx2, long cy2, char dapalnum) +{ + long x, y, xsiz, ysiz, tx1, ty1, tx2, ty2; + + xsiz = tilesizx[tilenum]; tx1 = cx1/xsiz; tx2 = cx2/xsiz; + ysiz = tilesizy[tilenum]; ty1 = cy1/ysiz; ty2 = cy2/ysiz; + + for(x=tx1;x<=tx2;x++) + for(y=ty1;y<=ty2;y++) + rotatesprite(x*xsiz<<16,y*ysiz<<16,65536L,0,tilenum,shade,dapalnum,8+16+64+128,cx1,cy1,cx2,cy2); +} + + +/* + * vim:ts=4:sw=4: + */ diff --git a/polymer/build/src/glbuild.c b/polymer/build/src/glbuild.c index 060c9ace3..e5ad09eb0 100644 --- a/polymer/build/src/glbuild.c +++ b/polymer/build/src/glbuild.c @@ -1,359 +1,359 @@ -#include "glbuild.h" -#include "baselayer.h" -#include -#include -#include - -#if defined DYNAMIC_OPENGL && defined USE_OPENGL - -#ifdef RENDERTYPESDL -#include "SDL.h" -#endif - -void (APIENTRY * bglClearColor)( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ); -void (APIENTRY * bglClear)( GLbitfield mask ); -void (APIENTRY * bglColorMask)( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ); -void (APIENTRY * bglAlphaFunc)( GLenum func, GLclampf ref ); -void (APIENTRY * bglBlendFunc)( GLenum sfactor, GLenum dfactor ); -void (APIENTRY * bglCullFace)( GLenum mode ); -void (APIENTRY * bglFrontFace)( GLenum mode ); -void (APIENTRY * bglPolygonOffset)( GLfloat factor, GLfloat units ); -void (APIENTRY * bglPolygonMode)( GLenum face, GLenum mode ); -void (APIENTRY * bglEnable)( GLenum cap ); -void (APIENTRY * bglDisable)( GLenum cap ); -void (APIENTRY * bglGetFloatv)( GLenum pname, GLfloat *params ); -void (APIENTRY * bglGetIntegerv)( GLenum pname, GLint *params ); -void (APIENTRY * bglPushAttrib)( GLbitfield mask ); -void (APIENTRY * bglPopAttrib)( void ); -GLenum (APIENTRY * bglGetError)( void ); -const GLubyte* (APIENTRY * bglGetString)( GLenum name ); -void (APIENTRY * bglHint)( GLenum target, GLenum mode ); - -// Depth -void (APIENTRY * bglDepthFunc)( GLenum func ); -void (APIENTRY * bglDepthMask)( GLboolean flag ); -void (APIENTRY * bglDepthRange)( GLclampd near_val, GLclampd far_val ); - -// Matrix -void (APIENTRY * bglMatrixMode)( GLenum mode ); -void (APIENTRY * bglOrtho)( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val ); -void (APIENTRY * bglFrustum)( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val ); -void (APIENTRY * bglViewport)( GLint x, GLint y, GLsizei width, GLsizei height ); -void (APIENTRY * bglPushMatrix)( void ); -void (APIENTRY * bglPopMatrix)( void ); -void (APIENTRY * bglLoadIdentity)( void ); -void (APIENTRY * bglLoadMatrixf)( const GLfloat *m ); - -// Drawing -void (APIENTRY * bglBegin)( GLenum mode ); -void (APIENTRY * bglEnd)( void ); -void (APIENTRY * bglVertex2f)( GLfloat x, GLfloat y ); -void (APIENTRY * bglVertex2i)( GLint x, GLint y ); -void (APIENTRY * bglVertex3d)( GLdouble x, GLdouble y, GLdouble z ); -void (APIENTRY * bglVertex3fv)( const GLfloat *v ); -void (APIENTRY * bglColor4f)( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ); -void (APIENTRY * bglColor4ub)( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha ); -void (APIENTRY * bglTexCoord2d)( GLdouble s, GLdouble t ); -void (APIENTRY * bglTexCoord2f)( GLfloat s, GLfloat t ); - -// Lighting -void (APIENTRY * bglShadeModel)( GLenum mode ); - -// Raster funcs -void (APIENTRY * bglReadPixels)( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels ); - -// Texture mapping -void (APIENTRY * bglTexEnvf)( GLenum target, GLenum pname, GLfloat param ); -void (APIENTRY * bglGenTextures)( GLsizei n, GLuint *textures ); // 1.1 -void (APIENTRY * bglDeleteTextures)( GLsizei n, const GLuint *textures); // 1.1 -void (APIENTRY * bglBindTexture)( GLenum target, GLuint texture ); // 1.1 -void (APIENTRY * bglTexImage2D)( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels ); -void (APIENTRY * bglTexSubImage2D)( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels ); // 1.1 -void (APIENTRY * bglTexParameterf)( GLenum target, GLenum pname, GLfloat param ); -void (APIENTRY * bglTexParameteri)( GLenum target, GLenum pname, GLint param ); -void (APIENTRY * bglGetTexLevelParameteriv)( GLenum target, GLint level, GLenum pname, GLint *params ); -void (APIENTRY * bglCompressedTexImage2DARB)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); -void (APIENTRY * bglGetCompressedTexImageARB)(GLenum, GLint, GLvoid *); - -// Fog -void (APIENTRY * bglFogf)( GLenum pname, GLfloat param ); -void (APIENTRY * bglFogi)( GLenum pname, GLint param ); -void (APIENTRY * bglFogfv)( GLenum pname, const GLfloat *params ); - -#ifdef RENDERTYPEWIN -// Windows -HGLRC (WINAPI * bwglCreateContext)(HDC); -BOOL (WINAPI * bwglDeleteContext)(HGLRC); -PROC (WINAPI * bwglGetProcAddress)(LPCSTR); -BOOL (WINAPI * bwglMakeCurrent)(HDC,HGLRC); - -BOOL (WINAPI * bwglSwapBuffers)(HDC); -int (WINAPI * bwglChoosePixelFormat)(HDC,CONST PIXELFORMATDESCRIPTOR*); -int (WINAPI * bwglDescribePixelFormat)(HDC,int,UINT,LPPIXELFORMATDESCRIPTOR); -int (WINAPI * bwglGetPixelFormat)(HDC); -BOOL (WINAPI * bwglSetPixelFormat)(HDC,int,const PIXELFORMATDESCRIPTOR*); - -static HANDLE hGLDLL; -#endif - - -char *gldriver = NULL; - -static void * getproc_(const char *s, int *err, int fatal, int extension) -{ - void *t; -#if defined RENDERTYPESDL - t = (void*)SDL_GL_GetProcAddress(s); -#elif defined _WIN32 - if (extension) t = (void*)bwglGetProcAddress(s); - else t = (void*)GetProcAddress(hGLDLL,s); -#else -#error Need a dynamic loader for this platform... -#endif - if (!t && fatal) { - initprintf("Failed to find %s in %s\n", s, gldriver); - *err = 1; - } - return t; -} -#define GETPROC(s) getproc_(s,&err,1,0) -#define GETPROCSOFT(s) getproc_(s,&err,0,0) -#define GETPROCEXT(s) getproc_(s,&err,1,1) -#define GETPROCEXTSOFT(s) getproc_(s,&err,0,1) - -int loadgldriver(const char *driver) -{ - void *t; - int err=0; - -#ifdef RENDERTYPEWIN - if (hGLDLL) return 0; -#endif - - if (!driver) { -#ifdef _WIN32 - driver = "OPENGL32.DLL"; -#else - driver = "libGL.so"; -#endif - } - - initprintf("Loading %s\n",driver); - -#if defined RENDERTYPESDL - if (SDL_GL_LoadLibrary(driver)) return -1; -#elif defined _WIN32 - hGLDLL = LoadLibrary(driver); - if (!hGLDLL) return -1; -#endif - gldriver = strdup(driver); - -#ifdef RENDERTYPEWIN - bwglCreateContext = GETPROC("wglCreateContext"); - bwglDeleteContext = GETPROC("wglDeleteContext"); - bwglGetProcAddress = GETPROC("wglGetProcAddress"); - bwglMakeCurrent = GETPROC("wglMakeCurrent"); - - bwglSwapBuffers = GETPROC("wglSwapBuffers"); - bwglChoosePixelFormat = GETPROC("wglChoosePixelFormat"); - bwglDescribePixelFormat = GETPROC("wglDescribePixelFormat"); - bwglGetPixelFormat = GETPROC("wglGetPixelFormat"); - bwglSetPixelFormat = GETPROC("wglSetPixelFormat"); -#endif - - bglClearColor = GETPROC("glClearColor"); - bglClear = GETPROC("glClear"); - bglColorMask = GETPROC("glColorMask"); - bglAlphaFunc = GETPROC("glAlphaFunc"); - bglBlendFunc = GETPROC("glBlendFunc"); - bglCullFace = GETPROC("glCullFace"); - bglFrontFace = GETPROC("glFrontFace"); - bglPolygonOffset = GETPROC("glPolygonOffset"); - bglPolygonMode = GETPROC("glPolygonMode"); - bglEnable = GETPROC("glEnable"); - bglDisable = GETPROC("glDisable"); - bglGetFloatv = GETPROC("glGetFloatv"); - bglGetIntegerv = GETPROC("glGetIntegerv"); - bglPushAttrib = GETPROC("glPushAttrib"); - bglPopAttrib = GETPROC("glPopAttrib"); - bglGetError = GETPROC("glGetError"); - bglGetString = GETPROC("glGetString"); - bglHint = GETPROC("glHint"); - - // Depth - bglDepthFunc = GETPROC("glDepthFunc"); - bglDepthMask = GETPROC("glDepthMask"); - bglDepthRange = GETPROC("glDepthRange"); - - // Matrix - bglMatrixMode = GETPROC("glMatrixMode"); - bglOrtho = GETPROC("glOrtho"); - bglFrustum = GETPROC("glFrustum"); - bglViewport = GETPROC("glViewport"); - bglPushMatrix = GETPROC("glPushMatrix"); - bglPopMatrix = GETPROC("glPopMatrix"); - bglLoadIdentity = GETPROC("glLoadIdentity"); - bglLoadMatrixf = GETPROC("glLoadMatrixf"); - - // Drawing - bglBegin = GETPROC("glBegin"); - bglEnd = GETPROC("glEnd"); - bglVertex2f = GETPROC("glVertex2f"); - bglVertex2i = GETPROC("glVertex2i"); - bglVertex3d = GETPROC("glVertex3d"); - bglVertex3fv = GETPROC("glVertex3fv"); - bglColor4f = GETPROC("glColor4f"); - bglColor4ub = GETPROC("glColor4ub"); - bglTexCoord2d = GETPROC("glTexCoord2d"); - bglTexCoord2f = GETPROC("glTexCoord2f"); - - // Lighting - bglShadeModel = GETPROC("glShadeModel"); - - // Raster funcs - bglReadPixels = GETPROC("glReadPixels"); - - // Texture mapping - bglTexEnvf = GETPROC("glTexEnvf"); - bglGenTextures = GETPROC("glGenTextures"); - bglDeleteTextures = GETPROC("glDeleteTextures"); - bglBindTexture = GETPROC("glBindTexture"); - bglTexImage2D = GETPROC("glTexImage2D"); - bglTexSubImage2D = GETPROC("glTexSubImage2D"); - bglTexParameterf = GETPROC("glTexParameterf"); - bglTexParameteri = GETPROC("glTexParameteri"); - bglGetTexLevelParameteriv = GETPROC("glGetTexLevelParameteriv"); - - // Fog - bglFogf = GETPROC("glFogf"); - bglFogi = GETPROC("glFogi"); - bglFogfv = GETPROC("glFogfv"); - - loadglextensions(); - - if (err) unloadgldriver(); - return err; -} - -int loadglextensions(void) -{ - int err = 0; -#ifdef RENDERTYPEWIN - if (!hGLDLL) return 0; -#endif - - bglCompressedTexImage2DARB = GETPROCEXTSOFT("glCompressedTexImage2DARB"); - bglGetCompressedTexImageARB = GETPROCEXTSOFT("glGetCompressedTexImageARB"); - - return err; -} - -int unloadgldriver(void) -{ -#ifdef RENDERTYPEWIN - if (!hGLDLL) return 0; -#endif - - free(gldriver); - gldriver = NULL; - -#ifdef RENDERTYPEWIN - FreeLibrary(hGLDLL); - hGLDLL = NULL; -#endif - - bglClearColor = NULL; - bglClear = NULL; - bglColorMask = NULL; - bglAlphaFunc = NULL; - bglBlendFunc = NULL; - bglCullFace = NULL; - bglFrontFace = NULL; - bglPolygonOffset = NULL; - bglPolygonMode = NULL; - bglEnable = NULL; - bglDisable = NULL; - bglGetFloatv = NULL; - bglGetIntegerv = NULL; - bglPushAttrib = NULL; - bglPopAttrib = NULL; - bglGetError = NULL; - bglGetString = NULL; - bglHint = NULL; - - // Depth - bglDepthFunc = NULL; - bglDepthMask = NULL; - bglDepthRange = NULL; - - // Matrix - bglMatrixMode = NULL; - bglOrtho = NULL; - bglFrustum = NULL; - bglViewport = NULL; - bglPushMatrix = NULL; - bglPopMatrix = NULL; - bglLoadIdentity = NULL; - bglLoadMatrixf = NULL; - - // Drawing - bglBegin = NULL; - bglEnd = NULL; - bglVertex2f = NULL; - bglVertex2i = NULL; - bglVertex3d = NULL; - bglVertex3fv = NULL; - bglColor4f = NULL; - bglColor4ub = NULL; - bglTexCoord2d = NULL; - bglTexCoord2f = NULL; - - // Lighting - bglShadeModel = NULL; - - // Raster funcs - bglReadPixels = NULL; - - // Texture mapping - bglTexEnvf = NULL; - bglGenTextures = NULL; - bglDeleteTextures = NULL; - bglBindTexture = NULL; - bglTexImage2D = NULL; - bglTexSubImage2D = NULL; - bglTexParameterf = NULL; - bglTexParameteri = NULL; - bglGetTexLevelParameteriv = NULL; - bglCompressedTexImage2DARB = NULL; - bglGetCompressedTexImageARB = NULL; - - // Fog - bglFogf = NULL; - bglFogi = NULL; - bglFogfv = NULL; - -#ifdef RENDERTYPEWIN - bwglCreateContext = NULL; - bwglDeleteContext = NULL; - bwglGetProcAddress = NULL; - bwglMakeCurrent = NULL; - - bwglSwapBuffers = NULL; - bwglChoosePixelFormat = NULL; - bwglDescribePixelFormat = NULL; - bwglGetPixelFormat = NULL; - bwglSetPixelFormat = NULL; -#endif - - return 0; -} - -#else - -char *gldriver = ""; - -int loadgldriver(const char *a) { return 0; } -int unloadgldriver(void) { return 0; } - -#endif - +#include "glbuild.h" +#include "baselayer.h" +#include +#include +#include + +#if defined DYNAMIC_OPENGL && defined USE_OPENGL + +#ifdef RENDERTYPESDL +#include "SDL.h" +#endif + +void (APIENTRY * bglClearColor)( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ); +void (APIENTRY * bglClear)( GLbitfield mask ); +void (APIENTRY * bglColorMask)( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ); +void (APIENTRY * bglAlphaFunc)( GLenum func, GLclampf ref ); +void (APIENTRY * bglBlendFunc)( GLenum sfactor, GLenum dfactor ); +void (APIENTRY * bglCullFace)( GLenum mode ); +void (APIENTRY * bglFrontFace)( GLenum mode ); +void (APIENTRY * bglPolygonOffset)( GLfloat factor, GLfloat units ); +void (APIENTRY * bglPolygonMode)( GLenum face, GLenum mode ); +void (APIENTRY * bglEnable)( GLenum cap ); +void (APIENTRY * bglDisable)( GLenum cap ); +void (APIENTRY * bglGetFloatv)( GLenum pname, GLfloat *params ); +void (APIENTRY * bglGetIntegerv)( GLenum pname, GLint *params ); +void (APIENTRY * bglPushAttrib)( GLbitfield mask ); +void (APIENTRY * bglPopAttrib)( void ); +GLenum (APIENTRY * bglGetError)( void ); +const GLubyte* (APIENTRY * bglGetString)( GLenum name ); +void (APIENTRY * bglHint)( GLenum target, GLenum mode ); + +// Depth +void (APIENTRY * bglDepthFunc)( GLenum func ); +void (APIENTRY * bglDepthMask)( GLboolean flag ); +void (APIENTRY * bglDepthRange)( GLclampd near_val, GLclampd far_val ); + +// Matrix +void (APIENTRY * bglMatrixMode)( GLenum mode ); +void (APIENTRY * bglOrtho)( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val ); +void (APIENTRY * bglFrustum)( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val ); +void (APIENTRY * bglViewport)( GLint x, GLint y, GLsizei width, GLsizei height ); +void (APIENTRY * bglPushMatrix)( void ); +void (APIENTRY * bglPopMatrix)( void ); +void (APIENTRY * bglLoadIdentity)( void ); +void (APIENTRY * bglLoadMatrixf)( const GLfloat *m ); + +// Drawing +void (APIENTRY * bglBegin)( GLenum mode ); +void (APIENTRY * bglEnd)( void ); +void (APIENTRY * bglVertex2f)( GLfloat x, GLfloat y ); +void (APIENTRY * bglVertex2i)( GLint x, GLint y ); +void (APIENTRY * bglVertex3d)( GLdouble x, GLdouble y, GLdouble z ); +void (APIENTRY * bglVertex3fv)( const GLfloat *v ); +void (APIENTRY * bglColor4f)( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ); +void (APIENTRY * bglColor4ub)( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha ); +void (APIENTRY * bglTexCoord2d)( GLdouble s, GLdouble t ); +void (APIENTRY * bglTexCoord2f)( GLfloat s, GLfloat t ); + +// Lighting +void (APIENTRY * bglShadeModel)( GLenum mode ); + +// Raster funcs +void (APIENTRY * bglReadPixels)( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels ); + +// Texture mapping +void (APIENTRY * bglTexEnvf)( GLenum target, GLenum pname, GLfloat param ); +void (APIENTRY * bglGenTextures)( GLsizei n, GLuint *textures ); // 1.1 +void (APIENTRY * bglDeleteTextures)( GLsizei n, const GLuint *textures); // 1.1 +void (APIENTRY * bglBindTexture)( GLenum target, GLuint texture ); // 1.1 +void (APIENTRY * bglTexImage2D)( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels ); +void (APIENTRY * bglTexSubImage2D)( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels ); // 1.1 +void (APIENTRY * bglTexParameterf)( GLenum target, GLenum pname, GLfloat param ); +void (APIENTRY * bglTexParameteri)( GLenum target, GLenum pname, GLint param ); +void (APIENTRY * bglGetTexLevelParameteriv)( GLenum target, GLint level, GLenum pname, GLint *params ); +void (APIENTRY * bglCompressedTexImage2DARB)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); +void (APIENTRY * bglGetCompressedTexImageARB)(GLenum, GLint, GLvoid *); + +// Fog +void (APIENTRY * bglFogf)( GLenum pname, GLfloat param ); +void (APIENTRY * bglFogi)( GLenum pname, GLint param ); +void (APIENTRY * bglFogfv)( GLenum pname, const GLfloat *params ); + +#ifdef RENDERTYPEWIN +// Windows +HGLRC (WINAPI * bwglCreateContext)(HDC); +BOOL (WINAPI * bwglDeleteContext)(HGLRC); +PROC (WINAPI * bwglGetProcAddress)(LPCSTR); +BOOL (WINAPI * bwglMakeCurrent)(HDC,HGLRC); + +BOOL (WINAPI * bwglSwapBuffers)(HDC); +int (WINAPI * bwglChoosePixelFormat)(HDC,CONST PIXELFORMATDESCRIPTOR*); +int (WINAPI * bwglDescribePixelFormat)(HDC,int,UINT,LPPIXELFORMATDESCRIPTOR); +int (WINAPI * bwglGetPixelFormat)(HDC); +BOOL (WINAPI * bwglSetPixelFormat)(HDC,int,const PIXELFORMATDESCRIPTOR*); + +static HANDLE hGLDLL; +#endif + + +char *gldriver = NULL; + +static void * getproc_(const char *s, int *err, int fatal, int extension) +{ + void *t; +#if defined RENDERTYPESDL + t = (void*)SDL_GL_GetProcAddress(s); +#elif defined _WIN32 + if (extension) t = (void*)bwglGetProcAddress(s); + else t = (void*)GetProcAddress(hGLDLL,s); +#else +#error Need a dynamic loader for this platform... +#endif + if (!t && fatal) { + initprintf("Failed to find %s in %s\n", s, gldriver); + *err = 1; + } + return t; +} +#define GETPROC(s) getproc_(s,&err,1,0) +#define GETPROCSOFT(s) getproc_(s,&err,0,0) +#define GETPROCEXT(s) getproc_(s,&err,1,1) +#define GETPROCEXTSOFT(s) getproc_(s,&err,0,1) + +int loadgldriver(const char *driver) +{ + void *t; + int err=0; + +#ifdef RENDERTYPEWIN + if (hGLDLL) return 0; +#endif + + if (!driver) { +#ifdef _WIN32 + driver = "OPENGL32.DLL"; +#else + driver = "libGL.so"; +#endif + } + + initprintf("Loading %s\n",driver); + +#if defined RENDERTYPESDL + if (SDL_GL_LoadLibrary(driver)) return -1; +#elif defined _WIN32 + hGLDLL = LoadLibrary(driver); + if (!hGLDLL) return -1; +#endif + gldriver = strdup(driver); + +#ifdef RENDERTYPEWIN + bwglCreateContext = GETPROC("wglCreateContext"); + bwglDeleteContext = GETPROC("wglDeleteContext"); + bwglGetProcAddress = GETPROC("wglGetProcAddress"); + bwglMakeCurrent = GETPROC("wglMakeCurrent"); + + bwglSwapBuffers = GETPROC("wglSwapBuffers"); + bwglChoosePixelFormat = GETPROC("wglChoosePixelFormat"); + bwglDescribePixelFormat = GETPROC("wglDescribePixelFormat"); + bwglGetPixelFormat = GETPROC("wglGetPixelFormat"); + bwglSetPixelFormat = GETPROC("wglSetPixelFormat"); +#endif + + bglClearColor = GETPROC("glClearColor"); + bglClear = GETPROC("glClear"); + bglColorMask = GETPROC("glColorMask"); + bglAlphaFunc = GETPROC("glAlphaFunc"); + bglBlendFunc = GETPROC("glBlendFunc"); + bglCullFace = GETPROC("glCullFace"); + bglFrontFace = GETPROC("glFrontFace"); + bglPolygonOffset = GETPROC("glPolygonOffset"); + bglPolygonMode = GETPROC("glPolygonMode"); + bglEnable = GETPROC("glEnable"); + bglDisable = GETPROC("glDisable"); + bglGetFloatv = GETPROC("glGetFloatv"); + bglGetIntegerv = GETPROC("glGetIntegerv"); + bglPushAttrib = GETPROC("glPushAttrib"); + bglPopAttrib = GETPROC("glPopAttrib"); + bglGetError = GETPROC("glGetError"); + bglGetString = GETPROC("glGetString"); + bglHint = GETPROC("glHint"); + + // Depth + bglDepthFunc = GETPROC("glDepthFunc"); + bglDepthMask = GETPROC("glDepthMask"); + bglDepthRange = GETPROC("glDepthRange"); + + // Matrix + bglMatrixMode = GETPROC("glMatrixMode"); + bglOrtho = GETPROC("glOrtho"); + bglFrustum = GETPROC("glFrustum"); + bglViewport = GETPROC("glViewport"); + bglPushMatrix = GETPROC("glPushMatrix"); + bglPopMatrix = GETPROC("glPopMatrix"); + bglLoadIdentity = GETPROC("glLoadIdentity"); + bglLoadMatrixf = GETPROC("glLoadMatrixf"); + + // Drawing + bglBegin = GETPROC("glBegin"); + bglEnd = GETPROC("glEnd"); + bglVertex2f = GETPROC("glVertex2f"); + bglVertex2i = GETPROC("glVertex2i"); + bglVertex3d = GETPROC("glVertex3d"); + bglVertex3fv = GETPROC("glVertex3fv"); + bglColor4f = GETPROC("glColor4f"); + bglColor4ub = GETPROC("glColor4ub"); + bglTexCoord2d = GETPROC("glTexCoord2d"); + bglTexCoord2f = GETPROC("glTexCoord2f"); + + // Lighting + bglShadeModel = GETPROC("glShadeModel"); + + // Raster funcs + bglReadPixels = GETPROC("glReadPixels"); + + // Texture mapping + bglTexEnvf = GETPROC("glTexEnvf"); + bglGenTextures = GETPROC("glGenTextures"); + bglDeleteTextures = GETPROC("glDeleteTextures"); + bglBindTexture = GETPROC("glBindTexture"); + bglTexImage2D = GETPROC("glTexImage2D"); + bglTexSubImage2D = GETPROC("glTexSubImage2D"); + bglTexParameterf = GETPROC("glTexParameterf"); + bglTexParameteri = GETPROC("glTexParameteri"); + bglGetTexLevelParameteriv = GETPROC("glGetTexLevelParameteriv"); + + // Fog + bglFogf = GETPROC("glFogf"); + bglFogi = GETPROC("glFogi"); + bglFogfv = GETPROC("glFogfv"); + + loadglextensions(); + + if (err) unloadgldriver(); + return err; +} + +int loadglextensions(void) +{ + int err = 0; +#ifdef RENDERTYPEWIN + if (!hGLDLL) return 0; +#endif + + bglCompressedTexImage2DARB = GETPROCEXTSOFT("glCompressedTexImage2DARB"); + bglGetCompressedTexImageARB = GETPROCEXTSOFT("glGetCompressedTexImageARB"); + + return err; +} + +int unloadgldriver(void) +{ +#ifdef RENDERTYPEWIN + if (!hGLDLL) return 0; +#endif + + free(gldriver); + gldriver = NULL; + +#ifdef RENDERTYPEWIN + FreeLibrary(hGLDLL); + hGLDLL = NULL; +#endif + + bglClearColor = NULL; + bglClear = NULL; + bglColorMask = NULL; + bglAlphaFunc = NULL; + bglBlendFunc = NULL; + bglCullFace = NULL; + bglFrontFace = NULL; + bglPolygonOffset = NULL; + bglPolygonMode = NULL; + bglEnable = NULL; + bglDisable = NULL; + bglGetFloatv = NULL; + bglGetIntegerv = NULL; + bglPushAttrib = NULL; + bglPopAttrib = NULL; + bglGetError = NULL; + bglGetString = NULL; + bglHint = NULL; + + // Depth + bglDepthFunc = NULL; + bglDepthMask = NULL; + bglDepthRange = NULL; + + // Matrix + bglMatrixMode = NULL; + bglOrtho = NULL; + bglFrustum = NULL; + bglViewport = NULL; + bglPushMatrix = NULL; + bglPopMatrix = NULL; + bglLoadIdentity = NULL; + bglLoadMatrixf = NULL; + + // Drawing + bglBegin = NULL; + bglEnd = NULL; + bglVertex2f = NULL; + bglVertex2i = NULL; + bglVertex3d = NULL; + bglVertex3fv = NULL; + bglColor4f = NULL; + bglColor4ub = NULL; + bglTexCoord2d = NULL; + bglTexCoord2f = NULL; + + // Lighting + bglShadeModel = NULL; + + // Raster funcs + bglReadPixels = NULL; + + // Texture mapping + bglTexEnvf = NULL; + bglGenTextures = NULL; + bglDeleteTextures = NULL; + bglBindTexture = NULL; + bglTexImage2D = NULL; + bglTexSubImage2D = NULL; + bglTexParameterf = NULL; + bglTexParameteri = NULL; + bglGetTexLevelParameteriv = NULL; + bglCompressedTexImage2DARB = NULL; + bglGetCompressedTexImageARB = NULL; + + // Fog + bglFogf = NULL; + bglFogi = NULL; + bglFogfv = NULL; + +#ifdef RENDERTYPEWIN + bwglCreateContext = NULL; + bwglDeleteContext = NULL; + bwglGetProcAddress = NULL; + bwglMakeCurrent = NULL; + + bwglSwapBuffers = NULL; + bwglChoosePixelFormat = NULL; + bwglDescribePixelFormat = NULL; + bwglGetPixelFormat = NULL; + bwglSetPixelFormat = NULL; +#endif + + return 0; +} + +#else + +char *gldriver = ""; + +int loadgldriver(const char *a) { return 0; } +int unloadgldriver(void) { return 0; } + +#endif + diff --git a/polymer/build/src/hightile.c b/polymer/build/src/hightile.c index 182216af7..eaa32d0c4 100644 --- a/polymer/build/src/hightile.c +++ b/polymer/build/src/hightile.c @@ -1,254 +1,254 @@ -/* - * High-colour textures support for Polymost - * by Jonathon Fowler - * See the included license file "BUILDLIC.TXT" for license info. - */ - -#include "kplib.h" - -#define HICEFFECTMASK (1|2) -static palette_t hictinting[MAXPALOOKUPS]; - -struct hicskybox_t { - long ignore; - char *face[6]; -}; -typedef struct hicreplc_t { - struct hicreplc_t *next; - char palnum, ignore, flags, filler; - char *filename; - float alphacut; - struct hicskybox_t *skybox; -} hicreplctyp; -static hicreplctyp *hicreplc[MAXTILES]; -static char hicfirstinit = 0; - -// -// find the index into hicreplc[] which contains the replacement tile particulars -// -static hicreplctyp * hicfindsubst(long picnum, long palnum, long skybox) -{ - hicreplctyp *hr; - - if (!hicfirstinit) return NULL; - if ((unsigned long)picnum >= (unsigned long)MAXTILES) return NULL; - - do { - for (hr = hicreplc[picnum]; hr; hr = hr->next) { - if (hr->palnum == palnum) { - if (skybox) { - if (hr->skybox && !hr->skybox->ignore) return hr; - } else { - if (!hr->ignore) return hr; - } - } - } - - if (!palnum) break; - palnum = 0; - } while (1); - - return NULL; // no replacement found -} - - -// -// hicinit() -// Initialise the high-colour stuff to default. -// -void hicinit(void) -{ - long i,j; - hicreplctyp *hr, *next; - - for (i=0;i=0;i--) { - for (hr=hicreplc[i]; hr; ) { - next = hr->next; - - if (hr->skybox) { - for (j=5;j>=0;j--) { - if (hr->skybox->face[j]) { - free(hr->skybox->face[j]); - } - } - free(hr->skybox); - } - if (hr->filename) free(hr->filename); - free(hr); - - hr = next; - } - } - memset(hicreplc,0,sizeof(hicreplc)); - - hicfirstinit = 1; -} - - -// -// hicsetpalettetint(pal,r,g,b,effect) -// The tinting values represent a mechanism for emulating the effect of global sector -// palette shifts on true-colour textures and only true-colour textures. -// effect bitset: 1 = greyscale, 2 = invert -// -void hicsetpalettetint(long palnum, unsigned char r, unsigned char g, unsigned char b, unsigned char effect) -{ - if ((unsigned long)palnum >= (unsigned long)MAXPALOOKUPS) return; - if (!hicfirstinit) hicinit(); - - hictinting[palnum].r = r; - hictinting[palnum].g = g; - hictinting[palnum].b = b; - hictinting[palnum].f = effect & HICEFFECTMASK; -} - - -// -// hicsetsubsttex(picnum,pal,filen,alphacut) -// Specifies a replacement graphic file for an ART tile. -// -int hicsetsubsttex(long picnum, long palnum, char *filen, float alphacut, char flags) -{ - hicreplctyp *hr, *hrn; - - if ((unsigned long)picnum >= (unsigned long)MAXTILES) return -1; - if ((unsigned long)palnum >= (unsigned long)MAXPALOOKUPS) return -1; - if (!hicfirstinit) hicinit(); - - for (hr = hicreplc[picnum]; hr; hr = hr->next) { - if (hr->palnum == palnum) - break; - } - - if (!hr) { - // no replacement yet defined - hrn = (hicreplctyp *)calloc(1,sizeof(hicreplctyp)); - if (!hrn) return -1; - hrn->palnum = palnum; - } else hrn = hr; - - // store into hicreplc the details for this replacement - if (hrn->filename) free(hrn->filename); - - hrn->filename = strdup(filen); - if (!hrn->filename) { - if (hrn->skybox) return -1; // don't free the base structure if there's a skybox defined - if (hr == NULL) free(hrn); // not yet a link in the chain - return -1; - } - hrn->ignore = 0; - hrn->alphacut = min(alphacut,1.0); - hrn->flags = flags; - if (hr == NULL) { - hrn->next = hicreplc[picnum]; - hicreplc[picnum] = hrn; - } - - //printf("Replacement [%d,%d]: %s\n", picnum, palnum, hicreplc[i]->filename); - - return 0; -} - - -// -// hicsetskybox(picnum,pal,faces[6]) -// Specifies a graphic files making up a skybox. -// -int hicsetskybox(long picnum, long palnum, char *faces[6]) -{ - hicreplctyp *hr, *hrn; - long j; - - if ((unsigned long)picnum >= (unsigned long)MAXTILES) return -1; - if ((unsigned long)palnum >= (unsigned long)MAXPALOOKUPS) return -1; - for (j=5;j>=0;j--) if (!faces[j]) return -1; - if (!hicfirstinit) hicinit(); - - for (hr = hicreplc[picnum]; hr; hr = hr->next) { - if (hr->palnum == palnum) - break; - } - - if (!hr) { - // no replacement yet defined - hrn = (hicreplctyp *)calloc(1,sizeof(hicreplctyp)); - if (!hrn) return -1; - - hrn->palnum = palnum; - } else hrn = hr; - - if (!hrn->skybox) { - hrn->skybox = (struct hicskybox_t *)calloc(1,sizeof(struct hicskybox_t)); - if (!hrn->skybox) { - if (hr == NULL) free(hrn); // not yet a link in the chain - return -1; - } - } else { - for (j=5;j>=0;j--) { - if (hrn->skybox->face[j]) - free(hrn->skybox->face[j]); - } - } - - // store each face's filename - for (j=0;j<6;j++) { - hrn->skybox->face[j] = strdup(faces[j]); - if (!hrn->skybox->face[j]) { - for (--j; j>=0; --j) // free any previous faces - free(hrn->skybox->face[j]); - free(hrn->skybox); - hrn->skybox = NULL; - if (hr == NULL) free(hrn); - return -1; - } - } - hrn->skybox->ignore = 0; - if (hr == NULL) { - hrn->next = hicreplc[picnum]; - hicreplc[picnum] = hrn; - } - - return 0; -} - - -// -// hicclearsubst(picnum,pal) -// Clears a replacement for an ART tile, including skybox faces. -// -int hicclearsubst(long picnum, long palnum) -{ - hicreplctyp *hr, *hrn = NULL; - - if ((unsigned long)picnum >= (unsigned long)MAXTILES) return -1; - if ((unsigned long)palnum >= (unsigned long)MAXPALOOKUPS) return -1; - if (!hicfirstinit) return 0; - - for (hr = hicreplc[picnum]; hr; hrn = hr, hr = hr->next) { - if (hr->palnum == palnum) - break; - } - - if (!hr) return 0; - - if (hr->filename) free(hr->filename); - if (hr->skybox) { - int i; - for (i=5;i>=0;i--) - if (hr->skybox->face[i]) - free(hr->skybox->face[i]); - free(hr->skybox); - } - - if (hrn) hrn->next = hr->next; - else hicreplc[picnum] = hr->next; - free(hr); - - return 0; -} +/* + * High-colour textures support for Polymost + * by Jonathon Fowler + * See the included license file "BUILDLIC.TXT" for license info. + */ + +#include "kplib.h" + +#define HICEFFECTMASK (1|2) +static palette_t hictinting[MAXPALOOKUPS]; + +struct hicskybox_t { + long ignore; + char *face[6]; +}; +typedef struct hicreplc_t { + struct hicreplc_t *next; + char palnum, ignore, flags, filler; + char *filename; + float alphacut; + struct hicskybox_t *skybox; +} hicreplctyp; +static hicreplctyp *hicreplc[MAXTILES]; +static char hicfirstinit = 0; + +// +// find the index into hicreplc[] which contains the replacement tile particulars +// +static hicreplctyp * hicfindsubst(long picnum, long palnum, long skybox) +{ + hicreplctyp *hr; + + if (!hicfirstinit) return NULL; + if ((unsigned long)picnum >= (unsigned long)MAXTILES) return NULL; + + do { + for (hr = hicreplc[picnum]; hr; hr = hr->next) { + if (hr->palnum == palnum) { + if (skybox) { + if (hr->skybox && !hr->skybox->ignore) return hr; + } else { + if (!hr->ignore) return hr; + } + } + } + + if (!palnum) break; + palnum = 0; + } while (1); + + return NULL; // no replacement found +} + + +// +// hicinit() +// Initialise the high-colour stuff to default. +// +void hicinit(void) +{ + long i,j; + hicreplctyp *hr, *next; + + for (i=0;i=0;i--) { + for (hr=hicreplc[i]; hr; ) { + next = hr->next; + + if (hr->skybox) { + for (j=5;j>=0;j--) { + if (hr->skybox->face[j]) { + free(hr->skybox->face[j]); + } + } + free(hr->skybox); + } + if (hr->filename) free(hr->filename); + free(hr); + + hr = next; + } + } + memset(hicreplc,0,sizeof(hicreplc)); + + hicfirstinit = 1; +} + + +// +// hicsetpalettetint(pal,r,g,b,effect) +// The tinting values represent a mechanism for emulating the effect of global sector +// palette shifts on true-colour textures and only true-colour textures. +// effect bitset: 1 = greyscale, 2 = invert +// +void hicsetpalettetint(long palnum, unsigned char r, unsigned char g, unsigned char b, unsigned char effect) +{ + if ((unsigned long)palnum >= (unsigned long)MAXPALOOKUPS) return; + if (!hicfirstinit) hicinit(); + + hictinting[palnum].r = r; + hictinting[palnum].g = g; + hictinting[palnum].b = b; + hictinting[palnum].f = effect & HICEFFECTMASK; +} + + +// +// hicsetsubsttex(picnum,pal,filen,alphacut) +// Specifies a replacement graphic file for an ART tile. +// +int hicsetsubsttex(long picnum, long palnum, char *filen, float alphacut, char flags) +{ + hicreplctyp *hr, *hrn; + + if ((unsigned long)picnum >= (unsigned long)MAXTILES) return -1; + if ((unsigned long)palnum >= (unsigned long)MAXPALOOKUPS) return -1; + if (!hicfirstinit) hicinit(); + + for (hr = hicreplc[picnum]; hr; hr = hr->next) { + if (hr->palnum == palnum) + break; + } + + if (!hr) { + // no replacement yet defined + hrn = (hicreplctyp *)calloc(1,sizeof(hicreplctyp)); + if (!hrn) return -1; + hrn->palnum = palnum; + } else hrn = hr; + + // store into hicreplc the details for this replacement + if (hrn->filename) free(hrn->filename); + + hrn->filename = strdup(filen); + if (!hrn->filename) { + if (hrn->skybox) return -1; // don't free the base structure if there's a skybox defined + if (hr == NULL) free(hrn); // not yet a link in the chain + return -1; + } + hrn->ignore = 0; + hrn->alphacut = min(alphacut,1.0); + hrn->flags = flags; + if (hr == NULL) { + hrn->next = hicreplc[picnum]; + hicreplc[picnum] = hrn; + } + + //printf("Replacement [%d,%d]: %s\n", picnum, palnum, hicreplc[i]->filename); + + return 0; +} + + +// +// hicsetskybox(picnum,pal,faces[6]) +// Specifies a graphic files making up a skybox. +// +int hicsetskybox(long picnum, long palnum, char *faces[6]) +{ + hicreplctyp *hr, *hrn; + long j; + + if ((unsigned long)picnum >= (unsigned long)MAXTILES) return -1; + if ((unsigned long)palnum >= (unsigned long)MAXPALOOKUPS) return -1; + for (j=5;j>=0;j--) if (!faces[j]) return -1; + if (!hicfirstinit) hicinit(); + + for (hr = hicreplc[picnum]; hr; hr = hr->next) { + if (hr->palnum == palnum) + break; + } + + if (!hr) { + // no replacement yet defined + hrn = (hicreplctyp *)calloc(1,sizeof(hicreplctyp)); + if (!hrn) return -1; + + hrn->palnum = palnum; + } else hrn = hr; + + if (!hrn->skybox) { + hrn->skybox = (struct hicskybox_t *)calloc(1,sizeof(struct hicskybox_t)); + if (!hrn->skybox) { + if (hr == NULL) free(hrn); // not yet a link in the chain + return -1; + } + } else { + for (j=5;j>=0;j--) { + if (hrn->skybox->face[j]) + free(hrn->skybox->face[j]); + } + } + + // store each face's filename + for (j=0;j<6;j++) { + hrn->skybox->face[j] = strdup(faces[j]); + if (!hrn->skybox->face[j]) { + for (--j; j>=0; --j) // free any previous faces + free(hrn->skybox->face[j]); + free(hrn->skybox); + hrn->skybox = NULL; + if (hr == NULL) free(hrn); + return -1; + } + } + hrn->skybox->ignore = 0; + if (hr == NULL) { + hrn->next = hicreplc[picnum]; + hicreplc[picnum] = hrn; + } + + return 0; +} + + +// +// hicclearsubst(picnum,pal) +// Clears a replacement for an ART tile, including skybox faces. +// +int hicclearsubst(long picnum, long palnum) +{ + hicreplctyp *hr, *hrn = NULL; + + if ((unsigned long)picnum >= (unsigned long)MAXTILES) return -1; + if ((unsigned long)palnum >= (unsigned long)MAXPALOOKUPS) return -1; + if (!hicfirstinit) return 0; + + for (hr = hicreplc[picnum]; hr; hrn = hr, hr = hr->next) { + if (hr->palnum == palnum) + break; + } + + if (!hr) return 0; + + if (hr->filename) free(hr->filename); + if (hr->skybox) { + int i; + for (i=5;i>=0;i--) + if (hr->skybox->face[i]) + free(hr->skybox->face[i]); + free(hr->skybox); + } + + if (hrn) hrn->next = hr->next; + else hicreplc[picnum] = hr->next; + free(hr); + + return 0; +} diff --git a/polymer/build/src/mmulti.c b/polymer/build/src/mmulti.c index 9e138152b..cd38dd6c8 100644 --- a/polymer/build/src/mmulti.c +++ b/polymer/build/src/mmulti.c @@ -1,371 +1,372 @@ -#include -#include -#include - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#else -#include -#include -#ifndef __BEOS__ -#include -#endif -#ifdef __sun -#include -#endif -#include -#include -#include -#define SOCKET int -#define INVALID_HANDLE_VALUE (-1) -#define INVALID_SOCKET (-1) -#define SOCKET_ERROR (-1) -#define closesocket close -#define ioctlsocket ioctl -#define LPHOSTENT struct hostent * - -#include -static long GetTickCount(void) -{ - struct timeval tv; - long ti; - if (gettimeofday(&tv,NULL) < 0) return 0; - // tv is sec.usec, GTC gives msec - ti = tv.tv_sec * 1000; - ti += tv.tv_usec / 1000; - return ti; -} -#endif - -#ifdef KSFORBUILD -# include "baselayer.h" -# define printf initprintf -#endif - -#ifndef min -#define min(a,b) ((a)<(b)?(a):(b)) -#endif - -#define MAXPLAYERS 16 -#define MAXPAKSIZ 256 //576 - - -#define PAKRATE 26 //Packet rate/sec limit ... necessary? -#define SIMMIS 0 //Release:0 Test:100 Packets per 256 missed. -#define SIMLAG 0 //Release:0 Test: 10 Packets to delay receipt -static long simlagcnt[MAXPLAYERS]; -static char simlagfif[MAXPLAYERS][SIMLAG+1][MAXPAKSIZ+2]; -#if ((SIMMIS != 0) || (SIMLAG != 0)) -#pragma message("\n\nWARNING! INTENTIONAL PACKET LOSS SIMULATION IS ENABLED!\nREMEMBER TO CHANGE SIMMIS&SIMLAG to 0 before RELEASE!\n\n") -#endif - -long myconnectindex, numplayers; -long connecthead, connectpoint2[MAXPLAYERS]; - -static long tims, lastsendtims[MAXPLAYERS]; -static char pakbuf[MAXPAKSIZ]; - -#define FIFSIZ 512 //16384/40 = 6min:49sec -static long ipak[MAXPLAYERS][FIFSIZ], icnt0[MAXPLAYERS]; -static long opak[MAXPLAYERS][FIFSIZ], ocnt0[MAXPLAYERS], ocnt1[MAXPLAYERS]; -static char pakmem[4194304]; static long pakmemi = 1; - -#define NETPORT 0x5bd9 -static SOCKET mysock; -static long myip, myport = NETPORT, otherip[MAXPLAYERS], otherport[MAXPLAYERS]; -static long snatchip = 0, snatchport = 0, danetmode = 255, netready = 0; - -void netuninit () -{ - if (mysock != (SOCKET)INVALID_HANDLE_VALUE) closesocket(mysock); -#ifdef _WIN32 - WSACleanup(); -#endif -} - -long netinit (long portnum) -{ - LPHOSTENT lpHostEnt; - char hostnam[256]; - struct sockaddr_in ip; - long i; - -#ifdef _WIN32 - WSADATA ws; - - if (WSAStartup(0x101,&ws) == SOCKET_ERROR) return(0); -#endif - - mysock = socket(AF_INET,SOCK_DGRAM,0); if (mysock == INVALID_SOCKET) return(0); -#ifdef __BEOS__ - i = 1; if (setsockopt(mysock,SOL_SOCKET,SO_NONBLOCK,&i,sizeof(i)) < 0) return(0); -#else - i = 1; if (ioctlsocket(mysock,FIONBIO,(unsigned long *)&i) == SOCKET_ERROR) return(0); -#endif - - ip.sin_family = AF_INET; - ip.sin_addr.s_addr = INADDR_ANY; - ip.sin_port = htons(portnum); - if (bind(mysock,(struct sockaddr *)&ip,sizeof(ip)) != SOCKET_ERROR) - { - myport = portnum; - if (gethostname(hostnam,sizeof(hostnam)) != SOCKET_ERROR) - if ((lpHostEnt = gethostbyname(hostnam))) - { - myip = ip.sin_addr.s_addr = *(long *)lpHostEnt->h_addr; - printf("mmulti: This machine's IP is %s\n", inet_ntoa(ip.sin_addr)); - } - return(1); - } - return(0); -} - -long netsend (long other, char *dabuf, long bufsiz) //0:buffer full... can't send -{ - struct sockaddr_in ip; - - if (!otherip[other]) return(0); - ip.sin_family = AF_INET; - ip.sin_addr.s_addr = otherip[other]; - ip.sin_port = otherport[other]; - return(sendto(mysock,dabuf,bufsiz,0,(struct sockaddr *)&ip,sizeof(struct sockaddr_in)) != SOCKET_ERROR); -} - -long netread (long *other, char *dabuf, long bufsiz) //0:no packets in buffer -{ - struct sockaddr_in ip; - long i; - - i = sizeof(ip); - if (recvfrom(mysock,dabuf,bufsiz,0,(struct sockaddr *)&ip,(int *)&i) == -1) return(0); -#if (SIMMIS > 0) - if ((rand()&255) < SIMMIS) return(0); -#endif - - snatchip = (long)ip.sin_addr.s_addr; snatchport = (long)ip.sin_port; - - (*other) = myconnectindex; - for(i=0;i 1) - i = simlagcnt[*other]%(SIMLAG+1); - *(short *)&simlagfif[*other][i][0] = bufsiz; memcpy(&simlagfif[*other][i][2],dabuf,bufsiz); - simlagcnt[*other]++; if (simlagcnt[*other] < SIMLAG+1) return(0); - i = simlagcnt[*other]%(SIMLAG+1); - bufsiz = *(short *)&simlagfif[*other][i][0]; memcpy(dabuf,&simlagfif[*other][i][2],bufsiz); -#endif - - return(1); -} - -long isvalidipaddress (char *st) -{ - long i, bcnt, num; - - bcnt = 0; num = 0; - for(i=0;st[i];i++) - { - if (st[i] == '.') { bcnt++; num = 0; continue; } - if (st[i] == ':') - { - if (bcnt != 3) return(0); - num = 0; - for(i++;st[i];i++) - { - if ((st[i] >= '0') && (st[i] <= '9')) - { num = num*10+st[i]-'0'; if (num >= 65536) return(0); } - else return(0); - } - return(1); - } - if ((st[i] >= '0') && (st[i] <= '9')) - { num = num*10+st[i]-'0'; if (num >= 256) return(0); } - - } - return(bcnt == 3); -} - -//---------------------------------- Obsolete variables&functions ---------------------------------- -char syncstate = 0; -void setpackettimeout (long datimeoutcount, long daresendagaincount) {} -void genericmultifunction (long other, char *bufptr, long messleng, long command) {} -long getoutputcirclesize () { return(0); } -void setsocket (long newsocket) { } -void flushpackets () {} -void sendlogon () {} -void sendlogoff () {} -//-------------------------------------------------------------------------------------------------- - -static long crctab16[256]; -static void initcrc16 () -{ - long i, j, k, a; - for(j=0;j<256;j++) - { - for(i=7,k=(j<<8),a=0;i>=0;i--,k=((k<<1)&65535)) - { - if ((k^a)&0x8000) a = ((a<<1)&65535)^0x1021; - else a = ((a<<1)&65535); - } - crctab16[j] = (a&65535); - } -} -#define updatecrc16(crc,dat) crc = (((crc<<8)&65535)^crctab16[((((unsigned short)crc)>>8)&65535)^dat]) -static unsigned short getcrc16 (char *buffer, long bufleng) -{ - long i, j; - - j = 0; - for(i=bufleng-1;i>=0;i--) updatecrc16(j,buffer[i]); - return((unsigned short)(j&65535)); -} - -void uninitmultiplayers () { netuninit(); } - -long getpacket(long *, char *); -static void initmultiplayers_reset(void) -{ - long i; - - initcrc16(); - memset(icnt0,0,sizeof(icnt0)); - memset(ocnt0,0,sizeof(ocnt0)); - memset(ocnt1,0,sizeof(ocnt1)); - memset(ipak,0,sizeof(ipak)); - //memset(opak,0,sizeof(opak)); //Don't need to init opak - //memset(pakmem,0,sizeof(pakmem)); //Don't need to init pakmem -#if (SIMLAG > 1) - memset(simlagcnt,0,sizeof(simlagcnt)); -#endif - - lastsendtims[0] = GetTickCount(); - for(i=1;i 0 && j<65535) portnum = j; - - printf("mmulti: Using port %ld\n", portnum); - } - } - - netinit(portnum); - - for(i=0;i= '0') && (argv[i][4] <= '9')) - { - numplayers = (argv[i][4]-'0'); - if ((argv[i][5] >= '0') && (argv[i][5] <= '9')) numplayers = numplayers*10+(argv[i][5]-'0'); - printf("mmulti: %ld-player game\n", numplayers); - } - printf("mmulti: Master-slave mode\n"); - } - else if (argv[i][2] == '1') - { - danetmode = 1; - myconnectindex = daindex; daindex++; - printf("mmulti: Peer-to-peer mode\n"); - } - continue; - } - else if ((argv[i][1] == 'P') || (argv[i][1] == 'p')) continue; - } - - st = strdup(argv[i]); if (!st) break; - if (isvalidipaddress(st)) - { - if ((danetmode == 1) && (daindex == myconnectindex)) daindex++; - for(j=0;st[j];j++) { - if (st[j] == ':') - { otherport[daindex] = htons((unsigned short)atol(&st[j+1])); st[j] = 0; break; } - } - otherip[daindex] = inet_addr(st); - printf("mmulti: Player %ld at %s:%d\n",daindex,st,ntohs(otherport[daindex])); - daindex++; - } - else - { - LPHOSTENT lph; - unsigned short pt = htons(NETPORT); - - for(j=0;st[j];j++) - if (st[j] == ':') - { pt = htons((unsigned short)atol(&st[j+1])); st[j] = 0; break; } - if ((lph = gethostbyname(st))) - { - if ((danetmode == 1) && (daindex == myconnectindex)) daindex++; - otherip[daindex] = *(long *)lph->h_addr; - otherport[daindex] = pt; - printf("mmulti: Player %ld at %s:%d (%s)\n",daindex, - inet_ntoa(*(struct in_addr *)lph->h_addr),ntohs(pt),argv[i]); - daindex++; - } else printf("mmulti: Failed resolving %s\n",argv[i]); - } - free(st); - } - if ((danetmode == 255) && (daindex)) { numplayers = 2; danetmode = 0; } //an IP w/o /n# defaults to /n0 - if ((numplayers >= 2) && (daindex) && (!danetmode)) myconnectindex = 1; - if (daindex > numplayers) numplayers = daindex; - - //for(i=0;i>8)&255,(otherip[i]>>16)&255,((unsigned long)otherip[i])>>24,ntohs(otherport[i])); - - connecthead = 0; - for(i=0;i= 2)) || (numplayers == 2)); -} - -long initmultiplayerscycle(void) -{ - long i, k; +#include +#include +#include + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#else +#include +#include +#ifndef __BEOS__ +#include +#endif +#ifdef __sun +#include +#endif +#include +#include +#include +#define SOCKET int +#define INVALID_HANDLE_VALUE (-1) +#define INVALID_SOCKET (-1) +#define SOCKET_ERROR (-1) +#define closesocket close +#define ioctlsocket ioctl +#define LPHOSTENT struct hostent * + +#include "compat.h" +#include +static long GetTickCount(void) +{ + struct timeval tv; + long ti; + if (gettimeofday(&tv,NULL) < 0) return 0; + // tv is sec.usec, GTC gives msec + ti = tv.tv_sec * 1000; + ti += tv.tv_usec / 1000; + return ti; +} +#endif + +#ifdef KSFORBUILD +# include "baselayer.h" +# define printf initprintf +#endif + +#ifndef min +#define min(a,b) ((a)<(b)?(a):(b)) +#endif + +#define MAXPLAYERS 16 +#define MAXPAKSIZ 256 //576 + + +#define PAKRATE 26 //Packet rate/sec limit ... necessary? +#define SIMMIS 0 //Release:0 Test:100 Packets per 256 missed. +#define SIMLAG 0 //Release:0 Test: 10 Packets to delay receipt +static long simlagcnt[MAXPLAYERS]; +static char simlagfif[MAXPLAYERS][SIMLAG+1][MAXPAKSIZ+2]; +#if ((SIMMIS != 0) || (SIMLAG != 0)) +#pragma message("\n\nWARNING! INTENTIONAL PACKET LOSS SIMULATION IS ENABLED!\nREMEMBER TO CHANGE SIMMIS&SIMLAG to 0 before RELEASE!\n\n") +#endif + +long myconnectindex, numplayers; +long connecthead, connectpoint2[MAXPLAYERS]; + +static long tims, lastsendtims[MAXPLAYERS]; +static char pakbuf[MAXPAKSIZ]; + +#define FIFSIZ 512 //16384/40 = 6min:49sec +static long ipak[MAXPLAYERS][FIFSIZ], icnt0[MAXPLAYERS]; +static long opak[MAXPLAYERS][FIFSIZ], ocnt0[MAXPLAYERS], ocnt1[MAXPLAYERS]; +static char pakmem[4194304]; static long pakmemi = 1; + +#define NETPORT 0x5bd9 +static SOCKET mysock; +static long myip, myport = NETPORT, otherip[MAXPLAYERS], otherport[MAXPLAYERS]; +static long snatchip = 0, snatchport = 0, danetmode = 255, netready = 0; + +void netuninit () +{ + if (mysock != (SOCKET)INVALID_HANDLE_VALUE) closesocket(mysock); +#ifdef _WIN32 + WSACleanup(); +#endif +} + +long netinit (long portnum) +{ + LPHOSTENT lpHostEnt; + char hostnam[256]; + struct sockaddr_in ip; + long i; + +#ifdef _WIN32 + WSADATA ws; + + if (WSAStartup(0x101,&ws) == SOCKET_ERROR) return(0); +#endif + + mysock = socket(AF_INET,SOCK_DGRAM,0); if (mysock == INVALID_SOCKET) return(0); +#ifdef __BEOS__ + i = 1; if (setsockopt(mysock,SOL_SOCKET,SO_NONBLOCK,&i,sizeof(i)) < 0) return(0); +#else + i = 1; if (ioctlsocket(mysock,FIONBIO,(unsigned long *)&i) == SOCKET_ERROR) return(0); +#endif + + ip.sin_family = AF_INET; + ip.sin_addr.s_addr = INADDR_ANY; + ip.sin_port = htons(portnum); + if (bind(mysock,(struct sockaddr *)&ip,sizeof(ip)) != SOCKET_ERROR) + { + myport = portnum; + if (gethostname(hostnam,sizeof(hostnam)) != SOCKET_ERROR) + if ((lpHostEnt = gethostbyname(hostnam))) + { + myip = ip.sin_addr.s_addr = *(long *)lpHostEnt->h_addr; + printf("mmulti: This machine's IP is %s\n", inet_ntoa(ip.sin_addr)); + } + return(1); + } + return(0); +} + +long netsend (long other, char *dabuf, long bufsiz) //0:buffer full... can't send +{ + struct sockaddr_in ip; + + if (!otherip[other]) return(0); + ip.sin_family = AF_INET; + ip.sin_addr.s_addr = otherip[other]; + ip.sin_port = otherport[other]; + return(sendto(mysock,dabuf,bufsiz,0,(struct sockaddr *)&ip,sizeof(struct sockaddr_in)) != SOCKET_ERROR); +} + +long netread (long *other, char *dabuf, long bufsiz) //0:no packets in buffer +{ + struct sockaddr_in ip; + long i; + + i = sizeof(ip); + if (recvfrom(mysock,dabuf,bufsiz,0,(struct sockaddr *)&ip,(int *)&i) == -1) return(0); +#if (SIMMIS > 0) + if ((rand()&255) < SIMMIS) return(0); +#endif + + snatchip = (long)ip.sin_addr.s_addr; snatchport = (long)ip.sin_port; + + (*other) = myconnectindex; + for(i=0;i 1) + i = simlagcnt[*other]%(SIMLAG+1); + *(short *)&simlagfif[*other][i][0] = bufsiz; memcpy(&simlagfif[*other][i][2],dabuf,bufsiz); + simlagcnt[*other]++; if (simlagcnt[*other] < SIMLAG+1) return(0); + i = simlagcnt[*other]%(SIMLAG+1); + bufsiz = *(short *)&simlagfif[*other][i][0]; memcpy(dabuf,&simlagfif[*other][i][2],bufsiz); +#endif + + return(1); +} + +long isvalidipaddress (char *st) +{ + long i, bcnt, num; + + bcnt = 0; num = 0; + for(i=0;st[i];i++) + { + if (st[i] == '.') { bcnt++; num = 0; continue; } + if (st[i] == ':') + { + if (bcnt != 3) return(0); + num = 0; + for(i++;st[i];i++) + { + if ((st[i] >= '0') && (st[i] <= '9')) + { num = num*10+st[i]-'0'; if (num >= 65536) return(0); } + else return(0); + } + return(1); + } + if ((st[i] >= '0') && (st[i] <= '9')) + { num = num*10+st[i]-'0'; if (num >= 256) return(0); } + + } + return(bcnt == 3); +} + +//---------------------------------- Obsolete variables&functions ---------------------------------- +char syncstate = 0; +void setpackettimeout (long datimeoutcount, long daresendagaincount) {} +void genericmultifunction (long other, char *bufptr, long messleng, long command) {} +long getoutputcirclesize () { return(0); } +void setsocket (long newsocket) { } +void flushpackets () {} +void sendlogon () {} +void sendlogoff () {} +//-------------------------------------------------------------------------------------------------- + +static long crctab16[256]; +static void initcrc16 () +{ + long i, j, k, a; + for(j=0;j<256;j++) + { + for(i=7,k=(j<<8),a=0;i>=0;i--,k=((k<<1)&65535)) + { + if ((k^a)&0x8000) a = ((a<<1)&65535)^0x1021; + else a = ((a<<1)&65535); + } + crctab16[j] = (a&65535); + } +} +#define updatecrc16(crc,dat) crc = (((crc<<8)&65535)^crctab16[((((unsigned short)crc)>>8)&65535)^dat]) +static unsigned short getcrc16 (char *buffer, long bufleng) +{ + long i, j; + + j = 0; + for(i=bufleng-1;i>=0;i--) updatecrc16(j,buffer[i]); + return((unsigned short)(j&65535)); +} + +void uninitmultiplayers () { netuninit(); } + +long getpacket(long *, char *); +static void initmultiplayers_reset(void) +{ + long i; + + initcrc16(); + memset(icnt0,0,sizeof(icnt0)); + memset(ocnt0,0,sizeof(ocnt0)); + memset(ocnt1,0,sizeof(ocnt1)); + memset(ipak,0,sizeof(ipak)); + //memset(opak,0,sizeof(opak)); //Don't need to init opak + //memset(pakmem,0,sizeof(pakmem)); //Don't need to init pakmem +#if (SIMLAG > 1) + memset(simlagcnt,0,sizeof(simlagcnt)); +#endif + + lastsendtims[0] = GetTickCount(); + for(i=1;i 0 && j<65535) portnum = j; + + printf("mmulti: Using port %ld\n", portnum); + } + } + + netinit(portnum); + + for(i=0;i= '0') && (argv[i][4] <= '9')) + { + numplayers = (argv[i][4]-'0'); + if ((argv[i][5] >= '0') && (argv[i][5] <= '9')) numplayers = numplayers*10+(argv[i][5]-'0'); + printf("mmulti: %ld-player game\n", numplayers); + } + printf("mmulti: Master-slave mode\n"); + } + else if (argv[i][2] == '1') + { + danetmode = 1; + myconnectindex = daindex; daindex++; + printf("mmulti: Peer-to-peer mode\n"); + } + continue; + } + else if ((argv[i][1] == 'P') || (argv[i][1] == 'p')) continue; + } + + st = strdup(argv[i]); if (!st) break; + if (isvalidipaddress(st)) + { + if ((danetmode == 1) && (daindex == myconnectindex)) daindex++; + for(j=0;st[j];j++) { + if (st[j] == ':') + { otherport[daindex] = htons((unsigned short)atol(&st[j+1])); st[j] = 0; break; } + } + otherip[daindex] = inet_addr(st); + printf("mmulti: Player %ld at %s:%d\n",daindex,st,ntohs(otherport[daindex])); + daindex++; + } + else + { + LPHOSTENT lph; + unsigned short pt = htons(NETPORT); + + for(j=0;st[j];j++) + if (st[j] == ':') + { pt = htons((unsigned short)atol(&st[j+1])); st[j] = 0; break; } + if ((lph = gethostbyname(st))) + { + if ((danetmode == 1) && (daindex == myconnectindex)) daindex++; + otherip[daindex] = *(long *)lph->h_addr; + otherport[daindex] = pt; + printf("mmulti: Player %ld at %s:%d (%s)\n",daindex, + inet_ntoa(*(struct in_addr *)lph->h_addr),ntohs(pt),argv[i]); + daindex++; + } else printf("mmulti: Failed resolving %s\n",argv[i]); + } + free(st); + } + if ((danetmode == 255) && (daindex)) { numplayers = 2; danetmode = 0; } //an IP w/o /n# defaults to /n0 + if ((numplayers >= 2) && (daindex) && (!danetmode)) myconnectindex = 1; + if (daindex > numplayers) numplayers = daindex; + + //for(i=0;i>8)&255,(otherip[i]>>16)&255,((unsigned long)otherip[i])>>24,ntohs(otherport[i])); + + connecthead = 0; + for(i=0;i= 2)) || (numplayers == 2)); +} + +long initmultiplayerscycle(void) +{ + long i, k; extern long totalclock; #ifdef _WIN32 @@ -374,275 +375,275 @@ long initmultiplayerscycle(void) usleep(1); #endif - getpacket(&i,0); - - tims = GetTickCount(); - if (myconnectindex == connecthead) - { - for(i=numplayers-1;i>0;i--) - if (!otherip[i]) break; - if (!i) { - netready = 1; - return 0; - } - } - else - { - if (netready) return 0; - if (tims < lastsendtims[connecthead]) lastsendtims[connecthead] = tims; - if (tims >= lastsendtims[connecthead]+250) //1000/PAKRATE) - { - lastsendtims[connecthead] = tims; - - // short crc16ofs; //offset of crc16 - // long icnt0; //-1 (special packet for MMULTI.C's player collection) - // ... - // unsigned short crc16; //CRC16 of everything except crc16 - k = 2; - *(long *)&pakbuf[k] = -1; k += 4; - pakbuf[k++] = 0xaa; - *(unsigned short *)&pakbuf[0] = (unsigned short)k; - *(unsigned short *)&pakbuf[k] = getcrc16(pakbuf,k); k += 2; - netsend(connecthead,pakbuf,k); - } - } - - return 1; -} - -void initmultiplayers (long argc, char **argv, char damultioption, char dacomrateoption, char dapriority) -{ - long i, j, k, otims; - - if (initmultiplayersparms(argc,argv)) - { -#if 0 - //Console code seems to crash Win98 upon quitting game - //it's not necessary and it's not portable anyway - char tbuf[1024]; - unsigned long u; - HANDLE hconsout; - AllocConsole(); - SetConsoleTitle("Multiplayer status..."); - hconsout = GetStdHandle(STD_OUTPUT_HANDLE); - otims = 0; -#endif - while (initmultiplayerscycle()) - { -#if 0 - if ((tims < otims) || (tims > otims+100)) - { - otims = tims; - sprintf(tbuf,"\rWait for players (%d/%d): ",myconnectindex,numplayers); - for(i=0;i "); continue; } - if (!otherip[i]) { strcat(tbuf,"?.?.?.?:? "); continue; } - sprintf(&tbuf[strlen(tbuf)],"%d.%d.%d.%d:%04x ",otherip[i]&255,(otherip[i]>>8)&255,(otherip[i]>>16)&255,(((unsigned long)otherip[i])>>24),otherport[i]); - } - WriteConsole(hconsout,tbuf,strlen(tbuf),&u,0); - } - } - FreeConsole(); -#else - } -#endif - } - netready = 1; -} - -void dosendpackets (long other) -{ - long i, j, k; - - if (!otherip[other]) return; - - //Packet format: - // short crc16ofs; //offset of crc16 - // long icnt0; //earliest unacked packet - // char ibits[32]; //ack status of packets icnt0<=i>3)+k] |= (1<<((i-icnt0[other])&7)); - k += 32; - - while ((ocnt0[other] < ocnt1[other]) && (!opak[other][ocnt0[other]&(FIFSIZ-1)])) ocnt0[other]++; - for(i=ocnt0[other];i (long)sizeof(pakbuf)) break; - - *(unsigned short *)&pakbuf[k] = (unsigned short)j; k += 2; - *(long *)&pakbuf[k] = i; k += 4; - memcpy(&pakbuf[k],&pakmem[opak[other][i&(FIFSIZ-1)]+2],j); k += j; - } - *(unsigned short *)&pakbuf[k] = 0; k += 2; - *(unsigned short *)&pakbuf[0] = (unsigned short)k; - *(unsigned short *)&pakbuf[k] = getcrc16(pakbuf,k); k += 2; - - //printf("Send: "); for(i=0;i (long)sizeof(pakmem)) pakmemi = 1; - opak[other][ocnt1[other]&(FIFSIZ-1)] = pakmemi; - *(short *)&pakmem[pakmemi] = messleng; - memcpy(&pakmem[pakmemi+2],bufptr,messleng); pakmemi += messleng+2; - ocnt1[other]++; - - //printf("Send: "); for(i=0;i=0;i=connectpoint2[i]) - { - if (i != myconnectindex) dosendpackets(i); - if ((!danetmode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master - } - } - - while (netread(&other,pakbuf,sizeof(pakbuf))) - { - //Packet format: - // short crc16ofs; //offset of crc16 - // long icnt0; //earliest unacked packet - // char ibits[32]; //ack status of packets icnt0<=i>3)+k]&(1<<((i-ic0)&7))) - opak[other][i&(FIFSIZ-1)] = 0; - k += 32; - - messleng = (long)(*(unsigned short *)&pakbuf[k]); k += 2; - while (messleng) - { - j = *(long *)&pakbuf[k]; k += 4; - if ((j >= icnt0[other]) && (!ipak[other][j&(FIFSIZ-1)])) - { - if (pakmemi+messleng+2 > (long)sizeof(pakmem)) pakmemi = 1; - ipak[other][j&(FIFSIZ-1)] = pakmemi; - *(short *)&pakmem[pakmemi] = messleng; - memcpy(&pakmem[pakmemi+2],&pakbuf[k],messleng); pakmemi += messleng+2; - } - k += messleng; - messleng = (long)(*(unsigned short *)&pakbuf[k]); k += 2; - } - } - } - } - - //Return next valid packet from any player - if (!bufptr) return(0); - for(i=connecthead;i>=0;i=connectpoint2[i]) - { - if (i != myconnectindex) - { - j = ipak[i][icnt0[i]&(FIFSIZ-1)]; - if (j) - { - messleng = *(short *)&pakmem[j]; memcpy(bufptr,&pakmem[j+2],messleng); - *retother = i; ipak[i][icnt0[i]&(FIFSIZ-1)] = 0; icnt0[i]++; - //printf("Recv: "); for(i=0;i0;i--) + if (!otherip[i]) break; + if (!i) { + netready = 1; + return 0; + } + } + else + { + if (netready) return 0; + if (tims < lastsendtims[connecthead]) lastsendtims[connecthead] = tims; + if (tims >= lastsendtims[connecthead]+250) //1000/PAKRATE) + { + lastsendtims[connecthead] = tims; + + // short crc16ofs; //offset of crc16 + // long icnt0; //-1 (special packet for MMULTI.C's player collection) + // ... + // unsigned short crc16; //CRC16 of everything except crc16 + k = 2; + *(long *)&pakbuf[k] = -1; k += 4; + pakbuf[k++] = 0xaa; + *(unsigned short *)&pakbuf[0] = (unsigned short)k; + *(unsigned short *)&pakbuf[k] = getcrc16(pakbuf,k); k += 2; + netsend(connecthead,pakbuf,k); + } + } + + return 1; +} + +void initmultiplayers (long argc, char **argv, char damultioption, char dacomrateoption, char dapriority) +{ + long i, j, k, otims; + + if (initmultiplayersparms(argc,argv)) + { +#if 0 + //Console code seems to crash Win98 upon quitting game + //it's not necessary and it's not portable anyway + char tbuf[1024]; + unsigned long u; + HANDLE hconsout; + AllocConsole(); + SetConsoleTitle("Multiplayer status..."); + hconsout = GetStdHandle(STD_OUTPUT_HANDLE); + otims = 0; +#endif + while (initmultiplayerscycle()) + { +#if 0 + if ((tims < otims) || (tims > otims+100)) + { + otims = tims; + sprintf(tbuf,"\rWait for players (%d/%d): ",myconnectindex,numplayers); + for(i=0;i "); continue; } + if (!otherip[i]) { strcat(tbuf,"?.?.?.?:? "); continue; } + sprintf(&tbuf[strlen(tbuf)],"%d.%d.%d.%d:%04x ",otherip[i]&255,(otherip[i]>>8)&255,(otherip[i]>>16)&255,(((unsigned long)otherip[i])>>24),otherport[i]); + } + WriteConsole(hconsout,tbuf,strlen(tbuf),&u,0); + } + } + FreeConsole(); +#else + } +#endif + } + netready = 1; +} + +void dosendpackets (long other) +{ + long i, j, k; + + if (!otherip[other]) return; + + //Packet format: + // short crc16ofs; //offset of crc16 + // long icnt0; //earliest unacked packet + // char ibits[32]; //ack status of packets icnt0<=i>3)+k] |= (1<<((i-icnt0[other])&7)); + k += 32; + + while ((ocnt0[other] < ocnt1[other]) && (!opak[other][ocnt0[other]&(FIFSIZ-1)])) ocnt0[other]++; + for(i=ocnt0[other];i (long)sizeof(pakbuf)) break; + + *(unsigned short *)&pakbuf[k] = (unsigned short)j; k += 2; + *(long *)&pakbuf[k] = i; k += 4; + memcpy(&pakbuf[k],&pakmem[opak[other][i&(FIFSIZ-1)]+2],j); k += j; + } + *(unsigned short *)&pakbuf[k] = 0; k += 2; + *(unsigned short *)&pakbuf[0] = (unsigned short)k; + *(unsigned short *)&pakbuf[k] = getcrc16(pakbuf,k); k += 2; + + //printf("Send: "); for(i=0;i (long)sizeof(pakmem)) pakmemi = 1; + opak[other][ocnt1[other]&(FIFSIZ-1)] = pakmemi; + *(short *)&pakmem[pakmemi] = messleng; + memcpy(&pakmem[pakmemi+2],bufptr,messleng); pakmemi += messleng+2; + ocnt1[other]++; + + //printf("Send: "); for(i=0;i=0;i=connectpoint2[i]) + { + if (i != myconnectindex) dosendpackets(i); + if ((!danetmode) && (myconnectindex != connecthead)) break; //slaves in M/S mode only send to master + } + } + + while (netread(&other,pakbuf,sizeof(pakbuf))) + { + //Packet format: + // short crc16ofs; //offset of crc16 + // long icnt0; //earliest unacked packet + // char ibits[32]; //ack status of packets icnt0<=i>3)+k]&(1<<((i-ic0)&7))) + opak[other][i&(FIFSIZ-1)] = 0; + k += 32; + + messleng = (long)(*(unsigned short *)&pakbuf[k]); k += 2; + while (messleng) + { + j = *(long *)&pakbuf[k]; k += 4; + if ((j >= icnt0[other]) && (!ipak[other][j&(FIFSIZ-1)])) + { + if (pakmemi+messleng+2 > (long)sizeof(pakmem)) pakmemi = 1; + ipak[other][j&(FIFSIZ-1)] = pakmemi; + *(short *)&pakmem[pakmemi] = messleng; + memcpy(&pakmem[pakmemi+2],&pakbuf[k],messleng); pakmemi += messleng+2; + } + k += messleng; + messleng = (long)(*(unsigned short *)&pakbuf[k]); k += 2; + } + } + } + } + + //Return next valid packet from any player + if (!bufptr) return(0); + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + if (i != myconnectindex) + { + j = ipak[i][icnt0[i]&(FIFSIZ-1)]; + if (j) + { + messleng = *(short *)&pakmem[j]; memcpy(bufptr,&pakmem[j+2],messleng); + *retother = i; ipak[i][icnt0[i]&(FIFSIZ-1)] = 0; icnt0[i]++; + //printf("Recv: "); for(i=0;iwallptr]; - OSD_Printf("%i\n", sec->wallnum); -} - -void polymer_drawrooms(void) -{ - OSD_Printf("drawrooms\n"); - polymer_glinit(); - polymer_drawsector(globalcursectnum); -} +//placeholder placeholder lol + +void polymer_glinit(void) +{ + bglClearColor(0.0f, 0.0f, 0.0f, 1.0f); + bglClear(GL_COLOR_BUFFER_BIT); + bglViewport(0, 0, 1024, 768); + bglDisable(GL_TEXTURE_2D); + bglEnable(GL_DEPTH_TEST); + bglMatrixMode(GL_PROJECTION); + bglLoadIdentity(); + bglFrustum(-1.0f, 1.0f, -0.75f, 0.75, 1.0f, 100.0f); + bglMatrixMode(GL_MODELVIEW); + bglLoadIdentity(); +} + +void polymer_drawsector(short sectnum) +{ + sectortype *sec; + walltype *wal; + + sec = §or[sectnum]; + wal = &wall[sec->wallptr]; + OSD_Printf("%i\n", sec->wallnum); +} + +void polymer_drawrooms(void) +{ + OSD_Printf("drawrooms\n"); + polymer_glinit(); + polymer_drawsector(globalcursectnum); +} diff --git a/polymer/build/src/polymost.c b/polymer/build/src/polymost.c index 2fb9f9921..733c8c99c 100644 --- a/polymer/build/src/polymost.c +++ b/polymer/build/src/polymost.c @@ -543,17 +543,17 @@ void polymost_glinit() bglBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - if (glmultisample > 0 && glinfo.multisample) { - if (glinfo.nvmultisamplehint) - bglHint(GL_MULTISAMPLE_FILTER_HINT_NV, glnvmultisamplehint ? GL_NICEST:GL_FASTEST); - bglEnable(GL_MULTISAMPLE_ARB); - } + if (glmultisample > 0 && glinfo.multisample) { + if (glinfo.nvmultisamplehint) + bglHint(GL_MULTISAMPLE_FILTER_HINT_NV, glnvmultisamplehint ? GL_NICEST:GL_FASTEST); + bglEnable(GL_MULTISAMPLE_ARB); + } } void resizeglcheck () { - float m[4][4]; - float ratioratio = 1.0; + float m[4][4]; + float ratioratio = 1.0; int fovcorrect; if (glredbluemode < lastglredbluemode) { @@ -587,9 +587,9 @@ void resizeglcheck () { glox1 = windowx1; gloy1 = windowy1; glox2 = windowx2; gloy2 = windowy2; - - ratioratio = 1.6 / (((float)(windowx2-windowx1+1)) / (windowy2-windowy1)); // computes the ratio between 16/10 and current resolution ratio - fovcorrect = (ratioratio > 1) ? (((windowx2-windowx1+1) * ratioratio) - (windowx2-windowx1+1)) * ((float)glratiocorrection / 63) : 0; + + ratioratio = 1.6 / (((float)(windowx2-windowx1+1)) / (windowy2-windowy1)); // computes the ratio between 16/10 and current resolution ratio + fovcorrect = (ratioratio > 1) ? (((windowx2-windowx1+1) * ratioratio) - (windowx2-windowx1+1)) * ((float)glratiocorrection / 63) : 0; bglViewport(windowx1 - (fovcorrect / 2), yres-(windowy2+1),windowx2-windowx1+1 + fovcorrect, windowy2-windowy1+1); @@ -600,7 +600,7 @@ void resizeglcheck () m[2][2] = 1.0; m[2][3] = (float)ydimen / (1 + (glratiocorrection / (63 / (ratioratio - 1)))); m[3][2] =-1.0; bglLoadMatrixf(&m[0][0]); - //bglLoadIdentity(); + //bglLoadIdentity(); bglMatrixMode(GL_MODELVIEW); bglLoadIdentity(); @@ -1063,7 +1063,7 @@ failure: int gloadtile_hi(long dapic, long facen, hicreplctyp *hicr, long dameth, pthtyp *pth, long doalloc, char effect) { coltype *pic = NULL, *rpptr; - long j, x, y, x2, y2, xsiz = -1, ysiz = -1, tsizx, tsizy; + long j, x, y, x2, y2, xsiz=0, ysiz=0, tsizx, tsizy; char *picfil = NULL, *fn, hasalpha = 255; long picfillen, texfmt = GL_RGBA, intexfmt = GL_RGBA, filh; @@ -3635,7 +3635,7 @@ void polymost_drawsprite (long snum) double px[6], py[6]; float f, r, c, s, fx, fy, sx0, sy0, sx1, sy1, xp0, yp0, xp1, yp1, oxp0, oyp0, ryp0, ryp1, ft[4]; float x0, y0, x1, y1, sc0, sf0, sc1, sf1, px2[6], py2[6], xv, yv, t0, t1; - long i, j, spritenum, xoff = -1, yoff = -1, method, npoints; + long i, j, spritenum, xoff=0, yoff=0, method, npoints; spritetype *tspr; tspr = tspriteptr[snum]; @@ -3965,8 +3965,8 @@ void polymost_dorotatesprite (long sx, long sy, long z, short a, short picnum, double ogchang, ogshang, ogctang, ogstang, oghalfx, oghoriz, fx, fy, x1, y1, z1, x2, y2; double ogrhalfxdown10, ogrhalfxdown10x; double d, cosang, sinang, cosang2, sinang2, px[8], py[8], px2[8], py2[8]; - float m[4][4]; - float ratioratio = 1.0; + float m[4][4]; + float ratioratio = 1.0; int fovcorrect; #ifdef USE_OPENGL @@ -4034,17 +4034,17 @@ void polymost_dorotatesprite (long sx, long sy, long z, short a, short picnum, tspr.pal = dapalnum; tspr.owner = uniqid+MAXSPRITES; globalorientation = (dastat&1)+((dastat&32)<<4)+((dastat&4)<<1); - - if ((dastat&10) == 2) - { - ratioratio = 1.6 / (((float)(windowx2-windowx1+1)) / (windowy2-windowy1)); // computes the ratio between 16/10 and current resolution ratio - fovcorrect = (ratioratio > 1) ? (((windowx2-windowx1+1) * ratioratio) - windowx2-windowx1+1) * ((float)glratiocorrection / 63) * 2 : 0; - bglViewport(windowx1 - (fovcorrect / 2),yres-(windowy2+1),windowx2-windowx1+1 + fovcorrect,windowy2-windowy1+1); + + if ((dastat&10) == 2) + { + ratioratio = 1.6 / (((float)(windowx2-windowx1+1)) / (windowy2-windowy1)); // computes the ratio between 16/10 and current resolution ratio + fovcorrect = (ratioratio > 1) ? (((windowx2-windowx1+1) * ratioratio) - windowx2-windowx1+1) * ((float)glratiocorrection / 63) * 2 : 0; + bglViewport(windowx1 - (fovcorrect / 2),yres-(windowy2+1),windowx2-windowx1+1 + fovcorrect,windowy2-windowy1+1); } - else - { - bglViewport(0,0,xdim,ydim); - glox1 = -1; //Force fullscreen (glox1=-1 forces it to restore) + else + { + bglViewport(0,0,xdim,ydim); + glox1 = -1; //Force fullscreen (glox1=-1 forces it to restore) } bglMatrixMode(GL_PROJECTION); @@ -4750,16 +4750,16 @@ static int osdcmd_polymostvars(const osdfuncparm_t *parm) else glusetexcachecompression = (val != 0); return OSDCMD_OK; } - else if (!Bstrcasecmp(parm->name, "glmultisample")) { - if (showval) { OSD_Printf("glmultisample is %d\n", glmultisample); } - else glmultisample = max(0,val); - return OSDCMD_OK; - } - else if (!Bstrcasecmp(parm->name, "glnvmultisamplehint")) { - if (showval) { OSD_Printf("glnvmultisamplehint is %d\n", glnvmultisamplehint); } - else glnvmultisamplehint = (val != 0); - return OSDCMD_OK; - } + else if (!Bstrcasecmp(parm->name, "glmultisample")) { + if (showval) { OSD_Printf("glmultisample is %d\n", glmultisample); } + else glmultisample = max(0,val); + return OSDCMD_OK; + } + else if (!Bstrcasecmp(parm->name, "glnvmultisamplehint")) { + if (showval) { OSD_Printf("glnvmultisamplehint is %d\n", glnvmultisamplehint); } + else glnvmultisamplehint = (val != 0); + return OSDCMD_OK; + } #endif return OSDCMD_SHOWHELP; } @@ -4805,8 +4805,8 @@ void polymost_initosdfuncs(void) OSD_RegisterFunction("glpolygonmode","glpolygonmode: debugging feature",osdcmd_polymostvars); //FUK OSD_RegisterFunction("glusetexcache","glusetexcache: enable/disable OpenGL compressed texture cache",osdcmd_polymostvars); OSD_RegisterFunction("glusetexcachecompression","usetexcachecompression: enable/disable compression of files in the OpenGL compressed texture cache",osdcmd_polymostvars); - OSD_RegisterFunction("glmultisample","glmultisample: sets the number of samples used for antialiasing (0 = off)",osdcmd_polymostvars); - OSD_RegisterFunction("glnvmultisamplehint","glnvmultisamplehint: enable/disable Nvidia multisampling hinting",osdcmd_polymostvars); + OSD_RegisterFunction("glmultisample","glmultisample: sets the number of samples used for antialiasing (0 = off)",osdcmd_polymostvars); + OSD_RegisterFunction("glnvmultisamplehint","glnvmultisamplehint: enable/disable Nvidia multisampling hinting",osdcmd_polymostvars); #endif OSD_RegisterFunction("usemodels","usemodels: enable/disable model rendering in >8-bit mode",osdcmd_polymostvars); OSD_RegisterFunction("usehightile","usehightile: enable/disable hightile texture rendering in >8-bit mode",osdcmd_polymostvars); @@ -4929,7 +4929,7 @@ int dxtfilter(int fil, texcachepicture *pict, char *pic, void *midbuf, char *pac if (Bwrite(fil, &j, sizeof(unsigned long)) != sizeof(unsigned long)) return -1; if (Bwrite(fil, writebuf, cleng) != cleng) return -1; #else - long j, k, offs, stride, cleng; + unsigned long j, k, offs, stride, cleng; char *cptr; if ((pict->format == B_LITTLE32(GL_COMPRESSED_RGB_S3TC_DXT1_EXT)) || diff --git a/polymer/build/src/scriptfile.c b/polymer/build/src/scriptfile.c index 514cfcb93..c7cb9d1d8 100644 --- a/polymer/build/src/scriptfile.c +++ b/polymer/build/src/scriptfile.c @@ -1,394 +1,395 @@ -/* - * File Tokeniser/Parser/Whatever - * by Jonathon Fowler - * Remixed completely by Ken Silverman - * See the included license file "BUILDLIC.TXT" for license info. - */ - -#include "scriptfile.h" -#include "baselayer.h" -#include "compat.h" -#include "cache1d.h" - - -#define ISWS(x) ((x == ' ') || (x == '\t') || (x == '\r') || (x == '\n')) -static void skipoverws(scriptfile *sf) { if ((sf->textptr < sf->eof) && (!sf->textptr[0])) sf->textptr++; } -static void skipovertoken(scriptfile *sf) { while ((sf->textptr < sf->eof) && (sf->textptr[0])) sf->textptr++; } - -char *scriptfile_gettoken(scriptfile *sf) -{ - char *start; - - skipoverws(sf); - if (sf->textptr >= sf->eof) return NULL; - - start = sf->ltextptr = sf->textptr; - skipovertoken(sf); - return start; -} - -int scriptfile_getstring(scriptfile *sf, char **retst) -{ - (*retst) = scriptfile_gettoken(sf); - if (*retst == NULL) - { - initprintf("Error on line %s:%d: unexpected eof\n",sf->filename,scriptfile_getlinum(sf,sf->textptr)); - return(-2); - } - return(0); -} - -int scriptfile_getnumber(scriptfile *sf, int *num) -{ - skipoverws(sf); - if (sf->textptr >= sf->eof) - { - initprintf("Error on line %s:%d: unexpected eof\n",sf->filename,scriptfile_getlinum(sf,sf->textptr)); - return -1; - } - - while ((sf->textptr[0] == '0') && (sf->textptr[1] >= '0') && (sf->textptr[1] <= '9')) - sf->textptr++; //hack to treat octal numbers like decimal - - sf->ltextptr = sf->textptr; - (*num) = strtol((const char *)sf->textptr,&sf->textptr,0); - if (!ISWS(*sf->textptr) && *sf->textptr) { - char *p = sf->textptr; - skipovertoken(sf); - initprintf("Error on line %s:%d: expecting int, got \"%s\"\n",sf->filename,scriptfile_getlinum(sf,sf->ltextptr),p); - return -2; - } - return 0; -} - -static double parsedouble(char *ptr, char **end) -{ - int beforedecimal = 1, negative = 0, dig; - int exposgn = 0, expo = 0; - double num = 0.0, decpl = 0.1; - char *p; - - p = ptr; - if (*p == '-') negative = 1, p++; - else if (*p == '+') p++; - for (;; p++) { - if (*p >= '0' && *p <= '9') { - dig = *p - '0'; - if (beforedecimal) num = num * 10.0 + dig; - else if (exposgn) expo = expo*10 + dig; - else { - num += (double)dig * decpl; - decpl /= 10.0; - } - } else if (*p == '.') { - if (beforedecimal) beforedecimal = 0; - else break; - } else if ((*p == 'E') || (*p == 'e')) { - exposgn = 1; - if (p[1] == '-') { exposgn = -1; p++; } - else if (p[1] == '+') p++; - } else break; - } - - if (end) *end = p; - if (exposgn) num *= pow(10.0,(double)(expo*exposgn)); - return negative ? -num : num; -} - -int scriptfile_getdouble(scriptfile *sf, double *num) -{ - skipoverws(sf); - if (sf->textptr >= sf->eof) - { - initprintf("Error on line %s:%d: unexpected eof\n",sf->filename,scriptfile_getlinum(sf,sf->textptr)); - return -1; - } - - sf->ltextptr = sf->textptr; - - // On Linux, locale settings interfere with interpreting x.y format numbers - //(*num) = strtod((const char *)sf->textptr,&sf->textptr); - (*num) = parsedouble(sf->textptr, &sf->textptr); - - if (!ISWS(*sf->textptr) && *sf->textptr) { - char *p = sf->textptr; - skipovertoken(sf); - initprintf("Error on line %s:%d: expecting float, got \"%s\"\n",sf->filename,scriptfile_getlinum(sf,sf->ltextptr),p); - return -2; - } - return 0; -} - -int scriptfile_getsymbol(scriptfile *sf, int *num) -{ - char *t, *e; - int v; - - t = scriptfile_gettoken(sf); - if (!t) return -1; - - v = Bstrtol(t, &e, 10); - if (*e) { - // looks like a string, so find it in the symbol table - if (scriptfile_getsymbolvalue(t, num)) return 0; - initprintf("Error on line %s:%d: expecting symbol, got \"%s\"\n",sf->filename,scriptfile_getlinum(sf,sf->ltextptr),t); - return -2; // not found - } - - *num = v; - return 0; -} - -int scriptfile_getbraces(scriptfile *sf, char **braceend) -{ - int bracecnt; - char *bracestart; - - skipoverws(sf); - if (sf->textptr >= sf->eof) - { - initprintf("Error on line %s:%d: unexpected eof\n",sf->filename,scriptfile_getlinum(sf,sf->textptr)); - return -1; - } - - if (sf->textptr[0] != '{') { - initprintf("Error on line %s:%d: expecting '{'\n",sf->filename,scriptfile_getlinum(sf,sf->textptr)); - return -1; - } - bracestart = ++sf->textptr; bracecnt = 1; - while (1) - { - if (sf->textptr >= sf->eof) return(0); - if (sf->textptr[0] == '{') bracecnt++; - if (sf->textptr[0] == '}') { bracecnt--; if (!bracecnt) break; } - sf->textptr++; - } - (*braceend) = sf->textptr; - sf->textptr = bracestart; - return 0; -} - - -int scriptfile_getlinum (scriptfile *sf, char *ptr) -{ - int i, stp, ind; - - //for(i=0;ilinenum;i++) if (sf->lineoffs[i] >= ind) return(i+1); //brute force algo - - ind = ((long)ptr) - ((long)sf->textbuf); - - for(stp=1;stp+stplinenum;stp+=stp); //stp = highest power of 2 less than sf->linenum - for(i=0;stp;stp>>=1) - if ((i+stp < sf->linenum) && (sf->lineoffs[i+stp] < ind)) i += stp; - return(i+1); //i = index to highest lineoffs which is less than ind; convert to 1-based line numbers -} - -void scriptfile_preparse (scriptfile *sf, char *tx, long flen) -{ - long i, cr, numcr, nflen, ws, cs, inquote; - - //Count number of lines - numcr = 1; - for(i=0;ilinenum = numcr; - sf->lineoffs = (long *)malloc(sf->linenum*sizeof(long)); - - //Preprocess file for comments (// and /*...*/, and convert all whitespace to single spaces) - nflen = 0; ws = 0; cs = 0; numcr = 0; inquote = 0; - for(i=0;ilineoffs[numcr++] = nflen; - if (cs == 1) cs = 0; - ws = 1; continue; //strip CR/LF - } - - if ((!inquote) && ((tx[i] == ' ') || (tx[i] == '\t'))) { ws = 1; continue; } //strip Space/Tab - if ((tx[i] == '/') && (tx[i+1] == '/') && (!cs)) cs = 1; - if ((tx[i] == '/') && (tx[i+1] == '*') && (!cs)) { ws = 1; cs = 2; } - if ((tx[i] == '*') && (tx[i+1] == '/') && (cs == 2)) { cs = 0; i++; continue; } - if (cs) continue; - - if (ws) { tx[nflen++] = 0; ws = 0; } - - //quotes inside strings: \" - if ((tx[i] == '\\') && (tx[i+1] == '\"')) { i++; tx[nflen++] = '\"'; continue; } - if (tx[i] == '\"') { inquote ^= 1; continue; } - tx[nflen++] = tx[i]; - } - tx[nflen++] = 0; sf->lineoffs[numcr] = nflen; - tx[nflen++] = 0; - -#if 0 - //for debugging only: - printf("pre-parsed file:flen=%d,nflen=%d\n",flen,nflen); - for(i=0;ilinenum); - for(i=0;ilinenum;i++) printf("line %d = byte %d\n",i,sf->lineoffs[i]); -#endif - flen = nflen; - - sf->textbuf = sf->textptr = tx; - sf->textlength = nflen; - sf->eof = &sf->textbuf[nflen-1]; -} - -scriptfile *scriptfile_fromfile(char *fn) -{ - int fp; - scriptfile *sf; - char *tx; - unsigned int flen; - - fp = kopen4load(fn,0); - if (fp<0) return NULL; - - flen = kfilelength(fp); - tx = (char *) malloc(flen + 2); - if (!tx) { - kclose(fp); - return NULL; - } - - sf = (scriptfile*) malloc(sizeof(scriptfile)); - if (!sf) { - kclose(fp); - free(tx); - return NULL; - } - - kread(fp, tx, flen); - tx[flen] = tx[flen+1] = 0; - - kclose(fp); - - scriptfile_preparse(sf,tx,flen); - sf->filename = strdup(fn); - - return sf; -} - -scriptfile *scriptfile_fromstring(char *string) -{ - scriptfile *sf; - char *tx; - unsigned int flen; - - if (!string) return NULL; - - flen = strlen(string); - - tx = (char *) malloc(flen + 2); - if (!tx) return NULL; - - sf = (scriptfile*) malloc(sizeof(scriptfile)); - if (!sf) { - free(tx); - return NULL; - } - - memcpy(tx, string, flen); - tx[flen] = tx[flen+1] = 0; - - scriptfile_preparse(sf,tx,flen); - sf->filename = NULL; - - return sf; -} - -void scriptfile_close(scriptfile *sf) -{ - if (!sf) return; - if (sf->lineoffs) free(sf->lineoffs); - if (sf->textbuf) free(sf->textbuf); - if (sf->filename) free(sf->filename); - sf->textbuf = NULL; - sf->filename = NULL; - free(sf); -} - - -#define SYMBTABSTARTSIZE 256 -static int symbtablength=0, symbtaballoclength=0; -static char *symbtab = NULL; - -static char * getsymbtabspace(int reqd) -{ - char *pos,*np; - int i; - - if (symbtablength + reqd > symbtaballoclength) - { - for(i=max(symbtaballoclength,SYMBTABSTARTSIZE);symbtablength+reqd>i;i<<=1); - np = (char *)realloc(symbtab, i); if (!np) return NULL; - symbtab = np; symbtaballoclength = i; - } - - pos = &symbtab[symbtablength]; - symbtablength += reqd; - return pos; -} - -int scriptfile_getsymbolvalue(char *name, int *val) -{ - char *scanner = symbtab; - - if (!symbtab) return 0; - while (scanner - symbtab < symbtablength) { - if (!Bstrcasecmp(name, scanner)) { - *val = *(int*)(scanner + strlen(scanner) + 1); - return 1; - } - - scanner += strlen(scanner) + 1 + sizeof(int); - } - - return 0; -} - -int scriptfile_addsymbolvalue(char *name, int val) -{ - int x; - char *sp; -// if (scriptfile_getsymbolvalue(name, &x)) return -1; // already exists - - if (symbtab) { - char *scanner = symbtab; - while (scanner - symbtab < symbtablength) { - if (!Bstrcasecmp(name, scanner)) { - *(int*)(scanner + strlen(scanner) + 1) = val; - return 1; - } - - scanner += strlen(scanner) + 1 + sizeof(int); - } - } - - sp = getsymbtabspace(strlen(name) + 1 + sizeof(int)); - if (!sp) return 0; - strcpy(sp, name); - sp += strlen(name)+1; - *(int*)sp = val; - return 1; // added -} - -void scriptfile_clearsymbols(void) -{ - if (symbtab) free(symbtab); - symbtab = NULL; - symbtablength = 0; - symbtaballoclength = 0; -} +/* + * File Tokeniser/Parser/Whatever + * by Jonathon Fowler + * Remixed completely by Ken Silverman + * See the included license file "BUILDLIC.TXT" for license info. + */ + +#include "scriptfile.h" +#include "baselayer.h" +#include "compat.h" +#include "cache1d.h" +#include + + +#define ISWS(x) ((x == ' ') || (x == '\t') || (x == '\r') || (x == '\n')) +static void skipoverws(scriptfile *sf) { if ((sf->textptr < sf->eof) && (!sf->textptr[0])) sf->textptr++; } +static void skipovertoken(scriptfile *sf) { while ((sf->textptr < sf->eof) && (sf->textptr[0])) sf->textptr++; } + +char *scriptfile_gettoken(scriptfile *sf) +{ + char *start; + + skipoverws(sf); + if (sf->textptr >= sf->eof) return NULL; + + start = sf->ltextptr = sf->textptr; + skipovertoken(sf); + return start; +} + +int scriptfile_getstring(scriptfile *sf, char **retst) +{ + (*retst) = scriptfile_gettoken(sf); + if (*retst == NULL) + { + initprintf("Error on line %s:%d: unexpected eof\n",sf->filename,scriptfile_getlinum(sf,sf->textptr)); + return(-2); + } + return(0); +} + +int scriptfile_getnumber(scriptfile *sf, int *num) +{ + skipoverws(sf); + if (sf->textptr >= sf->eof) + { + initprintf("Error on line %s:%d: unexpected eof\n",sf->filename,scriptfile_getlinum(sf,sf->textptr)); + return -1; + } + + while ((sf->textptr[0] == '0') && (sf->textptr[1] >= '0') && (sf->textptr[1] <= '9')) + sf->textptr++; //hack to treat octal numbers like decimal + + sf->ltextptr = sf->textptr; + (*num) = strtol((const char *)sf->textptr,&sf->textptr,0); + if (!ISWS(*sf->textptr) && *sf->textptr) { + char *p = sf->textptr; + skipovertoken(sf); + initprintf("Error on line %s:%d: expecting int, got \"%s\"\n",sf->filename,scriptfile_getlinum(sf,sf->ltextptr),p); + return -2; + } + return 0; +} + +static double parsedouble(char *ptr, char **end) +{ + int beforedecimal = 1, negative = 0, dig; + int exposgn = 0, expo = 0; + double num = 0.0, decpl = 0.1; + char *p; + + p = ptr; + if (*p == '-') negative = 1, p++; + else if (*p == '+') p++; + for (;; p++) { + if (*p >= '0' && *p <= '9') { + dig = *p - '0'; + if (beforedecimal) num = num * 10.0 + dig; + else if (exposgn) expo = expo*10 + dig; + else { + num += (double)dig * decpl; + decpl /= 10.0; + } + } else if (*p == '.') { + if (beforedecimal) beforedecimal = 0; + else break; + } else if ((*p == 'E') || (*p == 'e')) { + exposgn = 1; + if (p[1] == '-') { exposgn = -1; p++; } + else if (p[1] == '+') p++; + } else break; + } + + if (end) *end = p; + if (exposgn) num *= pow(10.0,(double)(expo*exposgn)); + return negative ? -num : num; +} + +int scriptfile_getdouble(scriptfile *sf, double *num) +{ + skipoverws(sf); + if (sf->textptr >= sf->eof) + { + initprintf("Error on line %s:%d: unexpected eof\n",sf->filename,scriptfile_getlinum(sf,sf->textptr)); + return -1; + } + + sf->ltextptr = sf->textptr; + + // On Linux, locale settings interfere with interpreting x.y format numbers + //(*num) = strtod((const char *)sf->textptr,&sf->textptr); + (*num) = parsedouble(sf->textptr, &sf->textptr); + + if (!ISWS(*sf->textptr) && *sf->textptr) { + char *p = sf->textptr; + skipovertoken(sf); + initprintf("Error on line %s:%d: expecting float, got \"%s\"\n",sf->filename,scriptfile_getlinum(sf,sf->ltextptr),p); + return -2; + } + return 0; +} + +int scriptfile_getsymbol(scriptfile *sf, int *num) +{ + char *t, *e; + int v; + + t = scriptfile_gettoken(sf); + if (!t) return -1; + + v = Bstrtol(t, &e, 10); + if (*e) { + // looks like a string, so find it in the symbol table + if (scriptfile_getsymbolvalue(t, num)) return 0; + initprintf("Error on line %s:%d: expecting symbol, got \"%s\"\n",sf->filename,scriptfile_getlinum(sf,sf->ltextptr),t); + return -2; // not found + } + + *num = v; + return 0; +} + +int scriptfile_getbraces(scriptfile *sf, char **braceend) +{ + int bracecnt; + char *bracestart; + + skipoverws(sf); + if (sf->textptr >= sf->eof) + { + initprintf("Error on line %s:%d: unexpected eof\n",sf->filename,scriptfile_getlinum(sf,sf->textptr)); + return -1; + } + + if (sf->textptr[0] != '{') { + initprintf("Error on line %s:%d: expecting '{'\n",sf->filename,scriptfile_getlinum(sf,sf->textptr)); + return -1; + } + bracestart = ++sf->textptr; bracecnt = 1; + while (1) + { + if (sf->textptr >= sf->eof) return(0); + if (sf->textptr[0] == '{') bracecnt++; + if (sf->textptr[0] == '}') { bracecnt--; if (!bracecnt) break; } + sf->textptr++; + } + (*braceend) = sf->textptr; + sf->textptr = bracestart; + return 0; +} + + +int scriptfile_getlinum (scriptfile *sf, char *ptr) +{ + int i, stp, ind; + + //for(i=0;ilinenum;i++) if (sf->lineoffs[i] >= ind) return(i+1); //brute force algo + + ind = ((long)ptr) - ((long)sf->textbuf); + + for(stp=1;stp+stplinenum;stp+=stp); //stp = highest power of 2 less than sf->linenum + for(i=0;stp;stp>>=1) + if ((i+stp < sf->linenum) && (sf->lineoffs[i+stp] < ind)) i += stp; + return(i+1); //i = index to highest lineoffs which is less than ind; convert to 1-based line numbers +} + +void scriptfile_preparse (scriptfile *sf, char *tx, long flen) +{ + long i, cr, numcr, nflen, ws, cs, inquote; + + //Count number of lines + numcr = 1; + for(i=0;ilinenum = numcr; + sf->lineoffs = (long *)malloc(sf->linenum*sizeof(long)); + + //Preprocess file for comments (// and /*...*/, and convert all whitespace to single spaces) + nflen = 0; ws = 0; cs = 0; numcr = 0; inquote = 0; + for(i=0;ilineoffs[numcr++] = nflen; + if (cs == 1) cs = 0; + ws = 1; continue; //strip CR/LF + } + + if ((!inquote) && ((tx[i] == ' ') || (tx[i] == '\t'))) { ws = 1; continue; } //strip Space/Tab + if ((tx[i] == '/') && (tx[i+1] == '/') && (!cs)) cs = 1; + if ((tx[i] == '/') && (tx[i+1] == '*') && (!cs)) { ws = 1; cs = 2; } + if ((tx[i] == '*') && (tx[i+1] == '/') && (cs == 2)) { cs = 0; i++; continue; } + if (cs) continue; + + if (ws) { tx[nflen++] = 0; ws = 0; } + + //quotes inside strings: \" + if ((tx[i] == '\\') && (tx[i+1] == '\"')) { i++; tx[nflen++] = '\"'; continue; } + if (tx[i] == '\"') { inquote ^= 1; continue; } + tx[nflen++] = tx[i]; + } + tx[nflen++] = 0; sf->lineoffs[numcr] = nflen; + tx[nflen++] = 0; + +#if 0 + //for debugging only: + printf("pre-parsed file:flen=%d,nflen=%d\n",flen,nflen); + for(i=0;ilinenum); + for(i=0;ilinenum;i++) printf("line %d = byte %d\n",i,sf->lineoffs[i]); +#endif + flen = nflen; + + sf->textbuf = sf->textptr = tx; + sf->textlength = nflen; + sf->eof = &sf->textbuf[nflen-1]; +} + +scriptfile *scriptfile_fromfile(char *fn) +{ + int fp; + scriptfile *sf; + char *tx; + unsigned int flen; + + fp = kopen4load(fn,0); + if (fp<0) return NULL; + + flen = kfilelength(fp); + tx = (char *) malloc(flen + 2); + if (!tx) { + kclose(fp); + return NULL; + } + + sf = (scriptfile*) malloc(sizeof(scriptfile)); + if (!sf) { + kclose(fp); + free(tx); + return NULL; + } + + kread(fp, tx, flen); + tx[flen] = tx[flen+1] = 0; + + kclose(fp); + + scriptfile_preparse(sf,tx,flen); + sf->filename = strdup(fn); + + return sf; +} + +scriptfile *scriptfile_fromstring(char *string) +{ + scriptfile *sf; + char *tx; + unsigned int flen; + + if (!string) return NULL; + + flen = strlen(string); + + tx = (char *) malloc(flen + 2); + if (!tx) return NULL; + + sf = (scriptfile*) malloc(sizeof(scriptfile)); + if (!sf) { + free(tx); + return NULL; + } + + memcpy(tx, string, flen); + tx[flen] = tx[flen+1] = 0; + + scriptfile_preparse(sf,tx,flen); + sf->filename = NULL; + + return sf; +} + +void scriptfile_close(scriptfile *sf) +{ + if (!sf) return; + if (sf->lineoffs) free(sf->lineoffs); + if (sf->textbuf) free(sf->textbuf); + if (sf->filename) free(sf->filename); + sf->textbuf = NULL; + sf->filename = NULL; + free(sf); +} + + +#define SYMBTABSTARTSIZE 256 +static int symbtablength=0, symbtaballoclength=0; +static char *symbtab = NULL; + +static char * getsymbtabspace(int reqd) +{ + char *pos,*np; + int i; + + if (symbtablength + reqd > symbtaballoclength) + { + for(i=max(symbtaballoclength,SYMBTABSTARTSIZE);symbtablength+reqd>i;i<<=1); + np = (char *)realloc(symbtab, i); if (!np) return NULL; + symbtab = np; symbtaballoclength = i; + } + + pos = &symbtab[symbtablength]; + symbtablength += reqd; + return pos; +} + +int scriptfile_getsymbolvalue(char *name, int *val) +{ + char *scanner = symbtab; + + if (!symbtab) return 0; + while (scanner - symbtab < symbtablength) { + if (!Bstrcasecmp(name, scanner)) { + *val = *(int*)(scanner + strlen(scanner) + 1); + return 1; + } + + scanner += strlen(scanner) + 1 + sizeof(int); + } + + return 0; +} + +int scriptfile_addsymbolvalue(char *name, int val) +{ + int x; + char *sp; +// if (scriptfile_getsymbolvalue(name, &x)) return -1; // already exists + + if (symbtab) { + char *scanner = symbtab; + while (scanner - symbtab < symbtablength) { + if (!Bstrcasecmp(name, scanner)) { + *(int*)(scanner + strlen(scanner) + 1) = val; + return 1; + } + + scanner += strlen(scanner) + 1 + sizeof(int); + } + } + + sp = getsymbtabspace(strlen(name) + 1 + sizeof(int)); + if (!sp) return 0; + strcpy(sp, name); + sp += strlen(name)+1; + *(int*)sp = val; + return 1; // added +} + +void scriptfile_clearsymbols(void) +{ + if (symbtab) free(symbtab); + symbtab = NULL; + symbtablength = 0; + symbtaballoclength = 0; +} diff --git a/polymer/build/src/sdlayer.c b/polymer/build/src/sdlayer.c index 2ebb2e08c..2bccd9cbb 100644 --- a/polymer/build/src/sdlayer.c +++ b/polymer/build/src/sdlayer.c @@ -1105,6 +1105,7 @@ void showframe(int w) bglPushMatrix(); bglLoadIdentity(); + bglDisable(GL_ALPHA_TEST); bglDisable(GL_DEPTH_TEST); bglDisable(GL_ALPHA_TEST); bglDisable(GL_TEXTURE_2D); diff --git a/polymer/build/src/smalltextfont.c b/polymer/build/src/smalltextfont.c index ef60b8715..c72eef6bf 100644 --- a/polymer/build/src/smalltextfont.c +++ b/polymer/build/src/smalltextfont.c @@ -1,179 +1,179 @@ -// SMALLTEXTFONT.C - -// Font created by Ken Silverman -// Generated by BIN2C.EXE by Jonathon Fowler - -char smalltextfont[2048] = { - // 2048 bytes - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x24, - 0x3C, 0x18, 0x00, 0x00, 0x00, 0x18, 0x24, 0x3C, 0x24, 0x18, 0x00, 0x00, - 0x00, 0x28, 0x3C, 0x3C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x10, 0x38, 0x3C, - 0x38, 0x10, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x3C, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x3C, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x28, 0x38, 0x38, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x14, 0x14, 0x30, 0x00, 0x00, - 0x00, 0x24, 0x18, 0x3C, 0x18, 0x24, 0x00, 0x00, 0x00, 0x20, 0x30, 0x38, - 0x30, 0x20, 0x00, 0x00, 0x00, 0x08, 0x18, 0x38, 0x18, 0x08, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x10, 0x38, 0x10, 0x00, 0x00, 0x00, 0x28, 0x28, 0x28, - 0x00, 0x28, 0x00, 0x00, 0x00, 0x1C, 0x34, 0x34, 0x14, 0x14, 0x00, 0x00, - 0x00, 0x1C, 0x30, 0x28, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x38, 0x38, 0x00, 0x00, 0x00, 0x10, 0x38, 0x10, 0x38, 0x38, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, - 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3C, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x28, 0x28, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x3C, 0x28, 0x3C, 0x28, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x10, 0x18, 0x30, 0x00, 0x00, 0x00, 0x28, 0x08, 0x10, - 0x20, 0x28, 0x00, 0x00, 0x00, 0x10, 0x28, 0x10, 0x30, 0x38, 0x00, 0x00, - 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, - 0x20, 0x10, 0x00, 0x00, 0x00, 0x10, 0x08, 0x08, 0x08, 0x10, 0x00, 0x00, - 0x00, 0x00, 0x28, 0x10, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x10, 0x20, 0x00, 0x00, - 0x00, 0x38, 0x28, 0x28, 0x28, 0x38, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x00, 0x00, 0x00, 0x38, 0x08, 0x38, 0x20, 0x38, 0x00, 0x00, - 0x00, 0x38, 0x08, 0x38, 0x08, 0x38, 0x00, 0x00, 0x00, 0x28, 0x28, 0x38, - 0x08, 0x08, 0x00, 0x00, 0x00, 0x38, 0x20, 0x38, 0x08, 0x38, 0x00, 0x00, - 0x00, 0x38, 0x20, 0x38, 0x28, 0x38, 0x00, 0x00, 0x00, 0x38, 0x08, 0x08, - 0x08, 0x08, 0x00, 0x00, 0x00, 0x38, 0x28, 0x38, 0x28, 0x38, 0x00, 0x00, - 0x00, 0x38, 0x28, 0x38, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x20, 0x00, 0x00, - 0x00, 0x08, 0x10, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, - 0x38, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x10, 0x20, 0x00, 0x00, - 0x00, 0x30, 0x08, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x38, 0x28, 0x38, - 0x30, 0x38, 0x00, 0x00, 0x00, 0x10, 0x28, 0x38, 0x28, 0x28, 0x00, 0x00, - 0x00, 0x30, 0x28, 0x30, 0x28, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0x20, - 0x20, 0x18, 0x00, 0x00, 0x00, 0x30, 0x28, 0x28, 0x28, 0x30, 0x00, 0x00, - 0x00, 0x38, 0x20, 0x30, 0x20, 0x38, 0x00, 0x00, 0x00, 0x38, 0x20, 0x30, - 0x20, 0x20, 0x00, 0x00, 0x00, 0x38, 0x20, 0x28, 0x28, 0x38, 0x00, 0x00, - 0x00, 0x28, 0x28, 0x38, 0x28, 0x28, 0x00, 0x00, 0x00, 0x38, 0x10, 0x10, - 0x10, 0x38, 0x00, 0x00, 0x00, 0x38, 0x08, 0x08, 0x28, 0x18, 0x00, 0x00, - 0x00, 0x28, 0x28, 0x30, 0x28, 0x28, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, - 0x20, 0x38, 0x00, 0x00, 0x00, 0x28, 0x38, 0x38, 0x28, 0x28, 0x00, 0x00, - 0x00, 0x28, 0x38, 0x38, 0x38, 0x28, 0x00, 0x00, 0x00, 0x38, 0x28, 0x28, - 0x28, 0x38, 0x00, 0x00, 0x00, 0x38, 0x28, 0x38, 0x20, 0x20, 0x00, 0x00, - 0x00, 0x38, 0x28, 0x28, 0x38, 0x18, 0x00, 0x00, 0x00, 0x38, 0x28, 0x30, - 0x28, 0x28, 0x00, 0x00, 0x00, 0x38, 0x20, 0x38, 0x08, 0x38, 0x00, 0x00, - 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x28, 0x28, 0x28, - 0x28, 0x38, 0x00, 0x00, 0x00, 0x28, 0x28, 0x28, 0x10, 0x10, 0x00, 0x00, - 0x00, 0x28, 0x28, 0x38, 0x38, 0x28, 0x00, 0x00, 0x00, 0x28, 0x28, 0x10, - 0x28, 0x28, 0x00, 0x00, 0x00, 0x28, 0x28, 0x38, 0x10, 0x10, 0x00, 0x00, - 0x00, 0x38, 0x08, 0x10, 0x20, 0x38, 0x00, 0x00, 0x00, 0x30, 0x20, 0x20, - 0x20, 0x30, 0x00, 0x00, 0x00, 0x20, 0x10, 0x10, 0x08, 0x08, 0x00, 0x00, - 0x00, 0x18, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x10, 0x28, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, - 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x28, 0x18, 0x00, 0x00, 0x00, 0x20, 0x20, 0x38, 0x28, 0x38, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x38, 0x20, 0x38, 0x00, 0x00, 0x00, 0x08, 0x08, 0x38, - 0x28, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x18, 0x00, 0x00, - 0x00, 0x08, 0x10, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, - 0x18, 0x08, 0x30, 0x00, 0x00, 0x20, 0x20, 0x38, 0x28, 0x28, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, - 0x10, 0x10, 0x20, 0x00, 0x00, 0x20, 0x20, 0x28, 0x30, 0x28, 0x00, 0x00, - 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x20, 0x38, - 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x28, 0x28, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x38, 0x28, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, - 0x28, 0x38, 0x20, 0x00, 0x00, 0x00, 0x00, 0x38, 0x28, 0x38, 0x08, 0x00, - 0x00, 0x00, 0x00, 0x38, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x10, 0x30, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x10, 0x10, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x28, 0x28, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, - 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x28, 0x10, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, - 0x28, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x18, 0x00, 0x00, - 0x00, 0x18, 0x10, 0x20, 0x10, 0x18, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, - 0x10, 0x10, 0x00, 0x00, 0x00, 0x30, 0x10, 0x08, 0x10, 0x30, 0x00, 0x00, - 0x00, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, - 0x38, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x18, 0x30, 0x00, - 0x00, 0x28, 0x00, 0x28, 0x28, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, - 0x38, 0x18, 0x00, 0x00, 0x00, 0x38, 0x00, 0x18, 0x28, 0x18, 0x00, 0x00, - 0x00, 0x28, 0x00, 0x18, 0x28, 0x18, 0x00, 0x00, 0x00, 0x30, 0x00, 0x18, - 0x28, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x28, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x38, 0x20, 0x38, 0x10, 0x00, 0x00, 0x38, 0x00, 0x18, - 0x38, 0x18, 0x00, 0x00, 0x00, 0x28, 0x00, 0x18, 0x38, 0x18, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x18, 0x38, 0x18, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, - 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x10, 0x10, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x28, 0x10, 0x28, - 0x38, 0x28, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x38, 0x28, 0x00, 0x00, - 0x00, 0x18, 0x00, 0x38, 0x30, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, - 0x28, 0x1C, 0x00, 0x00, 0x00, 0x1C, 0x28, 0x3C, 0x28, 0x2C, 0x00, 0x00, - 0x00, 0x38, 0x00, 0x38, 0x28, 0x38, 0x00, 0x00, 0x00, 0x28, 0x00, 0x38, - 0x28, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x38, 0x28, 0x38, 0x00, 0x00, - 0x00, 0x38, 0x00, 0x28, 0x28, 0x18, 0x00, 0x00, 0x00, 0x30, 0x00, 0x28, - 0x28, 0x18, 0x00, 0x00, 0x00, 0x28, 0x00, 0x28, 0x28, 0x18, 0x30, 0x00, - 0x00, 0x28, 0x00, 0x38, 0x28, 0x38, 0x00, 0x00, 0x00, 0x28, 0x00, 0x28, - 0x28, 0x38, 0x00, 0x00, 0x00, 0x10, 0x38, 0x20, 0x38, 0x10, 0x00, 0x00, - 0x00, 0x18, 0x14, 0x30, 0x10, 0x3C, 0x00, 0x00, 0x00, 0x28, 0x10, 0x38, - 0x38, 0x10, 0x00, 0x00, 0x00, 0x30, 0x28, 0x3C, 0x28, 0x2C, 0x00, 0x00, - 0x00, 0x18, 0x10, 0x38, 0x10, 0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, - 0x28, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x10, 0x10, 0x00, 0x00, - 0x00, 0x18, 0x00, 0x38, 0x28, 0x38, 0x00, 0x00, 0x00, 0x18, 0x00, 0x28, - 0x28, 0x18, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x28, 0x28, 0x00, 0x00, - 0x00, 0x38, 0x00, 0x28, 0x38, 0x28, 0x00, 0x00, 0x00, 0x18, 0x28, 0x18, - 0x00, 0x38, 0x00, 0x00, 0x00, 0x38, 0x28, 0x38, 0x00, 0x38, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x10, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x20, 0x28, 0x10, 0x38, 0x18, 0x00, 0x00, 0x00, 0x20, 0x28, 0x18, - 0x38, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, - 0x00, 0x00, 0x14, 0x28, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x14, - 0x28, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x08, 0x20, 0x08, 0x20, 0x00, - 0x00, 0x14, 0x28, 0x14, 0x28, 0x14, 0x28, 0x00, 0x00, 0x34, 0x1C, 0x34, - 0x1C, 0x34, 0x1C, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, - 0x00, 0x10, 0x10, 0x30, 0x10, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x30, - 0x30, 0x10, 0x10, 0x00, 0x00, 0x18, 0x18, 0x38, 0x18, 0x18, 0x18, 0x00, - 0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x30, - 0x30, 0x10, 0x10, 0x00, 0x00, 0x18, 0x18, 0x38, 0x38, 0x18, 0x18, 0x00, - 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x38, - 0x38, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x38, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x18, 0x18, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x30, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x10, 0x10, 0x00, - 0x00, 0x10, 0x10, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x3C, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x10, 0x00, - 0x00, 0x10, 0x10, 0x1C, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3C, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x3C, 0x10, 0x10, 0x10, 0x00, - 0x00, 0x10, 0x10, 0x1C, 0x1C, 0x10, 0x10, 0x00, 0x00, 0x18, 0x18, 0x1C, - 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x1C, 0x1C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x3C, - 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x18, 0x18, 0x00, - 0x00, 0x18, 0x18, 0x1C, 0x1C, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x3C, - 0x3C, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, - 0x00, 0x10, 0x10, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x3C, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x10, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x1C, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1C, 0x1C, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1C, - 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x3C, 0x18, 0x18, 0x18, 0x00, - 0x00, 0x10, 0x10, 0x3C, 0x3C, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x30, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x10, 0x10, 0x10, 0x00, - 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, - 0x00, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x00, 0x00, 0x3C, 0x3C, 0x3C, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x28, 0x34, 0x00, 0x00, - 0x00, 0x30, 0x28, 0x30, 0x28, 0x30, 0x20, 0x00, 0x00, 0x38, 0x28, 0x20, - 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x38, 0x20, 0x10, 0x20, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, - 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28, 0x30, 0x20, 0x00, 0x00, - 0x00, 0x00, 0x14, 0x28, 0x08, 0x08, 0x00, 0x00, 0x00, 0x38, 0x10, 0x28, - 0x10, 0x38, 0x00, 0x00, 0x00, 0x10, 0x28, 0x38, 0x28, 0x10, 0x00, 0x00, - 0x00, 0x18, 0x24, 0x24, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x18, 0x10, 0x18, - 0x28, 0x38, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x18, 0x3C, 0x18, 0x20, 0x00, 0x00, 0x00, 0x18, 0x20, 0x30, - 0x20, 0x18, 0x00, 0x00, 0x00, 0x10, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00, - 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x00, 0x00, 0x10, 0x38, 0x10, - 0x00, 0x38, 0x00, 0x00, 0x00, 0x10, 0x08, 0x10, 0x00, 0x38, 0x00, 0x00, - 0x00, 0x10, 0x20, 0x10, 0x00, 0x38, 0x00, 0x00, 0x00, 0x10, 0x28, 0x20, - 0x20, 0x20, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x28, 0x10, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x38, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x38, 0x28, 0x38, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x10, 0x10, 0x30, 0x10, 0x00, 0x00, - 0x00, 0x30, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x38, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; +// SMALLTEXTFONT.C + +// Font created by Ken Silverman +// Generated by BIN2C.EXE by Jonathon Fowler + +char smalltextfont[2048] = { + // 2048 bytes + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x24, + 0x3C, 0x18, 0x00, 0x00, 0x00, 0x18, 0x24, 0x3C, 0x24, 0x18, 0x00, 0x00, + 0x00, 0x28, 0x3C, 0x3C, 0x38, 0x10, 0x00, 0x00, 0x00, 0x10, 0x38, 0x3C, + 0x38, 0x10, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x3C, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x3C, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x28, 0x38, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x14, 0x14, 0x30, 0x00, 0x00, + 0x00, 0x24, 0x18, 0x3C, 0x18, 0x24, 0x00, 0x00, 0x00, 0x20, 0x30, 0x38, + 0x30, 0x20, 0x00, 0x00, 0x00, 0x08, 0x18, 0x38, 0x18, 0x08, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x10, 0x38, 0x10, 0x00, 0x00, 0x00, 0x28, 0x28, 0x28, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x1C, 0x34, 0x34, 0x14, 0x14, 0x00, 0x00, + 0x00, 0x1C, 0x30, 0x28, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x38, 0x00, 0x00, 0x00, 0x10, 0x38, 0x10, 0x38, 0x38, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, + 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3C, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x28, 0x28, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x3C, 0x28, 0x3C, 0x28, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x10, 0x18, 0x30, 0x00, 0x00, 0x00, 0x28, 0x08, 0x10, + 0x20, 0x28, 0x00, 0x00, 0x00, 0x10, 0x28, 0x10, 0x30, 0x38, 0x00, 0x00, + 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, + 0x20, 0x10, 0x00, 0x00, 0x00, 0x10, 0x08, 0x08, 0x08, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x28, 0x10, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x10, 0x20, 0x00, 0x00, + 0x00, 0x38, 0x28, 0x28, 0x28, 0x38, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x00, 0x00, 0x00, 0x38, 0x08, 0x38, 0x20, 0x38, 0x00, 0x00, + 0x00, 0x38, 0x08, 0x38, 0x08, 0x38, 0x00, 0x00, 0x00, 0x28, 0x28, 0x38, + 0x08, 0x08, 0x00, 0x00, 0x00, 0x38, 0x20, 0x38, 0x08, 0x38, 0x00, 0x00, + 0x00, 0x38, 0x20, 0x38, 0x28, 0x38, 0x00, 0x00, 0x00, 0x38, 0x08, 0x08, + 0x08, 0x08, 0x00, 0x00, 0x00, 0x38, 0x28, 0x38, 0x28, 0x38, 0x00, 0x00, + 0x00, 0x38, 0x28, 0x38, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x20, 0x00, 0x00, + 0x00, 0x08, 0x10, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x10, 0x20, 0x00, 0x00, + 0x00, 0x30, 0x08, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x38, 0x28, 0x38, + 0x30, 0x38, 0x00, 0x00, 0x00, 0x10, 0x28, 0x38, 0x28, 0x28, 0x00, 0x00, + 0x00, 0x30, 0x28, 0x30, 0x28, 0x30, 0x00, 0x00, 0x00, 0x18, 0x20, 0x20, + 0x20, 0x18, 0x00, 0x00, 0x00, 0x30, 0x28, 0x28, 0x28, 0x30, 0x00, 0x00, + 0x00, 0x38, 0x20, 0x30, 0x20, 0x38, 0x00, 0x00, 0x00, 0x38, 0x20, 0x30, + 0x20, 0x20, 0x00, 0x00, 0x00, 0x38, 0x20, 0x28, 0x28, 0x38, 0x00, 0x00, + 0x00, 0x28, 0x28, 0x38, 0x28, 0x28, 0x00, 0x00, 0x00, 0x38, 0x10, 0x10, + 0x10, 0x38, 0x00, 0x00, 0x00, 0x38, 0x08, 0x08, 0x28, 0x18, 0x00, 0x00, + 0x00, 0x28, 0x28, 0x30, 0x28, 0x28, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, + 0x20, 0x38, 0x00, 0x00, 0x00, 0x28, 0x38, 0x38, 0x28, 0x28, 0x00, 0x00, + 0x00, 0x28, 0x38, 0x38, 0x38, 0x28, 0x00, 0x00, 0x00, 0x38, 0x28, 0x28, + 0x28, 0x38, 0x00, 0x00, 0x00, 0x38, 0x28, 0x38, 0x20, 0x20, 0x00, 0x00, + 0x00, 0x38, 0x28, 0x28, 0x38, 0x18, 0x00, 0x00, 0x00, 0x38, 0x28, 0x30, + 0x28, 0x28, 0x00, 0x00, 0x00, 0x38, 0x20, 0x38, 0x08, 0x38, 0x00, 0x00, + 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x28, 0x28, 0x28, + 0x28, 0x38, 0x00, 0x00, 0x00, 0x28, 0x28, 0x28, 0x10, 0x10, 0x00, 0x00, + 0x00, 0x28, 0x28, 0x38, 0x38, 0x28, 0x00, 0x00, 0x00, 0x28, 0x28, 0x10, + 0x28, 0x28, 0x00, 0x00, 0x00, 0x28, 0x28, 0x38, 0x10, 0x10, 0x00, 0x00, + 0x00, 0x38, 0x08, 0x10, 0x20, 0x38, 0x00, 0x00, 0x00, 0x30, 0x20, 0x20, + 0x20, 0x30, 0x00, 0x00, 0x00, 0x20, 0x10, 0x10, 0x08, 0x08, 0x00, 0x00, + 0x00, 0x18, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x10, 0x28, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, + 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x28, 0x18, 0x00, 0x00, 0x00, 0x20, 0x20, 0x38, 0x28, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x20, 0x38, 0x00, 0x00, 0x00, 0x08, 0x08, 0x38, + 0x28, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x18, 0x00, 0x00, + 0x00, 0x08, 0x10, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, + 0x18, 0x08, 0x30, 0x00, 0x00, 0x20, 0x20, 0x38, 0x28, 0x28, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x10, 0x10, 0x20, 0x00, 0x00, 0x20, 0x20, 0x28, 0x30, 0x28, 0x00, 0x00, + 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x20, 0x38, + 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x28, 0x28, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x28, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, + 0x28, 0x38, 0x20, 0x00, 0x00, 0x00, 0x00, 0x38, 0x28, 0x38, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x10, 0x30, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x10, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x28, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x10, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x28, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x18, 0x00, 0x00, + 0x00, 0x18, 0x10, 0x20, 0x10, 0x18, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, + 0x10, 0x10, 0x00, 0x00, 0x00, 0x30, 0x10, 0x08, 0x10, 0x30, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x20, 0x20, 0x18, 0x30, 0x00, + 0x00, 0x28, 0x00, 0x28, 0x28, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, + 0x38, 0x18, 0x00, 0x00, 0x00, 0x38, 0x00, 0x18, 0x28, 0x18, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x18, 0x28, 0x18, 0x00, 0x00, 0x00, 0x30, 0x00, 0x18, + 0x28, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x28, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x20, 0x38, 0x10, 0x00, 0x00, 0x38, 0x00, 0x18, + 0x38, 0x18, 0x00, 0x00, 0x00, 0x28, 0x00, 0x18, 0x38, 0x18, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x18, 0x38, 0x18, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x10, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x28, 0x10, 0x28, + 0x38, 0x28, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x38, 0x28, 0x00, 0x00, + 0x00, 0x18, 0x00, 0x38, 0x30, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, + 0x28, 0x1C, 0x00, 0x00, 0x00, 0x1C, 0x28, 0x3C, 0x28, 0x2C, 0x00, 0x00, + 0x00, 0x38, 0x00, 0x38, 0x28, 0x38, 0x00, 0x00, 0x00, 0x28, 0x00, 0x38, + 0x28, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x38, 0x28, 0x38, 0x00, 0x00, + 0x00, 0x38, 0x00, 0x28, 0x28, 0x18, 0x00, 0x00, 0x00, 0x30, 0x00, 0x28, + 0x28, 0x18, 0x00, 0x00, 0x00, 0x28, 0x00, 0x28, 0x28, 0x18, 0x30, 0x00, + 0x00, 0x28, 0x00, 0x38, 0x28, 0x38, 0x00, 0x00, 0x00, 0x28, 0x00, 0x28, + 0x28, 0x38, 0x00, 0x00, 0x00, 0x10, 0x38, 0x20, 0x38, 0x10, 0x00, 0x00, + 0x00, 0x18, 0x14, 0x30, 0x10, 0x3C, 0x00, 0x00, 0x00, 0x28, 0x10, 0x38, + 0x38, 0x10, 0x00, 0x00, 0x00, 0x30, 0x28, 0x3C, 0x28, 0x2C, 0x00, 0x00, + 0x00, 0x18, 0x10, 0x38, 0x10, 0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, + 0x28, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x10, 0x10, 0x00, 0x00, + 0x00, 0x18, 0x00, 0x38, 0x28, 0x38, 0x00, 0x00, 0x00, 0x18, 0x00, 0x28, + 0x28, 0x18, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x28, 0x28, 0x00, 0x00, + 0x00, 0x38, 0x00, 0x28, 0x38, 0x28, 0x00, 0x00, 0x00, 0x18, 0x28, 0x18, + 0x00, 0x38, 0x00, 0x00, 0x00, 0x38, 0x28, 0x38, 0x00, 0x38, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x10, 0x20, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x28, 0x10, 0x38, 0x18, 0x00, 0x00, 0x00, 0x20, 0x28, 0x18, + 0x38, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x28, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x14, + 0x28, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x08, 0x20, 0x08, 0x20, 0x00, + 0x00, 0x14, 0x28, 0x14, 0x28, 0x14, 0x28, 0x00, 0x00, 0x34, 0x1C, 0x34, + 0x1C, 0x34, 0x1C, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, + 0x00, 0x10, 0x10, 0x30, 0x10, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x30, + 0x30, 0x10, 0x10, 0x00, 0x00, 0x18, 0x18, 0x38, 0x18, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x30, + 0x30, 0x10, 0x10, 0x00, 0x00, 0x18, 0x18, 0x38, 0x38, 0x18, 0x18, 0x00, + 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x38, + 0x38, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x38, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x30, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x10, 0x10, 0x00, + 0x00, 0x10, 0x10, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x10, 0x10, 0x10, 0x00, + 0x00, 0x10, 0x10, 0x1C, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x3C, 0x10, 0x10, 0x10, 0x00, + 0x00, 0x10, 0x10, 0x1C, 0x1C, 0x10, 0x10, 0x00, 0x00, 0x18, 0x18, 0x1C, + 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x1C, 0x1C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x3C, + 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x18, 0x18, 0x00, + 0x00, 0x18, 0x18, 0x1C, 0x1C, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x3C, + 0x3C, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, + 0x00, 0x10, 0x10, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x10, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x1C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1C, 0x1C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x1C, + 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x3C, 0x18, 0x18, 0x18, 0x00, + 0x00, 0x10, 0x10, 0x3C, 0x3C, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x10, 0x10, 0x10, 0x00, + 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, + 0x00, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x00, 0x00, 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x28, 0x34, 0x00, 0x00, + 0x00, 0x30, 0x28, 0x30, 0x28, 0x30, 0x20, 0x00, 0x00, 0x38, 0x28, 0x20, + 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x38, 0x20, 0x10, 0x20, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, + 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28, 0x30, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x28, 0x08, 0x08, 0x00, 0x00, 0x00, 0x38, 0x10, 0x28, + 0x10, 0x38, 0x00, 0x00, 0x00, 0x10, 0x28, 0x38, 0x28, 0x10, 0x00, 0x00, + 0x00, 0x18, 0x24, 0x24, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x18, 0x10, 0x18, + 0x28, 0x38, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x18, 0x3C, 0x18, 0x20, 0x00, 0x00, 0x00, 0x18, 0x20, 0x30, + 0x20, 0x18, 0x00, 0x00, 0x00, 0x10, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00, + 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x00, 0x00, 0x10, 0x38, 0x10, + 0x00, 0x38, 0x00, 0x00, 0x00, 0x10, 0x08, 0x10, 0x00, 0x38, 0x00, 0x00, + 0x00, 0x10, 0x20, 0x10, 0x00, 0x38, 0x00, 0x00, 0x00, 0x10, 0x28, 0x20, + 0x20, 0x20, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x28, 0x10, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x38, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x38, 0x28, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x10, 0x10, 0x30, 0x10, 0x00, 0x00, + 0x00, 0x30, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x38, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; diff --git a/polymer/build/src/textfont.c b/polymer/build/src/textfont.c index f946ac280..ab233647b 100644 --- a/polymer/build/src/textfont.c +++ b/polymer/build/src/textfont.c @@ -1,179 +1,179 @@ -// TEXTFONT.C - -// Extracted from a Matrox Millenium -// Generated by BIN2C.EXE by Jonathon Fowler - -char textfont[2048] = { - // 2048 bytes - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, - 0xBD, 0x99, 0x81, 0x7E, 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E, - 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x10, 0x38, 0x7C, 0xFE, - 0x7C, 0x38, 0x10, 0x00, 0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x7C, 0x38, 0x7C, - 0x10, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, 0x00, 0x00, 0x18, 0x3C, - 0x3C, 0x18, 0x00, 0x00, 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, - 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00, 0xFF, 0xC3, 0x99, 0xBD, - 0xBD, 0x99, 0xC3, 0xFF, 0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78, - 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x3F, 0x33, 0x3F, 0x30, - 0x30, 0x70, 0xF0, 0xE0, 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0, - 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99, 0x80, 0xE0, 0xF8, 0xFE, - 0xF8, 0xE0, 0x80, 0x00, 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00, - 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x00, 0x66, 0x00, 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00, - 0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x7E, 0x7E, 0x7E, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF, - 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, - 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, - 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, - 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00, - 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7E, - 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, 0x6C, 0x6C, 0x6C, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, - 0x30, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x30, 0x00, 0x00, 0xC6, 0xCC, 0x18, - 0x30, 0x66, 0xC6, 0x00, 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00, - 0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x60, - 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, - 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x30, 0x30, 0xFC, - 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, - 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x30, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, - 0x7C, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0x7C, 0x00, 0x30, 0x70, 0x30, 0x30, - 0x30, 0x30, 0xFC, 0x00, 0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00, - 0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00, 0x1C, 0x3C, 0x6C, 0xCC, - 0xFE, 0x0C, 0x1E, 0x00, 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00, - 0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00, 0xFC, 0xCC, 0x0C, 0x18, - 0x30, 0x30, 0x30, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00, - 0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00, 0x00, 0x30, 0x30, 0x00, - 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, - 0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0xFC, 0x00, - 0x00, 0xFC, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00, - 0x78, 0xCC, 0x0C, 0x18, 0x30, 0x00, 0x30, 0x00, 0x7C, 0xC6, 0xDE, 0xDE, - 0xDE, 0xC0, 0x78, 0x00, 0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00, - 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x3C, 0x66, 0xC0, 0xC0, - 0xC0, 0x66, 0x3C, 0x00, 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, - 0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00, 0xFE, 0x62, 0x68, 0x78, - 0x68, 0x60, 0xF0, 0x00, 0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3E, 0x00, - 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00, 0x78, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x78, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, - 0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0xF0, 0x60, 0x60, 0x60, - 0x62, 0x66, 0xFE, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00, - 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00, 0x38, 0x6C, 0xC6, 0xC6, - 0xC6, 0x6C, 0x38, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, - 0x78, 0xCC, 0xCC, 0xCC, 0xDC, 0x78, 0x1C, 0x00, 0xFC, 0x66, 0x66, 0x7C, - 0x6C, 0x66, 0xE6, 0x00, 0x78, 0xCC, 0xE0, 0x70, 0x1C, 0xCC, 0x78, 0x00, - 0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, - 0xCC, 0xCC, 0xFC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, - 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0xEE, 0xC6, 0x00, 0xC6, 0xC6, 0x6C, 0x38, - 0x38, 0x6C, 0xC6, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00, - 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00, 0x78, 0x60, 0x60, 0x60, - 0x60, 0x60, 0x78, 0x00, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00, - 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, 0x10, 0x38, 0x6C, 0xC6, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, - 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, - 0x7C, 0xCC, 0x76, 0x00, 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00, - 0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, 0x1C, 0x0C, 0x0C, 0x7C, - 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, - 0x38, 0x6C, 0x60, 0xF0, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x76, 0xCC, - 0xCC, 0x7C, 0x0C, 0xF8, 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00, - 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0x0C, 0x00, 0x0C, 0x0C, - 0x0C, 0xCC, 0xCC, 0x78, 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00, - 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0xCC, 0xFE, - 0xFE, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, - 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0xDC, 0x66, - 0x66, 0x7C, 0x60, 0xF0, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E, - 0x00, 0x00, 0xDC, 0x76, 0x66, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x7C, 0xC0, - 0x78, 0x0C, 0xF8, 0x00, 0x10, 0x30, 0x7C, 0x30, 0x30, 0x34, 0x18, 0x00, - 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0xCC, 0xCC, - 0xCC, 0x78, 0x30, 0x00, 0x00, 0x00, 0xC6, 0xD6, 0xFE, 0xFE, 0x6C, 0x00, - 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0xCC, 0xCC, - 0xCC, 0x7C, 0x0C, 0xF8, 0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, - 0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00, 0x18, 0x18, 0x18, 0x00, - 0x18, 0x18, 0x18, 0x00, 0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00, - 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, - 0xC6, 0xC6, 0xFE, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x18, 0x0C, 0x78, - 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, 0x1C, 0x00, 0x78, 0xCC, - 0xFC, 0xC0, 0x78, 0x00, 0x7E, 0xC3, 0x3C, 0x06, 0x3E, 0x66, 0x3F, 0x00, - 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, 0xE0, 0x00, 0x78, 0x0C, - 0x7C, 0xCC, 0x7E, 0x00, 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, - 0x00, 0x00, 0x78, 0xC0, 0xC0, 0x78, 0x0C, 0x38, 0x7E, 0xC3, 0x3C, 0x66, - 0x7E, 0x60, 0x3C, 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, - 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, 0xCC, 0x00, 0x70, 0x30, - 0x30, 0x30, 0x78, 0x00, 0x7C, 0xC6, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, - 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0xC6, 0x38, 0x6C, 0xC6, - 0xFE, 0xC6, 0xC6, 0x00, 0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00, - 0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00, 0x00, 0x00, 0x7F, 0x0C, - 0x7F, 0xCC, 0x7F, 0x00, 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00, - 0x78, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0xCC, 0x00, 0x78, - 0xCC, 0xCC, 0x78, 0x00, 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, - 0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, 0x00, 0xE0, 0x00, 0xCC, - 0xCC, 0xCC, 0x7E, 0x00, 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, - 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00, 0xCC, 0x00, 0xCC, 0xCC, - 0xCC, 0xCC, 0x78, 0x00, 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18, - 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00, 0xCC, 0xCC, 0x78, 0xFC, - 0x30, 0xFC, 0x30, 0x30, 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC7, - 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70, 0x1C, 0x00, 0x78, 0x0C, - 0x7C, 0xCC, 0x7E, 0x00, 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, - 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x1C, 0x00, 0xCC, - 0xCC, 0xCC, 0x7E, 0x00, 0x00, 0xF8, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0x00, - 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00, 0x3C, 0x6C, 0x6C, 0x3E, - 0x00, 0x7E, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, - 0x30, 0x00, 0x30, 0x60, 0xC0, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, 0xFC, - 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00, - 0xC3, 0xC6, 0xCC, 0xDE, 0x33, 0x66, 0xCC, 0x0F, 0xC3, 0xC6, 0xCC, 0xDB, - 0x37, 0x6F, 0xCF, 0x03, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, - 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, 0x00, 0xCC, 0x66, 0x33, - 0x66, 0xCC, 0x00, 0x00, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, - 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0xDB, 0x77, 0xDB, 0xEE, - 0xDB, 0x77, 0xDB, 0xEE, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, - 0xF8, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, - 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, 0x00, 0x00, 0xF8, 0x18, - 0xF8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xFE, 0x06, - 0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, - 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, 0x18, 0x18, 0xF8, 0x18, - 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, - 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, - 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, - 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xFF, 0x00, - 0xFF, 0x00, 0x00, 0x00, 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, - 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, - 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x3F, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x3F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, - 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, - 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, - 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00, - 0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0, 0x00, 0xFC, 0xCC, 0xC0, - 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, - 0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00, 0x00, 0x00, 0x7E, 0xD8, - 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0, - 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00, 0xFC, 0x30, 0x78, 0xCC, - 0xCC, 0x78, 0x30, 0xFC, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00, - 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00, 0x1C, 0x30, 0x18, 0x7C, - 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00, - 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0, 0x38, 0x60, 0xC0, 0xF8, - 0xC0, 0x60, 0x38, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, - 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0x00, 0x30, 0x30, 0xFC, 0x30, - 0x30, 0x00, 0xFC, 0x00, 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00, - 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00, 0x0E, 0x1B, 0x1B, 0x18, - 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70, - 0x30, 0x30, 0x00, 0xFC, 0x00, 0x30, 0x30, 0x00, 0x00, 0x76, 0xDC, 0x00, - 0x76, 0xDC, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, - 0x78, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x70, 0x18, 0x30, 0x60, - 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; +// TEXTFONT.C + +// Extracted from a Matrox Millenium +// Generated by BIN2C.EXE by Jonathon Fowler + +char textfont[2048] = { + // 2048 bytes + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x81, 0xA5, 0x81, + 0xBD, 0x99, 0x81, 0x7E, 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E, + 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, 0x10, 0x38, 0x7C, 0xFE, + 0x7C, 0x38, 0x10, 0x00, 0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x7C, 0x38, 0x7C, + 0x10, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, 0x00, 0x00, 0x18, 0x3C, + 0x3C, 0x18, 0x00, 0x00, 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, + 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00, 0xFF, 0xC3, 0x99, 0xBD, + 0xBD, 0x99, 0xC3, 0xFF, 0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78, + 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, 0x3F, 0x33, 0x3F, 0x30, + 0x30, 0x70, 0xF0, 0xE0, 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0, + 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99, 0x80, 0xE0, 0xF8, 0xFE, + 0xF8, 0xE0, 0x80, 0x00, 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00, + 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x00, 0x66, 0x00, 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00, + 0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x7E, 0x7E, 0x7E, 0x00, 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF, + 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, + 0x7E, 0x3C, 0x18, 0x00, 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, + 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, + 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00, + 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x7E, + 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, 0x6C, 0x6C, 0x6C, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, + 0x30, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x30, 0x00, 0x00, 0xC6, 0xCC, 0x18, + 0x30, 0x66, 0xC6, 0x00, 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00, + 0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x60, + 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, + 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x30, 0x30, 0xFC, + 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, + 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x30, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, + 0x7C, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0x7C, 0x00, 0x30, 0x70, 0x30, 0x30, + 0x30, 0x30, 0xFC, 0x00, 0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00, + 0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00, 0x1C, 0x3C, 0x6C, 0xCC, + 0xFE, 0x0C, 0x1E, 0x00, 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00, + 0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00, 0xFC, 0xCC, 0x0C, 0x18, + 0x30, 0x30, 0x30, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00, 0x00, 0x30, 0x30, 0x00, + 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, + 0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0xFC, 0x00, + 0x00, 0xFC, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00, + 0x78, 0xCC, 0x0C, 0x18, 0x30, 0x00, 0x30, 0x00, 0x7C, 0xC6, 0xDE, 0xDE, + 0xDE, 0xC0, 0x78, 0x00, 0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00, + 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, 0x3C, 0x66, 0xC0, 0xC0, + 0xC0, 0x66, 0x3C, 0x00, 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, + 0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00, 0xFE, 0x62, 0x68, 0x78, + 0x68, 0x60, 0xF0, 0x00, 0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3E, 0x00, + 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00, 0x78, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x78, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, + 0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0xF0, 0x60, 0x60, 0x60, + 0x62, 0x66, 0xFE, 0x00, 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00, + 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00, 0x38, 0x6C, 0xC6, 0xC6, + 0xC6, 0x6C, 0x38, 0x00, 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, + 0x78, 0xCC, 0xCC, 0xCC, 0xDC, 0x78, 0x1C, 0x00, 0xFC, 0x66, 0x66, 0x7C, + 0x6C, 0x66, 0xE6, 0x00, 0x78, 0xCC, 0xE0, 0x70, 0x1C, 0xCC, 0x78, 0x00, + 0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, + 0xCC, 0xCC, 0xFC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, + 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0xEE, 0xC6, 0x00, 0xC6, 0xC6, 0x6C, 0x38, + 0x38, 0x6C, 0xC6, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00, + 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00, 0x78, 0x60, 0x60, 0x60, + 0x60, 0x60, 0x78, 0x00, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00, + 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, 0x10, 0x38, 0x6C, 0xC6, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, + 0x7C, 0xCC, 0x76, 0x00, 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00, + 0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, 0x1C, 0x0C, 0x0C, 0x7C, + 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + 0x38, 0x6C, 0x60, 0xF0, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x76, 0xCC, + 0xCC, 0x7C, 0x0C, 0xF8, 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00, + 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0x0C, 0x00, 0x0C, 0x0C, + 0x0C, 0xCC, 0xCC, 0x78, 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00, + 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0xCC, 0xFE, + 0xFE, 0xD6, 0xC6, 0x00, 0x00, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, + 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0xDC, 0x66, + 0x66, 0x7C, 0x60, 0xF0, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E, + 0x00, 0x00, 0xDC, 0x76, 0x66, 0x60, 0xF0, 0x00, 0x00, 0x00, 0x7C, 0xC0, + 0x78, 0x0C, 0xF8, 0x00, 0x10, 0x30, 0x7C, 0x30, 0x30, 0x34, 0x18, 0x00, + 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00, 0xCC, 0xCC, + 0xCC, 0x78, 0x30, 0x00, 0x00, 0x00, 0xC6, 0xD6, 0xFE, 0xFE, 0x6C, 0x00, + 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0xCC, 0xCC, + 0xCC, 0x7C, 0x0C, 0xF8, 0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, + 0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00, 0x18, 0x18, 0x18, 0x00, + 0x18, 0x18, 0x18, 0x00, 0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00, + 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, + 0xC6, 0xC6, 0xFE, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x18, 0x0C, 0x78, + 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, 0x1C, 0x00, 0x78, 0xCC, + 0xFC, 0xC0, 0x78, 0x00, 0x7E, 0xC3, 0x3C, 0x06, 0x3E, 0x66, 0x3F, 0x00, + 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, 0xE0, 0x00, 0x78, 0x0C, + 0x7C, 0xCC, 0x7E, 0x00, 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, + 0x00, 0x00, 0x78, 0xC0, 0xC0, 0x78, 0x0C, 0x38, 0x7E, 0xC3, 0x3C, 0x66, + 0x7E, 0x60, 0x3C, 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, + 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, 0xCC, 0x00, 0x70, 0x30, + 0x30, 0x30, 0x78, 0x00, 0x7C, 0xC6, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, + 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0xC6, 0x38, 0x6C, 0xC6, + 0xFE, 0xC6, 0xC6, 0x00, 0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00, + 0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00, 0x00, 0x00, 0x7F, 0x0C, + 0x7F, 0xCC, 0x7F, 0x00, 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00, + 0x78, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0xCC, 0x00, 0x78, + 0xCC, 0xCC, 0x78, 0x00, 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, + 0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, 0x00, 0xE0, 0x00, 0xCC, + 0xCC, 0xCC, 0x7E, 0x00, 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, + 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00, 0xCC, 0x00, 0xCC, 0xCC, + 0xCC, 0xCC, 0x78, 0x00, 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18, + 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00, 0xCC, 0xCC, 0x78, 0xFC, + 0x30, 0xFC, 0x30, 0x30, 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC7, + 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70, 0x1C, 0x00, 0x78, 0x0C, + 0x7C, 0xCC, 0x7E, 0x00, 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, + 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x1C, 0x00, 0xCC, + 0xCC, 0xCC, 0x7E, 0x00, 0x00, 0xF8, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0x00, + 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00, 0x3C, 0x6C, 0x6C, 0x3E, + 0x00, 0x7E, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, + 0x30, 0x00, 0x30, 0x60, 0xC0, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x00, 0xFC, + 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00, + 0xC3, 0xC6, 0xCC, 0xDE, 0x33, 0x66, 0xCC, 0x0F, 0xC3, 0xC6, 0xCC, 0xDB, + 0x37, 0x6F, 0xCF, 0x03, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, + 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, 0x00, 0xCC, 0x66, 0x33, + 0x66, 0xCC, 0x00, 0x00, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, + 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0xDB, 0x77, 0xDB, 0xEE, + 0xDB, 0x77, 0xDB, 0xEE, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, + 0xF8, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, 0x00, 0x00, 0xF8, 0x18, + 0xF8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xFE, 0x06, + 0xF6, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, 0x18, 0x18, 0xF8, 0x18, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, + 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0xF7, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x3F, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, + 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00, + 0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0, 0x00, 0xFC, 0xCC, 0xC0, + 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, + 0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00, 0x00, 0x00, 0x7E, 0xD8, + 0xD8, 0xD8, 0x70, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0, + 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00, 0xFC, 0x30, 0x78, 0xCC, + 0xCC, 0x78, 0x30, 0xFC, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00, + 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00, 0x1C, 0x30, 0x18, 0x7C, + 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00, + 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0, 0x38, 0x60, 0xC0, 0xF8, + 0xC0, 0x60, 0x38, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, + 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0x00, 0x30, 0x30, 0xFC, 0x30, + 0x30, 0x00, 0xFC, 0x00, 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00, + 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00, 0x0E, 0x1B, 0x1B, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70, + 0x30, 0x30, 0x00, 0xFC, 0x00, 0x30, 0x30, 0x00, 0x00, 0x76, 0xDC, 0x00, + 0x76, 0xDC, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, + 0x78, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x70, 0x18, 0x30, 0x60, + 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; diff --git a/polymer/eduke32/source/duke3d.h b/polymer/eduke32/source/duke3d.h index dec466d37..c48c5de0c 100644 --- a/polymer/eduke32/source/duke3d.h +++ b/polymer/eduke32/source/duke3d.h @@ -89,6 +89,8 @@ extern int shareware; #define TICRATE (120) #define TICSPERFRAME (TICRATE/26) +#define MAXCACHE1DSIZE (16*1048576) + // #define GC (TICSPERFRAME*44) #define NUM_SOUNDS 1500 diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c index 970c73977..ba511a344 100644 --- a/polymer/eduke32/source/game.c +++ b/polymer/eduke32/source/game.c @@ -8141,7 +8141,7 @@ void Startup(void) //initprintf("* Hold Esc to Abort. *\n"); initprintf("Loading art header.\n"); - if (loadpics("tiles000.art",32*1048576) < 0) + if (loadpics("tiles000.art",MAXCACHE1DSIZE) < 0) gameexit("Failed loading art."); initprintf("Loading palette/lookups...\n"); diff --git a/polymer/eduke32/source/jfaud_sounds.cpp b/polymer/eduke32/source/jfaud_sounds.cpp index 89d8627cc..e9e73a5e2 100644 --- a/polymer/eduke32/source/jfaud_sounds.cpp +++ b/polymer/eduke32/source/jfaud_sounds.cpp @@ -197,7 +197,18 @@ void SoundStartup(void) return; } - jfaud->SetCacheSize(1048576,1048576/2); + { + // the engine will take 60% of the system memory size for cache1d if there + // is less than the 16MB asked for in loadpics(), so we'll + // take 30% of what's left for the sound cache if that happened, or + // 50% of the system memory sans the 16MB maximum otherwise + unsigned k; + if (Bgetsysmemsize() <= MAXCACHE1DSIZE) + k = Bgetsysmemsize()/100*30; + else + k = Bgetsysmemsize()/100*50 - MAXCACHE1DSIZE; + jfaud->SetCacheSize(k,k/2); + } chans = new SoundChannel[NumVoices]; if (!chans) { @@ -334,9 +345,6 @@ int xyzsound(short num, short i, long x, long y, long z) return 0; } - swaplong(&y,&z); - y = -y>>4; - if (soundm[num] & SOUNDM_DUKE) { // Duke speech, one at a time only int j; @@ -415,7 +423,7 @@ int xyzsound(short num, short i, long x, long y, long z) } else { chan->SetRolloff(global ? 0.0 : 0.2); chan->SetFollowListener(false); - chan->SetPosition((float)x/UNITSPERMETRE, (float)y/UNITSPERMETRE, (float)z/UNITSPERMETRE); + chan->SetPosition((float)x/UNITSPERMETRE, (float)(-z>>4)/UNITSPERMETRE, (float)y/UNITSPERMETRE); } r = keephandle(chan, num, i);