diff --git a/polymer/eduke32/build/include/build.h b/polymer/eduke32/build/include/build.h index 4fefb6b5c..f42239b9d 100644 --- a/polymer/eduke32/build/include/build.h +++ b/polymer/eduke32/build/include/build.h @@ -62,7 +62,9 @@ extern "C" { #define PR_LIGHT_PRIO_LOW_GAME 5 ////////// yax defs ////////// -#define YAX_MAXBUNCHES (MAXSECTORS>>1) +#define SECTORFLD(Sect,Fld, Cf) (*((Cf) ? (§or[Sect].floor##Fld) : (§or[Sect].ceiling##Fld))) + +#define YAX_MAXBUNCHES 256 #define YAX_BIT 1024 // "has next wall when constrained"-bit (1<<10: ceiling, 1<<11: floor) #define YAX_NEXTWALLBIT(Cf) (1<<(10+Cf)) @@ -70,12 +72,13 @@ extern "C" { #define YAX_CEILING 0 // don't change! #define YAX_FLOOR 1 // don't change! -#define SECTORFLD(Sect,Fld, Cf) (*((Cf) ? (§or[Sect].floor##Fld) : (§or[Sect].ceiling##Fld))) +void yax_updategrays(int32_t posze); +#ifdef YAX_ENABLE // more user tag hijacking: lotag/extra :/ -#define YAX_NEXTWALL(Wall, Cf) (*(&wall[Wall].lotag + 2*Cf)) +# define YAX_NEXTWALL(Wall, Cf) (*(&wall[Wall].lotag + 2*Cf)) -#define YAX_ITER_WALLS(Wal, Itervar, Cfvar) Cfvar=0, Itervar=(Wal); Itervar!=-1; \ +# define YAX_ITER_WALLS(Wal, Itervar, Cfvar) Cfvar=0, Itervar=(Wal); Itervar!=-1; \ Itervar=yax_getnextwall(Itervar, Cfvar), (void)(Itervar==-1 && Cfvar==0 && (Cfvar=1) && (Itervar=yax_getnextwall((Wal), Cfvar))) int16_t yax_getbunch(int16_t i, int16_t cf); @@ -85,14 +88,21 @@ void yax_setbunches(int16_t i, int16_t cb, int16_t fb); int16_t yax_getnextwall(int16_t wal, int16_t cf); void yax_setnextwall(int16_t wal, int16_t cf, int16_t thenextwall); void yax_update(int32_t onlyreset); -void yax_updategrays(int32_t posze); int32_t yax_getneighborsect(int32_t x, int32_t y, int32_t sectnum, int32_t cf, int16_t *ret_bunchnum); -void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectnum); -#ifdef YAX_ENABLE +static inline int32_t yax_waltosecmask(int32_t walclipmask) +{ + // blocking: walstat&1 --> secstat&512 + // hitscan: walstat&64 --> secstat&2048 + return ((walclipmask&1)<<9) | ((walclipmask&64)<<5); +} +void yax_preparedrawrooms(void); +void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectnum); # define YAX_SKIPSECTOR(i) if (graysectbitmap[(i)>>3]&(1<<((i)&7))) continue # define YAX_SKIPWALL(i) if (graywallbitmap[(i)>>3]&(1<<((i)&7))) continue #else +# define yax_preparedrawrooms() +# define yax_drawrooms(ExtAnalyzeSprites, horiz, sectnum) # define YAX_SKIPSECTOR(i) (i)=(i) # define YAX_SKIPWALL(i) (i)=(i) #endif @@ -128,7 +138,8 @@ void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectn // 11 = reverse transluscent masked floors // bit 9: 1 = blocking ceiling/floor // bit 10: 1 = YAX'ed ceiling/floor -// bits 11-15: reserved +// bit 11: 1 = hitscan-sensitive ceiling/floor +// bits 12-15: reserved //40 bytes typedef struct diff --git a/polymer/eduke32/build/include/editor.h b/polymer/eduke32/build/include/editor.h index 0a922deba..4629e2bfd 100644 --- a/polymer/eduke32/build/include/editor.h +++ b/polymer/eduke32/build/include/editor.h @@ -70,10 +70,8 @@ extern int32_t m32_osd_tryscript; extern int32_t showheightindicators; extern int32_t showambiencesounds; -#ifdef YAX_ENABLE extern uint8_t graysectbitmap[MAXSECTORS>>3]; extern uint8_t graywallbitmap[MAXWALLS>>3]; -#endif // editor side view extern int32_t m32_sideview; @@ -97,9 +95,10 @@ extern void bfirst_search_try(int16_t *list, uint8_t *bitmap, int32_t *eltnumptr extern int32_t wallength(int16_t i); extern void fixrepeats(int16_t i); -extern void fixxrepeat(int16_t i, uint32_t lenrepquot); +extern uint32_t getlenbyrep(int32_t len, int32_t repeat); +extern void fixxrepeat(int16_t wallnum, uint32_t lenrepquot); extern void AlignWallPoint2(int32_t w0); -extern int32_t AutoAlignWalls(int32_t w0, int32_t dorecurse, int32_t nrecurs); +extern int32_t AutoAlignWalls(int32_t w0, uint32_t flags, int32_t nrecurs); extern int32_t ExtInit(void); extern int32_t ExtPreInit(int32_t argc,const char **argv); diff --git a/polymer/eduke32/build/include/m32script.h b/polymer/eduke32/build/include/m32script.h index ac7854c4c..ebc3ad6bb 100644 --- a/polymer/eduke32/build/include/m32script.h +++ b/polymer/eduke32/build/include/m32script.h @@ -247,16 +247,18 @@ extern int32_t halfxdim16, midydim16; #define M32_SECTOR_VAR_ID 1 #define M32_WALL_VAR_ID 2 #define M32_TSPRITE_VAR_ID 3 +#define M32_LIGHT_VAR_ID 4 -#define M32_THISACTOR_VAR_ID 4 -#define M32_RETURN_VAR_ID 5 -#define M32_LOTAG_VAR_ID 6 -#define M32_HITAG_VAR_ID 7 -#define M32_TEXTURE_VAR_ID 8 +#define M32_THISACTOR_VAR_ID 5 +#define M32_RETURN_VAR_ID 6 +#define M32_LOTAG_VAR_ID 7 +#define M32_HITAG_VAR_ID 8 +#define M32_TEXTURE_VAR_ID 9 #define M32_LOCAL_ARRAY_ID 0 #define M32_PRINTERROR(Text, ...) OSD_Printf(OSD_ERROR "Line %d, %s: " Text "\n", g_errorLineNum, keyw[g_tw], ## __VA_ARGS__) +#define M32_ERROR(Text, ...) do { M32_PRINTERROR(Text, ## __VA_ARGS__); vm.flags |= VMFLAG_ERROR; } while (0) // how local gamevars are allocated: diff --git a/polymer/eduke32/build/src/build.c b/polymer/eduke32/build/src/build.c index 6235f56e3..cfb5f5573 100644 --- a/polymer/eduke32/build/src/build.c +++ b/polymer/eduke32/build/src/build.c @@ -329,11 +329,8 @@ static void M32_drawdebug(void) if (m32_numdebuglines>0) { begindrawing(); - for (i=0; i640?0:1); - } enddrawing(); } m32_numdebuglines=0; @@ -414,6 +411,9 @@ static void reset_default_mapstate(void) numwalls = 0; numsprites = 0; + editorzrange[0] = INT_MIN; + editorzrange[1] = INT_MAX; + initspritelists(); taglab_init(); @@ -642,10 +642,10 @@ CANCEL: ExtPreCheckKeys(); + yax_preparedrawrooms(); drawrooms(pos.x,pos.y,pos.z,ang,horiz,cursectnum); -#ifdef YAX_ENABLE yax_drawrooms(ExtAnalyzeSprites, horiz, cursectnum); -#endif + ExtAnalyzeSprites(); drawmasks(); @@ -2229,7 +2229,7 @@ void overheadeditor(void) int32_t tempint, tempint1, tempint2; int32_t startwall=0, endwall, dax, day, x1, y1, x2, y2, x3, y3, x4, y4; int32_t highlightx1, highlighty1, highlightx2, highlighty2; - int16_t pag, suckwall=0, sucksect, split=0, bad; + int16_t suckwall=0, sucksect, split=0, bad; int16_t splitsect=0, joinsector[2]; int16_t splitstartwall=0; int32_t mousx, mousy, bstatus; @@ -2256,13 +2256,14 @@ void overheadeditor(void) searchy = clamp(scale(searchy,ydim2d-STATUS2DSIZ2,ydimgame), 8, ydim2d-STATUS2DSIZ-8-1); oposz = pos.z; + yax_updategrays(pos.z); + begindrawing(); //{{{ CLEARLINES2D(0, ydim, 0); enddrawing(); //}}} ydim16 = ydim-STATUS2DSIZ2; - pag = 0; cursectorhighlight = -1; lastpm16time = -1; @@ -3542,7 +3543,10 @@ end_yax: ; } } else - hlsectorbitmap[i>>3] |= (1<<(i&7)); + { + if ((graysectbitmap[i>>3]&(1<<(i&7)))==0) + hlsectorbitmap[i>>3] |= (1<<(i&7)); + } } } @@ -4263,7 +4267,11 @@ end_join_sectors: NEXTWALL(i).nextwall = i; NEXTWALL(i).nextsector = numsectors; } - +#ifdef YAX_ENABLE + yax_setbunches(numsectors, -1, -1); + yax_update(0); + yax_updategrays(pos.z); +#endif numwalls = newnumwalls; newnumwalls = -1; numsectors++; @@ -5872,17 +5880,13 @@ int32_t LoadBoard(const char *filename, uint32_t flags) if (filename != boardfilename) Bstrcpy(boardfilename, filename); - if ((flags&1)==0) - { - highlightcnt = -1; - Bmemset(show2dwall, 0, sizeof(show2dwall)); //Clear all highlights - Bmemset(show2dsprite, 0, sizeof(show2dsprite)); - } - for (i=0; i= 0) { k = wall[j].nextwall; - templenrepquot = divscale12(wallength(k), wall[k].xrepeat); + templenrepquot = getlenbyrep(wallength(k), wall[k].xrepeat); sucksect = sectorofwall(k); @@ -6452,12 +6456,20 @@ void fixrepeats(int16_t i) wall[i].xrepeat = clamp(mulscale10(dist,day), 1, 255); } -void fixxrepeat(int16_t i, uint32_t lenrepquot) // lenrepquot: divscale12(wallength,xrepeat) +uint32_t getlenbyrep(int32_t len, int32_t repeat) +{ + if (repeat <= 0) + return ((uint32_t)len)<<12; + + return divscale12(len, repeat); +} + +void fixxrepeat(int16_t wallnum, uint32_t lenrepquot) // lenrepquot: divscale12(wallength,xrepeat) { if (lenrepquot != 0) { - uint32_t res = (((wallength(i)<<12)+(1<<11))/lenrepquot); - wall[i].xrepeat = clamp(res, 1, 255); + uint32_t res = (((wallength(wallnum)<<12)+(1<<11))/lenrepquot); + wall[wallnum].xrepeat = clamp(res, 1, 255); } } @@ -6726,10 +6738,10 @@ int32_t _getnumber256(const char *namestart, int32_t num, int32_t maxnumber, cha if (handleevents()) quitevent = 0; + yax_preparedrawrooms(); drawrooms(pos.x,pos.y,pos.z,ang,horiz,cursectnum); -#ifdef YAX_ENABLE yax_drawrooms(ExtAnalyzeSprites, horiz, cursectnum); -#endif + ExtAnalyzeSprites(); drawmasks(); @@ -8197,11 +8209,15 @@ void AlignWallPoint2(int32_t w0) AlignWalls(w0,GetWallBaseZ(w0), w1,GetWallBaseZ(w1), wall[w0].picnum); } -// pass maxrecurs=0 for unconstrained recursion -int32_t AutoAlignWalls(int32_t w0, int32_t dorecurse, int32_t nrecurs) +// flags: +// 1: recurse nextwalls +// 2: iterate point2's +// 4: carry pixel width from first wall over to the rest +int32_t AutoAlignWalls(int32_t w0, uint32_t flags, int32_t nrecurs) { int32_t z0, z1, tilenum, w1, visible, nextsec, sectnum; - static int32_t numaligned; + static int32_t numaligned, wall0; + static uint32_t lenrepquot; tilenum = wall[w0].picnum; @@ -8211,6 +8227,8 @@ int32_t AutoAlignWalls(int32_t w0, int32_t dorecurse, int32_t nrecurs) Bmemset(visited, 0, sizeof(visited)); visited[w0>>3] |= (1<<(w0&7)); numaligned = 0; + lenrepquot = getlenbyrep(wallength(w0), wall[w0].xrepeat); + wall0 = w0; } z0 = GetWallBaseZ(w0); @@ -8253,23 +8271,28 @@ int32_t AutoAlignWalls(int32_t w0, int32_t dorecurse, int32_t nrecurs) if (visible) { - numaligned++; + if ((flags&4) && w0!=wall0) + fixxrepeat(w0, lenrepquot); AlignWalls(w0,z0, w1,z1, tilenum); + numaligned++; //if wall was 1-sided, no need to recurse if (wall[w1].nextwall < 0) { + if (!(flags&2)) + break; w0 = w1; z0 = GetWallBaseZ(w0); w1 = wall[w0].point2; continue; } - else if (dorecurse) - AutoAlignWalls(w1, 1, nrecurs+1); + else if (flags&1) + AutoAlignWalls(w1, flags, nrecurs+1); } } - if (wall[w1].nextwall < 0) break; + if (wall[w1].nextwall < 0 || !(flags&2)) + break; w1 = NEXTWALL(w1).point2; } diff --git a/polymer/eduke32/build/src/engine.c b/polymer/eduke32/build/src/engine.c index 1267e0f0d..ed3671af1 100644 --- a/polymer/eduke32/build/src/engine.c +++ b/polymer/eduke32/build/src/engine.c @@ -188,19 +188,73 @@ int16_t editstatus = 0; ////////// YAX ////////// +#if YAX_M32_DEBUG +extern char m32_debugstr[64][128]; +extern int32_t m32_numdebuglines; +# define yaxdebug(fmt, ...) do { if (m32_numdebuglines<64) Bsprintf(m32_debugstr[m32_numdebuglines++], fmt, ##__VA_ARGS__); } while (0) +#else +# define yaxdebug(fmt, ...) +#endif + +uint8_t graysectbitmap[MAXSECTORS>>3]; +uint8_t graywallbitmap[MAXWALLS>>3]; + +#ifdef ENGINE_SCREENSHOT_DEBUG +int32_t engine_screenshot = 0; +#endif + +void yax_updategrays(int32_t posze) +{ + int32_t i, j, k=1; +#ifndef YAX_ENABLE + UNREFERENCED_PARAMETER(posze); +#endif + Bmemset(graysectbitmap, 0, sizeof(graysectbitmap)); + Bmemset(graywallbitmap, 0, sizeof(graywallbitmap)); + + // update grayouts due to editorzrange + for (i=0; i= editorzrange[0] && sector[i].floorz <= editorzrange[1]); + + if (!k) // outside bounds, gray out! + { + graysectbitmap[i>>3] |= (1<<(i&7)); + for (j=sector[i].wallptr; j>3] |= (1<<(j&7)); + } + } +} + + #ifdef YAX_ENABLE // all references to floor/ceiling bunchnums should be through the // get/set functions! +static int32_t g_nodraw = 0; static int32_t scansector_retfast = 0; +static int32_t scansector_collectsprites = 1; +static int32_t yax_globalcf = -1; +static int32_t yax_globallev = YAX_MAXDRAWS; + +// duplicated tsprites +// [i]: +// i==MAXDRAWS: base level +// iMAXDRAWS: i-MAXDRAWS-1 is level towards floor +static int16_t yax_spritesortcnt[1 + 2*YAX_MAXDRAWS]; +static int16_t yax_tsprite[1 + 2*YAX_MAXDRAWS][MAXSPRITESONSCREEN]; // game-time YAX data structures static int16_t yax_bunchnum[MAXSECTORS][2]; static int16_t yax_nextwall[MAXWALLS][2]; -uint8_t graysectbitmap[MAXSECTORS>>3]; -uint8_t graywallbitmap[MAXWALLS>>3]; - static int32_t yax_islockededge(/*int16_t sec,*/ int16_t line, int16_t cf) #if 1 { @@ -223,7 +277,7 @@ static int32_t yax_islockededge(/*int16_t sec,*/ int16_t line, int16_t cf) } #endif -#define YAX_BUNCHNUM(Sect, Cf) (*(int16_t *)(§or[Sect].ceilingxpanning + 8*Cf)) +#define YAX_BUNCHNUM(Sect, Cf) (*(§or[Sect].ceilingxpanning + 8*Cf)) //// bunch getters/setters int16_t yax_getbunch(int16_t i, int16_t cf) @@ -312,6 +366,7 @@ void yax_setnextwall(int16_t wal, int16_t cf, int16_t thenextwall) //// in-struct --> array transfer; list construction void yax_update(int32_t onlyreset) { +// TODO: always make bunchnums consecutive int32_t i, j, oeditstatus=editstatus; int16_t cb, fb, tmpsect; @@ -382,34 +437,6 @@ void yax_update(int32_t onlyreset) editstatus = oeditstatus; } -void yax_updategrays(int32_t posze) -{ - int32_t i, j, k; - int16_t cb, fb; - - Bmemset(graysectbitmap, 0, sizeof(graysectbitmap)); - Bmemset(graywallbitmap, 0, sizeof(graywallbitmap)); - - if (numyaxbunches==0) - return; - - for (i=0; i>3] |= (1<<(i&7)); - for (j=sector[i].wallptr; j>3] |= (1<<(j&7)); - } - } -} - int32_t yax_getneighborsect(int32_t x, int32_t y, int32_t sectnum, int32_t cf, int16_t *ret_bunchnum) { int16_t bunchnum = yax_getbunch(sectnum, cf); @@ -429,144 +456,326 @@ int32_t yax_getneighborsect(int32_t x, int32_t y, int32_t sectnum, int32_t cf, i return -1; } -static int32_t globalcf; - +// >0 b2 is farther away than b1 static int yax_cmpbunches(const int16_t *b1, const int16_t *b2) { int32_t s1,s2, w1,w2; - int64_t x1,y1, x2,y2, r; - - s1 = headsectbunch[globalcf][*b1]; - s2 = headsectbunch[globalcf][*b2]; +#if 1 + int32_t dx1,dy1, dx2,dy2, r; +#else + int64_t dx1,dy1, dx2,dy2, r; +#endif + s1 = headsectbunch[yax_globalcf][*b1]; + s2 = headsectbunch[yax_globalcf][*b2]; w1 = sector[s1].wallptr; w2 = sector[s2].wallptr; - x1 = wall[w1].x-globalposx; y1 = wall[w1].y-globalposy; - x2 = wall[w2].x-globalposx; y2 = wall[w2].y-globalposy; - - r = (x2*x2 + y2*y2) - (x1*x1 + y1*y1); + dx1 = wall[w1].x-globalposx; dy1 = wall[w1].y-globalposy; + dx2 = wall[w2].x-globalposx; dy2 = wall[w2].y-globalposy; +#if 1 + r = klabs(dx2+dy2) - klabs(dx1+dy1); + return r; +#else + r = (dx2*dx2 + dy2*dy2) - (dx1*dx1 + dy1*dy1); if (r > 0) return 1; return r>>63; +#endif +} + +static int32_t yax_getbestsector(int32_t bunchnum, int32_t cf, const int16_t *ourbunch, int16_t sectnum) +{ + int32_t k; + + if (bunchnum==ourbunch[cf]) + { + k = yax_getneighborsect(globalposx, globalposy, sectnum, cf, NULL); + if (k < 0) + k = headsectbunch[!cf][bunchnum]; + return k; + } + else + { +// return headsectbunch[!cf][bunchnum]; + + scansector_retfast = 1; + scansector_collectsprites = 0; + for (k = headsectbunch[!cf][bunchnum]; k != -1; k = nextsectbunch[!cf][k]) + { + numscans = numbunches = 0; + scansector(k); + if (numbunches > 0) + break; + } + scansector_collectsprites = 1; + scansector_retfast = 0; + + return k; + } +} + +static void yax_tweakpicnums(int32_t bunchnum, int32_t cf, int32_t restore) +{ + static int16_t opicnum[2][MAXSECTORS]; + int32_t i; + + for (i=headsectbunch[cf][bunchnum]; i!=-1; i=nextsectbunch[cf][i]) + if ((SECTORFLD(i,stat, cf)&(128+256))==0) + { + if (!restore) + { + opicnum[cf][i] = SECTORFLD(i,picnum, cf); + if (editstatus && showinvisibility) + SECTORFLD(i,picnum, cf) = MAXTILES-1; + else + SECTORFLD(i,picnum, cf) = 13; //FOF; + } + else + { + SECTORFLD(i,picnum, cf) = opicnum[cf][i]; + } + } +} + +static void yax_copytsprite(int16_t curbunchnum) +{ + int16_t bunchnum; + int32_t i, spritenum, gotthrough, sectnum, cf; + int32_t sortcnt = yax_spritesortcnt[yax_globallev]; + const spritetype *spr; + + spritesortcnt = 0; + + for (i=0; isectnum; + + cf = -1; + if (gotthrough & MAXSPRITES) + cf = YAX_CEILING; // sprite got here through the ceiling of lower sector + else if (gotthrough & (MAXSPRITES<<1)) + cf = YAX_FLOOR; // sprite got here through the floor of upper sector + + if (cf != -1) + { + bunchnum = yax_getbunch(sectnum, cf); + if (yax_globallev != YAX_MAXDRAWS && curbunchnum != bunchnum) + continue; + + sectnum = yax_getneighborsect(spr->x, spr->y, sectnum, cf, NULL); + if (sectnum < 0) + continue; + } + + Bmemcpy(&tsprite[spritesortcnt], spr, sizeof(spritetype)); + spriteext[spritenum].tspr = &tsprite[spritesortcnt]; + tsprite[spritesortcnt].owner = spritenum; + + tsprite[spritesortcnt].sectnum = sectnum; // tweak sectnum! + spritesortcnt++; + } +} + +void yax_preparedrawrooms(void) +{ + if (rendmode!=0 || numyaxbunches==0) + return; + + g_nodraw = 1; + Bmemset(yax_spritesortcnt, 0, sizeof(yax_spritesortcnt)); } void yax_drawrooms(void (*ExtAnalyzeSprites)(void), int32_t horiz, int16_t sectnum) { - static uint8_t havebunch[2][YAX_MAXBUNCHES>>3]; - static int16_t bunches[2][YAX_MAXBUNCHES]; + static uint8_t havebunch[YAX_MAXBUNCHES>>3]; + static int16_t bunches[2][YAX_MAXBUNCHES], bestsec[2][YAX_MAXBUNCHES]; - int32_t i, j, k, cf, diddraw = 0; - int32_t bnchcnt, bnchnum[2] = {0,0}; - int16_t ourbunch[2] = {-1,-1}; + int32_t i, j, k, lev, cf; + int32_t bnchcnt, bnchnum[2] = {0,0}, maxlev[2]; + int16_t ourbunch[2] = {-1,-1}, osectnum=sectnum; + int32_t bnchbeg[YAX_MAXDRAWS][2], bnchend[YAX_MAXDRAWS][2]; + int32_t bbeg, numhere; - static uint8_t allgotsector[MAXSECTORS>>3]; - static int16_t opicnum[MAXSECTORS]; + // original (1st-draw) and accumulated ('per-level') gotsector bitmaps + static uint8_t ogotsector[MAXSECTORS>>3], lgotsector[MAXSECTORS>>3]; +// int32_t t; - if (rendmode == 4 || numyaxbunches==0) + if (rendmode!=0 || numyaxbunches==0) + { +#ifdef ENGINE_SCREENSHOT_DEBUG + engine_screenshot = 0; +#endif return; + } - Bmemset(&havebunch[0], 0, (numsectors+7)>>3); - Bmemset(&havebunch[1], 0, (numsectors+7)>>3); + // if we're here, there was just a drawrooms() call with g_nodraw=1 + + Bmemcpy(ogotsector, gotsector, (numsectors+7)>>3); if (sectnum >= 0) yax_getbunches(sectnum, &ourbunch[0], &ourbunch[1]); + Bmemset(&havebunch, 0, (numyaxbunches+7)>>3); - for (i=0; i>3]&(1<<(i&7)))) - continue; - - for (cf=0; cf<2; cf++) - { - j = yax_getbunch(i, cf); - if (j >= 0 && !(havebunch[cf][j>>3]&(1<<(j&7)))) - { - havebunch[cf][j>>3] |= (1<<(j&7)); - bunches[cf][bnchnum[cf]++] = j; - } - } - } - - Bmemcpy(allgotsector, gotsector, (numsectors+7)>>3); - + // first scan all bunches above, then all below... for (cf=0; cf<2; cf++) { - globalcf = cf; + yax_globalcf = cf; - qsort(bunches[cf], bnchnum[cf], sizeof(int16_t), (int(*)(const void *, const void *))&yax_cmpbunches); - - for (bnchcnt=0; bnchcnt 0) - break; - } - scansector_retfast = 0; - - if (k < 0) - continue; - } - - // tweak picnums vvv - for (i=headsectbunch[cf][j]; i!=-1; i=nextsectbunch[cf][i]) - { - if ((SECTORFLD(i,stat, cf)&(128+256))==0) - { - opicnum[i] = SECTORFLD(i,picnum, cf); - if (editstatus && showinvisibility) - SECTORFLD(i,picnum, cf) = MAXTILES-1; - else - SECTORFLD(i,picnum, cf) = 13; //FOF; - } - } - -// if (allgotsector[k>>3]&(1<<(k&7))) -// continue; - - drawrooms(globalposx,globalposy,globalposz,globalang,horiz,k+MAXSECTORS); // +MAXSECTORS: force - ExtAnalyzeSprites(); - drawmasks(); - - for (i=0; i<(numsectors+7)>>3; i++) - allgotsector[i] |= gotsector[i]; - - diddraw = 1; + sectnum = osectnum; + Bmemcpy(gotsector, ogotsector, (numsectors+7)>>3); } - } - if (diddraw) - { - drawrooms(globalposx,globalposy,globalposz,globalang,horiz,sectnum); - - if (editstatus) + for (lev=0; /*lev>3]&(1<<(i&7)))) + continue; + + j = yax_getbunch(i, cf); + if (j >= 0 && !(havebunch[j>>3]&(1<<(j&7)))) + { + havebunch[j>>3] |= (1<<(j&7)); + bunches[cf][bnchnum[cf]++] = j; + bnchend[lev][cf]++; + numhere++; + } + } + + if (numhere > 0) + { + // found bunches -- need to fake-draw + if (numhere > 1 && lev != YAX_MAXDRAWS-1) + Bmemset(lgotsector, 0, (numsectors+7)>>3); + + qsort(&bunches[cf][bbeg], numhere, sizeof(int16_t), + (int(*)(const void *, const void *))&yax_cmpbunches); + + for (bnchcnt=bbeg; bnchcnt < bbeg+numhere; bnchcnt++) { j = bunches[cf][bnchcnt]; // the actual bunchnum... - // restore picnums ^^^ - for (i=headsectbunch[cf][j]; i!=-1; i=nextsectbunch[cf][i]) - if ((SECTORFLD(i,stat, cf)&(128+256))==0) - SECTORFLD(i,picnum, cf) = opicnum[i]; +// t=getticks(); + k = yax_getbestsector(j, cf, ourbunch, sectnum); + bestsec[cf][bnchcnt] = k; + if (k < 0) + { +// initprintf("cf %d, lev %d: skipped bunch %d\n", cf, lev, j); + continue; + } + + if (ourbunch[cf]==j) + { + ourbunch[cf] = yax_getbunch(k, cf); + sectnum = k; + } + + if (lev != YAX_MAXDRAWS-1) + { + // +MAXSECTORS: force + drawrooms(globalposx,globalposy,globalposz,globalang,horiz,k+MAXSECTORS); + if (numhere > 1) + for (i=0; i<(numsectors+7)>>3; i++) + lgotsector[i] |= gotsector[i]; + +// yaxdebug("cf %d, lev %d: fake-drawn sec %d (bunch %d), %d dspr, %2d ms", +// cf, lev, k, j, yax_spritesortcnt[yax_globallev], getticks()-t); + } } + + if (numhere > 1 && lev != YAX_MAXDRAWS-1) + Bmemcpy(gotsector, lgotsector, (numsectors+7)>>3); + } + + if (numhere==0 || lev==YAX_MAXDRAWS-1) + { + // no new bunches or max level reached + maxlev[cf] = lev - (numhere==0); + break; + } } } + + yax_globalcf = -1; + + // now comes the real drawing! + g_nodraw = 0; + scansector_collectsprites = 0; + +#if 0 + begindrawing(); + for (i=0; i=0; lev--) + { + yax_globallev = YAX_MAXDRAWS + (-1 + 2*cf)*(lev+1); + + for (bnchcnt=bnchbeg[lev][cf]; bnchcnt= 0) + for (bnchcnt=bnchbeg[0][cf]; bnchcnt=0; z=nextspritesect[z]) { spr = &sprite[z]; if ((((spr->cstat&0x8000) == 0) || (showinvisibility)) && - (spr->xrepeat > 0) && (spr->yrepeat > 0) && - (spritesortcnt < MAXSPRITESONSCREEN)) + (spr->xrepeat > 0) && (spr->yrepeat > 0)) { xs = spr->x-globalposx; ys = spr->y-globalposy; if ((spr->cstat&48) || (xs*cosglobalang+ys*singlobalang > 0)) { - copybufbyte(spr,&tsprite[spritesortcnt],sizeof(spritetype)); - spriteext[z].tspr = (spritetype *)&tsprite[spritesortcnt]; - tsprite[spritesortcnt++].owner = z; +#ifdef YAX_ENABLE + if (g_nodraw==0) + { +#endif + if (spritesortcnt >= MAXSPRITESONSCREEN) + break; + + copybufbyte(spr,&tsprite[spritesortcnt],sizeof(spritetype)); + spriteext[z].tspr = (spritetype *)&tsprite[spritesortcnt]; + tsprite[spritesortcnt++].owner = z; +#ifdef YAX_ENABLE + } + else + { + sortcnt = &yax_spritesortcnt[yax_globallev]; + if (*sortcnt >= MAXSPRITESONSCREEN) + break; + + yax_tsprite[yax_globallev][*sortcnt] = z; + (*sortcnt)++; + + // now check whether the tsprite needs duplication into another level + if ((spr->cstat&48)==32) + continue; + + yax_getbunches(sectnum, &cb, &fb); + if (cb < 0 && fb < 0) + continue; + + spriteheightofs(z, &spheight, &spzofs); + + // TODO: get*zofslope? + if (cb>=0 && spr->z+spzofs-spheight < sector[sectnum].ceilingz) + { + sortcnt = &yax_spritesortcnt[yax_globallev-1]; + if (*sortcnt < MAXSPRITESONSCREEN) + { + yax_tsprite[yax_globallev-1][*sortcnt] = z|MAXSPRITES; + (*sortcnt)++; + } + } + if (fb>=0 && spr->z+spzofs > sector[sectnum].floorz) + { + sortcnt = &yax_spritesortcnt[yax_globallev+1]; + if (*sortcnt < MAXSPRITESONSCREEN) + { + yax_tsprite[yax_globallev+1][*sortcnt] = z|(MAXSPRITES<<1); + (*sortcnt)++; + } + } + } +#endif } } } @@ -2863,7 +3126,10 @@ static void wallscan(int32_t x1, int32_t x2, int16_t *uwal, int16_t *dwal, int32 char bad; int32_t i, u4, d4, z; #endif - +#ifdef YAX_ENABLE + if (g_nodraw) + return; +#endif if (x2 >= xdim) x2 = xdim-1; tsizx = tilesizx[globalpicnum]; @@ -3605,23 +3871,28 @@ static void drawalls(int32_t bunch) andwstat2 &= wallmost(dplc,z,sectnum,(uint8_t)1); } - if ((andwstat1&3) != 3) //draw ceilings +#ifdef YAX_ENABLE + if (!g_nodraw) +#endif { - if ((sec->ceilingstat&3) == 2) - grouscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,0); - else if ((sec->ceilingstat&1) == 0) - ceilscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum); - else - parascan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,0,bunch); - } - if ((andwstat2&12) != 12) //draw floors - { - if ((sec->floorstat&3) == 2) - grouscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,1); - else if ((sec->floorstat&1) == 0) - florscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum); - else - parascan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,1,bunch); + if ((andwstat1&3) != 3) //draw ceilings + { + if ((sec->ceilingstat&3) == 2) + grouscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,0); + else if ((sec->ceilingstat&1) == 0) + ceilscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum); + else + parascan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,0,bunch); + } + if ((andwstat2&12) != 12) //draw floors + { + if ((sec->floorstat&3) == 2) + grouscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,1); + else if ((sec->floorstat&1) == 0) + florscan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum); + else + parascan(xb1[bunchfirst[bunch]],xb2[bunchlast[bunch]],sectnum,1,bunch); + } } //DRAW WALLS SECTION! @@ -3929,7 +4200,8 @@ static void drawalls(int32_t bunch) if (gotswall == 0) { gotswall = 1; prepwall(z,wal); } wallscan(x1,x2,uplc,dplc,swall,lwall); #ifdef YAX_ENABLE - if ((wal->cstat&YAX_NEXTWALLBIT(YAX_FLOOR)) && globalposz > sec->floorz) + // TODO: slopes? + if (globalposz > sec->floorz && (x = yax_getnextwall(wallnum, YAX_FLOOR)) >= 0 && wall[x].nextwall>=0) { for (x=x1; x<=x2; x++) if (dplc[x] > umost[x] && umost[x] <= dmost[x]) @@ -3938,7 +4210,7 @@ static void drawalls(int32_t bunch) if (umost[x] > dmost[x]) numhits--; } } - else if ((wal->cstat&YAX_NEXTWALLBIT(YAX_CEILING)) && globalposz < sec->ceilingz) + else if (globalposz < sec->ceilingz && (x = yax_getnextwall(wallnum, YAX_CEILING)) >= 0 && wall[x].nextwall>=0) { for (x=x1; x<=x2; x++) if (uplc[x] < dmost[x] && umost[x] <= dmost[x]) @@ -3962,6 +4234,17 @@ static void drawalls(int32_t bunch) if (nextsectnum < 0) searchstat = 0; else searchstat = 4; } } + +#ifdef ENGINE_SCREENSHOT_DEBUG + if (engine_screenshot && !g_nodraw) + { + static char fn[BMAX_PATH]; + + Bsprintf(fn, "engshot%04d.png", engine_screenshot); + screencapture(fn, 0, "BUILD engine"); + engine_screenshot++; + } +#endif } } @@ -7308,7 +7591,7 @@ void drawmasks(void) } else if ((tspriteptr[i]->cstat&48) == 0) { - killsprite: +killsprite: spritesortcnt--; //Delete face sprite if on wrong side! if (i == spritesortcnt) continue; tspriteptr[i] = tspriteptr[spritesortcnt]; @@ -10113,15 +10396,15 @@ restart_grand: return 0; } + // 1st, 2nd, ... ceil/floor hit + // hitinfo->hitsect is >=0 because if oldhitsect's init and check above + if (SECTORFLD(hitinfo->hitsect,stat, hitscan_hitsectcf)&yax_waltosecmask(dawalclipmask)) + return 0; + i = yax_getneighborsect(hitinfo->pos.x, hitinfo->pos.y, hitinfo->hitsect, hitscan_hitsectcf, NULL); if (i >= 0) { - // 1st, 2nd, ... ceil/floor hit - // hitinfo->hitsect is >=0 because if oldhitsect's init and check above - - // TODO: check against cstat - Bmemcpy(&newsv, &hitinfo->pos, sizeof(vec3_t)); sectnum = i; sv = &newsv; @@ -11212,6 +11495,20 @@ void updatesectorz(int32_t x, int32_t y, int32_t z, int16_t *sectnum) getzsofslope(*sectnum, x, y, &cz, &fz); if ((z >= cz) && (z <= fz)) if (inside(x,y,*sectnum) != 0) return; +#ifdef YAX_ENABLE + if (z < cz) + { + i = yax_getneighborsect(x, y, *sectnum, YAX_CEILING, NULL); + if (i >= 0 && z >= getceilzofslope(i, x, y)) + { *sectnum = i; return; } + } + if (z > fz) + { + i = yax_getneighborsect(x, y, *sectnum, YAX_FLOOR, NULL); + if (i >= 0 && z <= getflorzofslope(i, x, y)) + { *sectnum = i; return; } + } +#endif wal = &wall[sector[*sectnum].wallptr]; j = sector[*sectnum].wallnum; @@ -11220,6 +11517,7 @@ void updatesectorz(int32_t x, int32_t y, int32_t z, int16_t *sectnum) i = wal->nextsector; if (i >= 0) { +// YAX: TODO: check neighboring sectors here too? getzsofslope(i, x, y, &cz, &fz); if ((z >= cz) && (z <= fz)) if (inside(x,y,(int16_t)i) == 1) @@ -11661,7 +11959,7 @@ restart_grand: #ifdef YAX_ENABLE if (numyaxbunches > 0) { - int32_t dasecclipmask = (dawalclipmask&1)<<9; // blocking: walstat&1 --> secstat&512 + int32_t dasecclipmask = yax_waltosecmask(dawalclipmask); int16_t cb, fb, didchange; yax_getbunches(sectnum, &cb, &fb); @@ -13417,11 +13715,16 @@ static void drawscreen_drawwall(int32_t i, int32_t posxe, int32_t posye, int32_t if (!m32_sideview && (j >= 0) && (i > j)) return; } -#ifdef YAX_ENABLE +#if 1 +//def YAX_ENABLE if ((graywallbitmap[i>>3] & (1<<(i&7))) || (j>=0 && (graywallbitmap[j>>3] & (1<<(j&7))))) { - if (!m32_sideview) +#ifdef YAX_ENABLE + // yax'ed grayed out walls are always cleared from the overhead map. + // normal walls cleared out due to editorzrange are displayed, though + if (!m32_sideview && ((wall[i].cstat&YAX_NEXTWALLBITS) || (j>=0 && wall[j].cstat&YAX_NEXTWALLBITS))) return; +#endif col = 8; } else diff --git a/polymer/eduke32/build/src/engine_priv.h b/polymer/eduke32/build/src/engine_priv.h index 5ddadbb58..468984292 100644 --- a/polymer/eduke32/build/src/engine_priv.h +++ b/polymer/eduke32/build/src/engine_priv.h @@ -8,6 +8,10 @@ #define MAXNODESPERLINE 42 //Warning: This depends on MAXYSAVES & MAXYDIM! #define MAXCLIPDIST 1024 +#ifdef YAX_ENABLE +# define YAX_MAXDRAWS 4 +#endif + extern uint8_t **basepaltableptr; extern uint8_t basepalcount; extern uint8_t curbasepal; diff --git a/polymer/eduke32/build/src/sdlayer.c b/polymer/eduke32/build/src/sdlayer.c index ee90cef96..2b8852e23 100644 --- a/polymer/eduke32/build/src/sdlayer.c +++ b/polymer/eduke32/build/src/sdlayer.c @@ -1586,6 +1586,13 @@ int32_t handleevents(void) } else { +#ifdef __linux + // The pause key generates a release event right after + // the pressing one on linux. As a result, it gets unseen + // by the game most of the time. + if (code == 0x59) // pause + break; +#endif SetKey(code, 0); if (keypresscallback) keypresscallback(code, 0); @@ -1668,6 +1675,10 @@ int32_t handleevents(void) } else { +#ifdef __linux + if (code == 0x59) // pause + break; +#endif SetKey(code, 0); if (keypresscallback) keypresscallback(code, 0); diff --git a/polymer/eduke32/samples/a.m32 b/polymer/eduke32/samples/a.m32 index 84db81d7c..0393629fa 100644 --- a/polymer/eduke32/samples/a.m32 +++ b/polymer/eduke32/samples/a.m32 @@ -115,6 +115,56 @@ defstate printlights print "--ENDPRLIGHTS--" ends +defstate insertlights + var sectnum + + set k 0 + for i activelights + { + insertsprite light[i].sector + + // I is the inserted sprites' index now + set .picnum 1 + + set .x light[i].x + set .y light[i].y + set .z light[i].z + + set .hitag light[i].range + set .xvel light[i].r + set .yvel light[i].g + set .zvel light[i].b + + set .extra light[i].horiz + + set .xoffset light[i].minshade + set .yoffset light[i].maxshade + + set .owner light[i].tilenum + + // now those that are calculated + ifge light[i].priority 4 or .cstat 512 + ifge light[i].priority 2 or .cstat 2 + + ife light[i].radius 0 + { + set .lotag 49 + } + else + { + set .lotag 50 + set j light[i].radius, shiftr j 1, sub j 128, inv j + clamp j -128 127 + set .shade j + } + + add k 1 + } + + qsprintf TQUOTE "* Inserted %d SE sprites based on active lights." k + print TQUOTE +ends + // convenient polymer SE light manipulation with keypad keys // when aiming at light SE (49 or 50): // KP 4,5,6,8: angle/horiz diff --git a/polymer/eduke32/source/actors.c b/polymer/eduke32/source/actors.c index f677a2865..9326a994c 100644 --- a/polymer/eduke32/source/actors.c +++ b/polymer/eduke32/source/actors.c @@ -409,7 +409,14 @@ int32_t A_MoveSprite(int32_t spritenum, const vec3_t *change, uint32_t cliptype) && (osectnum == dasectnum || cansee(oldx, oldy, spr->z - bg, osectnum, spr->x, spr->y, daz - bg, dasectnum))*/ ) + { spr->z = daz; +#ifdef YAX_ENABLE + if (change->z && yax_getbunch(spr->sectnum, !!change->z)>=0) + if ((SECTORFLD(spr->sectnum,stat, !!change->z)&yax_waltosecmask(cliptype))==0) + setspritez(spritenum, (vec3_t *)spr); +#endif + } else if (retval == 0) retval = 16384+dasectnum; if (retval == (16384+dasectnum)) diff --git a/polymer/eduke32/source/astub.c b/polymer/eduke32/source/astub.c index 7ad3a739e..0b8989a6c 100644 --- a/polymer/eduke32/source/astub.c +++ b/polymer/eduke32/source/astub.c @@ -298,7 +298,8 @@ static void drawgradient(void) static void message_common1(const char *tmpstr) { - Bstrcpy(getmessage,tmpstr); + Bstrncpy(getmessage,tmpstr,sizeof(getmessage)); + getmessage[sizeof(getmessage)-1] = 0; getmessageleng = Bstrlen(getmessage); getmessagetimeoff = totalclock + 120*2 + getmessageleng*(120/30); @@ -1011,8 +1012,8 @@ static uint64_t taglab_nolink_SEs = (1ull<<10)|(1ull<<27)|(1ull<<28)|(1ull<<29)| // 16: yvel // 32: zvel // 64: owner -// The caller is responsible for checking bounds (usually tag>0), because -// this function is supposed to say something about the potential of a tag +// This function is only supposed to say something about the potential of a tag: +// it will also 'say yes' if a particular tag is zero. int32_t taglab_linktags(int32_t spritep, int32_t num) { int32_t picnum; @@ -4360,12 +4361,13 @@ static void getnumberptr256(const char *namestart, void *num, int32_t bytes, int if (handleevents()) quitevent = 0; + yax_preparedrawrooms(); drawrooms(pos.x,pos.y,pos.z,ang,horiz,cursectnum); -#ifdef YAX_ENABLE yax_drawrooms(ExtAnalyzeSprites, horiz, cursectnum); -#endif + ExtAnalyzeSprites(); drawmasks(); + #ifdef POLYMER if (rendmode == 4 && searchit == 2) { @@ -4569,12 +4571,14 @@ ENDFOR1: if (PRESSED_KEYSC(PGDN)) sprite[linebegspr].pal -= (sprite[linebegspr].pal>0); + + yax_preparedrawrooms(); drawrooms(pos.x,pos.y,pos.z,ang,horiz,cursectnum); -#ifdef YAX_ENABLE yax_drawrooms(ExtAnalyzeSprites, horiz, cursectnum); -#endif + ExtAnalyzeSprites(); drawmasks(); + #ifdef POLYMER if (rendmode == 4 && searchit == 2) { @@ -4830,6 +4834,16 @@ static void mouseaction_movesprites(int32_t *sumxvect, int32_t *sumyvect, int32_ } } +static int32_t addtobyte(int8_t *byte, int32_t num) +{ + int32_t onum = *byte, clamped=0; + if (onum + num != (int8_t)(onum + num)) + clamped = 1; + if (!clamped) + *byte = (onum + num); + return clamped; +} + static void Keys3d(void) { int32_t i = 0, changedir,tsign; // ,count,nexti @@ -5200,19 +5214,22 @@ static void Keys3d(void) ShowFileText("sthelp.hlp", 1); } + // . Search & fix panning to the right (3D) if (AIMING_AT_WALL_OR_MASK && PRESSED_KEYSC(PERIOD)) { - int32_t naligned=AutoAlignWalls(searchwall, eitherCTRL, 0); - message("Auto-aligned %d wall%s%s based on wall %d", naligned, - naligned==1?"":"s", eitherCTRL?" recursively":"", searchwall); + int32_t naligned=AutoAlignWalls(searchwall, eitherCTRL|((!eitherSHIFT)<<1)|eitherALT<<2, 0); + message("Aligned %d wall%s based on wall %d%s%s%s", naligned, + naligned==1?"":"s", searchwall, + eitherCTRL?", recursing nextwalls":"", + !eitherSHIFT?", iterating point2s":"", + eitherALT?", aligning xrepeats":""); } - tsign = 0; tsign -= PRESSED_KEYSC(COMMA); tsign += PRESSED_KEYSC(PERIOD); - if (tsign) // , . Search & fix panning to the left/right (3D) + if (tsign) { if (AIMING_AT_SPRITE) { @@ -5426,18 +5443,29 @@ static void Keys3d(void) message("Sprite %d hitscan sensitivity bit %s", searchwall, ONOFF(sprite[searchwall].cstat&256)); asksave = 1; } - else + else if (AIMING_AT_WALL_OR_MASK || AIMING_AT_CEILING_OR_FLOOR) { - wall[searchwall].cstat ^= 64; - - if (wall[searchwall].nextwall >= 0 && !eitherSHIFT) +#ifdef YAX_ENABLE + if (AIMING_AT_CEILING_OR_FLOOR && yax_getbunch(searchsector, AIMING_AT_FLOOR)>=0) { - NEXTWALL(searchwall).cstat &= ~64; - NEXTWALL(searchwall).cstat |= (wall[searchwall].cstat&64); + SECTORFLD(searchsector,stat, AIMING_AT_FLOOR) ^= 2048; + message("Sector %d's %s hitscan sensitivity bit %s", searchsector, typestr[searchstat], + ONOFF(SECTORFLD(searchsector,stat, AIMING_AT_FLOOR)&2048)); + asksave = 1; } - message("Wall %d hitscan sensitivity bit %s", searchwall, ONOFF(wall[searchwall].cstat&64)); + else +#endif + { + wall[searchwall].cstat ^= 64; - asksave = 1; + if (wall[searchwall].nextwall >= 0 && !eitherSHIFT) + { + NEXTWALL(searchwall).cstat &= ~64; + NEXTWALL(searchwall).cstat |= (wall[searchwall].cstat&64); + } + message("Wall %d hitscan sensitivity bit %s", searchwall, ONOFF(wall[searchwall].cstat&64)); + asksave = 1; + } } } } @@ -5524,6 +5552,8 @@ static void Keys3d(void) } else // if !eitherALT { + int32_t clamped=0; + k = (highlightsectorcnt>0 && (hlsectorbitmap[searchsector>>3]&(1<<(searchsector&7)))); tsign *= (1+3*eitherCTRL); @@ -5531,8 +5561,9 @@ static void Keys3d(void) { if (ASSERT_AIMING) { - AIMED_CF_SEL(shade) += tsign; - message("%s %d shade %d", Typestr[searchstat], i, AIMED_CF_SEL(shade)); + clamped = addtobyte(&AIMED_CF_SEL(shade), tsign); + message("%s %d shade %d%s", Typestr[searchstat], i, AIMED_CF_SEL(shade), + clamped ? " (clamped)":""); } } else @@ -5542,18 +5573,19 @@ static void Keys3d(void) dasector = highlightsector[i]; // sector shade - sector[dasector].ceilingshade += tsign; - sector[dasector].floorshade += tsign; + clamped |= addtobyte(§or[dasector].ceilingshade, tsign); + clamped |= addtobyte(§or[dasector].floorshade, tsign); // wall shade for (WALLS_OF_SECTOR(dasector, j)) - wall[j].shade += tsign; + clamped |= addtobyte(&wall[j].shade, tsign); // sprite shade for (j=headspritesect[dasector]; j!=-1; j=nextspritesect[j]) - sprite[j].shade += tsign; + clamped |= addtobyte(&sprite[j].shade, tsign); } - message("Highlighted sector shade changed by %d", tsign); + message("Highlighted sector shade changed by %d%s", tsign, + clamped?" (some objects' shade clamped)":""); } asksave = 1; } @@ -5826,44 +5858,41 @@ static void Keys3d(void) } else { - k = 0; - if (highlightcnt > 0) - for (i=0; i>3]&(1<<(searchwall&7))); + + tsign *= (updownunits << ((eitherCTRL && mouseaction)*3)); + + for (i=0; i= 0) + { + int16_t cb, fb; + yax_getbunches(sprite[sp].sectnum, &cb, &fb); + if (cb >= 0 || fb >= 0) + setspritez(sp, (vec3_t *)&sprite[sp]); + } +#endif + if (k==0) + { + silentmessage("Sprite %d z = %d", searchwall, sprite[searchwall].z); break; } - - if (k == 0) - { - sprite[searchwall].z += tsign * (updownunits << ((eitherCTRL && mouseaction)*3)); - if (!spnoclip) - { - spriteoncfz(searchwall, &cz, &fz); - inpclamp(&sprite[searchwall].z, cz, fz); } - silentmessage("Sprite %d z = %d", searchwall, sprite[searchwall].z); - - } - else - { - for (i=0; i= 0) - for (i=0; i0) { - int32_t zsign=0, bestzdiff=INT32_MAX, hiz=0, loz=0, bottomp=0; + int32_t zsign=0; if (PRESSED_KEYSC(PGDN) || (eitherCTRL && PRESSED_KEYSC(DOWN))) zsign = 1; @@ -7500,9 +7526,11 @@ static void Keys2d(void) if (zsign) { + int32_t bestzdiff=INT32_MAX, hiz=0, loz=0, bottomp=0; + for (i=0; ix, s->y, ud.cameraang, smoothratio); #endif - + yax_preparedrawrooms(); drawrooms(s->x,s->y,s->z-(4<<8),ud.cameraang,s->yvel,s->sectnum); - + g_yax_smoothratio = smoothratio; + yax_drawrooms(G_AnalyzeSprites, s->yvel, s->sectnum); G_DoSpriteAnimations(s->x,s->y,ud.cameraang,smoothratio); - drawmasks(); } else @@ -3418,8 +3418,14 @@ void G_DrawRooms(int32_t snum, int32_t smoothratio) if (ud.camerasect >= 0) { getzsofslope(ud.camerasect,ud.camera.x,ud.camera.y,&cz,&fz); - if (ud.camera.z < cz+(4<<8)) ud.camera.z = cz+(4<<8); - if (ud.camera.z > fz-(4<<8)) ud.camera.z = fz-(4<<8); +#ifdef YAX_ENABLE + if (yax_getbunch(ud.camerasect, YAX_CEILING) < 0) +#endif + if (ud.camera.z < cz+(4<<8)) ud.camera.z = cz+(4<<8); +#ifdef YAX_ENABLE + if (yax_getbunch(ud.camerasect, YAX_FLOOR) < 0) +#endif + if (ud.camera.z > fz-(4<<8)) ud.camera.z = fz-(4<<8); } if (ud.camerahoriz > HORIZ_MAX) ud.camerahoriz = HORIZ_MAX; @@ -3470,11 +3476,11 @@ void G_DrawRooms(int32_t snum, int32_t smoothratio) polymer_setanimatesprites(G_DoSpriteAnimations, ud.camera.x,ud.camera.y,ud.cameraang,smoothratio); #endif + yax_preparedrawrooms(); drawrooms(ud.camera.x,ud.camera.y,ud.camera.z,ud.cameraang,ud.camerahoriz,ud.camerasect); -#ifdef YAX_ENABLE g_yax_smoothratio = smoothratio; yax_drawrooms(G_AnalyzeSprites, ud.camerahoriz, ud.camerasect); -#endif + // dupe the sprites touching the portal to the other sector if (ror_sprite != -1) @@ -7242,7 +7248,8 @@ void G_HandleLocalKeys(void) switch (ud.recstat) { case 0: - G_OpenDemoWrite(); + if (SHIFTS_IS_PRESSED) + G_OpenDemoWrite(); break; case 1: G_CloseDemoWrite(); diff --git a/polymer/eduke32/source/gameexec.c b/polymer/eduke32/source/gameexec.c index cea089ae9..ab0f910da 100644 --- a/polymer/eduke32/source/gameexec.c +++ b/polymer/eduke32/source/gameexec.c @@ -310,7 +310,9 @@ void A_Fall(int32_t iActor) { spritetype *s = &sprite[iActor]; int32_t hz,lz,c = g_spriteGravity; - +#ifdef YAX_ENABLE + int16_t fbunch; +#endif if (G_CheckForSpaceFloor(s->sectnum)) c = 0; else @@ -334,12 +336,27 @@ void A_Fall(int32_t iActor) actor[iActor].floorz = sector[s->sectnum].floorz; } - if (s->z < actor[iActor].floorz-(ZOFFSET)) +#ifdef YAX_ENABLE + if (sector[s->sectnum].floorstat&512) + fbunch = -1; + else + fbunch = yax_getbunch(s->sectnum, YAX_FLOOR); +#endif + if (s->z < actor[iActor].floorz-(ZOFFSET) +#ifdef YAX_ENABLE + || (fbunch >= 0) +#endif + ) { if (sector[s->sectnum].lotag == 2 && s->zvel > 3122) s->zvel = 3144; s->z += s->zvel = min(6144, s->zvel+c); } +#ifdef YAX_ENABLE + if (fbunch >= 0) + setspritez(iActor, (vec3_t *)s); + if (fbunch < 0) +#endif if (s->z >= actor[iActor].floorz-(ZOFFSET)) { s->z = actor[iActor].floorz - ZOFFSET; @@ -1106,7 +1123,12 @@ skip_check: if (vm.g_sp->z < (actor[vm.g_i].floorz-ZOFFSET)) { vm.g_sp->z += vm.g_sp->zvel = min(6144, vm.g_sp->zvel+j); - +#ifdef YAX_ENABLE + j = yax_getbunch(vm.g_sp->sectnum, YAX_FLOOR); + if (j >= 0 && (sector[vm.g_sp->sectnum].floorstat&512)==0) + setspritez(vm.g_i, (vec3_t *)vm.g_sp); + else +#endif if (vm.g_sp->z > (actor[vm.g_i].floorz - ZOFFSET)) vm.g_sp->z = (actor[vm.g_i].floorz - ZOFFSET); continue; diff --git a/polymer/eduke32/source/m32def.c b/polymer/eduke32/source/m32def.c index 183cdda7e..8794a98d3 100644 --- a/polymer/eduke32/source/m32def.c +++ b/polymer/eduke32/source/m32def.c @@ -189,16 +189,6 @@ const char *keyw[] = "jump", "{", "}", -#if 0 - "setsector", - "getsector", - "setwall", - "getwall", - "setsprite", - "getsprite", - "gettspr", - "settspr", -#endif "gamearray", "setarray", "getarraysize", @@ -503,7 +493,29 @@ const memberlabel_t SpriteLabels[]= { "extra", SPRITE_EXTRA, 0, 0, 0 }, // aliases { "filler", SPRITE_DETAIL, 1, 0, 0 }, + { "", -1, 0, 0, 0 } // END OF LIST +}; +const memberlabel_t LightLabels[]= +{ + { "x", LIGHT_X, 0, -BXY_MAX, BXY_MAX }, + { "y", LIGHT_Y, 0, -BXY_MAX, BXY_MAX }, + { "z", LIGHT_Z, 0, 0, 0 }, + { "horiz", LIGHT_HORIZ, 0, 0, 0 }, + { "range", LIGHT_RANGE, 0, 0, 0 }, + { "angle", LIGHT_ANGLE, 0, 0, 0 }, + { "faderadius", LIGHT_FADERADIUS, 0, 0, 0 }, + { "radius", LIGHT_RADIUS, 0, 0, 0 }, + { "sector", LIGHT_SECTOR, 0, 0, 0 }, + { "r", LIGHT_R, 0, 0, 255 }, + { "g", LIGHT_G, 0, 0, 255 }, + { "b", LIGHT_B, 0, 0, 255 }, + { "priority", LIGHT_PRIORITY, 0, 0, PR_MAXLIGHTPRIORITY-1 }, + { "tilenum", LIGHT_TILENUM, 0, 0, MAXTILES-1 }, + { "minshade", LIGHT_MINSHADE, 0, -128, 127 }, + { "maxshade", LIGHT_MAXSHADE, 0, -128, 127 }, +// + { "active", LIGHT_ACTIVE, 0, 0, 1 }, { "", -1, 0, 0, 0 } // END OF LIST }; @@ -512,6 +524,7 @@ const tokenmap_t iter_tokens[] = { "allsprites", ITER_ALLSPRITES }, { "allsectors", ITER_ALLSECTORS }, { "allwalls", ITER_ALLWALLS }, + { "activelights", ITER_ACTIVELIGHTS }, { "selsprites", ITER_SELSPRITES }, { "selsectors", ITER_SELSECTORS }, { "selwalls", ITER_SELWALLS }, @@ -523,6 +536,7 @@ const tokenmap_t iter_tokens[] = // vvv alternatives go here vvv { "selspr", ITER_SELSPRITES }, { "selsec", ITER_SELSECTORS }, + { "lights", ITER_ACTIVELIGHTS }, { "sprofsec", ITER_SPRITESOFSECTOR }, { "walofsec", ITER_WALLSOFSECTOR }, { "", -1 } // END OF LIST @@ -541,6 +555,7 @@ static hashtable_t h_iter = { ITER_END, NULL }; static hashtable_t h_sector = { SECTOR_END>>1, NULL }; static hashtable_t h_wall = { WALL_END>>1, NULL }; static hashtable_t h_sprite = { SPRITE_END>>1, NULL }; +static hashtable_t h_light = { SPRITE_END>>1, NULL }; static void C_InitHashes() @@ -574,6 +589,10 @@ static void C_InitHashes() hash_add(&h_sprite,SpriteLabels[i].name,i, 0); // hash_add(&h_sprite,"filler", SPRITE_DETAIL, 0); + hash_init(&h_light); + for (i=0; LightLabels[i].lId >=0; i++) + hash_add(&h_light,LightLabels[i].name,i, 0); + hash_init(&h_iter); for (i=0; iter_tokens[i].val >=0; i++) hash_add(&h_iter, iter_tokens[i].token, iter_tokens[i].val, 0); @@ -926,7 +945,7 @@ static int32_t parse_integer_literal(int32_t *num) { long lnum; errno = 0; - lnum = strtol(textptr, NULL, 10); + lnum = Bstrtol(textptr, NULL, 10); if (errno || (sizeof(long)>4 && (lnumINT_MAX))) { C_CUSTOMERROR("integer literal exceeds bitwidth."); @@ -1084,6 +1103,9 @@ static void C_GetNextVarType(int32_t type) if (*textptr == '[') //read of array as a gamevar { int32_t lLabelID = -1, aridx; +#ifdef POLYMER + int32_t lightp = 0; +#endif textptr++; flags |= M32_FLAG_ARRAY; @@ -1100,12 +1122,18 @@ static void C_GetNextVarType(int32_t type) { id = GetGamevarID(tlabel, 0); - if (id < 0 || id >= 4) + if (id < 0 || id >= 5) { - C_CUSTOMERROR("symbol `%s' is neither an array name nor one of `(t)sprite', `sector' or `wall'.", tlabel); + C_CUSTOMERROR("symbol `%s' is neither an array name nor one of `(t)sprite', `sector', `wall' or `light'.", tlabel); return; } + if (id==4) + { + id = 3; // smuggle lights into tspr + lightp = 1; + } + flags &= ~M32_FLAG_ARRAY; // not an array flags |= M32_FLAG_STRUCT; } @@ -1175,7 +1203,9 @@ static void C_GetNextVarType(int32_t type) if (*textptr != '.') { - static const char *types[4] = {"sprite","sector","wall","tsprite"}; + const char *types[4] = {"sprite","sector","wall","tsprite"}; + if (lightp) + types[3] = "light"; C_CUSTOMERROR("syntax error. Expected `.