Feature/groove animations (#59)

* implements groove animations
This commit is contained in:
Jeff Harris 2021-09-14 12:00:21 +12:00 committed by GitHub
parent f0ff895a8f
commit 9ac6479f34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 885 additions and 29 deletions

View File

@ -12,4 +12,5 @@ Does a `return` at the top of the function in the retail game. Appears to have b
### SetFlag2 / ToggleFlying
TBA
### DoDemo
Reads `DEMOFILE.TXT` which lists a number of `.CNT` files. Each `.CNT` file appears to contain a number of full-screen background images which are displayed as a slideshow. Sound ID `10000` is played during the slideshow.

View File

@ -206,19 +206,55 @@ void BrMatrix34Scale(br_matrix34* mat, br_scalar sx, br_scalar sy, br_scalar sz)
// IDA: void __cdecl BrMatrix34ShearX(br_matrix34 *mat, br_scalar sy, br_scalar sz)
void BrMatrix34ShearX(br_matrix34* mat, br_scalar sy, br_scalar sz) {
LOG_TRACE("(%p, %f, %f)", mat, sy, sz);
NOT_IMPLEMENTED();
M(0, 0) = 1;
M(0, 1) = sy;
M(0, 2) = sz;
M(1, 0) = 0;
M(1, 1) = 1;
M(1, 2) = 0;
M(2, 0) = 0;
M(2, 1) = 0;
M(2, 2) = 1;
M(3, 0) = 0;
M(3, 1) = 0;
M(3, 2) = 0;
}
// IDA: void __cdecl BrMatrix34ShearY(br_matrix34 *mat, br_scalar sx, br_scalar sz)
void BrMatrix34ShearY(br_matrix34* mat, br_scalar sx, br_scalar sz) {
LOG_TRACE("(%p, %f, %f)", mat, sx, sz);
NOT_IMPLEMENTED();
M(0, 0) = 1;
M(0, 1) = 0;
M(0, 2) = 0;
M(1, 0) = sx;
M(1, 1) = 1;
M(1, 2) = sz;
M(2, 0) = 0;
M(2, 1) = 0;
M(2, 2) = 1;
M(3, 0) = 0;
M(3, 1) = 0;
M(3, 2) = 0;
}
// IDA: void __cdecl BrMatrix34ShearZ(br_matrix34 *mat, br_scalar sx, br_scalar sy)
void BrMatrix34ShearZ(br_matrix34* mat, br_scalar sx, br_scalar sy) {
LOG_TRACE("(%p, %f, %f)", mat, sx, sy);
NOT_IMPLEMENTED();
M(0, 0) = 1;
M(0, 1) = 0;
M(0, 2) = 0;
M(1, 0) = 0;
M(1, 1) = 1;
M(1, 2) = 0;
M(2, 0) = sx;
M(2, 1) = sy;
M(2, 2) = 1;
M(3, 0) = 0;
M(3, 1) = 0;
M(3, 2) = 0;
}
// IDA: br_scalar __cdecl BrMatrix34Inverse(br_matrix34 *B, br_matrix34 *A)
@ -527,7 +563,10 @@ void BrMatrix34PreShearX(br_matrix34* mat, br_scalar sy, br_scalar sz) {
// IDA: void __cdecl BrMatrix34PostShearX(br_matrix34 *mat, br_scalar sy, br_scalar sz)
void BrMatrix34PostShearX(br_matrix34* mat, br_scalar sy, br_scalar sz) {
LOG_TRACE("(%p, %f, %f)", mat, sy, sz);
NOT_IMPLEMENTED();
BrMatrix34ShearX(&mattmp1, sy, sz);
BrMatrix34Mul(&mattmp2, mat, &mattmp1);
BrMatrix34Copy(mat, &mattmp2);
}
// IDA: void __cdecl BrMatrix34PreShearY(br_matrix34 *mat, br_scalar sx, br_scalar sz)
@ -539,7 +578,10 @@ void BrMatrix34PreShearY(br_matrix34* mat, br_scalar sx, br_scalar sz) {
// IDA: void __cdecl BrMatrix34PostShearY(br_matrix34 *mat, br_scalar sx, br_scalar sz)
void BrMatrix34PostShearY(br_matrix34* mat, br_scalar sx, br_scalar sz) {
LOG_TRACE("(%p, %f, %f)", mat, sx, sz);
NOT_IMPLEMENTED();
BrMatrix34ShearY(&mattmp1, sx, sz);
BrMatrix34Mul(&mattmp2, mat, &mattmp1);
BrMatrix34Copy(mat, &mattmp2);
}
// IDA: void __cdecl BrMatrix34PreShearZ(br_matrix34 *mat, br_scalar sx, br_scalar sy)
@ -551,5 +593,8 @@ void BrMatrix34PreShearZ(br_matrix34* mat, br_scalar sx, br_scalar sy) {
// IDA: void __cdecl BrMatrix34PostShearZ(br_matrix34 *mat, br_scalar sx, br_scalar sy)
void BrMatrix34PostShearZ(br_matrix34* mat, br_scalar sx, br_scalar sy) {
LOG_TRACE("(%p, %f, %f)", mat, sx, sy);
NOT_IMPLEMENTED();
BrMatrix34ShearZ(&mattmp1, sx, sy);
BrMatrix34Mul(&mattmp2, mat, &mattmp1);
BrMatrix34Copy(mat, &mattmp2);
}

View File

@ -77,6 +77,9 @@ void BrMatrix34LPNormalise(br_matrix34* A, br_matrix34* B);
void BrMatrix34PreRotate(br_matrix34* mat, br_angle r, br_vector3* axis);
void BrMatrix34Rotate(br_matrix34* mat, br_angle r, br_vector3* a);
void BrMatrix34PreTranslate(br_matrix34* mat, br_scalar x, br_scalar y, br_scalar z);
void BrMatrix34PostShearX(br_matrix34* mat, br_scalar sy, br_scalar sz);
void BrMatrix34PostShearY(br_matrix34* mat, br_scalar sx, br_scalar sz);
void BrMatrix34PostShearZ(br_matrix34* mat, br_scalar sx, br_scalar sy);
// BrMem
void BrMemFree(void* block);

View File

@ -182,7 +182,7 @@ void SelectOpponents(tRace_info* pRace_info) {
had_scum = 0;
if (!gNet_mode) {
pRace_info->number_of_racers = 5;
pRace_info->number_of_racers = OPPONENT_COUNT;
for (i = 0; i < gNumber_of_racers; ++i) {
gOpponents[i].picked = 0;
}
@ -191,7 +191,7 @@ void SelectOpponents(tRace_info* pRace_info) {
} else {
rank_band = gRace_list[gProgram_state.current_race_index].suggested_rank / 10;
}
for (i = 0; i < 5; i++) {
for (i = 0; i < OPPONENT_COUNT; i++) {
nastiness = gOpponent_mix[rank_band][i];
pRace_info->opponent_list[i].index = ChooseOpponent(nastiness, &had_scum);
pRace_info->opponent_list[i].ranking = IRandomBetween(gProgram_state.rank - 10, gProgram_state.rank + 10);

View File

@ -327,40 +327,58 @@ void DRMatrix34RotateX(br_matrix34* mat, br_angle rx) {
br_scalar s;
br_scalar c;
LOG_TRACE("(%p, %d)", mat, rx);
NOT_IMPLEMENTED();
s = FastScalarSinAngle(rx);
c = FastScalarCosAngle(rx);
mat->m[0][0] = 1.0;
mat->m[0][1] = 0.0;
mat->m[0][2] = 0.0;
mat->m[1][0] = 0.0;
mat->m[1][1] = c;
mat->m[1][2] = s;
mat->m[2][0] = 0.0;
mat->m[2][1] = -s;
mat->m[2][2] = c;
mat->m[3][0] = 0.0;
mat->m[3][1] = 0.0;
mat->m[3][2] = 0.0;
}
// IDA: void __usercall DRMatrix34RotateY(br_matrix34 *mat@<EAX>, br_angle ry@<EDX>)
void DRMatrix34RotateY(br_matrix34* mat, br_angle ry) {
br_scalar s;
br_scalar c;
LOG_TRACE("(%p, %d)", mat, ry);
LOG_TRACE8("(%p, %d)", mat, ry);
s = FastScalarSinAngle(ry);
c = FastScalarCosAngle(ry);
mat->m[0][0] = c;
mat->m[0][1] = 0.0;
mat->m[0][2] = -s;
mat->m[1][0] = 0.0;
mat->m[1][1] = 1.0;
mat->m[1][2] = 0.0;
mat->m[2][0] = s;
mat->m[2][1] = 0.0;
mat->m[2][2] = c;
mat->m[3][0] = 0.0;
mat->m[3][1] = 0.0;
mat->m[3][2] = 0.0;
mat->m[0][0] = c;
mat->m[2][0] = s;
mat->m[0][2] = -s;
mat->m[2][2] = c;
}
// IDA: void __usercall DRMatrix34RotateZ(br_matrix34 *mat@<EAX>, br_angle rz@<EDX>)
void DRMatrix34RotateZ(br_matrix34* mat, br_angle rz) {
br_scalar s;
br_scalar c;
LOG_TRACE("(%p, %d)", mat, rz);
LOG_TRACE8("(%p, %d)", mat, rz);
s = FastScalarSinAngle(rz);
c = FastScalarCosAngle(rz);
mat->m[0][0] = c;
mat->m[0][1] = s;
mat->m[0][2] = 0.0;
mat->m[1][0] = -s;
mat->m[1][1] = c;
mat->m[1][2] = 0.0;
mat->m[2][0] = 0.0;
mat->m[2][1] = 0.0;
@ -368,10 +386,6 @@ void DRMatrix34RotateZ(br_matrix34* mat, br_angle rz) {
mat->m[3][0] = 0.0;
mat->m[3][1] = 0.0;
mat->m[3][2] = 0.0;
mat->m[0][0] = c;
mat->m[0][1] = s;
mat->m[1][0] = -s;
mat->m[1][1] = c;
}
// IDA: void __usercall DRMatrix34Rotate(br_matrix34 *mat@<EAX>, br_angle r@<EDX>, br_vector3 *a@<EBX>)
@ -398,7 +412,10 @@ void DRMatrix34PreRotateX(br_matrix34* mat, br_angle rx) {
// IDA: void __usercall DRMatrix34PostRotateX(br_matrix34 *mat@<EAX>, br_angle rx@<EDX>)
void DRMatrix34PostRotateX(br_matrix34* mat, br_angle rx) {
LOG_TRACE("(%p, %d)", mat, rx);
NOT_IMPLEMENTED();
DRMatrix34RotateX(&mattmp2__trig, rx);
BrMatrix34Mul(&mattmp1__trig, mat, &mattmp2__trig);
BrMatrix34Copy(mat, &mattmp1__trig);
}
// IDA: void __usercall DRMatrix34PreRotateY(br_matrix34 *mat@<EAX>, br_angle ry@<EDX>)

View File

@ -11,12 +11,16 @@
#include "flicplay.h"
#include "globvars.h"
#include "globvrpb.h"
#include "graphics.h"
#include "harness.h"
#include "loading.h"
#include "opponent.h"
#include "pd/sys.h"
#include "pedestrn.h"
#include "piping.h"
#include "replay.h"
#include "spark.h"
#include "trig.h"
#include "utility.h"
#include <string.h>
@ -71,7 +75,12 @@ br_scalar gSight_distance_squared;
// IDA: float __cdecl MapSawToTriangle(float pNumber)
float MapSawToTriangle(float pNumber) {
LOG_TRACE("(%f)", pNumber);
NOT_IMPLEMENTED();
if (pNumber >= 0.5) {
return 3.0 - pNumber * 4.0;
} else {
return pNumber * 4.0 - 1.0;
}
}
// IDA: void __cdecl SetSightDistance(br_scalar pYon)
@ -2572,21 +2581,285 @@ void LollipopizeActor(br_actor* pSubject_actor, br_matrix34* ref_to_world, tLoll
// IDA: void __usercall CalcActorGlobalPos(br_vector3 *pResult@<EAX>, br_actor *pActor@<EDX>)
void CalcActorGlobalPos(br_vector3* pResult, br_actor* pActor) {
LOG_TRACE("(%p, %p)", pResult, pActor);
NOT_IMPLEMENTED();
pResult->v[0] = 0.0;
pResult->v[1] = 0.0;
pResult->v[2] = 0.0;
while (pActor && pActor != gNon_track_actor) {
pResult->v[0] = pActor->t.t.mat.m[3][0] + pResult->v[0];
pResult->v[1] = pActor->t.t.mat.m[3][1] + pResult->v[1];
pResult->v[2] = pActor->t.t.mat.m[3][2] + pResult->v[2];
pActor = pActor->parent;
}
}
// IDA: int __usercall PointOutOfSight@<EAX>(br_vector3 *pPoint@<EAX>, br_scalar pMax_distance)
int PointOutOfSight(br_vector3* pPoint, br_scalar pMax_distance) {
br_vector3 distance_vector;
LOG_TRACE("(%p, %f)", pPoint, pMax_distance);
NOT_IMPLEMENTED();
if (gMirror_on__graphics) {
distance_vector.v[0] = pPoint->v[0] - gRearview_camera_to_world.m[3][0];
distance_vector.v[1] = pPoint->v[1] - gRearview_camera_to_world.m[3][1];
distance_vector.v[2] = pPoint->v[2] - gRearview_camera_to_world.m[3][2];
if (distance_vector.v[0] * distance_vector.v[0]
+ distance_vector.v[1] * distance_vector.v[1]
+ distance_vector.v[2] * distance_vector.v[2]
< pMax_distance
&& gRearview_camera_to_world.m[2][2] * distance_vector.v[2]
+ gRearview_camera_to_world.m[2][1] * distance_vector.v[1]
+ gRearview_camera_to_world.m[2][0] * distance_vector.v[0]
< 0.0) {
return 0;
}
}
distance_vector.v[0] = pPoint->v[0] - gCamera_to_world.m[3][0];
distance_vector.v[1] = pPoint->v[1] - gCamera_to_world.m[3][1];
distance_vector.v[2] = pPoint->v[2] - gCamera_to_world.m[3][2];
return distance_vector.v[0] * distance_vector.v[0] + distance_vector.v[1] * distance_vector.v[1] + distance_vector.v[2] * distance_vector.v[2] >= pMax_distance
|| gCamera_to_world.m[2][2] * distance_vector.v[2] + gCamera_to_world.m[2][1] * distance_vector.v[1] + gCamera_to_world.m[2][0] * distance_vector.v[0] >= 0.0;
}
// IDA: void __usercall PathGrooveBastard(tGroovidelic_spec *pGroove@<EAX>, tU32 pTime@<EDX>, br_matrix34 *pMat@<EBX>, int pInterrupt_it@<ECX>)
void PathGrooveBastard(tGroovidelic_spec* pGroove, tU32 pTime, br_matrix34* pMat, int pInterrupt_it) {
br_scalar pos;
LOG_TRACE("(%p, %d, %p, %d)", pGroove, pTime, pMat, pInterrupt_it);
NOT_IMPLEMENTED();
pos = 0;
if (pGroove->path_type == eGroove_path_straight) {
if (pGroove->path_data.straight_info.x_delta != 0.0) {
switch (pGroove->path_mode) {
case eMove_continuous:
if (pGroove->path_data.straight_info.period != 0.0) {
pos = fmod(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period * pGroove->path_data.straight_info.x_delta;
}
break;
case eMove_controlled:
pos = pGroove->path_data.straight_info.period * pGroove->path_data.straight_info.x_delta;
break;
case eMove_absolute:
pos = pGroove->path_data.straight_info.period;
break;
case eMove_flash:
if (fmod(pTime, pGroove->path_data.straight_info.period) * 2.0 <= pGroove->path_data.straight_info.period) {
pos = pGroove->path_data.straight_info.x_delta;
} else {
pos = -pGroove->path_data.straight_info.x_delta;
}
break;
case eMove_harmonic:
if (pGroove->path_data.straight_info.period != 0.0) {
pos = sin(
BrAngleToRadian(
BrDegreeToAngle(
fmod(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period * 360.0)))
* pGroove->path_data.straight_info.x_delta;
}
break;
case eMove_linear:
if (pGroove->path_data.straight_info.period != 0.0) {
pos = MapSawToTriangle(fmod(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period)
* pGroove->path_data.straight_info.x_delta;
}
break;
case eMove_none:
break;
}
pos = pGroove->path_data.straight_info.centre.v[0] + pos;
if (pInterrupt_it) {
pGroove->path_resumption_value = pos;
if (pMat->m[3][0] <= pos) {
pGroove->path_interrupt_status = eInterrupt_greater_than;
} else {
pGroove->path_interrupt_status = eInterrupt_less_than;
}
} else if (pGroove->path_interrupt_status) {
if (pGroove->path_interrupt_status == eInterrupt_less_than) {
if (pGroove->path_resumption_value > pos) {
pGroove->path_interrupt_status = eInterrupt_none;
pGroove->actor->t.t.translate.t = pGroove->path_data.straight_info.centre;
pMat->m[3][0] = pos;
}
} else if (pGroove->path_resumption_value < pos) {
pGroove->path_interrupt_status = eInterrupt_none;
pGroove->actor->t.t.euler.t = pGroove->path_data.straight_info.centre;
pMat->m[3][0] = pos;
}
}
}
if (pGroove->path_data.straight_info.y_delta != 0.0) {
pos = 0;
switch (pGroove->path_mode) {
case eMove_continuous:
if (pGroove->path_data.straight_info.period != 0.0) {
pos = fmod(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period * pGroove->path_data.straight_info.y_delta;
}
break;
case eMove_controlled:
pos = pGroove->path_data.straight_info.period * pGroove->path_data.straight_info.y_delta;
break;
case eMove_absolute:
pos = pGroove->path_data.straight_info.period;
break;
case eMove_flash:
if (fmod(pTime, pGroove->path_data.straight_info.period) * 2.0 <= pGroove->path_data.straight_info.period) {
pos = pGroove->path_data.straight_info.y_delta;
} else {
pos = -pGroove->path_data.straight_info.y_delta;
}
break;
case eMove_harmonic:
if (pGroove->path_data.straight_info.period != 0.0) {
pos = sin(
BrAngleToRadian(
BrDegreeToAngle(
fmod(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period * 360.0)))
* pGroove->path_data.straight_info.y_delta;
}
break;
case eMove_linear:
if (pGroove->path_data.straight_info.period != 0.0) {
pos = MapSawToTriangle(fmod(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period)
* pGroove->path_data.straight_info.y_delta;
}
break;
case eMove_none:
break;
}
pos = pGroove->path_data.straight_info.centre.v[1] + pos;
if (pInterrupt_it) {
pGroove->path_resumption_value = pos;
if (pMat->m[3][1] <= pos) {
pGroove->path_interrupt_status = eInterrupt_greater_than;
} else {
pGroove->path_interrupt_status = eInterrupt_less_than;
}
} else if (pGroove->path_interrupt_status) {
if (pGroove->path_interrupt_status == eInterrupt_less_than) {
if (pGroove->path_resumption_value > pos) {
pGroove->path_interrupt_status = eInterrupt_none;
pGroove->actor->t.t.translate.t = pGroove->path_data.straight_info.centre;
pMat->m[3][1] = pos;
}
} else if (pGroove->path_resumption_value < pos) {
pGroove->path_interrupt_status = eInterrupt_none;
pGroove->actor->t.t.euler.t = pGroove->path_data.straight_info.centre;
pMat->m[3][1] = pos;
}
}
}
if (pGroove->path_data.straight_info.z_delta != 0.0) {
pos = 0;
switch (pGroove->path_mode) {
case eMove_continuous:
if (pGroove->path_data.straight_info.period != 0.0) {
pos = fmod(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period * pGroove->path_data.straight_info.z_delta;
}
break;
case eMove_controlled:
pos = pGroove->path_data.straight_info.period * pGroove->path_data.straight_info.z_delta;
break;
case eMove_absolute:
pos = pGroove->path_data.straight_info.period;
break;
case eMove_flash:
if (fmod(pTime, pGroove->path_data.straight_info.period) * 2.0 <= pGroove->path_data.straight_info.period) {
pos = pGroove->path_data.straight_info.z_delta;
} else {
pos = -pGroove->path_data.straight_info.z_delta;
}
break;
case eMove_harmonic:
if (pGroove->path_data.straight_info.period != 0.0) {
pos = sin(
BrAngleToRadian(
BrDegreeToAngle(
fmod(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period * 360.0)))
* pGroove->path_data.straight_info.z_delta;
}
break;
case eMove_linear:
if (pGroove->path_data.straight_info.period != 0.0) {
pos = MapSawToTriangle(fmod(pTime, pGroove->path_data.straight_info.period) / pGroove->path_data.straight_info.period)
* pGroove->path_data.straight_info.z_delta;
}
break;
case eMove_none:
break;
}
pos = pGroove->path_data.straight_info.centre.v[1] + pos;
if (pInterrupt_it) {
pGroove->path_resumption_value = pos;
if (pMat->m[3][2] <= pos) {
pGroove->path_interrupt_status = eInterrupt_greater_than;
} else {
pGroove->path_interrupt_status = eInterrupt_less_than;
}
} else if (pGroove->path_interrupt_status) {
if (pGroove->path_interrupt_status == eInterrupt_less_than) {
if (pGroove->path_resumption_value > pos) {
pGroove->path_interrupt_status = eInterrupt_none;
pGroove->actor->t.t.translate.t = pGroove->path_data.straight_info.centre;
pMat->m[3][2] = pos;
}
} else if (pGroove->path_resumption_value < pos) {
pGroove->path_interrupt_status = eInterrupt_none;
pGroove->actor->t.t.euler.t = pGroove->path_data.straight_info.centre;
pMat->m[3][2] = pos;
}
}
}
pGroove->object_position = pGroove->actor->t.t.translate.t;
} else if (pGroove->path_type == eGroove_path_circular) {
pGroove->actor->t.t.translate.t = pGroove->path_data.circular_info.centre;
if (pGroove->path_data.circular_info.axis == eGroove_axis_y) {
if (pGroove->path_data.circular_info.period != 0.0) {
pos = cos(BrAngleToRadian(BrDegreeToAngle(fmod(pTime, pGroove->path_data.circular_info.period) / pGroove->path_data.circular_info.period * 360.0))) * pGroove->path_data.circular_info.radius;
pMat->m[3][0] = pGroove->path_data.circular_info.centre.v[0] + pos;
}
} else if (pGroove->path_data.circular_info.axis == eGroove_axis_z) {
if (pGroove->path_data.circular_info.period != 0.0) {
pos = sin(BrAngleToRadian(BrDegreeToAngle(fmod(pTime, pGroove->path_data.circular_info.period) / pGroove->path_data.circular_info.period * 360.0))) * pGroove->path_data.circular_info.radius;
pMat->m[3][0] = pGroove->path_data.circular_info.centre.v[0] + pos;
}
}
if (pGroove->path_data.circular_info.axis) {
if (pGroove->path_data.circular_info.axis == eGroove_axis_z) {
if (pGroove->path_data.circular_info.period != 0.0) {
pos = cos(BrAngleToRadian(BrDegreeToAngle(fmod(pTime, pGroove->path_data.circular_info.period) / pGroove->path_data.circular_info.period * 360.0))) * pGroove->path_data.circular_info.radius;
pMat->m[3][1] = pGroove->path_data.circular_info.centre.v[1] + pos;
}
} else {
if (pGroove->path_data.circular_info.period != 0.0) {
pos = sin(BrAngleToRadian(BrDegreeToAngle(fmod(pTime, pGroove->path_data.circular_info.period) / pGroove->path_data.circular_info.period * 360.0))) * pGroove->path_data.circular_info.radius;
pMat->m[3][1] = pGroove->path_data.circular_info.centre.v[1] + pos;
}
}
}
if (pGroove->path_data.circular_info.axis) {
if (pGroove->path_data.circular_info.axis == eGroove_axis_y) {
if (pGroove->path_data.circular_info.period != 0.0) {
pos = sin(BrAngleToRadian(BrDegreeToAngle(fmod(pTime, pGroove->path_data.circular_info.period) / pGroove->path_data.circular_info.period * 360.0))) * pGroove->path_data.circular_info.radius;
pMat->m[3][2] = pGroove->path_data.circular_info.centre.v[2] + pos;
}
} else {
if (pGroove->path_data.circular_info.period != 0.0) {
pos = cos(BrAngleToRadian(BrDegreeToAngle(fmod(pTime, pGroove->path_data.circular_info.period) / pGroove->path_data.circular_info.period * 360.0))) * pGroove->path_data.circular_info.radius;
pMat->m[3][2] = pGroove->path_data.circular_info.centre.v[2] + pos;
}
}
pGroove->object_position = pGroove->actor->t.t.translate.t;
}
}
}
// IDA: void __usercall ObjectGrooveBastard(tGroovidelic_spec *pGroove@<EAX>, tU32 pTime@<EDX>, br_matrix34 *pMat@<EBX>, int pInterrupt_it@<ECX>)
@ -2598,7 +2871,445 @@ void ObjectGrooveBastard(tGroovidelic_spec* pGroove, tU32 pTime, br_matrix34* pM
br_scalar pos;
br_bounds* bounds;
LOG_TRACE("(%p, %d, %p, %d)", pGroove, pTime, pMat, pInterrupt_it);
NOT_IMPLEMENTED();
x_size = 0;
y_size = 0;
z_size = 0;
pos = 0;
switch (pGroove->object_type) {
case eGroove_object_spin:
if (pGroove->object_data.spin_info.axis == eGroove_axis_y) {
if (pGroove->object_mode == eMove_continuous) {
if (pGroove->object_data.spin_info.period != 0.0) {
pos = fmod(pTime, pGroove->object_data.spin_info.period) / pGroove->object_data.spin_info.period * 360.0;
}
} else if (pGroove->object_mode == eMove_controlled) {
pos = pGroove->object_data.spin_info.period * 360.0;
} else if (pGroove->object_mode == eMove_absolute) {
pos = pGroove->object_data.spin_info.period;
} else if (pGroove->object_mode == eMove_flash) {
if (fmod(pTime, pGroove->object_data.spin_info.period) * 2.0 <= pGroove->object_data.spin_info.period) {
pos = 3.85156;
} else {
pos = -3.85156;
}
} else if (pGroove->object_mode == eMove_harmonic) {
if (pGroove->object_data.spin_info.period != 0.0) {
pos = sin(
BrAngleToRadian(
BrDegreeToAngle(
fmod(pTime, pGroove->object_data.spin_info.period) / pGroove->object_data.spin_info.period * 360.0)))
* 360.0;
}
} else {
if (pGroove->object_data.spin_info.period != 0.0) {
pos = fmod(pTime, pGroove->object_data.spin_info.period) / pGroove->object_data.spin_info.period;
pos = MapSawToTriangle(pos) * 360.0;
}
}
DRMatrix34PostRotateY(pMat, BrDegreeToAngle(pos));
} else if (pGroove->object_data.spin_info.axis == eGroove_axis_z) {
if (pGroove->object_mode == eMove_continuous) {
if (pGroove->object_data.spin_info.period != 0.0) {
pos = fmod(pTime, pGroove->object_data.spin_info.period) / pGroove->object_data.spin_info.period * 360.0;
}
} else if (pGroove->object_mode == eMove_controlled) {
pos = pGroove->object_data.spin_info.period * 360.0;
} else if (pGroove->object_mode == eMove_absolute) {
pos = pGroove->object_data.spin_info.period;
} else if (pGroove->object_mode == eMove_flash) {
if (fmod(pTime, pGroove->object_data.spin_info.period) * 2.0 <= pGroove->object_data.spin_info.period) {
pos = 3.85156;
} else {
pos = -3.85156;
}
} else if (pGroove->object_mode == eMove_harmonic) {
if (pGroove->object_data.spin_info.period != 0.0) {
pos = sin(
BrAngleToRadian(
BrDegreeToAngle(
fmod(pTime, pGroove->object_data.spin_info.period) / pGroove->object_data.spin_info.period * 360.0)))
* 360.0;
}
} else {
if (pGroove->object_data.spin_info.period != 0.0) {
pos = fmod(pTime, pGroove->object_data.spin_info.period) / pGroove->object_data.spin_info.period;
pos = MapSawToTriangle(pos) * 360.0;
}
}
DRMatrix34PostRotateZ(pMat, BrDegreeToAngle(pos));
} else if (pGroove->object_data.spin_info.axis == eGroove_axis_x) {
if (pGroove->object_mode == eMove_continuous) {
if (pGroove->object_data.spin_info.period != 0.0) {
pos = fmod(pTime, pGroove->object_data.spin_info.period) / pGroove->object_data.spin_info.period * 360.0;
}
} else if (pGroove->object_mode == eMove_controlled) {
pos = pGroove->object_data.spin_info.period * 360.0;
} else if (pGroove->object_mode == eMove_absolute) {
pos = pGroove->object_data.spin_info.period;
} else if (pGroove->object_mode == eMove_flash) {
if (fmod(pTime, pGroove->object_data.spin_info.period) * 2.0 <= pGroove->object_data.spin_info.period) {
pos = 3.85156;
} else {
pos = -3.85156;
}
} else if (pGroove->object_mode == eMove_harmonic) {
if (pGroove->object_data.spin_info.period != 0.0) {
pos = sin(
BrAngleToRadian(
BrDegreeToAngle(
fmod(pTime, pGroove->object_data.spin_info.period) / pGroove->object_data.spin_info.period * 360.0)))
* 360.0;
}
} else {
if (pGroove->object_data.spin_info.period != 0.0) {
pos = fmod(pTime, pGroove->object_data.spin_info.period) / pGroove->object_data.spin_info.period;
pos = MapSawToTriangle(pos) * 360.0;
}
}
DRMatrix34PostRotateX(pMat, BrDegreeToAngle(pos));
}
break;
case eGroove_object_rock:
rock_it = 1;
if (pGroove->object_mode == eMove_continuous) {
if (pGroove->object_data.rock_info.period != 0.0) {
pos = fmod(pTime, pGroove->object_data.rock_info.period) / pGroove->object_data.rock_info.period * pGroove->object_data.rock_info.max_angle;
}
} else if (pGroove->object_mode == eMove_controlled) {
pos = pGroove->object_data.rock_info.period * pGroove->object_data.rock_info.max_angle;
} else if (pGroove->object_mode == eMove_absolute) {
pos = pGroove->object_data.rock_info.period;
} else if (pGroove->object_mode == eMove_flash) {
if (fmod(pTime, pGroove->object_data.rock_info.period) * 2.0 <= pGroove->object_data.rock_info.period) {
pos = pGroove->object_data.rock_info.max_angle;
} else {
pos = -pGroove->object_data.rock_info.max_angle;
}
} else if (pGroove->object_mode == eMove_harmonic) {
if (pGroove->object_data.rock_info.period != 0.0) {
pos = sin(
BrAngleToRadian(
BrDegreeToAngle(
fmod(pTime, pGroove->object_data.rock_info.period) / pGroove->object_data.rock_info.period * 360.0)))
* pGroove->object_data.rock_info.max_angle;
}
} else {
if (pGroove->object_data.rock_info.period != 0.0) {
pos = fmod(pTime, pGroove->object_data.rock_info.period) / pGroove->object_data.rock_info.period;
pos = MapSawToTriangle(pos) * pGroove->object_data.rock_info.max_angle;
}
}
if (pInterrupt_it) {
pGroove->object_resumption_value = pos;
if (pGroove->object_data.rock_info.current_angle <= pos) {
pGroove->object_interrupt_status = eInterrupt_greater_than;
} else {
pGroove->object_interrupt_status = eInterrupt_less_than;
}
} else if (pGroove->object_interrupt_status == eInterrupt_less_than) {
if (pGroove->object_resumption_value <= pos || gAction_replay_mode) {
rock_it = 0;
} else {
pGroove->object_interrupt_status = eInterrupt_none;
}
} else if (pGroove->object_interrupt_status == eInterrupt_greater_than) {
if (pGroove->object_resumption_value >= pos || gAction_replay_mode) {
rock_it = 0;
} else {
pGroove->object_interrupt_status = eInterrupt_none;
}
}
if (rock_it) {
pGroove->object_data.rock_info.current_angle = pos;
}
if (pGroove->object_data.rock_info.axis == eGroove_axis_y) {
DRMatrix34PostRotateY(pMat, BrDegreeToAngle(pGroove->object_data.rock_info.current_angle));
} else if (pGroove->object_data.rock_info.axis == eGroove_axis_z) {
DRMatrix34PostRotateZ(pMat, BrDegreeToAngle(pGroove->object_data.rock_info.current_angle));
} else if (pGroove->object_data.rock_info.axis == eGroove_axis_x) {
DRMatrix34PostRotateX(pMat, BrDegreeToAngle(pGroove->object_data.rock_info.current_angle));
}
break;
case eGroove_object_throb:
if (pGroove->object_mode == eMove_continuous) {
if (pGroove->object_data.throb_info.z_period != 0.0) {
z_size = fmod(pTime, pGroove->object_data.throb_info.z_period) / pGroove->object_data.throb_info.z_period * pGroove->object_data.throb_info.z_magnitude;
}
} else if (pGroove->object_mode == eMove_controlled) {
z_size = pGroove->object_data.throb_info.z_magnitude * pGroove->object_data.throb_info.z_period;
} else if (pGroove->object_mode == eMove_absolute) {
z_size = pGroove->object_data.throb_info.z_period;
} else if (pGroove->object_mode == eMove_flash) {
if (fmod(pTime, pGroove->object_data.throb_info.z_period) * 2.0 <= pGroove->object_data.throb_info.z_period) {
z_size = pGroove->object_data.throb_info.z_magnitude;
} else {
z_size = -pGroove->object_data.throb_info.z_magnitude;
}
} else if (pGroove->object_mode == eMove_harmonic) {
if (pGroove->object_data.throb_info.z_period != 0.0) {
z_size = sin(
BrAngleToRadian(
BrDegreeToAngle(
fmod(pTime, pGroove->object_data.throb_info.z_period) / pGroove->object_data.throb_info.z_period * 360.0)))
* pGroove->object_data.throb_info.z_magnitude;
}
} else {
if (pGroove->object_data.throb_info.z_period != 0.0) {
z_size = fmod(pTime, pGroove->object_data.throb_info.z_period) / pGroove->object_data.throb_info.z_period;
z_size = MapSawToTriangle(z_size) * pGroove->object_data.throb_info.z_magnitude;
}
}
if (pGroove->object_mode == eMove_continuous) {
if (pGroove->object_data.throb_info.x_period != 0.0) {
x_size = fmod(pTime, pGroove->object_data.throb_info.x_period) / pGroove->object_data.throb_info.x_period * pGroove->object_data.throb_info.x_magnitude;
}
} else if (pGroove->object_mode == eMove_controlled) {
x_size = pGroove->object_data.throb_info.x_magnitude * pGroove->object_data.throb_info.x_period;
} else if (pGroove->object_mode == eMove_absolute) {
x_size = pGroove->object_data.throb_info.x_period;
} else if (pGroove->object_mode == eMove_flash) {
if (fmod(pTime, pGroove->object_data.throb_info.x_period) * 2.0 <= pGroove->object_data.throb_info.x_period) {
x_size = pGroove->object_data.throb_info.x_magnitude;
} else {
x_size = -pGroove->object_data.throb_info.x_magnitude;
}
} else if (pGroove->object_mode == eMove_harmonic) {
if (pGroove->object_data.throb_info.x_period != 0.0) {
x_size = sin(
BrAngleToRadian(
BrDegreeToAngle(
fmod(pTime, pGroove->object_data.throb_info.x_period) / pGroove->object_data.throb_info.x_period * 360.0)))
* pGroove->object_data.throb_info.x_magnitude;
}
} else {
if (pGroove->object_data.throb_info.x_period != 0.0) {
x_size = fmod(pTime, pGroove->object_data.throb_info.x_period) / pGroove->object_data.throb_info.x_period;
x_size = MapSawToTriangle(x_size) * pGroove->object_data.throb_info.x_magnitude;
}
}
if (pGroove->object_mode == eMove_continuous) {
if (pGroove->object_data.throb_info.y_period != 0.0) {
y_size = fmod(pTime, pGroove->object_data.throb_info.y_period) / pGroove->object_data.throb_info.y_period * pGroove->object_data.throb_info.y_magnitude;
}
} else if (pGroove->object_mode == eMove_controlled) {
y_size = pGroove->object_data.throb_info.y_magnitude * pGroove->object_data.throb_info.y_period;
} else if (pGroove->object_mode == eMove_absolute) {
y_size = pGroove->object_data.throb_info.y_period;
} else if (pGroove->object_mode == eMove_flash) {
if (fmod(pTime, pGroove->object_data.throb_info.y_period) * 2.0 <= pGroove->object_data.throb_info.y_period) {
y_size = pGroove->object_data.throb_info.y_magnitude;
} else {
y_size = -pGroove->object_data.throb_info.y_magnitude;
}
} else if (pGroove->object_mode == eMove_harmonic) {
if (pGroove->object_data.throb_info.y_period != 0.0) {
y_size = sin(
BrAngleToRadian(
BrDegreeToAngle(
fmod(pTime, pGroove->object_data.throb_info.y_period) / pGroove->object_data.throb_info.y_period * 360.0)))
* pGroove->object_data.throb_info.y_magnitude;
}
} else {
if (pGroove->object_data.throb_info.y_period != 0.0) {
y_size = fmod(pTime, pGroove->object_data.throb_info.y_period) / pGroove->object_data.throb_info.y_period;
y_size = MapSawToTriangle(y_size) * pGroove->object_data.throb_info.y_magnitude;
}
}
BrMatrix34PostScale(pMat, x_size + 1.0, y_size + 1.0, z_size + 1.0);
/* FALLTHROUGH */
case eGroove_object_shear:
bounds = &pGroove->actor->model->bounds;
if (pGroove->object_data.shear_info.x_magnitude == 0.0) {
if (pGroove->object_mode == eMove_continuous) {
if (pGroove->object_data.shear_info.z_period != 0.0) {
z_size = fmod(pTime, pGroove->object_data.shear_info.z_period) / pGroove->object_data.shear_info.z_period * pGroove->object_data.shear_info.z_magnitude;
}
} else if (pGroove->object_mode == eMove_controlled) {
z_size = pGroove->object_data.shear_info.z_magnitude * pGroove->object_data.shear_info.z_period;
} else if (pGroove->object_mode == eMove_absolute) {
z_size = pGroove->object_data.shear_info.z_period;
} else if (pGroove->object_mode == eMove_flash) {
if (fmod(pTime, pGroove->object_data.shear_info.z_period) * 2.0 <= pGroove->object_data.shear_info.z_period) {
z_size = pGroove->object_data.shear_info.z_magnitude;
} else {
z_size = -pGroove->object_data.shear_info.z_magnitude;
}
} else if (pGroove->object_mode == eMove_harmonic) {
if (pGroove->object_data.shear_info.z_period != 0.0) {
z_size = sin(
BrAngleToRadian(
BrDegreeToAngle(
fmod(pTime, pGroove->object_data.shear_info.z_period) / pGroove->object_data.shear_info.z_period * 360.0)))
* pGroove->object_data.shear_info.z_magnitude;
}
} else {
if (pGroove->object_data.shear_info.z_period != 0.0) {
z_size = fmod(pTime, pGroove->object_data.shear_info.z_period) / pGroove->object_data.shear_info.z_period;
z_size = MapSawToTriangle(z_size) * pGroove->object_data.shear_info.z_magnitude;
}
}
if (pGroove->object_mode == eMove_continuous) {
if (pGroove->object_data.shear_info.y_period != 0.0) {
y_size = fmod(pTime, pGroove->object_data.shear_info.y_period) / pGroove->object_data.shear_info.y_period * pGroove->object_data.shear_info.y_magnitude;
}
} else if (pGroove->object_mode == eMove_controlled) {
y_size = pGroove->object_data.shear_info.y_magnitude * pGroove->object_data.shear_info.y_period;
} else if (pGroove->object_mode == eMove_absolute) {
y_size = pGroove->object_data.shear_info.y_period;
} else if (pGroove->object_mode == eMove_flash) {
if (fmod(pTime, pGroove->object_data.shear_info.y_period) * 2.0 <= pGroove->object_data.shear_info.y_period) {
y_size = pGroove->object_data.shear_info.y_magnitude;
} else {
y_size = -pGroove->object_data.shear_info.y_magnitude;
}
} else if (pGroove->object_mode == eMove_harmonic) {
if (pGroove->object_data.shear_info.y_period != 0.0) {
y_size = sin(
BrAngleToRadian(
BrDegreeToAngle(
fmod(pTime, pGroove->object_data.shear_info.y_period) / pGroove->object_data.shear_info.y_period * 360.0)))
* pGroove->object_data.shear_info.y_magnitude;
}
} else {
if (pGroove->object_data.shear_info.y_period != 0.0) {
y_size = fmod(pTime, pGroove->object_data.shear_info.y_period) / pGroove->object_data.shear_info.y_period;
y_size = MapSawToTriangle(y_size) * pGroove->object_data.shear_info.y_magnitude;
}
}
BrMatrix34PostShearX(pMat, y_size / (bounds->max.v[1] - bounds->min.v[1]), z_size / bounds->max.v[2] - bounds->min.v[2]);
} else if (pGroove->object_data.shear_info.y_magnitude == 0.0) {
if (pGroove->object_mode == eMove_continuous) {
if (pGroove->object_data.shear_info.z_period != 0.0) {
z_size = fmod(pTime, pGroove->object_data.shear_info.z_period) / pGroove->object_data.shear_info.z_period * pGroove->object_data.shear_info.z_magnitude;
}
} else if (pGroove->object_mode == eMove_controlled) {
z_size = pGroove->object_data.shear_info.z_magnitude * pGroove->object_data.shear_info.z_period;
} else if (pGroove->object_mode == eMove_absolute) {
z_size = pGroove->object_data.shear_info.z_period;
} else if (pGroove->object_mode == eMove_flash) {
if (fmod(pTime, pGroove->object_data.shear_info.z_period) * 2.0 <= pGroove->object_data.shear_info.z_period) {
z_size = pGroove->object_data.shear_info.z_magnitude;
} else {
z_size = -pGroove->object_data.shear_info.z_magnitude;
}
} else if (pGroove->object_mode == eMove_harmonic) {
if (pGroove->object_data.shear_info.z_period != 0.0) {
z_size = sin(
BrAngleToRadian(
BrDegreeToAngle(
fmod(pTime, pGroove->object_data.shear_info.z_period) / pGroove->object_data.shear_info.z_period * 360.0)))
* pGroove->object_data.shear_info.z_magnitude;
}
} else {
if (pGroove->object_data.shear_info.z_period != 0.0) {
z_size = fmod(pTime, pGroove->object_data.shear_info.z_period) / pGroove->object_data.shear_info.z_period;
z_size = MapSawToTriangle(z_size) * pGroove->object_data.shear_info.z_magnitude;
}
}
if (pGroove->object_mode == eMove_continuous) {
if (pGroove->object_data.shear_info.x_period != 0.0) {
x_size = fmod(pTime, pGroove->object_data.shear_info.x_period) / pGroove->object_data.shear_info.x_period * pGroove->object_data.shear_info.x_magnitude;
}
} else if (pGroove->object_mode == eMove_controlled) {
x_size = pGroove->object_data.shear_info.x_magnitude * pGroove->object_data.shear_info.x_period;
} else if (pGroove->object_mode == eMove_absolute) {
x_size = pGroove->object_data.shear_info.x_period;
} else if (pGroove->object_mode == eMove_flash) {
if (fmod(pTime, pGroove->object_data.shear_info.x_period) * 2.0 <= pGroove->object_data.shear_info.x_period) {
x_size = pGroove->object_data.shear_info.x_magnitude;
} else {
x_size = -pGroove->object_data.shear_info.x_magnitude;
}
} else if (pGroove->object_mode == eMove_harmonic) {
if (pGroove->object_data.shear_info.x_period != 0.0) {
x_size = sin(
BrAngleToRadian(
BrDegreeToAngle(
fmod(pTime, pGroove->object_data.shear_info.x_period) / pGroove->object_data.shear_info.x_period * 360.0)))
* pGroove->object_data.shear_info.x_magnitude;
}
} else { // linear
if (pGroove->object_data.shear_info.x_period != 0.0) {
x_size = fmod(pTime, pGroove->object_data.shear_info.x_period) / pGroove->object_data.shear_info.x_period;
x_size = MapSawToTriangle(x_size) * pGroove->object_data.shear_info.x_magnitude;
}
}
BrMatrix34PostShearY(pMat, x_size / (bounds->max.v[0] - bounds->min.v[0]), z_size / (bounds->max.v[2] - bounds->min.v[2]));
} else { // x_magnitude == 0
if (pGroove->object_mode == eMove_continuous) {
if (pGroove->object_data.shear_info.y_period != 0.0) {
y_size = fmod(pTime, pGroove->object_data.shear_info.y_period) / pGroove->object_data.shear_info.y_period * pGroove->object_data.shear_info.y_magnitude;
}
} else if (pGroove->object_mode == eMove_controlled) {
y_size = pGroove->object_data.shear_info.y_magnitude * pGroove->object_data.shear_info.y_period;
} else if (pGroove->object_mode == eMove_absolute) {
y_size = pGroove->object_data.shear_info.y_period;
} else if (pGroove->object_mode == eMove_flash) {
if (fmod(pTime, pGroove->object_data.shear_info.y_period) * 2.0 <= pGroove->object_data.shear_info.y_period) {
y_size = pGroove->object_data.shear_info.y_magnitude;
} else {
y_size = -pGroove->object_data.shear_info.y_magnitude;
}
} else if (pGroove->object_mode == eMove_harmonic) {
if (pGroove->object_data.shear_info.y_period != 0.0) {
y_size = sin(
BrAngleToRadian(
BrDegreeToAngle(
fmod(pTime, pGroove->object_data.shear_info.y_period) / pGroove->object_data.shear_info.y_period * 360.0)))
* pGroove->object_data.shear_info.y_magnitude;
}
} else {
if (pGroove->object_data.shear_info.y_period != 0.0) {
y_size = fmod(pTime, pGroove->object_data.shear_info.y_period) / pGroove->object_data.shear_info.y_period;
y_size = MapSawToTriangle(y_size) * pGroove->object_data.shear_info.y_magnitude;
}
}
if (pGroove->object_mode == eMove_continuous) {
if (pGroove->object_data.shear_info.x_period != 0.0) {
x_size = fmod(pTime, pGroove->object_data.shear_info.x_period) / pGroove->object_data.shear_info.x_period * pGroove->object_data.shear_info.x_magnitude;
}
} else if (pGroove->object_mode == eMove_controlled) {
x_size = pGroove->object_data.shear_info.x_magnitude * pGroove->object_data.shear_info.x_period;
} else if (pGroove->object_mode == eMove_absolute) {
x_size = pGroove->object_data.shear_info.x_period;
} else if (pGroove->object_mode == eMove_flash) {
if (fmod(pTime, pGroove->object_data.shear_info.x_period) * 2.0 <= pGroove->object_data.shear_info.x_period) {
x_size = pGroove->object_data.shear_info.x_magnitude;
} else {
x_size = -pGroove->object_data.shear_info.x_magnitude;
}
} else if (pGroove->object_mode == eMove_harmonic) {
if (pGroove->object_data.shear_info.x_period != 0.0) {
x_size = sin(
BrAngleToRadian(
BrDegreeToAngle(
fmod(pTime, pGroove->object_data.shear_info.x_period) / pGroove->object_data.shear_info.x_period * 360.0)))
* pGroove->object_data.shear_info.x_magnitude;
}
} else {
if (pGroove->object_data.shear_info.x_period != 0.0) {
x_size = fmod(pTime, pGroove->object_data.shear_info.x_period) / pGroove->object_data.shear_info.x_period;
x_size = MapSawToTriangle(x_size) * pGroove->object_data.shear_info.x_magnitude;
}
}
BrMatrix34PostShearZ(pMat, x_size / (bounds->max.v[0] - bounds->min.v[0]), y_size / (bounds->max.v[1] - bounds->min.v[1]));
}
break;
default:
return;
}
}
// IDA: void __usercall GrooveThisDelic(tGroovidelic_spec *pGroove@<EAX>, tU32 pTime@<EDX>, int pInterrupt_it@<EBX>)
@ -2608,8 +3319,70 @@ void GrooveThisDelic(tGroovidelic_spec* pGroove, tU32 pTime, int pInterrupt_it)
br_matrix34* the_mat;
tInterrupt_status old_path_interrupt;
tInterrupt_status old_object_interrupt;
LOG_TRACE("(%p, %d, %d)", pGroove, pTime, pInterrupt_it);
NOT_IMPLEMENTED();
LOG_TRACE8("(%p, %d, %d)", pGroove, pTime, pInterrupt_it);
old_path_interrupt = pGroove->path_interrupt_status;
old_object_interrupt = pGroove->object_interrupt_status;
the_actor = pGroove->actor;
pGroove->done_this_frame = 1;
CalcActorGlobalPos(&actor_pos, the_actor);
if (pGroove->mode == eGroove_mode_distance) {
if (PointOutOfSight(&actor_pos, gYon_squared)) {
return;
}
} else {
if (PointOutOfSight(&actor_pos, 36.0)) {
return;
}
}
the_mat = &the_actor->t.t.mat;
if (!gAction_replay_mode
|| !ReplayIsPaused()
|| pGroove->path_mode == eMove_controlled
|| pGroove->path_mode == eMove_absolute) {
PathGrooveBastard(pGroove, pTime, the_mat, pInterrupt_it);
}
if ((pGroove->object_type != -1 || pGroove->lollipop_mode != -1)
&& (!gAction_replay_mode
|| !ReplayIsPaused()
|| pGroove->object_mode == eMove_controlled
|| pGroove->object_mode == eMove_absolute)) {
the_mat->m[0][0] = 1.0;
the_actor->t.t.mat.m[0][1] = 0.0;
the_actor->t.t.mat.m[0][2] = 0.0;
the_actor->t.t.mat.m[1][0] = 0.0;
the_actor->t.t.mat.m[1][1] = 1.0;
the_actor->t.t.mat.m[1][2] = 0.0;
the_actor->t.t.mat.m[2][0] = 0.0;
the_actor->t.t.mat.m[2][1] = 0.0;
the_actor->t.t.mat.m[2][2] = 1.0;
the_actor->t.t.mat.m[3][0] = -pGroove->object_centre.v[0];
the_actor->t.t.mat.m[3][1] = -pGroove->object_centre.v[1];
the_actor->t.t.mat.m[3][2] = -pGroove->object_centre.v[2];
ObjectGrooveBastard(pGroove, pTime, the_mat, pInterrupt_it);
the_actor->t.t.mat.m[3][0] = the_actor->t.t.mat.m[3][0]
+ pGroove->object_position.v[0]
+ pGroove->object_centre.v[0];
the_actor->t.t.mat.m[3][1] = pGroove->object_position.v[1]
+ the_actor->t.t.mat.m[3][1]
+ pGroove->object_centre.v[1];
the_actor->t.t.mat.m[3][2] = pGroove->object_position.v[2]
+ pGroove->object_centre.v[2]
+ the_actor->t.t.mat.m[3][2];
if (pGroove->lollipop_mode != -1) {
LollipopizeActor(pGroove->actor, &gCamera_to_world, pGroove->lollipop_mode);
}
}
if (pGroove->path_interrupt_status != old_path_interrupt || pGroove->object_interrupt_status != old_object_interrupt) {
PipeSingleGrooveStop(
pGroove - gGroovidelics_array,
the_mat,
pGroove->path_interrupt_status,
pGroove->object_interrupt_status,
pGroove->path_resumption_value,
pGroove->object_resumption_value);
}
}
// IDA: void __cdecl GrooveThoseDelics()
@ -2618,7 +3391,20 @@ void GrooveThoseDelics() {
tGroovidelic_spec* the_groove;
float f_the_time;
LOG_TRACE("()");
SILENT_STUB();
if (gGroovidelics_array) {
f_the_time = (double)GetTotalTime();
gPrevious_groove_times[1] = gPrevious_groove_times[0];
gPrevious_groove_times[0] = f_the_time;
the_groove = gGroovidelics_array;
for (i = 0; i < gGroovidelics_array_size; i++) {
if (the_groove->owner != -999 && !the_groove->done_this_frame) {
GrooveThisDelic(the_groove, f_the_time, 0);
}
the_groove++;
}
}
}
// IDA: void __usercall StopGroovidelic(br_actor *pActor@<EAX>)

View File

@ -292,4 +292,6 @@ typedef enum keymapcodes {
#define TIME_CONV_THING 0.00050000002
#define OPPONENT_COUNT 0
#endif

View File

@ -665,6 +665,8 @@ def generate_h_file(module):
s = resolve_type_str(module, gv['type'], name)
h_file.write('extern ' + s)
h_file.write(';')
h_file.write(' // addr: ' + gv['addr'][5:])
if '__' in name:
h_file.write(' // suffix added to avoid duplicate symbol')
h_file.write('\n')