- foundation for a better collision info management.

The way this is handled is the main reason why Build maps are size limited, but since it is extremely invasive it needs to be taken out of the game code piece by piece, this is the framework for doing this for Duke.
This commit is contained in:
Christoph Oelckers 2020-10-24 09:31:15 +02:00
parent 16e49ac1fd
commit a5b3681630
8 changed files with 123 additions and 52 deletions

View file

@ -926,6 +926,7 @@ extern void(*PolymostProcessVoxels_Callback)(void);
// Names taken from DukeGDX
enum EHitBits
{
kHitNone = 0,
kHitTypeMask = 0xE000,
kHitIndexMask = 0x1FFF,
kHitSector = 0x4000,
@ -933,6 +934,7 @@ enum EHitBits
kHitSprite = 0xC000,
};
#include "iterators.h"
#endif // build_h_

View file

@ -226,14 +226,12 @@ void clearcamera(player_struct* ps)
int ssp(DDukeActor* const actor, unsigned int cliptype) //The set sprite function
{
int movetype;
Collision c;
movetype = fi.movesprite(actor->GetIndex(),
return movesprite_ex(actor,
(actor->s.xvel * (sintable[(actor->s.ang + 512) & 2047])) >> 14,
(actor->s.xvel * (sintable[actor->s.ang & 2047])) >> 14, actor->s.zvel,
cliptype);
return (movetype == 0);
cliptype, c) == kHitNone;
}
//---------------------------------------------------------------------------

View file

