diff --git a/source/build/include/build.h b/source/build/include/build.h index 7c2bf24cf..56a5669d0 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -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_ diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index 7a01e17b4..2169f78f0 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -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; } //--------------------------------------------------------------------------- diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp index c11b67717..0d57798b2 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -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); } - //--------------------------------------------------------------------------- // // diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index aad1e3123..32304e89c 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -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); } //--------------------------------------------------------------------------- diff --git a/source/games/duke/src/dispatch.cpp b/source/games/duke/src/dispatch.cpp index e1cb71262..ce6aca306 100644 --- a/source/games/duke/src/dispatch.cpp +++ b/source/games/duke/src/dispatch.cpp @@ -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); diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index 76b5e29af..240dbbc30 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -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); diff --git a/source/games/duke/src/dukeactor.h b/source/games/duke/src/dukeactor.h index 83ac4ff04..de7f7f7c9 100644 --- a/source/games/duke/src/dukeactor.h +++ b/source/games/duke/src/dukeactor.h @@ -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 diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h index 0ffd23f8d..d62fcae1f 100644 --- a/source/games/duke/src/types.h +++ b/source/games/duke/src/types.h @@ -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