Skip to content

Commit 8a24f85

Browse files
authored
Implement funkotronics (#145)
1 parent 0dc0c55 commit 8a24f85

File tree

3 files changed

+253
-20
lines changed

3 files changed

+253
-20
lines changed

src/BRSRC13/include/brender/br_defs.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@
5454

5555
#define BR_FONTF_PROPORTIONAL 1
5656

57-
#define BR_SIN(a) ((br_scalar)sin(BrAngleToRadian(a)))
58-
#define BR_COS(a) ((br_scalar)cos(BrAngleToRadian(a)))
59-
#define BR_TAN(a) ((br_scalar)tan(BrAngleToRadian(a)))
57+
#define BR_SIN(a) ((br_scalar)sinf(BrAngleToRadian(a)))
58+
#define BR_COS(a) ((br_scalar)cosf(BrAngleToRadian(a)))
59+
#define BR_TAN(a) ((br_scalar)tanf(BrAngleToRadian(a)))
6060
#define BR_ASIN(a) BrRadianToAngle(asin(a))
6161
#define BR_ACOS(a) BrRadianToAngle(acos(a))
6262
#define BR_ATAN2(a, b) BrRadianToAngle(atan2((a), (b)))

src/BRSRC13/include/brender/brender.h

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ br_pixelmap* BrMapRemove(br_pixelmap* pixelmap);
4545
br_pixelmap* BrMapFind(char* pattern);
4646
br_uint_32 BrMapAddMany(br_pixelmap** items, int n);
4747
br_map_find_cbfn* BrMapFindHook(br_map_find_cbfn* hook);
48+
void BrMapUpdate(br_pixelmap* map, br_uint_16 flags);
4849

4950
// BrMaterial
5051
br_material* BrMaterialAllocate(char* name);
@@ -63,6 +64,7 @@ br_material_find_cbfn* BrMaterialFindHook(br_material_find_cbfn* hook);
6364
void BrMatrix23Copy(br_matrix23* A, br_matrix23* B);
6465
void BrMatrix23Identity(br_matrix23* mat);
6566
void BrMatrix23Mul(br_matrix23* A, br_matrix23* B, br_matrix23* C);
67+
void BrMatrix23PostScale(br_matrix23* mat, br_scalar sx, br_scalar sy);
6668

6769
// BrMatrix34
6870
void BrMatrix34Identity(br_matrix34* mat);

src/DETHRACE/common/world.c

+248-17
Original file line numberDiff line numberDiff line change
@@ -1586,15 +1586,27 @@ void KillGroovadelic(int pOwner) {
15861586
tGroovidelic_spec* the_groove;
15871587
LOG_TRACE("(%d)", pOwner);
15881588

1589+
if (gGroovidelics_array == NULL) {
1590+
return;
1591+
}
15891592
for (i = 0; i < gGroovidelics_array_size; i++) {
15901593
the_groove = &gGroovidelics_array[i];
1591-
if (the_groove->owner == pOwner
1592-
&& the_groove->path_mode != eMove_controlled
1593-
&& the_groove->path_mode != eMove_absolute
1594-
&& the_groove->object_mode != eMove_controlled
1595-
&& the_groove->object_mode != eMove_absolute) {
1596-
the_groove->owner = -999;
1594+
if (the_groove->owner != pOwner) {
1595+
continue;
1596+
}
1597+
if (the_groove->path_mode == eMove_controlled) {
1598+
continue;
15971599
}
1600+
if (the_groove->path_mode == eMove_absolute) {
1601+
continue;
1602+
}
1603+
if (the_groove->object_mode == eMove_controlled) {
1604+
continue;
1605+
}
1606+
if (the_groove->object_mode == eMove_absolute) {
1607+
continue;
1608+
}
1609+
the_groove->owner = -999;
15981610
}
15991611
}
16001612

@@ -1604,16 +1616,30 @@ void KillFunkotronic(int pOwner) {
16041616
tFunkotronic_spec* the_funk;
16051617
LOG_TRACE("(%d)", pOwner);
16061618

1619+
if (gFunkotronics_array == NULL) {
1620+
return;
1621+
}
16071622
for (i = 0; i < gFunkotronics_array_size; i++) {
16081623
the_funk = &gFunkotronics_array[i];
1609-
if (the_funk->owner == pOwner
1610-
&& the_funk->matrix_mode != eMove_controlled
1611-
&& the_funk->matrix_mode != eMove_absolute
1612-
&& the_funk->lighting_animation_type != eMove_controlled
1613-
&& the_funk->lighting_animation_type != eMove_absolute
1614-
&& (the_funk->texture_animation_data.frames_info.mode != eMove_controlled || the_funk->texture_animation_type)) {
1615-
the_funk->owner = -999;
1624+
if (the_funk->owner != pOwner) {
1625+
continue;
1626+
}
1627+
if (the_funk->matrix_mode == eMove_controlled) {
1628+
continue;
1629+
}
1630+
if (the_funk->matrix_mode == eMove_absolute) {
1631+
continue;
16161632
}
1633+
if (the_funk->lighting_animation_type == eMove_controlled) {
1634+
continue;
1635+
}
1636+
if (the_funk->lighting_animation_type == eMove_absolute) {
1637+
continue;
1638+
}
1639+
if (the_funk->texture_animation_data.frames_info.mode == eMove_controlled && the_funk->texture_animation_type == eTexture_animation_frames) {
1640+
continue;
1641+
}
1642+
the_funk->owner = -999;
16171643
}
16181644
}
16191645

@@ -2947,8 +2973,57 @@ void ProcessTrack(br_actor* pWorld, tTrack_spec* pTrack_spec, br_actor* pCamera,
29472973
// IDA: br_scalar __cdecl NormaliseDegreeAngle(br_scalar pAngle)
29482974
br_scalar NormaliseDegreeAngle(br_scalar pAngle) {
29492975
LOG_TRACE("(%f)", pAngle);
2950-
NOT_IMPLEMENTED();
2951-
}
2976+
2977+
while (pAngle < .0f) {
2978+
pAngle += 360.f;
2979+
}
2980+
return pAngle;
2981+
}
2982+
2983+
2984+
#define SAW(T, PERIOD) (fmodf((T), (PERIOD)) / (PERIOD))
2985+
2986+
#define MOVE_FUNK_PARAMETER(DEST, MODE, PERIOD, AMPLITUDE, FLASH_VALUE) \
2987+
do { \
2988+
switch (MODE) { \
2989+
case eMove_continuous: \
2990+
if ((PERIOD) == 0.f) { \
2991+
DEST = 0.f; \
2992+
} else { \
2993+
DEST = (AMPLITUDE) * SAW(f_the_time, (PERIOD)); \
2994+
} \
2995+
break; \
2996+
case eMove_controlled: \
2997+
DEST = (PERIOD) * (AMPLITUDE); \
2998+
break; \
2999+
case eMove_absolute: \
3000+
DEST = (PERIOD); \
3001+
break; \
3002+
case eMove_linear: \
3003+
if ((PERIOD) == 0.f) { \
3004+
DEST = 0.f; \
3005+
} else { \
3006+
DEST = (AMPLITUDE) * MapSawToTriangle(SAW(f_the_time, (PERIOD))); \
3007+
} \
3008+
break; \
3009+
case eMove_flash: \
3010+
if (2 * fmodf(f_the_time, (PERIOD)) > (PERIOD)) { \
3011+
DEST = (FLASH_VALUE); \
3012+
} else { \
3013+
DEST = -(FLASH_VALUE); \
3014+
} \
3015+
break; \
3016+
case eMove_harmonic: \
3017+
if ((PERIOD) == 0.f) { \
3018+
DEST = 0.f; \
3019+
} else { \
3020+
DEST = (AMPLITUDE) * BR_SIN(BR_ANGLE_DEG(SAW(f_the_time, (PERIOD)) * 360)); \
3021+
} \
3022+
break; \
3023+
default: \
3024+
TELL_ME_IF_WE_PASS_THIS_WAY(); \
3025+
} \
3026+
} while (0)
29523027

29533028
// IDA: void __cdecl FunkThoseTronics()
29543029
void FunkThoseTronics() {
@@ -2966,9 +3041,159 @@ void FunkThoseTronics() {
29663041
float f_the_time;
29673042
float rot_amount;
29683043
float f_time_diff;
3044+
br_vector2 tmp_v2;
29693045
br_pixelmap* old_colour_map;
29703046
LOG_TRACE("()");
2971-
STUB_ONCE();
3047+
3048+
if (gFunkotronics_array == NULL) {
3049+
return;
3050+
}
3051+
DontLetFlicFuckWithPalettes();
3052+
the_time = GetTotalTime();
3053+
f_the_time = (float)the_time;
3054+
for (i = 0; i < gFunkotronics_array_size; i++) {
3055+
the_funk = &gFunkotronics_array[i];
3056+
if (the_funk->owner == -999) {
3057+
continue;
3058+
}
3059+
j = 0;
3060+
if (the_funk->mode == eFunk_mode_distance && the_funk->proximity_array != NULL) {
3061+
j = -2;
3062+
for (j = 0; j < the_funk->proximity_count; j++) {
3063+
if (Vector3DistanceSquared(&the_funk->proximity_array[j], gOur_pos) <= gSight_distance_squared) {
3064+
j = -1;
3065+
break;
3066+
}
3067+
}
3068+
}
3069+
if (j == -1 || (j != -2 && (the_funk->mode != eFunk_mode_last_lap_only || gLap >= gTotal_laps) && (the_funk->mode != eFunk_mode_all_laps_but_last || gLap < gTotal_laps))) {
3070+
the_material = the_funk->material;
3071+
mat_matrix = &the_material->map_transform;
3072+
if (!gAction_replay_mode || !ReplayIsPaused() || the_funk->matrix_mode == eMove_controlled || the_funk->matrix_mode == eMove_absolute) {
3073+
switch (the_funk->matrix_mod_type) {
3074+
case eMatrix_mod_spin:
3075+
3076+
BrMatrix23Identity(mat_matrix);
3077+
the_material->map_transform.m[2][0] -= .5f;
3078+
the_material->map_transform.m[2][1] -= .5f;
3079+
if (the_funk->matrix_mod_data.spin_info.period > 0.f) {
3080+
f_time_diff = 1.f - fmodf(the_funk->matrix_mod_data.spin_info.period, 1.f);
3081+
} else {
3082+
f_time_diff = fmodf(-the_funk->matrix_mod_data.spin_info.period, 1.f);
3083+
}
3084+
3085+
MOVE_FUNK_PARAMETER(rot_amount, the_funk->matrix_mode, f_time_diff, 65536.f, 7.5f);
3086+
DRMatrix23PostRotate(mat_matrix, (br_angle)rot_amount);
3087+
3088+
the_material->map_transform.m[2][0] += .5f;
3089+
the_material->map_transform.m[2][1] += .5f;
3090+
break;
3091+
case eMatrix_mod_rock:
3092+
BrMatrix23Identity(mat_matrix);
3093+
the_material->map_transform.m[2][0] -= the_funk->matrix_mod_data.rock_info.x_centre;
3094+
the_material->map_transform.m[2][1] -= the_funk->matrix_mod_data.rock_info.y_centre;
3095+
3096+
MOVE_FUNK_PARAMETER(rot_amount, the_funk->matrix_mode, the_funk->matrix_mod_data.rock_info.period, the_funk->matrix_mod_data.rock_info.rock_angle, the_funk->matrix_mod_data.rock_info.rock_angle);
3097+
DRMatrix23PostRotate(mat_matrix, BrDegreeToAngle(NormaliseDegreeAngle(rot_amount)));
3098+
3099+
the_material->map_transform.m[2][0] += the_funk->matrix_mod_data.rock_info.x_centre;
3100+
the_material->map_transform.m[2][1] += the_funk->matrix_mod_data.rock_info.y_centre;
3101+
break;
3102+
case eMatrix_mod_throb:
3103+
BrMatrix23Identity(mat_matrix);
3104+
the_material->map_transform.m[2][0] -= the_funk->matrix_mod_data.throb_info.x_centre;
3105+
the_material->map_transform.m[2][1] -= the_funk->matrix_mod_data.throb_info.y_centre;
3106+
3107+
MOVE_FUNK_PARAMETER(tmp_v2.v[1], the_funk->matrix_mode, the_funk->matrix_mod_data.throb_info.y_period, the_funk->matrix_mod_data.throb_info.y_magnitude, the_funk->matrix_mod_data.throb_info.y_magnitude);
3108+
MOVE_FUNK_PARAMETER(tmp_v2.v[0], the_funk->matrix_mode, the_funk->matrix_mod_data.throb_info.x_period, the_funk->matrix_mod_data.throb_info.x_magnitude, the_funk->matrix_mod_data.throb_info.x_magnitude);
3109+
BrMatrix23PostScale(mat_matrix, tmp_v2.v[0] + 1.f, tmp_v2.v[1] + 1.f);
3110+
3111+
the_material->map_transform.m[2][0] += the_funk->matrix_mod_data.throb_info.x_centre;
3112+
the_material->map_transform.m[2][1] += the_funk->matrix_mod_data.throb_info.y_centre;
3113+
break;
3114+
case eMatrix_mod_slither:
3115+
MOVE_FUNK_PARAMETER(the_material->map_transform.m[2][0], the_funk->matrix_mode, the_funk->matrix_mod_data.slither_info.x_period, the_funk->matrix_mod_data.slither_info.x_magnitude, the_funk->matrix_mod_data.slither_info.x_magnitude);
3116+
MOVE_FUNK_PARAMETER(the_material->map_transform.m[2][1], the_funk->matrix_mode, the_funk->matrix_mod_data.slither_info.y_period, the_funk->matrix_mod_data.slither_info.y_magnitude, the_funk->matrix_mod_data.slither_info.y_magnitude);
3117+
break;
3118+
case eMatrix_mod_roll:
3119+
MOVE_FUNK_PARAMETER(the_material->map_transform.m[2][0], the_funk->matrix_mode, the_funk->matrix_mod_data.roll_info.x_period, 1.f, 1.875f);
3120+
MOVE_FUNK_PARAMETER(the_material->map_transform.m[2][1], the_funk->matrix_mode, the_funk->matrix_mod_data.roll_info.y_period, 1.f, 1.875f);
3121+
break;
3122+
case eMatrix_mod_none:
3123+
break;
3124+
}
3125+
if (the_funk->matrix_mod_type != eMatrix_mod_none) {
3126+
BrMaterialUpdate(the_funk->material, BR_MATU_MAP_TRANSFORM);
3127+
}
3128+
}
3129+
if (the_funk->lighting_animation_type != eMove_none) {
3130+
MOVE_FUNK_PARAMETER(the_material->ka, the_funk->lighting_animation_type, the_funk->lighting_animation_period, the_funk->ambient_delta, the_funk->ambient_delta);
3131+
the_material->ka += the_funk->ambient_base;
3132+
3133+
MOVE_FUNK_PARAMETER(the_material->kd, the_funk->lighting_animation_type, the_funk->lighting_animation_period, the_funk->direct_delta, the_funk->direct_delta);
3134+
the_material->kd += the_funk->direct_base;
3135+
3136+
MOVE_FUNK_PARAMETER(the_material->ks, the_funk->lighting_animation_type, the_funk->lighting_animation_period, the_funk->specular_delta, the_funk->specular_delta);
3137+
the_material->ks += the_funk->specular_base;
3138+
}
3139+
if (the_funk->texture_animation_type == eTexture_animation_frames) {
3140+
if (!gAction_replay_mode || !ReplayIsPaused() || the_funk->mode == eFunk_mode_all_laps_but_last || the_funk->mode == 4) {
3141+
old_colour_map = the_material->colour_map;
3142+
if (the_funk->time_mode == eTime_mode_accurate) {
3143+
MOVE_FUNK_PARAMETER(rot_amount, the_funk->texture_animation_data.frames_info.mode, the_funk->texture_animation_data.frames_info.period, the_funk->texture_animation_data.frames_info.texture_count, the_funk->texture_animation_data.frames_info.texture_count);
3144+
the_material->colour_map = the_funk->texture_animation_data.frames_info.textures[(int)rot_amount];
3145+
} else {
3146+
if (the_funk->texture_animation_data.frames_info.period <= fabsf(f_the_time - the_funk->last_frame)) {
3147+
the_funk->last_frame = f_the_time;
3148+
the_funk->texture_animation_data.frames_info.current_frame++;
3149+
if (the_funk->texture_animation_data.frames_info.current_frame >= the_funk->texture_animation_data.frames_info.texture_count) {
3150+
the_funk->texture_animation_data.frames_info.current_frame = 0;
3151+
}
3152+
the_material->colour_map = the_funk->texture_animation_data.frames_info.textures[(int)rot_amount];
3153+
}
3154+
}
3155+
if (the_material->colour_map != old_colour_map) {
3156+
BrMaterialUpdate(the_funk->material, BR_MATU_COLOURMAP);
3157+
}
3158+
}
3159+
} else if (the_funk->texture_animation_type == eTexture_animation_flic && (!gAction_replay_mode || !ReplayIsPaused())) {
3160+
f_time_diff = f_the_time;
3161+
if (f_time_diff < the_funk->last_frame) {
3162+
f_time_diff = 2 * the_funk->last_frame - f_time_diff;
3163+
}
3164+
if (the_funk->time_mode == eTime_mode_accurate) {
3165+
if (the_funk->last_frame) {
3166+
iteration_count = (f_time_diff - the_funk->last_frame) / the_funk->texture_animation_data.flic_info.flic_descriptor.frame_period;
3167+
} else {
3168+
iteration_count = 1;
3169+
}
3170+
} else {
3171+
if (f_time_diff - the_funk->last_frame > the_funk->texture_animation_data.flic_info.flic_descriptor.frame_period) {
3172+
iteration_count = 1;
3173+
} else {
3174+
iteration_count = 0;
3175+
}
3176+
}
3177+
for (j = 0; j < iteration_count; j++) {
3178+
finished = PlayNextFlicFrame(&the_funk->texture_animation_data.flic_info.flic_descriptor);
3179+
BrMapUpdate(the_funk->material->colour_map, BR_MAPU_ALL);
3180+
BrMaterialUpdate(the_funk->material, BR_MATU_COLOURMAP);
3181+
if (finished) {
3182+
EndFlic(&the_funk->texture_animation_data.flic_info.flic_descriptor);
3183+
StartFlic(
3184+
the_funk->texture_animation_data.flic_info.flic_descriptor.file_name,
3185+
-1,
3186+
&the_funk->texture_animation_data.flic_info.flic_descriptor,
3187+
the_funk->texture_animation_data.flic_info.flic_data_length,
3188+
(tS8*)the_funk->texture_animation_data.flic_info.flic_data,
3189+
the_material->colour_map, 0, 0, 0);
3190+
}
3191+
the_funk->last_frame = f_the_time;
3192+
}
3193+
}
3194+
}
3195+
}
3196+
LetFlicFuckWithPalettes();
29723197
}
29733198

29743199
// IDA: void __usercall LollipopizeActor(br_actor *pSubject_actor@<EAX>, br_matrix34 *ref_to_world@<EDX>, tLollipop_mode pWhich_axis@<EBX>)
@@ -3880,7 +4105,13 @@ void StopGroovidelic(br_actor* pActor) {
38804105
void SetGrooveInterrupt(int pGroove_index, br_matrix34* pMatrix, int pPath_interrupt, int pObject_interrupt, float pPath_resumption, float pObject_resumption) {
38814106
tGroovidelic_spec* the_groove;
38824107
LOG_TRACE("(%d, %p, %d, %d, %f, %f)", pGroove_index, pMatrix, pPath_interrupt, pObject_interrupt, pPath_resumption, pObject_resumption);
3883-
NOT_IMPLEMENTED();
4108+
4109+
the_groove = &gGroovidelics_array[pGroove_index];
4110+
the_groove->path_interrupt_status = pPath_interrupt;
4111+
the_groove->object_interrupt_status = pObject_interrupt;
4112+
the_groove->path_resumption_value = pPath_resumption;
4113+
the_groove->object_resumption_value = pObject_resumption;
4114+
BrMatrix34Copy(&the_groove->actor->t.t.mat, pMatrix);
38844115
}
38854116

38864117
// IDA: void __cdecl ResetGrooveFlags()

0 commit comments

Comments
 (0)