@ -538,13 +538,14 @@ SKIPWALLCHECK:
//
//---------------------------------------------------------------------------
int movesprite_d(short spritenum, int xchange, int ychange, int zchange, unsigned int cliptype)
int movesprite_ex_d(DDukeActor* actor, int xchange, int ychange, int zchange, unsigned int cliptype, Collision &result)
{
int daz, h, oldx, oldy;
short retval, dasectnum, cd;
auto spri = &sprite[spritenum];
int bg = badguy(spri);
auto spri = &actor->s;
int bg = badguy(actor);
if (spri->statnum == 5 || (bg && spri->xrepeat < 4))
{
@ -552,14 +553,14 @@ int movesprite_d(short spritenum, int xchange, int ychange, int zchange, unsigne
spri->y += (ychange * TICSPERFRAME) >> 2;
spri->z += (zchange * TICSPERFRAME) >> 2;
if (bg)
setsprite(spritenum, spri->x, spri->y, spri->z);
return 0;
setsprite(actor, spri->x, spri->y, spri->z);
return result.setNone();
}
dasectnum = spri->sectnum;
daz = spri->z;
h = ((tilesiz[spri->picnum].y * spri->yrepeat) << 1);
h = ((tileHeight(spri->picnum) * spri->yrepeat) << 1);
daz -= h;
if (bg)
@ -573,7 +574,7 @@ int movesprite_d(short spritenum, int xchange, int ychange, int zchange, unsigne
{
if (spri->picnum == LIZMAN)
cd = 292;
else if (actorflag(spritenum, SFLAG_BADGUY))
else if (actorflag(actor->GetIndex(), SFLAG_BADGUY))
cd = spri->clipdist << 2;
else
cd = 192;
@ -583,7 +584,7 @@ int movesprite_d(short spritenum, int xchange, int ychange, int zchange, unsigne
// conditional code from hell...
if (dasectnum < 0 || (dasectnum >= 0 &&
((hittype[spritenum].actorstayput >= 0 && hittype[spritenum].actorstayput != dasectnum) ||
((actor->actorstayput >= 0 && actor->actorstayput != dasectnum) ||
((spri->picnum == BOSS2) && spri->pal == 0 && sector[dasectnum].lotag != 3) ||
((spri->picnum == BOSS1 || spri->picnum == BOSS2) && sector[dasectnum].lotag == ST_1_ABOVE_WATER) ||
(sector[dasectnum].lotag == ST_1_ABOVE_WATER && (spri->picnum == LIZMAN || (spri->picnum == LIZTROOP && spri->zvel == 0)))
@ -594,17 +595,17 @@ int movesprite_d(short spritenum, int xchange, int ychange, int zchange, unsigne
spri->y = oldy;
if (sector[dasectnum].lotag == ST_1_ABOVE_WATER && spri->picnum == LIZMAN)
spri->ang = (krand()&2047);
else if ((hittype[spritenum].temp_data[0]&3) == 1 && spri->picnum != COMMANDER)
else if ((actor->temp_data[0]&3) == 1 && spri->picnum != COMMANDER)
spri->ang = (krand()&2047);
setsprite(spritenum,oldx,oldy,spri->z);
setsprite(actor,oldx,oldy,spri->z);
if (dasectnum < 0) dasectnum = 0;
return (16384+dasectnum);
return result.setSector(dasectnum);
}
if ((retval&49152) >= 32768 && (hittype[spritenum].cgg==0)) spri->ang += 768;
if ((retval & kHitTypeMask) != kHitSector && (actor->cgg == 0)) spri->ang += 768;
}
else
{
if (spri->statnum == 4)
if (spri->statnum == STAT_PROJECTILE)
retval =
clipmove(&spri->x, &spri->y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 8L, (4 << 8), (4 << 8), cliptype);
else
@ -614,17 +615,15 @@ int movesprite_d(short spritenum, int xchange, int ychange, int zchange, unsigne
if (dasectnum >= 0)
if ((dasectnum != spri->sectnum))
changespritesect(spritenum, dasectnum);
changespritesect(actor, dasectnum);
daz = spri->z + ((zchange * TICSPERFRAME) >> 3);
if ((daz > hittype[spritenum].ceilingz) && (daz <= hittype[spritenum].floorz))
if ((daz > actor->ceilingz) && (daz <= actor->floorz))
spri->z = daz;
else
if (retval == 0)
return(16384 + dasectnum);
else if (retval == 0)
return result.setSector(dasectnum);
return(retval);
return result.setFromEngine(retval);
}
//---------------------------------------------------------------------------
//
//

View file

@ -375,14 +375,12 @@ SKIPWALLCHECK:
//
//---------------------------------------------------------------------------
int movesprite_r(short spritenum, int xchange, int ychange, int zchange, unsigned int cliptype)
int movesprite_ex_r(DDukeActor* actor, int xchange, int ychange, int zchange, unsigned int cliptype, Collision &result)
{
int daz, h, oldx, oldy;
short retval, dasectnum, cd;
char bg;
auto spri = &sprite[spritenum];
bg = badguy(&sprite[spritenum]);
auto spri = &actor->s;
int bg = badguy(actor);
if (spri->statnum == 5 || (bg && spri->xrepeat < 4))
{
@ -390,14 +388,14 @@ int movesprite_r(short spritenum, int xchange, int ychange, int zchange, unsigne
spri->y += (ychange * TICSPERFRAME) >> 2;
spri->z += (zchange * TICSPERFRAME) >> 2;
if (bg)
setsprite(spritenum, spri->x, spri->y, spri->z);
return 0;
setsprite(actor, spri->x, spri->y, spri->z);
return result.setNone();
}
dasectnum = spri->sectnum;
daz = spri->z;
h = ((tilesiz[spri->picnum].y * spri->yrepeat) << 1);
h = ((tileHeight(spri->picnum) * spri->yrepeat) << 1);
daz -= h;
if (bg)
@ -407,48 +405,46 @@ int movesprite_r(short spritenum, int xchange, int ychange, int zchange, unsigne
if (spri->xrepeat > 60)
retval = clipmove(&spri->x, &spri->y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 1024L, (4 << 8), (4 << 8), cliptype);
else
else
{
cd = 192;
retval = clipmove(&spri->x, &spri->y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), cd, (4 << 8), (4 << 8), cliptype);
}
if (dasectnum < 0 || (dasectnum >= 0 &&
hittype[spritenum].actorstayput >= 0 && hittype[spritenum].actorstayput != dasectnum))
if (dasectnum < 0 || (dasectnum >= 0 && actor->actorstayput >= 0 && actor->actorstayput != dasectnum))
{
spri->x = oldx;
spri->y = oldy;
if (sector[dasectnum].lotag == ST_1_ABOVE_WATER)
spri->ang = (krand() & 2047);
else if ((hittype[spritenum].temp_data[0] & 3) == 1)
else if ((actor->temp_data[0] & 3) == 1)
spri->ang = (krand() & 2047);
setsprite(spritenum, oldx, oldy, spri->z);
setsprite(actor, oldx, oldy, spri->z);
if (dasectnum < 0) dasectnum = 0;
return (16384 + dasectnum);
return result.setSector(dasectnum);
}
if ((retval & 49152) >= 32768 && (hittype[spritenum].cgg == 0)) spri->ang += 768;
if ((retval & kHitTypeMask) != kHitSector && (actor->cgg == 0)) spri->ang += 768;
}
else
{
if (spri->statnum == 4)
if (spri->statnum == STAT_PROJECTILE)
retval =
clipmove(&spri->x, &spri->y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 8L, (4 << 8), (4 << 8), cliptype);
else
retval =
clipmove(&spri->x, &spri->y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 128L, (4 << 8), (4 << 8), cliptype);
clipmove(&spri->x, &spri->y, &daz, &dasectnum, ((xchange * TICSPERFRAME) << 11), ((ychange * TICSPERFRAME) << 11), 128, (4 << 8), (4 << 8), cliptype);
}
if (dasectnum >= 0)
if ((dasectnum != spri->sectnum))
changespritesect(spritenum, dasectnum);
changespritesect(actor, dasectnum);
daz = spri->z + ((zchange * TICSPERFRAME) >> 3);
if ((daz > hittype[spritenum].ceilingz) && (daz <= hittype[spritenum].floorz))
if ((daz > actor->ceilingz) && (daz <= actor->floorz))
spri->z = daz;
else
if (retval == 0)
return(16384 + dasectnum);
else if (retval == 0)
return result.setSector(dasectnum);
return(retval);
return result.setFromEngine(retval);
}
//---------------------------------------------------------------------------

View file

@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "ns.h"
#include "global.h"
#include "dukeactor.h"
BEGIN_DUKE_NS
@ -65,8 +66,6 @@ void addweapon_d(struct player_struct* p, int weapon);
void addweapon_r(struct player_struct* p, int weapon);
void hitradius_d(short i, int r, int hp1, int hp2, int hp3, int hp4);
void hitradius_r(short i, int r, int hp1, int hp2, int hp3, int hp4);
int movesprite_d(short spritenum, int xchange, int ychange, int zchange, unsigned int cliptype);
int movesprite_r(short spritenum, int xchange, int ychange, int zchange, unsigned int cliptype);
void lotsofmoney_d(spritetype* s, short n);
void lotsofmail_d(spritetype* s, short n);
void lotsofpaper_d(spritetype* s, short n);

View file

@ -88,7 +88,7 @@ struct Dispatcher
bool (*floorspace)(int sectnum);
void (*addweapon)(struct player_struct *p, int weapon);
void (*hitradius)(short i, int r, int hp1, int hp2, int hp3, int hp4);
int (*movesprite)(short spritenum, int xchange, int ychange, int zchange, unsigned int cliptype);
int (*movesprite)(int spritenum, int xchange, int ychange, int zchange, unsigned int cliptype);
void (*lotsofmoney)(spritetype *s, short n);
void (*lotsofmail)(spritetype *s, short n);
void (*lotsofpaper)(spritetype *s, short n);

View file

@ -68,7 +68,6 @@ public:
}
};
inline DDukeActor* player_struct::GetActor()
{
return &hittype[i];
@ -213,5 +212,29 @@ inline int ssp(int i, unsigned int cliptype) //The set sprite function
return ssp(&hittype[i], cliptype);
}
int movesprite_ex_d(DDukeActor* actor, int xchange, int ychange, int zchange, unsigned int cliptype, Collision& result);
int movesprite_ex_r(DDukeActor* actor, int xchange, int ychange, int zchange, unsigned int cliptype, Collision& result);
inline int movesprite_d(int actor, int xchange, int ychange, int zchange, unsigned int cliptype)
{
Collision c;
movesprite_ex_d(&hittype[actor], xchange, ychange, zchange, cliptype, c);
return c.legacyVal;
}
inline int movesprite_r(int actor, int xchange, int ychange, int zchange, unsigned int cliptype)
{
Collision c;
movesprite_ex_r(&hittype[actor], xchange, ychange, zchange, cliptype, c);
return c.legacyVal;
}
inline int movesprite_ex(DDukeActor* actor, int xchange, int ychange, int zchange, unsigned int cliptype, Collision& result)
{
auto f = isRR() ? movesprite_ex_r : movesprite_ex_d;
return f(actor, xchange, ychange, zchange, cliptype, result);
}
END_DUKE_NS

View file

@ -278,5 +278,59 @@ struct player_struct
};
// Wrapper around the insane collision info mess from Build.
struct Collision
{
int type;
int index;
int legacyVal; // should be removed later, but needed for converting back for unadjusted code.
DDukeActor* actor;
int setNone()
{
type = kHitNone;
index = -1;
legacyVal = 0;
actor = nullptr;
return kHitNone;
}
int setSector(int num)
{
type = kHitSector;
index = num;
legacyVal = type | index;
actor = nullptr;
return kHitSector;
}
int setWall(int num)
{
type = kHitWall;
index = num;
legacyVal = type | index;
actor = nullptr;
return kHitWall;
}
int setSprite(DDukeActor* num)
{
type = kHitSprite;
index = -1;
legacyVal = type | int(num - hittype);
actor = num;
return kHitSprite;
}
int setFromEngine(int value)
{
legacyVal = value;
type = value & kHitTypeMask;
if (type == 0) { index = -1; actor = nullptr; }
else if (type != kHitSprite) { index = value & kHitIndexMask; actor = nullptr; }
else { index = -1; actor = &hittype[value & kHitIndexMask]; }
return type;
}
};
END_DUKE_NS