curtains.c data work, assorted funcs, new file, etc and cleanup: misc decomp (#360)

* PlayEffect progress, two insane funcs

* PartnerActionStatus struct and some cleanup

* file split

* physics funcs

* data migration, some decomp

* curtains data, etc

* git subrepo pull (merge) --force tools/splat

subrepo:
  subdir:   "tools/splat"
  merged:   "b8bf80cd07"
upstream:
  origin:   "https://github.com/ethteck/splat.git"
  branch:   "master"
  commit:   "b8bf80cd07"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "2f68596"

* git subrepo pull tools/splat

subrepo:
  subdir:   "tools/splat"
  merged:   "265b837554"
upstream:
  origin:   "https://github.com/ethteck/splat.git"
  branch:   "master"
  commit:   "265b837554"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "2f68596"

* PR comments
This commit is contained in:
Ethan Roseman 2021-08-14 02:27:57 +09:00 committed by GitHub
parent 3dfb922ce0
commit 3c887e6ac3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
177 changed files with 1679 additions and 1993 deletions

View File

@ -13,7 +13,8 @@
"includePath": [
"${workspaceFolder}/include",
"${workspaceFolder}/ver/us/build/include",
"${workspaceFolder}/src"
"${workspaceFolder}/src",
"${workspaceFolder}/assets/us",
],
"defines": [
"F3DEX_GBI_2",

View File

@ -1442,13 +1442,13 @@ typedef struct ActorPart {
} ActorPart; // size = 0xC4
typedef struct ColliderTriangle {
/* 0x00 */ f32* v1[3]; /* note: the order of v1,2,3 is reversed from the ijk in the hit file */
/* 0x04 */ f32* v2[3];
/* 0x08 */ f32* v3[3];
/* 0x0C */ f32 e13[3]; /* = v3 - v1 */
/* 0x18 */ f32 e21[3]; /* = v1 - v2 */
/* 0x24 */ f32 e32[3]; /* = v2 - v3 */
/* 0x30 */ f32 normal[3];
/* 0x00 */ Vec3f* v1; /* note: the order of v1,2,3 is reversed from the ijk in the hit file */
/* 0x04 */ Vec3f* v2;
/* 0x08 */ Vec3f* v3;
/* 0x0C */ Vec3f e13; /* = v3 - v1 */
/* 0x18 */ Vec3f e21; /* = v1 - v2 */
/* 0x24 */ Vec3f e32; /* = v2 - v3 */
/* 0x30 */ Vec3f normal;
/* 0x3C */ s16 oneSided; /* 1 = yes, 0 = no */
/* 0x3E */ char unk_3E[2];
} ColliderTriangle; // size = 0x40
@ -2147,20 +2147,21 @@ typedef struct Temp8010F250 {
/* 0x30 */ SoundID unk_30;
} Temp8010F250; // size = 0x34
typedef struct Temp8010EBB0 {
/* 0x000 */ s8 unk_00;
/* 0x001 */ s8 unk_01;
/* 0x002 */ s8 unk_02;
/* 0x003 */ s8 unk_03;
/* 0x004 */ char unk_04[0x4];
/* 0x008 */ s32 unk_08;
/* 0x009 */ s32 unk_0C;
/* 0x010 */ char unk_10[0x4];
/* 0x014 */ s8 unk_14;
typedef struct PartnerActionStatus {
/* 0x000 */ union {
/* */ s32 i;
/* */ s8 b[4];
} actionState;
/* 0x004 */ s16 stickX;
/* 0x006 */ s16 stickY;
/* 0x008 */ s32 currentButtons;
/* 0x00C */ s32 pressedButtons;
/* 0x010 */ s32 heldButtons;
/* 0x014 */ s8 inputDisabled;
/* 0x015 */ char unk_15[0x343];
/* 0x358 */ s32 unk_358;
/* 0x35C */ char unk_35C[0x4];
} Temp8010EBB0; // size = 0x360
} PartnerActionStatus; // size = 0x360
typedef struct Temp8025D160 {
/* 0x00 */ s32 unk_00;

View File

@ -16,11 +16,11 @@ void fx_land(s32, f32, f32, f32, f32);
void fx_walk(s32, f32, f32, f32, f32, f32);
void playFX_08(f32, f32, f32, f32);
void playFX_09(s32, f32, f32, f32, f32, f32);
EffectInstance* playFX_0A(f32, f32, s32, s32, f32, f32);
EffectInstance* playFX_0A(f32, f32, f32, f32);
EffectInstance* playFX_0B(s32, f32, f32, f32);
EffectInstance* playFX_0C(f32, f32, f32, f32, f32);
EffectInstance* playFX_0D(s32, f32, f32, f32, s32);
EffectInstance* playFX_0E(f32, f32, s32, s32, f32, s32);
EffectInstance* playFX_0E(f32, f32, f32, s32);
void playFX_0F(s32, f32, f32, f32, f32, f32, f32, f32);
void fx_emote(s32, Npc*, f32, f32, f32, f32, f32, s32, s32*);
void playFX_11(s32, f32, f32, f32, f32);
@ -33,12 +33,12 @@ void playFX_17(s32, f32, f32, f32);
void playFX_18(s32, f32, f32, f32, f32, f32, f32, s32);
void playFX_19(s32, f32, f32, f32);
EffectInstance* playFX_1A(s32, f32, f32, f32, s32);
EffectInstance* playFX_1B(s32, f32, f32, f32, f32, EffectInstanceData**);
EffectInstance* playFX_1B(s32, f32, f32, f32, f32, s32);
EffectInstance* playFX_1C(s32, f32, f32, f32, s32);
void playFX_1D(s32, f32, f32, f32, f32, s32, f32, s32);
EffectInstance* playFX_1E(s32, f32, f32, f32, f32, f32, s32, s32*);
EffectInstance* playFX_1F(s32, f32, f32, f32, f32, f32, f32, f32);
EffectInstance* playFX_20(s32, f32, f32, f32, f32, EffectInstanceData**);
EffectInstance* playFX_20(s32, f32, f32, f32, f32, s32);
EffectInstance* playFX_21(s32, f32, f32, f32, f32, f32, s32);
void playFX_22(s32, f32, f32, f32, f32, f32, s32, s32);
EffectInstance* playFX_23(u32, f32, f32, f32, f32);
@ -47,26 +47,26 @@ EffectInstance* playFX_25(s32, f32, f32, f32);
void playFX_26(s32, f32, f32, f32);
EffectInstance* playFX_27(s32, f32, f32, f32, f32, s32);
void fx_sweat(s32, f32 x, f32 y, f32 z, f32, f32, s32);
void fx_sleep_bubble(s32, f32, f32, f32, f32, f32, EffectInstanceData**);
void fx_sleep_bubble(s32, f32, f32, f32, f32, f32, s32);
EffectInstance* playFX_2A(s32, f32, f32, f32);
EffectInstance* playFX_2B(s32, f32, f32, f32);
EffectInstance* playFX_2C(s32, f32, f32, f32);
void playFX_2D(s32, f32, f32, f32, s32, s32);
void playFX_2E(s32, f32, f32, f32, f32, s32);
void playFX_2F(s32, f32, f32, f32, f32, s32, EffectInstanceData**);
void playFX_2F(s32, f32, f32, f32, f32, s32, s32);
void playFX_30(s32, f32, f32, f32);
void playFX_31(s32, f32, f32, f32);
void playFX_32(s32, f32, f32, f32, f32);
EffectInstance* playFX_33(s32, f32, f32, f32, f32, s32);
EffectInstance* playFX_34(s32, f32, f32, f32, f32, EffectInstanceData**);
EffectInstance* playFX_35(s32, f32, f32, f32, f32, EffectInstanceData**);
EffectInstance* playFX_34(s32, f32, f32, f32, f32, s32);
EffectInstance* playFX_35(s32, f32, f32, f32, f32, s32);
EffectInstance* playFX_36(s32, f32, f32, f32, f32, f32);
EffectInstance* playFX_37(s32, f32, f32, f32, f32, f32, f32, s32, s32, s32);
EffectInstance* playFX_38(s32, f32, f32, f32, f32, s32);
EffectInstance* playFX_39(s32, f32, f32, f32, f32, s32);
EffectInstance* playFX_3A(s32, f32, f32, f32, f32, f32, s32, s32);
void playFX_3B(s32, f32, f32, f32, f32, EffectInstanceData**);
EffectInstance* playFX_3C(s32, f32, f32, f32, f32, EffectInstanceData**);
void playFX_3B(s32, f32, f32, f32, f32, s32);
EffectInstance* playFX_3C(s32, f32, f32, f32, f32, s32);
void playFX_3D(s32, f32, f32, f32, f32, f32, f32, s32, s32*);
EffectInstance* playFX_3E(s32, f32, f32, f32, f32, s32);
EffectInstance* playFX_3F(s32, f32, f32, f32, s32);
@ -101,7 +101,7 @@ EffectInstance* playFX_5B(s32, f32, f32, f32, f32, s32);
EffectInstance* playFX_5C(s32, f32, f32, f32, f32, s32);
EffectInstance* playFX_5D(s32, f32, f32, f32, f32, s32);
EffectInstance* playFX_5E(s32, f32, f32, f32, f32, f32, f32, f32, s32);
void playFX_5F(s32, f32 x, f32 y, f32 z, f32 scale /* maybe */, s32);
EffectInstance* playFX_5F(s32, f32 x, f32 y, f32 z, f32 scale /* maybe */, s32);
EffectInstance* playFX_60(s32, f32, f32, f32, f32, s32);
EffectInstance* playFX_61(s32, f32, f32, f32, f32, s32);
EffectInstance* playFX_62(s32, f32, f32, f32, f32, s32);
@ -136,7 +136,7 @@ EffectInstance* playFX_7E(s32, f32, f32, f32, f32, s32);
EffectInstance* playFX_7F(s32, f32, f32, f32, f32, s32);
EffectInstance* playFX_80(s32, f32, f32, f32, f32, s32);
EffectInstance* playFX_81(s32, f32 x, f32 y, f32 z, f32, s32);
void playFX_82(s32, f32, f32, f32, f32, s32 time);
EffectInstance* playFX_82(s32, f32, f32, f32, f32, s32 time);
EffectInstance* playFX_83(s32, f32, f32, f32, f32, s32);
EffectInstance* playFX_84(s32, f32, f32, f32, f32, f32);
EffectInstance* playFX_85(s32, f32, f32, f32, f32, s32);

View File

@ -194,6 +194,10 @@ s32 battle_heap_create(void);
void filemenu_init(s32);
s32 test_ray_zones(f32, f32, f32, f32*, f32*, f32*, f32*, f32*, f32*, f32*);
s32 test_ray_colliders(s32 ignoreFlags, f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ, f32* hitX,
f32* hitY, f32* hitZ, f32* hitDepth, f32* hitNx, f32* hitNy, f32* hitNz);
s32 test_ray_entities(f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ, f32* hitX, f32* hitY, f32* hitZ,
f32* hitDepth, f32* hitNx, f32* hitNy, f32* hitNz);
void mem_clear(s8* data, s32 numBytes);

14
include/mips.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef _MIPS_H_
#define _MIPS_H_
#define JAL 0x03
#define ADDIU 0x09
#define LUI 0x0F
#define LW 0x23
#define LOWER(x) ((x) & 0xFFFF)
#define UPPER(x) ((x) >> 16)
#define OPCODE(x) ((x) >> 26)
#define GET_RS(x) ((x >> 0x15) & 0x1F)
#define GET_RT(x) (UPPER(x) & 0x1F)
#endif

View File

@ -288,8 +288,9 @@ extern f32 D_800F7B40;
extern s32 D_800F7B44;
extern f32 D_8010C938;
extern f32 D_8010C990;
extern s32 D_8010C978;
extern Temp8010EBB0 D_8010EBB0; // something with partners
extern PartnerActionStatus gPartnerActionStatus; // something with partners
extern Temp8010F250 D_8010F250; // sfx_play_sound state struct?
// Effects

View File

@ -1,3 +1,53 @@
#include "common.h"
#include "nu/nusys.h"
#include "ld_addrs.h"
#include "mips.h"
INCLUDE_ASM(s32, "316C00", func_802AE000_316C00);
extern s32 D_7012BC11[];
void func_802AE000_316C00(void) {
s32(*readFunc)(OSPiHandle*, u32, u32*);
UNK_FUN_PTR(generalHeapCreate);
u32 thisInsn;
u32* it;
u32 prevInsn;
s32 seed;
u32 blah;
u32 hash;
readFunc = osEPiReadIo;
seed = 0x4BF15BF6; // 0x3C016C07 + 0xFEFEFEF;
generalHeapCreate = D_7012BC11; // 0x8002AC00 - 0xFEFEFEF (the former address being that of general_heap_create)
hash = 0;
readFunc(nuPiCartHandle, 0xB0000574, &thisInsn);
seed -= thisInsn; // thisInsn = 0x3C016C07 here
prevInsn = 0;
for (it = _316A70_ROM_START; it < _316A70_ROM_END; it++) {
readFunc(nuPiCartHandle, it, &thisInsn);
hash += LOWER(thisInsn) + UPPER(thisInsn);
if (OPCODE(prevInsn) == LUI && (OPCODE(thisInsn) == ADDIU || OPCODE(thisInsn) == LW)) {
if (GET_RS(thisInsn) == GET_RT(prevInsn) && GET_RS(thisInsn) == GET_RT(thisInsn)) {
hash -= LOWER(thisInsn);
hash -= LOWER(prevInsn);
}
}
if (OPCODE(thisInsn) == JAL) {
hash -= LOWER(thisInsn) + (UPPER(thisInsn) & 0xFC00);
}
prevInsn = thisInsn;
}
generalHeapCreate += seed + 0x2499BF - hash;
// If the function's address is 0x8XXXXXXX
if (((u32)generalHeapCreate >> 0x1C) == 8) {
// Call the function that ends up being generalHeapCreate
(generalHeapCreate)();
}
}

View File

@ -1,3 +1,54 @@
#include "common.h"
#include "nu/nusys.h"
#include "ld_addrs.h"
#include "mips.h"
INCLUDE_ASM(s32, "316d90", func_802AE000);
extern s32 D_7012ACA1[];
void func_802AE000(void) {
s32(*readFunc)(OSPiHandle*, u32, u32*);
UNK_FUN_PTR(aFunction);
u32 thisInsn;
u32* it;
u32 prevInsn;
s32 seed;
u32 blah;
u32 hash;
readFunc = osEPiReadIo;
seed = 0x33F50000;
aFunction = D_7012ACA1;
hash = 0;
readFunc(nuPiCartHandle, 0xB0000800, &thisInsn);
seed -= thisInsn;
prevInsn = 0;
for (it = _316C00_ROM_START; it < _316C00_ROM_END; it++) {
readFunc(nuPiCartHandle, it, &thisInsn);
hash += LOWER(thisInsn) + UPPER(thisInsn);
if (OPCODE(prevInsn) == LUI && (OPCODE(thisInsn) == ADDIU || OPCODE(thisInsn) == LW)) {
if (GET_RS(thisInsn) == GET_RT(prevInsn) && GET_RS(thisInsn) == GET_RT(thisInsn)) {
hash -= LOWER(thisInsn);
hash -= LOWER(prevInsn);
}
}
if (OPCODE(thisInsn) == JAL) {
hash -= LOWER(thisInsn) + (UPPER(thisInsn) & 0xFC00);
}
prevInsn = thisInsn;
}
aFunction += seed + 0x291993 - hash;
// If the function's address is 0x8XXXXXXX
if (((u32)aFunction >> 0x1C) == 8) {
(aFunction)();
} else {
_heap_create(&D_803DA800, 0x10000);
}
}

View File

@ -17,7 +17,7 @@ void func_802B203C(void) {
void func_802B2078(void) {
dma_copy(_316C00_ROM_START, _316C00_ROM_END, _316C00_VRAM);
func_802AE000();
func_802AE000_316C00();
}
void func_802B20B4(void) {

View File

@ -67,7 +67,20 @@ INCLUDE_ASM(void, "362a0_len_2f70", load_hit_data, s32 idx, HitAsset* hit);
INCLUDE_ASM(void, "362a0_len_2f70", parent_collider_to_model, s32 colliderID, s16 modelIndex);
INCLUDE_ASM(s32, "362a0_len_2f70", _add_hit_vert_to_buffer);
void _add_hit_vert_to_buffer(f32** buf, f32* vert, s32* bufSize) {
s32 i;
for (i = 0; i < *bufSize; i++) {
if (buf[i] == vert) {
break;
}
}
if (i == *bufSize) {
buf[i] = vert;
(*bufSize)++;
}
}
s32 _get_hit_vert_index_from_buffer(f32** buffer, f32* vert, s32* bufferSize) {
s32 i;
@ -84,40 +97,110 @@ s32 _get_hit_vert_index_from_buffer(f32** buffer, f32* vert, s32* bufferSize) {
INCLUDE_ASM(void, "362a0_len_2f70", update_collider_transform, s16 colliderID);
// Simon says there's a struct size issue here which is causing the subu/addu issue
#ifdef NON_MATCHING
s32 get_collider_type_by_id(s32 colliderID) {
if (colliderID & 0x4000) {
return 0;
} else {
return gCollisionData.collider_list[colliderID].flags;
return gCollisionData.colliderList[colliderID].flags;
}
}
#else
INCLUDE_ASM(s32, "362a0_len_2f70", get_collider_type_by_id);
#endif
INCLUDE_ASM(s32, "362a0_len_2f70", get_flat_collider_normal);
void get_flat_collider_normal(s32 colliderID, f32* x, f32* y, f32* z) {
ColliderTriangle* triangle = &gCollisionData.colliderList[colliderID].triangleTable[0];
INCLUDE_ASM(void, "362a0_len_2f70", get_collider_center, s32 colliderID, f32* x, f32* y, f32* z);
*x = triangle->normal.x;
*y = triangle->normal.y;
*z = triangle->normal.z;
}
void get_collider_center(s32 colliderID, f32* x, f32* y, f32* z) {
ColliderBoundingBox* aabb = gCollisionData.colliderList[colliderID].aabb;
*x = (aabb->min[0] + aabb->max[0]) * 0.5f;
*y = (aabb->min[1] + aabb->max[1]) * 0.5f;
*z = (aabb->min[2] + aabb->max[2]) * 0.5f;
}
INCLUDE_ASM(s32, "362a0_len_2f70", test_ray_triangle_general);
INCLUDE_ASM(s32, "362a0_len_2f70", test_down_ray_triangle);
INCLUDE_ASM(s32, "362a0_len_2f70", test_up_ray_triangle);
s32 test_up_ray_triangle(ColliderTriangle* triangle, f32* vertices);
INCLUDE_ASM(s32, "362a0_len_2f70", test_up_ray_triangle, ColliderTriangle* triangle, f32* vertices);
INCLUDE_ASM(s32, "362a0_len_2f70", test_ray_colliders);
INCLUDE_ASM(s32, "362a0_len_2f70", test_ray_colliders, s32 ignoreFlags, f32 startX, f32 startY, f32 startZ, f32 dirX,
f32 dirY, f32 dirZ, f32* hitX, f32* hitY, f32* hitZ, f32* hitDepth, f32* hitNx, f32* hitNy, f32* hitNz);
INCLUDE_ASM(s32, "362a0_len_2f70", test_ray_zones, f32 arg0, f32 arg1, f32 arg2, f32* arg3, f32* arg4, f32* arg5, f32* arg6, f32* arg7, f32* arg8, f32* arg9);
INCLUDE_ASM(s32, "362a0_len_2f70", test_up_ray_collider);
//s32 test_up_ray_collider(s32 ignoreFlags, s32 colliderID, f32 x, f32 y, f32 z, f32 length, f32 yaw);
// Close, but no cigar
extern f32 D_800A4230;
extern f32 D_800A4234;
extern f32 D_800A4238;
extern f32 D_800A423C;
extern s32 D_800A4240;
extern f32 D_800A4244;
extern f32 D_800A4254;
INCLUDE_ASM(s32, "362a0_len_2f70", test_ray_entities);
#ifdef NON_MATCHING
f32 test_up_ray_collider(s32 ignoreFlags, s32 colliderID, f32 x, f32 y, f32 z, f32 length, f32 yaw) {
CollisionData* collisionData = &gCollisionData;
f32 cosTheta;
f32 sinTheta;
Collider* collider;
ColliderTriangle* triangleTable;
s32 i;
f32 ret;
sin_cos_rad(yaw * TAU / 360.0f, &sinTheta, &cosTheta);
collider = &collisionData->colliderList[colliderID];
D_800A4240 = 0;
D_800A4230 = x;
D_800A4234 = y;
D_800A4238 = z;
D_800A4254 = length;
D_800A423C = sinTheta;
D_800A4244 = -cosTheta;
ret = -1.0f;
if (!(collider->flags & ignoreFlags)) {
if (collider->numTriangles != 0) {
triangleTable = collider->triangleTable;
for (i = 0; i < collider->numTriangles; i++) {
if (test_up_ray_triangle(&triangleTable[i], collisionData->vertices)) {
ret = D_800A4254;
}
}
}
}
return ret;
}
#else
INCLUDE_ASM(s32, "362a0_len_2f70", test_up_ray_collider, s32 ignoreFlags, s32 colliderID, f32 x, f32 y, f32 z, f32 length, f32 yaw);
#endif
INCLUDE_ASM(s32, "362a0_len_2f70", test_ray_entities, f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ,
f32* hitX, f32* hitY, f32* hitZ, f32* hitDepth, f32* hitNx, f32* hitNy, f32* hitNz);
INCLUDE_ASM(s32, "362a0_len_2f70", func_8005DB00);
INCLUDE_ASM(s32, "362a0_len_2f70", func_8005DD54);
ApiStatus func_8005DD54(ScriptInstance* script, s32 isInitialCall) {
f32 angle = clamp_angle(script->varTable[0]);
script->varTable[0] = angle;
if (angle >= 180.0f) {
angle -= 180.0f;
}
if (angle >= 90.0f) {
angle = 180.0f - angle;
}
script->varTable[2] = (s32) (((90.0f - angle) * 95.0f) / 90.0f) + 160;
return ApiStatus_DONE2;
}
s32 func_8005DDF0(void) {
return ~gCurrentEncounter.unk_08 != 0;

View File

@ -10,28 +10,141 @@ INCLUDE_ASM(s32, "759b0_len_61b0", npc_raycast_down_sides, s32 arg0, f32* arg1,
INCLUDE_ASM(s32, "759b0_len_61b0", npc_raycast_up);
INCLUDE_ASM(s32, "759b0_len_61b0", npc_raycast_up_corner);
s32 npc_raycast_up_corner(s32 ignoreFlags, f32* x, f32* y, f32* z, f32* length);
INCLUDE_ASM(s32, "759b0_len_61b0", npc_raycast_up_corner, s32 ignoreFlags, f32* x, f32* y, f32* z, f32* length);
INCLUDE_ASM(s32, "759b0_len_61b0", npc_raycast_up_corners);
INCLUDE_ASM(s32, "759b0_len_61b0", npc_raycast_general);
s32 npc_raycast_general(s32 ignoreFlags, f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ, f32* hitX,
f32* hitY, f32* hitZ, f32* outDepth, f32* hitNx, f32* hitNy, f32* hitNz);
// Dumb float regalloc
#ifdef NON_MATCHING
s32 npc_raycast_general(s32 flags, f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ, f32* hitX,
f32* hitY, f32* hitZ, f32* outDepth, f32* hitNx, f32* hitNy, f32* hitNz) {
s32 entityID;
s32 ret;
void npc_get_slip_vector(f32* arg0, f32* arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5) {
f32 temp = (arg2 * arg4) + (arg3 * arg5);
ret = -1;
if (flags & 0x100000) {
entityID = test_ray_entities(startX, startY, startZ, dirX, dirY, dirZ, hitX, hitY, hitZ, outDepth, hitNx, hitNy,
hitNz);
if (entityID >= 0) {
ret = entityID | 0x4000;
}
} else {
ret = test_ray_colliders(flags, startX, startY, startZ, dirX, dirY, dirZ, hitX, hitY, hitZ, outDepth, hitNx,
hitNy, hitNz);
if (flags & 0x40000) {
return ret;
}
*arg0 = (arg2 - (temp * arg4)) * 0.5f;
*arg1 = (arg3 - (temp * arg5)) * 0.5f;
entityID = test_ray_entities(startX, startY, startZ, dirX, dirY, dirZ, hitX, hitY, hitZ, outDepth, hitNx,
hitNy, hitNz);
if (entityID >= 0) {
ret = entityID | 0x4000;
}
}
return ret;
}
#else
INCLUDE_ASM(s32, "759b0_len_61b0", npc_raycast_general, s32 ignoreFlags, f32 startX, f32 startY, f32 startZ, f32 dirX,
f32 dirY, f32 dirZ, f32* hitX, f32* hitY, f32* hitZ, f32* outDepth, f32* hitNx, f32* hitNy, f32* hitNz);
#endif
void npc_get_slip_vector(f32* outX, f32* outZ, f32 aX, f32 aZ, f32 bX, f32 bZ) {
f32 dotProduct = (aX * bX) + (aZ * bZ);
*outX = (aX - (dotProduct * bX)) * 0.5f;
*outZ = (aZ - (dotProduct * bZ)) * 0.5f;
}
INCLUDE_ASM(s32, "759b0_len_61b0", npc_test_move_with_slipping);
s32 npc_test_move_with_slipping(s32 ignoreFlags, f32* x, f32* y, f32* z, f32 length, f32 yaw, f32 radius);
INCLUDE_ASM(s32, "759b0_len_61b0", npc_test_move_with_slipping, s32 ignoreFlags, f32* x, f32* y, f32* z, f32 length, f32 yaw, f32 radius);
INCLUDE_ASM(s32, "759b0_len_61b0", npc_test_move_without_slipping);
s32 npc_test_move_without_slipping(s32 ignoreFlags, f32* x, f32* y, f32* z, f32 length, f32 yaw, f32 radius) {
s32 ret = -1;
f32 depth;
f32 originalDepth;
f32 dirY;
f32 cosTheta;
f32 hitNx, hitNy, hitNz;
f32 hitX, hitY, hitZ;
s32 hitID;
f32 temp1;
f32 temp2;
INCLUDE_ASM(s32, "759b0_len_61b0", npc_test_move_taller_with_slipping);
sin_cos_rad(yaw * TAU / 360.0f, &dirY, &cosTheta);
cosTheta = -cosTheta;
originalDepth = length + radius + (radius * 0.5f);
depth = originalDepth;
temp1 = length * dirY;
temp2 = length * cosTheta;
INCLUDE_ASM(s32, "759b0_len_61b0", npc_test_move_simple_with_slipping, s32 arg0, f32* arg1, f32* arg2, f32* arg3, f32 arg4, f32 arg5,
f32 arg6, f32 arg7);
hitID = npc_raycast_general(ignoreFlags, *x - (radius * dirY * 0.5f), *y, *z - (radius * cosTheta * 0.5f), dirY,
0.0f, cosTheta, &hitX, &hitY, &hitZ, &depth, &hitNx, &hitNy, &hitNz);
if (hitID >= 0 && depth <= originalDepth) {
f32 depthDiff = depth - originalDepth;
f32 cosThetaTemp = cosTheta; // needed to match
*x += depthDiff * dirY;
*z += depthDiff * cosThetaTemp;
D_8010C978 = hitID;
ret = hitID;
}
*x += temp1;
*z += temp2;
return ret;
}
s32 npc_test_move_taller_with_slipping(s32 ignoreFlags, f32* x, f32* y, f32* z, f32 length, f32 yaw, f32 height,
f32 radius) {
f32 xTemp = *x;
f32 yTemp = *y + height - 1.0f;
f32 zTemp = *z;
s32 ret;
radius *= 0.5f;
if (npc_test_move_with_slipping(ignoreFlags, &xTemp, &yTemp, &zTemp, fabsf(length), yaw, radius) < 0) {
xTemp = *x;
yTemp = *y + 10.01f;
zTemp = *z;
ret = npc_test_move_with_slipping(ignoreFlags, &xTemp, &yTemp, &zTemp, fabsf(length), yaw, radius) >= 0;
*x = xTemp;
*z = zTemp;
} else {
ret = 1;
*x = xTemp;
*z = zTemp;
}
return ret;
}
s32 npc_test_move_simple_with_slipping(s32 ignoreFlags, f32* x, f32* y, f32* z, f32 length, f32 yaw, f32 height,
f32 radius) {
f32 tempX = *x;
f32 tempY = *y + 10.01f;
f32 tempZ = *z;
s32 hitID = npc_test_move_with_slipping(ignoreFlags, &tempX, &tempY, &tempZ, fabsf(length), yaw, radius * 0.5f);
*x = tempX;
*z = tempZ;
return hitID >= 0;
}
s32 npc_test_move_simple_without_slipping(s32 ignoreFlags, f32* x, f32* y, f32* z, f32 length, f32 yaw, f32 height,
f32 radius) {
f32 tempX = *x;
f32 tempY = *y + 10.01f;
f32 tempZ = *z;
s32 hitID = npc_test_move_without_slipping(ignoreFlags, &tempX, &tempY, &tempZ, fabsf(length), yaw, radius * 0.5f);
*x = tempX;
*z = tempZ;
return hitID >= 0;
}
INCLUDE_ASM(s32, "759b0_len_61b0", npc_test_move_simple_without_slipping);
INCLUDE_ASM(s32, "759b0_len_61b0", npc_test_move_complex_with_slipping);

View File

@ -350,9 +350,10 @@ void player_reset_data(void) {
}
s32 func_800DFCF4(void) {
if (D_8010EBB0.unk_00 == 1 &&
(D_8010EBB0.unk_03 == 6 || D_8010EBB0.unk_03 == 9 || D_8010EBB0.unk_03 == 7 || D_8010EBB0.unk_03 == 4 ||
D_8010EBB0.unk_03 == 8)) {
if (gPartnerActionStatus.actionState.b[0] == 1 &&
(gPartnerActionStatus.actionState.b[3] == 6 || gPartnerActionStatus.actionState.b[3] == 9 ||
gPartnerActionStatus.actionState.b[3] == 7 || gPartnerActionStatus.actionState.b[3] == 4 ||
gPartnerActionStatus.actionState.b[3] == 8)) {
return 0;
}
return 1;
@ -455,7 +456,7 @@ s32 func_800E0208(void) {
s32 ret = 0;
if (gGameStatusPtr->disableScripts && (gGameStatusPtr->currentButtons & 0x10)) {
if (D_8010EBB0.unk_00 == 0) {
if (gPartnerActionStatus.actionState.b[0] == 0) {
set_action_state(ACTION_STATE_IDLE);
}
ret = 1;

317
src/7E9D0.c Normal file
View File

@ -0,0 +1,317 @@
#include "common.h"
#include "world/partners.h"
extern s32 D_8010C924;
extern s32 D_8010C964;
extern s32 D_8010C96C; // npc list index
extern s32 gSpinHistoryBufferPos;
extern s16 D_8010C9B0;
extern s32 gSpinHistoryPosY[5];
extern s32 gSpinHistoryPosX[5];
extern s32 gSpinHistoryPosZ[5];
extern s16 gSpinHistoryPosAngle[5];
void func_800E5520(void) {
D_8010C9B0 = 0;
}
INCLUDE_ASM(void, "7bb60_len_41b0", phys_adjust_cam_on_landing);
void phys_clear_spin_history(void) {
s32 i;
gSpinHistoryBufferPos = 0;
for (i = 0; i < ARRAY_COUNT(gSpinHistoryPosY); i++) {
gSpinHistoryPosAngle[i] = 180;
gSpinHistoryPosY[i] = 0x80000000;
}
}
f32 phys_get_spin_history(s32 lag, s32* x, s32* y, s32* z) {
s32 idx = gSpinHistoryBufferPos;
// Can't get this if/else to match otherwise...
if (idx - lag >= 0) {
idx -= lag;
} else {
idx = gSpinHistoryBufferPos - lag + 5;
}
*x = gSpinHistoryPosX[idx];
*y = gSpinHistoryPosY[idx];
*z = gSpinHistoryPosZ[idx];
return gSpinHistoryPosAngle[idx];
}
void phys_reset_spin_history(void) {
s32 i;
mem_clear(&D_8010F250, sizeof(Temp8010F250));
gSpinHistoryBufferPos = 0;
for (i = 0; i < ARRAY_COUNT(gSpinHistoryPosAngle); i++) {
gSpinHistoryPosAngle[i] = 0;
gSpinHistoryPosX[i] = 0;
gSpinHistoryPosY[i] = 0;
gSpinHistoryPosZ[i] = 0;
}
D_8010C964 = 0;
D_8010C924 = 0;
}
INCLUDE_ASM(s32, "7bb60_len_41b0", phys_update_action_state);
INCLUDE_ASM(s32, "7bb60_len_41b0", phys_peach_update);
void set_action_state(s32 actionState) {
PlayerStatus* playerStatus = &gPlayerStatus;
PlayerData* playerData = &gPlayerData;
UNK_TYPE* unknownStruct = &D_8010F250;
if (playerStatus->flags & 0x200) {
playerStatus->flags &= ~0x200;
enable_player_input();
}
if (playerStatus->animFlags & 0x4000) {
// TODO figure this out
#ifdef NON_MATCHING
if (
actionState == ACTION_STATE_IDLE || actionState == ACTION_STATE_WALK ||
actionState == ACTION_STATE_RUN || actionState == ACTION_STATE_JUMP ||
actionState == ACTION_STATE_BOUNCE || actionState == ACTION_STATE_HOP ||
actionState == ACTION_STATE_LAUNCH || actionState == ACTION_STATE_LAND_ON_SWITCH ||
actionState == ACTION_STATE_FALLING || actionState == ACTION_STATE_STEP_DOWN ||
actionState == ACTION_STATE_LAND || actionState == ACTION_STATE_STEP_DOWN_LAND
) {
#else
if (actionState < ACTION_STATE_TALK)
if (actionState >= 0) {
#endif
playerStatus->prevActionState = playerStatus->actionState;
playerStatus->actionState = actionState;
playerStatus->flags |= 0x80000000;
}
return;
}
if (actionState == ACTION_STATE_HIT_FIRE || actionState == ACTION_STATE_HIT_LAVA) {
PartnerID partner;
if (playerStatus->unk_BF == 3) {
actionState = ACTION_STATE_HIT_FIRE;
}
// Whilst Sushie, Lakilester, Parakarry's ability is active, hazards have no effect.
partner = playerData->currentPartner;
if (partner == PARTNER_SUSHIE || partner == PARTNER_LAKILESTER || partner == PARTNER_PARAKARRY) {
if (gPartnerActionStatus.actionState.b[0] != 0) {
playerStatus->animFlags |= 0x4;
playerStatus->flags |= 0x800;
return;
}
}
}
if (actionState == ACTION_STATE_SLIDE) {
playerStatus->flags |= 0x10;
playerStatus->moveFrames = 0;
playerStatus->flags &= ~0x4000;
}
playerStatus->prevActionState = playerStatus->actionState;
if (actionState == ACTION_STATE_USE_TWEESTER) {
playerStatus->prevActionState = ACTION_STATE_IDLE;
}
if (actionState == ACTION_STATE_ENEMY_FIRST_STRIKE) {
playerStatus->animFlags |= 4;
}
playerStatus->actionState = actionState;
playerStatus->flags |= 0x80000000;
if (playerStatus->actionState == ACTION_STATE_SPIN) {
return;
}
playerStatus->flags &= ~0x20000;
playerStatus->animFlags &= ~0x10000;
if (unknownStruct[0xC]) {
sfx_stop_sound(unknownStruct[0xC]);
}
if (playerStatus->unk_D8) {
playerStatus->unk_D8[3][9] = 0xA;
playerStatus->unk_D8 = NULL;
}
}
void update_locomotion_state(void) {
PlayerStatus* playerStatus = &gPlayerStatus;
do { } while (0); // required to match
set_action_state((!is_ability_active(ABILITY_SLOW_GO)
&& (SQ(playerStatus->stickAxis[0]) + SQ(playerStatus->stickAxis[1]) >= 0xBD2)) ? ACTION_STATE_RUN : ACTION_STATE_WALK);
}
void start_falling(void) {
PlayerStatus* playerStatus = &gPlayerStatus;
set_action_state(ACTION_STATE_FALLING);
playerStatus->gravityIntegrator[0] = 0.1143f;
playerStatus->gravityIntegrator[1] = -0.2871f;
playerStatus->gravityIntegrator[2] = -0.1823f;
playerStatus->gravityIntegrator[3] = 0.01152f;
}
void start_bounce_a(void) {
PlayerStatus* playerStatus = &gPlayerStatus;
set_action_state(ACTION_STATE_BOUNCE);
playerStatus->gravityIntegrator[0] = 10.0f;
playerStatus->gravityIntegrator[1] = -2.0f;
playerStatus->gravityIntegrator[2] = 0.8f;
playerStatus->gravityIntegrator[3] = -0.75f;
}
void start_bounce_b(void) {
PlayerStatus* playerStatus = &gPlayerStatus;
set_action_state(ACTION_STATE_BOUNCE);
playerStatus->gravityIntegrator[0] = 8.0f;
playerStatus->gravityIntegrator[1] = -1.0f;
playerStatus->gravityIntegrator[2] = 0;
playerStatus->gravityIntegrator[3] = 0;
playerStatus->flags |= 0x800000;
}
// TODO playerData isn't used
s32 check_input_hammer(void) {
PlayerData* playerData = &gPlayerData;
if (gPlayerStatus.pressedButtons & BUTTON_B) {
if (!(gPlayerStatus.flags & 4)) {
if (gPartnerActionStatus.actionState.b[0] != 1 || gPlayerData.currentPartner != PARTNER_WATT) {
if (gPlayerData.hammerLevel != -1) {
set_action_state(ACTION_STATE_HAMMER);
return TRUE;
}
}
}
}
return FALSE;
}
INCLUDE_ASM(s32, "7bb60_len_41b0", check_input_jump);
void check_input_spin(void) {
PlayerStatus* playerStatus = &gPlayerStatus;
Temp8010F250* temp_8010F250 = &D_8010F250;
Temp8010F250* temp2 = temp_8010F250;
if (!(playerStatus->flags & (PLAYER_ANIM_FLAG_8BIT_MARIO | PLAYER_ANIM_FLAG_PEACH_PHYSICS)) &&
!(playerStatus->animFlags & 1) &&
!(playerStatus->currentButtons & D_CBUTTONS) &&
!is_ability_active(ABILITY_SLOW_GO)) {
s32 actionState = playerStatus->actionState;
s32 btnPressed = playerStatus->pressedButtons & Z_TRIG;
// TODO
if (actionState != 0x21) {
if (actionState < 0x22) {
if (actionState < 3) {
if (actionState >= 0 && !(playerStatus->animFlags & 0x10000)) {
if (btnPressed || temp_8010F250->unk_01) {
set_action_state(ACTION_STATE_SPIN);
if (temp_8010F250->unk_01 != 0) {
if (temp_8010F250->unk_08 != 0 || temp_8010F250->unk_0C != 0) {
playerStatus->prevActionState = temp2->unk_07;
} else {
playerStatus->prevActionState = ACTION_STATE_IDLE;
}
}
}
}
}
}
}
}
}
void peach_set_disguise_anim(s32 arg0) {
s32 listIndex = D_8010C96C;
if (listIndex >= 0) {
get_npc_by_index(listIndex)->currentAnim.w = arg0;
}
}
void func_800E63A4(s32 arg0) {
PlayerStatus* playerStatus = &gPlayerStatus;
if (arg0 != 0) {
set_action_state(ACTION_STATE_SNEAKY_PARASOL);
} else {
playerStatus->animFlags &= ~PLAYER_ANIM_FLAG_IN_DISGUISE;
gGameStatusPtr->peachFlags &= ~0x2;
playerStatus->peachDisguise = 0;
free_npc_by_index(D_8010C96C);
set_action_state(ACTION_STATE_IDLE);
playerStatus->colliderHeight = 55;
playerStatus->colliderDiameter = 38;
}
}
void peach_check_for_parasol_input(void) {
PlayerStatus* playerStatus = &gPlayerStatus;
s32 actionState = playerStatus->actionState;
Npc* disguiseNpc;
if (actionState == ACTION_STATE_IDLE || actionState == ACTION_STATE_WALK || actionState == ACTION_STATE_RUN) {
if (D_8010C92C != 0) {
D_8010C92C--;
if (D_8010C92C == 0) {
if (gGameStatusPtr->peachFlags & 2) {
playerStatus->animFlags |= PLAYER_ANIM_FLAG_IN_DISGUISE;
gGameStatusPtr->peachFlags |= 2;
disguiseNpc = peach_make_disguise_npc(gGameStatusPtr->peachDisguise);
if (disguiseNpc != NULL) {
disguiseNpc->flags &= ~NPC_FLAG_40000;
}
}
}
} else if (gGameStatusPtr->peachFlags & 4 && playerStatus->pressedButtons & B_BUTTON) {
set_action_state(ACTION_STATE_SNEAKY_PARASOL);
}
}
}
void peach_sync_disguise_npc(void) {
PlayerStatus* playerStatus = &gPlayerStatus;
if (D_8010C96C >= 0) {
Npc* npc = get_npc_by_index(D_8010C96C);
if (npc->flags & NPC_FLAG_40000) {
npc->renderYaw = playerStatus->spriteFacingAngle;
} else {
npc->yaw = playerStatus->targetYaw;
}
npc->pos.x = playerStatus->position.x;
npc->pos.y = playerStatus->position.y;
npc->pos.z = playerStatus->position.z;
}
}
INCLUDE_ASM(Npc*, "7bb60_len_41b0", peach_make_disguise_npc, s32 peachDisguise);
INCLUDE_ASM(s32, "7bb60_len_41b0", peach_disguise_check_overlaps);

View File

@ -1,9 +1,6 @@
#include "common.h"
#include "world/partners.h"
extern s32 D_8010C96C; // npc list index
extern s16 D_8010C9B0;
void record_jump_apex(void) {
gPlayerStatus.jumpApexHeight = gPlayerStatus.position.y;
}
@ -11,7 +8,7 @@ void record_jump_apex(void) {
s32 can_trigger_loading_zone(void) {
PlayerData* playerData = &gPlayerData;
s32 actionState = gPlayerStatusPtr->actionState;
Temp8010EBB0* temp_8010EBB0 = &D_8010EBB0;
PartnerActionStatus* partnerActionStatus = &gPartnerActionStatus;
if (actionState == ACTION_STATE_IDLE ||
actionState == ACTION_STATE_WALK ||
@ -24,17 +21,17 @@ s32 can_trigger_loading_zone(void) {
if (actionState == ACTION_STATE_RIDE) {
if (playerData->currentPartner == PARTNER_LAKILESTER || playerData->currentPartner == PARTNER_BOW) {
if (temp_8010EBB0->unk_00 != 0) {
if (partnerActionStatus->actionState.b[0] != 0) {
return TRUE;
} else {
gPlayerStatusPtr->animFlags |= 4;
return FALSE;
}
} else {
if (temp_8010EBB0->unk_03 == 6 || temp_8010EBB0->unk_03 == 7) {
return temp_8010EBB0->unk_00 != 0;
if (partnerActionStatus->actionState.b[3] == 6 || partnerActionStatus->actionState.b[3] == 7) {
return partnerActionStatus->actionState.b[0] != 0;
}
if (temp_8010EBB0->unk_03 == 4) {
if (partnerActionStatus->actionState.b[3] == 4) {
gPlayerStatusPtr->animFlags |= 4;
return FALSE;
}
@ -43,8 +40,6 @@ s32 can_trigger_loading_zone(void) {
return FALSE;
}
void set_action_state(s32 actionState);
void move_player(s32 duration, f32 heading, f32 speed) {
gPlayerStatus.flags |= 0x4000;
gPlayerStatus.heading = heading;
@ -94,7 +89,7 @@ void phys_init_integrator_for_current_state() {
playerStatus->gravityIntegrator[0] = *temp_a0++;
playerStatus->gravityIntegrator[1] = *temp_a0++;
playerStatus->gravityIntegrator[2] = *temp_a0++;
playerStatus->gravityIntegrator[3] = *temp_a0;
playerStatus->gravityIntegrator[3] = *temp_a0++;
return;
}
@ -110,42 +105,25 @@ void phys_init_integrator_for_current_state() {
INCLUDE_ASM(void, "7bb60_len_41b0", phys_init_integrator_for_current_state);
#endif // NON_MATCHING
#ifdef NON_MATCHING
// void gravity_use_fall_parms(void) {
// f32* floats = D_800F7B60;
// do { } while (0);
// if (gPlayerStatus.flags & 0x40000) {
// gPlayerStatus.gravityIntegrator[0] = *floats++ / 12.0f;
// gPlayerStatus.gravityIntegrator[1] = *floats++ / 12.0f;
// gPlayerStatus.gravityIntegrator[2] = *floats++ / 12.0f;
// gPlayerStatus.gravityIntegrator[3] = *floats++ / 12.0f;
// } else {
// gPlayerStatus.gravityIntegrator[0] = *floats++;
// gPlayerStatus.gravityIntegrator[1] = *floats++;
// gPlayerStatus.gravityIntegrator[2] = *floats++;
// gPlayerStatus.gravityIntegrator[3] = *floats++;
// }
// }
// This function is wack. This weird stuff is needed to match
void gravity_use_fall_parms(void) {
PlayerStatus* playerStatus;
f32* floats = D_800F7B60;
PlayerStatus* playerStatus;
do {} while (0);
playerStatus = &gPlayerStatus;
if (playerStatus->flags & 0x40000) {
playerStatus->gravityIntegrator[0] = (*(floats++)) / 12.0f;
playerStatus->gravityIntegrator[1] = (*(floats++)) / 12.0f;
playerStatus->gravityIntegrator[2] = (*(floats++)) / 12.0f;
playerStatus->gravityIntegrator[3] = (*(floats++)) / 12.0f;
playerStatus->gravityIntegrator[0] = *floats++ / 12.0f;
playerStatus->gravityIntegrator[1] = *floats++ / 12.0f;
playerStatus->gravityIntegrator[2] = *floats++ / 12.0f;
playerStatus->gravityIntegrator[3] = *floats++ / 12.0f;
} else {
playerStatus->gravityIntegrator[0] = *(floats++);
playerStatus->gravityIntegrator[1] = *(floats++);
playerStatus->gravityIntegrator[2] = *(floats++);
playerStatus->gravityIntegrator[3] = *(floats++);
playerStatus->gravityIntegrator[0] = *floats++;
playerStatus->gravityIntegrator[1] = *floats++;
playerStatus->gravityIntegrator[2] = *floats++;
playerStatus->gravityIntegrator[3] = *floats++;
}
}
#else
INCLUDE_ASM(s32, "7bb60_len_41b0", gravity_use_fall_parms);
#endif
void phys_update_falling(void) {
if (gPlayerStatus.actionState != ACTION_STATE_LAND_ON_SWITCH && gPlayerStatus.actionState != ACTION_STATE_BOUNCE) {
@ -157,7 +135,54 @@ void phys_update_falling(void) {
}
}
// Matches but we need to decomp collision_main_lateral since there's a rodata padding issue
#ifdef NON_MATCHING
void func_800E315C(s32 colliderID) {
PlayerStatus* playerStatus = &gPlayerStatus;
PartnerActionStatus* partnerActionStatus = &gPartnerActionStatus;
if (colliderID >= 0) {
u8 colliderType = get_collider_type_by_id(colliderID);
switch (colliderType) {
case 1:
case 4:
case 5:
set_action_state(ACTION_STATE_LAND);
break;
case 3:
if ((partnerActionStatus->actionState.i & 0xFF0000FF) != 0x01000009) {
if (playerStatus->unk_10 == 0) {
if (playerStatus->actionState != ACTION_STATE_HIT_LAVA) {
playerStatus->unk_BF = 1;
set_action_state(ACTION_STATE_HIT_LAVA);
}
} else {
set_action_state(ACTION_STATE_UNKNOWN_16);
}
}
break;
case 2:
if ((partnerActionStatus->actionState.i & 0xFF0000FF) != 0x01000009) {
if (playerStatus->unk_10 == 0) {
if (playerStatus->actionState != ACTION_STATE_HIT_FIRE) {
playerStatus->unk_BF = 2;
set_action_state(ACTION_STATE_HIT_LAVA);
}
break;
}
set_action_state(ACTION_STATE_UNKNOWN_16);
}
break;
default:
phys_player_land();
break;
}
}
}
#else
INCLUDE_ASM(s32, "7bb60_len_41b0", func_800E315C);
#endif
INCLUDE_ASM(s32, "7bb60_len_41b0", phys_player_land);
@ -266,7 +291,18 @@ void collision_check_player_overlaps(void) {
INCLUDE_ASM(s32, "7bb60_len_41b0", phys_should_player_be_sliding);
INCLUDE_ASM(s32, "7bb60_len_41b0", phys_is_on_sloped_ground);
s32 phys_is_on_sloped_ground(void) {
Shadow* playerShadow = get_shadow_by_index(gPlayerStatus.shadowID);
f32 rotZ = playerShadow->rotation.z + 180.0;
f32 rotX = playerShadow->rotation.x + 180.0;
s32 ret = TRUE;
if (fabsf(rotZ) < 20.0f && fabsf(rotX) < 20.0f) {
ret = FALSE;
}
return ret;
}
INCLUDE_ASM(s32, "7bb60_len_41b0", phys_main_collision_below);
@ -356,7 +392,26 @@ void phys_update_interact_collider(void) {
INCLUDE_ASM(s32, "7bb60_len_41b0", phys_check_interactable_collision);
INCLUDE_ASM(s32, "7bb60_len_41b0", phys_can_player_interact);
s32 phys_can_player_interact(void) {
PartnerActionStatus* partnerActionStatus = &gPartnerActionStatus;
PlayerStatus* playerStatus = &gPlayerStatus;
s32 ret = TRUE;
if (gPartnerActionStatus.actionState.b[0] != 0) {
if (gPartnerActionStatus.actionState.b[3] == 3) {
if (gPartnerActionStatus.actionState.b[0] < 3) {
ret = FALSE;
}
} else {
ret = FALSE;
}
} else if (!(gPlayerStatus.actionState == ACTION_STATE_IDLE ||
gPlayerStatus.actionState == ACTION_STATE_WALK ||
gPlayerStatus.actionState == ACTION_STATE_RUN)) {
ret = FALSE;
}
return ret;
}
INCLUDE_ASM(f32, "7bb60_len_41b0", func_800E5348, void);
@ -379,270 +434,3 @@ void phys_save_ground_pos(void) {
playerStatus->lastGoodPosition.y = playerStatus->position.y;
playerStatus->lastGoodPosition.z = playerStatus->position.z;
}
void func_800E5520(void) {
D_8010C9B0 = 0;
}
INCLUDE_ASM(void, "7bb60_len_41b0", phys_adjust_cam_on_landing);
INCLUDE_ASM(s32, "7bb60_len_41b0", phys_clear_spin_history);
INCLUDE_ASM(f32, "7bb60_len_41b0", phys_get_spin_history, s32 lag, s32* x, s32* y, s32* z);
INCLUDE_ASM(s32, "7bb60_len_41b0", phys_reset_spin_history);
INCLUDE_ASM(s32, "7bb60_len_41b0", phys_update_action_state);
INCLUDE_ASM(s32, "7bb60_len_41b0", phys_peach_update);
void set_action_state(s32 actionState) {
PlayerStatus* playerStatus = &gPlayerStatus;
PlayerData* playerData = &gPlayerData;
UNK_TYPE* unknownStruct = &D_8010F250;
if (playerStatus->flags & 0x200) {
playerStatus->flags &= ~0x200;
enable_player_input();
}
if (playerStatus->animFlags & 0x4000) {
// TODO figure this out
#ifdef NON_MATCHING
if (
actionState == ACTION_STATE_IDLE || actionState == ACTION_STATE_WALK ||
actionState == ACTION_STATE_RUN || actionState == ACTION_STATE_JUMP ||
actionState == ACTION_STATE_BOUNCE || actionState == ACTION_STATE_HOP ||
actionState == ACTION_STATE_LAUNCH || actionState == ACTION_STATE_LAND_ON_SWITCH ||
actionState == ACTION_STATE_FALLING || actionState == ACTION_STATE_STEP_DOWN ||
actionState == ACTION_STATE_LAND || actionState == ACTION_STATE_STEP_DOWN_LAND
) {
#else
if (actionState < ACTION_STATE_TALK)
if (actionState >= 0) {
#endif
playerStatus->prevActionState = playerStatus->actionState;
playerStatus->actionState = actionState;
playerStatus->flags |= 0x80000000;
}
return;
}
if (actionState == ACTION_STATE_HIT_FIRE || actionState == ACTION_STATE_HIT_LAVA) {
PartnerID partner;
if (playerStatus->unk_BF == 3) {
actionState = ACTION_STATE_HIT_FIRE;
}
// Whilst Sushie, Lakilester, Parakarry's ability is active, hazards have no effect.
partner = playerData->currentPartner;
if (partner == PARTNER_SUSHIE || partner == PARTNER_LAKILESTER || partner == PARTNER_PARAKARRY) {
if (D_8010EBB0.unk_00 != 0) {
playerStatus->animFlags |= 0x4;
playerStatus->flags |= 0x800;
return;
}
}
}
if (actionState == ACTION_STATE_SLIDE) {
playerStatus->flags |= 0x10;
playerStatus->moveFrames = 0;
playerStatus->flags &= ~0x4000;
}
playerStatus->prevActionState = playerStatus->actionState;
if (actionState == ACTION_STATE_USE_TWEESTER) {
playerStatus->prevActionState = ACTION_STATE_IDLE;
}
if (actionState == ACTION_STATE_ENEMY_FIRST_STRIKE) {
playerStatus->animFlags |= 4;
}
playerStatus->actionState = actionState;
playerStatus->flags |= 0x80000000;
if (playerStatus->actionState == ACTION_STATE_SPIN) {
return;
}
playerStatus->flags &= ~0x20000;
playerStatus->animFlags &= ~0x10000;
if (unknownStruct[0xC]) {
sfx_stop_sound(unknownStruct[0xC]);
}
if (playerStatus->unk_D8) {
playerStatus->unk_D8[3][9] = 0xA;
playerStatus->unk_D8 = NULL;
}
}
void update_locomotion_state(void) {
PlayerStatus* playerStatus = &gPlayerStatus;
do { } while (0); // required to match
set_action_state((!is_ability_active(ABILITY_SLOW_GO)
&& (SQ(playerStatus->stickAxis[0]) + SQ(playerStatus->stickAxis[1]) >= 0xBD2)) ? ACTION_STATE_RUN : ACTION_STATE_WALK