@@ -1586,15 +1586,27 @@ void KillGroovadelic(int pOwner) {
1586
1586
tGroovidelic_spec * the_groove ;
1587
1587
LOG_TRACE ("(%d)" , pOwner );
1588
1588
1589
+ if (gGroovidelics_array == NULL ) {
1590
+ return ;
1591
+ }
1589
1592
for (i = 0 ; i < gGroovidelics_array_size ; i ++ ) {
1590
1593
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 ;
1597
1599
}
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 ;
1598
1610
}
1599
1611
}
1600
1612
@@ -1604,16 +1616,30 @@ void KillFunkotronic(int pOwner) {
1604
1616
tFunkotronic_spec * the_funk ;
1605
1617
LOG_TRACE ("(%d)" , pOwner );
1606
1618
1619
+ if (gFunkotronics_array == NULL ) {
1620
+ return ;
1621
+ }
1607
1622
for (i = 0 ; i < gFunkotronics_array_size ; i ++ ) {
1608
1623
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 ;
1616
1632
}
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 ;
1617
1643
}
1618
1644
}
1619
1645
@@ -2947,8 +2973,57 @@ void ProcessTrack(br_actor* pWorld, tTrack_spec* pTrack_spec, br_actor* pCamera,
2947
2973
// IDA: br_scalar __cdecl NormaliseDegreeAngle(br_scalar pAngle)
2948
2974
br_scalar NormaliseDegreeAngle (br_scalar pAngle ) {
2949
2975
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)
2952
3027
2953
3028
// IDA: void __cdecl FunkThoseTronics()
2954
3029
void FunkThoseTronics () {
@@ -2966,9 +3041,159 @@ void FunkThoseTronics() {
2966
3041
float f_the_time ;
2967
3042
float rot_amount ;
2968
3043
float f_time_diff ;
3044
+ br_vector2 tmp_v2 ;
2969
3045
br_pixelmap * old_colour_map ;
2970
3046
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 ();
2972
3197
}
2973
3198
2974
3199
// 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) {
3880
4105
void SetGrooveInterrupt (int pGroove_index , br_matrix34 * pMatrix , int pPath_interrupt , int pObject_interrupt , float pPath_resumption , float pObject_resumption ) {
3881
4106
tGroovidelic_spec * the_groove ;
3882
4107
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 );
3884
4115
}
3885
4116
3886
4117
// IDA: void __cdecl ResetGrooveFlags()
0 commit comments