From c354695d601c450a4ac50d316c9e8f4ca3249051 Mon Sep 17 00:00:00 2001 From: helixhorned Date: Sat, 14 Aug 2010 21:32:28 +0000 Subject: [PATCH] bugfixes; mark tiles in tile selector for later grouping (press SPACE on a tile); a.m32: convert to CRLF and add [xyz]vel query in 3d mode (Alt-KP1), also different keys for Polymer override var tweaking; some CRLF->LF in LF-only files. git-svn-id: https://svn.eduke32.com/eduke32@1695 1a8010ca-5511-0410-912e-c29ae57300e0 --- polymer/eduke32/build/include/build.h | 2 + polymer/eduke32/build/include/editor.h | 3 + polymer/eduke32/build/include/scriptfile.h | 4 +- polymer/eduke32/build/src/build.c | 91 +- polymer/eduke32/build/src/cache1d.c | 88 +- polymer/eduke32/build/src/config.c | 2 +- polymer/eduke32/build/src/engine.c | 113 +- polymer/eduke32/build/src/scriptfile.c | 4 +- polymer/eduke32/samples/a.m32 | 1761 ++++++++++---------- polymer/eduke32/samples/tiles.cfg | 256 ++- polymer/eduke32/source/astub.c | 431 ++++- polymer/eduke32/source/m32exec.c | 4 +- polymer/eduke32/source/mapster32.h | 2 +- 13 files changed, 1591 insertions(+), 1170 deletions(-) diff --git a/polymer/eduke32/build/include/build.h b/polymer/eduke32/build/include/build.h index a0048449e..2f738da86 100644 --- a/polymer/eduke32/build/include/build.h +++ b/polymer/eduke32/build/include/build.h @@ -453,6 +453,8 @@ void setview(int32_t x1, int32_t y1, int32_t x2, int32_t y2); void setaspect(int32_t daxrange, int32_t daaspect); void flushperms(void); +void plotlines2d(int32_t *xx, int32_t *yy, int32_t numpoints, char col); + void plotpixel(int32_t x, int32_t y, char col); char getpixel(int32_t x, int32_t y); void setviewtotile(int16_t tilenume, int32_t xsiz, int32_t ysiz); diff --git a/polymer/eduke32/build/include/editor.h b/polymer/eduke32/build/include/editor.h index c68cf0f01..edaa758b4 100644 --- a/polymer/eduke32/build/include/editor.h +++ b/polymer/eduke32/build/include/editor.h @@ -102,6 +102,9 @@ int32_t _getnumber16(const char *namestart, int32_t num, int32_t maxnumber, char #define getnumber16(namestart, num, maxnumber, sign) _getnumber16(namestart, num, maxnumber, sign, NULL) void printmessage256(int32_t x, int32_t y, const char *name); +// currently only for 3d mode +const char* getstring_simple(const char *querystr, const char *defaultstr, int32_t maxlen); + // like snprintf, but pads the output buffer with 'fill' at the end int32_t snfillprintf(char *outbuf, size_t bufsiz, int32_t fill, const char *fmt, ...); void _printmessage16(const char *fmt, ...); diff --git a/polymer/eduke32/build/include/scriptfile.h b/polymer/eduke32/build/include/scriptfile.h index 6e94d3afe..a19531a9a 100644 --- a/polymer/eduke32/build/include/scriptfile.h +++ b/polymer/eduke32/build/include/scriptfile.h @@ -17,8 +17,8 @@ int32_t scriptfile_getsymbol(scriptfile *sf, int32_t *num); int32_t scriptfile_getlinum(scriptfile *sf, char *ptr); int32_t scriptfile_getbraces(scriptfile *sf, char **braceend); -scriptfile *scriptfile_fromfile(char *fn); -scriptfile *scriptfile_fromstring(char *string); +scriptfile *scriptfile_fromfile(const char *fn); +scriptfile *scriptfile_fromstring(const char *string); void scriptfile_close(scriptfile *sf); int32_t scriptfile_eof(scriptfile *sf); diff --git a/polymer/eduke32/build/src/build.c b/polymer/eduke32/build/src/build.c index 4de2dd746..2fa549e57 100644 --- a/polymer/eduke32/build/src/build.c +++ b/polymer/eduke32/build/src/build.c @@ -417,6 +417,8 @@ int32_t app_main(int32_t argc, const char **argv) } //Bcanonicalisefilename(boardfilename,0); + loadnames(); // should be before ExtInit() because of auto 'Y' tile group + if ((i = ExtInit()) < 0) return -1; #if defined RENDERTYPEWIN || (defined RENDERTYPESDL && !defined __APPLE__ && defined HAVE_GTK2) if (i || forcesetup || cmdsetup) @@ -437,7 +439,6 @@ int32_t app_main(int32_t argc, const char **argv) installusertimercallback(keytimerstuff); loadpics("tiles000.art", 1048576*16); - loadnames(); Bstrcpy(kensig,"Uses BUILD technology by Ken Silverman"); initcrc(); @@ -679,7 +680,8 @@ void showmouse(void) plotpixel(searchx,searchy-i,whitecol); plotpixel(searchx,searchy+i,whitecol); } -}*/ +} +*/ static int32_t mhk=0; void loadmhk() @@ -3864,7 +3866,7 @@ SKIP: if (newnumwalls >= numwalls) { - if (newnumwalls > numwalls) + if (newnumwalls > numwalls+1) newnumwalls--; else newnumwalls = -1; @@ -4445,6 +4447,7 @@ CANCEL: } } } + if (bad == 1) { Bstrcpy(boardfilename, selectedboardfilename); @@ -4452,7 +4455,7 @@ CANCEL: printmessage16("Operation cancelled"); showframe(1); } - if (bad == 2) + else if (bad == 2) { char *f; int32_t res; keystatus[0x1c] = 0; @@ -5319,6 +5322,86 @@ int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, cha return(oldnum); } +// querystr: e.g. "Name: ", must be !=NULL +// defaultstr: can be NULL +// NO overflow checks are done when copying them! +// maxlen: maximum length of entry string, if ==1, enter single char +const char* getstring_simple(const char *querystr, const char *defaultstr, int32_t maxlen) +{ + static char buf[128]; + int32_t ei=0, qrylen=0; + char ch; + + bflushchars(); + clearkeys(); + + if (maxlen==0) + maxlen = 1000; + + Bmemset(buf, 0, sizeof(buf)); + + qrylen = Bstrlen(querystr); + Bmemcpy(buf, querystr, qrylen); + + ei = qrylen; + + if (defaultstr) + { + int32_t deflen = Bstrlen(defaultstr); + Bmemcpy(&buf[ei], defaultstr, deflen); + ei += deflen; + } + + buf[ei] = 0; + + if (maxlen==1) + { + ei = qrylen; + buf[ei+1] = 0; + } + + while (1) + { + printext256(0, 0, whitecol, 0, buf, 0); + showframe(1); + + if (handleevents()) + quitevent = 0; + + idle_waitevent(); + + ch = bgetchar(); + + if (ch==13) + break; + else if (keystatus[1]) + { + clearkeys(); + return defaultstr; + } + + if (maxlen!=1) + { + if (ei>qrylen && (ch==8 || ch==127)) + buf[--ei] = ' '; + else if ((unsigned)ei= 0) - { - *where = tfn; - return 0; - } - - Bstrupr(tfn); - - if (access(tfn, F_OK) >= 0) - { - *where = tfn; - return 0; - } - - Bfree(tfn); - } + else + { + char *tfn = Bstrtolower(Bstrdup(fn)); + + if (access(tfn, F_OK) >= 0) + { + *where = tfn; + return 0; + } + + Bstrupr(tfn); + + if (access(tfn, F_OK) >= 0) + { + *where = tfn; + return 0; + } + + Bfree(tfn); + } } for (pfn = (char*)fn; toupperlookup[*pfn] == '/'; pfn++); @@ -370,30 +370,30 @@ int32_t findfrompath(const char *fn, char **where) *where = pfn; Bfree(ffn); Bfree(tfn); - return 0; - } - - //Check with all lowercase - strcpy(pfn, sp->path); - Bstrtolower(tfn); - strcat(pfn, tfn); - if (access(pfn, F_OK) >= 0) - { - *where = pfn; - Bfree(ffn); - Bfree(tfn); - return 0; - } - - //Check again with uppercase - strcpy(pfn, sp->path); - Bstrupr(tfn); - strcat(pfn, tfn); - if (access(pfn, F_OK) >= 0) - { - *where = pfn; - Bfree(ffn); - Bfree(tfn); + return 0; + } + + //Check with all lowercase + strcpy(pfn, sp->path); + Bstrtolower(tfn); + strcat(pfn, tfn); + if (access(pfn, F_OK) >= 0) + { + *where = pfn; + Bfree(ffn); + Bfree(tfn); + return 0; + } + + //Check again with uppercase + strcpy(pfn, sp->path); + Bstrupr(tfn); + strcat(pfn, tfn); + if (access(pfn, F_OK) >= 0) + { + *where = pfn; + Bfree(ffn); + Bfree(tfn); return 0; } diff --git a/polymer/eduke32/build/src/config.c b/polymer/eduke32/build/src/config.c index 0fe2af8fd..d2f39c091 100644 --- a/polymer/eduke32/build/src/config.c +++ b/polymer/eduke32/build/src/config.c @@ -236,7 +236,7 @@ int32_t loadsetup(const char *fn) if (readconfig(fp, "showheightindicators", val, VL) > 0) showheightindicators = min(max(Batoi(val),0),2); if (readconfig(fp, "showambiencesounds", val, VL) > 0) - showheightindicators = min(max(Batoi(val),0),2); + showambiencesounds = min(max(Batoi(val),0),2); if (readconfig(fp, "graphicsmode", val, VL) > 0) graphicsmode = min(max(Batoi(val),0),2); diff --git a/polymer/eduke32/build/src/engine.c b/polymer/eduke32/build/src/engine.c index 9ca83e3cd..a9ecf8812 100644 --- a/polymer/eduke32/build/src/engine.c +++ b/polymer/eduke32/build/src/engine.c @@ -7667,6 +7667,7 @@ int32_t setgamemode(char davidoption, int32_t daxdim, int32_t daydim, int32_t da //bytesperline is set in this function j = bpp; + if (setvideomode(daxdim,daydim,dabpp,davidoption) < 0) return(-1); #if defined(POLYMOST) && defined(USE_OPENGL) @@ -9982,6 +9983,18 @@ void setbrightness(char dabrightness, uint8_t *dapal, char noapply) palfadedelta = 0; } +static inline palette_t getpal(int32_t col) +{ + if (gammabrightness) return curpalette[col]; + else + { + palette_t p; + p.b = britable[curbrightness][ curpalette[col].b ]; + p.g = britable[curbrightness][ curpalette[col].g ]; + p.r = britable[curbrightness][ curpalette[col].r ]; + return p; + } +} // // setpalettefade @@ -9998,13 +10011,7 @@ void setpalettefade(char r, char g, char b, char offset) for (i=0; i<256; i++) { - if (gammabrightness) p = curpalette[i]; - else - { - p.b = britable[curbrightness][ curpalette[i].b ]; - p.g = britable[curbrightness][ curpalette[i].g ]; - p.r = britable[curbrightness][ curpalette[i].r ]; - } + p = getpal(i); curpalettefaded[i].b = p.b + (((palfadergb.b - p.b) * offset) >> 6); @@ -10032,14 +10039,8 @@ void clearview(int32_t dacol) #if defined(POLYMOST) && defined(USE_OPENGL) if (rendmode >= 3) { - palette_t p; - if (gammabrightness) p = curpalette[dacol]; - else - { - p.r = britable[curbrightness][ curpalette[dacol].r ]; - p.g = britable[curbrightness][ curpalette[dacol].g ]; - p.b = britable[curbrightness][ curpalette[dacol].b ]; - } + palette_t p = getpal(dacol); + bglClearColor(((float)p.r)/255.0, ((float)p.g)/255.0, ((float)p.b)/255.0, @@ -10076,14 +10077,8 @@ void clearallviews(int32_t dacol) #if defined(POLYMOST) && defined(USE_OPENGL) if (rendmode >= 3) { - palette_t p; - if (gammabrightness) p = curpalette[dacol]; - else - { - p.r = britable[curbrightness][ curpalette[dacol].r ]; - p.g = britable[curbrightness][ curpalette[dacol].g ]; - p.b = britable[curbrightness][ curpalette[dacol].b ]; - } + palette_t p = getpal(dacol); + bglViewport(0,0,xdim,ydim); glox1 = -1; bglClearColor(((float)p.r)/255.0, ((float)p.g)/255.0, @@ -10112,14 +10107,7 @@ void plotpixel(int32_t x, int32_t y, char col) #if defined(POLYMOST) && defined(USE_OPENGL) if (rendmode >= 3 && qsetmode == 200) { - palette_t p; - if (gammabrightness) p = curpalette[col]; - else - { - p.r = britable[curbrightness][ curpalette[col].r ]; - p.g = britable[curbrightness][ curpalette[col].g ]; - p.b = britable[curbrightness][ curpalette[col].b ]; - } + palette_t p = getpal(col); setpolymost2dview(); // JBF 20040205: more efficient setup @@ -10130,7 +10118,6 @@ void plotpixel(int32_t x, int32_t y, char col) bglRasterPos4i(x, y, 0, 1); bglDrawPixels(1, 1, GL_RGB, GL_UNSIGNED_BYTE, &p); bglRasterPos4i(0, 0, 0, 1); - return; } #endif @@ -10140,6 +10127,35 @@ void plotpixel(int32_t x, int32_t y, char col) enddrawing(); //}}} } +void plotlines2d(int32_t *xx, int32_t *yy, int32_t numpoints, char col) +{ + int32_t i; + + if (rendmode >= 3) + { + palette_t p = getpal(col); + + bglBegin(GL_LINE_STRIP); + + bglColor4ub(p.r, p.g, p.b, 1); + + for (i=0; ieof = &sf->textbuf[nflen-1]; } -scriptfile *scriptfile_fromfile(char *fn) +scriptfile *scriptfile_fromfile(const char *fn) { int32_t fp; scriptfile *sf; @@ -298,7 +298,7 @@ scriptfile *scriptfile_fromfile(char *fn) return sf; } -scriptfile *scriptfile_fromstring(char *string) +scriptfile *scriptfile_fromstring(const char *string) { scriptfile *sf; char *tx; diff --git a/polymer/eduke32/samples/a.m32 b/polymer/eduke32/samples/a.m32 index 5ca673549..8d082299d 100644 --- a/polymer/eduke32/samples/a.m32 +++ b/polymer/eduke32/samples/a.m32 @@ -1,866 +1,895 @@ -// m32 script test & show-off file -// do "include a" in the console - -include names.h - -// flag 1: per-block (top-level, event, or state) variable -gamevar i 0 1 -gamevar j 0 1 -gamevar k 0 1 -gamevar l 0 1 -gamevar m 0 1 -gamevar p 0 1 -gamevar q 0 1 -gamevar r 0 1 - -gamevar x 0 0 -gamevar y 0 0 -gamevar z 0 0 - -gamevar gi 0 0 -gamevar gj 0 0 -gamevar gk 0 0 - -gamevar dx 0 0 -gamevar dy 0 0 -gamevar dz 0 0 -gamevar dang 0 0 - -gamevar tmp 0 0 -gamevar cnt 0 0 - -gamevar thecount 0 0 - -gamevar davr 65536 0 -gamevar dayx 65536 0 - -gamevar drawcol 9 0 - - -define TQUOTE 0 -definequote TQUOTE >>> write on me! <<< - -//light -define LIGHTQUOTE 1 -// x y z r g b mins maxs -definequote LIGHTQUOTE light %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d -// sec range radius fade ang horiz prio tile - - -// Corruption checker -definequote 19 PANIC!!! SECTOR OR WALL LIMIT EXCEEDED!!! -definequote 20 SECTOR[%d].WALLPTR=%d out of range: numwalls=%d!!! -definequote 21 SECTOR[%d].WALLPTR=%d inconsistent, expected %d!!! -definequote 22 SECTOR[%d]: wallptr+wallnum=%d out of range: numwalls=%d!!! -definequote 23 WALL[%d].POINT2=%d out of range: sector[%d].wallptr=%d, endwall=%d!!! -definequote 24 WALL[%d].NEXTWALL=%d out of range: numwalls=%d!!! -definequote 25 WALL[%d].NEXTSECTOR=%d out of range: numsectors=%d!!! - -definequote 27 OVERRIDE POLYMER PARALLAX & SPECULAR: OFF -definequote 28 OVERRIDE POLYMER PARALLAX & SPECULAR: ON - -define PRSCALE 1000 -define MAXSPECULAR 100000 - -gamearray ar 128 -gamearray parm 8 - -// prints out maphack light definitions based on SE lights in map -defstate printlights - print "--PRLIGHTS--" - for i allsprites, ifactor SECTOREFFECTOR, ifge .lotag 49, ifle .lotag 50 - { - ife .lotag 50 - { - set j 128, sub j .shade, shiftl j 1 - set k j, mul k 3, div k 4 - } - else - { - set j 0, set k 0 - } - - set l 0 - ifand .cstat 2 - { - ifand .cstat 512 - set l 4 - else - set l 2 - } - // range r g b - qsprintf TQUOTE LIGHTQUOTE .sectnum .x .y .z .hitag .xvel .yvel .zvel - j k .ang .extra .xoffset .yoffset l .owner - // radius fade horiz minshade maxshade prio tile - print TQUOTE - } - print "--ENDPRLIGHTS--" -ends - -// convenient polymer SE light manipulation with keypad keys -// when aiming at light SE (49 or 50): -// KP 4,5,6,8: angle/horiz -// KP 7,9: range -// KP+/-: radius -// KP 1,2,3: RGB color (Shift inverts) -// -// when aiming at wall or sector: -// KP/ enable/disable overrides -// when overrides are on: -// KP 4,7: parallaxscale -// KP 8,9: parallaxbias -// KP 1,2: specularfactor -// KP 3,6: specularpower -// -// Also try Shift and/or Ctrl modifiers for different increments -defstate fiddlewithlights - ife searchstat 3 nullop else - { - ifhitkey KEY_gSLASH - { - ife pr_overrideparallax 0 - { - set pr_overrideparallax 1 - set pr_overridespecular 1 - quote 28 - } - else - { - set pr_overrideparallax 0 - set pr_overridespecular 0 - quote 27 - } - } - } - - // if aiming at sector or wall - ife searchstat 3 nullop - else ifn pr_overrideparallax 0 - { - // polymer override parallaxscale - set j 0 set k 0 - - ifhitkey KEY_KP4 set j -1 - ifhitkey KEY_KP7 set j 1 - ifn j 0 set k 1 - - ifhitkey KEY_KP8 set j -1 - ifhitkey KEY_KP9 set j 1 - ife k 0 ifn j 0 set k 2 - - ifhitkey KEY_KP1 set j -1 - ifhitkey KEY_KP2 set j 1 - ife k 0 ifn j 0 set k 3 - - ifhitkey KEY_KP3 set j -1 - ifhitkey KEY_KP6 set j 1 - ife k 0 ifn j 0 set k 4 - - ifeithershift mul j 2 else mul j 10 - ifeitherctrl mul j 10 - - switch k - case 0: break; - case 1: - { - set k pr_parallaxscale - ftoi k PRSCALE // must convert to scaled integer, scale is 1:PRSCALE - add k j, clamp k -10000 10000 - itof k PRSCALE // convert back - qsprintf TQUOTE "PARALLAX SCALE: %f" k, quote TQUOTE - set pr_parallaxscale k - break; - } - case 2: - { - set k pr_parallaxbias - ftoi k PRSCALE, add k j, clamp k -10000 10000, itof k PRSCALE - qsprintf TQUOTE "PARALLAX BIAS: %f" k, quote TQUOTE - set pr_parallaxbias k - break; - } - case 3: - { - set k pr_specularfactor - ftoi k PRSCALE, add k j, clamp k 0 MAXSPECULAR, itof k PRSCALE - qsprintf TQUOTE "SPECULAR FACTOR: %f" k, quote TQUOTE - set pr_specularfactor k - break; - } - case 4: - { - set k pr_specularpower - ftoi k PRSCALE, add k j, clamp k 0 MAXSPECULAR, itof k PRSCALE - qsprintf TQUOTE "SPECULAR POWER: %f" k, quote TQUOTE - set pr_specularpower k - break; - } - endswitch - } - - // if aiming at an SE with lotag 49 or 50 - ife searchstat 3 ife sprite[searchwall].picnum SECTOREFFECTOR - ifge sprite[searchwall].lotag 49 ifle sprite[searchwall].lotag 50 - { - set i searchwall, seti i // set current sprite = targeted sprite - - ife .lotag 50 - { - // horiz - ifeithershift set j 1 else set j 10 - ifhitkey KEY_gUP add .extra j - else ifhitkey KEY_gKP5 sub .extra j - clamp .extra -500 500 - - // angle - set j 128 - ifeitherctrl set j 4 - ifeithershift { ifeitherctrl set j 1 else set j 32 } - ifhitkey KEY_gLEFT sub .ang j - else ifhitkey KEY_gRIGHT add .ang j - - // radius - ifeitherctrl - { - ifholdkey KEY_gMINUS add .shade 9 - else ifholdkey KEY_gPLUS sub .shade 9 - - clamp .shade -118 117 - } - } - - // range - ifeithershift set j 10 - else ifeitherctrl set j 1000 - else set j 100 - ifhitkey KEY_KP9 add .hitag j - else ifhitkey KEY_KP7 sub .hitag j - clamp .hitag 0 16000 - - // min/max shade - ifeithershift set j -1 else set j 1 - ifeitherctrl - { - ifhitkey KEY_gSLASH - { - set .xoffset 0 - set .yoffset 0 - } - } - else - { - set k 0 - ifhitkey KEY_gSLASH { add .xoffset j, set k 1 } - else ifhitkey KEY_gSTAR { add .yoffset j, set k 1 } - - ife k 1 - { - qsprintf TQUOTE "XY offset: %d %d" .xoffset .yoffset - quote TQUOTE - } - } - - // color/picnum - ifeitheralt - { - ifhitkey KEY_KP1 - { - getnumber256 .xvel "RED:" 255 - getnumber256 .yvel "GREEN:" 255 - getnumber256 .zvel "BLUE:" 255 - } - else ifhitkey KEY_KP2 - { - getnumber256 .owner "PICNUM:" -MAXTILES - } - } - else - { - ifeitherctrl set j 1 else set j 10 - ifeithershift inv j - - set k 0 - ifhitkey KEY_KP1 { add .xvel j, set k 1 } - ifhitkey KEY_KP2 { add .yvel j, set k 1 } - ifhitkey KEY_KP3 { add .zvel j, set k 1 } - - ife k 1 - { - clamp .xvel 1 255 - clamp .yvel 1 255 - clamp .zvel 1 255 - - qsprintf TQUOTE "RGB color: %d %d %d" .xvel .yvel .zvel - quote TQUOTE - } - } - } -ends - -// rotate highlighted sprites around selected (closest to mouse) sprite -// global parameter: dang -defstate rotselspr - ifg highlightcnt 0 - ifge pointhighlight 16384, ifl pointhighlight 32768 - { - ife dang 0 return - - set p pointhighlight, and p 16383 - - add sprite[p].ang dang - - for i selsprites, ifn i p - { - rotatepoint sprite[p].x sprite[p].y .x .y dang (x y) - add .ang dang - bsetsprite I x y .z - } - } -ends - -onevent EVENT_PREKEYS2D -// state testkeyavail - - set j 0 - ifeitherctrl - { - ifhitkey KEY_COMMA set j -1 - ifhitkey KEY_PERIOD set j 1 - } - - ifn j 0 - { - mul j 512 - set dang j - state rotselspr - } -endevent - -onevent EVENT_PREKEYS3D -// state testkeyavail - state fiddlewithlights -endevent - -defstate setas - set j dayx - mul j ydim mul j 8 - div j xdim div j 5 - setaspect davr j -ends - -onevent EVENT_ENTER3DMODE - state setas -endevent - -defstate cmp_by_lotag // comparator subroutine for sorting - set RETURN sprite[SV2].lotag - sub RETURN sprite[SV1].lotag -ends - -onevent EVENT_DRAW2DSCREEN - ifl cursectnum 0 return - - // connect LOCATORS in a sector by lines - getarraysize ar tmp - set j 0 - for i spritesofsector cursectnum - { - ifge j tmp nullop else - ifactor LOCATORS - { - set ar[j] i - add j 1 - } - } - - set tmp j - sort ar tmp cmp_by_lotag - - sub tmp 1 - for i range tmp - { - set j ar[i] - set k i, add k 1, set k ar[k] - drawline16b sprite[j].x sprite[j].y sprite[k].x sprite[k].y drawcol - } -/* - set drawlinepat -1 - for i allsprites - ifactor LIZTROOP - drawcircle16b sprite[i].x sprite[i].y 256 drawcol -*/ - -////////// polymer light 2d projections ////////// - var c d h x2 y2 oldpat - - array xx 2 - array yy 2 - - set oldpat drawlinepat - set drawlinepat 0x11111111 - for i spritesofsector cursectnum - { - ifactor SECTOREFFECTOR - { - ife .lotag 49 // point light - { - set d .hitag // light distance - mul d d, mul d 2, sqrt d d, div d 2 - - getclosestcol .xvel .yvel .zvel c // light color - inv c - - set x .x, set x2 .x, set y .y, set y2 .y - add x d, add y d, sub x2 d, sub y2 d - drawline16b x y x2 y2 c - - set x .x, set x2 .x, set y .y, set y2 .y - add x d, sub y d, sub x2 d, add y2 d - drawline16b x y x2 y2 c - - drawcircle16b .x .y .hitag c - } - else ife .lotag 50 // spot light - { - set d .hitag // light distance - and d 65535 - set r 128, sub r .shade, shiftl r 1 // light cone radius (BUILD angles) - getclosestcol .xvel .yvel .zvel c // light color - inv c - - set x .x, set y .y, add x d - rotatepoint .x .y x y .ang x y - - set h .extra // horiz - sub h 100 - set tmp h, mul tmp tmp, add tmp 40000 - sqrt tmp tmp - divscale h 200 tmp 15 // h: horizontal distance fraction - - set dx .x, sub dx x - set dy .y, sub dy y - set tmp 32768, sub tmp h - mulscale dx dx tmp 15 - mulscale dy dy tmp 15 - - set tmp 0, sub tmp r - rotatepoint .x .y x y tmp xx[0] yy[0] - set tmp 0, add tmp r - rotatepoint .x .y x y tmp xx[1] yy[1] - - add xx[0] dx, add yy[0] dy - add xx[1] dx, add yy[1] dy - - drawline16b .x .y xx[0] yy[0] c - drawline16b .x .y xx[1] yy[1] c - } - } - } - set drawlinepat oldpat -endevent - -// LOCATORS auto-incrementer -onevent EVENT_INSERTSPRITE2D - set k I - set j -1 - for i spritesofsector .sectnum - { - ifn i k, ifactor LOCATORS, ifg .lotag j - set j .lotag - } - ifg j -1 - { - add j 1 - set .lotag j - } -endevent - - -//////////////////// SPRITE DUPLICATORS //////////////////// - -defstate transcnt - ifle cnt 0 { inv cnt, add cnt 128 } -ends - -define DUP_ROT_MAGIC 123 - -// duplicates and rotates selected sprites around -// pivot sprite with fields -// .extra=123 (magic) -// .ang: angle delta -// .yrepeat*32: z delta (positive if pal!=0, i.e. going down) -// .shade: count (-128 to 0 -> 255 to 128) -defstate duprot - ifn searchstat 3 return - ifn sprite[searchwall].extra DUP_ROT_MAGIC return - - set p searchwall // pivot sprite - set cnt sprite[p].shade, state transcnt - - set sprite[p].extra -1 - - for i range cnt - { - for j selsprites, ifn j p - { - dupsprite j // duplicate sprite j, I becomes index of newly created sprite - - set dang i, add dang 1, mul dang sprite[p].ang - rotatepoint sprite[p].x sprite[p].y .x .y dang (x y) - add .ang dang - - set z i, add z 1, mul z sprite[p].yrepeat, shiftl z 5 - ife sprite[p].pal 0, inv z - add z .z - - bsetsprite I x y z - } - } -ends - -// same as above but with tsprite[], as a kind of preview -defstate tduprot - ifn searchstat 3 return - ifn sprite[searchwall].extra DUP_ROT_MAGIC return - - set p searchwall // pivot sprite - set cnt sprite[p].shade, state transcnt - - for i range cnt - { - for j selsprites, ifn j p - { - set k spritesortcnt - tdupsprite j - - set dang i, add dang 1, mul dang sprite[p].ang - rotatepoint sprite[p].x sprite[p].y tsprite[k].x tsprite[k].y dang (x y) - add tsprite[k].ang dang - - set z i, add z 1, mul z sprite[p].yrepeat, shiftl z 5 - ife sprite[p].pal 0 inv z - add z tsprite[k].z - - set tsprite[k].x x - set tsprite[k].y y - set tsprite[k].z z - - or tsprite[k].cstat 514 - } - } -ends - -define DUP_LIN_MAGIC 234 -define DUP_LIN_MAGIC2 345 - -// duplicates and translates selected sprites in the direction between two -// reference sprites with fields -// .extra=234 (1st sprite), =345 (2nd, aimed at sprite) -// .shade: count (-128 to 0 -> 255 to 128) -defstate duplin - ifn searchstat 3 return - ifn sprite[searchwall].extra DUP_LIN_MAGIC2 return - - set r searchwall // 2nd reference point - - set cnt sprite[r].shade, state transcnt - - set p -1 // 1st reference point - for i selsprites, ifn i r - { - ife .extra DUP_LIN_MAGIC { set p i, break } - } - ifl p 0 return - - set sprite[p].extra -1 - set sprite[r].extra -1 - - set dx sprite[r].x, sub dx sprite[p].x - set dy sprite[r].y, sub dy sprite[p].y - set dz sprite[r].z, sub dz sprite[p].z - - for i range cnt - { - for j selsprites, ifn j r - { - dupsprite j - - set x i, add x 1, mul x dx, add x .x - set y i, add y 1, mul y dy, add y .y - set z i, add z 1, mul z dz, add z .z - bsetsprite I x y z - } - } -ends - -defstate tduplin - ifn searchstat 3 return - ifn sprite[searchwall].extra DUP_LIN_MAGIC2 return - - set r searchwall // 2nd reference point - - set cnt sprite[r].shade, state transcnt - - set p -1 // 1st reference point - for i selsprites, ifn i r - { - ife .extra DUP_LIN_MAGIC { set p i, break } - } - ifl p 0 return - - set dx sprite[r].x, sub dx sprite[p].x - set dy sprite[r].y, sub dy sprite[p].y - set dz sprite[r].z, sub dz sprite[p].z - - for i range cnt - { - for j selsprites, ifn j r - { - set k spritesortcnt - tdupsprite j - - set tmp i, add tmp 1, mul tmp dx - add tsprite[k].x tmp - set tmp i, add tmp 1, mul tmp dy - add tsprite[k].y tmp - set tmp i, add tmp 1, mul tmp dz - add tsprite[k].z tmp - - or tsprite[k].cstat 514 -// bsetsprite I x y z - } - } -ends - -onevent EVENT_ANALYZESPRITES - state tduprot - state tduplin -endevent - -onevent EVENT_KEYS3D - // door sound tester - ife searchstat 0 - ifholdkey KEY_SPACE - { - set k wall[searchwall].nextsector - ifl k 0 set k searchsector - - ife sector[k].lotag 0 return - - for i spritesofsector k - { - ifactor MUSICANDSFX - ifge .lotag 0 ifl .lotag MAXSOUNDS - { - getsoundflags .lotag m - ifand m 1 nullop else soundonce .lotag - } - } - } - - // swinging doors tester -- hit space on a door wall - ife searchstat 0 - ifhitkey KEY_SPACE // SE11 ST23 up:ccw - { - set k wall[searchwall].nextsector - ifl k 0 return - ifn sector[k].lotag 23 return - set tmp 0 - for i loopofwall searchwall - { - ifl wall[i].nextsector 0 set tmp 1 else - ifn wall[i].nextsector k set tmp 1 - } -// a weaker condition -// for i loopofwall wall[searchwall].nextwall -// { -// ifl wall[i].nextsector 0 set tmp 1 else -// ifn wall[i].nextsector searchsector set tmp 1 -// } - ifn tmp 0 - { - quote "door sector not an island sector!" - return - } - - set l -1 - for i spritesofsector k - { - ifactor SECTOREFFECTOR ife sprite[i].lotag 11 - { - set l i - ifn sprite[i].ang 512 ifn sprite[i].ang 1024 ifn sprite[i].ang 1536 set l -1 - } - } - ifl l 0 - { - quote "door sector has no SE sprite!" - return - } - - for tmp wallsofsector k - { - rotatepoint (sprite[l].x sprite[l].y) (wall[tmp].x wall[tmp].y) sprite[l].ang (i j) - dragpoint tmp i j - } - for tmp spritesofsector k - { - ifn tmp l - { - rotatepoint (sprite[l].x sprite[l].y) (sprite[tmp].x sprite[tmp].y) sprite[l].ang (i j) - bsetsprite tmp i j sprite[tmp].z - } - } - inv sprite[l].ang - } - - // teleporter -- works on SE7 and SE17 (elevator) - ife searchstat 3 - ifhitkey KEY_SPACE - { - ife sprite[searchwall].picnum SECTOREFFECTOR - { - set tmp 0 - ife sprite[searchwall].lotag 7 set tmp 1 - ife sprite[searchwall].lotag 17 set tmp 1 - ife tmp 0 return - - for i allsprites - { - ifn i searchwall, ifactor SECTOREFFECTOR, ife sprite[i].lotag sprite[searchwall].lotag - ife sprite[i].hitag sprite[searchwall].hitag - { - add posx sprite[i].x, sub posx sprite[searchwall].x - add posy sprite[i].y, sub posy sprite[searchwall].y - add posz sprite[i].z, sub posz sprite[searchwall].z - - updatecursectnum - - return - } - } - } - else ife sprite[searchwall].extra DUP_ROT_MAGIC - { - state duprot - } - else ife sprite[searchwall].extra DUP_LIN_MAGIC2 - { - state duplin - } - } - - ifholdkey KEY_0 - // ife 0 1 - { - ifeithershift sub davr 512 else add davr 512 - ifl davr 32768 set davr 32768 - ifg davr 256000 set davr 256000 - setaspect davr yxaspect - qsprintf TQUOTE "ASPECT: VR=%d, YX=%d" davr yxaspect - quote TQUOTE - } -endevent - -defstate replacestuff - for i spritesofsector searchsector -// ife sprite[i].picnum AMMO set sprite[i].picnum BATTERYAMMO - ifactor parm[0] cactor parm[1] -ends - -defstate convlights // convert (0,0,0) lights to (255,255,255)-ones - for i allsprites ifactor 1 ifge .lotag 49 ifle .lotag 50 ife .xvel 0 ife .yvel 0 ife .zvel 0 - { set .xvel 255 set .yvel 255 set .zvel 255 } -ends - -defstate resetallws // reset all sprites and walls to default repeat/panning - for i allsprites - { - set .xrepeat 64 - set .yrepeat 64 - } - for i allwalls - { - set wall[i].cstat 0 - set wall[i].xpanning 0 - set wall[i].ypanning 0 - set wall[i].yrepeat 8 - fixrepeats i - } -ends - -defstate js // jump to current sprite - set posx .x - set posy .y - set posz .z - updatecursectnum -ends - -defstate jumptosec // (tmp) - ifge tmp 0 ifl tmp numsectors nullop else return - set j sector[tmp].wallptr - set posx wall[j].x - set posy wall[j].y - updatecursectnum -ends - -// Map corruption checker - -defstate corruptchk - var ewall - var endwall - - ifle numsectors MAXSECTORS ifle numwalls MAXWALLS nullop else - { quote 19 printmessage16 19 return } - - set ewall 0 // expected wall index - for i allsectors - { - set k 1 - ifge sector[i].wallptr 0 ifl sector[i].wallptr numwalls nullop else - { - qsprintf TQUOTE 20 i sector[i].wallptr numwalls - quote TQUOTE printmessage16 TQUOTE - set k 0 - } - ifn ewall sector[i].wallptr - { - qsprintf TQUOTE 21 i sector[i].wallptr ewall - quote TQUOTE printmessage16 TQUOTE - set ewall sector[i].wallptr - } - add ewall sector[i].wallnum - - set endwall sector[i].wallptr add endwall sector[i].wallnum - ifg endwall numwalls - { - qsprintf TQUOTE 22 i endwall numwalls - quote TQUOTE printmessage16 TQUOTE - set k 0 - } - - ifn k 0 - { - for j wallsofsector i - { - ifge wall[j].point2 sector[i].wallptr ifl wall[i].point2 endwall nullop else - { - qsprintf TQUOTE 23 j wall[j].point2 i sector[i].wallptr endwall - quote TQUOTE printmessage16 TQUOTE - } - - ifge wall[i].nextwall numwalls - { - qsprintf TQUOTE 24 j wall[j].nextwall numwalls - quote TQUOTE printmessage16 TQUOTE - } - - ifge wall[i].nextsector numsectors - { - qsprintf TQUOTE 25 j wall[j].nextsector numsectors - quote TQUOTE printmessage16 TQUOTE - } - } - } - } -ends +// m32 script test & show-off file +// do "include a" in the console + +include names.h + +// flag 1: per-block (top-level, event, or state) variable +gamevar i 0 1 +gamevar j 0 1 +gamevar k 0 1 +gamevar l 0 1 +gamevar m 0 1 +gamevar p 0 1 +gamevar q 0 1 +gamevar r 0 1 + +gamevar x 0 0 +gamevar y 0 0 +gamevar z 0 0 + +gamevar gi 0 0 +gamevar gj 0 0 +gamevar gk 0 0 + +gamevar dx 0 0 +gamevar dy 0 0 +gamevar dz 0 0 +gamevar dang 0 0 + +gamevar tmp 0 0 +gamevar cnt 0 0 + +gamevar thecount 0 0 + +gamevar davr 65536 0 +gamevar dayx 65536 0 + +gamevar drawcol 9 0 + + +define TQUOTE 0 +definequote TQUOTE >>> write on me! <<< + +//light +define LIGHTQUOTE 1 +// x y z r g b mins maxs +definequote LIGHTQUOTE light %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d +// sec range radius fade ang horiz prio tile + + +// Corruption checker +definequote 19 PANIC!!! SECTOR OR WALL LIMIT EXCEEDED!!! +definequote 20 SECTOR[%d].WALLPTR=%d out of range: numwalls=%d!!! +definequote 21 SECTOR[%d].WALLPTR=%d inconsistent, expected %d!!! +definequote 22 SECTOR[%d]: wallptr+wallnum=%d out of range: numwalls=%d!!! +definequote 23 WALL[%d].POINT2=%d out of range: sector[%d].wallptr=%d, endwall=%d!!! +definequote 24 WALL[%d].NEXTWALL=%d out of range: numwalls=%d!!! +definequote 25 WALL[%d].NEXTSECTOR=%d out of range: numsectors=%d!!! + +definequote 27 OVERRIDE POLYMER PARALLAX & SPECULAR: OFF +definequote 28 OVERRIDE POLYMER PARALLAX & SPECULAR: ON + +define PRSCALE 1000 +define MAXSPECULAR 100000 + +gamearray ar 128 +gamearray parm 8 + +// prints out maphack light definitions based on SE lights in map +defstate printlights + print "--PRLIGHTS--" + for i allsprites, ifactor SECTOREFFECTOR, ifge .lotag 49, ifle .lotag 50 + { + ife .lotag 50 + { + set j 128, sub j .shade, shiftl j 1 + set k j, mul k 3, div k 4 + } + else + { + set j 0, set k 0 + } + + set l 0 + ifand .cstat 2 + { + ifand .cstat 512 + set l 4 + else + set l 2 + } + // range r g b + qsprintf TQUOTE LIGHTQUOTE .sectnum .x .y .z .hitag .xvel .yvel .zvel + j k .ang .extra .xoffset .yoffset l .owner + // radius fade horiz minshade maxshade prio tile + print TQUOTE + } + print "--ENDPRLIGHTS--" +ends + +// convenient polymer SE light manipulation with keypad keys +// when aiming at light SE (49 or 50): +// KP 4,5,6,8: angle/horiz +// KP 7,9: range +// KP+/-: radius +// KP 1,2,3: RGB color (Shift inverts) +// +// when aiming at wall or sector: +// KP/ enable/disable overrides +// when overrides are on: +// KP 4,7: parallaxscale +// KP 8,9: parallaxbias +// KP 1,2: specularfactor +// KP 3,6: specularpower +// +// Also try Shift and/or Ctrl modifiers for different increments +defstate fiddlewithlights + ife searchstat 3 nullop else + { + ifeitherctrl ifhitkey KEY_gSLASH + { + ife pr_overrideparallax 0 + { + set pr_overrideparallax 1 + set pr_overridespecular 1 + quote 28 + } + else + { + set pr_overrideparallax 0 + set pr_overridespecular 0 + quote 27 + } + } + } + + // if aiming at sector or wall + ife searchstat 3 nullop + else ifn pr_overrideparallax 0 + { + // polymer override parallaxscale + set j 0 set k 0 + + ifhitkey KEY_KP5 set j -1 //pscale + ifhitkey KEY_KP8 set j 1 + ifn j 0 set k 1 + + ifhitkey KEY_KP4 set j -1 //pbias + ifhitkey KEY_KP6 set j 1 + ife k 0 ifn j 0 set k 2 + + ifhitkey KEY_gSLASH set j -1 //sfac + ifhitkey KEY_gSTAR set j 1 + ife k 0 ifn j 0 set k 3 + + ifhitkey KEY_KP7 set j -1 //spow + ifhitkey KEY_KP9 set j 1 + ife k 0 ifn j 0 set k 4 + + ifeithershift mul j 2 else mul j 10 + ifeitherctrl mul j 10 + + switch k + case 0: break; + case 1: + { + set k pr_parallaxscale + ftoi k PRSCALE // must convert to scaled integer, scale is 1:PRSCALE + add k j, clamp k -10000 10000 + itof k PRSCALE // convert back + qsprintf TQUOTE "PARALLAX SCALE: %f" k, quote TQUOTE + set pr_parallaxscale k + break; + } + case 2: + { + set k pr_parallaxbias + ftoi k PRSCALE, add k j, clamp k -10000 10000, itof k PRSCALE + qsprintf TQUOTE "PARALLAX BIAS: %f" k, quote TQUOTE + set pr_parallaxbias k + break; + } + case 3: + { + set k pr_specularfactor + ftoi k PRSCALE, add k j, clamp k 0 MAXSPECULAR, itof k PRSCALE + qsprintf TQUOTE "SPECULAR FACTOR: %f" k, quote TQUOTE + set pr_specularfactor k + break; + } + case 4: + { + set k pr_specularpower + ftoi k PRSCALE, add k j, clamp k 0 MAXSPECULAR, itof k PRSCALE + qsprintf TQUOTE "SPECULAR POWER: %f" k, quote TQUOTE + set pr_specularpower k + break; + } + endswitch + } + + // if aiming at a sprite that's not a Polymer light + set k 0 + ife searchstat 3 set k 1 + + ife k 1 ife sprite[searchwall].picnum SECTOREFFECTOR + ifge sprite[searchwall].lotag 49 ifle sprite[searchwall].lotag 50 + set k 0 + + ife k 1 + { + seti searchwall + + // [xyz]vel / owner + ifeitheralt + { + ifhitkey KEY_KP1 + { + getnumber256 .xvel "XVEL:" 255 + getnumber256 .yvel "YVEL:" 255 + getnumber256 .zvel "ZVEL:" 255 + } + else ifhitkey KEY_KP2 + { + getnumber256 .owner "OWNER:" -MAXTILES + } + } + } + + + // if aiming at an SE with lotag 49 or 50 (Polymer light) + ife searchstat 3 ife sprite[searchwall].picnum SECTOREFFECTOR + ifge sprite[searchwall].lotag 49 ifle sprite[searchwall].lotag 50 + { + set i searchwall, seti i // set current sprite = targeted sprite + + ife .lotag 50 + { + // horiz + ifeithershift set j 1 else set j 10 + ifhitkey KEY_gUP add .extra j + else ifhitkey KEY_gKP5 sub .extra j + clamp .extra -500 500 + + // angle + set j 128 + ifeitherctrl set j 4 + ifeithershift { ifeitherctrl set j 1 else set j 32 } + ifhitkey KEY_gLEFT sub .ang j + else ifhitkey KEY_gRIGHT add .ang j + + // radius + ifeitherctrl + { + ifholdkey KEY_gMINUS add .shade 9 + else ifholdkey KEY_gPLUS sub .shade 9 + + clamp .shade -118 117 + } + } + + // range + ifeithershift set j 10 + else ifeitherctrl set j 1000 + else set j 100 + ifhitkey KEY_KP9 add .hitag j + else ifhitkey KEY_KP7 sub .hitag j + clamp .hitag 0 16000 + + // min/max shade + ifeithershift set j -1 else set j 1 + ifeitherctrl + { + ifhitkey KEY_gSLASH + { + set .xoffset 0 + set .yoffset 0 + } + } + else + { + set k 0 + ifhitkey KEY_gSLASH { add .xoffset j, set k 1 } + else ifhitkey KEY_gSTAR { add .yoffset j, set k 1 } + + ife k 1 + { + qsprintf TQUOTE "XY offset: %d %d" .xoffset .yoffset + quote TQUOTE + } + } + + // color/picnum + ifeitheralt + { + ifhitkey KEY_KP1 + { + getnumber256 .xvel "RED:" 255 + getnumber256 .yvel "GREEN:" 255 + getnumber256 .zvel "BLUE:" 255 + } + else ifhitkey KEY_KP2 + { + getnumber256 .owner "PICNUM:" -MAXTILES + } + } + else + { + ifeitherctrl set j 1 else set j 10 + ifeithershift inv j + + set k 0 + ifhitkey KEY_KP1 { add .xvel j, set k 1 } + ifhitkey KEY_KP2 { add .yvel j, set k 1 } + ifhitkey KEY_KP3 { add .zvel j, set k 1 } + + ife k 1 + { + clamp .xvel 1 255 + clamp .yvel 1 255 + clamp .zvel 1 255 + + qsprintf TQUOTE "RGB color: %d %d %d" .xvel .yvel .zvel + quote TQUOTE + } + } + } +ends + +// rotate highlighted sprites around selected (closest to mouse) sprite +// global parameter: dang +defstate rotselspr + ifg highlightcnt 0 + ifge pointhighlight 16384, ifl pointhighlight 32768 + { + ife dang 0 return + + set p pointhighlight, and p 16383 + + add sprite[p].ang dang + + for i selsprites, ifn i p + { + rotatepoint sprite[p].x sprite[p].y .x .y dang (x y) + add .ang dang + bsetsprite I x y .z + } + } +ends + +onevent EVENT_PREKEYS2D +// state testkeyavail + + set j 0 + ifeitherctrl + { + ifhitkey KEY_COMMA set j -1 + ifhitkey KEY_PERIOD set j 1 + } + + ifn j 0 + { + mul j 512 + set dang j + state rotselspr + } +endevent + +onevent EVENT_PREKEYS3D +// state testkeyavail + state fiddlewithlights +endevent + +defstate setas + set j dayx + mul j ydim mul j 8 + div j xdim div j 5 + setaspect davr j +ends + +onevent EVENT_ENTER3DMODE + state setas +endevent + +defstate cmp_by_lotag // comparator subroutine for sorting + set RETURN sprite[SV2].lotag + sub RETURN sprite[SV1].lotag +ends + +onevent EVENT_DRAW2DSCREEN + ifl cursectnum 0 return + + // connect LOCATORS in a sector by lines + getarraysize ar tmp + set j 0 + for i spritesofsector cursectnum + { + ifge j tmp nullop else + ifactor LOCATORS + { + set ar[j] i + add j 1 + } + } + + set tmp j + sort ar tmp cmp_by_lotag + + sub tmp 1 + for i range tmp + { + set j ar[i] + set k i, add k 1, set k ar[k] + drawline16b sprite[j].x sprite[j].y sprite[k].x sprite[k].y drawcol + } +/* + set drawlinepat -1 + for i allsprites + ifactor LIZTROOP + drawcircle16b sprite[i].x sprite[i].y 256 drawcol +*/ + +////////// polymer light 2d projections ////////// + var c d h x2 y2 oldpat + + array xx 2 + array yy 2 + + set oldpat drawlinepat + set drawlinepat 0x11111111 + for i spritesofsector cursectnum + { + ifactor SECTOREFFECTOR + { + ife .lotag 49 // point light + { + set d .hitag // light distance + mul d d, mul d 2, sqrt d d, div d 2 + + getclosestcol .xvel .yvel .zvel c // light color + inv c + + set x .x, set x2 .x, set y .y, set y2 .y + add x d, add y d, sub x2 d, sub y2 d + drawline16b x y x2 y2 c + + set x .x, set x2 .x, set y .y, set y2 .y + add x d, sub y d, sub x2 d, add y2 d + drawline16b x y x2 y2 c + + drawcircle16b .x .y .hitag c + } + else ife .lotag 50 // spot light + { + set d .hitag // light distance + and d 65535 + set r 128, sub r .shade, shiftl r 1 // light cone radius (BUILD angles) + getclosestcol .xvel .yvel .zvel c // light color + inv c + + set x .x, set y .y, add x d + rotatepoint .x .y x y .ang x y + + set h .extra // horiz + sub h 100 + set tmp h, mul tmp tmp, add tmp 40000 + sqrt tmp tmp + divscale h 200 tmp 15 // h: horizontal distance fraction + + set dx .x, sub dx x + set dy .y, sub dy y + set tmp 32768, sub tmp h + mulscale dx dx tmp 15 + mulscale dy dy tmp 15 + + set tmp 0, sub tmp r + rotatepoint .x .y x y tmp xx[0] yy[0] + set tmp 0, add tmp r + rotatepoint .x .y x y tmp xx[1] yy[1] + + add xx[0] dx, add yy[0] dy + add xx[1] dx, add yy[1] dy + + drawline16b .x .y xx[0] yy[0] c + drawline16b .x .y xx[1] yy[1] c + } + } + } + set drawlinepat oldpat +endevent + +// LOCATORS auto-incrementer +onevent EVENT_INSERTSPRITE2D + set k I + set j -1 + for i spritesofsector .sectnum + { + ifn i k, ifactor LOCATORS, ifg .lotag j + set j .lotag + } + ifg j -1 + { + add j 1 + set .lotag j + } +endevent + + +//////////////////// SPRITE DUPLICATORS //////////////////// + +defstate transcnt + ifle cnt 0 { inv cnt, add cnt 128 } +ends + +define DUP_ROT_MAGIC 123 + +// duplicates and rotates selected sprites around +// pivot sprite with fields +// .extra=123 (magic) +// .ang: angle delta +// .yrepeat*32: z delta (positive if pal!=0, i.e. going down) +// .shade: count (-128 to 0 -> 255 to 128) +defstate duprot + ifn searchstat 3 return + ifn sprite[searchwall].extra DUP_ROT_MAGIC return + + set p searchwall // pivot sprite + set cnt sprite[p].shade, state transcnt + + set sprite[p].extra -1 + + for i range cnt + { + for j selsprites, ifn j p + { + dupsprite j // duplicate sprite j, I becomes index of newly created sprite + + set dang i, add dang 1, mul dang sprite[p].ang + rotatepoint sprite[p].x sprite[p].y .x .y dang (x y) + add .ang dang + + set z i, add z 1, mul z sprite[p].yrepeat, shiftl z 5 + ife sprite[p].pal 0, inv z + add z .z + + bsetsprite I x y z + } + } +ends + +// same as above but with tsprite[], as a kind of preview +defstate tduprot + ifn searchstat 3 return + ifn sprite[searchwall].extra DUP_ROT_MAGIC return + + set p searchwall // pivot sprite + set cnt sprite[p].shade, state transcnt + + for i range cnt + { + for j selsprites, ifn j p + { + set k spritesortcnt + tdupsprite j + + set dang i, add dang 1, mul dang sprite[p].ang + rotatepoint sprite[p].x sprite[p].y tsprite[k].x tsprite[k].y dang (x y) + add tsprite[k].ang dang + + set z i, add z 1, mul z sprite[p].yrepeat, shiftl z 5 + ife sprite[p].pal 0 inv z + add z tsprite[k].z + + set tsprite[k].x x + set tsprite[k].y y + set tsprite[k].z z + + or tsprite[k].cstat 514 + } + } +ends + +define DUP_LIN_MAGIC 234 +define DUP_LIN_MAGIC2 345 + +// duplicates and translates selected sprites in the direction between two +// reference sprites with fields +// .extra=234 (1st sprite), =345 (2nd, aimed at sprite) +// .shade: count (-128 to 0 -> 255 to 128) +defstate duplin + ifn searchstat 3 return + ifn sprite[searchwall].extra DUP_LIN_MAGIC2 return + + set r searchwall // 2nd reference point + + set cnt sprite[r].shade, state transcnt + + set p -1 // 1st reference point + for i selsprites, ifn i r + { + ife .extra DUP_LIN_MAGIC { set p i, break } + } + ifl p 0 return + + set sprite[p].extra -1 + set sprite[r].extra -1 + + set dx sprite[r].x, sub dx sprite[p].x + set dy sprite[r].y, sub dy sprite[p].y + set dz sprite[r].z, sub dz sprite[p].z + + for i range cnt + { + for j selsprites, ifn j r + { + dupsprite j + + set x i, add x 1, mul x dx, add x .x + set y i, add y 1, mul y dy, add y .y + set z i, add z 1, mul z dz, add z .z + bsetsprite I x y z + } + } +ends + +defstate tduplin + ifn searchstat 3 return + ifn sprite[searchwall].extra DUP_LIN_MAGIC2 return + + set r searchwall // 2nd reference point + + set cnt sprite[r].shade, state transcnt + + set p -1 // 1st reference point + for i selsprites, ifn i r + { + ife .extra DUP_LIN_MAGIC { set p i, break } + } + ifl p 0 return + + set dx sprite[r].x, sub dx sprite[p].x + set dy sprite[r].y, sub dy sprite[p].y + set dz sprite[r].z, sub dz sprite[p].z + + for i range cnt + { + for j selsprites, ifn j r + { + set k spritesortcnt + tdupsprite j + + set tmp i, add tmp 1, mul tmp dx + add tsprite[k].x tmp + set tmp i, add tmp 1, mul tmp dy + add tsprite[k].y tmp + set tmp i, add tmp 1, mul tmp dz + add tsprite[k].z tmp + + or tsprite[k].cstat 514 +// bsetsprite I x y z + } + } +ends + +onevent EVENT_ANALYZESPRITES + state tduprot + state tduplin +endevent + +onevent EVENT_KEYS3D + // door sound tester + ife searchstat 0 + ifholdkey KEY_SPACE + { + set k wall[searchwall].nextsector + ifl k 0 set k searchsector + + ife sector[k].lotag 0 return + + for i spritesofsector k + { + ifactor MUSICANDSFX + ifge .lotag 0 ifl .lotag MAXSOUNDS + { + getsoundflags .lotag m + ifand m 1 nullop else soundonce .lotag + } + } + } + + // swinging doors tester -- hit space on a door wall + ife searchstat 0 + ifhitkey KEY_SPACE // SE11 ST23 up:ccw + { + set k wall[searchwall].nextsector + ifl k 0 return + ifn sector[k].lotag 23 return + set tmp 0 + for i loopofwall searchwall + { + ifl wall[i].nextsector 0 set tmp 1 else + ifn wall[i].nextsector k set tmp 1 + } +// a weaker condition +// for i loopofwall wall[searchwall].nextwall +// { +// ifl wall[i].nextsector 0 set tmp 1 else +// ifn wall[i].nextsector searchsector set tmp 1 +// } + ifn tmp 0 + { + quote "door sector not an island sector!" + return + } + + set l -1 + for i spritesofsector k + { + ifactor SECTOREFFECTOR ife sprite[i].lotag 11 + { + set l i + ifn sprite[i].ang 512 ifn sprite[i].ang 1024 ifn sprite[i].ang 1536 set l -1 + } + } + ifl l 0 + { + quote "door sector has no SE sprite!" + return + } + + for tmp wallsofsector k + { + rotatepoint (sprite[l].x sprite[l].y) (wall[tmp].x wall[tmp].y) sprite[l].ang (i j) + dragpoint tmp i j + } + for tmp spritesofsector k + { + ifn tmp l + { + rotatepoint (sprite[l].x sprite[l].y) (sprite[tmp].x sprite[tmp].y) sprite[l].ang (i j) + bsetsprite tmp i j sprite[tmp].z + } + } + inv sprite[l].ang + } + + // teleporter -- works on SE7 and SE17 (elevator) + ife searchstat 3 + ifhitkey KEY_SPACE + { + ife sprite[searchwall].picnum SECTOREFFECTOR + { + set tmp 0 + ife sprite[searchwall].lotag 7 set tmp 1 + ife sprite[searchwall].lotag 17 set tmp 1 + ife tmp 0 return + + for i allsprites + { + ifn i searchwall, ifactor SECTOREFFECTOR, ife sprite[i].lotag sprite[searchwall].lotag + ife sprite[i].hitag sprite[searchwall].hitag + { + add posx sprite[i].x, sub posx sprite[searchwall].x + add posy sprite[i].y, sub posy sprite[searchwall].y + add posz sprite[i].z, sub posz sprite[searchwall].z + + updatecursectnum + + return + } + } + } + else ife sprite[searchwall].extra DUP_ROT_MAGIC + { + state duprot + } + else ife sprite[searchwall].extra DUP_LIN_MAGIC2 + { + state duplin + } + } + + ifholdkey KEY_0 + // ife 0 1 + { + ifeithershift sub davr 512 else add davr 512 + ifl davr 32768 set davr 32768 + ifg davr 256000 set davr 256000 + setaspect davr yxaspect + qsprintf TQUOTE "ASPECT: VR=%d, YX=%d" davr yxaspect + quote TQUOTE + } +endevent + +defstate replacestuff + for i spritesofsector searchsector +// ife sprite[i].picnum AMMO set sprite[i].picnum BATTERYAMMO + ifactor parm[0] cactor parm[1] +ends + +defstate convlights // convert (0,0,0) lights to (255,255,255)-ones + for i allsprites ifactor 1 ifge .lotag 49 ifle .lotag 50 ife .xvel 0 ife .yvel 0 ife .zvel 0 + { set .xvel 255 set .yvel 255 set .zvel 255 } +ends + +defstate resetallws // reset all sprites and walls to default repeat/panning + for i allsprites + { + set .xrepeat 64 + set .yrepeat 64 + } + for i allwalls + { + set wall[i].cstat 0 + set wall[i].xpanning 0 + set wall[i].ypanning 0 + set wall[i].yrepeat 8 + fixrepeats i + } +ends + +defstate js // jump to current sprite + set posx .x + set posy .y + set posz .z + updatecursectnum +ends + +defstate jumptosec // (tmp) + ifge tmp 0 ifl tmp numsectors nullop else return + set j sector[tmp].wallptr + set posx wall[j].x + set posy wall[j].y + updatecursectnum +ends + +// Map corruption checker + +defstate corruptchk + var ewall + var endwall + + ifle numsectors MAXSECTORS ifle numwalls MAXWALLS nullop else + { quote 19 printmessage16 19 return } + + set ewall 0 // expected wall index + for i allsectors + { + set k 1 + ifge sector[i].wallptr 0 ifl sector[i].wallptr numwalls nullop else + { + qsprintf TQUOTE 20 i sector[i].wallptr numwalls + quote TQUOTE printmessage16 TQUOTE + set k 0 + } + ifn ewall sector[i].wallptr + { + qsprintf TQUOTE 21 i sector[i].wallptr ewall + quote TQUOTE printmessage16 TQUOTE + set ewall sector[i].wallptr + } + add ewall sector[i].wallnum + + set endwall sector[i].wallptr add endwall sector[i].wallnum + ifg endwall numwalls + { + qsprintf TQUOTE 22 i endwall numwalls + quote TQUOTE printmessage16 TQUOTE + set k 0 + } + + ifn k 0 + { + for j wallsofsector i + { + ifge wall[j].point2 sector[i].wallptr ifl wall[i].point2 endwall nullop else + { + qsprintf TQUOTE 23 j wall[j].point2 i sector[i].wallptr endwall + quote TQUOTE printmessage16 TQUOTE + } + + ifge wall[i].nextwall numwalls + { + qsprintf TQUOTE 24 j wall[j].nextwall numwalls + quote TQUOTE printmessage16 TQUOTE + } + + ifge wall[i].nextsector numsectors + { + qsprintf TQUOTE 25 j wall[j].nextsector numsectors + quote TQUOTE printmessage16 TQUOTE + } + } + } + } +ends diff --git a/polymer/eduke32/samples/tiles.cfg b/polymer/eduke32/samples/tiles.cfg index 5af2fc5ee..235194a33 100644 --- a/polymer/eduke32/samples/tiles.cfg +++ b/polymer/eduke32/samples/tiles.cfg @@ -3,161 +3,159 @@ #include "names.h" -tilegroup "Player" -{ - hotkey "P" - - // Colors are the colors for Blocking OFF and Blocking ON. - colors 2 2 - - tiles - { - APLAYER - } -} +// tilegroup "All named" with the hotkey "Y" is constructed automatically tilegroup "Actors" { - hotkey "A" - - colors 31 31 + hotkey "A" + + colors 31 31 - tiles - { - LIZTROOP LIZTROOPRUNNING LIZTROOPSTAYPUT LIZTROOPSHOOT LIZTROOPJETPACK - LIZTROOPONTOILET LIZTROOPJUSTSIT LIZTROOPDUCKING - PIGCOP PIGCOPSTAYPUT PIGCOPDIVE - LIZMAN LIZMANSTAYPUT LIZMANSPITTING LIZMANFEEDING LIZMANJUMP - COMMANDER COMMANDERSTAYPUT - OCTABRAIN OCTABRAINSTAYPUT - ORGANTIC + tiles + { + LIZTROOP LIZTROOPRUNNING LIZTROOPSTAYPUT LIZTROOPSHOOT LIZTROOPJETPACK + LIZTROOPONTOILET LIZTROOPJUSTSIT LIZTROOPDUCKING + PIGCOP PIGCOPSTAYPUT PIGCOPDIVE + LIZMAN LIZMANSTAYPUT LIZMANSPITTING LIZMANFEEDING LIZMANJUMP + COMMANDER COMMANDERSTAYPUT + OCTABRAIN OCTABRAINSTAYPUT + ORGANTIC DRONE - NEWBEAST NEWBEASTSTAYPUT NEWBEASTHANG NEWBEASTJUMP - EGG GREENSLIME ROTATEGUN RECON TANK BOUNCEMINE - FLOORFLAME - // FEMS - FEM1 FEM2 FEM3 FEM4 FEM5 FEM6 FEM7 FEM8 FEM9 FEM10 NAKED1 - // Lil' critters - SHARK - // BIG critters - BOSS1 BOSS1STAYPUT BOSS1SHOOT BOSS1LOB - BOSS2 - BOSS3 - BOSS4 BOSS4STAYPUT - } + NEWBEAST NEWBEASTSTAYPUT NEWBEASTHANG NEWBEASTJUMP + EGG GREENSLIME ROTATEGUN RECON TANK BOUNCEMINE + FLOORFLAME + // FEMS + FEM1 FEM2 FEM3 FEM4 FEM5 FEM6 FEM7 FEM8 FEM9 FEM10 NAKED1 + // Lil' critters + SHARK + // BIG critters + BOSS1 BOSS1STAYPUT BOSS1SHOOT BOSS1LOB + BOSS2 + BOSS3 + BOSS4 BOSS4STAYPUT + } } tilegroup "Doors" { - hotkey "D" + hotkey "D" - tiles - { - DOORTILE1 DOORTILE2 DOORTILE3 DOORTILE4 DOORTILE5 - DOORTILE6 DOORTILE7 DOORTILE8 DOORTILE9 DOORTILE10 - 312 313 314 345 - DOORTILE22 DOORTILE18 DOORTILE19 DOORTILE20 - 450 455 457 458 459 469 470 477 - DOORTILE14 - 719 735 771 - DOORTILE16 - 843 858 883 - DOORTILE15 DOORTILE21 - 1173 - DOORTILE11 DOORTILE12 - 353 355 - // Related items - DOORSHOCK ACCESSCARD - } + tiles + { + DOORTILE1 DOORTILE2 DOORTILE3 DOORTILE4 DOORTILE5 + DOORTILE6 DOORTILE7 DOORTILE8 DOORTILE9 DOORTILE10 + 312 313 314 345 + DOORTILE22 DOORTILE18 DOORTILE19 DOORTILE20 + 450 455 457 458 459 469 470 477 + DOORTILE14 + 719 735 771 + DOORTILE16 + 843 858 883 + DOORTILE15 DOORTILE21 + 1173 + DOORTILE11 DOORTILE12 + 353 355 + // Related items + DOORSHOCK ACCESSCARD + } } tilegroup "Effectors" { - hotkey "E" - - tilerange 1 10 - - colors 15 15 -} + hotkey "E" -tilegroup "Switches" -{ - hotkey "S" - - tiles - { - ACCESSSWITCH ACCESSSWITCH2 ACCESSCARD SLOTDOOR LIGHTSWITCH SPACEDOORSWITCH SPACELIGHTSWITCH - FRANKENSTINESWITCH MULTISWITCH - DIPSWITCH DIPSWITCH2 DIPSWITCH3 TECHSWITCH - LIGHTSWITCH2 713 // LIGHTSWITCH2+1 - POWERSWITCH1 LOCKSWITCH1 POWERSWITCH2 HANDSWITCH PULLSWITCH - ALIENSWITCH HANDPRINTSWITCH NUKEBUTTON - TARGET - 4083 4954 // Busted switches (Atomic) - } + colors 15 15 + + tilerange 1 10 } tilegroup "Items" { - hotkey "I" - - colors 24 24 + hotkey "I" + + colors 24 24 - tiles - { - // Ammo - AMMO SHOTGUNAMMO BATTERYAMMO RPGAMMO HEAVYHBOMB FREEZEAMMO GROWAMMO CRYSTALAMMO - DEVISTATORAMMO HBOMBAMMO - - // Items (healthetc) - COLA SIXPAK FIRSTAID SHIELD STEROIDS AIRTANK JETPACK HEATSENSOR ACCESSCARD - BOOTS ATOMICHEALTH HOLODUKE - - // Weapons - FIRSTGUNSPRITE CHAINGUNSPRITE RPGSPRITE FREEZESPRITE SHRINKERSPRITE - TRIPBOMBSPRITE SHOTGUNSPRITE DEVISTATORSPRITE - } -} - -tilegroup "Respawn triggers" -{ - hotkey "R" - - tiles - { - CANWITHSOMETHING CANWITHSOMETHING2 CANWITHSOMETHING3 CANWITHSOMETHING4 - // FEMS - FEM1 FEM2 FEM3 FEM4 FEM5 FEM6 FEM7 FEM8 FEM9 FEM10 NAKED1 - } -} - -tilegroup "Exploding stuff" -{ - hotkey "X" - - tiles - { - CRACK1 CRACK2 CRACK3 CRACK4 - FIREEXT SEENINE OOZFILTER - EXPLODINGBARREL EXPLODINGBARREL2 FIREBARREL GUNPOWDERBARREL - REACTOR2SPARK BOLT1 SIDEBOLT1 - CEILINGSTEAM - FIREVASE 2066 BURNING FIRE BURNING2 FIRE2 - } + tiles + { + // Ammo + AMMO SHOTGUNAMMO BATTERYAMMO RPGAMMO HEAVYHBOMB FREEZEAMMO GROWAMMO CRYSTALAMMO + DEVISTATORAMMO HBOMBAMMO + + // Items (healthetc) + COLA SIXPAK FIRSTAID SHIELD STEROIDS AIRTANK JETPACK HEATSENSOR ACCESSCARD + BOOTS ATOMICHEALTH HOLODUKE + + // Weapons + FIRSTGUNSPRITE CHAINGUNSPRITE RPGSPRITE FREEZESPRITE SHRINKERSPRITE + TRIPBOMBSPRITE SHOTGUNSPRITE DEVISTATORSPRITE + } } tilegroup "Letters and numbers" { - hotkey "L" - - tilerange 2822 2915 - tilerange 2929 3022 - tilerange 3072 3135 - tilerange 3162 3165 - tilerange 640 649 - tilerange 2472 2481 + hotkey "L" + + tilerange 2822 2915 + tilerange 2929 3022 + tilerange 3072 3135 + tilerange 3162 3165 + tilerange 640 649 + tilerange 2472 2481 } +tilegroup "Player" +{ + hotkey "P" + + // Colors are the colors for Blocking OFF and Blocking ON. + colors 2 2 + + tile APLAYER +} + +tilegroup "Respawn triggers" +{ + hotkey "R" + + tiles + { + CANWITHSOMETHING CANWITHSOMETHING2 CANWITHSOMETHING3 CANWITHSOMETHING4 + // FEMS + FEM1 FEM2 FEM3 FEM4 FEM5 FEM6 FEM7 FEM8 FEM9 FEM10 NAKED1 + } +} + +tilegroup "Switches" +{ + hotkey "S" + + tiles + { + ACCESSSWITCH ACCESSSWITCH2 ACCESSCARD SLOTDOOR LIGHTSWITCH SPACEDOORSWITCH SPACELIGHTSWITCH + FRANKENSTINESWITCH MULTISWITCH + DIPSWITCH DIPSWITCH2 DIPSWITCH3 TECHSWITCH + LIGHTSWITCH2 713 // LIGHTSWITCH2+1 + POWERSWITCH1 LOCKSWITCH1 POWERSWITCH2 HANDSWITCH PULLSWITCH + ALIENSWITCH HANDPRINTSWITCH NUKEBUTTON + TARGET + 4083 4954 // Busted switches (Atomic) + } +} + +tilegroup "Exploding stuff" +{ + hotkey "X" + + tiles + { + CRACK1 CRACK2 CRACK3 CRACK4 + FIREEXT SEENINE OOZFILTER + EXPLODINGBARREL EXPLODINGBARREL2 FIREBARREL GUNPOWDERBARREL + REACTOR2SPARK BOLT1 SIDEBOLT1 + CEILINGSTEAM + FIREVASE 2066 BURNING FIRE BURNING2 FIRE2 + } +} // Alphabet configuration for text entry tool in 3D mode // (press Ctrl-T on a wall-aligned letter) diff --git a/polymer/eduke32/source/astub.c b/polymer/eduke32/source/astub.c index 9414a56b8..6c0df820d 100644 --- a/polymer/eduke32/source/astub.c +++ b/polymer/eduke32/source/astub.c @@ -59,7 +59,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. static int32_t floor_over_floor; // static char *startwin_labeltext = "Starting Mapster32..."; -static char setupfilename[BMAX_PATH]= "mapster32.cfg"; +static char setupfilename[]= "mapster32.cfg"; static char defaultduke3dgrp[BMAX_PATH] = "duke3d.grp"; static char *g_grpNamePtr = defaultduke3dgrp; static int32_t fixmapbeforesaving = 1; @@ -67,8 +67,11 @@ static int32_t lastsave = -180*60; static int32_t NoAutoLoad = 0; static int32_t spnoclip=1; +static char default_tiles_cfg[] = "tiles.cfg"; +static int32_t pathsearchmode_oninit; + // Sound in Mapster32 -static char defaultgamecon[BMAX_PATH] = "game.con"; +static char defaultgamecon[] = "game.con"; static char *gamecon = defaultgamecon; #pragma pack(push,1) @@ -192,6 +195,10 @@ static char wallpals[MAXWALLS]; static char sectorpals[MAXSECTORS][2]; static char spritepals[MAXSPRITES]; static char wallflag[MAXWALLS]; + +// tile marking in tile selector for custom creation of tile groups +static int16_t tilemarked[(MAXTILES+7)>>3]; + #ifdef POLYMER static int16_t spritelightid[MAXSPRITES]; _prlight *spritelightptr[MAXSPRITES]; @@ -2675,22 +2682,46 @@ static int32_t SelectAllTiles(int32_t iCurrentTile) static int32_t OnGotoTile(int32_t iTile); static int32_t OnSelectTile(int32_t iTile); +static int32_t OnSaveTileGroup(); +static int32_t loadtilegroups(const char *fn); static int32_t s_Zoom = INITIAL_ZOOM; static int32_t s_TileZoom = 1; +static char tilesel_errmsg[128], tilesel_showerr=0; static int32_t DrawTiles(int32_t iTopLeft, int32_t iSelected, int32_t nXTiles, int32_t nYTiles, int32_t TileDim, int32_t offset); +#define TMPERRMSG_SHOW(alsoOSD) do { \ + printext256(0, 0, whitecol, 0, tilesel_errmsg, 0); \ + if (alsoOSD) OSD_Printf("%s\n", tilesel_errmsg); \ + showframe(1); \ +} while (0) + +#define TMPERRMSG_PRINT(Msg, ...) do { \ + Bsprintf(tilesel_errmsg, Msg, __VA_ARGS__); \ + TMPERRMSG_SHOW(1); \ + tilesel_showerr = 1; \ +} while (0) + +#define TMPERRMSG_RETURN(Msg, ...) do \ +{ \ + TMPERRMSG_PRINT(Msg, __VA_ARGS__); \ + return 1; \ +} while (0) + static int32_t m32gettile(int32_t idInitialTile) { int32_t gap, temp, zoomsz; int32_t nXTiles, nYTiles, nDisplayedTiles; int32_t i; - int32_t iTile, iTopLeftTile; + int32_t iTile, iTopLeftTile, iLastTile; int32_t idSelectedTile; int32_t scrollmode; int32_t mousedx, mousedy, mtile, omousex=searchx, omousey=searchy, moffset=0; + int32_t noTilesMarked=1; + int32_t mark_lastk = -1; + // Enable following line for testing. I couldn't work out how to change vidmode on the fly // s_Zoom = NUM_ZOOMS - 1; @@ -2722,7 +2753,7 @@ static int32_t m32gettile(int32_t idInitialTile) localartlookup[i] = i; } - iTile = idSelectedTile = idInitialTile; + iLastTile = iTile = idSelectedTile = idInitialTile; switch (searchstat) { @@ -2839,6 +2870,14 @@ static int32_t m32gettile(int32_t idInitialTile) DrawTiles(iTopLeftTile, (iTile >= localartlookupnum) ? localartlookupnum-1 : iTile, nXTiles, nYTiles, zoomsz, moffset); + if (tilesel_showerr) + { + if (iTile == iLastTile) + TMPERRMSG_SHOW(0); + else + tilesel_showerr = 0; + } + iLastTile = iTile; idle_waitevent_timeout(500); // SDL seems to miss mousewheel events when rotated slowly. @@ -2952,28 +2991,76 @@ static int32_t m32gettile(int32_t idInitialTile) } if (PRESSED_KEYSC(LEFT)) - iTile -= (iTile > 0); + { + if (eitherCTRL) // same as HOME, for consistency with CTRL-UP/DOWN + iTile = (iTile/nXTiles)*nXTiles; + else + iTile--; + } if (PRESSED_KEYSC(RIGHT)) - iTile += (iTile < MAXTILES); + { + if (eitherCTRL) // same as END, for consistency with CTRL-UP/DOWN + iTile = ((iTile+nXTiles)/nXTiles)*nXTiles - 1; + else + iTile++; + } if (PRESSED_KEYSC(UP)) - iTile -= nXTiles; + { + if (eitherCTRL) + while (iTile-nXTiles >= iTopLeftTile) + iTile -= nXTiles; + else + iTile -= nXTiles; + } if (PRESSED_KEYSC(DOWN)) - iTile += nXTiles; + { + if (eitherCTRL) + while (iTile+nXTiles < iTopLeftTile + nDisplayedTiles) + iTile += nXTiles; + else + iTile += nXTiles; + } if (PRESSED_KEYSC(PGUP)) - iTile -= nDisplayedTiles; + { + if (eitherCTRL) + iTile = 0; + else + iTile -= nDisplayedTiles; + } if (PRESSED_KEYSC(PGDN)) - iTile += nDisplayedTiles; + { + if (eitherCTRL) + iTile = localartlookupnum-1; + else + iTile += nDisplayedTiles; + } + + if (PRESSED_KEYSC(HOME)) + { + if (eitherCTRL) + iTile = iTopLeftTile; + else + iTile = (iTile/nXTiles)*nXTiles; + } + + if (PRESSED_KEYSC(END)) + { + if (eitherCTRL) + iTile = iTopLeftTile + nDisplayedTiles - 1; + else + iTile = ((iTile+nXTiles)/nXTiles)*nXTiles - 1; + } // // Ensure tilenum is within valid range // - iTile = clamp(iTile, 0, MAXTILES-1); // shouldn't this be the count of num tiles ?? + iTile = clamp(iTile, 0, localartlookupnum-1); // 'V' KEYPRESS if (PRESSED_KEYSC(V)) @@ -2981,7 +3068,20 @@ static int32_t m32gettile(int32_t idInitialTile) // 'G' KEYPRESS - Goto frame if (PRESSED_KEYSC(G)) - iTile = OnGotoTile(iTile); + { + if (eitherCTRL) + { + if (OnSaveTileGroup() == 0) + { +// iTile = SelectAllTiles(iTile); + Bmemset(tilemarked, 0, sizeof(tilemarked)); + mark_lastk = -1; + noTilesMarked = 1; + } + } + else + iTile = OnGotoTile(iTile); + } // 'U' KEYPRESS : go straight to user defined art if (PRESSED_KEYSC(U)) @@ -2997,10 +3097,6 @@ static int32_t m32gettile(int32_t idInitialTile) iTile = FIRST_ATOMIC_TILE; } - // 'T' KEYPRESS = Select from pre-defined tileset - if (PRESSED_KEYSC(T)) - iTile = OnSelectTile(iTile); - // 'E' KEYPRESS : Go straight to start of extended art if (PRESSED_KEYSC(E)) { @@ -3011,6 +3107,10 @@ static int32_t m32gettile(int32_t idInitialTile) else iTile = FIRST_EXTENDED_TILE; } + // 'T' KEYPRESS = Select from pre-defined tileset + if (PRESSED_KEYSC(T)) + iTile = OnSelectTile(iTile); + if (PRESSED_KEYSC(Z)) s_TileZoom = !s_TileZoom; @@ -3026,6 +3126,51 @@ static int32_t m32gettile(int32_t idInitialTile) iTopLeftTile = clamp(iTopLeftTile, 0, MAXTILES - nDisplayedTiles); + + // SPACE keypress: mark/unmark selected tile + if (PRESSED_KEYSC(SPACE)) + { + if (iTile < localartlookupnum && IsValidTile(localartlookup[iTile])) + { + if (keystatus[KEYSC_LCTRL] && keystatus[KEYSC_RSHIFT]) + { + Bmemset(tilemarked, 0, sizeof(tilemarked)); + mark_lastk = -1; + noTilesMarked = 1; + } + else + { + int32_t k=iTile, kend, dir; + + if (noTilesMarked) + { + noTilesMarked = 0; + TMPERRMSG_PRINT("%s", "Beginning marking tiles. To group, press Ctrl-G. To reset, press LCtrl-RShift-SPACE."); + } + + if (mark_lastk>=0 && eitherCTRL) + { + kend = mark_lastk; + dir = ksgn(mark_lastk-k); + } + else + { + kend = k; + dir = 0; + } + + mark_lastk = k; + + for (; dir==0 || dir*(kend-k)>=1; k+=dir) + { + tilemarked[localartlookup[k]>>3] ^= (1<<(localartlookup[k]&7)); + if (dir==0) + break; + } + } + } + } + if ((keystatus[KEYSC_ENTER] || (bstatus&1)) == 0) // uh ? Not escape key ? { idSelectedTile = idInitialTile; @@ -3059,7 +3204,7 @@ static int32_t m32gettile(int32_t idInitialTile) keystatus[KEYSC_ESC] = 0; keystatus[KEYSC_ENTER] = 0; - return(idSelectedTile); + return idSelectedTile; } @@ -3068,6 +3213,124 @@ static int32_t m32gettile(int32_t idInitialTile) //{ //} +static int32_t OnSaveTileGroup() +{ + int32_t i, n=0; + char hotkey; + const char *cp, *name; + + if (tile_groups==MAX_TILE_GROUPS) + TMPERRMSG_RETURN("Cannot save tile group: maximum number of groups (%d) exceeded.", MAX_TILE_GROUPS); + + for (i=0; i>3]&(1<<(i&7))); + + if (n==0) + TMPERRMSG_RETURN("%s", "Cannot save tile group: no tiles marked."); + else if (n > MAX_TILE_GROUP_ENTRIES) + TMPERRMSG_RETURN("Cannot save tile group: too many tiles in group. Have %d, max is %d.", + n, MAX_TILE_GROUP_ENTRIES); + + cp = getstring_simple("Hotkey for new group: ", "", 1); + if (!cp || !*cp) + return 1; + + hotkey = Btoupper(cp[0]); + if (!isalpha(hotkey)) + TMPERRMSG_RETURN("%s", "Hotkey must be alphabetic."); + + for (i=0; i>3]&(1<<((i)&7)))) + Bfprintf(fp, "\n"); + Bfprintf(fp, "tilegroup \"%s\"\n{\n", name); + Bfprintf(fp, TTAB "hotkey \"%c\"\n\n", hotkey); + + // tileranges for consecutive runs of 3 or more tiles + for (i=0; i=0 && !TBITCHK(i)) + { + if (names[lasti][0] && names[i-1][0]) + Bfprintf(fp, TTAB "tilerange %s %s\n", names[lasti], names[i-1]); + else + Bfprintf(fp, TTAB "tilerange %d %d\n", lasti, i-1); + + for (k=lasti; k>3] &= ~(1<<(i&7)); + + lasti = -1; + } + else if (lasti==-1 && TBITCHK(i)) + { + if (TBITCHK(i+1) && TBITCHK(i+2)) + { + lasti = i; + i += 2; + } + } + } + if (lasti>=0) + Bfprintf(fp, TTAB "tilerange %d %d\n", lasti, MAXTILES-1); + Bfprintf(fp, "\n"); + + // throw them all in a tiles{...} group else + Bfprintf(fp, TTAB "tiles\n" TTAB "{\n"); + for (i=0; i80) + { + Bfprintf(fp, "\n"); + col = 0; + } + } + } + if (col>0) + Bfprintf(fp, "\n"); + Bfprintf(fp, TTAB "}\n"); +#undef TBITCHK +#undef TTAB + Bfprintf(fp, "}\n"); + + Bfclose(fp); + + if (loadtilegroups(default_tiles_cfg)) + TMPERRMSG_PRINT("%s", "Wrote new tile group but failed reloading them."); + else + TMPERRMSG_PRINT("%s", "Wrote and reloaded new tile group."); + } + + return 0; +} + + static int32_t OnGotoTile(int32_t iTile) { int32_t iTemp, iNewTile; @@ -3116,6 +3379,7 @@ static int32_t OnGotoTile(int32_t iTile) return iTile; } + static int32_t LoadTileSet(const int32_t idCurrentTile, const int32_t *pIds, const int32_t nIds) { int32_t iNewTile = 0; @@ -3143,15 +3407,12 @@ static int32_t OnSelectTile(int32_t iTile) int32_t i; char ch; - for (i = 0; (unsigned)i < tile_groups; i++) + if (tile_groups <= 0) { - if (s_TileGroups[i].pIds != NULL) - break; + TMPERRMSG_PRINT("No tile groups loaded. Check for existence of `%s'.", default_tiles_cfg); + return iTile; } - if ((unsigned)i == tile_groups) // no tile groups - return (iTile); - SelectAllTiles(iTile); bflushchars(); @@ -3176,7 +3437,7 @@ static int32_t OnSelectTile(int32_t iTile) // // Display the description strings for each available tile group // - for (i = 0; (unsigned)i < tile_groups; i++) + for (i = 0; i < tile_groups; i++) { if (s_TileGroups[i].szText != NULL) { @@ -3189,7 +3450,7 @@ static int32_t OnSelectTile(int32_t iTile) ch = bgetchar(); - for (i = 0; (unsigned)i < tile_groups; i++) + for (i = 0; i < tile_groups; i++) { if (s_TileGroups[i].pIds != NULL && s_TileGroups[i].key1) if ((ch == s_TileGroups[i].key1) || (ch == s_TileGroups[i].key2)) @@ -3208,6 +3469,11 @@ static int32_t OnSelectTile(int32_t iTile) return iTile; } +#undef TMPERRMSG_SHOW +#undef TMPERRMSG_PRINT +#undef TMPERRMSG_RETURN + + static const char *GetTilePixels(int32_t idTile) { char *pPixelData = 0; @@ -3228,10 +3494,9 @@ static int32_t DrawTiles(int32_t iTopLeft, int32_t iSelected, int32_t nXTiles, i { int32_t XTile, YTile; int32_t iTile, idTile; - int32_t XBox, YBox; int32_t XPos, YPos; int32_t XOffset, YOffset; - int32_t i; + int32_t i, marked; const char *pRawPixels; int32_t TileSizeX, TileSizeY; int32_t DivInc,MulInc; @@ -3306,30 +3571,45 @@ static int32_t DrawTiles(int32_t iTopLeft, int32_t iSelected, int32_t nXTiles, i printext256(XPos, YPos, whitecol, -1, szT, 1); } } + + marked = (IsValidTile(idTile) && tilemarked[idTile>>3]&(1<<(idTile&7))); + + // + // Draw white box around currently selected tile or marked tile + // p1=(x1, y1), p2=(x1+TileDim-1, y1+TileDim-1) + // + if (iTile == iSelected || marked) + { + int32_t x1 = ((iTile-iTopLeft) % nXTiles)*TileDim; + int32_t y1 = ((iTile - ((iTile-iTopLeft) % nXTiles) - iTopLeft)/nXTiles)*TileDim + offset; + int32_t x2 = x1+TileDim-1; + int32_t y2 = y1+TileDim-1; + + char markedcol = editorcolors[14]; + + setpolymost2dview(); + + y1=max(y1, 0); + y2=min(y2, ydim-1); + + // box + plotlines2d((int32_t[]){x1, x1, x2, x2, x1}, + (int32_t[]){y1, y2, y2, y1, y1}, 5, iTile==iSelected ? whitecol : markedcol); + // cross + if (marked) + { + plotlines2d((int32_t[]){x1, x2}, + (int32_t[]){y1, y2}, 2, markedcol); + plotlines2d((int32_t[]){x1, x2}, + (int32_t[]){y2, y1}, 2, markedcol); + } + } } } } - // - // Draw white box around currently selected tile - // - - XBox = ((iSelected-iTopLeft) % nXTiles) * TileDim; - YBox = ((iSelected - ((iSelected-iTopLeft) % nXTiles) - iTopLeft) / nXTiles) * TileDim+offset; - - if (iSelected-iTopLeft>0) - for (i = 0; i < TileDim; i++) - { - if (YBox>=0 && YBox=0 && YBox+TileDim=0 && YBox+i= MAXTILES) + return 1; idTile = localartlookup[ iSelected ]; @@ -8016,7 +8296,7 @@ int32_t parsetilegroups(scriptfile *script) if (scriptfile_getstring(script,&name)) break; if (scriptfile_getbraces(script,&end)) break; - s_TileGroups[tile_groups].pIds = Bcalloc(MAX_TILE_GROUP_ENTRIES,sizeof(int32_t)); + s_TileGroups[tile_groups].pIds = Bcalloc(MAX_TILE_GROUP_ENTRIES, sizeof(int32_t)); s_TileGroups[tile_groups].szText = Bstrdup(name); while (script->textptr < end) @@ -8090,7 +8370,9 @@ int32_t parsetilegroups(scriptfile *script) } } } - s_TileGroups[tile_groups].pIds = Brealloc(s_TileGroups[tile_groups].pIds,s_TileGroups[tile_groups].nIds*sizeof(int32_t)); + + s_TileGroups[tile_groups].pIds = Brealloc(s_TileGroups[tile_groups].pIds, + s_TileGroups[tile_groups].nIds*sizeof(int32_t)); tile_groups++; break; } @@ -8099,7 +8381,12 @@ int32_t parsetilegroups(scriptfile *script) char *end; int32_t i, j, k; - if (numalphabets >= MAX_ALPHABETS) break; + if (numalphabets >= MAX_ALPHABETS) + { + OSD_Printf("Too many alphabet definitions (max: %d).\n", MAX_ALPHABETS); + break; + } + if (scriptfile_getbraces(script,&end)) break; for (i=0; i= 0; i--) + for (i=0; i 0) - Bmemset(localvars, aEventNumLocals[iEventID]*sizeof(int32_t), 0); + Bmemset(localvars, 0, aEventNumLocals[iEventID]*sizeof(int32_t)); Bmemcpy(&vm_backup, &vm, sizeof(vmstate_t)); @@ -358,7 +358,7 @@ skip_check: // needed since any read access before initialization would cause undefined behaviour if (statesinfo[stateidx].numlocals > 0) - Bmemset(localvars, statesinfo[stateidx].numlocals*sizeof(int32_t), 0); + Bmemset(localvars, 0, statesinfo[stateidx].numlocals*sizeof(int32_t)); insptr = script + statesinfo[stateidx].ofs; vm.g_st = 1+MAXEVENTS+stateidx; diff --git a/polymer/eduke32/source/mapster32.h b/polymer/eduke32/source/mapster32.h index 1e2140e02..0fc450404 100644 --- a/polymer/eduke32/source/mapster32.h +++ b/polymer/eduke32/source/mapster32.h @@ -186,7 +186,7 @@ typedef struct static TileGroup s_TileGroups[MAX_TILE_GROUPS]; static int32_t tilegroupItems; static int32_t tilegroupActors; -static uint32_t tile_groups = 0; +static int32_t tile_groups = 0; #define NUMPRINTABLES 94