diff --git a/config/rel_slices.yml b/config/rel_slices.yml index 0a536ed0..14dd74b3 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -32,6 +32,11 @@ m_banti.c: .bss: [0x8125A830, 0x8125AC80] m_cockroach.c: .text: [0x80385430, 0x80385A80] +m_collision_obj.c: + .text: [0x80394518, 0x80395B24] + .rodata: [0x80641CE8, 0x80641D20] + .data: [0x80651208,0x806512D8] + .bss: [0x812663D0, 0x81266400] m_common_data.c: .text: [0x80395B24, 0x80395BE8] m_controller.c: diff --git a/include/m_collision_obj.h b/include/m_collision_obj.h index 57efa3b2..4e9c1145 100644 --- a/include/m_collision_obj.h +++ b/include/m_collision_obj.h @@ -2,7 +2,7 @@ #define M_COLLISION_OBJ_H #include "types.h" -#include "m_actor.h" +#include "m_actor_type.h" #include "sys_math3d.h" #include "m_play_h.h" @@ -18,6 +18,15 @@ enum collision_type { ClObj_TYPE_NUM }; +enum weight{ + MASS_IMMOVABLE, + MASS_HEAVY, + MASS_NORMAL +}; + +#define MASSTYPE_IMMOVABLE 0XFF +#define MASSTYPE_HEAVY 0XFE + typedef struct collision_obj_s { ACTOR* owner_actor; // actor which owns this collision object ACTOR* collided_actor; // actor which the owner collided with or NULL @@ -64,6 +73,55 @@ typedef struct collision_obj_pipe_data_s { ClObjPipeAttrData_c attribute_data; } ClObjPipeData_c; +typedef struct collision_check_tris_element_attr_data_s{ + xyz_t vtx[3]; +}ClObjTrisElemAttrData_c; + +typedef struct collision_check_tris_element_data_s{ + ClObjElemData_c element; + ClObjTrisElemAttrData_c data; +}ClObjTrisElemData_c; + +typedef struct collision_check_tris_element_s{ + Math3D_triangle_c tri; + xyz_t t; +}ClObjTrisElemAttr_c; + +typedef struct collision_tris_elem_s{ + ClObjElem_c element; + ClObjTrisElemAttr_c attribute; +}ClObjTrisElem_c; + +typedef struct collision_tris_s { + ClObj_c collision_obj; + int count; + ClObjTrisElem_c* elements; +} ClObjTris_c; + +typedef struct ClObjTris_Init { + ClObjData_c data; + int count; + ClObjTrisElemData_c* elem_data; +} ClObjTrisData_c; + +typedef struct collision_obj_joint_sphere_elem_attribute_s{ + Math3D_sphere_c s1; + Math3D_sphere_c s2; + f32 unk8; + u8 unk14; +}ClObjJntSphElemAttr_c; + +typedef struct collision_joint_sphere_elem_s{ + ClObjElem_c element; + ClObjJntSphElemAttr_c attribute; +}ClObjJntSphElem_c; + +typedef struct collision_joint_sphere_s { + ClObj_c collision_obj; + int count; + ClObjJntSphElem_c* elements; +}ClObjJntSph_c; + #define Cl_COLLIDER_NUM 50 typedef struct collision_check_s { u16 flags; @@ -95,14 +153,74 @@ typedef struct status_data_s { u8 weight; } StatusData_c; -extern void ClObjPipe_ct(GAME_PLAY* play, ClObjPipe_c* pipe); -extern void ClObjPipe_dt(GAME_PLAY* play, ClObjPipe_c* pipe); -extern void ClObjPipe_set5(GAME_PLAY* play, ClObjPipe_c* pipe, ACTOR* owner, ClObjPipeData_c* data); -extern void CollisionCheck_Uty_ActorWorldPosSetPipeC(ACTOR* actor, ClObjPipe_c* col_pipe); -extern int CollisionCheck_setOC(GAME_PLAY* play, CollisionCheck_c* collision_check, ClObj_c* col_obj); -extern void CollisionCheck_Status_set3(Status_c* status, StatusData_c* data); -extern void CollisionCheck_Status_ct(Status_c* status); -extern void CollisionCheck_Status_Clear(Status_c* status); +typedef struct mco_work_s { + int count; + ClObj_c* colliders[10]; +} McoWork; + +extern McoWork mco_work; + + +typedef void (*CollisionOCFunction)(GAME_PLAY*, CollisionCheck_c*, ClObj_c*,ClObj_c*); +typedef int (*CollisionOCClear)(GAME_PLAY*, ClObj_c*); +typedef int (*CollisionClearFunction)(GAME_PLAY*, ClObj_c*); + +extern void CollisionCheck_workTrisElemCenter(ClObjTrisElem_c *, xyz_t *); +extern int ClObj_ct(GAME_PLAY *, ClObj_c *); +extern int ClObj_dt(GAME_PLAY *, ClObj_c *); +extern int ClObj_set4(GAME_PLAY *, ClObj_c *, ACTOR *, ClObjData_c *); +extern void ClObj_OCClear(GAME_PLAY *, ClObj_c *); +extern int ClObjElem_ct(ClObjElem_c *); +extern int ClObjElem_set(ClObjElem_c *, ClObjElemData_c *); +extern void ClObjElem_OCClear(GAME_PLAY *, ClObjElem_c *); +extern int ClObjJntSphElem_OCClear(GAME_PLAY *, ClObjJntSphElem_c *); +extern int ClObjJntSph_OCClear(GAME_PLAY *, ClObj_c *); +extern int ClObjPipeAttr_ct(GAME_PLAY *, ClObjPipeAttr_c *); +extern int ClObjPipeAttr_dt(GAME_PLAY *, ClObjPipeAttr_c *); +extern int ClObjPipeAttr_set(GAME_PLAY *, ClObjPipeAttr_c *, ClObjPipeAttr_c *); +extern int ClObjPipe_ct(GAME_PLAY *, ClObjPipe_c *); +extern int ClObjPipe_dt(GAME_PLAY *, ClObjPipe_c *); +extern int ClObjPipe_set5(GAME_PLAY *, ClObjPipe_c *, ACTOR *, ClObjPipeData_c *); +extern int ClObjPipe_OCClear(GAME_PLAY *, ClObj_c *); +extern int ClObjTrisElemAttr_ct(GAME_PLAY *, ClObjTrisElemAttr_c *); +extern int ClObjTrisElemAttr_dt(GAME_PLAY *, ClObjTrisElemAttr_c *); +extern int ClObjTrisElemAttr_set(GAME_PLAY *, ClObjTrisElemAttr_c *, ClObjTrisElemAttrData_c *); +extern int ClObjTrisElem_ct(GAME_PLAY *, ClObjTrisElem_c *); +extern int ClObjTrisElem_dt(GAME_PLAY *, ClObjTrisElem_c *); +extern int ClObjTrisElem_set(GAME_PLAY *, ClObjTrisElem_c *, ClObjTrisElemData_c *); +extern int ClObjTrisElem_OCClear(GAME_PLAY *, ClObjTrisElem_c *); +extern int ClObjTris_ct(GAME_PLAY *, ClObjTris_c *); +extern int ClObjTris_dt_nzf(GAME_PLAY *, ClObjTris_c *); +extern int ClObjTris_set5_nzm(GAME_PLAY *, ClObjTris_c *, ACTOR *, ClObjTrisData_c *, ClObjTrisElem_c *); +extern int ClObjTris_OCClear(GAME_PLAY *, ClObj_c *); +extern void CollisionCheck_ct(GAME_PLAY *, CollisionCheck_c *); +extern void CollisionCheck_dt(GAME_PLAY *, CollisionCheck_c *); +extern void CollisionCheck_clear(GAME_PLAY *, CollisionCheck_c *); +extern int CollisionCheck_setOC(GAME_PLAY *, CollisionCheck_c *, ClObj_c *); +extern int get_type(u8); +extern void CollisionCheck_setOC_HitInfo(ClObj_c *, ClObjElem_c *, xyz_t *, ClObj_c *, ClObjElem_c *, xyz_t *, f32); +extern void CollisionCheck_OC_JntSph_Vs_JntSph(GAME_PLAY *, CollisionCheck_c *, ClObj_c *, ClObj_c *); +extern void CollisionCheck_OC_JntSph_Vs_Pipe(GAME_PLAY *, CollisionCheck_c *, ClObj_c *, ClObj_c *); +extern void CollisionCheck_OC_Pipe_Vs_JntSph(GAME_PLAY *, CollisionCheck_c *, ClObj_c *, ClObj_c *); +extern void CollisionCheck_OC_Pipe_Vs_Pipe(GAME_PLAY *, CollisionCheck_c *, ClObj_c *, ClObj_c *); +extern int CollisionCheck_Check1ClObjNoOC(ClObj_c *); +extern int CollisionCheck_Check2ClObjNoOC(ClObj_c *, ClObj_c *); +extern void CollisionCheck_OC(GAME_PLAY *, CollisionCheck_c *); +extern void CollisionCheck_setOCC_HitInfo(GAME_PLAY *, ClObj_c *, ClObjTrisElem_c *, xyz_t *, ClObj_c *, ClObjElem_c *, xyz_t *, xyz_t *); +extern void CollisionCheck_OCC_Tris_Vs_JntSph(GAME_PLAY *, CollisionCheck_c *, ClObjTris_c *, ClObjJntSph_c *); +extern void CollisionCheck_OCC_Tris_Vs_Pipe(GAME_PLAY *, CollisionCheck_c *, ClObjTris_c *, ClObjPipe_c *); +extern int CollisionCheck_Check1ClObjNoOCC(ClObj_c *); +extern void CollisionCheck_OCC(GAME_PLAY *, CollisionCheck_c *); +extern int ClObjTrisElem_OCCClear(GAME_PLAY *, ClObjTrisElem_c *); +extern int ClObj_OCCClear(GAME_PLAY *, ClObj_c *); +extern int ClObjTris_OCCClear(GAME_PLAY *, ClObj_c *); +extern int CollisionCheck_setOCC(GAME_PLAY *, CollisionCheck_c *, ClObj_c *); +extern void CollisionCheck_Status_ct(Status_c *); +extern void CollisionCheck_Status_Clear(Status_c *); +extern void CollisionCheck_Status_set3(Status_c *, StatusData_c *); +extern int CollisionCheck_Uty_ActorWorldPosSetPipeC(ACTOR *, ClObjPipe_c *); + + #ifdef __cplusplus } diff --git a/include/macros.inc b/include/macros.inc index 825a317b..30cb010a 100644 --- a/include/macros.inc +++ b/include/macros.inc @@ -1,5 +1,4 @@ -# PowerPC Register Constants -# General Purpose Registers (GPRs) +/* Register name macros */ .set r0, 0 .set r1, 1 .set r2, 2 @@ -32,8 +31,6 @@ .set r29, 29 .set r30, 30 .set r31, 31 - -# Floating Point Registers (FPRs) .set f0, 0 .set f1, 1 .set f2, 2 @@ -66,8 +63,6 @@ .set f29, 29 .set f30, 30 .set f31, 31 - -# Graphics Quantization Registers (GQRs) .set qr0, 0 .set qr1, 1 .set qr2, 2 @@ -76,73 +71,35 @@ .set qr5, 5 .set qr6, 6 .set qr7, 7 - -# Special Purpose Registers (SPRs) -.set XER, 1 -.set LR, 8 -.set CTR, 9 -.set DSISR, 18 -.set DAR, 19 -.set DEC, 22 -.set SDR1, 25 -.set SRR0, 26 -.set SRR1, 27 -.set SPRG0, 272 -.set SPRG1, 273 -.set SPRG2, 274 -.set SPRG3, 275 -.set EAR, 282 -.set PVR, 287 -.set IBAT0U, 528 -.set IBAT0L, 529 -.set IBAT1U, 530 -.set IBAT1L, 531 -.set IBAT2U, 532 -.set IBAT2L, 533 -.set IBAT3U, 534 -.set IBAT3L, 535 -.set DBAT0U, 536 -.set DBAT0L, 537 -.set DBAT1U, 538 -.set DBAT1L, 539 -.set DBAT2U, 540 -.set DBAT2L, 541 -.set DBAT3U, 542 -.set DBAT3L, 543 -.set GQR0, 912 -.set GQR1, 913 -.set GQR2, 914 -.set GQR3, 915 -.set GQR4, 916 -.set GQR5, 917 -.set GQR6, 918 -.set GQR7, 919 -.set HID2, 920 -.set WPAR, 921 -.set DMA_U, 922 -.set DMA_L, 923 -.set UMMCR0, 936 -.set UPMC1, 937 -.set UPMC2, 938 -.set USIA, 939 -.set UMMCR1, 940 -.set UPMC3, 941 -.set UPMC4, 942 -.set USDA, 943 -.set MMCR0, 952 -.set PMC1, 953 -.set PMC2, 954 -.set SIA, 955 -.set MMCR1, 956 -.set PMC3, 957 -.set PMC4, 958 -.set SDA, 959 -.set HID0, 1008 -.set HID1, 1009 -.set IABR, 1010 -.set DABR, 1013 -.set L2CR, 1017 -.set ICTC, 1019 -.set THRM1, 1020 -.set THRM2, 1021 -.set THRM3, 1022 +.set cr0lt, 0 +.set cr0gt, 1 +.set cr0eq, 2 +.set cr0un, 3 +.set cr1lt, 4 +.set cr1gt, 5 +.set cr1eq, 6 +.set cr1un, 7 +.set cr2lt, 8 +.set cr2gt, 9 +.set cr2eq, 10 +.set cr2un, 11 +.set cr3lt, 12 +.set cr3gt, 13 +.set cr3eq, 14 +.set cr3un, 15 +.set cr4lt, 16 +.set cr4gt, 17 +.set cr4eq, 18 +.set cr4un, 19 +.set cr5lt, 20 +.set cr5gt, 21 +.set cr5eq, 22 +.set cr5un, 23 +.set cr6lt, 24 +.set cr6gt, 25 +.set cr6eq, 26 +.set cr6un, 27 +.set cr7lt, 28 +.set cr7gt, 29 +.set cr7eq, 30 +.set cr7un, 31 diff --git a/include/sys_math3d.h b/include/sys_math3d.h index 34e69e78..c3a1bb93 100644 --- a/include/sys_math3d.h +++ b/include/sys_math3d.h @@ -15,10 +15,32 @@ typedef struct math_3d_pipe_s { s_xyz center; } Math3D_pipe_c; +typedef struct math_3d_sphere_s{ + s_xyz center; + s16 radius; +}Math3D_sphere_c; + +typedef struct math_3d_plane_s { + xyz_t normal; + f32 originDist; +} Math3D_plane_c; // size = 0x10 + +typedef struct math_3d_triangle_s { + xyz_t vtx[3]; + Math3D_plane_c plane; +} Math3D_triangle_c; // size = 0x34 + extern f32 Math3DVecLength(xyz_t* vec); extern void sMath_RotateX(xyz_t* pos, f32 rad); extern void sMath_RotateY(xyz_t* pos, f32 rad); extern void sMath_RotateZ(xyz_t* pos, f32 rad); +extern void Math3DPlane(xyz_t* va, xyz_t* vb, xyz_t* vc, f32* nox, f32* noy, f32* noz, f32* odist); +extern int Math3D_sphereCrossSphere_cl(Math3D_sphere_c* a, Math3D_sphere_c* b, f32* in); +extern int Math3D_sphereVsPipe_cl(Math3D_sphere_c* s, Math3D_pipe_c* c, f32* in); +extern int Math3D_pipeVsPipe_cl(Math3D_pipe_c* a, Math3D_pipe_c* b , f32* d); +extern int Math3D_sphereCrossTriangle3_cp(Math3D_sphere_c* s, Math3D_triangle_c* tri, xyz_t* ip); +extern int Math3D_pipeCrossTriangle_cp(Math3D_pipe_c* c,Math3D_triangle_c* tri, xyz_t* in); + extern xyz_t ZeroVec; extern s_xyz ZeroSVec; diff --git a/rel/m_collision_obj.c b/rel/m_collision_obj.c new file mode 100644 index 00000000..05924eab --- /dev/null +++ b/rel/m_collision_obj.c @@ -0,0 +1,984 @@ +#include "m_collision_obj.h" +#include "m_actor.h" + +McoWork mco_work; + + +void CollisionCheck_workTrisElemCenter(ClObjTrisElem_c* tri, xyz_t* vec) +{ + + vec->x = (tri->attribute.tri.vtx[0].x + tri->attribute.tri.vtx[1].x + tri->attribute.tri.vtx[2].x) * (1.0f / 3.0f); + vec->y = (tri->attribute.tri.vtx[0].y + tri->attribute.tri.vtx[1].y + + tri->attribute.tri.vtx[2].y) * + (1.0f / 3.0f); + vec->z = (tri->attribute.tri.vtx[0].z + tri->attribute.tri.vtx[1].z + + tri->attribute.tri.vtx[2].z) * + (1.0f / 3.0f); +} + +int ClObj_ct(GAME_PLAY* play, ClObj_c* cl) +{ + static ClObj_c clobj_default = {NULL, NULL, 0, 0, 3}; + + *cl = clobj_default; + + return 1; +} + +int ClObj_dt(GAME_PLAY*, ClObj_c*) +{ + return 1; +} + +int ClObj_set4(GAME_PLAY*, ClObj_c* cl, ACTOR* actor, ClObjData_c* data) +{ + + cl->owner_actor = actor; + cl->collision_flags0 = data->collision_flags0; + cl->collision_flags1 = data->collision_flags1; + cl->collision_type = data->type; + + return 1; +} + +void ClObj_OCClear(GAME_PLAY *, ClObj_c* cl) +{ + + cl->collision_flags0 &= ~2; + cl->collided_actor = NULL; + cl->collision_flags1 &= 0xFE; +} + +int ClObjElem_ct(ClObjElem_c* elem) +{ + + elem->flags = 0; + + return 1; +} + +int ClObjElem_set(ClObjElem_c* elem, ClObjElemData_c* data) +{ + + elem->flags = data->flags; + + return 1; +} + +void ClObjElem_OCClear(GAME_PLAY*, ClObjElem_c* elem) +{ + + elem->flags &= ~2; +} + +int ClObjJntSphElem_OCClear(GAME_PLAY* play, ClObjJntSphElem_c* col) +{ + + ClObjElem_OCClear(play, &col->element); + + return 1; +} + +int ClObjJntSph_OCClear(GAME_PLAY* play, ClObj_c* cl) +{ + + ClObjJntSph_c* jntsph = (ClObjJntSph_c*)cl; + ClObjJntSphElem_c* elem; + + ClObj_OCClear(play, &jntsph->collision_obj); + + for (elem = jntsph->elements; elem < &jntsph->elements[jntsph->count]; elem++) + { + ClObjJntSphElem_OCClear(play, elem); + } + + return 1; +} + +int ClObjPipeAttr_ct(GAME_PLAY* play, ClObjPipeAttr_c* attribute) +{ + + static ClObjPipeAttr_c default_pipe_attr = {0, 0, 0}; + + *attribute = default_pipe_attr; + + return 1; +} + +int ClObjPipeAttr_dt(GAME_PLAY*, ClObjPipeAttr_c*) +{ + + return 1; +} + +int ClObjPipeAttr_set(GAME_PLAY* play, ClObjPipeAttr_c* dst, ClObjPipeAttr_c* src) +{ + + *dst = *src; + + return 1; +} + +int ClObjPipe_ct(GAME_PLAY* play, ClObjPipe_c* pipe) +{ + + ClObj_ct(play, &pipe->collision_obj); + ClObjElem_ct(&pipe->element); + ClObjPipeAttr_ct(play, &pipe->attribute); + + return 1; +} + +int ClObjPipe_dt(GAME_PLAY* play, ClObjPipe_c* pipe) +{ + + ClObj_dt(play, &pipe->collision_obj); + ClObjPipeAttr_dt(play, &pipe->attribute); + + return 1; +} + +int ClObjPipe_set5(GAME_PLAY* play, ClObjPipe_c* pipe, ACTOR* owner, ClObjPipeData_c* data) +{ + + ClObj_set4(play, &pipe->collision_obj, owner, &data->collision_data); + ClObjElem_set(&pipe->element, &data->element_data); + ClObjPipeAttr_set(play, &pipe->attribute, (ClObjPipeAttr_c *)&data->attribute_data); + + return 1; +} + +int ClObjPipe_OCClear(GAME_PLAY* play, ClObj_c* cl) +{ + + ClObjPipe_c* pipe = (ClObjPipe_c *)cl; + + ClObj_OCClear(play, &pipe->collision_obj); + ClObjElem_OCClear(play, &pipe->element); + + return 1; +} + +int ClObjTrisElemAttr_ct(GAME_PLAY *play, ClObjTrisElemAttr_c *tris) +{ + + static ClObjTrisElemAttr_c default_clobjtriselem_attr = { + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; + + *tris = default_clobjtriselem_attr; + + return 1; +} + +int ClObjTrisElemAttr_dt(GAME_PLAY *play, ClObjTrisElemAttr_c *tris) +{ + + return 1; +} + +int ClObjTrisElemAttr_set(GAME_PLAY* play, ClObjTrisElemAttr_c* tris, ClObjTrisElemAttrData_c* data) +{ + + xyz_t* dst; + xyz_t* src; + f32 nox, noy, noz, odist; + + for (dst = tris->tri.vtx, src = data->vtx; dst < &tris->tri.vtx[3]; dst++, src++) + { + *dst = *src; + } + + Math3DPlane(&data->vtx[0], &data->vtx[1], &data->vtx[2], &nox, &noy, &noz, &odist); + tris->tri.plane.normal.x = nox; + tris->tri.plane.normal.y = noy; + tris->tri.plane.normal.z = noz; + tris->tri.plane.originDist = odist; + + return 1; +} + +int ClObjTrisElem_ct(GAME_PLAY* play, ClObjTrisElem_c* tris) +{ + + ClObjElem_ct(&tris->element); + ClObjTrisElemAttr_ct(play, &tris->attribute); + + return 1; +} + +int ClObjTrisElem_dt(GAME_PLAY* play, ClObjTrisElem_c* tris) +{ + + ClObjTrisElemAttr_dt(play, &tris->attribute); + + return 1; +} + +int ClObjTrisElem_set(GAME_PLAY* play, ClObjTrisElem_c* tris, ClObjTrisElemData_c* data) +{ + + ClObjElem_set(&tris->element, &data->element); + ClObjTrisElemAttr_set(play, &tris->attribute, &data->data); + + return 1; +} + +int ClObjTrisElem_OCClear(GAME_PLAY* play, ClObjTrisElem_c* tris) +{ + + ClObjElem_OCClear(play, &tris->element); + + return 1; +} + +int ClObjTris_ct(GAME_PLAY* play, ClObjTris_c* tris) +{ + + ClObj_ct(play, &tris->collision_obj); + tris->count = 0; + tris->elements = NULL; + + return 1; +} + +int ClObjTris_dt_nzf(GAME_PLAY *play, ClObjTris_c *tris) +{ + + ClObjTrisElem_c *element; + + ClObj_dt(play, &tris->collision_obj); + + for (element = tris->elements; element < &tris->elements[tris->count]; element++) + { + ClObjTrisElem_dt(play, element); + } + tris->count = 0; + tris->elements = NULL; + + return 1; +} + +int ClObjTris_set5_nzm(GAME_PLAY* play, ClObjTris_c* tris, ACTOR* actor, ClObjTrisData_c* data, + ClObjTrisElem_c *elem) +{ + + ClObjTrisElem_c* element; + ClObjTrisElemData_c* elementData; + + ClObj_set4(play, &tris->collision_obj, actor, &data->data); + + tris->count = data->count; + tris->elements = elem; + + for (element = tris->elements, elementData = data->elem_data; + element < &tris->elements[tris->count]; element++, elementData++) + { + ClObjTrisElem_ct(play, element); + ClObjTrisElem_set(play, element, elementData); + } + + return 1; +} + +int ClObjTris_OCClear(GAME_PLAY* play, ClObj_c* cl) +{ + ClObjTris_c* tris = (ClObjTris_c*)cl; + ClObjTrisElem_c* element; + + ClObj_OCClear(play, &tris->collision_obj); + + for (element = tris->elements; element < &tris->elements[tris->count]; element++) + { + ClObjTrisElem_OCClear(play, element); + } + + return 1; +} + +void CollisionCheck_ct(GAME_PLAY* play, CollisionCheck_c* col) +{ + + col->flags = 0; + CollisionCheck_clear(play, col); +} + +void CollisionCheck_dt(GAME_PLAY* play, CollisionCheck_c* col) +{ +} + +void CollisionCheck_clear(GAME_PLAY* play, CollisionCheck_c* col) +{ + + ClObj_c** clp; + + if (col->flags & 1) + { + return; + } + + col->collider_num = 0; + + for (clp = col->collider_table; clp < &col->collider_table[Cl_COLLIDER_NUM]; clp++) + { + *clp = NULL; + } + + mco_work.count = 0; + + for (clp = mco_work.colliders; clp < &mco_work.colliders[10]; clp++) + { + *clp = NULL; + } +} + +CollisionClearFunction OCClearFunctionTable[ClObj_TYPE_NUM] = { + ClObjJntSph_OCClear,ClObjPipe_OCClear,ClObjTris_OCClear +}; + +CollisionOCFunction oc_collision_function[ClObj_TYPE_NUM][ClObj_TYPE_NUM] = { + {CollisionCheck_OC_JntSph_Vs_JntSph, CollisionCheck_OC_JntSph_Vs_Pipe, NULL}, + {CollisionCheck_OC_Pipe_Vs_JntSph, CollisionCheck_OC_Pipe_Vs_Pipe, NULL}, + {NULL, NULL, NULL}}; + +CollisionOCFunction occ_collision_function[ClObj_TYPE_NUM][ClObj_TYPE_NUM] = { + {NULL, NULL, NULL}, + {NULL, NULL, NULL}, + {(CollisionOCFunction)CollisionCheck_OCC_Tris_Vs_JntSph, (CollisionOCFunction)CollisionCheck_OCC_Tris_Vs_Pipe, NULL} + }; + +CollisionOCClear OCCClearFunctionTable[ClObj_TYPE_NUM] = { + NULL, NULL, ClObjTris_OCCClear}; + + +int CollisionCheck_setOC(GAME_PLAY* play, CollisionCheck_c* col, ClObj_c* cl) +{ + + int ret; + + if (_Game_play_isPause(play) == 1) + { + return -1; + } + else + { + OCClearFunctionTable[cl->collision_type](play, cl); + + if ((cl->owner_actor != NULL) && (cl->owner_actor->mv_proc == NULL)) + { + return -1; + } + + if (col->collider_num >= Cl_COLLIDER_NUM) + { + return -1; + } + + if (col->flags & 1) + { + return -1; + } + + ret = col->collider_num; + col->collider_table[col->collider_num] = cl; + col->collider_num++; + } + + return ret; +} + +int get_type(u8 type) +{ + + if (type == MASSTYPE_IMMOVABLE) + { + return MASS_IMMOVABLE; + } + + if (type == MASSTYPE_HEAVY) + { + return MASS_HEAVY; + } + + return MASS_NORMAL; +} + +void CollisionCheck_setOC_HitInfo(ClObj_c* col1, ClObjElem_c* colelem1, xyz_t* pos1, ClObj_c* col2, + ClObjElem_c* colelem2, xyz_t* pos2, f32 diff) +{ + + ACTOR* actor1; + ACTOR* actor2; + int type1; + int type2; + + f32 xdiff; + f32 zdiff; + f32 xzdist; + + f32 weight1; + f32 weight2; + f32 minweight; + f32 comweight; + + f32 coldis1; + f32 coldis2; + + actor1 = col1->owner_actor; + actor2 = col2->owner_actor; + + col1->collided_actor = actor2; + col1->collision_flags0 |= 2; + colelem1->flags |= 2; + + if (col2->collision_flags1 & 8) + { + col1->collision_flags1 |= 1; + } + + col2->collided_actor = actor1; + col2->collision_flags0 |= 2; + colelem2->flags |= 2; + + if (col1->collision_flags1 & 8) + { + col2->collision_flags1 |= 1; + } + + if ((actor1 == NULL) || (actor2 == NULL)) + { + return; + } + + if ((col1->collision_flags0 & 4) || (col2->collision_flags0 & 4)) + { + return; + } + + type1 = get_type(actor1->status_data.weight); + type2 = get_type(actor2->status_data.weight); + + weight1 = actor1->status_data.weight; + weight2 = actor2->status_data.weight; + + comweight = weight1 + weight2; + + if (fabsf(comweight) < 0.008f) + { + weight1 = weight2 = 1.0f; + comweight = 2.0f; + } + + minweight = 1.0f / comweight; + + xdiff = pos2->x - pos1->x; + zdiff = pos2->z - pos1->z; + + xzdist = sqrtf((xdiff * xdiff) + (zdiff * zdiff)); + + if (type1 == 0) + { + if (type2 == 0) + { + return; + } + coldis1 = 0.0f; + coldis2 = 1.0f; + } + else if (type1 == 1) + { + if (type2 == 0) + { + coldis1 = 1.0f; + coldis2 = 0.0f; + } + else if (type2 == 1) + { + coldis1 = 0.5f; + coldis2 = 0.5f; + } + else + { + coldis1 = 0.0f; + coldis2 = 1.0f; + } + } + else + { + if (type2 == 2) + { + coldis1 = weight2 * minweight; + coldis2 = weight1 * minweight; + } + else + { + coldis1 = 1.0f; + coldis2 = 0.0f; + } + } + + if (col1->collision_flags0 & 0x40) + { + coldis1 = 0.0f; + coldis2 = 1.0f; + actor2->speed = 0.0f; + } + else if (col2->collision_flags0 & 0x40) + { + coldis1 = 1.0f; + coldis2 = 0.0f; + actor1->speed = 0.0f; + } + + if (!(fabsf(xzdist) < 0.008f)) + { + + xdiff *= diff / xzdist; + zdiff *= diff / xzdist; + + actor1->status_data.collision_vec.x += -xdiff * coldis1; + actor1->status_data.collision_vec.z += -zdiff * coldis1; + + actor2->status_data.collision_vec.x += xdiff * coldis2; + actor2->status_data.collision_vec.z += zdiff * coldis2; + } + else if (diff != 0) + { + actor1->status_data.collision_vec.x += -diff * coldis1; + actor2->status_data.collision_vec.x += diff * coldis2; + } + else + { + actor1->status_data.collision_vec.x -= coldis1; + actor2->status_data.collision_vec.x += coldis2; + } +} + +void CollisionCheck_OC_JntSph_Vs_JntSph(GAME_PLAY* play, CollisionCheck_c* check, ClObj_c* col1, + ClObj_c* col2) +{ + + ClObjJntSph_c* jntsph1 = (ClObjJntSph_c*)col1; + ClObjJntSph_c* jntsph2 = (ClObjJntSph_c*)col2; + + ClObjJntSphElem_c* elem1; + ClObjJntSphElem_c* elem2; + + if ((jntsph1->count <= 0) || (jntsph1->elements == NULL) || (jntsph2->count <= 0) || (jntsph2->elements == NULL)) + { + return; + } + + for (elem1 = jntsph1->elements; elem1 < &jntsph1->elements[jntsph1->count]; elem1++) + { + + if ((elem1->element.flags & 1)) + { + + for (elem2 = jntsph2->elements; elem2 < &jntsph2->elements[jntsph2->count]; elem2++) + { + + f32 in; + + if ((elem2->element.flags & 1)) + { + + if (Math3D_sphereCrossSphere_cl(&elem1->attribute.s2, &elem2->attribute.s2, &in) == 1) + { + + xyz_t pos1; + xyz_t pos2; + + xyz_t_move_s_xyz(&pos1, &elem1->attribute.s2.center); + xyz_t_move_s_xyz(&pos2, &elem2->attribute.s2.center); + CollisionCheck_setOC_HitInfo(&jntsph1->collision_obj, &elem1->element, &pos1, + &jntsph2->collision_obj, &elem2->element, &pos2, in); + } + } + } + } + } +} + +void CollisionCheck_OC_JntSph_Vs_Pipe(GAME_PLAY* play, CollisionCheck_c* check, ClObj_c* col1, + ClObj_c* col2) +{ + + ClObjJntSph_c* jntsph = (ClObjJntSph_c*)col1; + ClObjPipe_c* pipe = (ClObjPipe_c*)col2; + ClObjJntSphElem_c* elem; + f32 in; + xyz_t sphpos; + xyz_t pipepos; + + if ((jntsph->count > 0) && (jntsph->elements) != NULL) + { + + if (!(jntsph->collision_obj.collision_flags0 & 1) || !(pipe->collision_obj.collision_flags0 & 1) || + !(pipe->element.flags & 1)) + { + return; + } + + for (elem = jntsph->elements; elem < &jntsph->elements[jntsph->count]; elem++) + { + + if (!(elem->element.flags & 1)) + { + continue; + } + + if (Math3D_sphereVsPipe_cl(&elem->attribute.s2, &pipe->attribute.pipe, &in) == 1) + { + + xyz_t_move_s_xyz(&sphpos, &elem->attribute.s2.center); + xyz_t_move_s_xyz(&pipepos, &pipe->attribute.pipe.center); + CollisionCheck_setOC_HitInfo(&jntsph->collision_obj, &elem->element, &sphpos, + &pipe->collision_obj, &pipe->element, &pipepos, in); + } + } + } +} + +void CollisionCheck_OC_Pipe_Vs_JntSph(GAME_PLAY* play, CollisionCheck_c* colcheck, ClObj_c* col1, + ClObj_c* col2) +{ + + CollisionCheck_OC_JntSph_Vs_Pipe(play, colcheck, col2, col1); +} + +void CollisionCheck_OC_Pipe_Vs_Pipe(GAME_PLAY* play, CollisionCheck_c* colcheck, ClObj_c* col1, + ClObj_c* col2) +{ + + ClObjPipe_c* pipe1 = (ClObjPipe_c*)col1; + ClObjPipe_c* pipe2 = (ClObjPipe_c*)col2; + f32 in; + xyz_t pipepos1; + xyz_t pipepos2; + + if (!(pipe1->collision_obj.collision_flags0 & 1) || !(pipe2->collision_obj.collision_flags0 & 1) || !(pipe1->element.flags & 1) || !(pipe2->element.flags & 1)) + { + return; + } + + if (Math3D_pipeVsPipe_cl(&pipe1->attribute.pipe, &pipe2->attribute.pipe, &in) != 1) + { + return; + } + + xyz_t_move_s_xyz(&pipepos1, &pipe1->attribute.pipe.center); + xyz_t_move_s_xyz(&pipepos2, &pipe2->attribute.pipe.center); + + CollisionCheck_setOC_HitInfo(&pipe1->collision_obj, &pipe1->element, &pipepos1, + &pipe2->collision_obj, &pipe2->element, &pipepos2, in); +} + +int CollisionCheck_Check1ClObjNoOC(ClObj_c* col) +{ + + return col->collision_flags0 & 1 ^ 1; +} + +int CollisionCheck_Check2ClObjNoOC(ClObj_c* col1, ClObj_c* col2) +{ + + if (!(col1->collision_flags0 & col2->collision_flags1 & 0x38) || + !(col1->collision_flags1 & col2->collision_flags0 & 0x38)) + { + return 1; + } + + if (col1->owner_actor == col2->owner_actor) + { + return 1; + } + return 0; +} + + + +void CollisionCheck_OC(GAME_PLAY* play, CollisionCheck_c* colcheck) +{ + + ClObj_c** col1p; + ClObj_c** col2p; + CollisionOCFunction current; + + for (col1p = colcheck->collider_table; col1p < &colcheck->collider_table[colcheck->collider_num]; col1p++) + { + + if (((*col1p) == NULL) || (CollisionCheck_Check1ClObjNoOC(*col1p) == 1)) + { + continue; + } + + for (col2p = col1p + 1; col2p < &colcheck->collider_table[colcheck->collider_num]; col2p++) + { + + if ((*col2p == NULL) || (CollisionCheck_Check1ClObjNoOC(*col2p) == 1) || + (CollisionCheck_Check2ClObjNoOC(*col1p, *col2p) == 1)) + { + continue; + } + current = oc_collision_function[(*col1p)->collision_type][(*col2p)->collision_type]; + + if (current == NULL) + { + continue; + } + + current(play, colcheck, *col1p, *col2p); + } + } + CollisionCheck_OCC(play, colcheck); +} + +void CollisionCheck_setOCC_HitInfo(GAME_PLAY* play, ClObj_c* col1, ClObjTrisElem_c* elem1, xyz_t* pos1, + ClObj_c* col2, ClObjElem_c* elem2, xyz_t* pos2, xyz_t* pos3) +{ + + col1->collided_actor = col2->owner_actor; + col1->collision_flags1 |= 4; + + elem1->attribute.t.x = pos3->x; + elem1->attribute.t.y = pos3->y; + elem1->attribute.t.z = pos3->z; +} + + +void CollisionCheck_OCC_Tris_Vs_JntSph(GAME_PLAY* play, CollisionCheck_c* colcheck, ClObjTris_c* tris, + ClObjJntSph_c* jntsph) +{ + + ClObjTrisElem_c* triselem; + ClObjJntSphElem_c* jntsphelem; + xyz_t pos; + xyz_t sphpos; + xyz_t trispos; + + if ((tris->count <= 0) || (tris->elements == NULL) || + (jntsph->count <= 0) || (jntsph->elements == NULL)) + { + return; + } + + for (jntsphelem = jntsph->elements; jntsphelem < &jntsph->elements[jntsph->count]; jntsphelem++) + { + + if ((jntsphelem->element.flags & 1)) + { + + for (triselem = tris->elements; triselem < &tris->elements[tris->count]; triselem++) + { + + if (Math3D_sphereCrossTriangle3_cp(&jntsphelem->attribute.s2, &triselem->attribute.tri, &pos) != 0) + { + + xyz_t_move_s_xyz(&sphpos, &jntsphelem->attribute.s2.center); + CollisionCheck_workTrisElemCenter(triselem, &trispos); + CollisionCheck_setOCC_HitInfo(play, &tris->collision_obj, triselem, &trispos, &jntsph->collision_obj, &jntsphelem->element, + &sphpos, &pos); + } + } + } + } +} + + +void CollisionCheck_OCC_Tris_Vs_Pipe(GAME_PLAY* play, CollisionCheck_c* colcheck, ClObjTris_c* tris, ClObjPipe_c* pipe) +{ + + ClObjTrisElem_c* triselem; + xyz_t pos; + xyz_t pipepos; + xyz_t trispos; + + if ((pipe->attribute.pipe.radius > 0) && (pipe->attribute.pipe.height > 0) && (pipe->element.flags & 1)) + { + + if ((tris->count <= 0) || (tris->elements == NULL)) + { + return; + } + + for (triselem = tris->elements; triselem < &tris->elements[tris->count]; triselem++) + { + + if (Math3D_pipeCrossTriangle_cp(&pipe->attribute.pipe, &triselem->attribute.tri, &pos) != 0) + { + + CollisionCheck_workTrisElemCenter(triselem, &trispos); + xyz_t_move_s_xyz(&pipepos, &pipe->attribute.pipe.center); + CollisionCheck_setOCC_HitInfo(play, &tris->collision_obj, triselem, &trispos, &pipe->collision_obj, &pipe->element, &pipepos, &pos); + break; + } + } + } +} + +int CollisionCheck_Check1ClObjNoOCC(ClObj_c* col) +{ + + return col->collision_flags1 >> 1 & 1 ^ 1; +} + +void CollisionCheck_OCC(GAME_PLAY* play, CollisionCheck_c* colcheck) +{ + + + ClObj_c** col1p; + ClObj_c** col2p; + CollisionOCFunction current; + + if (mco_work.count == 0) + { + return; + } + + for (col1p = mco_work.colliders; col1p < &mco_work.colliders[mco_work.count]; col1p++) + { + + if (((*col1p) == NULL) || (CollisionCheck_Check1ClObjNoOCC(*col1p) == 1)) + { + continue; + } + + for (col2p = colcheck->collider_table; col2p < &colcheck->collider_table[colcheck->collider_num]; col2p++) + { + + if ((*col2p) == NULL) + { + continue; + } + + if ((*col1p)->owner_actor == (*col2p)->owner_actor) + { + continue; + } + + current = occ_collision_function[(*col1p)->collision_type][(*col2p)->collision_type]; + + if (current == NULL) + { + continue; + } + + current(play, colcheck, *col1p, *col2p); + } + } +} + +int ClObjTrisElem_OCCClear(GAME_PLAY* play, ClObjTrisElem_c* triselem) +{ + + triselem->attribute.t.x = 0.0f; + triselem->attribute.t.y = 0.0f; + triselem->attribute.t.z = 0.0f; + return 1; +} + +int ClObj_OCCClear(GAME_PLAY* play, ClObj_c* col) +{ + + col->collided_actor = NULL; + col->collision_flags1 &= ~4; +} + +int ClObjTris_OCCClear(GAME_PLAY* play, ClObj_c* col) +{ + + ClObjTris_c* tris = (ClObjTris_c*)col; + ClObjTrisElem_c* triselem; + + ClObj_OCCClear(play, &tris->collision_obj); + + for (triselem = tris->elements; triselem < &tris->elements[tris->count]; triselem++) + { + + ClObjTrisElem_OCCClear(play, triselem); + } + + return 1; +} + +int CollisionCheck_setOCC(GAME_PLAY* play, CollisionCheck_c* colcheck, ClObj_c* col) +{ + + int ret; + + if (_Game_play_isPause(play) == 1) + { + + return -1; + } + + if ((col->collision_type == 0) || (col->collision_type == 1)) + { + + return -1; + } + + OCCClearFunctionTable[col->collision_type](play, col); + + if ((col->owner_actor != NULL) && (col->owner_actor->mv_proc == NULL)) + { + + return -1; + } + + if (mco_work.count >= 10) + { + + return -1; + } + + if (colcheck->flags & 1) + { + + return -1; + } + + ret = mco_work.count; + mco_work.colliders[mco_work.count] = col; + mco_work.count++; + + return ret; +} + +void CollisionCheck_Status_ct(Status_c* status) +{ + + static Status_c status_org = {{0.0f, 0.0f, 0.0f}, 10, 10, 0, 50, 8, 0, 0, 0}; + + *status = status_org; +} + +void CollisionCheck_Status_Clear(Status_c* status) +{ + + status->damage = 0; + status->damage_effect = 0; + status->at_hit_effect = 0; + status->ac_hit_effect = 0; + status->collision_vec.z = 0.0f; + status->collision_vec.y = 0.0f; + status->collision_vec.x = 0.0f; +} + +void CollisionCheck_Status_set3(Status_c* status, StatusData_c* data) +{ + + status->hp = data->health; + status->radius = data->radius; + status->height = data->height; + status->offset = data->offset; + status->weight = data->weight; +} + +int CollisionCheck_Uty_ActorWorldPosSetPipeC(ACTOR* actor, ClObjPipe_c* pipe) +{ + + pipe->attribute.pipe.center.x = actor->world.position.x; + pipe->attribute.pipe.center.y = actor->world.position.y; + pipe->attribute.pipe.center.z = actor->world.position.z; +} \ No newline at end of file diff --git a/tools/ppcdis b/tools/ppcdis index ef5a43f0..b49c7feb 160000 --- a/tools/ppcdis +++ b/tools/ppcdis @@ -1 +1 @@ -Subproject commit ef5a43f0e09f3aa3a694d14ab9a777f7254b60be +Subproject commit b49c7feb305e562d5d4503fc117bf9020f941ef8