WIP wall texture rotation bit

git-svn-id: https://svn.eduke32.com/eduke32@7226 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
terminx 2018-11-18 18:13:48 +00:00
parent ccebff2c85
commit 4861d1fc3d
9 changed files with 139 additions and 65 deletions

View file

@ -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;

View file

@ -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

View file

@ -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;
}

View file

@ -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)

View file

@ -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)
{

View file

@ -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 };

View file

@ -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)
{

View file

@ -2454,7 +2454,8 @@ int32_t AskIfSure(const char *text)
static int32_t IsValidTile(int32_t idTile)
{
return (idTile>=0 && idTile<MAXTILES) && (tilesiz[idTile].x && tilesiz[idTile].y);
// this is MAXTILES-1 because TROR uses that tile and we don't need it showing up in the tile selector, etc
return (idTile>=0 && idTile<MAXTILES-1) && (tilesiz[idTile].x && tilesiz[idTile].y) && !rottile[idTile].owner;
}
static int32_t SelectAllTiles(int32_t iCurrentTile)
@ -3597,6 +3598,10 @@ restart:
// Get pointer to tile's raw pixel data
pRawPixels = GetTilePixels(idTile);
// don't draw rotated tiles generated near MAXTILES
if (EDUKE32_PREDICT_FALSE(rottile[idTile].owner))
pRawPixels = NULL;
if (pRawPixels != NULL)
{
x = XTile * TileDim;
@ -4414,9 +4419,9 @@ static void Keys3d(void)
break;
if (searchwall != searchbottomwall)
Bsprintf(lines[num++],"^%dWall %d ->^%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

View file

@ -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"