Merge pull request #108 from mrshigure/hsfex

Matched hsfex
This commit is contained in:
gamemasterplc 2024-01-15 08:03:30 -06:00 committed by GitHub
commit a3536d462a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 598 additions and 2 deletions

View file

@ -329,7 +329,7 @@ config.libs = [
Object(Matching, "game/hsfman.c"),
Object(NonMatching, "game/hsfmotion.c"),
Object(Matching, "game/hsfanim.c"),
Object(NonMatching, "game/hsfex.c"),
Object(Matching, "game/hsfex.c"),
Object(Matching, "game/perf.c"),
Object(Matching, "game/objmain.c"),
Object(NonMatching, "game/fault.c"),

15
include/game/hsfex.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef _GAME_HSFEX_H
#define _GAME_HSFEX_H
#include "dolphin.h"
void CamMotionEx2(s16 arg0, s16 arg1, float arg2, s16 arg3);
void CamMotionEx(s16 arg0, s16 arg1, Vec *arg2, Vec *arg3, Vec *arg4, float arg5, s16 arg6);
float InterpolateBMLine(float *arg0, float *arg1, float arg2);
void Hu3D2Dto3D(Vec *arg0, s16 arg1, Vec *arg2);
void Hu3D3Dto2D(Vec *arg0, s16 arg1, Vec *arg2);
void Hu3DMtxTransGet(Mtx arg0, Vec *arg1);
void Hu3DMtxRotGet(Mtx arg0, Vec *arg1);
void Hu3DMtxScaleGet(Mtx arg0, Vec *arg1);
#endif

View file

@ -3,7 +3,7 @@
#include "dolphin.h"
void Hu3D2Dto3D(Vec*, s32, Vec*);
void Hu3D2Dto3D(Vec*, s16, Vec*);
void HuAudFadeOut(s32 arg0);
void Hu3DModelPosSet(s16 index, float x, float y, float z);

581
src/game/hsfex.c Normal file
View file

@ -0,0 +1,581 @@
#include "game/hsfex.h"
#include "game/hsfman.h"
#include "math.h"
typedef struct {
/* 0x00 */ float unk00;
/* 0x04 */ float unk04;
/* 0x08 */ Vec unk08;
/* 0x14 */ Vec unk14;
/* 0x20 */ Vec unk20;
} HsfexStruct02; // Size 0x2C
static void SetObjCamMotion(s16 arg0, HsfTrack *arg1, float arg2, HsfexStruct02 *arg3);
float GetCurve(void*, float);
void CamMotionEx2(s16 arg0, s16 arg1, float arg2, s16 arg3) {
CameraData *temp_r30;
s16 i;
for (i = 0; i < 16; i++) {
if (arg1 & (1 << i)) {
break;
}
}
temp_r30 = &Hu3DCamera[i];
CamMotionEx(arg0, arg1, &temp_r30->pos, &temp_r30->up, &temp_r30->target, arg2, arg3);
}
void CamMotionEx(s16 arg0, s16 arg1, Vec *arg2, Vec *arg3, Vec *arg4, float arg5, s16 arg6) {
Vec sp3C;
float sp2C[4];
float sp1C[4];
float temp_f29;
float var_f27;
float var_f26;
float var_f30;
float var_f31;
s16 sp1A;
s16 var_r25;
s16 var_r29;
s16 var_r30;
HsfexStruct02 *var_r31;
CameraData *temp_r27;
ModelData *temp_r23;
HsfData *temp_r22;
MotionData *temp_r19;
HsfData *temp_r18;
HsfObject *temp_r24;
HsfTrack *temp_r20;
HsfMotion *temp_r26;
HsfexStruct02 *temp_r21;
HsfTrack *var_r28;
temp_r23 = &Hu3DData[arg0];
temp_r19 = &Hu3DMotion[temp_r23->unk_08];
temp_r22 = temp_r23->hsfData;
temp_r18 = temp_r19->unk_04;
temp_r26 = temp_r18->motion;
for (var_r25 = 0; var_r25 < 16; var_r25++) {
if (arg1 & (1 << var_r25)) {
break;
}
}
temp_r27 = &Hu3DCamera[var_r25];
temp_f29 = temp_r26->len;
sp1A = 0.5f + (temp_f29 / 6.0f) + 1.0f;
var_r31 = temp_r21 = HuMemDirectMallocNum(HEAP_SYSTEM, (sp1A + 1) * sizeof(HsfexStruct02), MEMORY_DEFAULT_NUM);
var_r31->unk00 = 0.0f;
var_r31->unk08 = *arg2;
var_r31->unk20 = *arg4;
var_r31->unk14 = *arg3;
var_r31++;
for (var_r29 = 1, var_f31 = 0.0f; var_f31 <= temp_f29; var_r31++, var_r29++) {
var_r31->unk00 = var_f31;
var_r28 = temp_r26->track;
temp_r20 = &var_r28[temp_r26->numTracks];
while (var_r28 < temp_r20) {
if (var_r28->type == 2) {
temp_r24 = &temp_r22->object[var_r28->target];
if (temp_r24->type == 7) {
SetObjCamMotion(arg0, var_r28, GetCurve(var_r28, var_f31), var_r31);
}
}
var_r28++;
}
var_f31 += 6.0f;
}
if (var_f31 != temp_f29) {
var_r31->unk00 = temp_f29;
var_r28 = temp_r26->track;
temp_r20 = &var_r28[temp_r26->numTracks];
while (var_r28 < temp_r20) {
if (var_r28->type == 2) {
temp_r24 = &temp_r22->object[var_r28->target];
if (temp_r24->type == 7) {
SetObjCamMotion(arg0, var_r28, GetCurve(var_r28, temp_f29), var_r31);
}
}
var_r28++;
}
var_r29++;
}
var_r31 = temp_r21;
var_r31->unk04 = 0.0f;
var_f26 = 0.0f;
for (var_f31 = var_f26; var_f31 < var_r29 - 1; var_f31 += 1.0f, var_r31++) {
PSVECSubtract(&var_r31[1].unk08, &var_r31[0].unk08, &sp3C);
var_r31[1].unk04 = PSVECMag(&sp3C);
var_f26 += var_r31[1].unk04;
}
var_r31 = temp_r21;
var_f27 = 0.0f;
var_f31 = var_f27;
while (var_f31 < var_r29) {
var_f27 += var_r31->unk04;
var_r31->unk00 = arg5 * (var_f27 / var_f26);
var_f31 += 1.0f;
var_r31++;
}
var_f31 = 0.0f;
while (var_f31 <= arg5) {
switch (arg6) {
case 0:
var_f30 = var_f31;
break;
case 1:
var_f30 = arg5 * sin(90.0f * (var_f31 / arg5) * M_PI / 180.0);
break;
case 2:
var_f30 = arg5 * (1.0 - cos(90.0f * (var_f31 / arg5) * M_PI / 180.0));
break;
}
var_r31 = temp_r21;
for (var_r30 = 0; var_r30 < var_r29; var_r30++, var_r31++) {
if (var_r31->unk00 <= var_f30 && var_r31[1].unk00 > var_f30) {
break;
}
}
if (var_r30 != var_r29) {
if (var_r30 == 0) {
sp1C[0] = -1.0f;
} else {
sp1C[0] = var_r31[-1].unk00;
}
sp1C[1] = var_r31->unk00;
if (var_r30 >= var_r29 - 1) {
sp1C[2] = 1.0f + var_r31->unk00;
}
sp1C[2] = var_r31[1].unk00;
if (var_r30 >= var_r29 - 2) {
sp1C[3] = 1.0f + sp1C[2];
} else {
sp1C[3] = var_r31[2].unk00;
}
if (var_r30 == 0) {
sp2C[0] = var_r31[0].unk08.x;
} else {
sp2C[0] = var_r31[-1].unk08.x;
}
sp2C[1] = var_r31[0].unk08.x;
if (var_r30 >= var_r29 - 1) {
sp2C[2] = sp2C[1];
} else {
sp2C[2] = var_r31[1].unk08.x;
}
if (var_r30 >= var_r29 - 2) {
sp2C[3] = sp2C[2];
} else {
sp2C[3] = var_r31[2].unk08.x;
}
temp_r27->pos.x = InterpolateBMLine(sp2C, sp1C, var_f30);
if (var_r30 == 0) {
sp2C[0] = var_r31[0].unk08.y;
} else {
sp2C[0] = var_r31[-1].unk08.y;
}
sp2C[1] = var_r31[0].unk08.y;
if (var_r30 >= var_r29 - 1) {
sp2C[2] = sp2C[1];
} else {
sp2C[2] = var_r31[1].unk08.y;
}
if (var_r30 >= var_r29 - 2) {
sp2C[3] = sp2C[2];
} else {
sp2C[3] = var_r31[2].unk08.y;
}
temp_r27->pos.y = InterpolateBMLine(sp2C, sp1C, var_f30);
if (var_r30 == 0) {
sp2C[0] = var_r31[0].unk08.z;
} else {
sp2C[0] = var_r31[-1].unk08.z;
}
sp2C[1] = var_r31[0].unk08.z;
if (var_r30 >= var_r29 - 1) {
sp2C[2] = sp2C[1];
} else {
sp2C[2] = var_r31[1].unk08.z;
}
if (var_r30 >= var_r29 - 2) {
sp2C[3] = sp2C[2];
} else {
sp2C[3] = var_r31[2].unk08.z;
}
temp_r27->pos.z = InterpolateBMLine(sp2C, sp1C, var_f30);
if (var_r30 == 0) {
sp2C[0] = var_r31[0].unk20.x;
} else {
sp2C[0] = var_r31[-1].unk20.x;
}
sp2C[1] = var_r31[0].unk20.x;
if (var_r30 >= var_r29 - 1) {
sp2C[2] = sp2C[1];
} else {
sp2C[2] = var_r31[1].unk20.x;
}
if (var_r30 >= var_r29 - 2) {
sp2C[3] = sp2C[2];
} else {
sp2C[3] = var_r31[2].unk20.x;
}
temp_r27->target.x = InterpolateBMLine(sp2C, sp1C, var_f30);
if (var_r30 == 0) {
sp2C[0] = var_r31->unk20.y;
} else {
sp2C[0] = var_r31[-1].unk20.y;
}
sp2C[1] = var_r31->unk20.y;
if (var_r30 >= var_r29 - 1) {
sp2C[2] = sp2C[1];
} else {
sp2C[2] = var_r31[1].unk20.y;
}
if (var_r30 >= var_r29 - 2) {
sp2C[3] = sp2C[2];
} else {
sp2C[3] = var_r31[2].unk20.y;
}
temp_r27->target.y = InterpolateBMLine(sp2C, sp1C, var_f30);
if (var_r30 == 0) {
sp2C[0] = var_r31->unk20.z;
} else {
sp2C[0] = var_r31[-1].unk20.z;
}
sp2C[1] = var_r31->unk20.z;
if (var_r30 >= var_r29 - 1) {
sp2C[2] = sp2C[1];
} else {
sp2C[2] = var_r31[1].unk20.z;
}
if (var_r30 >= var_r29 - 2) {
sp2C[3] = sp2C[2];
} else {
sp2C[3] = var_r31[2].unk20.z;
}
temp_r27->target.z = InterpolateBMLine(sp2C, sp1C, var_f30);
if (var_r30 == 0) {
sp2C[0] = var_r31->unk14.x;
} else {
sp2C[0] = var_r31[-1].unk14.x;
}
sp2C[1] = var_r31->unk14.x;
if (var_r30 >= var_r29 - 1) {
sp2C[2] = sp2C[1];
} else {
sp2C[2] = var_r31[1].unk14.x;
}
if (var_r30 >= var_r29 - 2) {
sp2C[3] = sp2C[2];
} else {
sp2C[3] = var_r31[2].unk14.x;
}
temp_r27->up.x = InterpolateBMLine(sp2C, sp1C, var_f30);
if (var_r30 == 0) {
sp2C[0] = var_r31->unk14.y;
} else {
sp2C[0] = var_r31[-1].unk14.y;
}
sp2C[1] = var_r31->unk14.y;
if (var_r30 >= var_r29 - 1) {
sp2C[2] = sp2C[1];
} else {
sp2C[2] = var_r31[1].unk14.y;
}
if (var_r30 >= var_r29 - 2) {
sp2C[3] = sp2C[2];
} else {
sp2C[3] = var_r31[2].unk14.y;
}
temp_r27->up.y = InterpolateBMLine(sp2C, sp1C, var_f30);
if (var_r30 == 0) {
sp2C[0] = var_r31->unk14.z;
} else {
sp2C[0] = var_r31[-1].unk14.z;
}
sp2C[1] = var_r31->unk14.z;
if (var_r30 >= var_r29 - 1) {
sp2C[2] = sp2C[1];
} else {
sp2C[2] = var_r31[1].unk14.z;
}
if (var_r30 >= var_r29 - 2) {
sp2C[3] = sp2C[2];
} else {
sp2C[3] = var_r31[2].unk14.z;
}
temp_r27->up.z = InterpolateBMLine(sp2C, sp1C, var_f30);
HuPrcVSleep();
var_f31 += 1.0f;
} else {
break;
}
}
HuMemDirectFree(temp_r21);
}
static void SetObjCamMotion(s16 arg0, HsfTrack *arg1, float arg2, HsfexStruct02 *arg3) {
ModelData *temp_r31 = &Hu3DData[arg0];
Vec sp18;
Vec spC;
switch (arg1->channel) {
case 8:
arg3->unk08.x = temp_r31->scale.x * (arg2 + temp_r31->pos.x);
break;
case 9:
arg3->unk08.y = temp_r31->scale.y * (arg2 + temp_r31->pos.y);
break;
case 10:
arg3->unk08.z = temp_r31->scale.z * (arg2 + temp_r31->pos.z);
break;
case 11:
arg3->unk20.x = temp_r31->scale.x * (arg2 + temp_r31->pos.x);
break;
case 12:
arg3->unk20.y = temp_r31->scale.y * (arg2 + temp_r31->pos.y);
break;
case 13:
arg3->unk20.z = temp_r31->scale.z * (arg2 + temp_r31->pos.z);
break;
case 14:
PSVECSubtract(&arg3->unk08, &arg3->unk20, &spC);
PSVECNormalize(&spC, &spC);
sp18.x = spC.x * spC.y * (1.0 - cos(M_PI * arg2 / 180.0)) - spC.z * sin(M_PI * arg2 / 180.0);
sp18.y = spC.y * spC.y + (1.0f - spC.y * spC.y) * cos(M_PI * arg2 / 180.0);
sp18.z = spC.y * spC.z * (1.0 - cos(M_PI * arg2 / 180.0)) + spC.x * sin(M_PI * arg2 / 180.0);
PSVECNormalize(&sp18, &arg3->unk14);
break;
}
}
float InterpolateBMLine(float *arg0, float *arg1, float arg2) {
float sp8[2];
float temp_f22;
float var_f21;
float temp_f20;
float temp_f29;
float temp_f31;
float var_f28;
float var_f27;
float var_f26;
float var_f25;
float var_f24;
float var_f23;
float var_f30;
s32 var_r30;
s32 var_r29;
s32 i;
if (arg0[0] == arg0[1] && arg0[0] == arg0[2] && arg0[0] == arg0[3]) {
return arg0[0];
}
for (i = 1; i <= 2; i++) {
sp8[i - 1] = 0.5f * ((arg0[i] - arg0[i - 1]) / (arg1[i] - arg1[i - 1]) + (arg0[i + 1] - arg0[i]) / (arg1[i + 1] - arg1[i]));
}
temp_f29 = 0.5f * (arg1[2] + arg1[1]);
var_r30 = 0;
if (sp8[1] - sp8[0] != 0.0f) {
temp_f22 = (sp8[1] * arg1[2] - sp8[0] * arg1[1] - (arg0[2] - arg0[1])) / (sp8[1] - sp8[0]);
var_r29 = 0;
if (arg1[1] <= temp_f22 && temp_f22 <= arg1[2]) {
var_r29 = 1;
}
var_r30 = (var_r29 != 0) ? 1 : 0;
}
if (var_r30 == 1) {
temp_f31 = temp_f29 - arg1[1];
temp_f20 = (arg0[2] - arg0[1]) / (arg1[2] - arg1[1]) - (sp8[1] - sp8[0]) / 2;
var_f28 = temp_f20 * temp_f31 + ((sp8[1] - sp8[0]) / (2.0f * (arg1[2] - arg1[1]))) * temp_f31 * temp_f31 + arg0[1];
var_f27 = temp_f20 + temp_f31 * ((sp8[1] - sp8[0]) / (arg1[2] - arg1[1]));
} else {
temp_f31 = temp_f29 - arg1[1];
var_f28 = (arg0[2] + arg0[1]) * (temp_f31 / (arg1[2] - arg1[1]));
var_f27 = 2.0f * (arg0[2] - arg0[1]) / (arg1[2] - arg1[1]) - (sp8[1] + sp8[0]) * (temp_f31 / (arg1[2] - arg1[1]));
}
if (arg2 < temp_f29) {
var_f30 = arg1[1];
var_f26 = arg0[1];
var_f25 = sp8[0];
var_f24 = temp_f29;
var_f21 = var_f28;
var_f23 = var_f27;
} else {
var_f30 = temp_f29;
var_f26 = var_f28;
var_f25 = var_f27;
var_f24 = arg1[2];
var_f21 = arg0[2];
var_f23 = sp8[1];
}
return ((var_f23 - var_f25) / (2.0f * (var_f24 - var_f30))) * (arg2 - var_f30) * (arg2 - var_f30) + (arg2 - var_f30) * ((var_f21 - var_f26) / (var_f24 - var_f30) - (var_f23 - var_f25) / 2) + var_f26;
}
void Hu3D2Dto3D(Vec *arg0, s16 arg1, Vec *arg2) {
CameraData *temp_r31;
float temp_f31;
float temp_f30;
float temp_f29;
float temp_f28;
float temp_f27;
s16 i;
Mtx spC;
for (i = 0; i < 16; i++) {
if (arg1 & (1 << i)) {
break;
}
}
temp_r31 = &Hu3DCamera[i];
temp_f30 = sin((temp_r31->fov / 2) * M_PI / 180.0) / cos((temp_r31->fov / 2) * M_PI / 180.0);
temp_f31 = temp_f30 * arg0->z * 2.0f;
temp_f29 = temp_f31 * 1.2f;
temp_f28 = arg0->x / 576.0f;
temp_f27 = arg0->y / 480.0f;
arg2->x = (temp_f28 - 0.5) * temp_f29;
arg2->y = -(temp_f27 - 0.5) * temp_f31;
arg2->z = -arg0->z;
C_MTXLookAt(spC, &temp_r31->pos, &temp_r31->up, &temp_r31->target);
PSMTXInverse(spC, spC);
PSMTXMultVec(spC, arg2, arg2);
}
void Hu3D3Dto2D(Vec *arg0, s16 arg1, Vec *arg2) {
Vec sp10;
CameraData *temp_r31;
float temp_f31;
float temp_f30;
s16 i;
Mtx sp1C;
for (i = 0; i < 16; i++) {
if (arg1 & (1 << i)) {
break;
}
}
temp_r31 = &Hu3DCamera[i];
C_MTXLookAt(sp1C, &temp_r31->pos, &temp_r31->up, &temp_r31->target);
PSMTXMultVec(sp1C, arg0, &sp10);
temp_f31 = (sin((temp_r31->fov / 2) * M_PI / 180.0) / cos((temp_r31->fov / 2) * M_PI / 180.0)) * sp10.z * 1.2000000476837158;
temp_f30 = (sin((temp_r31->fov / 2) * M_PI / 180.0) / cos((temp_r31->fov / 2) * M_PI / 180.0)) * sp10.z;
arg2->x = 288.0f + sp10.x * (288.0f / -temp_f31);
arg2->y = 240.0f + sp10.y * (240.0f / temp_f30);
arg2->z = 0.0f;
}
void Hu3DMtxTransGet(Mtx arg0, Vec *arg1) {
arg1->x = arg0[0][3];
arg1->y = arg0[1][3];
arg1->z = arg0[2][3];
}
static inline float Hu3DMtxRotGetInlineFunc01(float arg0, float arg1) {
return atan2(arg0, arg1);
}
static inline float Hu3DMtxRotGetInlineFunc02(float arg0) {
return asin(arg0);
}
static inline float Hu3DMtxRotGetInlineFunc03(float arg0, float arg1) {
if (arg1 == 0.0f) {
if (arg0 >= 0.0f) {
return M_PI / 2;
} else {
return -(M_PI / 2);
}
} else {
return Hu3DMtxRotGetInlineFunc01(arg0, arg1);
}
}
void Hu3DMtxRotGet(Mtx arg0, Vec *arg1) {
float sp48;
float sp44;
float sp3C;
float sp34;
float temp_f28;
float temp_f27;
float temp_f26;
float var_f25;
float temp_f24;
temp_f28 = arg0[0][0] * arg0[0][0] + arg0[1][0] * arg0[1][0] + arg0[2][0] * arg0[2][0];
sp44 = sqrtf(temp_f28);
if (!(sp44 < 0.00000001f)) {
temp_f27 = arg0[0][1] * arg0[0][1] + arg0[1][1] * arg0[1][1] + arg0[2][1] * arg0[2][1];
sp3C = sqrtf(temp_f27);
if (!(sp3C < 0.00000001f)) {
temp_f26 = arg0[0][2] * arg0[0][2] + arg0[1][2] * arg0[1][2] + arg0[2][2] * arg0[2][2];
sp34 = sqrtf(temp_f26);
if (!(sp34 < 0.00000001f)) {
temp_f24 = -arg0[2][0] / sp44;
if (temp_f24 >= 1.0f) {
var_f25 = M_PI / 2;
} else if (temp_f24 <= -1.0f) {
var_f25 = -(M_PI / 2);
} else {
var_f25 = Hu3DMtxRotGetInlineFunc02(temp_f24);
}
arg1->y = var_f25;
sp48 = cos(arg1->y);
if (sp48 >= 0.00000001f) {
arg1->x = Hu3DMtxRotGetInlineFunc03(arg0[2][1] / sp3C, arg0[2][2] / sp34);
arg1->z = Hu3DMtxRotGetInlineFunc03(arg0[1][0], arg0[0][0]);
} else {
arg1->x = Hu3DMtxRotGetInlineFunc03(arg0[0][1], arg0[1][1]);
arg1->z = 0.0f;
}
arg1->x = arg1->x * 57.29578f;
arg1->y = arg1->y * 57.29578f;
arg1->z = arg1->z * 57.29578f;
return;
}
}
}
arg1->x = 0.0f;
arg1->y = 0.0f;
arg1->z = 0.0f;
}
void Hu3DMtxScaleGet(Mtx arg0, Vec *arg1) {
Vec sp38;
Vec sp2C;
Vec sp20;
Vec sp14;
Vec sp8;
sp2C.x = arg0[0][0];
sp2C.y = arg0[1][0];
sp2C.z = arg0[2][0];
arg1->x = PSVECMag(&sp2C);
PSVECNormalize(&sp2C, &sp2C);
sp20.x = arg0[0][1];
sp20.y = arg0[1][1];
sp20.z = arg0[2][1];
sp38.x = PSVECDotProduct(&sp2C, &sp20);
PSVECScale(&sp2C, &sp8, sp38.x);
PSVECSubtract(&sp20, &sp8, &sp20);
arg1->y = PSVECMag(&sp20);
PSVECNormalize(&sp20, &sp20);
sp38.x /= arg1->y;
sp14.x = arg0[0][2];
sp14.y = arg0[1][2];
sp14.z = arg0[2][2];
sp38.z = PSVECDotProduct(&sp20, &sp14);
PSVECScale(&sp20, &sp8, sp38.z);
PSVECSubtract(&sp14, &sp8, &sp14);
sp38.y = PSVECDotProduct(&sp2C, &sp14);
PSVECScale(&sp2C, &sp8, sp38.y);
PSVECSubtract(&sp14, &sp8, &sp14);
arg1->z = PSVECMag(&sp14);
PSVECNormalize(&sp14, &sp14);
PSVECCrossProduct(&sp20, &sp14, &sp8);
if (PSVECDotProduct(&sp2C, &sp8) < 0.0) {
arg1->x *= -1.0;
arg1->y *= -1.0;
arg1->z *= -1.0;
}
}