Skip to content

Commit f575700

Browse files
committed
Implement funkotronics
1 parent 19ace40 commit f575700

File tree

3 files changed

+258
-24
lines changed

3 files changed

+258
-24
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

+253-21
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ br_scalar gSight_distance_squared;
7979
float MapSawToTriangle(float pNumber) {
8080
LOG_TRACE("(%f)", pNumber);
8181

82-
if (pNumber >= 0.5) {
83-
return 3.0 - pNumber * 4.0;
82+
if (pNumber >= 0.5f) {
83+
return 3.0f - pNumber * 4.0f;
8484
} else {
85-
return pNumber * 4.0 - 1.0;
85+
return pNumber * 4.0f - 1.0f;
8686
}
8787
}
8888

@@ -1594,15 +1594,27 @@ void KillGroovadelic(int pOwner) {
15941594
tGroovidelic_spec* the_groove;
15951595
LOG_TRACE("(%d)", pOwner);
15961596

1597+
if (gGroovidelics_array == NULL) {
1598+
return;
1599+
}
15971600
for (i = 0; i < gGroovidelics_array_size; i++) {
15981601
the_groove = &gGroovidelics_array[i];
1599-
if (the_groove->owner == pOwner
1600-
&& the_groove->path_mode != eMove_controlled
1601-
&& the_groove->path_mode != eMove_absolute
1602-
&& the_groove->object_mode != eMove_controlled
1603-
&& the_groove->object_mode != eMove_absolute) {
1604-
the_groove->owner = -999;
1602+
if (the_groove->owner != pOwner) {
1603+
continue;
1604+
}
1605+
if (the_groove->path_mode == eMove_controlled) {
1606+
continue;
16051607
}
1608+
if (the_groove->path_mode == eMove_absolute) {
1609+
continue;
1610+
}
1611+
if (the_groove->object_mode == eMove_controlled) {
1612+
continue;
1613+
}
1614+
if (the_groove->object_mode == eMove_absolute) {
1615+
continue;
1616+
}
1617+
the_groove->owner = -999;
16061618
}
16071619
}
16081620

@@ -1612,16 +1624,30 @@ void KillFunkotronic(int pOwner) {
16121624
tFunkotronic_spec* the_funk;
16131625
LOG_TRACE("(%d)", pOwner);
16141626

1627+
if (gFunkotronics_array == NULL) {
1628+
return;
1629+
}
16151630
for (i = 0; i < gFunkotronics_array_size; i++) {
16161631
the_funk = &gFunkotronics_array[i];
1617-
if (the_funk->owner == pOwner
1618-
&& the_funk->matrix_mode != eMove_controlled
1619-
&& the_funk->matrix_mode != eMove_absolute
1620-
&& the_funk->lighting_animation_type != eMove_controlled
1621-
&& the_funk->lighting_animation_type != eMove_absolute
1622-
&& (the_funk->texture_animation_data.frames_info.mode != eMove_controlled || the_funk->texture_animation_type)) {
1623-
the_funk->owner = -999;
1632+
if (the_funk->owner != pOwner) {
1633+
continue;
1634+
}
1635+
if (the_funk->matrix_mode == eMove_controlled) {
1636+
continue;
1637+
}
1638+
if (the_funk->matrix_mode == eMove_absolute) {
1639+
continue;
1640+
}
1641+
if (the_funk->lighting_animation_type == eMove_controlled) {
1642+
continue;
16241643
}
1644+
if (the_funk->lighting_animation_type == eMove_absolute) {
1645+
continue;
1646+
}
1647+
if (the_funk->texture_animation_data.frames_info.mode == eMove_controlled && the_funk->texture_animation_type == eTexture_animation_frames) {
1648+
continue;
1649+
}
1650+
the_funk->owner = -999;
16251651
}
16261652
}
16271653

@@ -2396,7 +2422,7 @@ void LoadTrack(char* pFile_name, tTrack_spec* pTrack_spec, tRace_info* pRace_inf
23962422
PathCat(the_path, gApplication_path, "RACES");
23972423
PathCat(the_path, the_path, pFile_name);
23982424
f = DRfopen(the_path, "rt");
2399-
if (f == NULL) {
2425+
if (!f) {
24002426
FatalError(50);
24012427
}
24022428
GetALineAndDontArgue(f, s);
@@ -2955,8 +2981,57 @@ void ProcessTrack(br_actor* pWorld, tTrack_spec* pTrack_spec, br_actor* pCamera,
29552981
// IDA: br_scalar __cdecl NormaliseDegreeAngle(br_scalar pAngle)
29562982
br_scalar NormaliseDegreeAngle(br_scalar pAngle) {
29572983
LOG_TRACE("(%f)", pAngle);
2958-
NOT_IMPLEMENTED();
2959-
}
2984+
2985+
while (pAngle < .0f) {
2986+
pAngle += 360.f;
2987+
}
2988+
return pAngle;
2989+
}
2990+
2991+
2992+
#define SAW(T, PERIOD) (fmodf((T), (PERIOD)) / (PERIOD))
2993+
2994+
#define MOVE_FUNK_PARAMETER(DEST, MODE, PERIOD, AMPLITUDE, FLASH_VALUE) \
2995+
do { \
2996+
switch (MODE) { \
2997+
case eMove_continuous: \
2998+
if ((PERIOD) == 0.f) { \
2999+
DEST = 0.f; \
3000+
} else { \
3001+
DEST = (AMPLITUDE) * SAW(f_the_time, (PERIOD)); \
3002+
} \
3003+
break; \
3004+
case eMove_controlled: \
3005+
DEST = (PERIOD) * (AMPLITUDE); \
3006+
break; \
3007+
case eMove_absolute: \
3008+
DEST = (PERIOD); \
3009+
break; \
3010+
case eMove_linear: \
3011+
if ((PERIOD) == 0.f) { \
3012+
DEST = 0.f; \
3013+
} else { \
3014+
DEST = (AMPLITUDE) * MapSawToTriangle(SAW(f_the_time, (PERIOD))); \
3015+
} \
3016+
break; \
3017+
case eMove_flash: \
3018+
if (2 * fmodf(f_the_time, (PERIOD)) > (PERIOD)) { \
3019+
DEST = (FLASH_VALUE); \
3020+
} else { \
3021+
DEST = -(FLASH_VALUE); \
3022+
} \
3023+
break; \
3024+
case eMove_harmonic: \
3025+
if ((PERIOD) == 0.f) { \
3026+
DEST = 0.f; \
3027+
} else { \
3028+
DEST = (AMPLITUDE) * BR_SIN(BR_ANGLE_DEG(SAW(f_the_time, (PERIOD)) * 360)); \
3029+
} \
3030+
break; \
3031+
default: \
3032+
TELL_ME_IF_WE_PASS_THIS_WAY(); \
3033+
} \
3034+
} while (0)
29603035

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

3207+
29823208
// IDA: void __usercall LollipopizeActor(br_actor *pSubject_actor@<EAX>, br_matrix34 *ref_to_world@<EDX>, tLollipop_mode pWhich_axis@<EBX>)
29833209
void LollipopizeActor(br_actor* pSubject_actor, br_matrix34* ref_to_world, tLollipop_mode pWhich_axis) {
29843210
br_vector3 ref_to_subject;
@@ -3901,7 +4127,13 @@ void StopGroovidelic(br_actor* pActor) {
39014127
void SetGrooveInterrupt(int pGroove_index, br_matrix34* pMatrix, int pPath_interrupt, int pObject_interrupt, float pPath_resumption, float pObject_resumption) {
39024128
tGroovidelic_spec* the_groove;
39034129
LOG_TRACE("(%d, %p, %d, %d, %f, %f)", pGroove_index, pMatrix, pPath_interrupt, pObject_interrupt, pPath_resumption, pObject_resumption);
3904-
NOT_IMPLEMENTED();
4130+
4131+
the_groove = &gGroovidelics_array[pGroove_index];
4132+
the_groove->path_interrupt_status = pPath_interrupt;
4133+
the_groove->object_interrupt_status = pObject_interrupt;
4134+
the_groove->path_resumption_value = pPath_resumption;
4135+
the_groove->object_resumption_value = pObject_resumption;
4136+
BrMatrix34Copy(&the_groove->actor->t.t.mat, pMatrix);
39054137
}
39064138

39074139
// IDA: void __cdecl ResetGrooveFlags()

0 commit comments

Comments
 (0)