@@ -79,10 +79,10 @@ br_scalar gSight_distance_squared;
79
79
float MapSawToTriangle (float pNumber ) {
80
80
LOG_TRACE ("(%f)" , pNumber );
81
81
82
- if (pNumber >= 0.5 ) {
83
- return 3.0 - pNumber * 4.0 ;
82
+ if (pNumber >= 0.5f ) {
83
+ return 3.0f - pNumber * 4.0f ;
84
84
} else {
85
- return pNumber * 4.0 - 1.0 ;
85
+ return pNumber * 4.0f - 1.0f ;
86
86
}
87
87
}
88
88
@@ -1594,15 +1594,27 @@ void KillGroovadelic(int pOwner) {
1594
1594
tGroovidelic_spec * the_groove ;
1595
1595
LOG_TRACE ("(%d)" , pOwner );
1596
1596
1597
+ if (gGroovidelics_array == NULL ) {
1598
+ return ;
1599
+ }
1597
1600
for (i = 0 ; i < gGroovidelics_array_size ; i ++ ) {
1598
1601
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 ;
1605
1607
}
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 ;
1606
1618
}
1607
1619
}
1608
1620
@@ -1612,16 +1624,30 @@ void KillFunkotronic(int pOwner) {
1612
1624
tFunkotronic_spec * the_funk ;
1613
1625
LOG_TRACE ("(%d)" , pOwner );
1614
1626
1627
+ if (gFunkotronics_array == NULL ) {
1628
+ return ;
1629
+ }
1615
1630
for (i = 0 ; i < gFunkotronics_array_size ; i ++ ) {
1616
1631
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 ;
1624
1643
}
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 ;
1625
1651
}
1626
1652
}
1627
1653
@@ -2396,7 +2422,7 @@ void LoadTrack(char* pFile_name, tTrack_spec* pTrack_spec, tRace_info* pRace_inf
2396
2422
PathCat (the_path , gApplication_path , "RACES" );
2397
2423
PathCat (the_path , the_path , pFile_name );
2398
2424
f = DRfopen (the_path , "rt" );
2399
- if (f == NULL ) {
2425
+ if (! f ) {
2400
2426
FatalError (50 );
2401
2427
}
2402
2428
GetALineAndDontArgue (f , s );
@@ -2955,8 +2981,57 @@ void ProcessTrack(br_actor* pWorld, tTrack_spec* pTrack_spec, br_actor* pCamera,
2955
2981
// IDA: br_scalar __cdecl NormaliseDegreeAngle(br_scalar pAngle)
2956
2982
br_scalar NormaliseDegreeAngle (br_scalar pAngle ) {
2957
2983
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)
2960
3035
2961
3036
// IDA: void __cdecl FunkThoseTronics()
2962
3037
void FunkThoseTronics () {
@@ -2974,11 +3049,162 @@ void FunkThoseTronics() {
2974
3049
float f_the_time ;
2975
3050
float rot_amount ;
2976
3051
float f_time_diff ;
3052
+ br_vector2 tmp_v2 ;
2977
3053
br_pixelmap * old_colour_map ;
2978
3054
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 ();
2980
3205
}
2981
3206
3207
+
2982
3208
// IDA: void __usercall LollipopizeActor(br_actor *pSubject_actor@<EAX>, br_matrix34 *ref_to_world@<EDX>, tLollipop_mode pWhich_axis@<EBX>)
2983
3209
void LollipopizeActor (br_actor * pSubject_actor , br_matrix34 * ref_to_world , tLollipop_mode pWhich_axis ) {
2984
3210
br_vector3 ref_to_subject ;
@@ -3901,7 +4127,13 @@ void StopGroovidelic(br_actor* pActor) {
3901
4127
void SetGrooveInterrupt (int pGroove_index , br_matrix34 * pMatrix , int pPath_interrupt , int pObject_interrupt , float pPath_resumption , float pObject_resumption ) {
3902
4128
tGroovidelic_spec * the_groove ;
3903
4129
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 );
3905
4137
}
3906
4138
3907
4139
// IDA: void __cdecl ResetGrooveFlags()
0 commit comments