From 4861d1fc3d6c4cdd87ffb2da80e2eb74384d8e34 Mon Sep 17 00:00:00 2001 From: terminx Date: Sun, 18 Nov 2018 18:13:48 +0000 Subject: [PATCH] WIP wall texture rotation bit git-svn-id: https://svn.eduke32.com/eduke32@7226 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/build/include/build.h | 2 ++ source/build/include/buildtypes.h | 17 +++++++++++ source/build/src/build.cpp | 47 ++++++++++++++++--------------- source/build/src/engine.cpp | 44 +++++++++++++++++++++++------ source/build/src/engine_priv.h | 8 +----- source/build/src/polymost.cpp | 8 +++--- source/build/src/tiles.cpp | 37 ++++++++++++++++++++++-- source/duke3d/src/astub.cpp | 29 +++++++++++++------ source/duke3d/src/macros.h | 12 -------- 9 files changed, 139 insertions(+), 65 deletions(-) diff --git a/source/build/include/build.h b/source/build/include/build.h index 4906d8896..9f90e36dd 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -832,6 +832,8 @@ typedef struct { uint8_t sf; // anim. speed and flags } picanm_t; EXTERN picanm_t picanm[MAXTILES]; +typedef struct { int16_t newtile; int16_t owner; } rottile_t; +EXTERN rottile_t rottile[MAXTILES]; EXTERN intptr_t waloff[MAXTILES]; // stores pointers to cache -- SA EXTERN int32_t windowpos, windowx, windowy; diff --git a/source/build/include/buildtypes.h b/source/build/include/buildtypes.h index 8264fa6ee..fafea2146 100644 --- a/source/build/include/buildtypes.h +++ b/source/build/include/buildtypes.h @@ -135,6 +135,23 @@ enum CSTAT_SPRITE_ALIGNMENT_MASK = 1u<<4u | 1u<<5u, }; + +enum +{ + CSTAT_WALL_BLOCK = 1u, + CSTAT_WALL_BOTTOM_SWAP = 1u<<1u, + CSTAT_WALL_ALIGN_BOTTOM = 1u<<2u, + CSTAT_WALL_XFLIP = 1u<<3u, + CSTAT_WALL_MASKED = 1u<<4u, + CSTAT_WALL_1WAY = 1u<<5u, + CSTAT_WALL_BLOCK_HITSCAN = 1u<<6u, + CSTAT_WALL_TRANSLUCENT = 1u<<7u, + CSTAT_WALL_YFLIP = 1u<<8u, + CSTAT_WALL_TRANS_FLIP = 1u<<9u, + CSTAT_WALL_YAX_UPWALL = 1u<<10u, + CSTAT_WALL_YAX_DOWNWALL = 1u<<11u, + CSTAT_WALL_ROTATE_90 = 1u<<12u, +}; #endif //44 bytes diff --git a/source/build/src/build.cpp b/source/build/src/build.cpp index 7e8a7b2e1..af9f289b6 100644 --- a/source/build/src/build.cpp +++ b/source/build/src/build.cpp @@ -10814,17 +10814,16 @@ static int32_t AlignGetWall(int32_t botswap, int32_t w) // 32: use special logic for 'bottom-swapped' walls int32_t AutoAlignWalls(int32_t w0, uint32_t flags, int32_t nrecurs) { - static int32_t numaligned, wall0, cstat0; + static int numaligned, wall0; + static int32_t cstat0; static uint32_t lenrepquot; - const int32_t totheleft = flags&16; - const int32_t botswap = flags&32; - - int32_t z0 = GetWallBaseZ(w0); - int32_t w1 = totheleft ? lastwall(w0) : wall[w0].point2; + int const totheleft = flags & 16; + int const botswap = flags & 32; + int32_t z0 = GetWallBaseZ(w0); + int32_t w1 = totheleft ? lastwall(w0) : wall[w0].point2; int32_t w0b = AlignGetWall(botswap, w0); - const int32_t tilenum = wall[w0b].picnum; if (nrecurs == 0) { @@ -10837,10 +10836,13 @@ int32_t AutoAlignWalls(int32_t w0, uint32_t flags, int32_t nrecurs) cstat0 = wall[w0b].cstat & ALIGN_WALLS_CSTAT_MASK; // top/bottom orientation; x/y-flip } + int const tilenum = wall[w0b].picnum; + int const rotated = wall[w0b].cstat & CSTAT_WALL_ROTATE_90; + //loop through walls at this vertex in point2 order - while (1) + do { - int32_t w1b = AlignGetWall(botswap, w1); + int const w1b = AlignGetWall(botswap, w1); //break if this wall would connect us in a loop if (visited[w1>>3]&(1<<(w1&7))) @@ -10851,15 +10853,14 @@ int32_t AutoAlignWalls(int32_t w0, uint32_t flags, int32_t nrecurs) #ifdef YAX_ENABLE if (flags&8) { - int32_t cf, ynw; - - for (cf=0; cf<2; cf++) + for (int cf=0; cf<2; cf++) { - ynw = yax_getnextwall(w0, cf); + int const ynw = yax_getnextwall(w0, cf); - if (ynw >= 0 && wall[ynw].picnum==tilenum && (visited[ynw>>3]&(1<<(ynw&7)))==0) + if (ynw >= 0 && wall[ynw].picnum == tilenum && ((wall[ynw].cstat & CSTAT_WALL_ROTATE_90) == rotated) + && (visited[ynw >> 3] & (1 << (ynw & 7))) == 0) { - wall[ynw].xrepeat = wall[w0].xrepeat; + wall[ynw].xrepeat = wall[w0].xrepeat; wall[ynw].xpanning = wall[w0].xpanning; AlignWalls(w0,z0, ynw,GetWallBaseZ(ynw), 0); // initial vertical alignment } @@ -10871,25 +10872,26 @@ int32_t AutoAlignWalls(int32_t w0, uint32_t flags, int32_t nrecurs) if (wall[w1].nextwall == w0) break; - if (wall[w1b].picnum == tilenum) + if (wall[w1b].picnum == tilenum && ((wall[w1b].cstat & CSTAT_WALL_ROTATE_90) == rotated)) { - int32_t visible = 1; - const int32_t nextsec = wall[w1].nextsector; + bool visible = true; + int const nextsec = wall[w1].nextsector; if (nextsec >= 0) { - int32_t cz,fz, czn,fzn; - const int32_t sectnum = NEXTWALL(w1).nextsector; + int const sectnum = NEXTWALL(w1).nextsector; //ignore two sided walls that have no visible face // TODO: can be more precise (i.e. taking into account the wall face) // ... needs to be factored out from some engine code maybe... // as is the whole "z base" determination. + + int32_t cz,fz, czn,fzn; getzsofslope(sectnum, wall[w1].x,wall[w1].y, &cz, &fz); getzsofslope(nextsec, wall[w1].x,wall[w1].y, &czn, &fzn); if (czn <= cz && fzn >= fz) - visible = 0; + visible = false; } if (visible) @@ -10898,6 +10900,7 @@ int32_t AutoAlignWalls(int32_t w0, uint32_t flags, int32_t nrecurs) if ((flags&4) && w1!=wall0) fixxrepeat(w1, lenrepquot); + AlignWalls_(tilenum,z0, z1, 1, w0b, w0, w1b, w1); wall[w1b].cstat &= ~ALIGN_WALLS_CSTAT_MASK; wall[w1b].cstat |= cstat0; @@ -10924,7 +10927,7 @@ int32_t AutoAlignWalls(int32_t w0, uint32_t flags, int32_t nrecurs) if (wall[w1].nextwall < 0) break; w1 = totheleft ? lastwall(wall[w1].nextwall) : NEXTWALL(w1).point2; - } + } while (1); return numaligned; } diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 4a8714dab..dd08e37ce 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -1614,6 +1614,17 @@ static int get_screen_coords(const vec2_t &p1, const vec2_t &p2, return 1; } +int lastUnusedTile = MAXUSERTILES-1; + +static inline int findUnusedTile(void) +{ + for (; lastUnusedTile > 0; --lastUnusedTile) + if (tilesiz[lastUnusedTile].x * tilesiz[lastUnusedTile].y == 0) + return lastUnusedTile; + + return MAXTILES; +} + // // scansector (internal) // @@ -2267,16 +2278,8 @@ static void prepwall(int32_t z, const uwalltype *wal) // // animateoffs (internal) // -#ifdef DEBUGGINGAIDS -int32_t animateoffs(int const tilenum, int fakevar) -#else int32_t animateoffs(int const tilenum) -#endif { -#ifdef DEBUGGINGAIDS - UNREFERENCED_PARAMETER(fakevar); -#endif - int const animnum = picanm[tilenum].num; if (animnum <= 0) @@ -3734,7 +3737,7 @@ static void setup_globals_wall1(const uwalltype *wal, int32_t dapicnum) globalpicnum = dapicnum; if ((unsigned)globalpicnum >= MAXTILES) globalpicnum = 0; - DO_TILE_ANIM(globalpicnum, 0); + DO_TILE_ANIM(globalpicnum, 16384); globalxpanning = wal->xpanning; globalypanning = wal->ypanning; @@ -7993,6 +7996,29 @@ int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, dmost[0] = shortptr2[0]-windowxy1.y; } + for (int i = 0; i < numwalls; ++i) + { + if (wall[i].cstat & CSTAT_WALL_ROTATE_90) + { + auto &w = wall[i]; + auto &tile = rottile[w.picnum+animateoffs(w.picnum)]; + + if (!tile.newtile && !tile.owner) + { + tile.newtile = findUnusedTile(); + Bassert(tile.newtile != MAXTILES); + + rottile[tile.newtile].owner = w.picnum+animateoffs(w.picnum); + + auto &siz = tilesiz[w.picnum+animateoffs(w.picnum)]; + tileSetSize(tile.newtile, siz.x, siz.y); + + tileLoad(tile.newtile); + Bassert(waloff[tile.newtile]); + } + } + } + #ifdef USE_OPENGL # ifdef POLYMER if (videoGetRenderMode() == REND_POLYMER) diff --git a/source/build/src/engine_priv.h b/source/build/src/engine_priv.h index 735cd65f1..ffcd5da8a 100644 --- a/source/build/src/engine_priv.h +++ b/source/build/src/engine_priv.h @@ -267,17 +267,11 @@ int32_t wallfront(int32_t l1, int32_t l2); void set_globalang(fix16_t ang); -#ifdef DEBUGGINGAIDS -int32_t animateoffs(int const tilenum, int fakevar); -#define DO_TILE_ANIM(Picnum, Fakevar) do { \ - if (picanm[Picnum].sf&PICANM_ANIMTYPE_MASK) Picnum += animateoffs(Picnum, Fakevar); \ - } while (0) -#else int32_t animateoffs(int tilenum); #define DO_TILE_ANIM(Picnum, Fakevar) do { \ if (picanm[Picnum].sf&PICANM_ANIMTYPE_MASK) Picnum += animateoffs(Picnum); \ + if ((((Fakevar) & 16384) == 16384) && (globalorientation & CSTAT_WALL_ROTATE_90) && rottile[Picnum].newtile) Picnum = rottile[Picnum].newtile; \ } while (0) -#endif static FORCE_INLINE int32_t bad_tspr(const uspritetype *tspr) { diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index aa7d8614b..dcea93f65 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -5004,7 +5004,7 @@ static void polymost_drawalls(int32_t const bunch) globalpicnum = wal->picnum; globalshade = wal->shade; globalpal = (int32_t)((uint8_t)wal->pal); globvis = globalvisibility; if (sector[sectnum].visibility != 0) globvis = mulscale4(globvis, (uint8_t)(sector[sectnum].visibility+16)); - + globalorientation = wal->cstat; DO_TILE_ANIM(globalpicnum, wallnum+16384); int i = (!(wal->cstat&4)) ? sector[nextsectnum].ceilingz : sec->ceilingz; @@ -5041,7 +5041,7 @@ static void polymost_drawalls(int32_t const bunch) globalpicnum = nwal->picnum; globalshade = nwal->shade; globalpal = (int32_t)((uint8_t)nwal->pal); globvis = globalvisibility; if (sector[sectnum].visibility != 0) globvis = mulscale4(globvis, (uint8_t)(sector[sectnum].visibility+16)); - + globalorientation = wal->cstat; DO_TILE_ANIM(globalpicnum, wallnum+16384); int i = (!(nwal->cstat&4)) ? sector[nextsectnum].floorz : sec->ceilingz; @@ -5085,7 +5085,7 @@ static void polymost_drawalls(int32_t const bunch) globvis = (sector[sectnum].visibility != 0) ? mulscale4(globalvisibility, (uint8_t)(sector[sectnum].visibility + 16)) : globalvisibility; - + globalorientation = wal->cstat; DO_TILE_ANIM(globalpicnum, wallnum+16384); int i; @@ -5533,13 +5533,13 @@ void polymost_drawmaskwall(int32_t damaskwallcnt) if ((uint32_t)globalpicnum >= MAXTILES) globalpicnum = 0; + globalorientation = (int32_t)wal->cstat; DO_TILE_ANIM(globalpicnum, (int16_t)thewall[z]+16384); globvis = (sector[sectnum].visibility != 0) ? mulscale4(globvis, (uint8_t)(sector[sectnum].visibility + 16)) : globalvisibility; globalshade = (int32_t)wal->shade; globalpal = (int32_t)((uint8_t)wal->pal); - globalorientation = (int32_t)wal->cstat; vec2f_t s0 = { (float)(wal->x-globalposx), (float)(wal->y-globalposy) }; vec2f_t p0 = { s0.y*gcosang - s0.x*gsinang, s0.x*gcosang2 + s0.y*gsinang2 }; diff --git a/source/build/src/tiles.cpp b/source/build/src/tiles.cpp index a374a36dc..bde9f7fd3 100644 --- a/source/build/src/tiles.cpp +++ b/source/build/src/tiles.cpp @@ -615,10 +615,43 @@ bool tileLoad(int16_t tileNum) return (waloff[tileNum] != 0 && tilesiz[tileNum].x > 0 && tilesiz[tileNum].y > 0); } +void tileMaybeRotate(int16_t tilenume) +{ + auto &rot = rottile[tilenume]; + auto &siz = tilesiz[rot.owner]; + + auto src = (char *)waloff[rot.owner]; + auto dst = (char *)waloff[tilenume]; + + // the engine has a squarerotatetile() we could call, but it mirrors at the same time + for (int x = 0; x < siz.x; ++x) + { + int const xofs = siz.x - x - 1; + int const yofs = siz.y * x; + + for (int y = 0; y < siz.y; ++y) + *(dst + y * siz.x + xofs) = *(src + y + yofs); + } + + tileSetSize(tilenume, siz.y, siz.x); +} + void tileLoadData(int16_t tilenume, int32_t dasiz, char *buffer) { - // dummy tiles for highres replacements and tilefromtexture definitions + int const owner = rottile[tilenume].owner; + if (owner) + { + if (!waloff[owner]) + tileLoad(owner); + + tileMaybeRotate(tilenume); + return; + } + + int const tfn = tilefilenum[tilenume]; + + // dummy tiles for highres replacements and tilefromtexture definitions if (faketile[tilenume>>3] & pow2char[tilenume&7]) { if (faketiledata[tilenume] != NULL) @@ -628,8 +661,6 @@ void tileLoadData(int16_t tilenume, int32_t dasiz, char *buffer) return; } - int const tfn = tilefilenum[tilenume]; - // Potentially switch open ART file. if (tfn != artfilnum) { diff --git a/source/duke3d/src/astub.cpp b/source/duke3d/src/astub.cpp index f147b5aeb..6332506ae 100644 --- a/source/duke3d/src/astub.cpp +++ b/source/duke3d/src/astub.cpp @@ -2454,7 +2454,8 @@ int32_t AskIfSure(const char *text) static int32_t IsValidTile(int32_t idTile) { - return (idTile>=0 && idTile=0 && idTile^%d %d", editorcolors[10], searchwall, editorcolors[14], searchbottomwall); + Bsprintf(lines[num++],"^%dWall%d ->^%d %d", editorcolors[10], searchwall, editorcolors[14], searchbottomwall); else - Bsprintf(lines[num++],"^%dWall %d", editorcolors[10], searchwall); + Bsprintf(lines[num++],"^%dWall^%d %d", editorcolors[10], (wall[searchwall].cstat & CSTAT_WALL_ROTATE_90) ? editorcolors[11] : editorcolors[10], searchwall); if (wall[searchwall].nextsector!=-1) Bsprintf(lines[num++],"LoHeight:%d, HiHeight:%d, Length:%d",height1,height3,dist); @@ -4479,7 +4484,7 @@ static void Keys3d(void) else Bsprintf(lines[num++],"^%dSprite %d^%d %s", editorcolors[10], searchwall, whitecol, names[sprite[searchwall].picnum]); } - else Bsprintf(lines[num++],"^%dSprite %d^%d, picnum %d", editorcolors[10], searchwall, whitecol, TrackerCast(sprite[searchwall].picnum)); + else Bsprintf(lines[num++],"^%dSprite %d^%d", editorcolors[10], searchwall, whitecol); Bsprintf(lines[num++], "Elevation:%d", getflorzofslope(searchsector, sprite[searchwall].x, sprite[searchwall].y) - sprite[searchwall].z); @@ -5187,7 +5192,7 @@ static void Keys3d(void) pic += dir + MAXTILES; pic %= MAXTILES; } - while (tilesiz[pic].x<=0 || tilesiz[pic].y<=0); + while (!IsValidTile(pic)); AIMED_SELOVR_PICNUM = pic; if (AIMING_AT_SPRITE) @@ -5226,6 +5231,14 @@ static void Keys3d(void) ONOFF(AIMED_CEILINGFLOOR(stat)&64)); asksave = 1; } + if (AIMING_AT_WALL_OR_MASK) + { + AIMED_SEL_WALL(cstat) ^= CSTAT_WALL_ROTATE_90; + + message("Wall %d texture rotation bit %s", SELECT_WALL(), + ONOFF(AIMED_SEL_WALL(cstat)&CSTAT_WALL_ROTATE_90)); + asksave = 1; + } else if (AIMING_AT_SPRITE) toggle_sprite_alignment(searchwall); } @@ -6685,8 +6698,8 @@ static void Keys3d(void) wall[i].xpanning = tempxpanning; wall[i].ypanning = tempypanning; - wall[i].cstat &= ~(4 + 1+64 + 8+256); - wall[i].cstat |= (tempcstat & (4 + 1+64 + 8+256)); + wall[i].cstat &= ~(4 + 1+64 + 8+256 + 4096); + wall[i].cstat |= (tempcstat & (4 + 1+64 + 8+256 + 4096)); fixxrepeat(i, templenrepquot); } @@ -6785,7 +6798,7 @@ static void Keys3d(void) wall[searchwall].xpanning = tempxpanning; wall[searchwall].ypanning = tempypanning; - SET_PROTECT_BITS(wall[searchwall].cstat, tempcstat, ~(4 + 1+64 + 8+256)); + SET_PROTECT_BITS(wall[searchwall].cstat, tempcstat, ~(4 + 1+64 + 8+256 + 4096)); wall[searchwall].hitag = temphitag; #ifdef YAX_ENABLE diff --git a/source/duke3d/src/macros.h b/source/duke3d/src/macros.h index 4714a4e35..a0cfb8977 100644 --- a/source/duke3d/src/macros.h +++ b/source/duke3d/src/macros.h @@ -140,18 +140,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define FLOOR_STAT_TRANS_FLIP (BIT(7)|BIT(8)) #define FLOOR_STAT_FAF_BLOCK_HITSCAN BIT(15) -#define CSTAT_WALL_BLOCK BIT(0) -#define CSTAT_WALL_BOTTOM_SWAP BIT(1) -#define CSTAT_WALL_ALIGN_BOTTOM BIT(2) -#define CSTAT_WALL_XFLIP BIT(3) -#define CSTAT_WALL_MASKED BIT(4) -#define CSTAT_WALL_1WAY BIT(5) -#define CSTAT_WALL_BLOCK_HITSCAN BIT(6) -#define CSTAT_WALL_TRANSLUCENT BIT(7) -#define CSTAT_WALL_YFLIP BIT(8) -#define CSTAT_WALL_TRANS_FLIP BIT(9) -#define CSTAT_WALL_BLOCK_ACTOR (BIT(14)) // my def -#define CSTAT_WALL_WARP_HITSCAN (BIT(15)) // my def //cstat, bit 0: 1 = Blocking sprite (use with clipmove, getzrange) "B" // bit 1: 1 = 50/50 transluscence, 0 = normal "T"