diff --git a/include/z64bgcheck.h b/include/z64bgcheck.h index aa25557c11..2396b9ccbe 100644 --- a/include/z64bgcheck.h +++ b/include/z64bgcheck.h @@ -1,16 +1,13 @@ -#ifndef Z_BGCHECK_H -#define Z_BGCHECK_H +#ifndef Z64BGCHECK_H +#define Z64BGCHECK_H + +#include "ultra64/ultratypes.h" +#include "z64math.h" struct PlayState; struct Actor; struct DynaPolyActor; -#define COLPOLY_NORMAL_FRAC (1.0f / SHT_MAX) -#define COLPOLY_SNORMAL(x) ((s16)((x) * SHT_MAX)) -#define COLPOLY_GET_NORMAL(n) ((n)*COLPOLY_NORMAL_FRAC) -#define COLPOLY_VIA_FLAG_TEST(vIA, flags) ((vIA) & (((flags)&7) << 13)) -#define COLPOLY_VTX_INDEX(vI) ((vI)&0x1FFF) - #define DYNAPOLY_INVALIDATE_LOOKUP (1 << 0) #define BGACTOR_NEG_ONE -1 @@ -27,10 +24,30 @@ struct DynaPolyActor; #define FUNC_80041EA4_VOID_OUT 12 typedef struct { - Vec3f scale; - Vec3s rot; - Vec3f pos; -} ScaleRotPos; + /* 0x00 */ Vec3f scale; + /* 0x0C */ Vec3s rot; + /* 0x14 */ Vec3f pos; +} ScaleRotPos; // size = 0x20 + +// Macros for `CollisionPoly` + +#define COLPOLY_NORMAL_FRAC (1.0f / SHT_MAX) +#define COLPOLY_SNORMAL(x) ((s16)((x) * SHT_MAX)) +#define COLPOLY_GET_NORMAL(n) ((n)*COLPOLY_NORMAL_FRAC) +#define COLPOLY_VTX_CHECK_FLAGS_ANY(vI, flags) ((vI) & (((flags) & 7) << 13)) +#define COLPOLY_VTX_FLAGS_MASKED(vI) ((vI) & 0xE000) +#define COLPOLY_VTX_INDEX(vI) ((vI) & 0x1FFF) +#define COLPOLY_VTX(vtxId, flags) ((((flags) & 7) << 13) | ((vtxId) & 0x1FFF)) + +// flags for flags_vIA +// poly exclusion flags (xpFlags) +#define COLPOLY_IGNORE_NONE 0 +#define COLPOLY_IGNORE_CAMERA (1 << 0) +#define COLPOLY_IGNORE_ENTITY (1 << 1) +#define COLPOLY_IGNORE_PROJECTILES (1 << 2) + +// flags for flags_vIB +#define COLPOLY_IS_FLOOR_CONVEYOR (1 << 0) typedef struct { /* 0x00 */ u16 type; @@ -39,7 +56,7 @@ typedef struct { struct { /* 0x02 */ u16 flags_vIA; // 0xE000 is poly exclusion flags (xpFlags), 0x1FFF is vtxId /* 0x04 */ u16 flags_vIB; // 0xE000 is flags, 0x1FFF is vtxId - // 0x2000 = poly IsConveyor surface + // 0x2000 = poly IsFloorConveyor surface /* 0x06 */ u16 vIC; }; }; @@ -75,29 +92,18 @@ typedef struct { // Macros for `WaterBox.properties` -#define WATERBOX_BGCAM_INDEX_SHIFT 0 -#define WATERBOX_BGCAM_INDEX_MASK 0x000000FF -#define WATERBOX_BGCAM_INDEX(properties) \ - (((properties) >> WATERBOX_BGCAM_INDEX_SHIFT) & (WATERBOX_BGCAM_INDEX_MASK >> WATERBOX_BGCAM_INDEX_SHIFT)) - -#define WATERBOX_LIGHT_INDEX_SHIFT 8 -#define WATERBOX_LIGHT_INDEX_MASK 0x00001F00 -#define WATERBOX_LIGHT_INDEX(properties) \ - (((properties) >> WATERBOX_LIGHT_INDEX_SHIFT) & (WATERBOX_LIGHT_INDEX_MASK >> WATERBOX_LIGHT_INDEX_SHIFT)) #define WATERBOX_LIGHT_INDEX_NONE 0x1F // warns and defaults to 0 -#define WATERBOX_ROOM_SHIFT 13 -#define WATERBOX_ROOM_MASK 0x0007E000 -#define WATERBOX_ROOM(properties) (((properties) >> WATERBOX_ROOM_SHIFT) & (WATERBOX_ROOM_MASK >> WATERBOX_ROOM_SHIFT)) +#define WATERBOX_ROOM(properties) (((properties) >> 13) & 0x3F) #define WATERBOX_ROOM_ALL 0x3F // value for "room index" indicating "all rooms" -#define WATERBOX_FLAG_19_SHIFT 19 -#define WATERBOX_FLAG_19 (1 << WATERBOX_FLAG_19_SHIFT) +#define WATERBOX_FLAG_19 (1 << 19) -#define WATERBOX_PROPERTIES(bgCamIndex, lightIndex, room, setFlag19) \ - ((((bgCamIndex) << WATERBOX_BGCAM_INDEX_SHIFT) & WATERBOX_BGCAM_INDEX_MASK) | \ - (((lightIndex) << WATERBOX_LIGHT_INDEX_SHIFT) & WATERBOX_LIGHT_INDEX_MASK) | \ - (((room) << WATERBOX_ROOM_SHIFT) & WATERBOX_ROOM_MASK) | (((setFlag19) & 1) << WATERBOX_FLAG_19_SHIFT)) +#define WATERBOX_PROPERTIES(bgCamIndex, lightIndex, room, setFlag19) \ + ((((bgCamIndex) & 0xFF) << 0) | \ + (((lightIndex) & 0x1F) << 8) | \ + (((room) & 0x3F) << 13) | \ + (((setFlag19) & 1) << 19)) typedef struct { /* 0x00 */ s16 xMin; @@ -213,6 +219,27 @@ typedef enum { } ConveyorSpeed; #define CONVEYOR_DIRECTION_TO_BINANG(conveyorDirection) ((conveyorDirection) * (0x10000 / 64)) +#define CONVEYOR_DIRECTION_FROM_BINANG(conveyorDirectionBinang) ((conveyorDirectionBinang) * (64 / 0x10000)) + +#define SURFACETYPE0(bgCamIndex, exitIndex, floorType, unk18, wallType, floorProperty, isSoft, isHorseBlocked) \ + ((((bgCamIndex) & 0xFF) << 0) | \ + (((exitIndex) & 0x1F) << 8) | \ + (((floorType) & 0x1F) << 13) | \ + (((unk18) & 0x07) << 18) | \ + (((wallType) & 0x1F) << 21) | \ + (((floorProperty) & 0x0F) << 26) | \ + (((isSoft) & 1) << 30) | \ + (((isHorseBlocked) & 1) << 31)) + +#define SURFACETYPE1(material, floorEffect, lightSetting, echo, canHookshot, conveyorSpeed, conveyorDirection, unk27) \ + ((((material) & 0x0F) << 0) | \ + (((floorEffect) & 0x03) << 4) | \ + (((lightSetting) & 0x1F) << 6) | \ + (((echo) & 0x3F) << 11) | \ + (((canHookshot) & 1) << 17) | \ + (((conveyorSpeed) & 0x07) << 18) | \ + (((conveyorDirection) & 0x3F) << 21) | \ + (((unk27) & 1) << 27)) typedef struct { u32 data[2]; diff --git a/include/z64collision_check.h b/include/z64collision_check.h index be80500050..3e4ae20f32 100644 --- a/include/z64collision_check.h +++ b/include/z64collision_check.h @@ -1,5 +1,5 @@ -#ifndef Z_COLLISION_CHECK_H -#define Z_COLLISION_CHECK_H +#ifndef Z64COLLISION_CHECK_H +#define Z64COLLISION_CHECK_H #define COLLISION_CHECK_AT_MAX 50 #define COLLISION_CHECK_AC_MAX 60 diff --git a/src/code/z_bgcheck.c b/src/code/z_bgcheck.c index 621ced77aa..e0634028c1 100644 --- a/src/code/z_bgcheck.c +++ b/src/code/z_bgcheck.c @@ -41,12 +41,6 @@ void BgCheck_ResetPolyCheckTbl(SSNodeList* nodeList, s32 numPolys); #define BGCHECK_IGNORE_WALL (1 << 1) #define BGCHECK_IGNORE_FLOOR (1 << 2) -// poly exclusion flags (xpFlags) -#define COLPOLY_IGNORE_NONE 0 -#define COLPOLY_IGNORE_CAMERA (1 << 0) -#define COLPOLY_IGNORE_ENTITY (1 << 1) -#define COLPOLY_IGNORE_PROJECTILES (1 << 2) - // raycast down flags (downChkFlags) #define BGCHECK_RAYCAST_DOWN_CHECK_CEILINGS (1 << 0) #define BGCHECK_RAYCAST_DOWN_CHECK_WALLS (1 << 1) @@ -579,7 +573,7 @@ f32 BgCheck_RaycastDownStaticList(CollisionContext* colCtx, u16 xpFlags, SSList* while (true) { polyId = curNode->polyId; - if (COLPOLY_VIA_FLAG_TEST(colCtx->colHeader->polyList[polyId].flags_vIA, xpFlags) || + if (COLPOLY_VTX_CHECK_FLAGS_ANY(colCtx->colHeader->polyList[polyId].flags_vIA, xpFlags) || ((groundChk & BGCHECK_GROUND_CHECK_ON) && colCtx->colHeader->polyList[polyId].normal.y < 0)) { if (curNode->next == SS_NULL) { break; @@ -735,7 +729,7 @@ s32 BgCheck_SphVsStaticWall(StaticLookup* lookup, CollisionContext* colCtx, u16 nz = COLPOLY_GET_NORMAL(curPoly->normal.z); normalXZ = sqrtf(SQ(nx) + SQ(nz)); planeDist = Math3D_DistPlaneToPos(nx, ny, nz, curPoly->dist, &resultPos); - if (radius < fabsf(planeDist) || COLPOLY_VIA_FLAG_TEST(curPoly->flags_vIA, xpFlags)) { + if (radius < fabsf(planeDist) || COLPOLY_VTX_CHECK_FLAGS_ANY(curPoly->flags_vIA, xpFlags)) { if (curNode->next == SS_NULL) { break; } else { @@ -816,7 +810,7 @@ s32 BgCheck_SphVsStaticWall(StaticLookup* lookup, CollisionContext* colCtx, u16 nz = COLPOLY_GET_NORMAL(curPoly->normal.z); normalXZ = sqrtf(SQ(nx) + SQ(nz)); planeDist = Math3D_DistPlaneToPos(nx, ny, nz, curPoly->dist, &resultPos); - if (radius < fabsf(planeDist) || COLPOLY_VIA_FLAG_TEST(curPoly->flags_vIA, xpFlags)) { + if (radius < fabsf(planeDist) || COLPOLY_VTX_CHECK_FLAGS_ANY(curPoly->flags_vIA, xpFlags)) { if (curNode->next == SS_NULL) { break; } else { @@ -916,7 +910,7 @@ s32 BgCheck_CheckStaticCeiling(StaticLookup* lookup, u16 xpFlags, CollisionConte while (true) { curPolyId = curNode->polyId; - if (COLPOLY_VIA_FLAG_TEST(colCtx->colHeader->polyList[curPolyId].flags_vIA, xpFlags)) { + if (COLPOLY_VTX_CHECK_FLAGS_ANY(colCtx->colHeader->polyList[curPolyId].flags_vIA, xpFlags)) { if (curNode->next == SS_NULL) { break; } else { @@ -977,8 +971,8 @@ s32 BgCheck_CheckLineAgainstSSList(SSList* ssList, CollisionContext* colCtx, u16 polyId = curNode->polyId; checkedPoly = &colCtx->polyNodes.polyCheckTbl[polyId]; - if (*checkedPoly == true || COLPOLY_VIA_FLAG_TEST(polyList[polyId].flags_vIA, xpFlags1) || - !(xpFlags2 == 0 || COLPOLY_VIA_FLAG_TEST(polyList[polyId].flags_vIA, xpFlags2))) { + if (*checkedPoly == true || COLPOLY_VTX_CHECK_FLAGS_ANY(polyList[polyId].flags_vIA, xpFlags1) || + !(xpFlags2 == 0 || COLPOLY_VTX_CHECK_FLAGS_ANY(polyList[polyId].flags_vIA, xpFlags2))) { if (curNode->next == SS_NULL) { break; @@ -1064,7 +1058,7 @@ s32 BgCheck_SphVsFirstStaticPolyList(SSNode* node, u16 xpFlags, CollisionContext while (true) { curPolyId = node->polyId; curPoly = &polyList[curPolyId]; - if (COLPOLY_VIA_FLAG_TEST(colCtx->colHeader->polyList[curPolyId].flags_vIA, xpFlags)) { + if (COLPOLY_VTX_CHECK_FLAGS_ANY(colCtx->colHeader->polyList[curPolyId].flags_vIA, xpFlags)) { if (node->next == SS_NULL) { break; } else { @@ -2964,10 +2958,10 @@ void DynaPoly_AddBgActorToLookup(PlayState* play, DynaCollisionContext* dyna, s3 *newPoly = pbgdata->polyList[i]; // Yeah, this is all kinds of fake, but my God, it matches. - newPoly->flags_vIA = - (COLPOLY_VTX_INDEX(newPoly->flags_vIA) + *vtxStartIndex) | ((*newPoly).flags_vIA & 0xE000); - newPoly->flags_vIB = - (COLPOLY_VTX_INDEX(newPoly->flags_vIB) + *vtxStartIndex) | ((*newPoly).flags_vIB & 0xE000); + newPoly->flags_vIA = (COLPOLY_VTX_INDEX(newPoly->flags_vIA) + *vtxStartIndex) | + COLPOLY_VTX_FLAGS_MASKED((*newPoly).flags_vIA); + newPoly->flags_vIB = (COLPOLY_VTX_INDEX(newPoly->flags_vIB) + *vtxStartIndex) | + COLPOLY_VTX_FLAGS_MASKED((*newPoly).flags_vIB); newPoly->vIC = *vtxStartIndex + newPoly->vIC; dVtxList = dyna->vtxList; vtxA.x = dVtxList[(u32)COLPOLY_VTX_INDEX(newPoly->flags_vIA)].x; @@ -3116,7 +3110,7 @@ f32 BgCheck_RaycastDownDynaList(DynaRaycastDown* dynaRaycastDown, u32 listType) while (true) { id = curNode->polyId; - if (COLPOLY_VIA_FLAG_TEST(polyList[id].flags_vIA, dynaRaycastDown->xpFlags)) { + if (COLPOLY_VTX_CHECK_FLAGS_ANY(polyList[id].flags_vIA, dynaRaycastDown->xpFlags)) { if (curNode->next == SS_NULL) { break; } else { @@ -3322,7 +3316,7 @@ s32 BgCheck_SphVsDynaWallInBgActor(CollisionContext* colCtx, u16 xpFlags, DynaCo ASSERT(!IS_ZERO(normalXZ), "!IS_ZERO(ac_size)", "../z_bgcheck.c", 7382); planeDist = Math3D_DistPlaneToPos(nx, ny, nz, poly->dist, &resultPos); - if (radius < fabsf(planeDist) || COLPOLY_VIA_FLAG_TEST(poly->flags_vIA, xpFlags)) { + if (radius < fabsf(planeDist) || COLPOLY_VTX_CHECK_FLAGS_ANY(poly->flags_vIA, xpFlags)) { if (curNode->next == SS_NULL) { break; } else { @@ -3395,7 +3389,7 @@ s32 BgCheck_SphVsDynaWallInBgActor(CollisionContext* colCtx, u16 xpFlags, DynaCo ASSERT(!IS_ZERO(normalXZ), "!IS_ZERO(ac_size)", "../z_bgcheck.c", 7489); planeDist = Math3D_DistPlaneToPos(nx, ny, nz, poly->dist, &resultPos); - if (radius < fabsf(planeDist) || COLPOLY_VIA_FLAG_TEST(poly->flags_vIA, xpFlags)) { + if (radius < fabsf(planeDist) || COLPOLY_VTX_CHECK_FLAGS_ANY(poly->flags_vIA, xpFlags)) { if (curNode->next == SS_NULL) { break; } else { @@ -3551,7 +3545,7 @@ s32 BgCheck_CheckDynaCeilingList(CollisionContext* colCtx, u16 xpFlags, DynaColl while (true) { polyId = curNode->polyId; poly = &dyna->polyList[polyId]; - if (COLPOLY_VIA_FLAG_TEST(poly->flags_vIA, xpFlags)) { + if (COLPOLY_VTX_CHECK_FLAGS_ANY(poly->flags_vIA, xpFlags)) { if (curNode->next == SS_NULL) { break; } else { @@ -3651,7 +3645,7 @@ s32 BgCheck_CheckLineAgainstBgActorSSList(DynaLineTest* dynaLineTest) { while (true) { polyId = curNode->polyId; curPoly = &dynaLineTest->dyna->polyList[polyId]; - if (COLPOLY_VIA_FLAG_TEST(curPoly->flags_vIA, dynaLineTest->xpFlags)) { + if (COLPOLY_VTX_CHECK_FLAGS_ANY(curPoly->flags_vIA, dynaLineTest->xpFlags)) { if (curNode->next == SS_NULL) { break; } else { @@ -3784,7 +3778,7 @@ s32 BgCheck_SphVsFirstDynaPolyList(CollisionContext* colCtx, u16 xpFlags, Collis while (true) { curPolyId = curNode->polyId; curPoly = &dyna->polyList[curPolyId]; - if (COLPOLY_VIA_FLAG_TEST(curPoly->flags_vIA, xpFlags)) { + if (COLPOLY_VTX_CHECK_FLAGS_ANY(curPoly->flags_vIA, xpFlags)) { if (curNode->next == SS_NULL) { break; } else { @@ -4158,7 +4152,7 @@ s32 SurfaceType_IsIgnoredByEntities(CollisionContext* colCtx, CollisionPoly* pol if (BgCheck_GetCollisionHeader(colCtx, bgId) == NULL) { return true; } - flags = poly->flags_vIA & 0x4000; + flags = COLPOLY_VTX_CHECK_FLAGS_ANY(poly->flags_vIA, COLPOLY_IGNORE_ENTITY); return !!flags; } @@ -4172,7 +4166,7 @@ s32 SurfaceType_IsIgnoredByProjectiles(CollisionContext* colCtx, CollisionPoly* if (BgCheck_GetCollisionHeader(colCtx, bgId) == NULL) { return true; } - flags = poly->flags_vIA & 0x8000; + flags = COLPOLY_VTX_CHECK_FLAGS_ANY(poly->flags_vIA, COLPOLY_IGNORE_PROJECTILES); return !!flags; } @@ -4191,7 +4185,7 @@ s32 SurfaceType_IsFloorConveyor(CollisionContext* colCtx, CollisionPoly* poly, s if (BgCheck_GetCollisionHeader(colCtx, bgId) == NULL) { return true; } - flags = poly->flags_vIB & 0x2000; + flags = COLPOLY_VTX_CHECK_FLAGS_ANY(poly->flags_vIB, COLPOLY_IS_FLOOR_CONVEYOR); return !!flags; } @@ -4321,7 +4315,7 @@ s32 WaterBox_GetSurface2(PlayState* play, CollisionContext* colCtx, Vec3f* pos, * WaterBox get BgCam index */ u32 WaterBox_GetBgCamIndex(CollisionContext* colCtx, WaterBox* waterBox) { - u32 bgCamIndex = WATERBOX_BGCAM_INDEX(waterBox->properties); + u32 bgCamIndex = waterBox->properties & 0xFF; return bgCamIndex; } @@ -4344,7 +4338,7 @@ u16 WaterBox_GetBgCamSetting(CollisionContext* colCtx, WaterBox* waterBox) { * WaterBox get lighting settings */ u32 WaterBox_GetLightIndex(CollisionContext* colCtx, WaterBox* waterBox) { - u32 lightIndex = WATERBOX_LIGHT_INDEX(waterBox->properties); + u32 lightIndex = (waterBox->properties >> 8) & 0x1F; return lightIndex; }