Rev 20 | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1 | pmbaty | 1 | // car.c + stuff.c |
| 2 | |||
| 3 | #include "car.h" |
||
| 20 | pmbaty | 4 | #include "brender/brender.h" |
| 1 | pmbaty | 5 | #include "brucetrk.h" |
| 6 | #include "car.h" |
||
| 7 | #include "constants.h" |
||
| 8 | #include "controls.h" |
||
| 9 | #include "crush.h" |
||
| 10 | #include "displays.h" |
||
| 11 | #include "finteray.h" |
||
| 12 | #include "globvars.h" |
||
| 13 | #include "globvrkm.h" |
||
| 14 | #include "globvrme.h" |
||
| 15 | #include "globvrpb.h" |
||
| 16 | #include "graphics.h" |
||
| 17 | #include "harness/config.h" |
||
| 18 | #include "harness/trace.h" |
||
| 19 | #include "netgame.h" |
||
| 20 | #include "network.h" |
||
| 21 | #include "oil.h" |
||
| 22 | #include "opponent.h" |
||
| 23 | #include "pd/sys.h" |
||
| 24 | #include "pedestrn.h" |
||
| 25 | #include "piping.h" |
||
| 26 | #include "pratcam.h" |
||
| 27 | #include "raycast.h" |
||
| 28 | #include "replay.h" |
||
| 29 | #include "skidmark.h" |
||
| 30 | #include "sound.h" |
||
| 31 | #include "spark.h" |
||
| 32 | #include "trig.h" |
||
| 33 | #include "utility.h" |
||
| 34 | #include "world.h" |
||
| 35 | #include <math.h> |
||
| 36 | #include <stdlib.h> |
||
| 37 | |||
| 38 | int gDoing_physics = 0; |
||
| 39 | br_scalar gDt = 0.f; |
||
| 40 | // suffix added to avoid duplicate symbol |
||
| 41 | int gCollision_detection_on__car = 1; |
||
| 42 | // suffix added to avoid duplicate symbol |
||
| 43 | br_vector3 gGround_normal__car = { { 0.0f, 1.0f, 0.0f } }; |
||
| 44 | // suffix added to avoid duplicate symbol |
||
| 45 | void (*ControlCar[6])(tCar_spec*, br_scalar) = { |
||
| 46 | &ControlCar1, |
||
| 47 | &ControlCar2, |
||
| 48 | &ControlCar3, |
||
| 49 | &ControlCar4, |
||
| 50 | &ControlCar5, |
||
| 51 | NULL, |
||
| 52 | }; |
||
| 53 | int gControl__car = 3; // suffix added to avoid duplicate symbol |
||
| 54 | int gFace_num__car = 1; // suffix added to avoid duplicate symbol |
||
| 55 | br_angle gOld_yaw__car = 0; // suffix added to avoid duplicate symbol |
||
| 56 | br_angle gOld_zoom = 0; |
||
| 57 | br_vector3 gCamera_pos_before_collide = { { 0 } }; |
||
| 58 | int gMetal_crunch_sound_id__car[5] = { |
||
| 59 | // suffix added to avoid duplicate symbol |
||
| 60 | 5000, |
||
| 61 | 5001, |
||
| 62 | 5002, |
||
| 63 | 5003, |
||
| 64 | 5004, |
||
| 65 | }; |
||
| 66 | int gMetal_scrape_sound_id__car[3] = { |
||
| 67 | // suffix added to avoid duplicate symbol |
||
| 68 | 5010, |
||
| 69 | 5011, |
||
| 70 | 5012, |
||
| 71 | }; |
||
| 72 | int gCar_car_collisions = 1; |
||
| 73 | int gFreeze_mechanics = 0; |
||
| 74 | tU32 gLast_cunning_stunt = 0; |
||
| 75 | tU32 gWild_start = 0; |
||
| 76 | tU32 gQuite_wild_start = 0; |
||
| 77 | tU32 gQuite_wild_end = 0; |
||
| 78 | tU32 gOn_me_wheels_start = 0; |
||
| 79 | int gWoz_upside_down_at_all = 0; |
||
| 80 | tS3_sound_tag gSkid_tag[2] = { 0, 0 }; |
||
| 81 | tCar_spec* gLast_car_to_skid[2] = { NULL, NULL }; |
||
| 82 | int gEliminate_faces = 0; |
||
| 83 | br_vector3 gZero_v__car = { { 0 } }; // suffix added to avoid duplicate symbol |
||
| 84 | tU32 gSwitch_time = 0; |
||
| 85 | tSave_camera gSave_camera[2]; |
||
| 86 | tU32 gLast_mechanics_time; |
||
| 87 | int gOpponent_viewing_mode; |
||
| 88 | int gNet_player_to_view_index = -1; |
||
| 89 | int gDouble_pling_water = 0; |
||
| 90 | int gStop_opponents_moving = 0; |
||
| 91 | float gDefensive_powerup_factor[6] = { 1.0f, 0.825f, 0.65f, 0.475f, 0.3f, 0.01f }; |
||
| 92 | float gOffensive_powerup_factor[6] = { 1.0f, 1.5f, 2.0f, 3.0f, 5.0f, 10.0f }; |
||
| 93 | float gEngine_powerup_factor[6] = { 1.3f, 1.9f, 2.5f, 3.2f, 4.0f, 10.0f }; |
||
| 94 | br_angle gPanning_camera_angle; |
||
| 95 | br_scalar gPanning_camera_height; |
||
| 96 | int gFace_count; |
||
| 97 | float gCar_simplification_factor[2][5] = { |
||
| 98 | { 10.0f, 3.0f, 1.5f, 0.75f, 0.0f }, |
||
| 99 | { 10.0f, 5.0f, 2.5f, 1.5f, 0.0f } |
||
| 100 | }; |
||
| 101 | int gCar_simplification_level = 0; |
||
| 102 | int gNum_active_non_cars = 0; |
||
| 103 | int gCamera_has_collided = 0; |
||
| 104 | tFace_ref gFace_list__car[150]; // suffix added to avoid duplicate symbol |
||
| 105 | tNon_car_spec* gActive_non_car_list[50]; |
||
| 106 | int gOver_shoot; |
||
| 107 | br_scalar gMin_world_y; |
||
| 108 | br_scalar gAccel; |
||
| 109 | br_vector3 gAverage_grid_position; |
||
| 110 | br_actor* gPed_actor; |
||
| 111 | int gCollision_count; |
||
| 112 | int gCamera_frozen; |
||
| 113 | int gMaterial_index; |
||
| 114 | int gInTheSea; |
||
| 115 | int gCamera_mode; |
||
| 116 | br_scalar gOur_yaw__car; // suffix added to avoid duplicate symbol |
||
| 117 | br_scalar gGravity__car; // suffix added to avoid duplicate symbol |
||
| 118 | br_vector3 gNew_ground_normal__car; // suffix added to avoid duplicate symbol |
||
| 119 | char gNon_car_spec_list[100]; |
||
| 120 | tU32 gMechanics_time_sync; |
||
| 121 | int gNum_cars_and_non_cars; |
||
| 122 | |||
| 123 | // IDA: void __usercall DamageUnit(tCar_spec *pCar@<EAX>, int pUnit_type@<EDX>, int pDamage_amount@<EBX>) |
||
| 124 | void DamageUnit(tCar_spec* pCar, int pUnit_type, int pDamage_amount) { |
||
| 125 | tDamage_unit* the_damage; |
||
| 126 | LOG_TRACE("(%p, %d, %d)", pCar, pUnit_type, pDamage_amount); |
||
| 127 | |||
| 128 | if (pDamage_amount > 0) { |
||
| 129 | the_damage = &pCar->damage_units[pUnit_type]; |
||
| 130 | the_damage->damage_level += pDamage_amount; |
||
| 131 | if (the_damage->damage_level >= 100) { |
||
| 132 | the_damage->damage_level = 99; |
||
| 133 | } |
||
| 134 | } |
||
| 135 | } |
||
| 136 | |||
| 137 | // IDA: void __usercall DamageUnitWithSmoke(tCar_spec *pCar@<EAX>, int pUnit_type@<EDX>, int pDamage_amount@<EBX>) |
||
| 138 | void DamageUnitWithSmoke(tCar_spec* pCar, int pUnit_type, int pDamage_amount) { |
||
| 139 | LOG_TRACE("(%p, %d, %d)", pCar, pUnit_type, pDamage_amount); |
||
| 140 | |||
| 141 | DamageUnit(pCar, pUnit_type, pDamage_amount); |
||
| 142 | SortOutSmoke(pCar); |
||
| 143 | } |
||
| 144 | |||
| 145 | // IDA: void __usercall DamageEngine(int pDamage_amount@<EAX>) |
||
| 146 | void DamageEngine(int pDamage_amount) { |
||
| 147 | LOG_TRACE("(%d)", pDamage_amount); |
||
| 148 | |||
| 149 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_engine, pDamage_amount); |
||
| 150 | } |
||
| 151 | |||
| 152 | // IDA: void __usercall DamageTrans(int pDamage_amount@<EAX>) |
||
| 153 | void DamageTrans(int pDamage_amount) { |
||
| 154 | LOG_TRACE("(%d)", pDamage_amount); |
||
| 155 | |||
| 156 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_transmission, pDamage_amount); |
||
| 157 | } |
||
| 158 | |||
| 159 | // IDA: void __usercall DamageSteering(int pDamage_amount@<EAX>) |
||
| 160 | void DamageSteering(int pDamage_amount) { |
||
| 161 | LOG_TRACE("(%d)", pDamage_amount); |
||
| 162 | |||
| 163 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_steering, pDamage_amount); |
||
| 164 | } |
||
| 165 | |||
| 166 | // IDA: void __usercall DamageLFWheel(int pDamage_amount@<EAX>) |
||
| 167 | void DamageLFWheel(int pDamage_amount) { |
||
| 168 | LOG_TRACE("(%d)", pDamage_amount); |
||
| 169 | |||
| 170 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_lf_wheel, pDamage_amount); |
||
| 171 | } |
||
| 172 | |||
| 173 | // IDA: void __usercall DamageLFBrake(int pDamage_amount@<EAX>) |
||
| 174 | void DamageLFBrake(int pDamage_amount) { |
||
| 175 | LOG_TRACE("(%d)", pDamage_amount); |
||
| 176 | |||
| 177 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_lf_brake, pDamage_amount); |
||
| 178 | } |
||
| 179 | |||
| 180 | // IDA: void __usercall DamageLRBrake(int pDamage_amount@<EAX>) |
||
| 181 | void DamageLRBrake(int pDamage_amount) { |
||
| 182 | LOG_TRACE("(%d)", pDamage_amount); |
||
| 183 | |||
| 184 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_lr_brake, pDamage_amount); |
||
| 185 | } |
||
| 186 | |||
| 187 | // IDA: void __usercall DamageLRWheel(int pDamage_amount@<EAX>) |
||
| 188 | void DamageLRWheel(int pDamage_amount) { |
||
| 189 | LOG_TRACE("(%d)", pDamage_amount); |
||
| 190 | |||
| 191 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_lr_wheel, pDamage_amount); |
||
| 192 | } |
||
| 193 | |||
| 194 | // IDA: void __usercall DamageRFWheel(int pDamage_amount@<EAX>) |
||
| 195 | void DamageRFWheel(int pDamage_amount) { |
||
| 196 | LOG_TRACE("(%d)", pDamage_amount); |
||
| 197 | |||
| 198 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_rf_wheel, pDamage_amount); |
||
| 199 | } |
||
| 200 | |||
| 201 | // IDA: void __usercall DamageRFBrake(int pDamage_amount@<EAX>) |
||
| 202 | void DamageRFBrake(int pDamage_amount) { |
||
| 203 | LOG_TRACE("(%d)", pDamage_amount); |
||
| 204 | |||
| 205 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_rf_brake, pDamage_amount); |
||
| 206 | } |
||
| 207 | |||
| 208 | // IDA: void __usercall DamageRRBrake(int pDamage_amount@<EAX>) |
||
| 209 | void DamageRRBrake(int pDamage_amount) { |
||
| 210 | LOG_TRACE("(%d)", pDamage_amount); |
||
| 211 | |||
| 212 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_rr_brake, pDamage_amount); |
||
| 213 | } |
||
| 214 | |||
| 215 | // IDA: void __usercall DamageRRWheel(int pDamage_amount@<EAX>) |
||
| 216 | void DamageRRWheel(int pDamage_amount) { |
||
| 217 | LOG_TRACE("(%d)", pDamage_amount); |
||
| 218 | |||
| 219 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_rr_wheel, pDamage_amount); |
||
| 220 | } |
||
| 221 | |||
| 222 | // IDA: void __usercall CalculatePlaneNormal(br_vector3 *pP1@<EAX>, br_vector3 *pP2@<EDX>, br_vector3 *pP3@<EBX>, br_vector3 *pNormal@<ECX>) |
||
| 223 | void CalculatePlaneNormal(br_vector3* pP1, br_vector3* pP2, br_vector3* pP3, br_vector3* pNormal) { |
||
| 224 | //br_vector3 p0; // Pierre-Marie Baty -- unused variable |
||
| 225 | //br_vector3 p1; // Pierre-Marie Baty -- unused variable |
||
| 226 | //br_vector3 cross_product; // Pierre-Marie Baty -- unused variable |
||
| 227 | //br_vector3 temp_vector; // Pierre-Marie Baty -- unused variable |
||
| 228 | LOG_TRACE("(%p, %p, %p, %p)", pP1, pP2, pP3, pNormal); |
||
| 229 | NOT_IMPLEMENTED(); |
||
| 230 | } |
||
| 231 | |||
| 232 | // IDA: void __usercall CalculateGroundNormal(br_model *pThe_model@<EAX>, int pFace_index@<EDX>) |
||
| 233 | void CalculateGroundNormal(br_model* pThe_model, int pFace_index) { |
||
| 234 | LOG_TRACE("(%p, %d)", pThe_model, pFace_index); |
||
| 235 | NOT_IMPLEMENTED(); |
||
| 236 | } |
||
| 237 | |||
| 238 | // IDA: void __cdecl ChangeYCoordinate(br_scalar pNew_y, tU32 pTime_taken, br_model *pThe_model, int pFace_index) |
||
| 239 | void ChangeYCoordinate(br_scalar pNew_y, tU32 pTime_taken, br_model* pThe_model, int pFace_index) { |
||
| 240 | //br_scalar y_change; // Pierre-Marie Baty -- unused variable |
||
| 241 | //br_transform new_transform; // Pierre-Marie Baty -- unused variable |
||
| 242 | //br_vector3 side_window; // Pierre-Marie Baty -- unused variable |
||
| 243 | LOG_TRACE("(%f, %d, %p, %d)", pNew_y, pTime_taken, pThe_model, pFace_index); |
||
| 244 | NOT_IMPLEMENTED(); |
||
| 245 | } |
||
| 246 | |||
| 247 | // IDA: void __usercall SwitchCarActor(tCar_spec *pCar_spec@<EAX>, int pModel_index@<EDX>) |
||
| 248 | void SwitchCarActor(tCar_spec* pCar_spec, int pModel_index) { |
||
| 249 | int i; |
||
| 250 | LOG_TRACE("(%p, %d)", pCar_spec, pModel_index); |
||
| 251 | |||
| 252 | for (i = 0; i < pCar_spec->car_actor_count; i++) { |
||
| 253 | if (i == pModel_index) { |
||
| 254 | pCar_spec->car_model_actors[i].actor->render_style = BR_RSTYLE_FACES; |
||
| 255 | } else { |
||
| 256 | pCar_spec->car_model_actors[i].actor->render_style = BR_RSTYLE_NONE; |
||
| 257 | } |
||
| 258 | } |
||
| 259 | pCar_spec->current_car_actor = pModel_index; |
||
| 260 | } |
||
| 261 | |||
| 262 | // IDA: void __usercall InitialiseCar2(tCar_spec *pCar@<EAX>, int pClear_disabled_flag@<EDX>) |
||
| 263 | void InitialiseCar2(tCar_spec* pCar, int pClear_disabled_flag) { |
||
| 264 | int index; |
||
| 265 | int j; |
||
| 266 | //int cat; // Pierre-Marie Baty -- unused variable |
||
| 267 | //int car_count; // Pierre-Marie Baty -- unused variable |
||
| 268 | br_actor* car_actor; |
||
| 269 | //br_angle initial_yaw; // Pierre-Marie Baty -- unused variable |
||
| 270 | //br_scalar nearest_y_above; // Pierre-Marie Baty -- unused variable |
||
| 271 | //br_scalar nearest_y_below; // Pierre-Marie Baty -- unused variable |
||
| 272 | //br_scalar speed; // Pierre-Marie Baty -- unused variable |
||
| 273 | //int below_face_index; // Pierre-Marie Baty -- unused variable |
||
| 274 | //int above_face_index; // Pierre-Marie Baty -- unused variable |
||
| 275 | //br_model* below_model; // Pierre-Marie Baty -- unused variable |
||
| 276 | //br_model* above_model; // Pierre-Marie Baty -- unused variable |
||
| 277 | //br_vector3 grid_offset; // Pierre-Marie Baty -- unused variable |
||
| 278 | //br_matrix34 initial_yaw_matrix; // Pierre-Marie Baty -- unused variable |
||
| 279 | br_matrix34 safe_position; |
||
| 280 | LOG_TRACE("(%p, %d)", pCar, pClear_disabled_flag); |
||
| 281 | |||
| 282 | PossibleService(); |
||
| 283 | if (pCar->disabled && pClear_disabled_flag) { |
||
| 284 | EnableCar(pCar); |
||
| 285 | } |
||
| 286 | car_actor = pCar->car_master_actor; |
||
| 287 | InitCarSkidStuff(pCar); |
||
| 288 | if (pCar->current_car_actor >= 0) { |
||
| 289 | pCar->car_model_actors[pCar->current_car_actor].actor->render_style = BR_RSTYLE_NONE; |
||
| 290 | } |
||
| 291 | SwitchCarActor(pCar, pCar->current_car_actor); |
||
| 292 | if (strcmp(pCar->name, "STELLA.TXT") == 0) { |
||
| 293 | pCar->proxy_ray_distance = 6.0f; |
||
| 294 | } else { |
||
| 295 | pCar->proxy_ray_distance = 0.0f; |
||
| 296 | } |
||
| 297 | pCar->last_special_volume = NULL; |
||
| 298 | pCar->auto_special_volume = NULL; |
||
| 299 | pCar->num_smoke_columns = 0; |
||
| 300 | pCar->who_last_hit_me = NULL; |
||
| 301 | pCar->screen_material_source = NULL; |
||
| 302 | if (pCar->screen_material != NULL) { |
||
| 303 | pCar->screen_material->colour_map = NULL; |
||
| 304 | pCar->screen_material->index_shade = gRender_shade_table; |
||
| 305 | BrMaterialUpdate(pCar->screen_material, BR_MATU_ALL); |
||
| 306 | } |
||
| 307 | if (pCar->driver == eDriver_local_human) { |
||
| 308 | ResetRecoveryVouchers(); |
||
| 309 | } |
||
| 310 | BrVector3SetFloat(&pCar->v, 0.0f, 0.0f, 0.0f); |
||
| 311 | BrVector3SetFloat(&pCar->omega, 0.0f, 0.0f, 0.0f); |
||
| 312 | pCar->curvature = 0.0f; |
||
| 313 | BrMatrix34Copy(&safe_position, &car_actor->t.t.mat); |
||
| 314 | if (safe_position.m[3][0] > 500.0f) { |
||
| 315 | safe_position.m[3][0] -= 1000.0f; |
||
| 316 | safe_position.m[3][1] -= 1000.0f; |
||
| 317 | safe_position.m[3][2] -= 1000.0f; |
||
| 318 | } |
||
| 319 | BrMatrix34Copy(&pCar->old_frame_mat, &safe_position); |
||
| 320 | BrMatrix34Copy(&pCar->oldmat, &safe_position); |
||
| 321 | BrVector3Scale((br_vector3*)pCar->oldmat.m[3], (br_vector3*)pCar->oldmat.m[3], WORLD_SCALE); |
||
| 322 | BrMatrix34ApplyP(&pCar->pos, &pCar->cmpos, &pCar->oldmat); |
||
| 323 | BrVector3InvScale(&pCar->pos, &pCar->pos, WORLD_SCALE); |
||
| 324 | for (j = 0; j < COUNT_OF(pCar->oldd); j++) { |
||
| 325 | pCar->oldd[j] = pCar->ride_height; |
||
| 326 | } |
||
| 327 | pCar->gear = 0; |
||
| 328 | pCar->revs = 0.f; |
||
| 329 | pCar->traction_control = 1; |
||
| 330 | BrVector3Negate(&pCar->direction, (br_vector3*)car_actor->t.t.mat.m[2]); |
||
| 331 | for (j = 0; j < COUNT_OF(pCar->last_safe_positions); j++) { |
||
| 332 | BrMatrix34Copy(&pCar->last_safe_positions[j], &safe_position); |
||
| 333 | } |
||
| 334 | pCar->message.type = 0; |
||
| 335 | pCar->message.time = 0; |
||
| 336 | pCar->dt = -1.f; |
||
| 337 | pCar->last_car_car_collision = 1; |
||
| 338 | pCar->time_to_recover = 0; |
||
| 339 | pCar->repair_time = 0; |
||
| 340 | |||
| 341 | switch (pCar->driver) { |
||
| 342 | |||
| 343 | case eDriver_oppo: |
||
| 344 | index = 0; |
||
| 345 | for (j = 0; j < gCurrent_race.number_of_racers; j++) { |
||
| 346 | if (gCurrent_race.opponent_list[j].car_spec->driver == eDriver_oppo) { |
||
| 347 | if (gCurrent_race.opponent_list[j].car_spec == pCar) { |
||
| 348 | pCar->car_ID = index + 512; |
||
| 349 | } |
||
| 350 | index++; |
||
| 351 | } |
||
| 352 | } |
||
| 353 | break; |
||
| 354 | |||
| 355 | case eDriver_net_human: |
||
| 356 | index = 0; |
||
| 357 | for (j = 0; j < gCurrent_race.number_of_racers; j++) { |
||
| 358 | if (gCurrent_race.opponent_list[j].car_spec |
||
| 359 | && gCurrent_race.opponent_list[j].car_spec->driver == eDriver_net_human) { |
||
| 360 | if (gCurrent_race.opponent_list[j].car_spec == pCar) { |
||
| 361 | pCar->car_ID = index + 256; |
||
| 362 | } |
||
| 363 | index++; |
||
| 364 | } |
||
| 365 | } |
||
| 366 | break; |
||
| 367 | |||
| 368 | case eDriver_local_human: |
||
| 369 | pCar->car_ID = 0; |
||
| 370 | break; |
||
| 371 | |||
| 372 | default: |
||
| 373 | LOG_WARN("Case %d not handled", pCar->driver); |
||
| 374 | break; |
||
| 375 | } |
||
| 376 | PossibleService(); |
||
| 377 | pCar->box_face_ref = gFace_num__car - 2; |
||
| 378 | pCar->doing_nothing_flag = 0; |
||
| 379 | pCar->end_steering_damage_effect = 0; |
||
| 380 | pCar->end_trans_damage_effect = 0; |
||
| 381 | pCar->wheel_dam_offset[0] = 0.f; |
||
| 382 | pCar->wheel_dam_offset[1] = 0.f; |
||
| 383 | pCar->wheel_dam_offset[2] = 0.f; |
||
| 384 | pCar->wheel_dam_offset[3] = 0.f; |
||
| 385 | pCar->shadow_intersection_flags = 0; |
||
| 386 | pCar->underwater_ability = 0; |
||
| 387 | pCar->invulnerable = 0; |
||
| 388 | pCar->wall_climber_mode = 0; |
||
| 389 | pCar->grip_multiplier = 1.f; |
||
| 390 | pCar->damage_multiplier = 1.f; |
||
| 391 | pCar->collision_mass_multiplier = 1.f; |
||
| 392 | pCar->engine_power_multiplier = 1.f; |
||
| 393 | pCar->bounce_rate = 0.f; |
||
| 394 | pCar->bounce_amount = 0.f; |
||
| 395 | pCar->knackered = 0; |
||
| 396 | TotallyRepairACar(pCar); |
||
| 397 | SetCarSuspGiveAndHeight(pCar, 1.f, 1.f, 1.f, 0.f, 0.f); |
||
| 398 | for (j = 0; j < COUNT_OF(pCar->powerups); ++j) { |
||
| 399 | pCar->powerups[j] = 0; |
||
| 400 | } |
||
| 401 | if (gNet_mode != eNet_mode_none) { |
||
| 402 | for (j = 0; j < COUNT_OF(pCar->power_up_levels); j++) { |
||
| 403 | pCar->power_up_levels[j] = 0; |
||
| 404 | } |
||
| 405 | } |
||
| 406 | } |
||
| 407 | |||
| 408 | // IDA: void __usercall InitialiseCar(tCar_spec *pCar@<EAX>) |
||
| 409 | void InitialiseCar(tCar_spec* pCar) { |
||
| 410 | LOG_TRACE("(%p)", pCar); |
||
| 411 | |||
| 412 | InitialiseCar2(pCar, 1); |
||
| 413 | } |
||
| 414 | |||
| 415 | // IDA: void __usercall InitialiseCarsEtc(tRace_info *pThe_race@<EAX>) |
||
| 416 | void InitialiseCarsEtc(tRace_info* pThe_race) { |
||
| 417 | int i; |
||
| 418 | int cat; |
||
| 419 | int car_count; |
||
| 420 | tCar_spec* car; |
||
| 421 | br_bounds bnds; |
||
| 422 | LOG_TRACE("(%p)", pThe_race); |
||
| 423 | |||
| 424 | gProgram_state.initial_position = pThe_race->initial_position; |
||
| 425 | gProgram_state.initial_yaw = pThe_race->initial_yaw; |
||
| 426 | BrActorToBounds(&bnds, gProgram_state.track_spec.the_actor); |
||
| 427 | gMin_world_y = bnds.min.v[1]; |
||
| 428 | gNum_active_non_cars = 0; |
||
| 429 | for (cat = eVehicle_self; cat <= eVehicle_not_really; cat++) { |
||
| 430 | if (cat == eVehicle_self) { |
||
| 431 | car_count = 1; |
||
| 432 | } else { |
||
| 433 | car_count = GetCarCount(cat); |
||
| 434 | } |
||
| 435 | for (i = 0; i < car_count; i++) { |
||
| 436 | PossibleService(); |
||
| 437 | if (cat == eVehicle_self) { |
||
| 438 | car = &gProgram_state.current_car; |
||
| 439 | } else { |
||
| 440 | car = GetCarSpec(cat, i); |
||
| 441 | } |
||
| 442 | if (cat != eVehicle_not_really) { |
||
| 443 | InitialiseCar(car); |
||
| 444 | } |
||
| 445 | } |
||
| 446 | } |
||
| 447 | gCamera_yaw = 0; |
||
| 448 | InitialiseExternalCamera(); |
||
| 449 | gLast_mechanics_time = 0; |
||
| 450 | } |
||
| 451 | |||
| 452 | // IDA: void __usercall GetAverageGridPosition(tRace_info *pThe_race@<EAX>) |
||
| 453 | void GetAverageGridPosition(tRace_info* pThe_race) { |
||
| 454 | int i; |
||
| 455 | br_scalar total_cars; |
||
| 456 | tCar_spec* car; |
||
| 457 | LOG_TRACE("(%p)", pThe_race); |
||
| 458 | |||
| 459 | total_cars = 0.0f; |
||
| 460 | BrVector3SetFloat(&gAverage_grid_position, 0.0f, 0.0f, 0.0f); |
||
| 461 | for (i = 0; i < pThe_race->number_of_racers; i++) { |
||
| 462 | car = pThe_race->opponent_list[i].car_spec; |
||
| 463 | BrVector3Accumulate(&gAverage_grid_position, &car->pos); |
||
| 464 | total_cars += 1.0f; |
||
| 465 | } |
||
| 466 | BrVector3InvScale(&gAverage_grid_position, &gAverage_grid_position, total_cars); |
||
| 467 | } |
||
| 468 | |||
| 469 | // IDA: void __usercall SetInitialPosition(tRace_info *pThe_race@<EAX>, int pCar_index@<EDX>, int pGrid_index@<EBX>) |
||
| 470 | void SetInitialPosition(tRace_info* pThe_race, int pCar_index, int pGrid_index) { |
||
| 471 | int place_on_grid; |
||
| 472 | int i; |
||
| 473 | int start_i; |
||
| 474 | int j; |
||
| 475 | br_actor* car_actor; |
||
| 476 | br_angle initial_yaw; |
||
| 477 | br_scalar nearest_y_above; |
||
| 478 | br_scalar nearest_y_below; |
||
| 479 | //br_scalar speed; // Pierre-Marie Baty -- unused variable |
||
| 480 | int below_face_index; |
||
| 481 | int above_face_index; |
||
| 482 | br_model* below_model; |
||
| 483 | br_model* above_model; |
||
| 484 | tCar_spec* car; |
||
| 485 | br_vector3 grid_offset; |
||
| 486 | br_vector3 dist; |
||
| 487 | br_vector3 real_pos; |
||
| 488 | br_matrix34 initial_yaw_matrix; |
||
| 489 | //br_bounds bnds; // Pierre-Marie Baty -- unused variable |
||
| 490 | LOG_TRACE("(%p, %d, %d)", pThe_race, pCar_index, pGrid_index); |
||
| 491 | |||
| 492 | initial_yaw = 0; |
||
| 493 | car_actor = pThe_race->opponent_list[pCar_index].car_spec->car_master_actor; |
||
| 494 | car = pThe_race->opponent_list[pCar_index].car_spec; |
||
| 495 | BrMatrix34Identity(&car_actor->t.t.mat); |
||
| 496 | place_on_grid = 1; |
||
| 497 | if (gNet_mode != eNet_mode_none && !gCurrent_net_game->options.grid_start && pThe_race->number_of_net_start_points != 0) { |
||
| 498 | start_i = i = IRandomBetween(0, pThe_race->number_of_net_start_points - 1); |
||
| 499 | do { |
||
| 500 | PossibleService(); |
||
| 501 | for (j = 0; j < gNumber_of_net_players; j++) { |
||
| 502 | if (j != pCar_index) { |
||
| 503 | BrVector3Copy(&real_pos, &pThe_race->opponent_list[j].car_spec->car_master_actor->t.t.translate.t); |
||
| 504 | if (real_pos.v[0] > 500.f) { |
||
| 505 | real_pos.v[0] -= 1000.f; |
||
| 506 | real_pos.v[1] -= 1000.f; |
||
| 507 | real_pos.v[2] -= 1000.f; |
||
| 508 | } |
||
| 509 | BrVector3Sub(&dist, &real_pos, &pThe_race->net_starts[i].pos); |
||
| 510 | if (BrVector3LengthSquared(&dist) < 16.f) { |
||
| 511 | break; |
||
| 512 | } |
||
| 513 | } |
||
| 514 | } |
||
| 515 | if (j == gNumber_of_net_players) { |
||
| 516 | BrVector3Copy(&car_actor->t.t.translate.t, &pThe_race->net_starts[i].pos); |
||
| 517 | initial_yaw = BrDegreeToAngle(pThe_race->net_starts[i].yaw); |
||
| 518 | place_on_grid = 0; |
||
| 519 | } |
||
| 520 | i++; |
||
| 521 | if (i == pThe_race->number_of_net_start_points) { |
||
| 522 | i = 0; |
||
| 523 | } |
||
| 524 | } while (start_i != i); |
||
| 525 | } |
||
| 526 | if (place_on_grid) { |
||
| 527 | initial_yaw = BrDegreeToAngle(pThe_race->initial_yaw); |
||
| 528 | BrMatrix34RotateY(&initial_yaw_matrix, initial_yaw); |
||
| 529 | grid_offset.v[0] = 0.0f - pGrid_index % 2; |
||
| 530 | grid_offset.v[1] = 0.0f; |
||
| 531 | grid_offset.v[2] = (br_scalar)(pGrid_index / 2) * 2.0f + (br_scalar)(pGrid_index % 2) * 0.4f; |
||
| 532 | BrMatrix34ApplyV(&car_actor->t.t.translate.t, &grid_offset, &initial_yaw_matrix); |
||
| 533 | BrVector3Accumulate(&car_actor->t.t.translate.t, &pThe_race->initial_position); |
||
| 534 | } |
||
| 535 | FindBestY( |
||
| 536 | &car_actor->t.t.translate.t, |
||
| 537 | gTrack_actor, |
||
| 538 | 10.0f, |
||
| 539 | &nearest_y_above, |
||
| 540 | &nearest_y_below, |
||
| 541 | &above_model, |
||
| 542 | &below_model, |
||
| 543 | &above_face_index, |
||
| 544 | &below_face_index); |
||
| 545 | if (nearest_y_above != 30000.0f) { |
||
| 546 | car_actor->t.t.translate.t.v[1] = nearest_y_above; |
||
| 547 | } else if (nearest_y_below != -30000.0f) { |
||
| 548 | car_actor->t.t.translate.t.v[1] = nearest_y_below; |
||
| 549 | } else { |
||
| 550 | car_actor->t.t.translate.t.v[1] = 0.0f; |
||
| 551 | } |
||
| 552 | BrMatrix34PreRotateY(&car_actor->t.t.mat, initial_yaw); |
||
| 553 | if (gNet_mode) { |
||
| 554 | BrMatrix34Copy( |
||
| 555 | &gNet_players[pThe_race->opponent_list[pCar_index].net_player_index].initial_position, |
||
| 556 | &car->car_master_actor->t.t.mat); |
||
| 557 | } |
||
| 558 | if (gNet_mode != eNet_mode_none && car->disabled && car_actor->t.t.translate.t.v[0] < 500.0f) { |
||
| 559 | DisableCar(car); |
||
| 560 | } |
||
| 561 | // Enable to start all opponent cars upside down ;) |
||
| 562 | // if (strstr(car->name, "EAGLE") == 0) { |
||
| 563 | // car_actor->t.t.translate.t.v[1] += 2; |
||
| 564 | // car_actor->t.t.look_up.up.v[1] = -1; |
||
| 565 | // } |
||
| 566 | } |
||
| 567 | |||
| 568 | // IDA: void __usercall SetInitialPositions(tRace_info *pThe_race@<EAX>) |
||
| 569 | void SetInitialPositions(tRace_info* pThe_race) { |
||
| 570 | int i; |
||
| 571 | LOG_TRACE("(%p)", pThe_race); |
||
| 572 | |||
| 573 | for (i = 0; i < pThe_race->number_of_racers; i++) { |
||
| 574 | SetInitialPosition(pThe_race, i, i); |
||
| 575 | } |
||
| 576 | } |
||
| 577 | |||
| 578 | // IDA: void __usercall InitialiseNonCar(tNon_car_spec *non_car@<EAX>) |
||
| 579 | void InitialiseNonCar(tNon_car_spec* non_car) { |
||
| 580 | tCollision_info* c; |
||
| 581 | LOG_TRACE("(%p)", non_car); |
||
| 582 | |||
| 583 | c = &non_car->collision_info; |
||
| 584 | BrMatrix34Copy(&c->oldmat, &c->car_master_actor->t.t.mat); |
||
| 585 | non_car->collision_info.box_face_ref = gFace_num__car - 2; |
||
| 586 | non_car->collision_info.doing_nothing_flag = 1; |
||
| 587 | non_car->collision_info.disabled = 0; |
||
| 588 | BrVector3SetFloat(&c->v, 0.0f, 0.0f, 0.0f); |
||
| 589 | BrVector3SetFloat(&c->omega, 0.0f, 0.0f, 0.0f); |
||
| 590 | BrVector3SetFloat(&c->oldomega, 0.0f, 0.0f, 0.0f); |
||
| 591 | non_car->collision_info.box_face_ref = gFace_num__car - 2; |
||
| 592 | c->collision_flag = 0; |
||
| 593 | c->who_last_hit_me = NULL; |
||
| 594 | if (c->car_master_actor->identifier[3] == '!') { |
||
| 595 | c->M = non_car->free_mass; |
||
| 596 | c->min_torque_squared = 0.0f; |
||
| 597 | BrVector3Copy(&c->cmpos, &non_car->free_cmpos); |
||
| 598 | } else { |
||
| 599 | c->M = non_car->attached_mass; |
||
| 600 | BrVector3Copy(&c->cmpos, &non_car->attached_cmpos); |
||
| 601 | c->min_torque_squared = non_car->min_torque_squared; |
||
| 602 | } |
||
| 603 | BrVector3Scale(&c->I, &non_car->I_over_M, c->M); |
||
| 604 | c->message.type = 0; |
||
| 605 | c->message.time = 0; |
||
| 606 | c->dt = -1.0f; |
||
| 607 | c->last_car_car_collision = 1; |
||
| 608 | } |
||
| 609 | |||
| 610 | // IDA: void __usercall GetFacesInBox(tCollision_info *c@<EAX>) |
||
| 611 | void GetFacesInBox(tCollision_info* c) { |
||
| 612 | tBounds bnds; |
||
| 613 | br_bounds new_in_old; |
||
| 614 | br_bounds predicted_bounds; |
||
| 615 | br_matrix34 mat; |
||
| 616 | br_matrix34 mat2; |
||
| 617 | br_matrix34 mat3; |
||
| 618 | br_matrix34 mat4; |
||
| 619 | br_matrix34 mat5; |
||
| 620 | br_matrix34 mat6; |
||
| 621 | br_scalar old_d; |
||
| 622 | int i; |
||
| 623 | br_bounds current_bounds; |
||
| 624 | LOG_TRACE("(%p)", c); |
||
| 625 | |||
| 626 | BrMatrix34Copy(&mat, &c->car_master_actor->t.t.mat); |
||
| 627 | BrMatrix34Copy(&mat2, &c->oldmat); |
||
| 628 | BrVector3InvScale((br_vector3*)mat.m[3], (br_vector3*)mat.m[3], WORLD_SCALE); |
||
| 629 | BrVector3InvScale((br_vector3*)mat2.m[3], (br_vector3*)mat2.m[3], WORLD_SCALE); |
||
| 630 | BrMatrix34LPInverse(&mat3, &mat); |
||
| 631 | BrMatrix34Mul(&mat4, &mat2, &mat3); |
||
| 632 | GetNewBoundingBox(&bnds.original_bounds, c->bounds, &mat4); |
||
| 633 | for (i = 0; i < 3; i++) { |
||
| 634 | if (bnds.original_bounds.min.v[i] > c->bounds[0].min.v[i]) { |
||
| 635 | bnds.original_bounds.min.v[i] = c->bounds[0].min.v[i]; |
||
| 636 | } |
||
| 637 | if (bnds.original_bounds.max.v[i] < c->bounds[0].max.v[i]) { |
||
| 638 | bnds.original_bounds.max.v[i] = c->bounds[0].max.v[i]; |
||
| 639 | } |
||
| 640 | bnds.original_bounds.min.v[i] -= 0.002f; |
||
| 641 | bnds.original_bounds.max.v[i] += 0.002f; |
||
| 642 | } |
||
| 643 | GetNewBoundingBox(&c->bounds_world_space, &bnds.original_bounds, &mat); |
||
| 644 | c->bounds_ws_type = eBounds_ws; |
||
| 645 | if ((c->box_face_ref != gFace_num__car && (c->box_face_ref != gFace_num__car - 1 || c->box_face_start <= gFace_count)) |
||
| 646 | || (BrMatrix34Mul(&mat5, &mat, &c->last_box_inv_mat), |
||
| 647 | GetNewBoundingBox(&new_in_old, &bnds.original_bounds, &mat5), |
||
| 648 | c->last_box.max.v[0] <= new_in_old.max.v[0]) |
||
| 649 | || c->last_box.max.v[1] <= new_in_old.max.v[1] |
||
| 650 | || c->last_box.max.v[2] <= new_in_old.max.v[2] |
||
| 651 | || c->last_box.min.v[0] >= new_in_old.min.v[0] |
||
| 652 | || c->last_box.min.v[1] >= new_in_old.min.v[1] |
||
| 653 | || c->last_box.min.v[2] >= new_in_old.min.v[2]) { |
||
| 654 | BrMatrix34Mul(&mat5, &mat4, &mat4); |
||
| 655 | BrMatrix34Mul(&mat6, &mat5, &mat4); |
||
| 656 | BrMatrix34LPInverse(&mat5, &mat6); |
||
| 657 | GetNewBoundingBox(&predicted_bounds, c->bounds, &mat5); |
||
| 658 | for (i = 0; i < 3; i++) { |
||
| 659 | if (bnds.original_bounds.min.v[i] > predicted_bounds.min.v[i]) { |
||
| 660 | bnds.original_bounds.min.v[i] = predicted_bounds.min.v[i]; |
||
| 661 | } |
||
| 662 | if (bnds.original_bounds.max.v[i] < predicted_bounds.max.v[i]) { |
||
| 663 | bnds.original_bounds.max.v[i] = predicted_bounds.max.v[i]; |
||
| 664 | } |
||
| 665 | bnds.original_bounds.min.v[i] -= 0.02f; |
||
| 666 | bnds.original_bounds.max.v[i] += 0.02f; |
||
| 667 | } |
||
| 668 | c->last_box = bnds.original_bounds; |
||
| 669 | BrMatrix34Copy(&c->last_box_inv_mat, &mat3); |
||
| 670 | bnds.mat = &mat; |
||
| 671 | c->box_face_start = gFace_count; |
||
| 672 | gPling_face = NULL; |
||
| 673 | gFace_count += FindFacesInBox(&bnds, &gFace_list__car[gFace_count], COUNT_OF(gFace_list__car) - gFace_count); |
||
| 674 | if (gFace_count >= COUNT_OF(gFace_list__car)) { |
||
| 675 | c->box_face_start = 0; |
||
| 676 | gFace_count = FindFacesInBox(&bnds, gFace_list__car, COUNT_OF(gFace_list__car)); |
||
| 677 | gFace_num__car++; |
||
| 678 | } |
||
| 679 | old_d = c->water_d; |
||
| 680 | if (c->driver == eDriver_local_human |
||
| 681 | && c->water_d != 10000.f |
||
| 682 | && gDouble_pling_water |
||
| 683 | && BrVector3Dot(&c->bounds_world_space.max, &c->water_normal) - c->water_d <= 0.f) { |
||
| 684 | gInTheSea = 1; |
||
| 685 | FreezeCamera(); |
||
| 686 | } |
||
| 687 | if (gPling_face != NULL && fabsf(gPling_face->normal.v[1]) >= 0.9f) { |
||
| 688 | BrVector3Copy(&c->water_normal, &gPling_face->normal); |
||
| 689 | if (c->water_normal.v[1] < 0.f) { |
||
| 690 | BrVector3Negate(&c->water_normal, &c->water_normal); |
||
| 691 | } |
||
| 692 | c->water_d = BrVector3Dot(&gPling_face->v[0], &c->water_normal); |
||
| 693 | if (c->driver == eDriver_local_human) { |
||
| 694 | if (gPling_face->material->identifier[1] != '!') { |
||
| 695 | gDouble_pling_water = 0; |
||
| 696 | } else { |
||
| 697 | if (BrVector3Dot(&c->bounds_world_space.min, &c->water_normal) - c->water_d < 0.0f) { |
||
| 698 | GetNewBoundingBox(¤t_bounds, &c->bounds[1], &c->car_master_actor->t.t.mat); |
||
| 699 | if (BrVector3Dot(¤t_bounds.min, &c->water_normal) / WORLD_SCALE - c->water_d < 0.0f) { |
||
| 700 | gInTheSea = 1; |
||
| 701 | FreezeCamera(); |
||
| 702 | } |
||
| 703 | } |
||
| 704 | gDouble_pling_water = 1; |
||
| 705 | } |
||
| 706 | } |
||
| 707 | } else { |
||
| 708 | c->water_d = 10000.0; |
||
| 709 | if (c->driver == eDriver_local_human) { |
||
| 710 | if (gInTheSea == 1) { |
||
| 711 | gInTheSea = 2; |
||
| 712 | } else { |
||
| 713 | gInTheSea = 0; |
||
| 714 | } |
||
| 715 | } |
||
| 716 | } |
||
| 717 | if (c->water_d != old_d) { |
||
| 718 | StartPipingSession(ePipe_chunk_splash); |
||
| 719 | AddSplashToPipingSession(c); |
||
| 720 | EndPipingSession(); |
||
| 721 | } |
||
| 722 | c->box_face_end = gFace_count; |
||
| 723 | c->box_face_ref = gFace_num__car; |
||
| 724 | } |
||
| 725 | } |
||
| 726 | |||
| 727 | // IDA: int __cdecl IsCarInTheSea() |
||
| 728 | int IsCarInTheSea(void) { |
||
| 729 | LOG_TRACE("()"); |
||
| 730 | |||
| 731 | return gInTheSea; |
||
| 732 | } |
||
| 733 | |||
| 734 | // IDA: void __usercall RememberSafePosition(tCar_spec *car@<EAX>, tU32 pTime@<EDX>) |
||
| 735 | void RememberSafePosition(tCar_spec* car, tU32 pTime) { |
||
| 736 | static tU32 time_count; |
||
| 737 | int j; |
||
| 738 | br_vector3 r; |
||
| 739 | //br_scalar ts; // Pierre-Marie Baty -- unused variable |
||
| 740 | LOG_TRACE("(%p, %d)", car, pTime); |
||
| 741 | |||
| 742 | if (car->disabled) { |
||
| 743 | return; |
||
| 744 | } |
||
| 745 | time_count += pTime; |
||
| 746 | if (time_count < 5000) { |
||
| 747 | return; |
||
| 748 | } |
||
| 749 | time_count = 4000; |
||
| 750 | for (j = 0; j < 4; j++) { |
||
| 751 | if (car->susp_height[j >> 1] <= car->oldd[j]) { |
||
| 752 | return; |
||
| 753 | } |
||
| 754 | } |
||
| 755 | if ((car->last_special_volume == NULL || car->last_special_volume->gravity_multiplier == 1.f) |
||
| 756 | && gCurrent_race.material_modifiers[car->material_index[0]].tyre_road_friction >= 0.1f |
||
| 757 | && gCurrent_race.material_modifiers[car->material_index[1]].tyre_road_friction >= 0.1f |
||
| 758 | && gCurrent_race.material_modifiers[car->material_index[2]].tyre_road_friction >= 0.1f |
||
| 759 | && gCurrent_race.material_modifiers[car->material_index[3]].tyre_road_friction >= 0.1f |
||
| 760 | && car->car_master_actor->t.t.mat.m[1][1] > 0.8f) { |
||
| 761 | |||
| 762 | for (j = 0; j < 5; j++) { |
||
| 763 | BrVector3Sub(&r, &car->car_master_actor->t.t.translate.t, (br_vector3*)car->last_safe_positions[j].m[3]); |
||
| 764 | |||
| 765 | if (BrVector3LengthSquared(&r) < 8.4015961f) { |
||
| 766 | return; |
||
| 767 | } |
||
| 768 | } |
||
| 769 | for (j = 3; j > 0; j--) { |
||
| 770 | BrMatrix34Copy(&car->last_safe_positions[j], &car->last_safe_positions[j - 1]); |
||
| 771 | } |
||
| 772 | BrMatrix34Copy(&car->last_safe_positions[0], &car->car_master_actor->t.t.mat); |
||
| 773 | time_count = 0; |
||
| 774 | } |
||
| 775 | } |
||
| 776 | |||
| 777 | // IDA: void __usercall ControlOurCar(tU32 pTime_difference@<EAX>) |
||
| 778 | void ControlOurCar(tU32 pTime_difference) { |
||
| 779 | br_scalar ts; |
||
| 780 | br_vector3 minus_k; |
||
| 781 | tCar_spec* car; |
||
| 782 | static int steering_locked; |
||
| 783 | //int i; // Pierre-Marie Baty -- unused variable |
||
| 784 | tU32 time; |
||
| 785 | LOG_TRACE("(%d)", pTime_difference); |
||
| 786 | |||
| 787 | car = &gProgram_state.current_car; |
||
| 788 | if (gCar_flying) { |
||
| 789 | if (gNet_mode != eNet_mode_none) { |
||
| 790 | gCar_flying = 0; |
||
| 791 | } else { |
||
| 792 | BrVector3Scale(&car->car_master_actor->t.t.translate.t, &car->car_master_actor->t.t.translate.t, WORLD_SCALE); |
||
| 793 | FlyCar(car, pTime_difference / 1000.f); |
||
| 794 | BrVector3InvScale(&car->car_master_actor->t.t.translate.t, &car->car_master_actor->t.t.translate.t, WORLD_SCALE); |
||
| 795 | } |
||
| 796 | return; |
||
| 797 | } |
||
| 798 | time = GetTotalTime(); |
||
| 799 | if (car->damage_units[eDamage_steering].damage_level > 40) { |
||
| 800 | if (car->end_steering_damage_effect) { |
||
| 801 | if (time < car->end_steering_damage_effect || car->damage_units[eDamage_steering].damage_level == 99) { |
||
| 802 | car->keys.left = car->false_key_left; |
||
| 803 | car->keys.right = car->false_key_right; |
||
| 804 | } else { |
||
| 805 | car->end_steering_damage_effect = 0; |
||
| 806 | } |
||
| 807 | } else { |
||
| 808 | ts = pTime_difference * (car->damage_units[eDamage_steering].damage_level - 40) * 0.0045f; |
||
| 809 | if (PercentageChance(ts) && fabsf(car->velocity_car_space.v[2]) > 0.0001f) { |
||
| 810 | if (car->keys.left || car->keys.right) { |
||
| 811 | car->false_key_left = !car->keys.left; |
||
| 812 | car->false_key_right = !car->keys.right; |
||
| 813 | } else if (PercentageChance(50)) { |
||
| 814 | car->false_key_left = 1; |
||
| 815 | } else { |
||
| 816 | car->false_key_right = 1; |
||
| 817 | } |
||
| 818 | ts = 5 * (5 * car->damage_units[eDamage_steering].damage_level - 200); |
||
| 819 | car->end_steering_damage_effect = FRandomBetween(0.0f, ts) + time; |
||
| 820 | } |
||
| 821 | } |
||
| 822 | } |
||
| 823 | if (car->damage_units[eDamage_transmission].damage_level > 40) { |
||
| 824 | if (car->end_trans_damage_effect) { |
||
| 825 | if (time < car->end_trans_damage_effect || car->damage_units[eDamage_transmission].damage_level == 99) { |
||
| 826 | car->gear = 0; |
||
| 827 | car->just_changed_gear = 1; |
||
| 828 | } else { |
||
| 829 | car->end_trans_damage_effect = 0; |
||
| 830 | } |
||
| 831 | } else { |
||
| 832 | ts = pTime_difference * (car->damage_units[eDamage_transmission].damage_level - 40) * 0.006; |
||
| 833 | if (PercentageChance(ts) != 0) { |
||
| 834 | ts = 10 * (5 * car->damage_units[eDamage_transmission].damage_level - 200); |
||
| 835 | car->end_trans_damage_effect = FRandomBetween(0.f, ts) + time; |
||
| 836 | } |
||
| 837 | } |
||
| 838 | } |
||
| 839 | ts = pTime_difference / 1000.0f; |
||
| 840 | ControlCar[gControl__car](car, ts); |
||
| 841 | RememberSafePosition(car, pTime_difference); |
||
| 842 | if (gCamera_reset) { |
||
| 843 | BrVector3SetFloat(&minus_k, 0.0f, 0.0f, -1.0f); |
||
| 844 | gCamera_sign = 0; |
||
| 845 | BrMatrix34ApplyV(&car->direction, &minus_k, &car->car_master_actor->t.t.mat); |
||
| 846 | } |
||
| 847 | } |
||
| 848 | |||
| 849 | // IDA: void __usercall CalcEngineForce(tCar_spec *c@<EAX>, br_scalar dt) |
||
| 850 | void CalcEngineForce(tCar_spec* c, br_scalar dt) { |
||
| 851 | br_scalar torque; |
||
| 852 | br_scalar ts; |
||
| 853 | br_scalar ts2; |
||
| 854 | //br_scalar brake_temp; // Pierre-Marie Baty -- unused variable |
||
| 855 | int sign; |
||
| 856 | tS32 temp_for_swap; |
||
| 857 | LOG_TRACE("(%p, %f)", c, dt); |
||
| 858 | |||
| 859 | c->acc_force = 0.0f; |
||
| 860 | if (c->revs == 0.0f) { |
||
| 861 | c->gear = 0; |
||
| 862 | } |
||
| 863 | sign = c->gear < 0 || (c->gear == 0 && c->velocity_car_space.v[2] > 0.5f); |
||
| 864 | if (c->keys.backwards != sign) { |
||
| 865 | c->keys.backwards = !c->keys.backwards; |
||
| 866 | temp_for_swap = c->keys.acc; |
||
| 867 | c->keys.acc = c->keys.dec; |
||
| 868 | c->keys.dec = temp_for_swap; |
||
| 869 | |||
| 870 | temp_for_swap = c->joystick.acc; |
||
| 871 | c->joystick.acc = c->joystick.dec; |
||
| 872 | c->joystick.dec = temp_for_swap; |
||
| 873 | } |
||
| 874 | if (!c->gear && !c->keys.acc && c->joystick.acc <= 0 && (c->keys.dec || c->joystick.dec > 0) && !c->keys.backwards && fabs(c->velocity_car_space.v[2]) < 1.0) { |
||
| 875 | c->keys.backwards = 1; |
||
| 876 | c->keys.acc = c->keys.dec; |
||
| 877 | c->keys.dec = 0; |
||
| 878 | temp_for_swap = c->joystick.acc; |
||
| 879 | c->joystick.acc = c->joystick.dec; |
||
| 880 | c->joystick.dec = temp_for_swap; |
||
| 881 | } |
||
| 882 | c->torque = -(c->revs * c->revs / 100000000.0f) - 0.2f; |
||
| 883 | if (c->keys.acc || c->joystick.acc >= 0) { |
||
| 884 | if (fabsf(c->curvature) > c->maxcurve / 2.0f && c->gear < 2 && c->gear && c->traction_control) { |
||
| 885 | ts = 0.7f; |
||
| 886 | } else if (c->joystick.acc < 0) { |
||
| 887 | ts = (br_scalar) 1.2; // Pierre-Marie Baty -- added type cast |
||
| 888 | } else { |
||
| 20 | pmbaty | 889 | ts = c->joystick.acc / 54613.0; |
| 890 | LOG_PANIC("ooo"); |
||
| 1 | pmbaty | 891 | } |
| 892 | |||
| 893 | torque = c->engine_power_multiplier * ts * gEngine_powerup_factor[c->power_up_levels[1]]; |
||
| 894 | if (c->damage_units[0].damage_level > 10) { |
||
| 895 | torque = (1.0f - (double)(c->damage_units[0].damage_level - 10) / 100.0f) * torque; |
||
| 896 | } |
||
| 897 | c->torque += torque; |
||
| 898 | } else { |
||
| 899 | c->traction_control = 1; |
||
| 900 | } |
||
| 901 | if (!c->keys.dec && (!c->keys.acc || c->gear) && c->joystick.dec <= 0 && (c->joystick.acc <= 0 || c->gear)) { |
||
| 902 | c->brake_force = 0.0f; |
||
| 903 | } else { |
||
| 904 | if (c->joystick.dec > 0) { |
||
| 905 | c->brake_force = (double)(c->joystick.dec / 0x10000) * c->brake_increase + c->initial_brake; |
||
| 906 | } |
||
| 907 | if (c->brake_force == 0.0f) { |
||
| 908 | c->brake_force = c->initial_brake; |
||
| 909 | } else { |
||
| 910 | c->brake_force += c->brake_increase * dt; |
||
| 911 | if (c->initial_brake + c->brake_increase < c->brake_force) { |
||
| 912 | c->brake_force = c->initial_brake + c->brake_increase; |
||
| 913 | } |
||
| 914 | } |
||
| 915 | } |
||
| 916 | if (c->gear) { |
||
| 917 | c->acc_force = c->force_torque_ratio * c->torque / (float)c->gear; |
||
| 918 | if (c->brake_force == 0.0f) { |
||
| 919 | if (c->revs - 1.0f > c->target_revs || c->revs + 1.0f < c->target_revs) { |
||
| 920 | ts2 = c->torque * dt / 0.0002 + c->revs - c->target_revs; |
||
| 921 | c->acc_force += ts2 / ((1.0f / (c->speed_revs_ratio * c->M) / (float)c->gear + 1.0 / (c->force_torque_ratio * 0.0002) * (double)c->gear) * dt); |
||
| 922 | } |
||
| 923 | } else { |
||
| 924 | c->revs = c->target_revs; |
||
| 925 | } |
||
| 926 | } |
||
| 927 | } |
||
| 928 | |||
| 929 | // IDA: void __usercall PrepareCars(tU32 pFrame_start_time@<EAX>) |
||
| 930 | void PrepareCars(tU32 pFrame_start_time) { |
||
| 931 | tCar_spec* car; |
||
| 932 | int i; |
||
| 933 | static tU32 last_frame_start; |
||
| 934 | LOG_TRACE("(%d)", pFrame_start_time); |
||
| 935 | |||
| 936 | last_frame_start = pFrame_start_time; |
||
| 937 | for (i = 0; i < gNum_cars_and_non_cars; i++) { |
||
| 938 | car = gActive_car_list[i]; |
||
| 939 | BrVector3Scale(&car->car_master_actor->t.t.translate.t, &car->car_master_actor->t.t.translate.t, WORLD_SCALE); |
||
| 940 | BrVector3Scale(&car->velocity_car_space, &car->velocity_car_space, WORLD_SCALE * 1000.f); |
||
| 941 | car->frame_collision_flag = gOver_shoot && car->collision_flag; |
||
| 942 | if (car->driver > eDriver_non_car) { |
||
| 943 | RecordLastDamage(car); |
||
| 944 | if (car->driver == eDriver_oppo && gStop_opponents_moving) { |
||
| 945 | car->acc_force = 0.0f; |
||
| 946 | car->brake_force = 0.0f; |
||
| 947 | car->keys.acc = 0; |
||
| 948 | car->keys.dec = 0; |
||
| 949 | car->joystick.acc = -1; |
||
| 950 | car->joystick.dec = -1; |
||
| 951 | } |
||
| 952 | if (!car->wheel_slip) { |
||
| 953 | StopSkid(car); |
||
| 954 | } |
||
| 955 | if (car->driver == eDriver_net_human && car->message.time < pFrame_start_time - 1000) { |
||
| 956 | car->keys.acc = 0; |
||
| 957 | car->keys.dec = 0; |
||
| 958 | car->joystick.acc = -1; |
||
| 959 | car->joystick.dec = -1; |
||
| 960 | car->keys.horn = 0; |
||
| 961 | } |
||
| 962 | SetSmokeLastDamageLevel(car); |
||
| 963 | } |
||
| 964 | BrMatrix34Copy(&car->car_master_actor->t.t.mat, &car->oldmat); |
||
| 965 | } |
||
| 966 | } |
||
| 967 | |||
| 968 | // IDA: void __usercall FinishCars(tU32 pLast_frame_time@<EAX>, tU32 pTime@<EDX>) |
||
| 969 | void FinishCars(tU32 pLast_frame_time, tU32 pTime) { |
||
| 970 | tCar_spec* car; |
||
| 971 | br_vector3 minus_k; |
||
| 972 | int i; |
||
| 973 | int wheel; |
||
| 974 | //br_scalar scale; // Pierre-Marie Baty -- unused variable |
||
| 975 | LOG_TRACE("(%d, %d)", pLast_frame_time, pTime); |
||
| 976 | |||
| 977 | for (i = 0; i < gNum_cars_and_non_cars; i++) { |
||
| 978 | car = gActive_car_list[i]; |
||
| 979 | if (fabsf(car->omega.v[0]) > 10000.f |
||
| 980 | || fabsf(car->omega.v[1]) > 10000.f |
||
| 981 | || fabsf(car->omega.v[2]) > 10000.f) { |
||
| 982 | BrVector3SetFloat(&car->omega, 0.f, 0.f, 0.f); |
||
| 983 | BrVector3SetFloat(&car->v, 0.f, 0.f, 0.f); |
||
| 984 | } |
||
| 985 | BrVector3InvScale(&car->velocity_car_space, &car->velocity_car_space, WORLD_SCALE * 1000.0f); |
||
| 986 | BrVector3InvScale(&car->car_master_actor->t.t.translate.t, &car->car_master_actor->t.t.translate.t, WORLD_SCALE); |
||
| 987 | |||
| 988 | car->speed = BR_LENGTH2(car->v.v[0], car->v.v[2]) / (WORLD_SCALE * 1000.0f); |
||
| 989 | BrVector3Negate(&minus_k, (br_vector3*)car->car_master_actor->t.t.mat.m[2]); |
||
| 990 | if (car->speed <= 0.0001f) { |
||
| 991 | if (BrVector3Dot(&car->direction, &minus_k) < 0.f) { |
||
| 992 | BrVector3SetFloat(&minus_k, 0.f, 0.f, 1.f); |
||
| 993 | } else { |
||
| 994 | BrVector3SetFloat(&minus_k, 0.f, 0.f, -1.f); |
||
| 995 | } |
||
| 996 | BrMatrix34ApplyV(&car->direction, &minus_k, &car->car_master_actor->t.t.mat); |
||
| 997 | } else if (gLast_mechanics_time > pLast_frame_time && gCar_to_view == car) { |
||
| 998 | BrVector3Sub(&car->old_v, &car->old_v, &car->v); |
||
| 999 | BrVector3Scale(&car->old_v, &car->old_v, (gLast_mechanics_time - pLast_frame_time) / harness_game_config.physics_step_time); |
||
| 1000 | BrVector3Accumulate(&car->old_v, &car->v); |
||
| 1001 | BrVector3Normalise(&car->direction, &car->old_v); |
||
| 1002 | } else { |
||
| 1003 | BrVector3Normalise(&car->direction, &car->v); |
||
| 1004 | } |
||
| 1005 | if (car->driver >= eDriver_oppo) { |
||
| 1006 | car->speedo_speed = BrVector3Dot(&minus_k, &car->v) / (WORLD_SCALE * 1000.0f); |
||
| 1007 | |||
| 1008 | car->steering_angle = BrRadianToDegree(atanf((car->wpos[0].v[2] - car->wpos[2].v[2]) * car->curvature)); |
||
| 1009 | |||
| 1010 | car->lr_sus_position = (car->ride_height - car->oldd[0]) / WORLD_SCALE; |
||
| 1011 | car->rr_sus_position = (car->ride_height - car->oldd[1]) / WORLD_SCALE; |
||
| 1012 | car->lf_sus_position = (car->ride_height - car->oldd[2]) / WORLD_SCALE; |
||
| 1013 | car->rf_sus_position = (car->ride_height - car->oldd[3]) / WORLD_SCALE; |
||
| 1014 | for (wheel = 0; wheel < 4; wheel++) { |
||
| 1015 | if (car->oldd[wheel] < car->susp_height[wheel >> 1] && gCurrent_race.material_modifiers[car->material_index[wheel]].smoke_type >= 2 && !car->doing_nothing_flag) { |
||
| 1016 | GenerateContinuousSmoke(car, wheel, pTime); |
||
| 1017 | } |
||
| 1018 | } |
||
| 1019 | } |
||
| 1020 | } |
||
| 1021 | } |
||
| 1022 | |||
| 1023 | // IDA: void __usercall InterpolateCars(tU32 pLast_frame_time@<EAX>, tU32 pTime@<EDX>) |
||
| 1024 | void InterpolateCars(tU32 pLast_frame_time, tU32 pTime) { |
||
| 1025 | br_scalar dt; |
||
| 1026 | tCar_spec* car; |
||
| 1027 | int i; |
||
| 1028 | LOG_TRACE("(%d, %d)", pLast_frame_time, pTime); |
||
| 1029 | |||
| 1030 | dt = ((int)(gLast_mechanics_time - pLast_frame_time)) / 1000.0; |
||
| 1031 | if (dt > 0.04 || dt < 0) |
||
| 1032 | dt = 0; |
||
| 1033 | |||
| 1034 | gOver_shoot = dt > 0.0; |
||
| 1035 | |||
| 1036 | for (i = 0; i < gNum_cars_and_non_cars; i++) { |
||
| 1037 | car = gActive_car_list[i]; |
||
| 1038 | BrMatrix34Copy(&car->oldmat, &car->car_master_actor->t.t.mat); |
||
| 1039 | SimpleRotate((tCollision_info*)car, -dt); |
||
| 1040 | TranslateCar((tCollision_info*)car, -dt); |
||
| 1041 | BrMatrix34ApplyP(&car->pos, &car->cmpos, &car->car_master_actor->t.t.mat); |
||
| 1042 | BrVector3InvScale(&car->pos, &car->pos, WORLD_SCALE); |
||
| 1043 | } |
||
| 1044 | } |
||
| 1045 | |||
| 1046 | // IDA: void __cdecl ResetOldmat() |
||
| 1047 | void ResetOldmat(void) { |
||
| 1048 | tCar_spec* car; |
||
| 1049 | int i; |
||
| 1050 | br_matrix34 mat; |
||
| 1051 | static int normalise_count = 0; |
||
| 1052 | LOG_TRACE("()"); |
||
| 1053 | |||
| 1054 | for (i = 0; i < gNum_cars_and_non_cars; i++) { |
||
| 1055 | BrMatrix34Copy(&gActive_car_list[i]->oldmat, &gActive_car_list[i]->car_master_actor->t.t.mat); |
||
| 1056 | } |
||
| 1057 | normalise_count++; |
||
| 1058 | if (normalise_count > 50) { |
||
| 1059 | normalise_count = 0; |
||
| 1060 | for (i = 0; i < gNum_cars_and_non_cars; i++) { |
||
| 1061 | car = gActive_car_list[i]; |
||
| 1062 | BrMatrix34LPNormalise(&mat, &car->car_master_actor->t.t.mat); |
||
| 1063 | BrMatrix34Copy(&car->car_master_actor->t.t.mat, &mat); |
||
| 1064 | } |
||
| 1065 | } |
||
| 1066 | } |
||
| 1067 | |||
| 1068 | // IDA: void __cdecl GetNonCars() |
||
| 1069 | void GetNonCars(void) { |
||
| 1070 | int i; |
||
| 1071 | int j; |
||
| 1072 | LOG_TRACE("()"); |
||
| 1073 | |||
| 1074 | gNum_cars_and_non_cars = gNum_active_non_cars + gNum_active_cars; |
||
| 1075 | j = 0; |
||
| 1076 | for (i = gNum_active_cars; i < gNum_cars_and_non_cars; i++) { |
||
| 1077 | gActive_car_list[i] = (tCar_spec*)gActive_non_car_list[j]; |
||
| 1078 | j++; |
||
| 1079 | } |
||
| 1080 | } |
||
| 1081 | |||
| 1082 | // IDA: void __usercall GetNetPos(tCar_spec *pCar@<EAX>) |
||
| 1083 | void GetNetPos(tCar_spec* pCar) { |
||
| 20 | pmbaty | 1084 | //int j; // Pierre-Marie Baty -- unused variable |
| 1085 | //float amount; // Pierre-Marie Baty -- unused variable |
||
| 1086 | //br_scalar total_deflection; // Pierre-Marie Baty -- unused variable |
||
| 1 | pmbaty | 1087 | LOG_TRACE("(%p)", pCar); |
| 20 | pmbaty | 1088 | NOT_IMPLEMENTED(); |
| 1 | pmbaty | 1089 | } |
| 1090 | |||
| 1091 | // IDA: void __usercall ApplyPhysicsToCars(tU32 last_frame_time@<EAX>, tU32 pTime_difference@<EDX>) |
||
| 1092 | void ApplyPhysicsToCars(tU32 last_frame_time, tU32 pTime_difference) { |
||
| 1093 | //br_vector3 minus_k; // Pierre-Marie Baty -- unused variable |
||
| 1094 | int i; |
||
| 1095 | int old_num_cars; |
||
| 1096 | int step_number; |
||
| 1097 | int dam_index; |
||
| 1098 | static int steering_locked; |
||
| 1099 | tCar_spec* car = NULL; |
||
| 1100 | tCollision_info* car_info; |
||
| 1101 | tNon_car_spec* non_car; |
||
| 1102 | //tU32 time_step; // Pierre-Marie Baty -- unused variable |
||
| 1103 | tU32 frame_end_time; |
||
| 1104 | LOG_TRACE("(%d, %d)", last_frame_time, pTime_difference); |
||
| 1105 | |||
| 1106 | step_number = 0; |
||
| 1107 | frame_end_time = last_frame_time + pTime_difference; |
||
| 1108 | if (gFreeze_mechanics) { |
||
| 1109 | return; |
||
| 1110 | } |
||
| 1111 | if (gNet_mode == eNet_mode_client) { |
||
| 1112 | ForceRebuildActiveCarList(); |
||
| 1113 | } |
||
| 1114 | if (gLast_mechanics_time < last_frame_time) { |
||
| 1115 | gLast_mechanics_time = harness_game_config.physics_step_time * (last_frame_time / harness_game_config.physics_step_time); |
||
| 1116 | } |
||
| 1117 | GetNonCars(); |
||
| 1118 | if (frame_end_time <= gLast_mechanics_time) { |
||
| 1119 | PrepareCars(last_frame_time); |
||
| 1120 | InterpolateCars(frame_end_time, pTime_difference); |
||
| 1121 | FinishCars(frame_end_time, pTime_difference); |
||
| 1122 | return; |
||
| 1123 | } |
||
| 1124 | |||
| 1125 | gDoing_physics = 1; |
||
| 1126 | PrepareCars(last_frame_time); |
||
| 1127 | gDt = harness_game_config.physics_step_time / 1000.0; // 0.04; |
||
| 1128 | gMechanics_time_sync = pTime_difference - (gLast_mechanics_time - last_frame_time); |
||
| 1129 | while (gLast_mechanics_time < frame_end_time && step_number < 5) { |
||
| 1130 | step_number++; |
||
| 1131 | ResetOldmat(); |
||
| 1132 | BrVector3Copy(&gProgram_state.current_car.old_v, &gProgram_state.current_car.v); |
||
| 1133 | if (&gProgram_state.current_car != gCar_to_view) { |
||
| 1134 | BrVector3Copy(&gCar_to_view->old_v, &gCar_to_view->v); |
||
| 1135 | } |
||
| 1136 | for (i = 0; i < gNum_active_cars; i++) { |
||
| 1137 | car = gActive_car_list[i]; |
||
| 1138 | car->dt = -1.f; |
||
| 20 | pmbaty | 1139 | if (car->message.type == 15 && car->message.time >= gLast_mechanics_time && gLast_mechanics_time + harness_game_config.physics_step_time >= car->message.time) { |
| 1140 | car->dt = (double)(gLast_mechanics_time + harness_game_config.physics_step_time - car->message.time) / 1000.0; |
||
| 1141 | if (gDt - 0.0001f <= car->dt) { |
||
| 1 | pmbaty | 1142 | GetNetPos(car); |
| 1143 | } else if (gNet_mode == eNet_mode_host) { |
||
| 1144 | car->dt = -1.f; |
||
| 1145 | } else { |
||
| 1146 | for (dam_index = 0; dam_index < COUNT_OF(car->damage_units); dam_index++) { |
||
| 1147 | if (car->damage_units[dam_index].damage_level < car->message.damage[dam_index]) { |
||
| 1148 | car->dt = -1.f; |
||
| 1149 | break; |
||
| 1150 | } |
||
| 1151 | } |
||
| 1152 | if (car->dt >= 0.f) { |
||
| 1153 | GetNetPos(car); |
||
| 1154 | } |
||
| 1155 | } |
||
| 1156 | } |
||
| 1157 | if (!car->disabled |
||
| 1158 | && (!car->doing_nothing_flag || (car->driver >= eDriver_net_human && (!gPalette_fade_time || car->driver != eDriver_local_human)))) { |
||
| 1159 | if (car->box_face_ref != gFace_num__car |
||
| 1160 | && (car->box_face_ref != gFace_num__car - 1 || car->box_face_start <= gFace_count)) { |
||
| 1161 | car_info = (tCollision_info*)car; |
||
| 1162 | GetFacesInBox(car_info); |
||
| 1163 | } |
||
| 1164 | if (car->dt != 0.f) { |
||
| 1165 | MoveAndCollideCar(car, gDt); |
||
| 1166 | } |
||
| 1167 | } |
||
| 1168 | } |
||
| 1169 | for (i = 0; i < gNum_active_non_cars; i++) { |
||
| 1170 | non_car = gActive_non_car_list[i]; |
||
| 1171 | if (!non_car->collision_info.doing_nothing_flag) { |
||
| 1172 | non_car->collision_info.dt = -1.f; |
||
| 20 | pmbaty | 1173 | if (non_car->collision_info.message.type == 16 && non_car->collision_info.message.time >= gLast_mechanics_time && gLast_mechanics_time + harness_game_config.physics_step_time >= non_car->collision_info.message.time) { |
| 1 | pmbaty | 1174 | non_car->collision_info.dt = (gLast_mechanics_time + harness_game_config.physics_step_time - non_car->collision_info.message.time) / 1000.0f; |
| 1175 | GetNetPos((tCar_spec*)non_car); |
||
| 1176 | } |
||
| 1177 | if (non_car->collision_info.box_face_ref != gFace_num__car |
||
| 1178 | && (non_car->collision_info.box_face_ref != gFace_num__car - 1 |
||
| 1179 | || non_car->collision_info.box_face_start <= gFace_count)) { |
||
| 1180 | GetFacesInBox(&non_car->collision_info); |
||
| 1181 | } |
||
| 1182 | if (non_car->collision_info.dt != 0.0f) { |
||
| 1183 | MoveAndCollideNonCar(non_car, gDt); |
||
| 1184 | } |
||
| 1185 | } |
||
| 1186 | } |
||
| 1187 | do { |
||
| 1188 | old_num_cars = gNum_cars_and_non_cars; |
||
| 1189 | CrashCarsTogether(gDt); |
||
| 1190 | } while (old_num_cars < gNum_cars_and_non_cars); |
||
| 1191 | gMechanics_time_sync -= harness_game_config.physics_step_time; |
||
| 1192 | gLast_mechanics_time += harness_game_config.physics_step_time; |
||
| 1193 | } |
||
| 1194 | gMechanics_time_sync = 1; |
||
| 1195 | SendCarData(gLast_mechanics_time); |
||
| 1196 | InterpolateCars(frame_end_time, pTime_difference); |
||
| 1197 | FinishCars(frame_end_time, pTime_difference); |
||
| 1198 | gDoing_physics = 0; |
||
| 1199 | CheckForDeAttachmentOfNonCars(pTime_difference); |
||
| 1200 | } |
||
| 1201 | |||
| 1202 | // IDA: void __usercall MungeSpecialVolume(tCollision_info *pCar@<EAX>) |
||
| 1203 | void MungeSpecialVolume(tCollision_info* pCar) { |
||
| 1204 | tSpecial_volume* new_special_volume; |
||
| 1205 | //tCar_spec* car; // Pierre-Marie Baty -- unused variable |
||
| 1206 | LOG_TRACE("(%p)", pCar); |
||
| 1207 | |||
| 1208 | new_special_volume = FindSpecialVolume(&pCar->pos, pCar->last_special_volume); |
||
| 1209 | if (pCar->auto_special_volume != NULL && (new_special_volume == NULL || new_special_volume->gravity_multiplier == 1.f)) { |
||
| 1210 | if (pCar->water_d == 10000.f && pCar->water_depth_factor != 1.f) { |
||
| 1211 | pCar->auto_special_volume = NULL; |
||
| 1212 | } else { |
||
| 1213 | new_special_volume = pCar->auto_special_volume; |
||
| 1214 | } |
||
| 1215 | } |
||
| 1216 | if (pCar->last_special_volume != new_special_volume && pCar->driver == eDriver_local_human) { |
||
| 1217 | if (pCar->last_special_volume != NULL && pCar->last_special_volume->exit_noise >= 0 && (new_special_volume == NULL || pCar->last_special_volume->exit_noise != new_special_volume->exit_noise)) { |
||
| 1218 | DRS3StartSound(gCar_outlet, pCar->last_special_volume->exit_noise); |
||
| 1219 | } |
||
| 1220 | if (new_special_volume != NULL && new_special_volume->entry_noise >= 0 && (pCar->last_special_volume == NULL || pCar->last_special_volume->entry_noise != new_special_volume->entry_noise)) { |
||
| 1221 | DRS3StartSound(gCar_outlet, new_special_volume->entry_noise); |
||
| 1222 | } |
||
| 1223 | } |
||
| 1224 | pCar->last_special_volume = new_special_volume; |
||
| 1225 | if (new_special_volume != NULL && pCar->num_smoke_columns != 0 && pCar->last_special_volume != NULL && pCar->last_special_volume->gravity_multiplier < 1.f) { |
||
| 1226 | StopCarSmoking((tCar_spec*)pCar); |
||
| 1227 | } |
||
| 1228 | } |
||
| 1229 | |||
| 1230 | // IDA: void __usercall ResetCarSpecialVolume(tCollision_info *pCar@<EAX>) |
||
| 1231 | void ResetCarSpecialVolume(tCollision_info* pCar) { |
||
| 1232 | br_vector3 cast_v; |
||
| 1233 | br_vector3 norm; |
||
| 1234 | br_scalar t; |
||
| 1235 | int id_len; |
||
| 1236 | char* mat_id; |
||
| 1237 | tSpecial_volume* new_special_volume; |
||
| 1238 | br_material* material; |
||
| 1239 | LOG_TRACE("(%p)", pCar); |
||
| 1240 | |||
| 1241 | new_special_volume = NULL; |
||
| 1242 | BrVector3Set(&cast_v, 0.f, 200.f, 0.f); |
||
| 1243 | DisablePlingMaterials(); |
||
| 1244 | FindFace(&pCar->car_master_actor->t.t.translate.t, &cast_v, &norm, &t, &material); |
||
| 1245 | EnablePlingMaterials(); |
||
| 1246 | if (t < 100.0f && material != NULL) { |
||
| 1247 | mat_id = material->identifier; |
||
| 1248 | if (mat_id) { |
||
| 1249 | id_len = strlen(mat_id); |
||
| 1250 | if (id_len > 0 && (*mat_id == '!' || *mat_id == '#')) { |
||
| 1251 | new_special_volume = GetDefaultSpecialVolumeForWater(); |
||
| 1252 | } |
||
| 1253 | } |
||
| 1254 | } |
||
| 1255 | pCar->auto_special_volume = new_special_volume; |
||
| 1256 | pCar->water_depth_factor = 1.0f; |
||
| 1257 | } |
||
| 1258 | |||
| 1259 | // IDA: void __usercall TestAutoSpecialVolume(tCollision_info *pCar@<EAX>) |
||
| 1260 | void TestAutoSpecialVolume(tCollision_info* pCar) { |
||
| 1261 | br_vector3 pos; |
||
| 1262 | //br_scalar car_d; // Pierre-Marie Baty -- unused variable |
||
| 1263 | br_scalar d; |
||
| 1264 | br_scalar d2; |
||
| 1265 | br_vector3 dir; |
||
| 1266 | br_vector3 tv; |
||
| 1267 | br_vector3 lp; |
||
| 1268 | br_vector3 hp; |
||
| 1269 | tSpecial_volume* vol; |
||
| 1270 | br_matrix34* mat; |
||
| 1271 | br_scalar lowest_p; |
||
| 1272 | br_scalar highest_p; |
||
| 1273 | br_scalar val; |
||
| 1274 | int i; |
||
| 1275 | LOG_TRACE("(%p)", pCar); |
||
| 1276 | |||
| 1277 | mat = &pCar->car_master_actor->t.t.mat; |
||
| 1278 | highest_p = 0.f; |
||
| 1279 | for (i = 0; i < 3; i++) { |
||
| 1280 | highest_p += BrVector3Dot((br_vector3*)mat->m[i], &pCar->water_normal) * pCar->bounds[0].min.v[i]; |
||
| 1281 | } |
||
| 1282 | highest_p += BrVector3Dot((br_vector3*)mat->m[3], &pCar->water_normal) / WORLD_SCALE; |
||
| 1283 | lowest_p = highest_p; |
||
| 1284 | for (i = 0; i < 3; i++) { |
||
| 1285 | val = (pCar->bounds[0].max.v[i] - pCar->bounds[0].min.v[i]) * BrVector3Dot((br_vector3*)mat->m[i], &pCar->water_normal); |
||
| 1286 | if (val >= 0.f) { |
||
| 1287 | highest_p += val; |
||
| 1288 | } else { |
||
| 1289 | lowest_p += val; |
||
| 1290 | } |
||
| 1291 | } |
||
| 1292 | |||
| 1293 | if (pCar->water_d > lowest_p) { |
||
| 1294 | if (pCar->water_d >= highest_p) { |
||
| 1295 | pCar->water_depth_factor = 1.f; |
||
| 1296 | } else { |
||
| 1297 | pCar->water_depth_factor = (pCar->water_d - lowest_p) / (highest_p - lowest_p); |
||
| 1298 | } |
||
| 1299 | if (pCar->auto_special_volume == NULL) { |
||
| 1300 | vol = GetDefaultSpecialVolumeForWater(); |
||
| 1301 | if (vol == NULL) { |
||
| 1302 | pCar->water_depth_factor = 1.f; |
||
| 1303 | pCar->auto_special_volume = NULL; |
||
| 1304 | } else { |
||
| 1305 | BrVector3Scale(&tv, &pCar->bounds[0].min, WORLD_SCALE); |
||
| 1306 | BrMatrix34ApplyP(&lp, &tv, mat); |
||
| 1307 | BrVector3InvScale(&lp, &lp, WORLD_SCALE); |
||
| 1308 | BrVector3Copy(&hp, &lp); |
||
| 1309 | for (i = 0; i < 3; i++) { |
||
| 1310 | val = pCar->bounds[0].max.v[i] - pCar->bounds[0].min.v[i]; |
||
| 1311 | BrVector3Scale(&tv, (br_vector3*)mat->m[i], val); |
||
| 1312 | if (BrVector3Dot(&pCar->water_normal, &tv) > 0.f) { |
||
| 1313 | BrVector3Accumulate(&hp, &tv); |
||
| 1314 | } else { |
||
| 1315 | BrVector3Accumulate(&lp, &tv); |
||
| 1316 | } |
||
| 1317 | } |
||
| 1318 | BrVector3Sub(&dir, &hp, &lp); |
||
| 1319 | DisablePlingMaterials(); |
||
| 1320 | FindFloorInBoxBU(&lp, &dir, &tv, &d, pCar); |
||
| 1321 | EnablePlingMaterials(); |
||
| 1322 | FindFloorInBoxBU(&pos, &dir, &tv, &d2, pCar); |
||
| 1323 | if (d2 <= d) { |
||
| 1324 | pCar->water_depth_factor = 1.f; |
||
| 1325 | pCar->auto_special_volume = NULL; |
||
| 1326 | } else { |
||
| 1327 | pCar->auto_special_volume = vol; |
||
| 1328 | } |
||
| 1329 | } |
||
| 1330 | } |
||
| 1331 | } else { |
||
| 1332 | pCar->auto_special_volume = NULL; |
||
| 1333 | pCar->water_depth_factor = 1.f; |
||
| 1334 | } |
||
| 1335 | } |
||
| 1336 | |||
| 1337 | // IDA: void __usercall MoveAndCollideCar(tCar_spec *car@<EAX>, br_scalar dt) |
||
| 1338 | void MoveAndCollideCar(tCar_spec* car, br_scalar dt) { |
||
| 1339 | tCollision_info* car_info; |
||
| 1340 | int wheel; |
||
| 1341 | LOG_TRACE("(%p, %f)", car, dt); |
||
| 1342 | |||
| 1343 | if (car->dt >= 0.f) { |
||
| 1344 | dt = car->dt; |
||
| 1345 | } |
||
| 1346 | if (dt != 0.f && (!gCar_flying || &gProgram_state.current_car != car)) { |
||
| 1347 | car_info = (tCollision_info*)car; |
||
| 1348 | car->new_skidding = 0; |
||
| 1349 | if (car->water_d != 10000.0f) { |
||
| 1350 | TestAutoSpecialVolume(car_info); |
||
| 1351 | } |
||
| 1352 | MungeSpecialVolume(car_info); |
||
| 1353 | if (car->driver <= eDriver_oppo) { |
||
| 1354 | CalcForce(car, dt); |
||
| 1355 | } else { |
||
| 1356 | CalcEngineForce(car, dt); |
||
| 1357 | CalcForce(car, dt); |
||
| 1358 | DoRevs(car, dt); |
||
| 1359 | } |
||
| 1360 | RotateCar(car_info, dt); |
||
| 1361 | TranslateCar(car_info, dt); |
||
| 1362 | CollideCarWithWall(car_info, dt); |
||
| 1363 | BrMatrix34ApplyP(&car->pos, &car->cmpos, &car->car_master_actor->t.t.mat); |
||
| 1364 | BrVector3InvScale(&car->pos, &car->pos, WORLD_SCALE); |
||
| 1365 | for (wheel = 0; wheel < 4; wheel++) { |
||
| 1366 | SkidMark(car, wheel); |
||
| 1367 | } |
||
| 1368 | } |
||
| 1369 | } |
||
| 1370 | |||
| 1371 | // IDA: void __usercall MoveAndCollideNonCar(tNon_car_spec *non_car@<EAX>, br_scalar dt) |
||
| 1372 | void MoveAndCollideNonCar(tNon_car_spec* non_car, br_scalar dt) { |
||
| 1373 | tCollision_info* car_info; |
||
| 1374 | LOG_TRACE("(%p, %f)", non_car, dt); |
||
| 1375 | |||
| 1376 | car_info = &non_car->collision_info; |
||
| 1377 | if (car_info->water_d != 10000.f) { |
||
| 1378 | TestAutoSpecialVolume(&non_car->collision_info); |
||
| 1379 | } |
||
| 1380 | MungeSpecialVolume(&non_car->collision_info); |
||
| 1381 | if (car_info->dt >= 0.f) { |
||
| 1382 | dt = car_info->dt; |
||
| 1383 | } |
||
| 1384 | NonCarCalcForce(non_car, dt); |
||
| 1385 | RotateCar(&non_car->collision_info, dt); |
||
| 1386 | TranslateCar(&non_car->collision_info, dt); |
||
| 1387 | CollideCarWithWall(&non_car->collision_info, dt); |
||
| 1388 | BrMatrix34ApplyP(&car_info->pos, &car_info->cmpos, &car_info->car_master_actor->t.t.mat); |
||
| 1389 | BrVector3InvScale(&car_info->pos, &car_info->pos, WORLD_SCALE); |
||
| 1390 | } |
||
| 1391 | |||
| 1392 | // IDA: int __usercall CollideCarWithWall@<EAX>(tCollision_info *car@<EAX>, br_scalar dt) |
||
| 1393 | int CollideCarWithWall(tCollision_info* car, br_scalar dt) { |
||
| 1394 | LOG_TRACE("(%p, %f)", car, dt); |
||
| 1395 | |||
| 1396 | GetFacesInBox(car); |
||
| 1397 | if (gCollision_detection_on__car) { |
||
| 1398 | car->collision_flag = 0; |
||
| 1399 | while (CollCheck(car, dt)) { |
||
| 1400 | car->collision_flag++; |
||
| 1401 | if (car->collision_flag - 1 > 20) { |
||
| 1402 | car->collision_flag = 1; |
||
| 1403 | BrVector3Set(&car->v, 0.f, 0.f, 0.f); |
||
| 1404 | BrVector3Set(&car->omega, 0.f, 0.f, 0.f); |
||
| 1405 | break; |
||
| 1406 | } |
||
| 1407 | RotateCar(car, dt); |
||
| 1408 | TranslateCar(car, dt); |
||
| 1409 | GetFacesInBox(car); |
||
| 1410 | } |
||
| 1411 | if (car->collision_flag) { |
||
| 1412 | CrashEarnings(CAR(car), NULL); |
||
| 1413 | } |
||
| 1414 | BrMatrix34TApplyV(&car->velocity_car_space, &car->v, &car->oldmat); |
||
| 1415 | car->frame_collision_flag += car->collision_flag; |
||
| 1416 | } |
||
| 1417 | return car->collision_flag; |
||
| 1418 | } |
||
| 1419 | |||
| 1420 | // IDA: void __cdecl ToggleControls() |
||
| 1421 | void ToggleControls(void) { |
||
| 1422 | LOG_TRACE("()"); |
||
| 1423 | |||
| 1424 | gControl__car++; |
||
| 20 | pmbaty | 1425 | if (ControlCar[gControl__car] == 0) { |
| 1 | pmbaty | 1426 | gControl__car = 0; |
| 1427 | } |
||
| 1428 | switch (gControl__car) { |
||
| 1429 | case 0: |
||
| 21 | pmbaty | 1430 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 500, -1, "Original Controls"); |
| 1 | pmbaty | 1431 | break; |
| 1432 | case 1: |
||
| 21 | pmbaty | 1433 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 500, -1, "Accelerated steering"); |
| 1 | pmbaty | 1434 | break; |
| 1435 | case 2: |
||
| 21 | pmbaty | 1436 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 500, -1, "0.75 Accelerated"); |
| 1 | pmbaty | 1437 | break; |
| 1438 | case 3: |
||
| 21 | pmbaty | 1439 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 500, -1, "0.5 Accelerated"); |
| 1 | pmbaty | 1440 | break; |
| 1441 | default: |
||
| 21 | pmbaty | 1442 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 500, -1, "New controls"); |
| 1 | pmbaty | 1443 | break; |
| 1444 | } |
||
| 1445 | } |
||
| 1446 | |||
| 1447 | // IDA: void __usercall ControlCar2(tCar_spec *c@<EAX>, br_scalar dt) |
||
| 1448 | void ControlCar2(tCar_spec* c, br_scalar dt) { |
||
| 1449 | LOG_TRACE("(%p, %f)", c, dt); |
||
| 20 | pmbaty | 1450 | NOT_IMPLEMENTED(); |
| 1 | pmbaty | 1451 | } |
| 1452 | |||
| 1453 | // IDA: void __usercall ControlCar3(tCar_spec *c@<EAX>, br_scalar dt) |
||
| 1454 | void ControlCar3(tCar_spec* c, br_scalar dt) { |
||
| 1455 | LOG_TRACE("(%p, %f)", c, dt); |
||
| 20 | pmbaty | 1456 | NOT_IMPLEMENTED(); |
| 1 | pmbaty | 1457 | } |
| 1458 | |||
| 1459 | // IDA: void __usercall ControlCar4(tCar_spec *c@<EAX>, br_scalar dt) |
||
| 1460 | void ControlCar4(tCar_spec* c, br_scalar dt) { |
||
| 1461 | //br_scalar ts; // Pierre-Marie Baty -- unused variable |
||
| 1462 | LOG_TRACE("(%p, %f)", c, dt); |
||
| 1463 | |||
| 1464 | if (c->keys.left) { |
||
| 1465 | if (c->turn_speed < 0.f) { |
||
| 1466 | c->turn_speed = 0.f; |
||
| 1467 | } |
||
| 1468 | if (c->velocity_car_space.v[2] > 0.f) { |
||
| 1469 | c->turn_speed += dt * 0.01f / .04f / 2.f * 2.f; |
||
| 1470 | } else if ((c->curvature >= 0.f && c->omega.v[1] >= -.001f) || c->turn_speed != 0.f) { |
||
| 1471 | c->turn_speed += dt / .04f * (0.05f / (BrVector3Length(&c->v) + 5.f)) / 2.f * .5f; |
||
| 1472 | } else { |
||
| 1473 | c->turn_speed = dt / .04f * (.05f / (BrVector3Length(&c->v) + 5.f)) * 4.f / 2.f * .5f; |
||
| 1474 | if (c->omega.v[1] < -.01f) { |
||
| 1475 | c->turn_speed -= dt * .01f / (harness_game_config.physics_step_time / 1000.f) / 2.f * c->omega.v[1] * 2.f; |
||
| 1476 | } |
||
| 1477 | } |
||
| 1478 | } |
||
| 1479 | if (c->keys.right) { |
||
| 1480 | if (c->turn_speed > 0.f) { |
||
| 1481 | c->turn_speed = 0.f; |
||
| 1482 | } |
||
| 1483 | if (c->velocity_car_space.v[2] > 0.f) { |
||
| 1484 | c->turn_speed -= dt * .01f / .04f / 2.f * 2.f; |
||
| 1485 | } else if ((c->curvature <= 0.f && c->omega.v[1] <= .001f) || c->turn_speed != 0.f) { |
||
| 1486 | c->turn_speed -= dt / .04f * (.05f / (BrVector3Length(&c->v) + 5.f)) / 2.f * .5f; |
||
| 1487 | } else { |
||
| 1488 | c->turn_speed = dt / .04f * (.05f / (BrVector3Length(&c->v) + 5.f)) * -4.f / 2.f * .5f; |
||
| 1489 | if (c->omega.v[1] < -.01f) { |
||
| 1490 | c->turn_speed -= dt * .01f / (harness_game_config.physics_step_time / 1000.f) / 2.f * c->omega.v[1] * 2.f; |
||
| 1491 | } |
||
| 1492 | } |
||
| 1493 | } |
||
| 1494 | if (!c->keys.left && !c->keys.right) { |
||
| 1495 | c->turn_speed = 0.f; |
||
| 1496 | } else if (fabsf(c->turn_speed) < fabsf(dt * 2.f * c->curvature) && c->curvature * c->turn_speed < 0.f) { |
||
| 1497 | c->turn_speed = -(dt * 2.f * c->curvature); |
||
| 1498 | } |
||
| 1499 | c->curvature += c->turn_speed; |
||
| 1500 | if (c->joystick.left > 0) { |
||
| 1501 | c->curvature = (float)c->joystick.left * (float)c->joystick.left / 4294967300.f * c->maxcurve; |
||
| 1502 | } else if (c->joystick.right >= 0) { |
||
| 1503 | c->curvature = -((float)c->joystick.right * (float)c->joystick.right / 4294967300.f) * c->maxcurve; |
||
| 1504 | } |
||
| 1505 | if (c->curvature > c->maxcurve) { |
||
| 1506 | c->curvature = c->maxcurve; |
||
| 1507 | } |
||
| 1508 | if (c->curvature < -c->maxcurve) { |
||
| 1509 | c->curvature = -c->maxcurve; |
||
| 1510 | } |
||
| 1511 | } |
||
| 1512 | |||
| 1513 | // IDA: void __usercall ControlCar5(tCar_spec *c@<EAX>, br_scalar dt) |
||
| 1514 | void ControlCar5(tCar_spec* c, br_scalar dt) { |
||
| 1515 | LOG_TRACE("(%p, %f)", c, dt); |
||
| 20 | pmbaty | 1516 | NOT_IMPLEMENTED(); |
| 1 | pmbaty | 1517 | } |
| 1518 | |||
| 1519 | // IDA: void __usercall ControlCar1(tCar_spec *c@<EAX>, br_scalar dt) |
||
| 1520 | void ControlCar1(tCar_spec* c, br_scalar dt) { |
||
| 1521 | LOG_TRACE("(%p, %f)", c, dt); |
||
| 20 | pmbaty | 1522 | NOT_IMPLEMENTED(); |
| 1 | pmbaty | 1523 | } |
| 1524 | |||
| 1525 | // IDA: void __usercall setrotate(br_vector3 *wdt@<EAX>, br_matrix34 *m@<EDX>) |
||
| 1526 | void setrotate(br_vector3* wdt, br_matrix34* m) { |
||
| 20 | pmbaty | 1527 | //br_euler e; // Pierre-Marie Baty -- unused variable |
| 1 | pmbaty | 1528 | LOG_TRACE("(%p, %p)", wdt, m); |
| 20 | pmbaty | 1529 | NOT_IMPLEMENTED(); |
| 1 | pmbaty | 1530 | } |
| 1531 | |||
| 1532 | // IDA: void __usercall RotateCar2(tCollision_info *c@<EAX>, br_scalar dt) |
||
| 1533 | void RotateCar2(tCollision_info* c, br_scalar dt) { |
||
| 20 | pmbaty | 1534 | //br_vector3 wdt; // Pierre-Marie Baty -- unused variable |
| 1535 | //br_vector3 wdt2; // Pierre-Marie Baty -- unused variable |
||
| 1536 | //br_vector3 L; // Pierre-Marie Baty -- unused variable |
||
| 1537 | //br_vector3 L2; // Pierre-Marie Baty -- unused variable |
||
| 1538 | //br_matrix34 m; // Pierre-Marie Baty -- unused variable |
||
| 1 | pmbaty | 1539 | LOG_TRACE("(%p, %f)", c, dt); |
| 20 | pmbaty | 1540 | NOT_IMPLEMENTED(); |
| 1 | pmbaty | 1541 | } |
| 1542 | |||
| 1543 | // IDA: void __usercall RotateCarSecondOrder(tCollision_info *c@<EAX>, br_scalar dt) |
||
| 1544 | void RotateCarSecondOrder(tCollision_info* c, br_scalar dt) { |
||
| 1545 | br_vector3 L; |
||
| 1546 | br_vector3 L2; |
||
| 1547 | br_vector3 axis; |
||
| 1548 | br_vector3 omega; |
||
| 1549 | br_scalar rad; |
||
| 1550 | br_scalar rad_rate; |
||
| 1551 | br_matrix34 m; |
||
| 1552 | LOG_TRACE("(%p, %f)", c, dt); |
||
| 1553 | |||
| 1554 | rad_rate = BrVector3Length(&c->omega); |
||
| 1555 | rad = rad_rate * dt; |
||
| 1556 | |||
| 1557 | BrVector3InvScale(&axis, &c->omega, rad_rate); |
||
| 1558 | BrVector3Mul(&L, &c->I, &c->omega); |
||
| 1559 | |||
| 1560 | BrMatrix34Rotate(&m, BrRadianToAngle(rad) / 2, &axis); |
||
| 1561 | BrMatrix34TApplyV(&L2, &L, &m); |
||
| 1562 | omega.v[0] = L2.v[0] / c->I.v[0]; |
||
| 1563 | omega.v[1] = L2.v[1] / c->I.v[1]; |
||
| 1564 | omega.v[2] = L2.v[2] / c->I.v[2]; |
||
| 1565 | |||
| 1566 | rad_rate = BrVector3Length(&omega); |
||
| 1567 | rad = rad_rate * dt; |
||
| 1568 | |||
| 1569 | BrVector3InvScale(&axis, &omega, rad_rate); |
||
| 1570 | BrMatrix34Rotate(&m, BrRadianToAngle(rad), &axis); |
||
| 1571 | BrMatrix34PreTranslate(&m, -c->cmpos.v[0], -c->cmpos.v[1], -c->cmpos.v[2]); |
||
| 1572 | BrMatrix34PostTranslate(&m, c->cmpos.v[0], c->cmpos.v[1], c->cmpos.v[2]); |
||
| 1573 | BrMatrix34Pre(&c->car_master_actor->t.t.mat, &m); |
||
| 1574 | BrMatrix34TApplyV(&L2, &L, &m); |
||
| 1575 | c->omega.v[0] = L2.v[0] / c->I.v[0]; |
||
| 1576 | c->omega.v[1] = L2.v[1] / c->I.v[1]; |
||
| 1577 | c->omega.v[2] = L2.v[2] / c->I.v[2]; |
||
| 1578 | } |
||
| 1579 | |||
| 1580 | // IDA: void __usercall RotateCarFirstOrder(tCollision_info *c@<EAX>, br_scalar dt) |
||
| 1581 | void RotateCarFirstOrder(tCollision_info* c, br_scalar dt) { |
||
| 1582 | br_vector3 axis; |
||
| 1583 | br_vector3 L; |
||
| 1584 | br_vector3 L2; |
||
| 1585 | br_matrix34 m; |
||
| 1586 | br_scalar rad_rate; |
||
| 1587 | br_scalar rad; |
||
| 1588 | //br_scalar e1; // Pierre-Marie Baty -- unused variable |
||
| 1589 | //br_scalar e2; // Pierre-Marie Baty -- unused variable |
||
| 1590 | static br_scalar max_rad; |
||
| 1591 | LOG_TRACE("(%p, %f)", c, dt); |
||
| 1592 | |||
| 1593 | rad_rate = BrVector3Length(&c->omega); |
||
| 1594 | rad = rad_rate * dt; |
||
| 1595 | |||
| 1596 | if (rad < .0001f) { |
||
| 1597 | return; |
||
| 1598 | } |
||
| 1599 | BrVector3InvScale(&axis, &c->omega, rad_rate); |
||
| 1600 | BrVector3Mul(&L, &c->I, &c->omega); |
||
| 1601 | BrMatrix34Rotate(&m, BrRadianToAngle(rad), &axis); |
||
| 1602 | BrMatrix34TApplyV(&L2, &L, &m); |
||
| 1603 | BrMatrix34PreTranslate(&m, -c->cmpos.v[0], -c->cmpos.v[1], -c->cmpos.v[2]); |
||
| 1604 | BrMatrix34PostTranslate(&m, c->cmpos.v[0], c->cmpos.v[1], c->cmpos.v[2]); |
||
| 1605 | BrMatrix34Pre(&c->car_master_actor->t.t.mat, &m); |
||
| 1606 | c->omega.v[0] = L2.v[0] / c->I.v[0]; |
||
| 1607 | c->omega.v[1] = L2.v[1] / c->I.v[1]; |
||
| 1608 | c->omega.v[2] = L2.v[2] / c->I.v[2]; |
||
| 1609 | } |
||
| 1610 | |||
| 1611 | // IDA: void __usercall SimpleRotate(tCollision_info *c@<EAX>, br_scalar dt) |
||
| 1612 | void SimpleRotate(tCollision_info* c, br_scalar dt) { |
||
| 1613 | br_vector3 axis; |
||
| 1614 | br_scalar rad_rate; |
||
| 1615 | br_scalar rad; |
||
| 1616 | LOG_TRACE("(%p, %f)", c, dt); |
||
| 1617 | |||
| 1618 | rad_rate = BrVector3Length(&c->omega); |
||
| 1619 | BrVector3InvScale(&axis, &c->omega, rad_rate); |
||
| 1620 | rad = rad_rate * dt; |
||
| 1621 | if (rad >= 0.0001) { |
||
| 1622 | BrMatrix34PreRotate(&c->car_master_actor->t.t.mat, BrRadianToAngle(rad), &axis); |
||
| 1623 | } |
||
| 1624 | } |
||
| 1625 | |||
| 1626 | // IDA: void __usercall RotateCar(tCollision_info *c@<EAX>, br_scalar dt) |
||
| 1627 | void RotateCar(tCollision_info* c, br_scalar dt) { |
||
| 1628 | br_scalar rad_squared; |
||
| 1629 | int steps; |
||
| 1630 | int i; |
||
| 1631 | LOG_TRACE("(%p, %f)", c, dt); |
||
| 1632 | |||
| 1633 | rad_squared = BrVector3LengthSquared(&c->omega) * dt; |
||
| 1634 | BrVector3Copy(&c->oldomega, &c->omega); |
||
| 1635 | |||
| 1636 | if (rad_squared < .0000001f) { |
||
| 1637 | return; |
||
| 1638 | } |
||
| 1639 | |||
| 1640 | if (rad_squared > .008f) { |
||
| 1641 | steps = sqrtf(rad_squared / .032f) + 1; |
||
| 1642 | dt = dt / steps; |
||
| 1643 | |||
| 1644 | for (i = 0; i < steps && i < 20; i++) { |
||
| 1645 | RotateCarSecondOrder(c, dt); |
||
| 1646 | } |
||
| 1647 | } else { |
||
| 1648 | RotateCarFirstOrder(c, dt); |
||
| 1649 | } |
||
| 1650 | } |
||
| 1651 | |||
| 1652 | // IDA: void __usercall SteeringSelfCentre(tCar_spec *c@<EAX>, br_scalar dt, br_vector3 *n) |
||
| 1653 | void SteeringSelfCentre(tCar_spec* c, br_scalar dt, br_vector3* n) { |
||
| 1654 | br_scalar ts; |
||
| 1655 | br_scalar ts2; |
||
| 1656 | LOG_TRACE("(%p, %f, %p)", c, dt, n); |
||
| 1657 | |||
| 1658 | if (c->curvature > c->maxcurve) { |
||
| 1659 | c->curvature = c->maxcurve; |
||
| 1660 | } |
||
| 1661 | if (-c->maxcurve > c->curvature) { |
||
| 1662 | c->curvature = -c->maxcurve; |
||
| 1663 | } |
||
| 1664 | if (!c->keys.left && c->joystick.left <= 0 && !c->keys.right && c->joystick.right <= 0 && !c->keys.holdw) { |
||
| 1665 | if (c->susp_height[1] > c->oldd[2] || c->susp_height[1] > c->oldd[3]) { |
||
| 1666 | ts = -((c->omega.v[2] * n->v[2] + c->omega.v[1] * n->v[1] + c->omega.v[0] * n->v[0]) * (dt / (c->wpos[0].v[2] - c->wpos[2].v[2]))); |
||
| 1667 | ts2 = -(c->curvature * dt); |
||
| 1668 | if (fabs(ts) < fabs(ts2) || (ts * ts2 < 0.0)) { |
||
| 1669 | ts = ts2; |
||
| 1670 | } |
||
| 1671 | c->curvature = c->curvature + ts; |
||
| 1672 | if (c->curvature * ts > 0.0) { |
||
| 1673 | c->curvature = 0.0; |
||
| 1674 | } |
||
| 1675 | } |
||
| 1676 | } |
||
| 1677 | } |
||
| 1678 | |||
| 1679 | // IDA: void __usercall NonCarCalcForce(tNon_car_spec *nc@<EAX>, br_scalar dt) |
||
| 1680 | void NonCarCalcForce(tNon_car_spec* nc, br_scalar dt) { |
||
| 1681 | tCollision_info* c; |
||
| 1682 | tSpecial_volume* vol; |
||
| 1683 | br_scalar ts; |
||
| 1684 | br_vector3 tv; |
||
| 1685 | br_vector3 v; |
||
| 1686 | LOG_TRACE("(%p, %f)", nc, dt); |
||
| 1687 | |||
| 1688 | c = &nc->collision_info; |
||
| 1689 | vol = nc->collision_info.last_special_volume; |
||
| 1690 | if (nc->collision_info.car_master_actor->identifier[3] != '!') { |
||
| 1691 | if (c->car_master_actor->t.t.mat.m[1][1] < nc->snap_off_cosine || c->min_torque_squared == 0.0f) { |
||
| 1692 | c->car_master_actor->identifier[3] = '!'; |
||
| 1693 | c->M = nc->free_mass; |
||
| 1694 | c->min_torque_squared = 0.0f; |
||
| 1695 | BrVector3Sub(&v, &nc->free_cmpos, &c->cmpos); |
||
| 1696 | BrVector3Cross(&tv, &c->omega, &v); |
||
| 1697 | BrMatrix34ApplyV(&v, &tv, &c->car_master_actor->t.t.mat); |
||
| 1698 | BrVector3Accumulate(&c->v, &v); |
||
| 1699 | c->cmpos = nc->free_cmpos; |
||
| 1700 | } else { |
||
| 1701 | BrVector3SetFloat(&c->v, 0.0f, 0.0f, 0.0f); |
||
| 1702 | ts = BrVector3LengthSquared(&c->omega); |
||
| 1703 | BrVector3SetFloat(&c->omega, 0.0f, 0.0f, 0.0f); |
||
| 1704 | c->doing_nothing_flag = 1; |
||
| 1705 | } |
||
| 1706 | } |
||
| 1707 | if (c->car_master_actor->identifier[3] == '!') { |
||
| 1708 | if (vol != NULL) { |
||
| 1709 | c->v.v[1] = c->v.v[1] - dt * 10.0f * vol->gravity_multiplier; |
||
| 1710 | } else { |
||
| 1711 | c->v.v[1] = c->v.v[1] - dt * 10.0f; |
||
| 1712 | } |
||
| 1713 | ts = BrVector3Length(&c->v); |
||
| 1714 | if (vol != NULL) { |
||
| 1715 | ts = vol->viscosity_multiplier * ts; |
||
| 1716 | } |
||
| 1717 | ts = -(dt * 0.0005f * ts) / c->M; |
||
| 1718 | BrVector3Scale(&v, &c->v, ts); |
||
| 1719 | BrVector3Accumulate(&c->v, &v); |
||
| 1720 | ts = BrVector3Length(&c->omega); |
||
| 1721 | if (vol != NULL) { |
||
| 1722 | ts = vol->viscosity_multiplier * ts; |
||
| 1723 | } |
||
| 1724 | ts = -(dt * 0.0005 * ts); |
||
| 1725 | BrVector3Scale(&v, &c->omega, ts); |
||
| 1726 | ApplyTorque(CAR(c), &v); |
||
| 1727 | } |
||
| 1728 | } |
||
| 1729 | |||
| 1730 | // IDA: void __usercall AddDrag(tCar_spec *c@<EAX>, br_scalar dt) |
||
| 1731 | void AddDrag(tCar_spec* c, br_scalar dt) { |
||
| 1732 | br_scalar drag_multiplier; |
||
| 1733 | br_scalar ts; |
||
| 1734 | tSpecial_volume* vol; |
||
| 1735 | br_vector3 b; |
||
| 1736 | LOG_TRACE("(%p, %f)", c, dt); |
||
| 1737 | |||
| 1738 | vol = c->last_special_volume; |
||
| 1739 | drag_multiplier = -(dt * TIME_CONV_THING); |
||
| 1740 | if (vol != NULL) { |
||
| 1741 | if (c->underwater_ability) { |
||
| 1742 | drag_multiplier = vol->viscosity_multiplier * drag_multiplier * .6f; |
||
| 1743 | } else { |
||
| 1744 | drag_multiplier = vol->viscosity_multiplier * drag_multiplier; |
||
| 1745 | } |
||
| 1746 | drag_multiplier = c->water_depth_factor * drag_multiplier; |
||
| 1747 | } |
||
| 1748 | ts = BrVector3Length(&c->v) * drag_multiplier / c->M; |
||
| 1749 | BrVector3Scale(&b, &c->v, ts); |
||
| 1750 | BrVector3Accumulate(&c->v, &b); |
||
| 1751 | ts = BrVector3Length(&c->omega) * drag_multiplier; |
||
| 1752 | BrVector3Scale(&b, &c->omega, ts); |
||
| 1753 | ApplyTorque(c, &b); |
||
| 1754 | } |
||
| 1755 | |||
| 1756 | // IDA: void __usercall DoBumpiness(tCar_spec *c@<EAX>, br_vector3 *wheel_pos@<EDX>, br_vector3 *norm@<EBX>, br_scalar *d@<ECX>, int n) |
||
| 1757 | void DoBumpiness(tCar_spec* c, br_vector3* wheel_pos, br_vector3* norm, br_scalar* d, int n) { |
||
| 1758 | br_vector3 tv; |
||
| 1759 | int delta; |
||
| 1760 | int x; |
||
| 1761 | int y; |
||
| 1762 | tMaterial_modifiers* mat_list; |
||
| 1763 | LOG_TRACE("(%p, %p, %p, %p, %d)", c, wheel_pos, norm, d, n); |
||
| 1764 | |||
| 1765 | tv.v[0] = c->nor[n].v[0] * d[n] + wheel_pos[n].v[0]; |
||
| 1766 | tv.v[2] = c->nor[n].v[2] * d[n] + wheel_pos[n].v[2]; |
||
| 1767 | |||
| 1768 | x = abs((int)(512.0f * tv.v[0])) % 2048; |
||
| 1769 | y = abs((int)(512.0f * tv.v[2])) % 2048; |
||
| 1770 | |||
| 1771 | if (x > 1024) { |
||
| 1772 | x = 2048 - x; |
||
| 1773 | } |
||
| 1774 | if (y > 1024) { |
||
| 1775 | y = 2048 - y; |
||
| 1776 | } |
||
| 1777 | if (x + y <= 1024) { |
||
| 1778 | delta = x + y; |
||
| 1779 | } else { |
||
| 1780 | delta = 2048 - x - y; |
||
| 1781 | } |
||
| 1782 | delta -= 400; |
||
| 1783 | if (delta < 0) { |
||
| 1784 | delta = 0; |
||
| 1785 | } |
||
| 1786 | mat_list = gCurrent_race.material_modifiers; |
||
| 1787 | d[n] = delta * mat_list[c->material_index[n]].bumpiness / 42400.0f * norm[n].v[1] + d[n]; |
||
| 1788 | } |
||
| 1789 | |||
| 1790 | // IDA: void __usercall CalcForce(tCar_spec *c@<EAX>, br_scalar dt) |
||
| 1791 | void CalcForce(tCar_spec* c, br_scalar dt) { |
||
| 1792 | //int n; // Pierre-Marie Baty -- unused variable |
||
| 1793 | int normnum; |
||
| 1794 | int i; |
||
| 1795 | //int x; // Pierre-Marie Baty -- unused variable |
||
| 1796 | //int y; // Pierre-Marie Baty -- unused variable |
||
| 1797 | br_scalar force[4]; |
||
| 1798 | br_scalar d[4]; |
||
| 1799 | br_scalar ts; |
||
| 1800 | br_scalar ts2; |
||
| 1801 | br_scalar ts3; |
||
| 1802 | br_scalar ts4; |
||
| 1803 | //br_scalar ts5; // Pierre-Marie Baty -- unused variable |
||
| 1804 | //br_scalar ts6; // Pierre-Marie Baty -- unused variable |
||
| 1805 | br_scalar deltaomega; |
||
| 1806 | br_scalar wheelratio; |
||
| 1807 | //br_scalar modf; // Pierre-Marie Baty -- unused variable |
||
| 1808 | br_scalar maxfl; |
||
| 1809 | br_scalar maxfr; |
||
| 1810 | //br_scalar max_retardation; // Pierre-Marie Baty -- unused variable |
||
| 1811 | //br_scalar front_retardation; // Pierre-Marie Baty -- unused variable |
||
| 1812 | br_scalar friction_number; |
||
| 1813 | br_vector3 a; |
||
| 1814 | br_vector3 b; |
||
| 1815 | //br_vector3 tv; // Pierre-Marie Baty -- unused variable |
||
| 1816 | //br_vector3 tv2; // Pierre-Marie Baty -- unused variable |
||
| 1817 | br_vector3 norm[4]; |
||
| 1818 | //br_vector3 v_batwick; // Pierre-Marie Baty -- unused variable |
||
| 1819 | br_vector3 vplane; |
||
| 1820 | br_vector3 rightplane; |
||
| 1821 | //br_vector3 t; // Pierre-Marie Baty -- unused variable |
||
| 1822 | br_vector3 f; |
||
| 1823 | //br_vector3 ff; // Pierre-Marie Baty -- unused variable |
||
| 1824 | //br_vector3 fb; // Pierre-Marie Baty -- unused variable |
||
| 1825 | //br_scalar ffi; // Pierre-Marie Baty -- unused variable |
||
| 1826 | //br_scalar ffk; // Pierre-Marie Baty -- unused variable |
||
| 1827 | //br_scalar fbi; // Pierre-Marie Baty -- unused variable |
||
| 1828 | //br_scalar fbk; // Pierre-Marie Baty -- unused variable |
||
| 1829 | br_vector3 wheel_pos[4]; |
||
| 1830 | //br_scalar direction; // Pierre-Marie Baty -- unused variable |
||
| 1831 | //br_scalar wheel_spin_force; // Pierre-Marie Baty -- unused variable |
||
| 1832 | //br_scalar d_damage; // Pierre-Marie Baty -- unused variable |
||
| 1833 | br_scalar fl_oil_factor; |
||
| 1834 | br_scalar fr_oil_factor; |
||
| 1835 | br_scalar rl_oil_factor; |
||
| 1836 | br_scalar rr_oil_factor; |
||
| 1837 | br_matrix34* mat; |
||
| 1838 | tMaterial_modifiers* mat_list; |
||
| 1839 | static br_scalar stop_timer; |
||
| 1840 | static br_scalar slide_dist; |
||
| 1841 | //tDamage_type dam; // Pierre-Marie Baty -- unused variable |
||
| 1842 | //br_scalar v; // Pierre-Marie Baty -- unused variable |
||
| 1843 | tSpecial_volume* vol; |
||
| 1844 | //br_scalar scale; // Pierre-Marie Baty -- unused variable |
||
| 1845 | LOG_TRACE("(%p, %f)", c, dt); |
||
| 1846 | |||
| 1847 | int v72; // [esp+24h] [ebp-1C8h] |
||
| 1848 | double v73; // [esp+2Ch] [ebp-1C0h] |
||
| 1849 | float v74; // [esp+34h] [ebp-1B8h] |
||
| 1850 | float v75; // [esp+38h] [ebp-1B4h] |
||
| 1851 | float v76; // [esp+3Ch] [ebp-1B0h] |
||
| 1852 | float v77; // [esp+40h] [ebp-1ACh] |
||
| 1853 | float v78; // [esp+44h] [ebp-1A8h] |
||
| 1854 | float v79; // [esp+48h] [ebp-1A4h] |
||
| 1855 | //float v80; // [esp+4Ch] [ebp-1A0h] MAPDST // Pierre-Marie Baty -- unused variable |
||
| 1856 | //float v82; // [esp+50h] [ebp-19Ch] MAPDST // Pierre-Marie Baty -- unused variable |
||
| 1857 | //float v84; // [esp+54h] [ebp-198h] // Pierre-Marie Baty -- unused variable |
||
| 1858 | //float v85; // [esp+58h] [ebp-194h] MAPDST // Pierre-Marie Baty -- unused variable |
||
| 1859 | float v87; // [esp+5Ch] [ebp-190h] MAPDST |
||
| 1860 | float v98; // [esp+88h] [ebp-164h] |
||
| 1861 | float v99; // [esp+8Ch] [ebp-160h] |
||
| 1862 | br_vector3 v102; // [esp+98h] [ebp-154h] |
||
| 1863 | br_vector3 v103; // [esp+A4h] [ebp-148h] |
||
| 1864 | int v105; // [esp+B8h] [ebp-134h] |
||
| 1865 | float v106; // [esp+C0h] [ebp-12Ch] |
||
| 1866 | br_vector3 v107; // [esp+C4h] [ebp-128h] |
||
| 1867 | float v108; // [esp+D0h] [ebp-11Ch] |
||
| 1868 | float v109; // [esp+D4h] [ebp-118h] |
||
| 1869 | float v116; // [esp+F8h] [ebp-F4h] |
||
| 1870 | br_vector3 B; // [esp+FCh] [ebp-F0h] BYREF |
||
| 1871 | br_scalar pV; // [esp+10Ch] [ebp-E0h] |
||
| 1872 | br_vector3 v123; // [esp+130h] [ebp-BCh] |
||
| 1873 | float v125; // [esp+16Ch] [ebp-80h] |
||
| 1874 | float v128; // [esp+18Ch] [ebp-60h] |
||
| 1875 | float v129; // [esp+190h] [ebp-5Ch] |
||
| 1876 | float v134; // [esp+1D8h] [ebp-14h] |
||
| 1877 | float v135; // [esp+1DCh] [ebp-10h] |
||
| 1878 | br_vector3 v136; // [esp+1E0h] [ebp-Ch] |
||
| 1879 | |||
| 1880 | BrVector3Set(&v136, 0, 0, 0); |
||
| 1881 | normnum = 0; |
||
| 1882 | BrVector3Set(&f, 0, 0, 0); |
||
| 1883 | BrVector3Set(&B, 0, 0, 0); |
||
| 1884 | mat = &c->car_master_actor->t.t.mat; |
||
| 1885 | mat_list = gCurrent_race.material_modifiers; |
||
| 1886 | vol = c->last_special_volume; |
||
| 1887 | b.v[0] = -mat->m[1][0]; |
||
| 1888 | b.v[1] = -mat->m[1][1]; |
||
| 1889 | b.v[2] = -mat->m[1][2]; |
||
| 1890 | c->material_index[0] = 0; |
||
| 1891 | c->material_index[1] = 0; |
||
| 1892 | c->material_index[2] = 0; |
||
| 1893 | c->material_index[3] = 0; |
||
| 1894 | wheelratio = (c->wpos[2].v[2] - c->cmpos.v[2]) / (c->wpos[0].v[2] - c->cmpos.v[2]); |
||
| 1895 | BrVector3Set(&c->road_normal, 0, 0, 0); |
||
| 1896 | for (i = 0; i < 4; ++i) { |
||
| 1897 | BrMatrix34ApplyP(&wheel_pos[i], &c->wpos[i], mat); |
||
| 1898 | } |
||
| 1899 | MultiFindFloorInBoxM(4, wheel_pos, &b, c->nor, d, c, c->material_index); |
||
| 1900 | if (c->last_special_volume && c->last_special_volume->material_modifier_index) { |
||
| 1901 | c->material_index[0] = c->last_special_volume->material_modifier_index; |
||
| 1902 | c->material_index[1] = c->material_index[0]; |
||
| 1903 | c->material_index[2] = c->material_index[1]; |
||
| 1904 | c->material_index[3] = c->material_index[2]; |
||
| 1905 | } |
||
| 1906 | for (i = 0; i < 4; ++i) { |
||
| 1907 | BrMatrix34TApplyV(&norm[i], &c->nor[i], mat); |
||
| 1908 | if (mat_list[c->material_index[i]].bumpiness != 0.0) { |
||
| 1909 | DoBumpiness(c, wheel_pos, norm, d, i); |
||
| 1910 | } |
||
| 1911 | if (d[i] < -0.5 || c->wheel_dam_offset[i ^ 2] * 6.9 + c->susp_height[i / 2] < d[i]) { |
||
| 1912 | force[i] = 0.0; |
||
| 1913 | d[i] = c->susp_height[i / 2]; |
||
| 1914 | } else { |
||
| 1915 | BrVector3Accumulate(&c->road_normal, &norm[i]); |
||
| 1916 | normnum++; |
||
| 1917 | d[i] = d[i] - c->wheel_dam_offset[i ^ 2] * 6.9; |
||
| 1918 | force[i] = (c->susp_height[i / 2] - d[i]) * c->sk[1 / 2]; |
||
| 1919 | force[i] = force[i] - (d[i] - c->oldd[i]) / dt * c->sb[i / 2]; |
||
| 1920 | if (c->susp_height[i / 2] == c->oldd[i] |
||
| 1921 | && c->nor[i].v[2] * c->v.v[2] + c->nor[i].v[1] * c->v.v[1] + c->nor[i].v[0] * c->v.v[0] > -0.0099999998 |
||
| 1922 | && c->M * 20.0 / 4.0 < force[i]) { |
||
| 1923 | d[i] = c->susp_height[i / 2]; |
||
| 1924 | force[i] = c->M * 20.0 / 4.0; |
||
| 1925 | } |
||
| 1926 | if (force[i] < 0.0) { |
||
| 1927 | force[i] = 0.0; |
||
| 1928 | } |
||
| 1929 | B.v[1] = force[i] + B.v[1]; |
||
| 1930 | f.v[0] = f.v[0] - (c->wpos[i].v[2] - c->cmpos.v[2]) * force[i]; |
||
| 1931 | f.v[2] = (c->wpos[i].v[0] - c->cmpos.v[0]) * force[i] + f.v[2]; |
||
| 1932 | } |
||
| 1933 | c->oldd[i] = d[i]; |
||
| 1934 | } |
||
| 1935 | if (c->driver <= eDriver_non_car || !c->wall_climber_mode || (c->road_normal.v[0] == 0.0 && c->road_normal.v[1] == 0.0 && c->road_normal.v[2] == 0.0)) { |
||
| 1936 | if (vol) { |
||
| 1937 | friction_number = (1.0 - vol->gravity_multiplier) * c->water_depth_factor; |
||
| 1938 | if (c->underwater_ability) { |
||
| 1939 | friction_number = friction_number * 0.6; |
||
| 1940 | } |
||
| 1941 | friction_number = (1.0 - friction_number) * c->M; |
||
| 1942 | } else { |
||
| 1943 | friction_number = c->M; |
||
| 1944 | } |
||
| 1945 | friction_number = friction_number * gGravity_multiplier * 10.0; |
||
| 1946 | B.v[0] = B.v[0] - mat->m[0][1] * friction_number; |
||
| 1947 | B.v[1] = B.v[1] - mat->m[1][1] * friction_number; |
||
| 1948 | B.v[2] = B.v[2] - mat->m[2][1] * friction_number; |
||
| 1949 | } else { |
||
| 1950 | BrVector3Normalise(&v107, &c->road_normal); |
||
| 1951 | BrVector3Scale(&v107, &v107, -(c->M * 10.0)); |
||
| 1952 | BrVector3Accumulate(&B, &v107); |
||
| 1953 | } |
||
| 1954 | if (c->driver >= eDriver_net_human) { |
||
| 1955 | SteeringSelfCentre(c, dt, &c->road_normal); |
||
| 1956 | } |
||
| 1957 | if (normnum) { |
||
| 1958 | // ts = 1.0 / sqrt(1.0); <- looked like this in the windows build definitely wrong |
||
| 1959 | // ts = 1.0 / sqrt(c->road_normal.v[0] * c->road_normal.v[0] + c->road_normal.v[1] * c->road_normal.v[1] + c->road_normal.v[2] * c->road_normal.v[2]); |
||
| 1960 | // c->road_normal.v[0] = c->road_normal.v[0] * ts; |
||
| 1961 | // c->road_normal.v[1] = c->road_normal.v[1] * ts; |
||
| 1962 | // c->road_normal.v[2] = c->road_normal.v[2] * ts; |
||
| 1963 | BrVector3NormaliseQuick(&c->road_normal, &c->road_normal); |
||
| 1964 | |||
| 1965 | friction_number = c->road_normal.v[1] * mat->m[1][1] + c->road_normal.v[2] * mat->m[2][1] + c->road_normal.v[0] * mat->m[0][1]; |
||
| 1966 | if (c->driver > eDriver_non_car && c->wall_climber_mode) { |
||
| 1967 | friction_number = 1.0; |
||
| 1968 | } |
||
| 1969 | friction_number = gCurrent_race.material_modifiers[c->material_index[0]].down_force * friction_number; |
||
| 1970 | if (friction_number > 0.0f) { |
||
| 1971 | friction_number = fabs(c->velocity_car_space.v[2]) * c->M * 10.0 * friction_number / c->down_force_speed; |
||
| 1972 | if (c->M * 10.0 < friction_number) { |
||
| 1973 | friction_number = c->M * 10.0; |
||
| 1974 | } |
||
| 1975 | if (c->number_of_wheels_on_ground == 4 && c->oldd[2] == c->susp_height[1] && c->oldd[3] == c->susp_height[1]) { |
||
| 1976 | a.v[0] = c->wpos[2].v[2] * mat->m[2][0]; |
||
| 1977 | a.v[1] = c->wpos[2].v[2] * mat->m[2][1]; |
||
| 1978 | a.v[2] = c->wpos[2].v[2] * mat->m[2][2]; |
||
| 1979 | a.v[0] = mat->m[3][0] + a.v[0]; |
||
| 1980 | a.v[1] = mat->m[3][1] + a.v[1]; |
||
| 1981 | a.v[2] = mat->m[3][2] + a.v[2]; |
||
| 1982 | BrVector3Scale(&b, &b, (c->wpos[0].v[2] - c->wpos[2].v[2])); |
||
| 1983 | findfloor(&a, &b, norm, &ts2); |
||
| 1984 | if (ts2 > 1.0) { |
||
| 1985 | c->down_force_flag = 1; |
||
| 1986 | } |
||
| 1987 | } else if (c->down_force_flag && (c->oldd[2] < c->susp_height[1] || c->oldd[3] < c->susp_height[1])) { |
||
| 1988 | c->down_force_flag = 0; |
||
| 1989 | } |
||
| 1990 | if (c->down_force_flag) { |
||
| 1991 | friction_number = (c->wpos[2].v[2] - c->cmpos.v[2]) / (c->wpos[2].v[2] - c->wpos[0].v[2]) * friction_number; |
||
| 1992 | f.v[0] = (c->wpos[0].v[2] - c->cmpos.v[2]) * friction_number + f.v[0]; |
||
| 1993 | } |
||
| 1994 | B.v[1] = B.v[1] - friction_number; |
||
| 1995 | } |
||
| 1996 | vplane.v[0] = BrVector3Dot(&c->velocity_car_space, &c->road_normal) * c->road_normal.v[0]; |
||
| 1997 | vplane.v[1] = BrVector3Dot(&c->velocity_car_space, &c->road_normal) * c->road_normal.v[1]; |
||
| 1998 | vplane.v[2] = BrVector3Dot(&c->velocity_car_space, &c->road_normal) * c->road_normal.v[2]; |
||
| 1999 | BrVector3Sub(&vplane, &c->velocity_car_space, &vplane); |
||
| 2000 | if (vplane.v[2] < 0.0) { |
||
| 2001 | ts = 1.0; |
||
| 2002 | } else { |
||
| 2003 | ts = -1.0; |
||
| 2004 | } |
||
| 2005 | ts3 = BrVector3Length(&vplane); |
||
| 2006 | deltaomega = ts3 * c->curvature * ts; |
||
| 2007 | deltaomega = deltaomega - BrVector3Dot(&c->omega, &c->road_normal); |
||
| 2008 | BrVector3Set(&v103, c->road_normal.v[1], -c->road_normal.v[0], 0); |
||
| 2009 | BrVector3Normalise(&v103, &v103); |
||
| 2010 | |||
| 2011 | friction_number = c->I.v[1] / dt * deltaomega; |
||
| 2012 | ts = friction_number / (c->wpos[2].v[2] - c->wpos[0].v[2]); |
||
| 2013 | v108 = ts; |
||
| 2014 | v109 = -ts; |
||
| 2015 | BrVector3Set(&rightplane, 0, c->road_normal.v[2], -c->road_normal.v[1]); |
||
| 2016 | BrVector3Normalise(&rightplane, &rightplane); |
||
| 2017 | v99 = c->acc_force; |
||
| 2018 | friction_number = BrVector3Dot(&rightplane, &vplane); |
||
| 2019 | v87 = BrVector3Dot(&v103, &vplane); |
||
| 2020 | ts2 = fabs(v87); |
||
| 2021 | friction_number = (c->wpos[0].v[2] - c->cmpos.v[2]) * friction_number * fabs(c->curvature); |
||
| 2022 | if (c->curvature <= 0.0) { |
||
| 2023 | friction_number = v87 - friction_number; |
||
| 2024 | } else { |
||
| 2025 | friction_number = v87 + friction_number; |
||
| 2026 | } |
||
| 2027 | friction_number = -(c->M / dt * friction_number); |
||
| 2028 | friction_number = friction_number - BrVector3Dot(&B, &v103); |
||
| 2029 | |||
| 2030 | friction_number = friction_number / (1.0 - wheelratio); |
||
| 2031 | v108 = friction_number + v108; |
||
| 2032 | v109 = -wheelratio * friction_number + v109; |
||
| 2033 | friction_number = (c->wpos[0].v[2] - c->wpos[2].v[2]) * v108; |
||
| 2034 | v98 = friction_number * c->curvature; |
||
| 2035 | friction_number = BrVector3Dot(&c->velocity_car_space, &rightplane) * c->M / dt; |
||
| 2036 | v129 = BrVector3Dot(&rightplane, &B) + friction_number; |
||
| 2037 | v128 = c->mu[0] * c->brake_force / (c->mu[1] / c->friction_elipticity + c->mu[0]); |
||
| 2038 | v125 = c->brake_force - v128; |
||
| 2039 | v105 = (c->damage_units[7].damage_level + c->damage_units[6].damage_level) / 2; |
||
| 2040 | if (v105 > 20) { |
||
| 2041 | v128 = (1.0 - (double)(v105 - 20) / 80.0) * (1.0 - (double)(v105 - 20) / 80.0) * v128; |
||
| 2042 | } |
||
| 2043 | v105 = (c->damage_units[5].damage_level + c->damage_units[4].damage_level) / 2; |
||
| 2044 | if (v105 > 20) { |
||
| 2045 | v125 = (1.0 - (double)(v105 - 20) / 80.0) * (1.0 - (double)(v105 - 20) / 80.0) * v125; |
||
| 2046 | } |
||
| 2047 | ts2 = (force[1] + force[0]) * c->rolling_r_back + v128; |
||
| 2048 | v87 = (force[2] + force[3]) * c->rolling_r_front + v125; |
||
| 2049 | v128 = c->wpos[0].v[2] - c->wpos[2].v[2]; |
||
| 2050 | v128 = sqrt(v128 * v128 * c->curvature * c->curvature + 1.0); |
||
| 2051 | v106 = v87 / v128; |
||
| 2052 | v134 = v106 + ts2; |
||
| 2053 | if (fabs(v129) < fabs(v134)) { |
||
| 2054 | ts2 = v129 / v134 * ts2; |
||
| 2055 | v106 = v129 / v134 * v106; |
||
| 2056 | } |
||
| 2057 | if ((v87 + ts2) * v129 < 0.0) { |
||
| 2058 | ts2 = -ts2; |
||
| 2059 | v106 = -v106; |
||
| 2060 | } |
||
| 2061 | v129 = v129 - (ts2 + v106); |
||
| 2062 | v99 = v99 - ts2; |
||
| 2063 | if (c->keys.brake && c->damage_units[eDamage_lr_brake].damage_level < 60 && c->damage_units[eDamage_rr_brake].damage_level < 60) { |
||
| 2064 | v99 = v99 - v129; |
||
| 2065 | c->gear = 0; |
||
| 2066 | } |
||
| 2067 | v99 = v99 / c->friction_elipticity; |
||
| 2068 | v135 = sqrt(v99 * v99 + v109 * v109) / 2.0; |
||
| 2069 | |||
| 2070 | GetOilFrictionFactors(c, &fl_oil_factor, &fr_oil_factor, &rl_oil_factor, &rr_oil_factor); |
||
| 2071 | if (c->driver <= eDriver_non_car) { |
||
| 2072 | v116 = 1.0; |
||
| 2073 | } else { |
||
| 2074 | v116 = c->grip_multiplier; |
||
| 2075 | } |
||
| 2076 | BrVector3Sub(&v102, &c->wpos[0], &c->cmpos); |
||
| 2077 | BrVector3Cross(&a, &c->omega, &v102); |
||
| 2078 | BrVector3Accumulate(&a, &c->velocity_car_space); |
||
| 2079 | if (c->driver >= eDriver_net_human |
||
| 2080 | && (((c->keys.left || c->joystick.left > 0x8000) && c->curvature > 0.0 && deltaomega > 0.1 && a.v[0] > 0.0) |
||
| 2081 | || ((c->keys.right || c->joystick.right > 0x8000) && c->curvature < 0.0 && deltaomega < 0.1 && a.v[0] < 0.0)) |
||
| 2082 | && ts > 0.0) { |
||
| 2083 | friction_number = c->mu[0]; |
||
| 2084 | } else { |
||
| 2085 | friction_number = c->mu[2]; |
||
| 2086 | ts2 = fabs(a.v[0]) / 10.0; |
||
| 2087 | if (ts2 > 1) { |
||
| 2088 | ts2 = 1.0; |
||
| 2089 | } |
||
| 2090 | friction_number = (c->mu[2] - c->mu[0]) * ts2 + friction_number; |
||
| 2091 | } |
||
| 2092 | |||
| 2093 | maxfl = sqrt(force[0]) * friction_number * (rl_oil_factor * v116) * mat_list[c->material_index[0]].tyre_road_friction; |
||
| 2094 | maxfr = sqrt(force[1]) * friction_number * (rr_oil_factor * v116) * mat_list[c->material_index[1]].tyre_road_friction; |
||
| 2095 | c->max_force_rear = maxfr + maxfl; |
||
| 2096 | if (rl_oil_factor == 1.0 && rr_oil_factor == 1.0 && c->traction_control && v135 * 2.0 > c->max_force_rear && c->acc_force > 0.0 |
||
| 2097 | && (c->driver < eDriver_net_human || (c->target_revs > 1000.0 && c->gear > 0))) { |
||
| 2098 | ts2 = v99; |
||
| 2099 | if (v99 * v99 <= v135 * v135 * 4.0) { |
||
| 2100 | v87 = sqrt(v135 * v135 * 4.0 - v99 * v99); |
||
| 2101 | } else { |
||
| 2102 | v87 = 0.0; |
||
| 2103 | } |
||
| 2104 | if (c->max_force_rear <= v87) { |
||
| 2105 | c->torque = -(c->revs * c->revs / 100000000.0) - 0.1; |
||
| 2106 | } else { |
||
| 2107 | float v177 = sqrt(c->max_force_rear * c->max_force_rear - v87 * v87); |
||
| 2108 | ts3 = ts2 < 0.0 ? -1.0 : 1.0; |
||
| 2109 | // ts4 = (ts2 - ts3 * sqrt(ts3)) * 1.01; |
||
| 2110 | // if (fabs(ts2) > fabs(ts4)) { |
||
| 2111 | // v87 = ts4; |
||
| 2112 | // ts2 = v87; |
||
| 2113 | // } |
||
| 2114 | |||
| 2115 | ts4 = (ts2 - ts3 * v177) * 1.01; |
||
| 2116 | if (fabs(ts2) > fabs(ts4)) { |
||
| 2117 | ts2 = ts4; |
||
| 2118 | } |
||
| 2119 | } |
||
| 2120 | v99 = v99 - ts2; |
||
| 2121 | v135 = sqrt(v99 * v99 + v109 * v109) / 2.0; |
||
| 2122 | |||
| 2123 | } else if (c->driver >= eDriver_net_human && c->gear > 0 && c->revs > c->target_revs && !c->traction_control) { |
||
| 2124 | if (!c->keys.change_down) { |
||
| 2125 | c->traction_control = 1; |
||
| 2126 | } |
||
| 2127 | friction_number = 1.0 - (c->revs - c->target_revs) / (double)(400 * c->gear); |
||
| 2128 | if (friction_number < 0.40000001) { |
||
| 2129 | friction_number = (br_scalar) 0.40000001; // Pierre-Marie Baty -- added type cast |
||
| 2130 | } |
||
| 2131 | maxfl = friction_number * maxfl; |
||
| 2132 | maxfr = friction_number * maxfr; |
||
| 2133 | } |
||
| 2134 | if (fabs(v109) > maxfr + maxfl && maxfr + maxfl > 0.1) { |
||
| 2135 | v87 = (maxfr + maxfl) / fabs(v109) * dt; |
||
| 2136 | v109 = v87 * v109; |
||
| 2137 | v99 = c->friction_elipticity * v87 * v99; |
||
| 2138 | friction_number = -((c->wpos[2].v[2] - c->cmpos.v[2]) * v108 * ((c->wpos[2].v[2] - c->cmpos.v[2]) * v108) / c->I.v[1] + (v98 * v98 + v108 * v108) / c->M); |
||
| 2139 | ts2 = (BrVector3Dot(&v103, &vplane) + v109 / c->M) * v108; |
||
| 2140 | ts2 = BrVector3Dot(&rightplane, &vplane) * v98 + ts2; |
||
| 2141 | ts2 = BrVector3Dot(&c->omega, &c->road_normal) * (c->wpos[2].v[2] - c->cmpos.v[2]) * v108 + ts2; |
||
| 2142 | ts2 = (c->wpos[0].v[2] - c->cmpos.v[2]) * (c->wpos[2].v[2] - c->cmpos.v[2]) * v109 / c->I.v[1] * v108 + ts2; |
||
| 2143 | if (fabs(friction_number) > 0.1) { |
||
| 2144 | friction_number = ts2 / (friction_number * dt); |
||
| 2145 | v108 = friction_number * v108; |
||
| 2146 | v98 = friction_number * v98; |
||
| 2147 | } |
||
| 2148 | v109 = v109 / v87; |
||
| 2149 | v99 = v99 / (c->friction_elipticity * v87); |
||
| 2150 | } |
||
| 2151 | v98 = v98 - v106; |
||
| 2152 | v108 = (c->wpos[0].v[2] - c->wpos[2].v[2]) * c->curvature * v106 + v108; |
||
| 2153 | if (v135 > 0.000099999997) { |
||
| 2154 | v109 = v109 / (v135 * 2.0); |
||
| 2155 | v99 = v99 / (v135 * 2.0); |
||
| 2156 | } |
||
| 2157 | v99 = c->friction_elipticity * v99; |
||
| 2158 | force[0] = v135; |
||
| 2159 | force[1] = v135; |
||
| 2160 | c->wheel_slip = 0; |
||
| 2161 | switch ((force[0] > maxfl) + 2 * (force[1] > maxfr)) { |
||
| 2162 | case 0: |
||
| 2163 | slide_dist = 0; |
||
| 2164 | break; |
||
| 2165 | case 1: |
||
| 2166 | force[0] = c->freduction * maxfl; |
||
| 2167 | force[1] = v135 - force[0] + force[1]; |
||
| 2168 | if (force[1] <= maxfr) { |
||
| 2169 | slide_dist = 0; |
||
| 2170 | } else { |
||
| 2171 | if (maxfr > 0.1) { |
||
| 2172 | pV = (force[1] - maxfr) / maxfr; |
||
| 2173 | if (&gProgram_state.current_car == c) { |
||
| 2174 | v78 = 20.0; |
||
| 2175 | } else { |
||
| 2176 | v78 = 60.0; |
||
| 2177 | } |
||
| 2178 | if (v78 <= pV) { |
||
| 2179 | c->new_skidding |= 2u; |
||
| 2180 | } |
||
| 2181 | SkidNoise(c, 1, pV, c->material_index[1]); |
||
| 2182 | } |
||
| 2183 | force[1] = c->freduction * maxfr; |
||
| 2184 | c->wheel_slip |= 2u; |
||
| 2185 | } |
||
| 2186 | break; |
||
| 2187 | case 2: |
||
| 2188 | force[1] = c->freduction * maxfr; |
||
| 2189 | force[0] = v135 - force[1] + force[0]; |
||
| 2190 | if (force[0] <= maxfl) { |
||
| 2191 | slide_dist = 0; |
||
| 2192 | } else { |
||
| 2193 | if (maxfl > 0.1) { |
||
| 2194 | pV = (force[0] - maxfl) / maxfl; |
||
| 2195 | if (&gProgram_state.current_car == c) { |
||
| 2196 | v77 = 20.0; |
||
| 2197 | } else { |
||
| 2198 | v77 = 60.0; |
||
| 2199 | } |
||
| 2200 | if (v77 <= pV) { |
||
| 2201 | c->new_skidding |= 1u; |
||
| 2202 | } |
||
| 2203 | SkidNoise(c, 0, pV, c->material_index[0]); |
||
| 2204 | } |
||
| 2205 | force[0] = c->freduction * maxfl; |
||
| 2206 | c->wheel_slip |= 2u; |
||
| 2207 | } |
||
| 2208 | break; |
||
| 2209 | case 3: |
||
| 2210 | force[0] = c->freduction * maxfl; |
||
| 2211 | force[1] = c->freduction * maxfr; |
||
| 2212 | c->wheel_slip |= 2u; |
||
| 2213 | pV = (v135 * 2.0 - maxfl - maxfr) / (maxfr + maxfl); |
||
| 2214 | if (&gProgram_state.current_car == c) { |
||
| 2215 | v79 = 20.0; |
||
| 2216 | } else { |
||
| 2217 | v79 = 60.0; |
||
| 2218 | } |
||
| 2219 | if (v79 <= pV) { |
||
| 2220 | if (maxfl > 0.1) { |
||
| 2221 | c->new_skidding |= 1u; |
||
| 2222 | } |
||
| 2223 | if (maxfr > 0.1) { |
||
| 2224 | c->new_skidding |= 2u; |
||
| 2225 | } |
||
| 2226 | } |
||
| 2227 | if (IRandomBetween(0, 1)) { |
||
| 2228 | if (maxfl > 0.1) { |
||
| 2229 | SkidNoise(c, 0, pV, c->material_index[0]); |
||
| 2230 | } |
||
| 2231 | } else if (maxfr > 0.1) { |
||
| 2232 | SkidNoise(c, 1, pV, c->material_index[1]); |
||
| 2233 | } |
||
| 2234 | break; |
||
| 2235 | default: |
||
| 2236 | break; |
||
| 2237 | } |
||
| 2238 | if (c->wheel_slip && c->curvature * c->turn_speed > 0.0 && fabs(v109) > 0.0099999998 && c->curvature * v109 < 0.0 && !c->keys.brake && !c->keys.change_down) { |
||
| 2239 | c->turn_speed = 0.0; |
||
| 2240 | } |
||
| 2241 | v135 = sqrt(v108 * v108 + v98 * v98) / 2.0; |
||
| 2242 | if (v135 > 0.000099999997) { |
||
| 2243 | v108 = v108 / (v135 * 2.0); |
||
| 2244 | v98 = v98 / (v135 * 2.0); |
||
| 2245 | } |
||
| 2246 | maxfl = sqrt(force[2]) * c->mu[1] * (fl_oil_factor * v116) * mat_list[c->material_index[2]].tyre_road_friction; |
||
| 2247 | maxfr = sqrt(force[3]) * c->mu[1] * (fr_oil_factor * v116) * mat_list[c->material_index[3]].tyre_road_friction; |
||
| 2248 | c->max_force_front = maxfr + maxfl; |
||
| 2249 | force[2] = v135; |
||
| 2250 | force[3] = v135; |
||
| 2251 | v72 = (v135 > maxfl) + 2 * (v135 > maxfr); |
||
| 2252 | switch (v72) { |
||
| 2253 | case 1: |
||
| 2254 | force[2] = c->freduction * maxfl; |
||
| 2255 | force[3] = v135 - force[2] + force[3]; |
||
| 2256 | if (force[3] > maxfr) { |
||
| 2257 | if (maxfr > 0.1) { |
||
| 2258 | pV = (force[3] - maxfr) / maxfr; |
||
| 2259 | if (&gProgram_state.current_car == c) { |
||
| 2260 | v75 = 20.0; |
||
| 2261 | } else { |
||
| 2262 | v75 = 60.0; |
||
| 2263 | } |
||
| 2264 | if (v75 <= pV) { |
||
| 2265 | c->new_skidding |= 8u; |
||
| 2266 | } |
||
| 2267 | SkidNoise(c, 3, pV, c->material_index[3]); |
||
| 2268 | } |
||
| 2269 | force[3] = c->freduction * maxfr; |
||
| 2270 | c->wheel_slip |= 1u; |
||
| 2271 | } |
||
| 2272 | break; |
||
| 2273 | case 2: |
||
| 2274 | force[3] = c->freduction * maxfr; |
||
| 2275 | force[2] = v135 - force[3] + force[2]; |
||
| 2276 | if (force[2] > maxfl) { |
||
| 2277 | if (maxfl > 0.1) { |
||
| 2278 | pV = (force[2] - maxfl) / maxfl; |
||
| 2279 | if (&gProgram_state.current_car == c) { |
||
| 2280 | v74 = 20.0; |
||
| 2281 | } else { |
||
| 2282 | v74 = 60.0; |
||
| 2283 | } |
||
| 2284 | if (v74 <= pV) { |
||
| 2285 | c->new_skidding |= 4u; |
||
| 2286 | } |
||
| 2287 | SkidNoise(c, 2, pV, c->material_index[2]); |
||
| 2288 | } |
||
| 2289 | force[2] = c->freduction * maxfl; |
||
| 2290 | c->wheel_slip |= 1u; |
||
| 2291 | } |
||
| 2292 | break; |
||
| 2293 | case 3: |
||
| 2294 | force[2] = c->freduction * maxfl; |
||
| 2295 | force[3] = c->freduction * maxfr; |
||
| 2296 | c->wheel_slip |= 1u; |
||
| 2297 | pV = (v135 * 2.0 - maxfl - maxfr) / (maxfr + maxfl); |
||
| 2298 | if (&gProgram_state.current_car == c) { |
||
| 2299 | v76 = 20.0; |
||
| 2300 | } else { |
||
| 2301 | v76 = 60.0; |
||
| 2302 | } |
||
| 2303 | if (v76 <= pV) { |
||
| 2304 | if (maxfl > 0.1) { |
||
| 2305 | c->new_skidding |= 4u; |
||
| 2306 | } |
||
| 2307 | if (maxfr > 0.1) { |
||
| 2308 | c->new_skidding |= 8u; |
||
| 2309 | } |
||
| 2310 | } |
||
| 2311 | if (IRandomBetween(0, 1)) { |
||
| 2312 | if (maxfl > 0.1) { |
||
| 2313 | SkidNoise(c, 2, pV, c->material_index[2]); |
||
| 2314 | } |
||
| 2315 | } else if (maxfr > 0.1) { |
||
| 2316 | SkidNoise(c, 3, pV, c->material_index[3]); |
||
| 2317 | } |
||
| 2318 | break; |
||
| 2319 | } |
||
| 2320 | BrVector3Scale(&v136, &rightplane, v99); |
||
| 2321 | BrVector3Scale(&a, &v103, v109); |
||
| 2322 | BrVector3Accumulate(&v136, &a); |
||
| 2323 | BrVector3Scale(&v123, &rightplane, v98); |
||
| 2324 | BrVector3Scale(&a, &v103, v108); |
||
| 2325 | BrVector3Accumulate(&v123, &a); |
||
| 2326 | |||
| 2327 | rightplane = c->wpos[0]; |
||
| 2328 | rightplane.v[1] = rightplane.v[1] - c->oldd[0]; |
||
| 2329 | BrVector3Sub(&rightplane, &rightplane, &c->cmpos); |
||
| 2330 | BrVector3Scale(&b, &v136, force[0]); |
||
| 2331 | BrVector3Accumulate(&B, &b); |
||
| 2332 | BrVector3Cross(&a, &rightplane, &b); |
||
| 2333 | BrVector3Accumulate(&f, &a); |
||
| 2334 | |||
| 2335 | rightplane = c->wpos[1]; |
||
| 2336 | rightplane.v[1] = rightplane.v[1] - c->oldd[1]; |
||
| 2337 | BrVector3Sub(&rightplane, &rightplane, &c->cmpos); |
||
| 2338 | BrVector3Scale(&b, &v136, force[1]); |
||
| 2339 | BrVector3Accumulate(&B, &b); |
||
| 2340 | BrVector3Cross(&a, &rightplane, &b); |
||
| 2341 | BrVector3Accumulate(&f, &a); |
||
| 2342 | |||
| 2343 | rightplane = c->wpos[2]; |
||
| 2344 | rightplane.v[1] = rightplane.v[1] - c->oldd[2]; |
||
| 2345 | BrVector3Sub(&rightplane, &rightplane, &c->cmpos); |
||
| 2346 | BrVector3Scale(&b, &v123, force[2]); |
||
| 2347 | BrVector3Accumulate(&B, &b); |
||
| 2348 | BrVector3Cross(&a, &rightplane, &b); |
||
| 2349 | BrVector3Accumulate(&f, &a); |
||
| 2350 | |||
| 2351 | rightplane = c->wpos[3]; |
||
| 2352 | rightplane.v[1] = rightplane.v[1] - c->oldd[3]; |
||
| 2353 | BrVector3Sub(&rightplane, &rightplane, &c->cmpos); |
||
| 2354 | BrVector3Scale(&b, &v123, force[3]); |
||
| 2355 | BrVector3Accumulate(&B, &b); |
||
| 2356 | BrVector3Cross(&a, &rightplane, &b); |
||
| 2357 | BrVector3Accumulate(&f, &a); |
||
| 2358 | |||
| 2359 | } else { |
||
| 2360 | c->max_force_front = 0.0; |
||
| 2361 | c->max_force_rear = 0.0; |
||
| 2362 | StopSkid(c); |
||
| 2363 | } |
||
| 2364 | c->number_of_wheels_on_ground = normnum; |
||
| 2365 | BrMatrix34ApplyV(&b, &B, mat); |
||
| 2366 | BrVector3Scale(&rightplane, &f, dt); |
||
| 2367 | ApplyTorque(c, &rightplane); |
||
| 2368 | BrVector3Scale(&rightplane, &b, dt / c->M); |
||
| 2369 | BrVector3Accumulate(&c->v, &rightplane); |
||
| 2370 | if (c->speed < 0.000099999997 |
||
| 2371 | && ((!c->keys.acc && c->joystick.acc <= 0) || !c->gear) |
||
| 2372 | && !c->keys.dec |
||
| 2373 | && c->joystick.dec <= 0 |
||
| 2374 | && c->bounce_rate == 0.0 |
||
| 2375 | && BrVector3Length(&c->omega) < 0.05) { |
||
| 2376 | if (vol) { |
||
| 2377 | v73 = c->driver > eDriver_non_car && c->underwater_ability ? 1.0 - (1.0 - vol->gravity_multiplier) * 0.6 : vol->gravity_multiplier; |
||
| 2378 | friction_number = BrVector3Length(&b) / v73 / gGravity_multiplier; |
||
| 2379 | } else { |
||
| 2380 | friction_number = BrVector3Length(&b); |
||
| 2381 | } |
||
| 2382 | if (c->M > friction_number || (c->keys.brake && normnum >= 3)) { |
||
| 2383 | if (stop_timer == 100.0) { |
||
| 2384 | stop_timer = 0.0; |
||
| 2385 | } |
||
| 2386 | if (stop_timer > 0.5) { |
||
| 2387 | BrVector3SetFloat(&c->v, 0.0, 0.0, 0.0); |
||
| 2388 | BrVector3SetFloat(&c->omega, 0.0, 0.0, 0.0); |
||
| 2389 | stop_timer = 0.5; |
||
| 2390 | } |
||
| 2391 | } |
||
| 2392 | } |
||
| 2393 | stop_timer = dt + stop_timer; |
||
| 2394 | if (stop_timer > 1.0) { |
||
| 2395 | stop_timer = 100.0; |
||
| 2396 | } |
||
| 2397 | AddDrag(c, dt); |
||
| 2398 | if (c->driver >= eDriver_net_human) { |
||
| 2399 | c->acc_force = -(v136.v[2] * force[0]) - v136.v[2] * force[1]; |
||
| 2400 | // LOG_DEBUG("old %f new %f", old, c->acc_force); |
||
| 2401 | } |
||
| 2402 | } |
||
| 2403 | |||
| 2404 | // IDA: void __usercall DoRevs(tCar_spec *c@<EAX>, br_scalar dt) |
||
| 2405 | void DoRevs(tCar_spec* c, br_scalar dt) { |
||
| 2406 | br_scalar wheel_spin_force; |
||
| 2407 | br_scalar ts; |
||
| 2408 | //int revs_increase; // Pierre-Marie Baty -- unused variable |
||
| 2409 | LOG_TRACE("(%p, %f)", c, dt); |
||
| 2410 | |||
| 2411 | ts = -BrVector3Dot((br_vector3*)c->car_master_actor->t.t.mat.m[2], &c->v); |
||
| 2412 | |||
| 2413 | if (c->gear) { |
||
| 2414 | c->target_revs = ts / c->speed_revs_ratio / (double)c->gear; |
||
| 2415 | } else { |
||
| 2416 | c->target_revs = 0.0; |
||
| 2417 | } |
||
| 2418 | if (c->target_revs < 0.0) { |
||
| 2419 | c->target_revs = 0.0; |
||
| 2420 | c->gear = 0; |
||
| 2421 | } |
||
| 2422 | if (!c->number_of_wheels_on_ground || ((c->wheel_slip & 2) + 1) != 0 || !c->gear) { |
||
| 2423 | if (c->number_of_wheels_on_ground) { |
||
| 2424 | wheel_spin_force = c->force_torque_ratio * c->torque - (double)c->gear * c->acc_force; |
||
| 2425 | } else { |
||
| 2426 | wheel_spin_force = c->force_torque_ratio * c->torque; |
||
| 2427 | } |
||
| 2428 | if (c->gear) { |
||
| 2429 | if (c->gear < 2 && (c->keys.dec || c->joystick.dec > 0) && fabs(ts) < 1.0 && c->revs > 1000.0) { |
||
| 2430 | c->gear = -c->gear; |
||
| 2431 | } |
||
| 2432 | } else { |
||
| 2433 | if (c->revs > 1000.0 && !c->keys.brake && (c->keys.acc || c->joystick.acc > 0) && !gCountdown) { |
||
| 2434 | if (c->keys.backwards) { |
||
| 2435 | c->gear = -1; |
||
| 2436 | } else { |
||
| 2437 | c->gear = 1; |
||
| 2438 | } |
||
| 2439 | } |
||
| 2440 | wheel_spin_force = c->force_torque_ratio * c->torque; |
||
| 2441 | } |
||
| 2442 | c->revs = wheel_spin_force / c->force_torque_ratio * dt / 0.0002 + c->revs; |
||
| 2443 | |||
| 2444 | if (c->traction_control && wheel_spin_force > 0.0 && c->revs > c->target_revs && c->gear && c->target_revs > 1000.0) { |
||
| 2445 | c->revs = c->target_revs; |
||
| 2446 | } |
||
| 2447 | if (c->revs <= 0.0) { |
||
| 2448 | c->revs = 0.0; |
||
| 2449 | } |
||
| 2450 | } |
||
| 2451 | if ((c->wheel_slip & 2) == 0 && c->target_revs > 6000.0 && c->revs > 6000.0 && c->gear < c->max_gear && c->gear > 0 && !c->just_changed_gear) { |
||
| 2452 | c->gear++; |
||
| 2453 | } |
||
| 2454 | if (c->gear > 1 && c->target_revs < 3000.0 && !c->just_changed_gear) { |
||
| 2455 | c->gear--; |
||
| 2456 | } |
||
| 2457 | if (c->revs < 200.0 && c->target_revs < 200.0 && c->gear <= 1 && !c->keys.acc && c->joystick.acc <= 0 && !c->just_changed_gear) { |
||
| 2458 | c->gear = 0; |
||
| 2459 | } |
||
| 2460 | if (c->just_changed_gear && c->revs < 6000.0 && c->revs > 200.0 && (c->gear < 2 || c->revs >= 3000.0)) { |
||
| 2461 | c->just_changed_gear = 0; |
||
| 2462 | } |
||
| 2463 | if (c->revs >= 6000.0 && (c->keys.acc || c->joystick.acc > 0)) { |
||
| 2464 | c->just_changed_gear = 0; |
||
| 2465 | } |
||
| 2466 | } |
||
| 2467 | |||
| 2468 | // IDA: void __usercall ApplyTorque(tCar_spec *c@<EAX>, br_vector3 *tdt@<EDX>) |
||
| 2469 | void ApplyTorque(tCar_spec* c, br_vector3* tdt) { |
||
| 2470 | LOG_TRACE("(%p, %p)", c, tdt); |
||
| 2471 | |||
| 2472 | c->omega.v[0] = tdt->v[0] / c->I.v[0] + c->omega.v[0]; |
||
| 2473 | c->omega.v[1] = tdt->v[1] / c->I.v[1] + c->omega.v[1]; |
||
| 2474 | c->omega.v[2] = tdt->v[2] / c->I.v[2] + c->omega.v[2]; |
||
| 2475 | } |
||
| 2476 | |||
| 2477 | // IDA: void __usercall TranslateCar(tCollision_info *c@<EAX>, br_scalar dt) |
||
| 2478 | void TranslateCar(tCollision_info* c, br_scalar dt) { |
||
| 2479 | br_vector3 t; |
||
| 2480 | LOG_TRACE("(%p, %f)", c, dt); |
||
| 2481 | |||
| 2482 | t.v[0] = c->v.v[0] * dt; |
||
| 2483 | t.v[1] = c->v.v[1] * dt; |
||
| 2484 | t.v[2] = c->v.v[2] * dt; |
||
| 2485 | c->car_master_actor->t.t.mat.m[3][0] = c->car_master_actor->t.t.mat.m[3][0] + t.v[0]; |
||
| 2486 | c->car_master_actor->t.t.mat.m[3][1] = c->car_master_actor->t.t.mat.m[3][1] + t.v[1]; |
||
| 2487 | c->car_master_actor->t.t.mat.m[3][2] = c->car_master_actor->t.t.mat.m[3][2] + t.v[2]; |
||
| 2488 | } |
||
| 2489 | |||
| 2490 | // IDA: int __usercall CollCheck@<EAX>(tCollision_info *c@<EAX>, br_scalar dt) |
||
| 2491 | int CollCheck(tCollision_info* c, br_scalar dt) { |
||
| 2492 | br_vector3 a; |
||
| 2493 | br_vector3 a1; |
||
| 2494 | br_vector3 aa; |
||
| 2495 | br_vector3 bb; |
||
| 2496 | br_vector3 cc; |
||
| 2497 | br_vector3 pos; |
||
| 2498 | br_vector3 r[8]; |
||
| 2499 | br_vector3 norm; |
||
| 2500 | br_vector3 n[8]; |
||
| 2501 | br_vector3 dir; |
||
| 2502 | br_vector3 tv; |
||
| 2503 | br_vector3 tv2; |
||
| 2504 | br_vector3 tau[4]; |
||
| 2505 | //br_vector3 old_val; // Pierre-Marie Baty -- unused variable |
||
| 2506 | //br_vector3 ftau; // Pierre-Marie Baty -- unused variable |
||
| 2507 | br_vector3 max_friction; |
||
| 2508 | br_vector3 vel; |
||
| 2509 | br_vector3 p_vel; |
||
| 2510 | br_vector3 normal_force; |
||
| 2511 | br_vector3 friction_force; |
||
| 2512 | br_scalar d[4]; |
||
| 2513 | br_scalar f[4]; |
||
| 2514 | br_scalar total_force; |
||
| 2515 | br_scalar point_vel; |
||
| 2516 | br_scalar batwick_length; |
||
| 2517 | br_matrix4 M; |
||
| 2518 | br_scalar dist; |
||
| 2519 | //br_scalar min_d; // Pierre-Marie Baty -- unused variable |
||
| 2520 | br_scalar ts; |
||
| 2521 | br_scalar ts2; |
||
| 2522 | br_scalar v_diff; |
||
| 2523 | br_matrix34* mat; |
||
| 2524 | br_matrix34* oldmat; |
||
| 2525 | br_matrix34 mat_to_oldmat; |
||
| 2526 | br_matrix34 oldmat_to_mat; |
||
| 2527 | br_matrix34 tm; |
||
| 2528 | int collision; |
||
| 2529 | br_bounds bnds; |
||
| 2530 | tFace_ref* f_ref; |
||
| 2531 | int i; |
||
| 2532 | int j; |
||
| 2533 | //int l; // Pierre-Marie Baty -- unused variable |
||
| 2534 | int k; |
||
| 2535 | int material; |
||
| 2536 | int noise_defeat; |
||
| 2537 | static int oldk; |
||
| 2538 | br_scalar min; |
||
| 2539 | br_scalar max; |
||
| 2540 | br_vector3 edges[3]; |
||
| 2541 | //br_vector3 corner; // Pierre-Marie Baty -- unused variable |
||
| 2542 | //br_vector3 test_dir; // Pierre-Marie Baty -- unused variable |
||
| 2543 | //br_scalar min_acc; // Pierre-Marie Baty -- unused variable |
||
| 2544 | //br_scalar max_acc; // Pierre-Marie Baty -- unused variable |
||
| 2545 | br_matrix34 message_mat; |
||
| 2546 | LOG_TRACE("(%p, %f)", c, dt); |
||
| 2547 | |||
| 2548 | tCar_spec* car_spec; // added for readability |
||
| 2549 | |||
| 2550 | // v34 = 0; |
||
| 2551 | // v35 = 0; |
||
| 2552 | // v36 = 0x3F800000; |
||
| 2553 | // v48 = 0x3F800347; |
||
| 2554 | car_spec = (tCar_spec*)c; |
||
| 2555 | mat = &c->car_master_actor->t.t.mat; |
||
| 2556 | oldmat = &c->oldmat; |
||
| 2557 | k = 0; |
||
| 2558 | gMaterial_index = 0; |
||
| 2559 | if (c->dt >= 0.0f && gNet_mode == eNet_mode_host) { |
||
| 2560 | oldmat = &message_mat; |
||
| 2561 | GetExpandedMatrix(&message_mat, &c->message.mat); |
||
| 2562 | } |
||
| 2563 | if (dt < 0.0f) { |
||
| 2564 | mat = oldmat; |
||
| 2565 | } |
||
| 2566 | BrMatrix34LPInverse(&tm, mat); |
||
| 2567 | BrMatrix34Mul(&oldmat_to_mat, oldmat, &tm); |
||
| 2568 | |||
| 2569 | oldmat_to_mat.m[3][0] = oldmat_to_mat.m[3][0] / WORLD_SCALE; |
||
| 2570 | oldmat_to_mat.m[3][1] = oldmat_to_mat.m[3][1] / WORLD_SCALE; |
||
| 2571 | oldmat_to_mat.m[3][2] = oldmat_to_mat.m[3][2] / WORLD_SCALE; |
||
| 2572 | GetNewBoundingBox(&bnds, &c->bounds[2], &oldmat_to_mat); |
||
| 2573 | for (i = 0; i < 3; ++i) { |
||
| 2574 | if (c->bounds[2].min.v[i] < bnds.min.v[i]) { |
||
| 2575 | bnds.min.v[i] = c->bounds[2].min.v[i]; |
||
| 2576 | } |
||
| 2577 | if (c->bounds[2].max.v[i] > bnds.max.v[i]) { |
||
| 2578 | bnds.max.v[i] = c->bounds[2].max.v[i]; |
||
| 2579 | } |
||
| 2580 | } |
||
| 2581 | a1.v[0] = mat->m[3][0] / WORLD_SCALE; |
||
| 2582 | a1.v[1] = mat->m[3][1] / WORLD_SCALE; |
||
| 2583 | a1.v[2] = mat->m[3][2] / WORLD_SCALE; |
||
| 2584 | BrMatrix34ApplyV(&aa, &bnds.min, mat); |
||
| 2585 | BrVector3Accumulate(&aa, &a1); |
||
| 2586 | for (j = 0; j < 3; ++j) { |
||
| 2587 | edges[j].v[0] = (bnds.max.v[j] - bnds.min.v[j]) * mat->m[j][0]; |
||
| 2588 | edges[j].v[1] = (bnds.max.v[j] - bnds.min.v[j]) * mat->m[j][1]; |
||
| 2589 | edges[j].v[2] = (bnds.max.v[j] - bnds.min.v[j]) * mat->m[j][2]; |
||
| 2590 | } |
||
| 2591 | for (i = 0; i < 50 && i < c->box_face_end - c->box_face_start; i++) { |
||
| 2592 | f_ref = &gFace_list__car[c->box_face_start + i]; |
||
| 2593 | BrVector3Sub(&bb, &aa, &f_ref->v[0]); |
||
| 2594 | max = BrVector3Dot(&bb, &f_ref->normal); |
||
| 2595 | min = max; |
||
| 2596 | for (j = 0; j < 3; ++j) { |
||
| 2597 | ts = BrVector3Dot(&edges[j], &f_ref->normal); |
||
| 2598 | if (ts >= 0) { |
||
| 2599 | max = max + ts; |
||
| 2600 | } else { |
||
| 2601 | min = min + ts; |
||
| 2602 | } |
||
| 2603 | } |
||
| 2604 | if ((max <= 0.001f || min <= 0.001f) && (max >= -0.001f || min >= -0.001f)) { |
||
| 2605 | f_ref->flags &= ~0x80u; |
||
| 2606 | k++; |
||
| 2607 | } else { |
||
| 2608 | f_ref->flags |= 0x80u; |
||
| 2609 | } |
||
| 2610 | } |
||
| 2611 | if (k == 0) { |
||
| 2612 | return 0; |
||
| 2613 | } |
||
| 2614 | k = 0; |
||
| 2615 | BrMatrix34LPInverse(&tm, oldmat); |
||
| 2616 | BrMatrix34Mul(&mat_to_oldmat, mat, &tm); |
||
| 2617 | gEliminate_faces = 1; |
||
| 2618 | for (i = 0; i < 8 + c->extra_point_num; i++) { |
||
| 2619 | if (i >= 8) { |
||
| 2620 | tv = c->extra_points[i - 8]; |
||
| 2621 | } else { |
||
| 2622 | tv.v[0] = ((i & 2) == 0) * c->bounds[1].min.v[0] + ((i & 2) >> 1) * c->bounds[1].max.v[0]; |
||
| 2623 | tv.v[1] = ((i & 1) == 0) * c->bounds[1].min.v[1] + ((i & 1) >> 0) * c->bounds[1].max.v[1]; |
||
| 2624 | tv.v[2] = ((i & 4) == 0) * c->bounds[1].max.v[2] + ((i & 4) >> 2) * c->bounds[1].min.v[2]; |
||
| 2625 | } |
||
| 2626 | BrMatrix34ApplyP(&dir, &tv, mat); |
||
| 2627 | if (dt >= 0.0f) { |
||
| 2628 | BrMatrix34ApplyP(&a, &tv, oldmat); |
||
| 2629 | } else { |
||
| 2630 | BrVector3Scale(&a, &c->pos, WORLD_SCALE); |
||
| 2631 | } |
||
| 2632 | BrVector3Sub(&dir, &dir, &a); |
||
| 2633 | BrVector3Normalise(&normal_force, &dir); |
||
| 2634 | BrVector3Scale(&normal_force, &normal_force, 0.0072463769f); |
||
| 2635 | BrVector3Accumulate(&dir, &normal_force); |
||
| 2636 | material = FindFloorInBoxM2(&a, &dir, &norm, &dist, c); |
||
| 2637 | if (dist >= 0.0f && dist < 1.0001f) { |
||
| 2638 | BrVector3Scale(&cc, &c->pos, WORLD_SCALE); |
||
| 2639 | BrVector3Sub(&cc, &cc, &a); |
||
| 2640 | FindFloorInBoxM(&a, &cc, &bb, &ts, c); |
||
| 2641 | if (i < 8 || ts > 1.0f) { |
||
| 2642 | BrMatrix34TApplyV(&a, &norm, oldmat); |
||
| 2643 | AddCollPoint(dist, &tv, &a, r, n, &dir, k, c); |
||
| 2644 | k++; |
||
| 2645 | if (gMaterial_index == 0) { |
||
| 2646 | gMaterial_index = material; |
||
| 2647 | } |
||
| 2648 | } |
||
| 2649 | } |
||
| 2650 | } |
||
| 2651 | gEliminate_faces = 0; |
||
| 2652 | if (k < 1) { |
||
| 2653 | k += BoxFaceIntersect(&c->bounds[1], mat, &mat_to_oldmat, &r[k], &n[k], &d[k], 8 - k, c); |
||
| 2654 | } |
||
| 2655 | if (k > 4) { |
||
| 2656 | k = 4; |
||
| 2657 | } |
||
| 2658 | for (i = 0; i < k; i++) { |
||
| 2659 | if (fabsf(r[i].v[1]) + fabsf(r[i].v[2]) + fabsf(r[i].v[0]) > 500.0f) { |
||
| 2660 | for (j = i + 1; j < k; j++) { |
||
| 2661 | if (fabsf(r[j].v[1]) + fabsf(r[j].v[2]) + fabsf(r[j].v[0]) < 500.0f) { |
||
| 2662 | r[i] = r[j]; |
||
| 2663 | n[i] = n[j]; |
||
| 2664 | i++; |
||
| 2665 | } |
||
| 2666 | } |
||
| 2667 | k = i; |
||
| 2668 | break; |
||
| 2669 | } |
||
| 2670 | } |
||
| 2671 | if (dt >= 0.0f) { |
||
| 2672 | if (k > 0 && c->collision_flag && k < 4 |
||
| 2673 | && (fabsf(r[0].v[0] - c->old_point.v[0]) > 0.05f |
||
| 2674 | || fabsf(r[0].v[1] - c->old_point.v[1]) > 0.05f |
||
| 2675 | || fabsf(r[0].v[2] - c->old_point.v[2]) > 0.05f)) { |
||
| 2676 | r[k] = c->old_point; |
||
| 2677 | n[k] = c->old_norm; |
||
| 2678 | k++; |
||
| 2679 | } |
||
| 2680 | if (k > 0) { |
||
| 2681 | c->old_point = r[0]; |
||
| 2682 | c->old_norm = n[0]; |
||
| 2683 | BrMatrix34Copy(mat, oldmat); |
||
| 2684 | c->omega = c->oldomega; |
||
| 2685 | BrMatrix34TApplyV(&c->velocity_car_space, &c->v, mat); |
||
| 2686 | memset(&norm, 0, sizeof(norm)); |
||
| 2687 | collision = 0; |
||
| 2688 | for (i = 0; i < k; i++) { |
||
| 2689 | BrVector3Cross(&tau[i], &r[i], &n[i]); |
||
| 2690 | tau[i].v[0] = tau[i].v[0] / c->I.v[0]; |
||
| 2691 | tau[i].v[1] = tau[i].v[1] / c->I.v[1]; |
||
| 2692 | tau[i].v[2] = tau[i].v[2] / c->I.v[2]; |
||
| 2693 | BrVector3Cross(&normal_force, &c->omega, &r[i]); |
||
| 2694 | BrVector3Accumulate(&normal_force, &c->velocity_car_space); |
||
| 2695 | d[i] = -(BrVector3Dot(&n[i], &normal_force)); |
||
| 2696 | BrVector3Add(&normal_force, &r[i], &c->cmpos); |
||
| 2697 | BrMatrix34ApplyP(&dir, &normal_force, &mat_to_oldmat); |
||
| 2698 | BrVector3Sub(&dir, &dir, &normal_force); |
||
| 2699 | ts = -(BrVector3Dot(&n[i], &dir) / dt); |
||
| 2700 | if (ts > d[i]) { |
||
| 2701 | d[i] = ts; |
||
| 2702 | } |
||
| 2703 | if (d[i] > 0.0f) { |
||
| 2704 | collision = 1; |
||
| 2705 | } |
||
| 2706 | } |
||
| 2707 | if (!collision) { |
||
| 2708 | d[0] = 0.5f; |
||
| 2709 | } |
||
| 2710 | for (i = 0; i < k; i++) { |
||
| 2711 | for (j = 0; j < k; j++) { |
||
| 2712 | BrVector3Cross(&normal_force, &tau[j], &r[i]); |
||
| 2713 | BrVector3InvScale(&norm, &n[j], c->M); |
||
| 2714 | BrVector3Accumulate(&normal_force, &norm); |
||
| 2715 | M.m[i][j] = BrVector3Dot(&n[i], &normal_force); |
||
| 2716 | } |
||
| 2717 | } |
||
| 2718 | switch (k) { |
||
| 2719 | case 1: |
||
| 2720 | ts = SinglePointColl(f, &M, d); |
||
| 2721 | break; |
||
| 2722 | case 2: |
||
| 2723 | ts = TwoPointColl(f, &M, d, tau, n); |
||
| 2724 | break; |
||
| 2725 | case 3: |
||
| 2726 | d[3] = 0.0f; |
||
| 2727 | ts = ThreePointCollRec(f, &M, d, tau, n, c); |
||
| 2728 | break; |
||
| 2729 | case 4: |
||
| 2730 | ts = FourPointColl(f, &M, d, tau, n, c); |
||
| 2731 | break; |
||
| 2732 | default: |
||
| 2733 | break; |
||
| 2734 | } |
||
| 2735 | if (k > 3) { |
||
| 2736 | k = 3; |
||
| 2737 | } |
||
| 2738 | // if (f[0] > 10.0f || f[1] > 10.0f || f[2] > 10.0f) { |
||
| 2739 | // v31 = 0; |
||
| 2740 | // } |
||
| 2741 | if (fabsf(ts) <= 0.000001f) { |
||
| 2742 | BrVector3Set(&c->v, 0.f, 0.f, 0.f); |
||
| 2743 | BrVector3Set(&c->omega, 0.f, 0.f, 0.f); |
||
| 2744 | BrVector3Set(&c->oldomega, 0.f, 0.f, 0.f); |
||
| 2745 | return k; |
||
| 2746 | } |
||
| 2747 | BrVector3Set(&p_vel, 0.f, 0.f, 0.f); |
||
| 2748 | BrVector3Set(&dir, 0.f, 0.f, 0.f); |
||
| 2749 | BrVector3Set(&friction_force, 0.f, 0.f, 0.f); |
||
| 2750 | total_force = 0.f; |
||
| 2751 | for (i = 0; i < k; i++) { |
||
| 2752 | if (f[i] < 0.001f) { |
||
| 2753 | f[i] = 0.001f; |
||
| 2754 | } |
||
| 2755 | f[i] = f[i] * 1.001f; |
||
| 2756 | BrVector3Scale(&tau[i], &tau[i], f[i]); |
||
| 2757 | BrVector3Accumulate(&c->omega, &tau[i]); |
||
| 2758 | f[i] = f[i] / c->M; |
||
| 2759 | BrVector3Scale(&n[i], &n[i], f[i]); |
||
| 2760 | BrVector3Accumulate(&p_vel, &n[i]); |
||
| 2761 | BrVector3Add(&bb, &r[i], &c->cmpos); |
||
| 2762 | BrVector3Scale(&bb, &bb, f[i]); |
||
| 2763 | BrVector3Accumulate(&dir, &bb); |
||
| 2764 | total_force = f[i] + total_force; |
||
| 2765 | } |
||
| 2766 | if (gPinball_factor != 0.0f) { |
||
| 2767 | BrVector3Scale(&p_vel, &p_vel, gPinball_factor); |
||
| 2768 | point_vel = BrVector3LengthSquared(&p_vel); |
||
| 2769 | if (point_vel > 10.0f) { |
||
| 2770 | noise_defeat = 1; |
||
| 2771 | if (c->driver == eDriver_local_human) { |
||
| 2772 | DRS3StartSound(gCar_outlet, 9011); |
||
| 2773 | } else { |
||
| 2774 | DRS3StartSound3D(gCar_outlet, 9011, &c->pos, &gZero_v__car, 1, 255, 0x10000, 0x10000); |
||
| 2775 | } |
||
| 2776 | if (point_vel > 10000.0f) { |
||
| 2777 | BrVector3Normalise(&p_vel, &p_vel); |
||
| 2778 | BrVector3Scale(&p_vel, &p_vel, 100); |
||
| 2779 | } |
||
| 2780 | } |
||
| 2781 | } |
||
| 2782 | BrVector3Accumulate(&c->velocity_car_space, &p_vel); |
||
| 2783 | BrVector3InvScale(&dir, &dir, total_force); |
||
| 2784 | BrVector3Cross(&tv, &c->omega, &dir); |
||
| 2785 | BrVector3Accumulate(&tv, &c->velocity_car_space); |
||
| 2786 | batwick_length = BrVector3Length(&tv); |
||
| 2787 | if (!c->collision_flag || (c->collision_flag == 1 && oldk < k)) { |
||
| 2788 | for (i = 0; i < k; i++) { |
||
| 2789 | BrVector3Cross(&vel, &c->omega, &r[i]); |
||
| 2790 | BrVector3Accumulate(&vel, &c->velocity_car_space); |
||
| 2791 | AddFriction(c, &vel, &n[i], &r[i], f[i], &max_friction); |
||
| 2792 | BrVector3Accumulate(&friction_force, &max_friction); |
||
| 2793 | BrVector3Accumulate(&c->velocity_car_space, &max_friction); |
||
| 2794 | } |
||
| 2795 | } |
||
| 2796 | oldk = k; |
||
| 2797 | BrMatrix34ApplyP(&pos, &dir, &c->car_master_actor->t.t.mat); |
||
| 2798 | BrVector3InvScale(&pos, &pos, WORLD_SCALE); |
||
| 2799 | noise_defeat = 0; |
||
| 2800 | BrVector3Add(&normal_force, &friction_force, &p_vel); |
||
| 2801 | BrMatrix34ApplyV(&norm, &normal_force, mat); |
||
| 2802 | min = dt * 90.0f / 10.0f; |
||
| 2803 | max = dt * 110.0f / 10.0f; |
||
| 2804 | if (c->last_special_volume != NULL) { |
||
| 2805 | min *= c->last_special_volume->gravity_multiplier; |
||
| 2806 | max *= c->last_special_volume->gravity_multiplier; |
||
| 2807 | } |
||
| 2808 | if (BrVector3LengthSquared(&c->velocity_car_space) < 0.05f |
||
| 2809 | && 0.1f * total_force > BrVector3Dot(&c->omega, &tv) |
||
| 2810 | && k >= 3 |
||
| 2811 | && norm.v[1] > min |
||
| 2812 | && norm.v[1] < max) { |
||
| 2813 | if (c->driver <= eDriver_non_car || fabsf(normal_force.v[2]) <= total_force * 0.9f) { |
||
| 2814 | BrVector3Set(&c->v, 0.f, 0.f, 0.f); |
||
| 2815 | BrVector3Set(&norm, 0.f, 0.f, 0.f); |
||
| 2816 | BrVector3Set(&normal_force, 0.f, 0.f, 0.f); |
||
| 2817 | BrVector3Set(&c->omega, 0.f, 0.f, 0.f); |
||
| 2818 | BrVector3Set(&c->oldomega, 0.f, 0.f, 0.f); |
||
| 2819 | if (c->driver <= eDriver_non_car || car_spec->max_force_rear == 0.0f) { |
||
| 2820 | if (c->driver <= eDriver_non_car) { |
||
| 2821 | PipeSingleNonCar(c); |
||
| 2822 | } |
||
| 2823 | c->doing_nothing_flag = 1; |
||
| 2824 | } |
||
| 2825 | } else { |
||
| 2826 | BrVector3SetFloat(&tv2, 0.0f, -1.0f, 0.0f); |
||
| 2827 | bb.v[0] = mat->m[1][2] * tv2.v[1] - mat->m[1][1] * tv2.v[2]; |
||
| 2828 | bb.v[1] = mat->m[1][0] * tv2.v[2] - mat->m[1][2] * tv2.v[0]; |
||
| 2829 | bb.v[2] = mat->m[1][1] * tv2.v[0] - mat->m[1][0] * tv2.v[1]; |
||
| 2830 | if (BrVector3Dot(&bb, (br_vector3*)&mat->m[0][1]) <= 0.0f) { |
||
| 2831 | c->omega.v[0] = -0.5f; |
||
| 2832 | } else { |
||
| 2833 | c->omega.v[0] = 0.5f; |
||
| 2834 | } |
||
| 2835 | } |
||
| 2836 | } |
||
| 2837 | BrVector3Accumulate(&c->v, &norm); |
||
| 2838 | if (c->driver >= eDriver_net_human) { |
||
| 2839 | BrVector3Scale(&normal_force, &normal_force, gDefensive_powerup_factor[car_spec->power_up_levels[0]]); |
||
| 2840 | } |
||
| 2841 | if (c->driver < eDriver_net_human) { |
||
| 2842 | BrVector3Scale(&normal_force, &normal_force, 0.01f); |
||
| 2843 | } else { |
||
| 2844 | BrVector3Scale(&normal_force, &normal_force, 0.75f); |
||
| 2845 | } |
||
| 2846 | if (CAR(c)->invulnerable |
||
| 2847 | || (c->driver < eDriver_net_human && (c->driver != eDriver_oppo || PointOutOfSight(&c->pos, 150.0f))) |
||
| 2848 | || ((v_diff = (car_spec->pre_car_col_velocity.v[1] - c->v.v[1]) * gDefensive_powerup_factor[car_spec->power_up_levels[0]]) >= -20.0f) |
||
| 2849 | || CAR(c)->number_of_wheels_on_ground >= 3) { |
||
| 2850 | CrushAndDamageCar(CAR(c), &dir, &normal_force, NULL); |
||
| 2851 | } else { |
||
| 2852 | // Cops Special Forces is always stolen if destroyed! |
||
| 2853 | if (c->driver == eDriver_oppo && c->index == 4 && v_diff < -40.0f) { |
||
| 2854 | KnackerThisCar(CAR(c)); |
||
| 2855 | StealCar(CAR(c)); |
||
| 2856 | v_diff = v_diff * 5.0f; |
||
| 2857 | } |
||
| 2858 | for (i = 0; i < CAR(c)->car_actor_count; i++) { |
||
| 2859 | ts2 = (v_diff + 20.0f) * -0.01f; |
||
| 2860 | TotallySpamTheModel(CAR(c), i, CAR(c)->car_model_actors[i].actor, &CAR(c)->car_model_actors[i].crush_data, ts2); |
||
| 2861 | } |
||
| 2862 | for (i = 0; i < COUNT_OF(CAR(c)->damage_units); i++) { |
||
| 2863 | DamageUnit(CAR(c), i, IRandomPosNeg(5) + (v_diff + 20.0f) * -1.5f); |
||
| 2864 | } |
||
| 2865 | } |
||
| 2866 | if (!noise_defeat) { |
||
| 2867 | CrashNoise(&norm, &pos, gMaterial_index); |
||
| 2868 | ScrapeNoise(batwick_length, &pos, gMaterial_index); |
||
| 2869 | } |
||
| 2870 | BrVector3InvScale(&tv, &tv, WORLD_SCALE); |
||
| 2871 | BrMatrix34ApplyV(&bb, &tv, &c->car_master_actor->t.t.mat); |
||
| 2872 | BrMatrix34ApplyV(&norm, &p_vel, &c->car_master_actor->t.t.mat); |
||
| 2873 | CreateSparks(&pos, &bb, &norm, gCurrent_race.material_modifiers[gMaterial_index].sparkiness, car_spec); |
||
| 2874 | } |
||
| 2875 | return k; |
||
| 2876 | } else { |
||
| 2877 | if (k != 0) { |
||
| 2878 | c->old_point = r[0]; |
||
| 2879 | c->old_norm = n[0]; |
||
| 2880 | } |
||
| 2881 | return k; |
||
| 2882 | } |
||
| 2883 | } |
||
| 2884 | |||
| 2885 | // IDA: br_scalar __usercall AddFriction@<ST0>(tCollision_info *c@<EAX>, br_vector3 *vel@<EDX>, br_vector3 *normal_force@<EBX>, br_vector3 *pos@<ECX>, br_scalar total_force, br_vector3 *max_friction) |
||
| 2886 | br_scalar AddFriction(tCollision_info* c, br_vector3* vel, br_vector3* normal_force, br_vector3* pos, br_scalar total_force, br_vector3* max_friction) { |
||
| 2887 | br_vector3 norm; |
||
| 2888 | br_vector3 tv; |
||
| 2889 | br_vector3 ftau; |
||
| 2890 | br_scalar ts; |
||
| 2891 | br_scalar point_vel; |
||
| 2892 | LOG_TRACE("(%p, %p, %p, %p, %f, %p)", c, vel, normal_force, pos, total_force, max_friction); |
||
| 2893 | |||
| 2894 | ts = BrVector3Dot(normal_force, vel) / BrVector3Dot(normal_force, normal_force); |
||
| 2895 | BrVector3Scale(&tv, normal_force, ts); |
||
| 2896 | BrVector3Sub(vel, vel, &tv); |
||
| 2897 | point_vel = total_force * 0.35f * gCurrent_race.material_modifiers[gMaterial_index].car_wall_friction; |
||
| 2898 | ts = BrVector3Length(vel); |
||
| 2899 | if (ts < 0.0001f) { |
||
| 2900 | BrVector3Set(max_friction, 0.f, 0.f, 0.f); |
||
| 2901 | return 0.0; |
||
| 2902 | } |
||
| 2903 | BrVector3InvScale(max_friction, vel, -ts); |
||
| 2904 | BrVector3Cross(&ftau, pos, max_friction); |
||
| 2905 | BrVector3Scale(&ftau, &ftau, c->M); |
||
| 2906 | ftau.v[0] = ftau.v[0] / c->I.v[0]; |
||
| 2907 | ftau.v[1] = ftau.v[1] / c->I.v[1]; |
||
| 2908 | ftau.v[2] = ftau.v[2] / c->I.v[2]; |
||
| 2909 | ts = 1.0 / c->M; |
||
| 2910 | norm.v[0] = pos->v[2] * ftau.v[1] - pos->v[1] * ftau.v[2]; |
||
| 2911 | norm.v[1] = pos->v[0] * ftau.v[2] - pos->v[2] * ftau.v[0]; |
||
| 2912 | norm.v[2] = pos->v[1] * ftau.v[0] - pos->v[0] * ftau.v[1]; |
||
| 2913 | ts = max_friction->v[0] * norm.v[0] + max_friction->v[1] * norm.v[1] + max_friction->v[2] * norm.v[2] + ts; |
||
| 2914 | if (fabsf(ts) <= 0.0001f) { |
||
| 2915 | ts = 0.0f; |
||
| 2916 | } else { |
||
| 2917 | ts = -BrVector3Dot(max_friction, vel) / ts; |
||
| 2918 | } |
||
| 2919 | if (ts > point_vel) { |
||
| 2920 | ts = point_vel; |
||
| 2921 | } |
||
| 2922 | BrVector3Scale(max_friction, max_friction, ts); |
||
| 2923 | BrVector3Cross(&tv, pos, max_friction); |
||
| 2924 | BrVector3Scale(&tv, &tv, c->M); |
||
| 2925 | ApplyTorque((tCar_spec*)c, &tv); |
||
| 2926 | return point_vel; |
||
| 2927 | } |
||
| 2928 | |||
| 2929 | // IDA: void __usercall AddFrictionCarToCar(tCollision_info *car1@<EAX>, tCollision_info *car2@<EDX>, br_vector3 *vel1@<EBX>, br_vector3 *vel2@<ECX>, br_vector3 *normal_force1, br_vector3 *pos1, br_vector3 *pos2, br_scalar total_force, br_vector3 *max_friction) |
||
| 2930 | void AddFrictionCarToCar(tCollision_info* car1, tCollision_info* car2, br_vector3* vel1, br_vector3* vel2, br_vector3* normal_force1, br_vector3* pos1, br_vector3* pos2, br_scalar total_force, br_vector3* max_friction) { |
||
| 2931 | br_vector3 v_diff1; |
||
| 2932 | br_vector3 v_diff2; |
||
| 2933 | br_vector3 tau1; |
||
| 2934 | br_vector3 tau2; |
||
| 2935 | br_vector3 tv; |
||
| 2936 | br_vector3 tv2; |
||
| 2937 | br_vector3 vel2_in_frame_1; |
||
| 2938 | br_scalar ts; |
||
| 2939 | br_scalar ts2; |
||
| 2940 | br_scalar v_diff; |
||
| 2941 | br_scalar stopping_impulse; |
||
| 2942 | br_scalar total_friction; |
||
| 2943 | int i; |
||
| 2944 | LOG_TRACE("(%p, %p, %p, %p, %p, %p, %p, %f, %p)", car1, car2, vel1, vel2, normal_force1, pos1, pos2, total_force, max_friction); |
||
| 2945 | |||
| 2946 | BrMatrix34TApplyV(&tv, vel2, &car2->oldmat); |
||
| 2947 | BrMatrix34ApplyV(&vel2_in_frame_1, &tv, &car1->oldmat); |
||
| 2948 | BrVector3Sub(&v_diff1, &vel2_in_frame_1, vel1); |
||
| 2949 | ts = BrVector3LengthSquared(normal_force1); |
||
| 2950 | ts2 = BrVector3Dot(normal_force1, &v_diff1) / ts; |
||
| 2951 | BrVector3Scale(&tv, normal_force1, ts2); |
||
| 2952 | BrVector3Sub(&v_diff1, &v_diff1, &tv); |
||
| 2953 | v_diff = BrVector3Length(&v_diff1); |
||
| 2954 | if (v_diff < 0.01f) { |
||
| 2955 | BrVector3Set(max_friction, 0.f, 0.f, 0.f); |
||
| 2956 | } else { |
||
| 2957 | BrVector3InvScale(&v_diff1, &v_diff1, v_diff); |
||
| 2958 | BrMatrix34ApplyV(&tv, &v_diff1, &car1->oldmat); |
||
| 2959 | BrMatrix34TApplyV(&v_diff2, &tv, &car2->oldmat); |
||
| 2960 | BrVector3Negate(&v_diff2, &v_diff2); |
||
| 2961 | BrVector3Cross(&tau1, pos1, &v_diff1); |
||
| 2962 | BrVector3Cross(&tau2, pos2, &v_diff2); |
||
| 2963 | for (i = 0; i < 3; ++i) { |
||
| 2964 | tau1.v[i] /= car1->I.v[i]; |
||
| 2965 | tau2.v[i] /= car2->I.v[i]; |
||
| 2966 | } |
||
| 2967 | BrVector3Cross(&tv, &tau1, pos1); |
||
| 2968 | BrVector3Cross(&tv2, &tau2, pos2); |
||
| 2969 | ts = BrVector3Dot(&tv, &v_diff1) + BrVector3Dot(&tv2, &v_diff2) + 1.f / car2->M + 1.f / car1->M; |
||
| 2970 | if (ts < 0.0001f) { |
||
| 2971 | BrVector3Set(max_friction, 0.f, 0.f, 0.f); |
||
| 2972 | } else { |
||
| 2973 | stopping_impulse = v_diff / ts; |
||
| 2974 | total_friction = total_force * 0.35f; |
||
| 2975 | if (stopping_impulse < total_friction) { |
||
| 2976 | total_friction = stopping_impulse; |
||
| 2977 | } |
||
| 2978 | if (!car1->infinite_mass) { |
||
| 2979 | BrVector3Scale(&tau1, &tau1, total_friction); |
||
| 2980 | BrVector3Accumulate(&car1->omega, &tau1); |
||
| 2981 | } |
||
| 2982 | if (!car2->infinite_mass) { |
||
| 2983 | BrVector3Scale(&tau2, &tau2, total_friction); |
||
| 2984 | BrVector3Accumulate(&car2->omega, &tau2); |
||
| 2985 | } |
||
| 2986 | BrVector3Scale(max_friction, &v_diff1, total_friction); |
||
| 2987 | } |
||
| 2988 | } |
||
| 2989 | } |
||
| 2990 | |||
| 2991 | // IDA: void __cdecl ScrapeNoise(br_scalar vel, br_vector3 *position, int material) |
||
| 2992 | void ScrapeNoise(br_scalar vel, br_vector3* position, int material) { |
||
| 2993 | tS3_volume vol; |
||
| 2994 | static tS3_sound_tag scrape_tag; |
||
| 2995 | static tS3_volume last_scrape_vol; |
||
| 2996 | br_vector3 velocity; |
||
| 2997 | //br_vector3 position_in_br; // Pierre-Marie Baty -- unused variable |
||
| 2998 | LOG_TRACE("(%f, %p, %d)", vel, position, material); |
||
| 2999 | |||
| 3000 | vol = vel * 7.0; |
||
| 3001 | if (gCurrent_race.material_modifiers[material].scrape_noise_index == -1) { |
||
| 3002 | return; |
||
| 3003 | } |
||
| 3004 | if ((scrape_tag && DRS3SoundStillPlaying(scrape_tag)) || vol <= 30) { |
||
| 3005 | if (last_scrape_vol < vol) { |
||
| 3006 | DRS3ChangeVolume(scrape_tag, vol); |
||
| 3007 | last_scrape_vol = vol; |
||
| 3008 | } |
||
| 3009 | } else { |
||
| 3010 | BrVector3Set(&velocity, 0.f, 0.f, 0.f); |
||
| 3011 | scrape_tag = DRS3StartSound3D( |
||
| 3012 | gCar_outlet, |
||
| 3013 | gMetal_scrape_sound_id__car[IRandomBetween(0, COUNT_OF(gMetal_scrape_sound_id__car) - 1)], |
||
| 3014 | position, |
||
| 3015 | &velocity, |
||
| 3016 | 1, |
||
| 3017 | vol, |
||
| 3018 | IRandomBetween(49152, 81920), |
||
| 3019 | 0x10000); |
||
| 3020 | last_scrape_vol = vol; |
||
| 3021 | } |
||
| 3022 | } |
||
| 3023 | |||
| 3024 | // IDA: void __usercall SkidNoise(tCar_spec *pC@<EAX>, int pWheel_num@<EDX>, br_scalar pV, int material) |
||
| 3025 | void SkidNoise(tCar_spec* pC, int pWheel_num, br_scalar pV, int material) { |
||
| 3026 | br_vector3 pos; |
||
| 3027 | br_vector3 world_pos; |
||
| 3028 | br_vector3 wv; |
||
| 3029 | br_vector3 wvw; |
||
| 3030 | br_scalar ts; |
||
| 3031 | static tS3_volume last_skid_vol[2]; |
||
| 3032 | int i; |
||
| 3033 | LOG_TRACE("(%p, %d, %f, %d)", pC, pWheel_num, pV, material); |
||
| 3034 | |||
| 3035 | i = IRandomBetween(0, 1); |
||
| 3036 | if (gCurrent_race.material_modifiers[material].tyre_noise_index == -1) { |
||
| 3037 | return; |
||
| 3038 | } |
||
| 3039 | if (IRandomBetween(0, 4) != 0) { |
||
| 3040 | return; |
||
| 3041 | } |
||
| 3042 | |||
| 3043 | last_skid_vol[i] = pV * 10.0; |
||
| 3044 | if ((pWheel_num & 1) != 0) { |
||
| 3045 | pos.v[0] = pC->bounds[1].max.v[0]; |
||
| 3046 | } else { |
||
| 3047 | pos.v[0] = pC->bounds[1].min.v[0]; |
||
| 3048 | } |
||
| 3049 | pos.v[1] = pC->wpos[pWheel_num].v[1] - pC->oldd[pWheel_num]; |
||
| 3050 | pos.v[2] = pC->wpos[pWheel_num].v[2]; |
||
| 3051 | BrMatrix34ApplyP(&world_pos, &pos, &pC->car_master_actor->t.t.mat); |
||
| 3052 | BrVector3InvScale(&world_pos, &world_pos, WORLD_SCALE); |
||
| 3053 | if (!DRS3SoundStillPlaying(gSkid_tag[i]) || (pC->driver == eDriver_local_human && gLast_car_to_skid[i] != pC)) { |
||
| 3054 | gSkid_tag[i] = DRS3StartSound3D( |
||
| 3055 | gCar_outlet, |
||
| 3056 | IRandomBetween(0, 4) + 9000, |
||
| 3057 | &world_pos, |
||
| 3058 | &pC->velocity_bu_per_sec, |
||
| 3059 | 1, |
||
| 3060 | last_skid_vol[i], |
||
| 3061 | IRandomBetween(49152, 81920), |
||
| 3062 | 0x10000); |
||
| 3063 | gLast_car_to_skid[i] = pC; |
||
| 3064 | } |
||
| 3065 | if (gCurrent_race.material_modifiers[material].smoke_type == 1) { |
||
| 3066 | BrVector3Cross(&wv, &pC->omega, &pos); |
||
| 3067 | BrVector3Add(&wv, &wv, &pC->velocity_car_space); |
||
| 3068 | ts = -(BrVector3Dot(&wv, &pC->road_normal)); |
||
| 3069 | BrVector3Scale(&wvw, &pC->road_normal, ts); |
||
| 3070 | BrVector3Add(&wv, &wv, &wvw); |
||
| 3071 | BrMatrix34ApplyV(&wvw, &wv, &pC->car_master_actor->t.t.mat); |
||
| 3072 | CreatePuffOfSmoke(&world_pos, &wvw, pV / 25.0, 1.0, 4, pC); |
||
| 3073 | } |
||
| 3074 | } |
||
| 3075 | |||
| 3076 | // IDA: void __usercall StopSkid(tCar_spec *pC@<EAX>) |
||
| 3077 | void StopSkid(tCar_spec* pC) { |
||
| 3078 | LOG_TRACE("(%p)", pC); |
||
| 3079 | |||
| 3080 | if (gLast_car_to_skid[0] == pC) { |
||
| 3081 | DRS3StopSound(gSkid_tag[0]); |
||
| 3082 | } |
||
| 3083 | if (gLast_car_to_skid[1] == pC) { |
||
| 3084 | DRS3StopSound(gSkid_tag[1]); |
||
| 3085 | } |
||
| 3086 | } |
||
| 3087 | |||
| 3088 | // IDA: void __usercall CrashNoise(br_vector3 *pForce@<EAX>, br_vector3 *position@<EDX>, int material@<EBX>) |
||
| 3089 | void CrashNoise(br_vector3* pForce, br_vector3* position, int material) { |
||
| 3090 | static tS3_sound_tag crunch_tag; |
||
| 3091 | static tS3_volume last_crunch_vol; |
||
| 3092 | tS3_volume vol; |
||
| 3093 | br_vector3 velocity; |
||
| 3094 | LOG_TRACE("(%p, %p, %d)", pForce, position, material); |
||
| 3095 | |||
| 3096 | vol = 60.f * BrVector3Length(pForce); |
||
| 3097 | if (gCurrent_race.material_modifiers[material].crash_noise_index != -1) { |
||
| 3098 | if (vol >= 256) { |
||
| 3099 | vol = 255; |
||
| 3100 | } |
||
| 3101 | if (crunch_tag == 0 || (!DRS3SoundStillPlaying(crunch_tag) && vol > 30)) { |
||
| 3102 | last_crunch_vol = vol; |
||
| 3103 | (void)last_crunch_vol; |
||
| 3104 | BrVector3Set(&velocity, 0.f, 0.f, 0.f); |
||
| 3105 | crunch_tag = DRS3StartSound3D(gCar_outlet, |
||
| 3106 | gMetal_crunch_sound_id__car[IRandomBetween(0, COUNT_OF(gMetal_crunch_sound_id__car) - 1)], |
||
| 3107 | position, &velocity, 1, vol, IRandomBetween(49152, 81920), 0x10000); |
||
| 3108 | } |
||
| 3109 | } |
||
| 3110 | } |
||
| 3111 | |||
| 3112 | // IDA: void __usercall CrushAndDamageCar(tCar_spec *c@<EAX>, br_vector3 *pPosition@<EDX>, br_vector3 *pForce_car_space@<EBX>, tCar_spec *car2@<ECX>) |
||
| 3113 | void CrushAndDamageCar(tCar_spec* c, br_vector3* pPosition, br_vector3* pForce_car_space, tCar_spec* car2) { |
||
| 3114 | br_vector3 force; |
||
| 3115 | //br_vector3 force2; // Pierre-Marie Baty -- unused variable |
||
| 3116 | br_vector3 position; |
||
| 3117 | br_vector3 pos_w; |
||
| 3118 | br_vector3 car_to_cam; |
||
| 3119 | br_vector3 force_for_bodywork; |
||
| 3120 | br_scalar ts; |
||
| 3121 | int i; |
||
| 3122 | br_matrix34 m; |
||
| 3123 | br_scalar fudge_multiplier; |
||
| 3124 | LOG_TRACE("(%p, %p, %p, %p)", c, pPosition, pForce_car_space, car2); |
||
| 3125 | |||
| 3126 | if (car2 != NULL) { |
||
| 3127 | car2->who_last_hit_me = c; |
||
| 3128 | c->who_last_hit_me = car2; |
||
| 3129 | } |
||
| 3130 | |||
| 3131 | if (c->driver == eDriver_non_car_unused_slot || c->driver == eDriver_non_car) { |
||
| 3132 | return; |
||
| 3133 | } |
||
| 3134 | fudge_multiplier = gNet_mode == eNet_mode_none || gNet_softness[gCurrent_net_game->type] == 1.0f ? 1.0f : gNet_softness[gCurrent_net_game->type]; |
||
| 3135 | BrVector3Sub(&car_to_cam, &c->pos, (br_vector3*)gCamera_to_world.m[3]); |
||
| 3136 | ts = BrVector3LengthSquared(&car_to_cam); |
||
| 3137 | if (c->driver == eDriver_oppo && ts > 200.0f) { |
||
| 3138 | return; |
||
| 3139 | } |
||
| 3140 | if (car2 != NULL) { |
||
| 3141 | if (car2->driver > eDriver_non_car) { |
||
| 3142 | TwoCarsHitEachOther(c, car2); |
||
| 3143 | } |
||
| 3144 | if (c->driver >= eDriver_net_human) { |
||
| 3145 | fudge_multiplier = gDefensive_powerup_factor[c->power_up_levels[0]] * 1.2f * fudge_multiplier; |
||
| 3146 | } |
||
| 3147 | if (car2->driver >= eDriver_net_human) { |
||
| 3148 | if (gNet_mode != eNet_mode_none |
||
| 3149 | && (gCurrent_net_game->type == eNet_game_type_fight_to_death || gCurrent_net_game->type == eNet_game_type_car_crusher)) { |
||
| 3150 | fudge_multiplier = gOffensive_powerup_factor[car2->power_up_levels[2]] * gNet_offensive[gCurrent_net_game->type] * car2->damage_multiplier * fudge_multiplier; |
||
| 3151 | } else { |
||
| 3152 | fudge_multiplier = gOffensive_powerup_factor[car2->power_up_levels[2]] * car2->damage_multiplier * fudge_multiplier; |
||
| 3153 | } |
||
| 3154 | } |
||
| 3155 | if (c->driver == eDriver_oppo && car2->driver == eDriver_oppo) { |
||
| 3156 | fudge_multiplier = fudge_multiplier * 0.2f; |
||
| 3157 | } |
||
| 3158 | if (car2->driver <= eDriver_non_car) { |
||
| 3159 | car2 = NULL; |
||
| 3160 | } else { |
||
| 3161 | fudge_multiplier /= ((car2->car_model_actors[car2->principal_car_actor].crush_data.softness_factor + 0.7f) / 0.7f); |
||
| 3162 | } |
||
| 3163 | } |
||
| 3164 | BrVector3InvScale(&position, pPosition, WORLD_SCALE); |
||
| 3165 | BrVector3Scale(&force, pForce_car_space, fudge_multiplier * 0.03f); |
||
| 3166 | ts = BrVector3LengthSquared(&force); |
||
| 3167 | if (c->driver <= eDriver_non_car || !c->invulnerable) { |
||
| 3168 | c->damage_magnitude_accumulator += ts; |
||
| 3169 | } |
||
| 3170 | if (c->driver < eDriver_net_human) { |
||
| 3171 | BrVector3Scale(&force_for_bodywork, &force, 1.5f); |
||
| 3172 | } else { |
||
| 3173 | if (c->collision_mass_multiplier != 1.0) { |
||
| 3174 | BrVector3InvScale(&force, &force, c->collision_mass_multiplier); |
||
| 3175 | } |
||
| 3176 | BrVector3Scale(&force_for_bodywork, &force, 0.5f); |
||
| 3177 | if (c->driver == eDriver_local_human) { |
||
| 3178 | DoPratcamHit(&force); |
||
| 3179 | } |
||
| 3180 | } |
||
| 3181 | if (gNet_mode == eNet_mode_host && (gCurrent_net_game->type == eNet_game_type_tag || gCurrent_net_game->type == eNet_game_type_foxy) && car2 != NULL |
||
| 3182 | && c->driver >= eDriver_net_human && car2->driver >= eDriver_net_human) { |
||
| 3183 | if (gNet_players[gIt_or_fox].car == c && car2->knackered) { |
||
| 3184 | CarInContactWithItOrFox(NetPlayerFromCar(car2)); |
||
| 3185 | } else if (gNet_players[gIt_or_fox].car == car2 && !c->knackered) { |
||
| 3186 | CarInContactWithItOrFox(NetPlayerFromCar(c)); |
||
| 3187 | } |
||
| 3188 | } |
||
| 3189 | if (gNet_mode != eNet_mode_client || car2 == NULL) { |
||
| 3190 | DamageSystems(c, &position, &force, car2 != NULL); |
||
| 3191 | } |
||
| 3192 | if (c->driver <= eDriver_non_car || !c->invulnerable) { |
||
| 3193 | for (i = 0; i < c->car_actor_count; i++) { |
||
| 3194 | if (c->car_model_actors[i].min_distance_squared != -1.0f || (pForce_car_space->v[1] >= 0.0f && pForce_car_space->v[2] >= 0.0f)) { |
||
| 3195 | CrushModel(c, i, c->car_model_actors[i].actor, &position, &force_for_bodywork, &c->car_model_actors[i].crush_data); |
||
| 3196 | } |
||
| 3197 | } |
||
| 3198 | if (car2 && car2->driver == eDriver_local_human && ts > 0.003f) { |
||
| 3199 | PipeSingleCarIncident(ts, c, &position); |
||
| 3200 | } |
||
| 3201 | if (!car2 && c->driver == eDriver_local_human && ts > 0.003f) { |
||
| 3202 | BrMatrix34Copy(&m, &c->car_master_actor->t.t.mat); |
||
| 3203 | m.m[3][0] /= WORLD_SCALE; |
||
| 3204 | m.m[3][1] /= WORLD_SCALE; |
||
| 3205 | m.m[3][2] /= WORLD_SCALE; |
||
| 3206 | BrMatrix34ApplyP(&pos_w, &position, &m); |
||
| 3207 | PipeSingleWallIncident(ts, &pos_w); |
||
| 3208 | } |
||
| 3209 | } |
||
| 3210 | if (car2 != NULL && car2->driver == eDriver_local_human && ts > 0.003f) { |
||
| 3211 | PipeSingleCarIncident(ts, c, &position); |
||
| 3212 | } |
||
| 3213 | if (car2 == NULL && c->driver == eDriver_local_human && ts > 0.003f) { |
||
| 3214 | BrMatrix34Copy(&m, &c->car_master_actor->t.t.mat); |
||
| 3215 | m.m[3][0] /= WORLD_SCALE; |
||
| 3216 | m.m[3][1] /= WORLD_SCALE; |
||
| 3217 | m.m[3][2] /= WORLD_SCALE; |
||
| 3218 | BrMatrix34ApplyP(&pos_w, &position, &m); |
||
| 3219 | PipeSingleWallIncident(ts, &pos_w); |
||
| 3220 | } |
||
| 3221 | } |
||
| 3222 | |||
| 3223 | // IDA: int __usercall ExpandBoundingBox@<EAX>(tCar_spec *c@<EAX>) |
||
| 3224 | int ExpandBoundingBox(tCar_spec* c) { |
||
| 3225 | br_scalar min_z; |
||
| 3226 | br_scalar max_z; |
||
| 3227 | br_scalar dist; |
||
| 3228 | br_vector3 tv; |
||
| 3229 | br_vector3 old_pos; |
||
| 3230 | int l; |
||
| 3231 | //br_matrix34 mat; // Pierre-Marie Baty -- unused variable |
||
| 3232 | LOG_TRACE("(%p)", c); |
||
| 3233 | |||
| 3234 | l = 0; |
||
| 3235 | min_z = c->bounds[1].min.v[2]; |
||
| 3236 | max_z = c->bounds[1].max.v[2]; |
||
| 3237 | old_pos = *(br_vector3*)&c->oldmat.m[3][0]; |
||
| 3238 | CrushBoundingBox(c, 0); |
||
| 3239 | for (l = 0; l < 5; l++) { |
||
| 3240 | if (TestForCarInSensiblePlace(c)) { |
||
| 3241 | break; |
||
| 3242 | } |
||
| 3243 | if (c->old_point.v[2] <= 0.0f) { |
||
| 3244 | dist = min_z - c->bounds[1].min.v[2]; |
||
| 3245 | } else { |
||
| 3246 | dist = c->bounds[1].max.v[2] - max_z; |
||
| 3247 | } |
||
| 3248 | if (dist >= 0.0f) { |
||
| 3249 | dist += 0.005f; |
||
| 3250 | BrVector3Scale(&c->old_norm, &c->old_norm, dist); |
||
| 3251 | BrMatrix34ApplyV(&tv, &c->old_norm, &c->car_master_actor->t.t.mat); |
||
| 3252 | c->oldmat.m[3][0] += tv.v[0]; |
||
| 3253 | c->oldmat.m[3][1] += tv.v[1]; |
||
| 3254 | c->oldmat.m[3][2] += tv.v[2]; |
||
| 3255 | l++; |
||
| 3256 | } else { |
||
| 3257 | l = 5; |
||
| 3258 | } |
||
| 3259 | } |
||
| 3260 | if (l < 5) { |
||
| 3261 | return 1; |
||
| 3262 | } |
||
| 3263 | *(br_vector3*)&c->oldmat.m[3][0] = old_pos; |
||
| 3264 | c->bounds[1].min.v[2] = min_z; |
||
| 3265 | c->bounds[1].max.v[2] = max_z; |
||
| 3266 | if (c->driver == eDriver_local_human) { |
||
| 21 | pmbaty | 3267 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 1000, -4, GetMiscString(kMiscString_RepairObstructed)); |
| 1 | pmbaty | 3268 | } |
| 3269 | return 0; |
||
| 3270 | } |
||
| 3271 | |||
| 3272 | // IDA: void __usercall CrushBoundingBox(tCar_spec *c@<EAX>, int crush_only@<EDX>) |
||
| 3273 | void CrushBoundingBox(tCar_spec* c, int crush_only) { |
||
| 3274 | br_vector3 min; |
||
| 3275 | br_vector3 max; |
||
| 3276 | int i; |
||
| 3277 | br_actor* actor; |
||
| 3278 | LOG_TRACE("(%p, %d)", c, crush_only); |
||
| 3279 | |||
| 3280 | if (c == NULL) { |
||
| 3281 | return; |
||
| 3282 | } |
||
| 3283 | actor = c->car_model_actors[c->principal_car_actor].actor; |
||
| 3284 | max.v[0] = c->wpos[2].v[2] - c->non_driven_wheels_circum / 6.2f; |
||
| 3285 | min.v[0] = c->driven_wheels_circum / 6.2f + c->wpos[0].v[2]; |
||
| 3286 | max.v[0] /= WORLD_SCALE; |
||
| 3287 | min.v[0] /= WORLD_SCALE; |
||
| 3288 | for (i = 0; i < actor->model->nvertices; i++) { |
||
| 3289 | if (actor->model->vertices[i].p.v[2] < max.v[0]) { |
||
| 3290 | max.v[0] = actor->model->vertices[i].p.v[2]; |
||
| 3291 | } |
||
| 3292 | if (actor->model->vertices[i].p.v[2] > min.v[0]) { |
||
| 3293 | min.v[0] = actor->model->vertices[i].p.v[2]; |
||
| 3294 | } |
||
| 3295 | } |
||
| 3296 | max.v[0] *= WORLD_SCALE; |
||
| 3297 | min.v[0] *= WORLD_SCALE; |
||
| 3298 | if (crush_only) { |
||
| 3299 | if (c->bounds[1].min.v[2] > max.v[0]) { |
||
| 3300 | max.v[0] = c->bounds[1].min.v[2]; |
||
| 3301 | } |
||
| 3302 | if (c->bounds[1].max.v[2] < min.v[0]) { |
||
| 3303 | min.v[0] = c->bounds[1].max.v[2]; |
||
| 3304 | } |
||
| 3305 | } else { |
||
| 3306 | if (c->max_bounds[1].min.v[2] > max.v[0]) { |
||
| 3307 | max.v[0] = c->max_bounds[1].min.v[2]; |
||
| 3308 | } |
||
| 3309 | if (c->max_bounds[1].max.v[2] < min.v[0]) { |
||
| 3310 | min.v[0] = c->max_bounds[1].max.v[2]; |
||
| 3311 | } |
||
| 3312 | } |
||
| 3313 | c->bounds[1].min.v[2] = max.v[0]; |
||
| 3314 | c->bounds[1].max.v[2] = min.v[0]; |
||
| 3315 | for (i = 0; i < c->extra_point_num; i++) { |
||
| 3316 | if (c->max_bounds[1].max.v[2] + 0.01f >= c->original_extra_points_z[i] && c->max_bounds[1].min.v[2] - 0.01f <= c->original_extra_points_z[i]) { |
||
| 3317 | if (c->original_extra_points_z[i] > min.v[0]) { |
||
| 3318 | c->extra_points[i].v[2] = min.v[0]; |
||
| 3319 | } else if (c->original_extra_points_z[i] >= max.v[0]) { |
||
| 3320 | c->extra_points[i].v[2] = c->original_extra_points_z[i]; |
||
| 3321 | } else { |
||
| 3322 | c->extra_points[i].v[2] = max.v[0]; |
||
| 3323 | } |
||
| 3324 | if (c->extra_points[i].v[2] > min.v[0]) { |
||
| 3325 | c->extra_points[i].v[2] = min.v[0]; |
||
| 3326 | } |
||
| 3327 | if (c->extra_points[i].v[2] < max.v[0]) { |
||
| 3328 | c->extra_points[i].v[2] = max.v[0]; |
||
| 3329 | } |
||
| 3330 | } else { |
||
| 3331 | c->extra_points[i].v[2] = c->original_extra_points_z[i]; |
||
| 3332 | } |
||
| 3333 | } |
||
| 3334 | } |
||
| 3335 | |||
| 3336 | // IDA: void __cdecl AddCollPoint(br_scalar dist, br_vector3 *p, br_vector3 *norm, br_vector3 *r, br_vector3 *n, br_vector3 *dir, int num, tCollision_info *c) |
||
| 3337 | void AddCollPoint(br_scalar dist, br_vector3* p, br_vector3* norm, br_vector3* r, br_vector3* n, br_vector3* dir, int num, tCollision_info* c) { |
||
| 3338 | static br_scalar d[4]; |
||
| 3339 | int i; |
||
| 3340 | int furthest; |
||
| 3341 | LOG_TRACE("(%f, %p, %p, %p, %p, %p, %d, %p)", dist, p, norm, r, n, dir, num, c); |
||
| 3342 | |||
| 3343 | if (num < 4) { |
||
| 3344 | d[num] = dist; |
||
| 3345 | n[num] = *norm; |
||
| 3346 | BrVector3Sub(&r[num], p, &c->cmpos); |
||
| 3347 | return; |
||
| 3348 | } |
||
| 3349 | furthest = 0; |
||
| 3350 | for (i = 1; i < 4; i++) { |
||
| 3351 | if (d[furthest] < d[i]) { |
||
| 3352 | furthest = i; |
||
| 3353 | } |
||
| 3354 | } |
||
| 3355 | if (d[furthest] >= dist) { |
||
| 3356 | num = furthest; |
||
| 3357 | d[num] = dist; |
||
| 3358 | n[num] = *norm; |
||
| 3359 | BrVector3Sub(&r[num], p, &c->cmpos); |
||
| 3360 | } |
||
| 3361 | } |
||
| 3362 | |||
| 3363 | // IDA: br_scalar __usercall SinglePointColl@<ST0>(br_scalar *f@<EAX>, br_matrix4 *m@<EDX>, br_scalar *d@<EBX>) |
||
| 3364 | br_scalar SinglePointColl(br_scalar* f, br_matrix4* m, br_scalar* d) { |
||
| 3365 | LOG_TRACE("(%p, %p, %p)", f, m, d); |
||
| 3366 | |||
| 3367 | f[0] = d[0] / m->m[0][0]; |
||
| 3368 | if (f[0] < 0.0f) { |
||
| 3369 | f[0] = 0.f; |
||
| 3370 | } |
||
| 3371 | return fabsf(m->m[0][0]); |
||
| 3372 | } |
||
| 3373 | |||
| 3374 | // IDA: br_scalar __usercall TwoPointColl@<ST0>(br_scalar *f@<EAX>, br_matrix4 *m@<EDX>, br_scalar *d@<EBX>, br_vector3 *tau@<ECX>, br_vector3 *n) |
||
| 3375 | br_scalar TwoPointColl(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n) { |
||
| 3376 | br_scalar ts; |
||
| 3377 | LOG_TRACE("(%p, %p, %p, %p, %p)", f, m, d, tau, n); |
||
| 3378 | |||
| 3379 | ts = m->m[1][1] * m->m[0][0] - m->m[0][1] * m->m[1][0]; |
||
| 3380 | |||
| 3381 | if (fabsf(ts) >= 0.000001f) { |
||
| 3382 | f[0] = (m->m[1][1] * d[0] - m->m[0][1] * d[1]) / ts; |
||
| 3383 | f[1] = (m->m[1][0] * d[0] - m->m[0][0] * d[1]) / -ts; |
||
| 3384 | } |
||
| 3385 | if (f[1] < 0.0f || fabs(ts) < 0.000001f) { |
||
| 3386 | ts = SinglePointColl(f, m, d); |
||
| 3387 | f[1] = 0.0f; |
||
| 3388 | } else if (f[0] < 0.0f) { |
||
| 3389 | m->m[0][0] = m->m[1][1]; |
||
| 3390 | tau[0] = tau[1]; |
||
| 3391 | n[0] = n[1]; |
||
| 3392 | d[0] = d[1]; |
||
| 3393 | ts = SinglePointColl(f, m, d); |
||
| 3394 | f[1] = 0.0; |
||
| 3395 | } |
||
| 3396 | return fabsf(ts); |
||
| 3397 | } |
||
| 3398 | |||
| 3399 | // IDA: br_scalar __usercall DrMatrix4Inverse@<ST0>(br_matrix4 *mi@<EAX>, br_matrix4 *mc@<EDX>) |
||
| 3400 | br_scalar DrMatrix4Inverse(br_matrix4* mi, br_matrix4* mc) { |
||
| 3401 | LOG_TRACE("(%p, %p)", mi, mc); |
||
| 3402 | |||
| 3403 | return BrMatrix4Inverse(mi, mc); |
||
| 3404 | } |
||
| 3405 | |||
| 3406 | // IDA: br_scalar __usercall ThreePointColl@<ST0>(br_scalar *f@<EAX>, br_matrix4 *m@<EDX>, br_scalar *d@<EBX>) |
||
| 3407 | br_scalar ThreePointColl(br_scalar* f, br_matrix4* m, br_scalar* d) { |
||
| 3408 | br_matrix4 mc; |
||
| 3409 | br_matrix4 mi; |
||
| 3410 | br_scalar ts; |
||
| 3411 | LOG_TRACE("(%p, %p, %p)", f, m, d); |
||
| 3412 | |||
| 3413 | BrMatrix4Copy(&mc, m); |
||
| 3414 | memset(&mc.m[2][3], 0, 16); |
||
| 3415 | mc.m[1][3] = 0.0f; |
||
| 3416 | mc.m[0][3] = 0.0f; |
||
| 3417 | mc.m[3][3] = 1.0f; |
||
| 3418 | ts = DrMatrix4Inverse(&mi, &mc); |
||
| 3419 | BrMatrix4TApply((br_vector4*)f, (br_vector4*)d, &mi); |
||
| 3420 | f[3] = 0.0f; |
||
| 3421 | return fabs(ts); |
||
| 3422 | } |
||
| 3423 | |||
| 3424 | // IDA: br_scalar __usercall ThreePointCollRec@<ST0>(br_scalar *f@<EAX>, br_matrix4 *m@<EDX>, br_scalar *d@<EBX>, br_vector3 *tau@<ECX>, br_vector3 *n, tCollision_info *c) |
||
| 3425 | br_scalar ThreePointCollRec(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n, tCollision_info* c) { |
||
| 3426 | int i; |
||
| 3427 | int j; |
||
| 3428 | br_scalar ts; |
||
| 3429 | LOG_TRACE("(%p, %p, %p, %p, %p, %p)", f, m, d, tau, n, c); |
||
| 3430 | |||
| 3431 | ts = ThreePointColl(f, m, d); |
||
| 3432 | if (f[0] >= 0.0f && f[1] >= 0.0f && f[2] >= 0.0f && ts >= 0.000001f) { |
||
| 3433 | c->infinite_mass = 256; |
||
| 3434 | return ts; |
||
| 3435 | } |
||
| 3436 | if (ts < 0.000001f) { |
||
| 3437 | i = 0; |
||
| 3438 | j = 1; |
||
| 3439 | } else if (f[0] < 0.0f) { |
||
| 3440 | i = 1; |
||
| 3441 | j = 2; |
||
| 3442 | } else if (f[1] < 0.0f) { |
||
| 3443 | i = 0; |
||
| 3444 | j = 2; |
||
| 3445 | } else if (f[2] < 0.0f) { |
||
| 3446 | i = 0; |
||
| 3447 | j = 1; |
||
| 3448 | } else { |
||
| 3449 | return 0.0f; |
||
| 3450 | } |
||
| 3451 | m->m[0][0] = ((float*)m->m)[5 * i]; |
||
| 3452 | m->m[1][0] = m->m[j][i]; |
||
| 3453 | m->m[0][1] = m->m[i][j]; |
||
| 3454 | m->m[1][1] = ((float*)m->m)[5 * j]; |
||
| 3455 | tau[0] = tau[i]; |
||
| 3456 | tau[1] = tau[j]; |
||
| 3457 | n[0] = n[i]; |
||
| 3458 | n[1] = n[j]; |
||
| 3459 | d[0] = d[i]; |
||
| 3460 | d[1] = d[j]; |
||
| 3461 | ts = TwoPointColl(f, m, d, tau, n); |
||
| 3462 | f[2] = 0.0f; |
||
| 3463 | return ts; |
||
| 3464 | } |
||
| 3465 | |||
| 3466 | // IDA: br_scalar __usercall FourPointColl@<ST0>(br_scalar *f@<EAX>, br_matrix4 *m@<EDX>, br_scalar *d@<EBX>, br_vector3 *tau@<ECX>, br_vector3 *n, tCollision_info *c) |
||
| 3467 | br_scalar FourPointColl(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n, tCollision_info* c) { |
||
| 3468 | int i; |
||
| 3469 | int j; |
||
| 3470 | int l; |
||
| 3471 | br_scalar ts; |
||
| 3472 | LOG_TRACE("(%p, %p, %p, %p, %p, %p)", f, m, d, tau, n, c); |
||
| 3473 | |||
| 3474 | ts = ThreePointColl(f, m, d); |
||
| 3475 | if (f[0] < 0.0 || f[1] < 0.0 || f[2] < 0.0 || ts < 0.000001) { |
||
| 3476 | if (ts < 0.000001) { |
||
| 3477 | j = 3; |
||
| 3478 | } else if (f[0] < 0.0) { |
||
| 3479 | j = 0; |
||
| 3480 | } else if (f[1] >= 0.0) { |
||
| 3481 | j = 2; |
||
| 3482 | } else { |
||
| 3483 | j = 1; |
||
| 3484 | } |
||
| 3485 | for (i = j; i < 3; ++i) { |
||
| 3486 | for (l = 0; l < 4; ++l) { |
||
| 3487 | m->m[i][l] = m->m[i + 1][l]; |
||
| 3488 | } |
||
| 3489 | d[i] = d[i + 1]; |
||
| 3490 | tau[i] = tau[i + 1]; |
||
| 3491 | n[i] = n[i + 1]; |
||
| 3492 | d[i] = d[i + 1]; |
||
| 3493 | } |
||
| 3494 | for (i = j; i < 3; ++i) { |
||
| 3495 | for (l = 0; l < 3; ++l) { |
||
| 3496 | m->m[l][i] = m->m[l][i + 1]; |
||
| 3497 | } |
||
| 3498 | } |
||
| 3499 | return ThreePointCollRec(f, m, d, tau, n, c); |
||
| 3500 | } else { |
||
| 3501 | c->infinite_mass = 256; |
||
| 3502 | return ts; |
||
| 3503 | } |
||
| 3504 | } |
||
| 3505 | |||
| 3506 | // IDA: void __usercall MultiFindFloorInBoxM(int pNum_rays@<EAX>, br_vector3 *a@<EDX>, br_vector3 *b@<EBX>, br_vector3 *nor@<ECX>, br_scalar *d, tCar_spec *c, int *mat_ref) |
||
| 3507 | void MultiFindFloorInBoxM(int pNum_rays, br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, tCar_spec* c, int* mat_ref) { |
||
| 3508 | br_vector3 aa[4]; |
||
| 3509 | br_vector3 bb; |
||
| 3510 | int i; |
||
| 3511 | LOG_TRACE("(%d, %p, %p, %p, %p, %p, %p)", pNum_rays, a, b, nor, d, c, mat_ref); |
||
| 3512 | |||
| 3513 | for (i = 0; i < pNum_rays; i++) { |
||
| 3514 | aa[i].v[0] = a[i].v[0] / WORLD_SCALE; |
||
| 3515 | aa[i].v[1] = a[i].v[1] / WORLD_SCALE; |
||
| 3516 | aa[i].v[2] = a[i].v[2] / WORLD_SCALE; |
||
| 3517 | d[i] = 2.0; |
||
| 3518 | } |
||
| 3519 | bb.v[0] = b->v[0] / WORLD_SCALE; |
||
| 3520 | bb.v[1] = b->v[1] / WORLD_SCALE; |
||
| 3521 | bb.v[2] = b->v[2] / WORLD_SCALE; |
||
| 3522 | MultiFindFloorInBoxBU(pNum_rays, aa, &bb, nor, d, c, mat_ref); |
||
| 3523 | } |
||
| 3524 | |||
| 3525 | // IDA: void __usercall MultiFindFloorInBoxBU(int pNum_rays@<EAX>, br_vector3 *a@<EDX>, br_vector3 *b@<EBX>, br_vector3 *nor@<ECX>, br_scalar *d, tCar_spec *c, int *mat_ref) |
||
| 3526 | void MultiFindFloorInBoxBU(int pNum_rays, br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, tCar_spec* c, int* mat_ref) { |
||
| 3527 | br_vector3 nor2; |
||
| 3528 | int i; |
||
| 3529 | int j; |
||
| 3530 | int l; |
||
| 3531 | br_scalar dist[4]; |
||
| 3532 | tFace_ref* face_ref; |
||
| 3533 | LOG_TRACE("(%d, %p, %p, %p, %p, %p, %p)", pNum_rays, a, b, nor, d, c, mat_ref); |
||
| 3534 | |||
| 3535 | for (i = c->box_face_start; i < c->box_face_end; i++) { |
||
| 3536 | face_ref = &gFace_list__car[i]; |
||
| 3537 | if (!gEliminate_faces || (face_ref->flags & 0x80) == 0x0) { |
||
| 3538 | MultiRayCheckSingleFace(pNum_rays, face_ref, a, b, &nor2, dist); |
||
| 3539 | for (j = 0; j < pNum_rays; ++j) { |
||
| 3540 | if (d[j] > dist[j]) { |
||
| 3541 | d[j] = dist[j]; |
||
| 3542 | nor[j] = nor2; |
||
| 3543 | l = *gFace_list__car[i].material->identifier - 47; |
||
| 3544 | if (l >= 0 && l < 11) { |
||
| 3545 | mat_ref[j] = l; |
||
| 3546 | } |
||
| 3547 | } |
||
| 3548 | } |
||
| 3549 | } |
||
| 3550 | } |
||
| 3551 | } |
||
| 3552 | |||
| 3553 | // IDA: void __usercall findfloor(br_vector3 *a@<EAX>, br_vector3 *b@<EDX>, br_vector3 *nor@<EBX>, br_scalar *d@<ECX>) |
||
| 3554 | void findfloor(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d) { |
||
| 3555 | br_material* material; |
||
| 3556 | br_vector3 aa; |
||
| 3557 | br_vector3 bb; |
||
| 3558 | LOG_TRACE("(%p, %p, %p, %p)", a, b, nor, d); |
||
| 3559 | |||
| 3560 | BrVector3InvScale(&aa, a, WORLD_SCALE); |
||
| 3561 | BrVector3InvScale(&bb, b, WORLD_SCALE); |
||
| 3562 | FindFace(&aa, &bb, nor, d, &material); |
||
| 3563 | } |
||
| 3564 | |||
| 3565 | // IDA: int __usercall FindFloorInBoxM@<EAX>(br_vector3 *a@<EAX>, br_vector3 *b@<EDX>, br_vector3 *nor@<EBX>, br_scalar *d@<ECX>, tCollision_info *c) |
||
| 3566 | int FindFloorInBoxM(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, tCollision_info* c) { |
||
| 3567 | br_vector3 aa; |
||
| 3568 | br_vector3 bb; |
||
| 3569 | LOG_TRACE("(%p, %p, %p, %p, %p)", a, b, nor, d, c); |
||
| 3570 | |||
| 3571 | aa.v[0] = a->v[0] / WORLD_SCALE; |
||
| 3572 | aa.v[1] = a->v[1] / WORLD_SCALE; |
||
| 3573 | aa.v[2] = a->v[2] / WORLD_SCALE; |
||
| 3574 | bb.v[0] = b->v[0] / WORLD_SCALE; |
||
| 3575 | bb.v[1] = b->v[1] / WORLD_SCALE; |
||
| 3576 | bb.v[2] = b->v[2] / WORLD_SCALE; |
||
| 3577 | return FindFloorInBoxBU(&aa, &bb, nor, d, c); |
||
| 3578 | } |
||
| 3579 | |||
| 3580 | // IDA: int __usercall FindFloorInBoxBU@<EAX>(br_vector3 *a@<EAX>, br_vector3 *b@<EDX>, br_vector3 *nor@<EBX>, br_scalar *d@<ECX>, tCollision_info *c) |
||
| 3581 | int FindFloorInBoxBU(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, tCollision_info* c) { |
||
| 3582 | br_vector3 nor2; |
||
| 3583 | int i; |
||
| 3584 | int j; |
||
| 3585 | br_scalar dist; |
||
| 3586 | tFace_ref* face_ref; |
||
| 3587 | LOG_TRACE("(%p, %p, %p, %p, %p)", a, b, nor, d, c); |
||
| 3588 | |||
| 3589 | #if defined(DETHRACE_FIX_BUGS) |
||
| 3590 | j = 0; // added to keep compiler happy |
||
| 3591 | #endif |
||
| 3592 | *d = 2.0; |
||
| 3593 | for (i = c->box_face_start; i < c->box_face_end; i++) { |
||
| 3594 | face_ref = &gFace_list__car[i]; |
||
| 3595 | if (!gEliminate_faces || SLOBYTE(face_ref->flags) >= 0) { |
||
| 3596 | CheckSingleFace(face_ref, a, b, &nor2, &dist); |
||
| 3597 | if (*d > dist) { |
||
| 3598 | *d = dist; |
||
| 3599 | j = i; |
||
| 3600 | BrVector3Copy(nor, &nor2); |
||
| 3601 | } |
||
| 3602 | } |
||
| 3603 | } |
||
| 3604 | if (*d >= 2.f) { |
||
| 3605 | return 0; |
||
| 3606 | } |
||
| 3607 | i = gFace_list__car[j].material->identifier[0] - ('0' - 1); |
||
| 3608 | if (i < 0 || i >= 11) { |
||
| 3609 | return 0; |
||
| 3610 | } else { |
||
| 3611 | return i; |
||
| 3612 | } |
||
| 3613 | } |
||
| 3614 | |||
| 3615 | // IDA: int __usercall FindFloorInBoxBU2@<EAX>(br_vector3 *a@<EAX>, br_vector3 *b@<EDX>, br_vector3 *nor@<EBX>, br_scalar *d@<ECX>, tCollision_info *c) |
||
| 3616 | int FindFloorInBoxBU2(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, tCollision_info* c) { |
||
| 3617 | br_vector3 nor2; |
||
| 3618 | br_vector3 tv; |
||
| 3619 | int i; |
||
| 3620 | int j; |
||
| 3621 | br_scalar dist; |
||
| 3622 | tFace_ref* face_ref; |
||
| 3623 | LOG_TRACE("(%p, %p, %p, %p, %p)", a, b, nor, d, c); |
||
| 3624 | |||
| 3625 | #if defined(DETHRACE_FIX_BUGS) |
||
| 3626 | j = 0; // added to keep compiler happy |
||
| 3627 | #endif |
||
| 3628 | *d = 2.f; |
||
| 3629 | for (i = c->box_face_start; i < c->box_face_end; i++) { |
||
| 3630 | face_ref = &gFace_list__car[i]; |
||
| 3631 | if (!gEliminate_faces || SLOBYTE(face_ref->flags) >= 0) { |
||
| 3632 | CheckSingleFace(face_ref, a, b, &nor2, &dist); |
||
| 3633 | if (*d > dist) { |
||
| 3634 | if (face_ref->material->user == DOUBLESIDED_USER_FLAG || (face_ref->material->flags & (BR_MATF_ALWAYS_VISIBLE | BR_MATF_TWO_SIDED)) != 0) { |
||
| 3635 | BrVector3Sub(&tv, &c->pos, a); |
||
| 3636 | if (BrVector3Dot(&tv, &nor2) >= 0.f) { |
||
| 3637 | *d = dist; |
||
| 3638 | j = i; |
||
| 3639 | BrVector3Copy(nor, &nor2); |
||
| 3640 | } |
||
| 3641 | } else { |
||
| 3642 | *d = dist; |
||
| 3643 | j = i; |
||
| 3644 | BrVector3Copy(nor, &nor2); |
||
| 3645 | } |
||
| 3646 | } |
||
| 3647 | } |
||
| 3648 | face_ref++; |
||
| 3649 | } |
||
| 3650 | if (*d >= 2.f) { |
||
| 3651 | return 0; |
||
| 3652 | } |
||
| 3653 | i = gFace_list__car[j].material->identifier[0] - ('0' - 1); |
||
| 3654 | if (i < 0 || i >= 11) { |
||
| 3655 | return 0; |
||
| 3656 | } else { |
||
| 3657 | return i; |
||
| 3658 | } |
||
| 3659 | } |
||
| 3660 | |||
| 3661 | // IDA: int __usercall FindFloorInBoxM2@<EAX>(br_vector3 *a@<EAX>, br_vector3 *b@<EDX>, br_vector3 *nor@<EBX>, br_scalar *d@<ECX>, tCollision_info *c) |
||
| 3662 | int FindFloorInBoxM2(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, tCollision_info* c) { |
||
| 3663 | br_vector3 aa; |
||
| 3664 | br_vector3 bb; |
||
| 3665 | LOG_TRACE("(%p, %p, %p, %p, %p)", a, b, nor, d, c); |
||
| 3666 | |||
| 3667 | aa.v[0] = a->v[0] / WORLD_SCALE; |
||
| 3668 | aa.v[1] = a->v[1] / WORLD_SCALE; |
||
| 3669 | aa.v[2] = a->v[2] / WORLD_SCALE; |
||
| 3670 | bb.v[0] = b->v[0] / WORLD_SCALE; |
||
| 3671 | bb.v[1] = b->v[1] / WORLD_SCALE; |
||
| 3672 | bb.v[2] = b->v[2] / WORLD_SCALE; |
||
| 3673 | return FindFloorInBoxBU2(&aa, &bb, nor, d, c); |
||
| 3674 | } |
||
| 3675 | |||
| 3676 | // IDA: int __usercall BoxFaceIntersect@<EAX>(br_bounds *pB@<EAX>, br_matrix34 *pM@<EDX>, br_matrix34 *pMold@<EBX>, br_vector3 *pPoint_list@<ECX>, br_vector3 *pNorm_list, br_scalar *pDist_list, int pMax_pnts, tCollision_info *c) |
||
| 3677 | int BoxFaceIntersect(br_bounds* pB, br_matrix34* pM, br_matrix34* pMold, br_vector3* pPoint_list, br_vector3* pNorm_list, br_scalar* pDist_list, int pMax_pnts, tCollision_info* c) { |
||
| 3678 | br_vector3 p[3]; |
||
| 3679 | br_vector3 tv; |
||
| 3680 | br_vector3 pos; |
||
| 3681 | br_bounds bnds; |
||
| 3682 | int i; |
||
| 3683 | int j; |
||
| 3684 | int n; |
||
| 3685 | int flag; |
||
| 3686 | int m; |
||
| 3687 | tFace_ref* f_ref; |
||
| 3688 | //br_face* face; // Pierre-Marie Baty -- unused variable |
||
| 3689 | LOG_TRACE("(%p, %p, %p, %p, %p, %p, %d, %p)", pB, pM, pMold, pPoint_list, pNorm_list, pDist_list, pMax_pnts, c); |
||
| 3690 | |||
| 3691 | n = 0; |
||
| 3692 | BrVector3InvScale(&bnds.min, &pB->min, WORLD_SCALE); |
||
| 3693 | BrVector3InvScale(&bnds.max, &pB->max, WORLD_SCALE); |
||
| 3694 | BrVector3InvScale(&pos, (br_vector3*)pM->m[3], WORLD_SCALE); |
||
| 3695 | BrVector3InvScale((br_vector3*)pMold->m[3], (br_vector3*)pMold->m[3], WORLD_SCALE); |
||
| 3696 | |||
| 3697 | for (i = c->box_face_start; i < c->box_face_end && i < c->box_face_start + 50; i++) { |
||
| 3698 | f_ref = &gFace_list__car[i]; |
||
| 3699 | if (SLOBYTE(f_ref->flags) >= 0 && f_ref->material->identifier[0] != '!') { |
||
| 3700 | BrVector3Sub(&tv, &f_ref->v[0], &pos); |
||
| 3701 | BrMatrix34TApplyV(&p[0], &tv, pM); |
||
| 3702 | BrVector3Sub(&tv, &f_ref->v[1], &pos); |
||
| 3703 | BrMatrix34TApplyV(&p[1], &tv, pM); |
||
| 3704 | BrVector3Sub(&tv, &f_ref->v[2], &pos); |
||
| 3705 | BrMatrix34TApplyV(&p[2], &tv, pM); |
||
| 3706 | j = n; |
||
| 3707 | if ((f_ref->flags & 1) == 0) { |
||
| 3708 | n += AddEdgeCollPoints(&p[0], &p[1], &bnds, pMold, pPoint_list, pNorm_list, n, pMax_pnts, c); |
||
| 3709 | } |
||
| 3710 | if ((f_ref->flags & 2) == 0) { |
||
| 3711 | n += AddEdgeCollPoints(&p[1], &p[2], &bnds, pMold, pPoint_list, pNorm_list, n, pMax_pnts, c); |
||
| 3712 | } |
||
| 3713 | if ((f_ref->flags & 4) == 0) { |
||
| 3714 | n += AddEdgeCollPoints(&p[2], &p[0], &bnds, pMold, pPoint_list, pNorm_list, n, pMax_pnts, c); |
||
| 3715 | } |
||
| 3716 | if (n > j) { |
||
| 3717 | if (gMaterial_index == 0) { |
||
| 3718 | m = f_ref->material->identifier[0] - '/'; |
||
| 3719 | if (m > 0 && m < 11) { |
||
| 3720 | gMaterial_index = m; |
||
| 3721 | } |
||
| 3722 | } |
||
| 3723 | while (j < n) { |
||
| 3724 | BrVector3Scale(&pPoint_list[j], &pPoint_list[j], WORLD_SCALE); |
||
| 3725 | BrVector3Sub(&pPoint_list[j], &pPoint_list[j], &c->cmpos); |
||
| 3726 | j++; |
||
| 3727 | } |
||
| 3728 | } |
||
| 3729 | } |
||
| 3730 | } |
||
| 3731 | if (n) { |
||
| 3732 | m = 0; |
||
| 3733 | for (i = 0; i < n - 1; i++) { |
||
| 3734 | flag = 1; |
||
| 3735 | for (j = i + 1; j < n; j++) { |
||
| 3736 | if (fabsf(pPoint_list[i].v[0] - pPoint_list[j].v[0]) <= 0.001f |
||
| 3737 | && fabsf(pPoint_list[i].v[1] - pPoint_list[j].v[1]) <= 0.001f |
||
| 3738 | && fabsf(pPoint_list[i].v[2] - pPoint_list[j].v[2]) <= 0.001f) { |
||
| 3739 | flag = 0; |
||
| 3740 | break; |
||
| 3741 | } |
||
| 3742 | } |
||
| 3743 | if (flag) { |
||
| 3744 | BrVector3Copy(&pPoint_list[m], &pPoint_list[i]); |
||
| 3745 | m++; |
||
| 3746 | } |
||
| 3747 | } |
||
| 3748 | BrVector3Copy(&pPoint_list[m], &pPoint_list[n - 1]); |
||
| 3749 | n = m + 1; |
||
| 3750 | } |
||
| 3751 | BrVector3Scale((br_vector3*)pMold->m[3], (br_vector3*)pMold->m[3], WORLD_SCALE); |
||
| 3752 | return n; |
||
| 3753 | } |
||
| 3754 | |||
| 3755 | // IDA: int __usercall AddEdgeCollPoints@<EAX>(br_vector3 *p1@<EAX>, br_vector3 *p2@<EDX>, br_bounds *pB@<EBX>, br_matrix34 *pMold@<ECX>, br_vector3 *pPoint_list, br_vector3 *pNorm_list, int n, int pMax_pnts, tCollision_info *c) |
||
| 3756 | int AddEdgeCollPoints(br_vector3* p1, br_vector3* p2, br_bounds* pB, br_matrix34* pMold, br_vector3* pPoint_list, br_vector3* pNorm_list, int n, int pMax_pnts, tCollision_info* c) { |
||
| 3757 | br_vector3 op1; |
||
| 3758 | br_vector3 op2; |
||
| 3759 | br_vector3 a; |
||
| 3760 | br_vector3 b; |
||
| 3761 | br_vector3 edge; |
||
| 3762 | br_vector3 hp1; |
||
| 3763 | br_vector3 hp2; |
||
| 3764 | br_vector3 hp3; |
||
| 3765 | int plane1; |
||
| 3766 | int plane2; |
||
| 3767 | int plane3; |
||
| 3768 | int d; |
||
| 3769 | LOG_TRACE("(%p, %p, %p, %p, %p, %p, %d, %d, %p)", p1, p2, pB, pMold, pPoint_list, pNorm_list, n, pMax_pnts, c); |
||
| 3770 | |||
| 3771 | //float scale; // Pierre-Marie Baty -- unused variable |
||
| 3772 | |||
| 3773 | plane1 = LineBoxColl(p1, p2, pB, &hp1); |
||
| 3774 | if (plane1 == 0) { |
||
| 3775 | return 0; |
||
| 3776 | } |
||
| 3777 | if (n + 2 > pMax_pnts) { |
||
| 3778 | return 0; |
||
| 3779 | } |
||
| 3780 | plane2 = LineBoxColl(p2, p1, pB, &hp2); |
||
| 3781 | if (plane2 == 0) { |
||
| 3782 | return 0; |
||
| 3783 | } |
||
| 3784 | if (plane1 != 8 && plane2 != 8 && (plane1 ^ plane2) == 4) { |
||
| 3785 | BrVector3Add(&op1, &hp2, &hp1); |
||
| 3786 | BrVector3Scale(&op1, &op1, .5f); |
||
| 3787 | BrMatrix34ApplyP(&op2, &op1, pMold); |
||
| 3788 | plane3 = LineBoxColl(&op2, &op1, pB, &hp3); |
||
| 3789 | if (plane3 == 8) { |
||
| 3790 | return 0; |
||
| 3791 | } |
||
| 3792 | GetBoundsEdge(&pPoint_list[n], &edge, pB, plane1, plane3, &op2, &hp1, &hp2, c->collision_flag); |
||
| 3793 | GetBoundsEdge(&pPoint_list[n + 1], &edge, pB, plane2, plane3, &op2, &hp1, &hp2, c->collision_flag); |
||
| 3794 | GetPlaneNormal(&pNorm_list[n], plane3); |
||
| 3795 | BrVector3Copy(&pNorm_list[n + 1], &pNorm_list[n]); |
||
| 3796 | return 2; |
||
| 3797 | } else if (plane1 == 8 && plane2 != 8) { |
||
| 3798 | BrMatrix34ApplyP(&a, p1, pMold); |
||
| 3799 | plane3 = LineBoxColl(&a, p1, pB, &hp3); |
||
| 3800 | if (plane3 == 8) { |
||
| 3801 | return 0; |
||
| 3802 | } |
||
| 3803 | BrVector3Copy(&pPoint_list[n], &hp3); |
||
| 3804 | GetPlaneNormal(&pNorm_list[n], plane2); |
||
| 3805 | if (plane2 == plane3 || (plane3 ^ plane2) == 4) { |
||
| 3806 | return 1; |
||
| 3807 | } |
||
| 3808 | GetBoundsEdge(&pPoint_list[n + 1], &edge, pB, plane2, plane3, p1, &hp2, &hp3, c->collision_flag); |
||
| 3809 | BrVector3Sub(&op1, p1, p2); |
||
| 3810 | BrVector3Cross(&pNorm_list[n + 1], &edge, &op1); |
||
| 3811 | BrVector3Normalise(&pNorm_list[n + 1], &pNorm_list[n + 1]); |
||
| 3812 | d = (plane2 - 1) & 3; |
||
| 3813 | if ((pNorm_list[n + 1].v[d] < 0.f) == (plane2 & 4) >> 2) { |
||
| 3814 | BrVector3Negate(&pNorm_list[n + 1], &pNorm_list[n + 1]); |
||
| 3815 | } |
||
| 3816 | BrVector3Copy(&op1, &pNorm_list[n + 1]); |
||
| 3817 | BrMatrix34ApplyV(&pNorm_list[n + 1], &op1, pMold); |
||
| 3818 | return 2; |
||
| 3819 | } else if (plane2 == 8 && plane1 != 8) { |
||
| 3820 | BrMatrix34ApplyP(&b, p2, pMold); |
||
| 3821 | plane3 = LineBoxColl(&b, p2, pB, &hp3); |
||
| 3822 | if (plane3 == 8) { |
||
| 3823 | return 0; |
||
| 3824 | } |
||
| 3825 | pPoint_list[n] = hp3; |
||
| 3826 | GetPlaneNormal(&pNorm_list[n], plane1); |
||
| 3827 | if (plane1 == plane3 || (plane3 ^ plane1) == 4) { |
||
| 3828 | return 1; |
||
| 3829 | } |
||
| 3830 | GetBoundsEdge(&pPoint_list[n + 1], &edge, pB, plane1, plane3, p2, &hp1, &hp3, c->collision_flag); |
||
| 3831 | BrVector3Sub(&op1, p1, p2); |
||
| 3832 | BrVector3Cross(&pNorm_list[n + 1], &edge, &op1); |
||
| 3833 | BrVector3Normalise(&pNorm_list[n + 1], &pNorm_list[n + 1]); |
||
| 3834 | d = (plane1 - 1) & 3; |
||
| 3835 | if ((pNorm_list[n + 1].v[d] < 0.f) == (plane1 & 4) >> 2) { |
||
| 3836 | BrVector3Negate(&pNorm_list[n + 1], &pNorm_list[n + 1]); |
||
| 3837 | } |
||
| 3838 | BrVector3Copy(&op1, &pNorm_list[n + 1]); |
||
| 3839 | BrMatrix34ApplyV(&pNorm_list[n + 1], &op1, pMold); |
||
| 3840 | return 2; |
||
| 3841 | } else if (plane1 != 8 && plane2 != 8) { |
||
| 3842 | BrVector3Add(&op1, &hp2, &hp1); |
||
| 3843 | BrVector3Scale(&op1, &op1, .5f); |
||
| 3844 | BrMatrix34ApplyP(&op2, &op1, pMold); |
||
| 3845 | plane3 = LineBoxColl(&op2, &op1, pB, &hp3); |
||
| 3846 | if (plane3 == 8 || plane3 == 0) { |
||
| 3847 | return 0; |
||
| 3848 | } |
||
| 3849 | if (plane1 == plane3 || plane2 == plane3) { |
||
| 3850 | GetBoundsEdge(&pPoint_list[n], &edge, pB, plane1, plane2, &op2, &hp1, &hp2, c->collision_flag); |
||
| 3851 | BrVector3Sub(&op1, &hp1, &hp2); |
||
| 3852 | BrVector3Cross(&op2, &edge, &op1); |
||
| 3853 | BrVector3Normalise(&pNorm_list[n], &op2); |
||
| 3854 | BrVector3Add(&op1, &pB->max, &pB->min); |
||
| 3855 | BrVector3Scale(&op1, &op1, .5f); |
||
| 3856 | BrVector3Sub(&op1, &pPoint_list[n], &op1); |
||
| 3857 | if (BrVector3Dot(&pNorm_list[n], &op1) > 0.f) { |
||
| 3858 | BrVector3Negate(&pNorm_list[n], &pNorm_list[n]); |
||
| 3859 | } |
||
| 3860 | BrVector3Copy(&op1, &pNorm_list[n]); |
||
| 3861 | BrMatrix34ApplyV(&pNorm_list[n], &op1, pMold); |
||
| 3862 | return 1; |
||
| 3863 | } else { |
||
| 3864 | GetBoundsEdge(&pPoint_list[n], &edge, pB, plane1, plane3, &hp3, &hp1, &hp2, c->collision_flag); |
||
| 3865 | GetBoundsEdge(&pPoint_list[n + 1], &edge, pB, plane2, plane3, &hp3, &hp1, &hp2, c->collision_flag); |
||
| 3866 | GetPlaneNormal(&pNorm_list[n], plane3); |
||
| 3867 | BrVector3Copy(&pNorm_list[n + 1], &pNorm_list[n]); |
||
| 3868 | return 2; |
||
| 3869 | } |
||
| 3870 | } else if (plane1 == 8 && plane2 == 8) { |
||
| 3871 | BrMatrix34ApplyP(&op1, p1, pMold); |
||
| 3872 | plane3 = LineBoxColl(&op1, p1, pB, &pPoint_list[n]); |
||
| 3873 | GetPlaneNormal(&pNorm_list[n], plane3); |
||
| 3874 | d = n + (plane3 != 8); |
||
| 3875 | BrMatrix34ApplyP(&op1, p2, pMold); |
||
| 3876 | plane3 = LineBoxColl(&op1, p2, pB, &pPoint_list[d]); |
||
| 3877 | GetPlaneNormal(&pNorm_list[d], plane3); |
||
| 3878 | return (n != d) + (plane3 != 8); |
||
| 3879 | } else { |
||
| 3880 | return 0; |
||
| 3881 | } |
||
| 3882 | } |
||
| 3883 | |||
| 3884 | // IDA: void __usercall GetPlaneNormal(br_vector3 *n@<EAX>, int p@<EDX>) |
||
| 3885 | void GetPlaneNormal(br_vector3* n, int p) { |
||
| 3886 | int d; |
||
| 3887 | LOG_TRACE("(%p, %d)", n, p); |
||
| 3888 | |||
| 3889 | d = (p - 1) & 3; |
||
| 3890 | BrVector3Set(n, 0.f, 0.f, 0.f); |
||
| 3891 | if ((p & 4) != 0) { |
||
| 3892 | n->v[d] = 1.0f; |
||
| 3893 | } else { |
||
| 3894 | n->v[d] = -1.0f; |
||
| 3895 | } |
||
| 3896 | } |
||
| 3897 | |||
| 3898 | // IDA: int __usercall GetBoundsEdge@<EAX>(br_vector3 *pos@<EAX>, br_vector3 *edge@<EDX>, br_bounds *pB@<EBX>, int plane1@<ECX>, int plane2, br_vector3 *a, br_vector3 *b, br_vector3 *c, int flag) |
||
| 3899 | int GetBoundsEdge(br_vector3* pos, br_vector3* edge, br_bounds* pB, int plane1, int plane2, br_vector3* a, br_vector3* b, br_vector3* c, int flag) { |
||
| 3900 | int d1; |
||
| 3901 | int d2; |
||
| 3902 | int d3; |
||
| 3903 | br_vector3 n; |
||
| 3904 | br_vector3 p; |
||
| 3905 | br_vector3 q; |
||
| 3906 | LOG_TRACE("(%p, %p, %p, %d, %d, %p, %p, %p, %d)", pos, edge, pB, plane1, plane2, a, b, c, flag); |
||
| 3907 | |||
| 3908 | d1 = (plane1 - 1) & 3; |
||
| 3909 | d2 = (plane2 - 1) & 3; |
||
| 3910 | BrVector3Sub(&n, b, a); |
||
| 3911 | BrVector3Sub(&p, c, a); |
||
| 3912 | BrVector3Cross(&q, &n, &p); |
||
| 3913 | if ((plane1 & 4) != 0) { |
||
| 3914 | pos->v[d1] = pB->min.v[d1]; |
||
| 3915 | } else { |
||
| 3916 | pos->v[d1] = pB->max.v[d1]; |
||
| 3917 | } |
||
| 3918 | if ((plane2 & 4) != 0) { |
||
| 3919 | pos->v[d2] = pB->min.v[d2]; |
||
| 3920 | } else { |
||
| 3921 | pos->v[d2] = pB->max.v[d2]; |
||
| 3922 | } |
||
| 3923 | d3 = 3 - d1 - d2; |
||
| 3924 | edge->v[d1] = 0.f; |
||
| 3925 | edge->v[d2] = 0.f; |
||
| 3926 | edge->v[d3] = 1.f; |
||
| 3927 | if ((flag & 1) != 0) { |
||
| 3928 | pos->v[d3] = (c->v[d3] + b->v[d3]) / 2.f; |
||
| 3929 | } else { |
||
| 3930 | pos->v[d3] = a->v[d3] - ((pos->v[d2] - a->v[d2]) * q.v[d2] + (pos->v[d1] - a->v[d1]) * q.v[d1]) / q.v[d3]; |
||
| 3931 | } |
||
| 3932 | return 1; |
||
| 3933 | } |
||
| 3934 | |||
| 3935 | // IDA: void __usercall oldMoveOurCar(tU32 pTime_difference@<EAX>) |
||
| 3936 | void oldMoveOurCar(tU32 pTime_difference) { |
||
| 3937 | //br_vector3 thrust_vector; // Pierre-Marie Baty -- unused variable |
||
| 3938 | //br_matrix34 direction_matrix; // Pierre-Marie Baty -- unused variable |
||
| 3939 | //br_matrix34 old_mat; // Pierre-Marie Baty -- unused variable |
||
| 3940 | //double rotate_amount; // Pierre-Marie Baty -- unused variable |
||
| 3941 | //br_scalar nearest_y_above; // Pierre-Marie Baty -- unused variable |
||
| 3942 | //br_scalar nearest_y_below; // Pierre-Marie Baty -- unused variable |
||
| 3943 | //br_scalar speed; // Pierre-Marie Baty -- unused variable |
||
| 3944 | //int below_face_index; // Pierre-Marie Baty -- unused variable |
||
| 3945 | //int above_face_index; // Pierre-Marie Baty -- unused variable |
||
| 3946 | //br_model* below_model; // Pierre-Marie Baty -- unused variable |
||
| 3947 | //br_model* above_model; // Pierre-Marie Baty -- unused variable |
||
| 3948 | LOG_TRACE("(%d)", pTime_difference); |
||
| 3949 | NOT_IMPLEMENTED(); |
||
| 3950 | } |
||
| 3951 | |||
| 3952 | // IDA: void __cdecl ToggleCollisionDetection() |
||
| 3953 | void ToggleCollisionDetection(void) { |
||
| 3954 | LOG_TRACE("()"); |
||
| 3955 | NOT_IMPLEMENTED(); |
||
| 3956 | } |
||
| 3957 | |||
| 3958 | // IDA: void __cdecl CancelPendingCunningStunt() |
||
| 3959 | void CancelPendingCunningStunt(void) { |
||
| 3960 | LOG_TRACE("()"); |
||
| 3961 | |||
| 3962 | gQuite_wild_end = 0; |
||
| 3963 | gQuite_wild_start = 0; |
||
| 3964 | gOn_me_wheels_start = 0; |
||
| 3965 | gWoz_upside_down_at_all = 0; |
||
| 3966 | gWild_start = 0; |
||
| 3967 | } |
||
| 3968 | |||
| 3969 | // IDA: float __cdecl frac(float pN) |
||
| 3970 | float frac(float pN) { |
||
| 3971 | LOG_TRACE("(%f)", pN); |
||
| 3972 | |||
| 3973 | return pN - (float)(int)pN; |
||
| 3974 | } |
||
| 3975 | |||
| 3976 | // IDA: void __usercall SetAmbientPratCam(tCar_spec *pCar@<EAX>) |
||
| 3977 | void SetAmbientPratCam(tCar_spec* pCar) { |
||
| 3978 | br_scalar vcs_x; |
||
| 3979 | br_scalar vcs_y; |
||
| 3980 | br_scalar vcs_z; |
||
| 3981 | br_scalar abs_vcs_x; |
||
| 3982 | br_scalar abs_vcs_y; |
||
| 3983 | br_scalar abs_vcs_z; |
||
| 3984 | br_scalar abs_omega_x; |
||
| 3985 | br_scalar abs_omega_y; |
||
| 3986 | br_scalar abs_omega_z; |
||
| 3987 | tU32 the_time; |
||
| 3988 | static tU32 last_time_on_ground; |
||
| 3989 | LOG_TRACE("(%p)", pCar); |
||
| 3990 | |||
| 3991 | if (gRace_finished) { |
||
| 3992 | return; |
||
| 3993 | } |
||
| 3994 | the_time = GetTotalTime(); |
||
| 3995 | if (pCar->number_of_wheels_on_ground != 0) { |
||
| 3996 | last_time_on_ground = the_time; |
||
| 3997 | } |
||
| 3998 | vcs_x = pCar->velocity_car_space.v[0]; |
||
| 3999 | vcs_y = pCar->velocity_car_space.v[1]; |
||
| 4000 | vcs_z = pCar->velocity_car_space.v[2]; |
||
| 4001 | abs_vcs_x = fabsf(vcs_x); |
||
| 4002 | abs_vcs_y = fabsf(vcs_y); |
||
| 4003 | abs_vcs_z = fabsf(vcs_z); |
||
| 4004 | abs_omega_x = fabsf(pCar->omega.v[0]); |
||
| 4005 | abs_omega_y = fabsf(pCar->omega.v[1]); |
||
| 4006 | abs_omega_z = fabsf(pCar->omega.v[2]); |
||
| 4007 | |||
| 4008 | if (abs_omega_x > 4.5f || abs_omega_z > 4.5f) { |
||
| 4009 | ChangeAmbientPratcam(9); |
||
| 4010 | } else if (abs_omega_y > 4.5f) { |
||
| 4011 | ChangeAmbientPratcam(12); |
||
| 4012 | } else if (abs_omega_x > 3.f || abs_omega_z > 3.f) { |
||
| 4013 | ChangeAmbientPratcam(8); |
||
| 4014 | } else if (abs_omega_y > 3.f) { |
||
| 4015 | ChangeAmbientPratcam(11); |
||
| 4016 | } else if (pCar->car_master_actor->t.t.mat.m[1][1] < 0.1f) { |
||
| 4017 | ChangeAmbientPratcam(44); |
||
| 4018 | } else if (abs_vcs_y > abs_vcs_z && abs_vcs_y > abs_vcs_x && vcs_y < -.004f) { |
||
| 4019 | ChangeAmbientPratcam(6); |
||
| 4020 | } else if (the_time - last_time_on_ground > 500) { |
||
| 4021 | ChangeAmbientPratcam(5); |
||
| 4022 | } else if (abs_vcs_x > abs_vcs_z && vcs_x > .001f) { |
||
| 4023 | ChangeAmbientPratcam(26); |
||
| 4024 | } else if (abs_vcs_x > abs_vcs_z && vcs_x < -.001f) { |
||
| 4025 | ChangeAmbientPratcam(25); |
||
| 4026 | } else if (abs_omega_x > 1.5f || abs_omega_z > 1.5f) { |
||
| 4027 | ChangeAmbientPratcam(7); |
||
| 4028 | } else if (abs_omega_y > 1.5f) { |
||
| 4029 | ChangeAmbientPratcam(10); |
||
| 4030 | } else if (abs_vcs_z > .01f) { |
||
| 4031 | ChangeAmbientPratcam(3); |
||
| 4032 | } else if (abs_vcs_z > .004f) { |
||
| 4033 | ChangeAmbientPratcam(2); |
||
| 4034 | } else if (abs_vcs_z > .0015f) { |
||
| 4035 | ChangeAmbientPratcam(1); |
||
| 4036 | } else { |
||
| 4037 | ChangeAmbientPratcam(0); |
||
| 4038 | } |
||
| 4039 | } |
||
| 4040 | |||
| 4041 | // IDA: void __usercall MungeCarGraphics(tU32 pFrame_period@<EAX>) |
||
| 4042 | void MungeCarGraphics(tU32 pFrame_period) { |
||
| 4043 | int i; |
||
| 4044 | //int j; // Pierre-Marie Baty -- unused variable |
||
| 4045 | int update_mat; |
||
| 4046 | int spinning_wildly; |
||
| 4047 | int spinning_mildly; |
||
| 4048 | int car_count; |
||
| 4049 | int oily_count; |
||
| 4050 | int car; |
||
| 4051 | int cat; |
||
| 4052 | //int new_special_screen; // Pierre-Marie Baty -- unused variable |
||
| 4053 | tCar_spec* the_car; |
||
| 4054 | br_scalar distance_from_camera; |
||
| 4055 | br_scalar car_x; |
||
| 4056 | br_scalar car_z; |
||
| 4057 | br_scalar oily_size; |
||
| 4058 | br_scalar car_radius; |
||
| 4059 | br_scalar abs_omega_x; |
||
| 4060 | br_scalar abs_omega_y; |
||
| 4061 | br_scalar abs_omega_z; |
||
| 4062 | float wheel_speed; |
||
| 4063 | //float speed_mph; // Pierre-Marie Baty -- unused variable |
||
| 4064 | //float rev_angle; // Pierre-Marie Baty -- unused variable |
||
| 4065 | float sine_angle; |
||
| 4066 | float raw_revs; |
||
| 4067 | float rev_reducer; |
||
| 4068 | //tSpecial_screen* the_special_screen; // Pierre-Marie Baty -- unused variable |
||
| 4069 | br_material* the_material; |
||
| 4070 | tU32 the_time; |
||
| 4071 | br_actor* oily_actor; |
||
| 4072 | LOG_TRACE("(%d)", pFrame_period); |
||
| 4073 | |||
| 4074 | if (gNet_mode != eNet_mode_none |
||
| 4075 | && ((gCurrent_net_game->type == eNet_game_type_foxy && gThis_net_player_index == gIt_or_fox) |
||
| 4076 | || (gCurrent_net_game->type == eNet_game_type_tag && gThis_net_player_index != gIt_or_fox))) { |
||
| 4077 | gProgram_state.current_car.power_up_levels[1] = 0; |
||
| 4078 | } |
||
| 4079 | SetAmbientPratCam(&gProgram_state.current_car); |
||
| 4080 | if (gProgram_state.cockpit_on) { |
||
| 4081 | SwitchCarActor(&gProgram_state.current_car, gProgram_state.current_car.car_actor_count - 1); |
||
| 4082 | } else { |
||
| 4083 | SwitchCarActor(&gProgram_state.current_car, gProgram_state.current_car.car_actor_count - 2); |
||
| 4084 | } |
||
| 4085 | |||
| 4086 | the_time = PDGetTotalTime(); |
||
| 4087 | for (cat = eVehicle_self; cat <= eVehicle_rozzer; cat++) { |
||
| 4088 | if (cat == eVehicle_self) { |
||
| 4089 | car_count = 1; |
||
| 4090 | } else { |
||
| 4091 | car_count = GetCarCount(cat); |
||
| 4092 | } |
||
| 4093 | for (car = 0; car < car_count; car++) { |
||
| 4094 | if (cat == eVehicle_self) { |
||
| 4095 | the_car = &gProgram_state.current_car; |
||
| 4096 | } else { |
||
| 4097 | the_car = GetCarSpec(cat, car); |
||
| 4098 | } |
||
| 4099 | the_car->car_master_actor->render_style = (the_car->driver == eDriver_local_human || !PointOutOfSight(&the_car->pos, gYon_squared)) ? BR_RSTYLE_DEFAULT : BR_RSTYLE_NONE; |
||
| 4100 | } |
||
| 4101 | } |
||
| 4102 | for (car = 0; car < gNum_active_cars; car++) { |
||
| 4103 | the_car = gActive_car_list[car]; |
||
| 4104 | if (the_car->car_master_actor->render_style != BR_RSTYLE_NONE) { |
||
| 4105 | car_x = the_car->car_master_actor->t.t.translate.t.v[0]; |
||
| 4106 | car_z = the_car->car_master_actor->t.t.translate.t.v[2]; |
||
| 4107 | the_car->shadow_intersection_flags = 0; |
||
| 4108 | oily_count = GetOilSpillCount(); |
||
| 4109 | for (i = 0; i < oily_count; i++) { |
||
| 4110 | GetOilSpillDetails(i, &oily_actor, &oily_size); |
||
| 4111 | if (oily_actor != NULL) { |
||
| 4112 | car_radius = the_car->bounds[1].max.v[2] / WORLD_SCALE * 1.5f; |
||
| 4113 | if (oily_actor->t.t.translate.t.v[0] - oily_size < car_x + car_radius |
||
| 4114 | && oily_actor->t.t.translate.t.v[0] + oily_size > car_x - car_radius |
||
| 4115 | && oily_actor->t.t.translate.t.v[2] - oily_size < car_z + car_radius |
||
| 4116 | && oily_actor->t.t.translate.t.v[2] + oily_size > car_z - car_radius) { |
||
| 4117 | the_car->shadow_intersection_flags |= 1 << i; |
||
| 4118 | } |
||
| 4119 | } |
||
| 4120 | } |
||
| 4121 | if (the_car->driver < eDriver_net_human && (!gAction_replay_mode || !ReplayIsPaused())) { |
||
| 4122 | if (gCountdown) { |
||
| 4123 | sine_angle = FRandomBetween(0.4f, 1.6f) * ((double)GetTotalTime() / ((double)gCountdown * 100.0f)); |
||
| 4124 | sine_angle = frac(sine_angle) * 360.0f; |
||
| 4125 | sine_angle = FastScalarSin(sine_angle); |
||
| 4126 | raw_revs = the_car->red_line * fabsf(sine_angle); |
||
| 4127 | rev_reducer = (11.0 - (double)gCountdown) / 10.0; |
||
| 4128 | the_car->revs = rev_reducer * raw_revs; |
||
| 4129 | } else { |
||
| 4130 | the_car->revs = (the_car->speedo_speed / 0.003 |
||
| 4131 | - (double)(int)(the_car->speedo_speed / 0.003)) |
||
| 4132 | * (double)(the_car->red_line - 800) |
||
| 4133 | + 800.0; |
||
| 4134 | } |
||
| 4135 | } |
||
| 4136 | for (i = 0; i < the_car->number_of_steerable_wheels; i++) { |
||
| 4137 | ControlBoundFunkGroove(the_car->steering_ref[i], the_car->steering_angle); |
||
| 4138 | } |
||
| 4139 | for (i = 0; i < COUNT_OF(the_car->rf_sus_ref); i++) { |
||
| 4140 | ControlBoundFunkGroove(the_car->rf_sus_ref[i], the_car->rf_sus_position); |
||
| 4141 | if ((i & 1) != 0) { |
||
| 4142 | ControlBoundFunkGroove(the_car->lf_sus_ref[i], -the_car->lf_sus_position); |
||
| 4143 | } else { |
||
| 4144 | ControlBoundFunkGroove(the_car->lf_sus_ref[i], the_car->lf_sus_position); |
||
| 4145 | } |
||
| 4146 | } |
||
| 4147 | for (i = 0; i < COUNT_OF(the_car->rr_sus_ref); i++) { |
||
| 4148 | ControlBoundFunkGroove(the_car->rr_sus_ref[i], the_car->rr_sus_position); |
||
| 4149 | if ((i & 1) != 0) { |
||
| 4150 | ControlBoundFunkGroove(the_car->lr_sus_ref[i], -the_car->lr_sus_position); |
||
| 4151 | } else { |
||
| 4152 | ControlBoundFunkGroove(the_car->lr_sus_ref[i], the_car->lr_sus_position); |
||
| 4153 | } |
||
| 4154 | } |
||
| 4155 | if (!gAction_replay_mode || !ReplayIsPaused()) { |
||
| 4156 | wheel_speed = -(the_car->speedo_speed / the_car->non_driven_wheels_circum * (float)gFrame_period); |
||
| 4157 | ControlBoundFunkGroovePlus(the_car->non_driven_wheels_spin_ref_1, wheel_speed); |
||
| 4158 | ControlBoundFunkGroovePlus(the_car->non_driven_wheels_spin_ref_2, wheel_speed); |
||
| 4159 | ControlBoundFunkGroovePlus(the_car->non_driven_wheels_spin_ref_3, wheel_speed); |
||
| 4160 | ControlBoundFunkGroovePlus(the_car->non_driven_wheels_spin_ref_4, wheel_speed); |
||
| 4161 | if (the_car->driver >= eDriver_net_human) { |
||
| 4162 | if (the_car->gear) { |
||
| 4163 | wheel_speed = -(the_car->revs |
||
| 4164 | * the_car->speed_revs_ratio |
||
| 4165 | / 6900.f |
||
| 4166 | * (double)the_car->gear |
||
| 4167 | / the_car->driven_wheels_circum |
||
| 4168 | * (double)gFrame_period); |
||
| 4169 | } else if (the_car->keys.brake) { |
||
| 4170 | wheel_speed = 0.0; |
||
| 4171 | } else { |
||
| 4172 | wheel_speed = -(the_car->speedo_speed / the_car->driven_wheels_circum * (double)gFrame_period); |
||
| 4173 | } |
||
| 4174 | } |
||
| 4175 | ControlBoundFunkGroovePlus(the_car->driven_wheels_spin_ref_1, wheel_speed); |
||
| 4176 | ControlBoundFunkGroovePlus(the_car->driven_wheels_spin_ref_2, wheel_speed); |
||
| 4177 | ControlBoundFunkGroovePlus(the_car->driven_wheels_spin_ref_3, wheel_speed); |
||
| 4178 | ControlBoundFunkGroovePlus(the_car->driven_wheels_spin_ref_4, wheel_speed); |
||
| 4179 | } |
||
| 4180 | if (gAction_replay_mode) { |
||
| 4181 | MungeSpecialVolume((tCollision_info*)the_car); |
||
| 4182 | } else if (the_car->driver == eDriver_local_human) { |
||
| 4183 | abs_omega_x = (fabsf(the_car->I.v[0]) + 3.3f) / 2.0f * fabsf(the_car->omega.v[0]); |
||
| 4184 | abs_omega_y = (fabsf(the_car->I.v[1]) + 3.57f) / 2.0f * fabsf(the_car->omega.v[1]); |
||
| 4185 | abs_omega_z = (fabsf(the_car->I.v[2]) + 0.44f) / 2.0f * fabsf(the_car->omega.v[2]); |
||
| 4186 | spinning_wildly = abs_omega_x > 26.4f || abs_omega_y > 49.98f || abs_omega_z > 3.52f; |
||
| 4187 | if (spinning_wildly && the_time - gLast_cunning_stunt > 10000) { |
||
| 4188 | if (!gWild_start |
||
| 4189 | || (the_car->last_special_volume != NULL && the_car->last_special_volume->gravity_multiplier != 1.f)) { |
||
| 4190 | gWild_start = the_time; |
||
| 4191 | } else if (the_time - gWild_start >= 500) { |
||
| 4192 | DoFancyHeadup(kFancyHeadupCunningStuntBonus); |
||
| 4193 | EarnCredits(gCunning_stunt_bonus[gProgram_state.skill_level]); |
||
| 4194 | gLast_cunning_stunt = the_time; |
||
| 4195 | gOn_me_wheels_start = 0; |
||
| 4196 | gQuite_wild_end = 0; |
||
| 4197 | gQuite_wild_start = 0; |
||
| 4198 | gWoz_upside_down_at_all = 0; |
||
| 4199 | } |
||
| 4200 | } else { |
||
| 4201 | gWild_start = 0; |
||
| 4202 | spinning_mildly = abs_omega_x > 1.65f || abs_omega_z > 0.22f; |
||
| 4203 | if (the_car->number_of_wheels_on_ground <= 3) { |
||
| 4204 | gOn_me_wheels_start = 0; |
||
| 4205 | if (the_car->number_of_wheels_on_ground || !spinning_mildly) { |
||
| 4206 | gQuite_wild_end = the_time; |
||
| 4207 | } else { |
||
| 4208 | if (!gQuite_wild_start) { |
||
| 4209 | gQuite_wild_start = the_time; |
||
| 4210 | } |
||
| 4211 | if (the_car->car_master_actor->t.t.mat.m[1][1] < -0.8f) { |
||
| 4212 | gWoz_upside_down_at_all = the_time; |
||
| 4213 | } |
||
| 4214 | } |
||
| 4215 | } else { |
||
| 4216 | if (!gQuite_wild_end) { |
||
| 4217 | gQuite_wild_end = the_time; |
||
| 4218 | } |
||
| 4219 | if (!gQuite_wild_start |
||
| 4220 | || the_time - gLast_cunning_stunt <= 10000 |
||
| 4221 | || gQuite_wild_end - gQuite_wild_start < 2000 |
||
| 4222 | || gWoz_upside_down_at_all < (int) gQuite_wild_start // Pierre-Marie Baty -- added type cast |
||
| 4223 | || gWoz_upside_down_at_all > (int) gQuite_wild_end // Pierre-Marie Baty -- added type cast |
||
| 4224 | || (!gOn_me_wheels_start && the_time - gQuite_wild_end >= 300)) { |
||
| 4225 | gQuite_wild_end = 0; |
||
| 4226 | gQuite_wild_start = 0; |
||
| 4227 | gOn_me_wheels_start = 0; |
||
| 4228 | gWoz_upside_down_at_all = 0; |
||
| 4229 | } else if (!gOn_me_wheels_start) { |
||
| 4230 | gOn_me_wheels_start = the_time; |
||
| 4231 | } else if (the_time - gOn_me_wheels_start > 500 |
||
| 4232 | && (the_car->last_special_volume == NULL |
||
| 4233 | || the_car->last_special_volume->gravity_multiplier == 1.0f)) { |
||
| 4234 | DoFancyHeadup(kFancyHeadupCunningStuntBonus); |
||
| 4235 | EarnCredits(gCunning_stunt_bonus[gProgram_state.skill_level]); |
||
| 4236 | gLast_cunning_stunt = PDGetTotalTime(); |
||
| 4237 | gQuite_wild_end = 0; |
||
| 4238 | gQuite_wild_start = 0; |
||
| 4239 | gOn_me_wheels_start = 0; |
||
| 4240 | gWoz_upside_down_at_all = 0; |
||
| 4241 | } |
||
| 4242 | } |
||
| 4243 | } |
||
| 4244 | } |
||
| 4245 | if (the_car->driver != eDriver_local_human && the_car->car_model_variable) { |
||
| 4246 | distance_from_camera = Vector3DistanceSquared(&the_car->car_master_actor->t.t.translate.t, |
||
| 4247 | (br_vector3*)gCamera_to_world.m[3]) |
||
| 4248 | / gCar_simplification_factor[gGraf_spec_index][gCar_simplification_level]; |
||
| 4249 | if (gNet_mode != eNet_mode_none && gNet_players[gIt_or_fox].car == the_car) { |
||
| 4250 | distance_from_camera = 0.f; |
||
| 4251 | } |
||
| 4252 | for (i = 0; i < the_car->car_actor_count; i++) { |
||
| 4253 | if (the_car->car_model_actors[i].min_distance_squared <= distance_from_camera) { |
||
| 4254 | SwitchCarActor(the_car, i); |
||
| 4255 | break; |
||
| 4256 | } |
||
| 4257 | } |
||
| 4258 | } |
||
| 4259 | if (the_car->screen_material != NULL) { |
||
| 4260 | the_material = NULL; |
||
| 4261 | if (the_car->last_special_volume != NULL && the_car->last_special_volume->screen_material != NULL) { |
||
| 4262 | if (!gAction_replay_mode && the_car->last_special_volume != gDefault_water_spec_vol) { |
||
| 4263 | the_material = the_car->last_special_volume->screen_material; |
||
| 4264 | } else if (gProgram_state.current_depth_effect.type == eDepth_effect_fog) { |
||
| 4265 | the_material = gProgram_state.standard_screen_fog; |
||
| 4266 | } else if (gProgram_state.current_depth_effect.sky_texture != NULL) { |
||
| 4267 | the_material = gProgram_state.standard_screen; |
||
| 4268 | } else { |
||
| 4269 | the_material = gProgram_state.standard_screen_dark; |
||
| 4270 | } |
||
| 4271 | } else { |
||
| 4272 | if (gProgram_state.current_depth_effect.type == eDepth_effect_fog) { |
||
| 4273 | the_material = gProgram_state.standard_screen_fog; |
||
| 4274 | } else if (gProgram_state.current_depth_effect.sky_texture != NULL) { |
||
| 4275 | the_material = gProgram_state.standard_screen; |
||
| 4276 | } else { |
||
| 4277 | the_material = gProgram_state.standard_screen_dark; |
||
| 4278 | } |
||
| 4279 | } |
||
| 4280 | update_mat = 0; |
||
| 4281 | if (the_material != NULL && the_car->screen_material_source != the_material) { |
||
| 4282 | the_car->screen_material->flags = the_material->flags; |
||
| 4283 | the_car->screen_material->ka = the_material->ka; |
||
| 4284 | the_car->screen_material->kd = the_material->kd; |
||
| 4285 | the_car->screen_material->ks = the_material->ks; |
||
| 4286 | the_car->screen_material->power = the_material->power; |
||
| 4287 | the_car->screen_material->index_base = the_material->index_base; |
||
| 4288 | the_car->screen_material->index_range = the_material->index_range; |
||
| 4289 | the_car->screen_material->colour_map = the_material->colour_map; |
||
| 4290 | |||
| 4291 | the_car->screen_material->map_transform = the_material->map_transform; |
||
| 4292 | the_car->screen_material->index_shade = gRender_shade_table; |
||
| 4293 | the_car->screen_material_source = the_material; |
||
| 4294 | update_mat = 1; |
||
| 4295 | } |
||
| 4296 | if (the_car->screen_material->colour_map != NULL) { |
||
| 4297 | the_car->screen_material->map_transform.m[2][0] = fmodf(car_x, 1.f); |
||
| 4298 | the_car->screen_material->map_transform.m[2][1] = fmodf(car_z, 1.f); |
||
| 4299 | if (!update_mat) { |
||
| 4300 | BrMaterialUpdate(the_car->screen_material, BR_MATU_MAP_TRANSFORM); |
||
| 4301 | } |
||
| 4302 | } |
||
| 4303 | if (update_mat) { |
||
| 4304 | BrMaterialUpdate(the_car->screen_material, BR_MATU_ALL); |
||
| 4305 | } |
||
| 4306 | } |
||
| 4307 | } |
||
| 4308 | } |
||
| 4309 | } |
||
| 4310 | |||
| 4311 | // IDA: void __cdecl ResetCarScreens() |
||
| 4312 | void ResetCarScreens(void) { |
||
| 4313 | int cat; |
||
| 4314 | int car_count; |
||
| 4315 | int i; |
||
| 4316 | tCar_spec* the_car; |
||
| 4317 | LOG_TRACE("()"); |
||
| 4318 | |||
| 4319 | for (cat = eVehicle_self; cat < eVehicle_drone; cat++) { |
||
| 4320 | car_count = (cat == eVehicle_self) ? 1 : GetCarCount(cat); |
||
| 4321 | for (i = 0; i < car_count; i++) { |
||
| 4322 | the_car = (cat == eVehicle_self) ? &gProgram_state.current_car : GetCarSpec(cat, i); |
||
| 4323 | the_car->last_special_volume = NULL; |
||
| 4324 | } |
||
| 4325 | } |
||
| 4326 | MungeCarGraphics(gFrame_period); |
||
| 4327 | } |
||
| 4328 | |||
| 4329 | // IDA: tCar_spec* __cdecl GetRaceLeader() |
||
| 4330 | tCar_spec* GetRaceLeader(void) { |
||
| 20 | pmbaty | 4331 | //int i; // Pierre-Marie Baty -- unused variable |
| 4332 | //int score; // Pierre-Marie Baty -- unused variable |
||
| 4333 | //tCar_spec* car; // Pierre-Marie Baty -- unused variable |
||
| 1 | pmbaty | 4334 | LOG_TRACE("()"); |
| 20 | pmbaty | 4335 | NOT_IMPLEMENTED(); |
| 1 | pmbaty | 4336 | } |
| 4337 | |||
| 4338 | // IDA: void __cdecl AmIGettingBoredWatchingCameraSpin() |
||
| 4339 | void AmIGettingBoredWatchingCameraSpin(void) { |
||
| 20 | pmbaty | 4340 | //static tU32 time_of_death; // Pierre-Marie Baty -- unused variable |
| 4341 | //static tU32 headup_timer; // Pierre-Marie Baty -- unused variable |
||
| 4342 | //tCar_spec* car; // Pierre-Marie Baty -- unused variable |
||
| 4343 | //char s[256]; // Pierre-Marie Baty -- unused variable |
||
| 1 | pmbaty | 4344 | LOG_TRACE("()"); |
| 4345 | |||
| 20 | pmbaty | 4346 | STUB_ONCE(); |
| 1 | pmbaty | 4347 | } |
| 4348 | |||
| 4349 | // IDA: void __cdecl ViewNetPlayer() |
||
| 4350 | void ViewNetPlayer(void) { |
||
| 4351 | LOG_TRACE("()"); |
||
| 4352 | |||
| 4353 | if (gOpponent_viewing_mode) { |
||
| 4354 | if (gProgram_state.cockpit_on) { |
||
| 4355 | ToggleCockpit(); |
||
| 4356 | } |
||
| 4357 | gNet_player_to_view_index++; |
||
| 4358 | if (gNumber_of_net_players <= gNet_player_to_view_index) { |
||
| 4359 | gNet_player_to_view_index = -1; |
||
| 4360 | } |
||
| 4361 | if (gNet_player_to_view_index < 0) { |
||
| 4362 | gCar_to_view = GetRaceLeader(); |
||
| 4363 | } else { |
||
| 4364 | gCar_to_view = gNet_players[gNet_player_to_view_index].car; |
||
| 4365 | } |
||
| 4366 | gCamera_yaw = 0; |
||
| 4367 | InitialiseExternalCamera(); |
||
| 4368 | PositionExternalCamera(gCar_to_view, 200u); |
||
| 4369 | } |
||
| 4370 | } |
||
| 4371 | |||
| 4372 | // IDA: void __cdecl ViewOpponent() |
||
| 4373 | void ViewOpponent(void) { |
||
| 4374 | static int n; |
||
| 4375 | LOG_TRACE("()"); |
||
| 4376 | |||
| 4377 | n++; |
||
| 4378 | if (gNet_mode != eNet_mode_none) { |
||
| 4379 | if (n >= gNumber_of_net_players) { |
||
| 4380 | n = 0; |
||
| 4381 | } |
||
| 4382 | gCar_to_view = gNet_players[n].car; |
||
| 21 | pmbaty | 4383 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -3, gNet_players[n].player_name); |
| 1 | pmbaty | 4384 | } else { |
| 4385 | if (n >= gNum_viewable_cars) { |
||
| 4386 | n = 0; |
||
| 4387 | } |
||
| 4388 | gCar_to_view = gViewable_car_list[n]; |
||
| 21 | pmbaty | 4389 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 2000, -3, gViewable_car_list[n]->driver_name); |
| 1 | pmbaty | 4390 | } |
| 4391 | gCamera_yaw = 0; |
||
| 4392 | InitialiseExternalCamera(); |
||
| 4393 | PositionExternalCamera(gCar_to_view, 200); |
||
| 4394 | } |
||
| 4395 | |||
| 4396 | // IDA: void __cdecl ToggleCarToCarCollisions() |
||
| 4397 | void ToggleCarToCarCollisions(void) { |
||
| 4398 | LOG_TRACE("()"); |
||
| 4399 | |||
| 4400 | gCar_car_collisions = !gCar_car_collisions; |
||
| 4401 | if (gCar_car_collisions) { |
||
| 21 | pmbaty | 4402 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 3000, -4, "Car Car Collisions"); |
| 1 | pmbaty | 4403 | } else { |
| 21 | pmbaty | 4404 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 3000, -4, "Ghost Cars"); |
| 1 | pmbaty | 4405 | } |
| 4406 | } |
||
| 4407 | |||
| 4408 | // IDA: void __cdecl SwapCar() |
||
| 4409 | void SwapCar(void) { |
||
| 4410 | LOG_TRACE("()"); |
||
| 4411 | } |
||
| 4412 | |||
| 4413 | // IDA: void __cdecl AdjustDownForce() |
||
| 4414 | void AdjustDownForce(void) { |
||
| 4415 | char s[100]; |
||
| 4416 | tCar_spec* c; |
||
| 4417 | LOG_TRACE("()"); |
||
| 4418 | |||
| 4419 | c = gCar_to_view; |
||
| 4420 | c->down_force_speed += 50.f; |
||
| 4421 | if (c->down_force_speed > 2000.f) { |
||
| 4422 | c->down_force_speed = 50.f; |
||
| 4423 | } |
||
| 4424 | if (c->down_force_speed > 300.f) { |
||
| 4425 | c->down_force_speed = 2000.0; |
||
| 4426 | } |
||
| 4427 | sprintf(s, "DownForceSpeed %f", c->down_force_speed); |
||
| 21 | pmbaty | 4428 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 1500, -4, s); |
| 1 | pmbaty | 4429 | } |
| 4430 | |||
| 4431 | // IDA: void __cdecl FreezeMechanics() |
||
| 4432 | void FreezeMechanics(void) { |
||
| 4433 | LOG_TRACE("()"); |
||
| 4434 | |||
| 4435 | gFreeze_mechanics = !gFreeze_mechanics; |
||
| 4436 | if (gFreeze_mechanics) { |
||
| 21 | pmbaty | 4437 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 3000, -4, "Mechanics Frozen"); |
| 1 | pmbaty | 4438 | } else { |
| 21 | pmbaty | 4439 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 3000, -4, "Thawed Mechanics"); |
| 1 | pmbaty | 4440 | } |
| 4441 | } |
||
| 4442 | |||
| 4443 | // IDA: void __cdecl PutOpponentsInNeutral() |
||
| 4444 | void PutOpponentsInNeutral(void) { |
||
| 4445 | LOG_TRACE("()"); |
||
| 4446 | |||
| 4447 | gStop_opponents_moving = !gStop_opponents_moving; |
||
| 4448 | if (gStop_opponents_moving == 0) { |
||
| 21 | pmbaty | 4449 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 3000, -4, "Opponents in neutral"); |
| 1 | pmbaty | 4450 | } else { |
| 21 | pmbaty | 4451 | NewTextHeadupSlot(eHeadupSlot_misc, 0, 3000, -4, "Back in gear"); |
| 1 | pmbaty | 4452 | } |
| 4453 | } |
||
| 4454 | |||
| 4455 | // IDA: void __cdecl SetPanningFieldOfView() |
||
| 4456 | void SetPanningFieldOfView(void) { |
||
| 4457 | br_camera* camera_ptr; |
||
| 4458 | static br_angle panning_angle = 0; // Added by DethRace |
||
| 4459 | LOG_TRACE("()"); |
||
| 4460 | |||
| 4461 | camera_ptr = gCamera->type_data; |
||
| 4462 | if (panning_angle == 0) { |
||
| 4463 | panning_angle = BrDegreeToAngle(gCamera_angle) * 0.7f; |
||
| 4464 | } |
||
| 4465 | camera_ptr->field_of_view = panning_angle; |
||
| 4466 | } |
||
| 4467 | |||
| 4468 | // IDA: void __usercall CheckDisablePlingMaterials(tCar_spec *pCar@<EAX>) |
||
| 4469 | void CheckDisablePlingMaterials(tCar_spec* pCar) { |
||
| 4470 | br_matrix34* mat; |
||
| 4471 | br_scalar height; |
||
| 4472 | int i; |
||
| 4473 | LOG_TRACE("(%p)", pCar); |
||
| 4474 | |||
| 4475 | height = 0.f; |
||
| 4476 | if (pCar->water_d == 10000.f) { |
||
| 4477 | DisablePlingMaterials(); |
||
| 4478 | } else { |
||
| 4479 | mat = &pCar->car_master_actor->t.t.mat; |
||
| 4480 | for (i = 0; i < 3; i++) { |
||
| 4481 | if (mat->m[i][1] > 0.f) { |
||
| 4482 | height += pCar->bounds[0].max.v[i] * mat->m[i][1]; |
||
| 4483 | } else { |
||
| 4484 | height += pCar->bounds[0].min.v[i] * mat->m[i][1]; |
||
| 4485 | } |
||
| 4486 | } |
||
| 4487 | if (mat->m[3][1] / WORLD_SCALE + height < pCar->water_d) { |
||
| 4488 | DisablePlingMaterials(); |
||
| 4489 | } |
||
| 4490 | } |
||
| 4491 | } |
||
| 4492 | |||
| 4493 | // IDA: void __usercall PositionExternalCamera(tCar_spec *c@<EAX>, tU32 pTime@<EDX>) |
||
| 4494 | void PositionExternalCamera(tCar_spec* c, tU32 pTime) { |
||
| 4495 | static int old_camera_mode; |
||
| 4496 | br_camera* camera_ptr; |
||
| 4497 | LOG_TRACE("(%p, %d)", c, pTime); |
||
| 4498 | |||
| 4499 | camera_ptr = (br_camera*)gCamera->type_data; |
||
| 4500 | CheckCameraHither(); |
||
| 4501 | AmIGettingBoredWatchingCameraSpin(); |
||
| 4502 | if ((!gAction_replay_mode || gAction_replay_camera_mode == eAction_replay_standard) && old_camera_mode != -1) { |
||
| 4503 | camera_ptr->field_of_view = BrDegreeToAngle(gCamera_angle); |
||
| 4504 | old_camera_mode = -1; |
||
| 4505 | } |
||
| 4506 | if (!gProgram_state.cockpit_on) { |
||
| 4507 | if (gOpponent_viewing_mode && gAction_replay_mode) { |
||
| 4508 | c = &gProgram_state.current_car; |
||
| 4509 | } else { |
||
| 4510 | c = gCar_to_view; |
||
| 4511 | } |
||
| 4512 | if (c->car_master_actor->t.t.translate.t.v[0] <= 500.0) { |
||
| 4513 | if (gAction_replay_mode && gAction_replay_camera_mode) { |
||
| 4514 | if (gAction_replay_camera_mode == eAction_replay_action) { |
||
| 4515 | CheckDisablePlingMaterials(c); |
||
| 4516 | if (IncidentCam(c, pTime)) { |
||
| 4517 | SetPanningFieldOfView(); |
||
| 4518 | EnablePlingMaterials(); |
||
| 4519 | old_camera_mode = gAction_replay_camera_mode; |
||
| 4520 | return; |
||
| 4521 | } |
||
| 4522 | } |
||
| 4523 | CheckDisablePlingMaterials(c); |
||
| 4524 | SetPanningFieldOfView(); |
||
| 4525 | if (gAction_replay_camera_mode != old_camera_mode) { |
||
| 4526 | SetUpPanningCamera(c); |
||
| 4527 | old_camera_mode = gAction_replay_camera_mode; |
||
| 4528 | } |
||
| 4529 | PanningExternalCamera(c, pTime); |
||
| 4530 | EnablePlingMaterials(); |
||
| 4531 | } else { |
||
| 4532 | NormalPositionExternalCamera(c, pTime); |
||
| 4533 | } |
||
| 4534 | } |
||
| 4535 | } |
||
| 4536 | } |
||
| 4537 | |||
| 4538 | // IDA: void __usercall CameraBugFix(tCar_spec *c@<EAX>, tU32 pTime@<EDX>) |
||
| 4539 | void CameraBugFix(tCar_spec* c, tU32 pTime) { |
||
| 4540 | //br_matrix34 mat; // Pierre-Marie Baty -- unused variable |
||
| 4541 | //br_matrix34* m2; // Pierre-Marie Baty -- unused variable |
||
| 4542 | //br_vector3 tv; // Pierre-Marie Baty -- unused variable |
||
| 4543 | LOG_TRACE("(%p, %d)", c, pTime); |
||
| 4544 | |||
| 4545 | if (gAction_replay_mode && gAction_replay_camera_mode != eAction_replay_standard && gPed_actor != NULL && !gProgram_state.cockpit_on) { |
||
| 4546 | IncidentCam(c, pTime); |
||
| 4547 | } |
||
| 4548 | } |
||
| 20 | pmbaty | 4549 | |
| 1 | pmbaty | 4550 | // IDA: int __usercall PossibleRemoveNonCarFromWorld@<EAX>(br_actor *pActor@<EAX>) |
| 4551 | int PossibleRemoveNonCarFromWorld(br_actor* pActor) { |
||
| 4552 | tU8 cx; |
||
| 4553 | tU8 cz; |
||
| 4554 | tTrack_spec* track_spec; |
||
| 4555 | LOG_TRACE("(%p)", pActor); |
||
| 4556 | |||
| 4557 | track_spec = &gProgram_state.track_spec; |
||
| 4558 | XZToColumnXZ(&cx, &cz, pActor->t.t.translate.t.v[0], pActor->t.t.translate.t.v[2], track_spec); |
||
| 4559 | if (track_spec->columns[cz][cx] == pActor->parent) { |
||
| 4560 | BrActorRemove(pActor); |
||
| 4561 | return 1; |
||
| 4562 | } |
||
| 4563 | return 0; |
||
| 4564 | } |
||
| 4565 | |||
| 4566 | // IDA: void __usercall PutNonCarBackInWorld(br_actor *pActor@<EAX>) |
||
| 4567 | void PutNonCarBackInWorld(br_actor* pActor) { |
||
| 4568 | tU8 cx; |
||
| 4569 | tU8 cz; |
||
| 4570 | tTrack_spec* track_spec; |
||
| 4571 | LOG_TRACE("(%p)", pActor); |
||
| 4572 | |||
| 4573 | track_spec = &gProgram_state.track_spec; |
||
| 4574 | XZToColumnXZ(&cx, &cz, pActor->t.t.translate.t.v[0], pActor->t.t.translate.t.v[2], track_spec); |
||
| 4575 | BrActorAdd(track_spec->columns[cz][cx], pActor); |
||
| 4576 | } |
||
| 4577 | |||
| 4578 | // IDA: int __usercall IncidentCam@<EAX>(tCar_spec *c@<EAX>, tU32 pTime@<EDX>) |
||
| 4579 | int IncidentCam(tCar_spec* c, tU32 pTime) { |
||
| 4580 | br_matrix34* m2; |
||
| 4581 | br_matrix34 mat; |
||
| 4582 | br_vector3 tv; |
||
| 4583 | //br_vector3 tv2; // Pierre-Marie Baty -- unused variable |
||
| 4584 | br_vector3 perp; |
||
| 4585 | br_vector3 vertical; |
||
| 4586 | br_vector3 murderer_pos; |
||
| 4587 | br_scalar ts; |
||
| 4588 | //tCar_spec* car2; // Pierre-Marie Baty -- unused variable |
||
| 4589 | static tU32 next_incident_time = 0; |
||
| 4590 | static tIncident_type type = eNo_incident; |
||
| 4591 | static float severity; |
||
| 4592 | static tIncident_info info; |
||
| 4593 | static int random = 1; |
||
| 4594 | static int count = 0; |
||
| 4595 | //br_scalar temp; // Pierre-Marie Baty -- unused variable |
||
| 4596 | br_vector3 old_cam_pos; |
||
| 4597 | int removed; |
||
| 4598 | LOG_TRACE("(%p, %d)", c, pTime); |
||
| 4599 | |||
| 4600 | gPed_actor = NULL; |
||
| 4601 | m2 = &gCamera->t.t.mat; |
||
| 4602 | if (type == eNo_incident) { |
||
| 4603 | MoveCamToIncident(c, &type, &severity, &info, &next_incident_time); |
||
| 4604 | } |
||
| 4605 | if (type == eNo_incident) { |
||
| 4606 | return 0; |
||
| 4607 | } |
||
| 4608 | if (type == eIncident_ped) { |
||
| 4609 | BrVector3Copy(&old_cam_pos, &gCamera->t.t.translate.t); |
||
| 4610 | gPed_actor = info.ped_info.ped_actor; |
||
| 4611 | removed = PossibleRemoveNonCarFromWorld(info.ped_info.murderer_actor); |
||
| 4612 | BrMatrix34Mul(&mat, &gPed_actor->t.t.mat, &gPed_actor->parent->t.t.mat); |
||
| 4613 | info.ped_info.murderer_actor = c->car_master_actor; |
||
| 4614 | if (info.ped_info.murderer_actor != NULL) { |
||
| 4615 | BrVector3Copy(&murderer_pos, &c->pos); |
||
| 4616 | } else if (info.ped_info.murderer_actor->model != NULL) { |
||
| 4617 | BrVector3Add(&murderer_pos, &info.ped_info.murderer_actor->model->bounds.max, &info.ped_info.murderer_actor->model->bounds.min); |
||
| 4618 | BrVector3Scale(&murderer_pos, &murderer_pos, 0.5f); |
||
| 4619 | BrMatrix34ApplyP(&murderer_pos, &murderer_pos, &info.ped_info.murderer_actor->t.t.mat); |
||
| 4620 | } else { |
||
| 4621 | BrVector3Copy(&murderer_pos, &info.ped_info.murderer_actor->t.t.translate.t); |
||
| 4622 | } |
||
| 4623 | BrVector3Normalise(&vertical, (br_vector3*)mat.m[1]); |
||
| 4624 | BrVector3Scale(&vertical, &vertical, PedHeightFromActor(info.ped_info.ped_actor) / 2.f); |
||
| 4625 | BrVector3Accumulate((br_vector3*)mat.m[3], &vertical); |
||
| 4626 | if (next_incident_time > GetTotalTime() || !PipeSearchForwards()) { |
||
| 4627 | BrVector3Sub(&tv, (br_vector3*)mat.m[3], &murderer_pos); |
||
| 4628 | tv.v[1] = 0.f; |
||
| 4629 | BrVector3Normalise(&tv, &tv); |
||
| 4630 | BrVector3Set(&vertical, .0f, .4f, .0f); |
||
| 4631 | BrVector3Cross(&perp, &tv, &vertical); |
||
| 4632 | if (random) { |
||
| 4633 | BrVector3Negate(&perp, &perp); |
||
| 4634 | } |
||
| 4635 | if (PipeSearchForwards()) { |
||
| 4636 | BrVector3Accumulate(&perp, &tv); |
||
| 4637 | } |
||
| 4638 | BrVector3Add(&gCamera->t.t.translate.t, (br_vector3*)mat.m[3], &perp); |
||
| 4639 | CollideCamera2(&murderer_pos, &gCamera->t.t.translate.t, NULL, 1); |
||
| 4640 | } |
||
| 4641 | PointCamera((br_vector3*)mat.m[3], m2); |
||
| 4642 | BrVector3Sub(&tv, &gCamera->t.t.translate.t, &info.ped_info.murderer_actor->t.t.translate.t); |
||
| 4643 | ts = BrVector3LengthSquared(&tv); |
||
| 4644 | if (/*abs*/(GetTotalTime() - next_incident_time) > 2500) { // Pierre-Marie Baty -- useless call (already unsigned) |
||
| 4645 | type = eNo_incident; |
||
| 4646 | } |
||
| 4647 | if ((PipeSearchForwards() ? (next_incident_time < GetTotalTime()) : (next_incident_time > GetTotalTime())) |
||
| 4648 | && (ts > 25.f || CheckForWall(&info.ped_info.murderer_actor->t.t.translate.t, &gCamera->t.t.translate.t))) { |
||
| 4649 | type = eNo_incident; |
||
| 4650 | } |
||
| 4651 | if (removed) { |
||
| 4652 | PutNonCarBackInWorld(info.ped_info.murderer_actor); |
||
| 4653 | } |
||
| 4654 | if (Vector3DistanceSquared((br_vector3*)mat.m[3], &gCamera->t.t.translate.t) < .15f * .15f) { |
||
| 4655 | BrVector3Copy(&gCamera->t.t.translate.t, &old_cam_pos); |
||
| 4656 | gPed_actor = NULL; |
||
| 4657 | return 0; |
||
| 4658 | } |
||
| 4659 | } else if (type == eIncident_car) { |
||
| 4660 | BrVector3Sub(&tv, &info.car_info.car->pos, &c->pos); |
||
| 4661 | tv.v[1] = 0.f; |
||
| 4662 | BrVector3Normalise(&tv, &tv); |
||
| 4663 | BrVector3Scale(&tv, &tv, 2.f); |
||
| 4664 | BrVector3Add(&gCamera->t.t.translate.t, &info.car_info.car->pos, &tv); |
||
| 4665 | gCamera->t.t.translate.t.v[1] += 1.f; |
||
| 4666 | CollideCamera2(&info.car_info.car->pos, &gCamera->t.t.translate.t, NULL, 1); |
||
| 4667 | PointCamera(&info.car_info.car->pos, m2); |
||
| 4668 | BrVector3Sub(&tv, &gCamera->t.t.translate.t, &c->pos); |
||
| 4669 | ts = BrVector3LengthSquared(&tv); |
||
| 4670 | if (/*abs*/(GetTotalTime() - next_incident_time) > 2500) { // Pierre-Marie Baty -- useless call (already unsigned) |
||
| 4671 | type = eNo_incident; |
||
| 4672 | } |
||
| 4673 | if ((PipeSearchForwards() ? (next_incident_time < GetTotalTime()) : (next_incident_time > GetTotalTime())) |
||
| 4674 | && (ts > 25.f || CheckForWall(&c->pos, &gCamera->t.t.translate.t))) { |
||
| 4675 | type = eNo_incident; |
||
| 4676 | } |
||
| 4677 | } else if (type == eIncident_wall) { |
||
| 4678 | PointCamera(&c->pos, m2); |
||
| 4679 | BrVector3Sub(&tv, &gCamera->t.t.translate.t, &c->pos); |
||
| 4680 | ts = BrVector3LengthSquared(&tv); |
||
| 4681 | if (/*abs*/(GetTotalTime() - next_incident_time) > 2500) { // Pierre-Marie Baty -- useless call (already unsigned) |
||
| 4682 | type = eNo_incident; |
||
| 4683 | } |
||
| 4684 | if ((PipeSearchForwards() ? (next_incident_time < GetTotalTime()) : (next_incident_time > GetTotalTime())) |
||
| 4685 | && (ts > 25.f || CheckForWall(&c->pos, &gCamera->t.t.translate.t))) { |
||
| 4686 | type = eNo_incident; |
||
| 4687 | } |
||
| 4688 | } else { |
||
| 4689 | type = eNo_incident; |
||
| 4690 | } |
||
| 4691 | if (type == eNo_incident) { |
||
| 4692 | if (count > 1) { |
||
| 4693 | SetUpPanningCamera(c); |
||
| 4694 | return 0; |
||
| 4695 | } else { |
||
| 4696 | count++; |
||
| 4697 | if (IncidentCam(c, pTime)) { |
||
| 4698 | count--; |
||
| 4699 | return 1; |
||
| 4700 | } else { |
||
| 4701 | count--; |
||
| 4702 | return 0; |
||
| 4703 | } |
||
| 4704 | } |
||
| 4705 | } else { |
||
| 4706 | return 1; |
||
| 4707 | } |
||
| 4708 | } |
||
| 4709 | |||
| 4710 | // IDA: int __usercall MoveCamToIncident@<EAX>(tCar_spec *c@<EAX>, tIncident_type *type@<EDX>, float *severity@<EBX>, tIncident_info *info@<ECX>, tU32 *next_incident_time) |
||
| 4711 | int MoveCamToIncident(tCar_spec* c, tIncident_type* type, float* severity, tIncident_info* info, tU32* next_incident_time) { |
||
| 4712 | tU32 next_incident_time2; |
||
| 4713 | tU32 t; |
||
| 4714 | tIncident_type type2; |
||
| 4715 | float severity2; |
||
| 4716 | tIncident_info info2; |
||
| 4717 | br_vector3 pos; |
||
| 4718 | br_vector3 left; |
||
| 4719 | br_vector3 right; |
||
| 4720 | br_vector3 vertical; |
||
| 4721 | br_vector3 tv; |
||
| 4722 | //br_vector3 tv2; // Pierre-Marie Baty -- unused variable |
||
| 4723 | br_vector3 perp; |
||
| 4724 | int test; |
||
| 4725 | LOG_TRACE("(%p, %p, %p, %p, %p)", c, type, severity, info, next_incident_time); |
||
| 4726 | |||
| 4727 | test = 0; |
||
| 4728 | if (!GetNextIncident(-1, type, severity, info, next_incident_time)) { |
||
| 4729 | *type = eNo_incident; |
||
| 4730 | } else { |
||
| 4731 | if (/*abs*/(*next_incident_time) > 2500) { // Pierre-Marie Baty -- useless call (already unsigned) |
||
| 4732 | *type = eNo_incident; |
||
| 4733 | } else { |
||
| 4734 | t = *next_incident_time; |
||
| 4735 | for (test = 0; GetNextIncident(/*abs*/(t), &type2, &severity2, &info2, &next_incident_time2) && test <= 10 && /*abs*/(next_incident_time2) <= 3500; test++) { // Pierre-Marie Baty -- useless calls (already unsigned) |
||
| 4736 | if ((*type != type2 && type2 < *type) || (*type == type2 && *severity <= severity2)) { |
||
| 4737 | *info = info2; |
||
| 4738 | *severity = severity2; |
||
| 4739 | *type = type2; |
||
| 4740 | *next_incident_time = next_incident_time2; |
||
| 4741 | } |
||
| 4742 | t = next_incident_time2; |
||
| 4743 | } |
||
| 4744 | if (/*abs*/(*next_incident_time) > 2500) { // Pierre-Marie Baty -- useless call (already unsigned) |
||
| 4745 | *type = eNo_incident; |
||
| 4746 | } else { |
||
| 4747 | if (*type == eIncident_wall) { |
||
| 4748 | if (*severity < 0.1f) { |
||
| 4749 | *type = eNo_incident; |
||
| 4750 | return 0; |
||
| 4751 | } |
||
| 4752 | ScanCarsPositions(c, &c->pos, 100000.f, -1, /*abs*/(*next_incident_time), &pos, &t); // Pierre-Marie Baty -- useless call (already unsigned) |
||
| 4753 | if (t == 0) { |
||
| 4754 | *type = eNo_incident; |
||
| 4755 | } else { |
||
| 4756 | BrVector3Sub(&tv, &pos, &c->pos); |
||
| 4757 | if (BrVector3LengthSquared(&tv) > 102.91955471539592f) { |
||
| 4758 | *type = eNo_incident; |
||
| 4759 | } else { |
||
| 4760 | BrVector3Sub(&tv, &pos, &info->wall_info.pos); |
||
| 4761 | BrVector3Normalise(&tv, &tv); |
||
| 4762 | BrVector3Scale(&tv, &tv, 2.f); |
||
| 4763 | BrVector3Set(&vertical, 0.f, 1.f, 0.f); |
||
| 4764 | BrVector3Cross(&perp, &vertical, &tv); |
||
| 4765 | BrVector3Add(&left, &pos, &tv); |
||
| 4766 | BrVector3Add(&left, &left, &perp); |
||
| 4767 | left.v[1] += 2.f; |
||
| 4768 | BrVector3Add(&right, &pos, &tv); |
||
| 4769 | BrVector3Sub(&right, &right, &perp); |
||
| 4770 | right.v[1] += 2.f; |
||
| 4771 | CollideCamera2(&pos, &left, NULL, 1); |
||
| 4772 | CollideCamera2(&pos, &right, NULL, 1); |
||
| 4773 | if (Vector3DistanceSquared(&left, &pos) <= Vector3DistanceSquared(&right, &pos)) { |
||
| 4774 | BrVector3Copy(&tv, &right); |
||
| 4775 | } else { |
||
| 4776 | BrVector3Copy(&tv, &left); |
||
| 4777 | } |
||
| 4778 | BrVector3Copy(&gCamera->t.t.translate.t, &tv); |
||
| 4779 | } |
||
| 4780 | } |
||
| 4781 | } |
||
| 4782 | *next_incident_time += GetTotalTime(); |
||
| 4783 | } |
||
| 4784 | } |
||
| 4785 | } |
||
| 4786 | return 0; |
||
| 4787 | } |
||
| 4788 | |||
| 4789 | // IDA: void __usercall PanningExternalCamera(tCar_spec *c@<EAX>, tU32 pTime@<EDX>) |
||
| 4790 | void PanningExternalCamera(tCar_spec* c, tU32 pTime) { |
||
| 4791 | br_matrix34* m2; |
||
| 4792 | br_matrix34* m1; |
||
| 4793 | br_vector3 tv; |
||
| 4794 | br_scalar ts; |
||
| 4795 | static int inside_camera_zone = 1; |
||
| 4796 | LOG_TRACE("(%p, %d)", c, pTime); |
||
| 4797 | |||
| 4798 | BrVector3Sub(&tv, &gCamera->t.t.translate.t, &c->pos); |
||
| 4799 | ts = BrVector3LengthSquared(&tv); |
||
| 4800 | if (ts > 102.91955471539592f || (gSwitch_time != 0 && (PipeSearchForwards() ? (gSwitch_time <= GetTotalTime()) : (gSwitch_time >= GetTotalTime())))) { |
||
| 4801 | if ((inside_camera_zone || ts > 205.83910943079184f) && (ts > 25.f || CheckForWall(&c->pos, &gCamera->t.t.translate.t))) { |
||
| 4802 | SetUpPanningCamera(c); |
||
| 4803 | inside_camera_zone = 0; |
||
| 4804 | } |
||
| 4805 | } else { |
||
| 4806 | inside_camera_zone = 1; |
||
| 4807 | } |
||
| 4808 | m1 = &c->car_master_actor->t.t.mat; |
||
| 4809 | m2 = &gCamera->t.t.mat; |
||
| 4810 | PointCameraAtCar(c, m1, m2); |
||
| 4811 | } |
||
| 4812 | |||
| 4813 | // IDA: int __usercall CheckForWall@<EAX>(br_vector3 *start@<EAX>, br_vector3 *end@<EDX>) |
||
| 4814 | int CheckForWall(br_vector3* start, br_vector3* end) { |
||
| 4815 | br_vector3 dir; |
||
| 4816 | br_material* material; |
||
| 4817 | br_vector3 normal; |
||
| 4818 | br_scalar d; |
||
| 4819 | LOG_TRACE("(%p, %p)", start, end); |
||
| 4820 | |||
| 4821 | BrVector3Sub(&dir, end, start); |
||
| 4822 | FindFace(start, &dir, &normal, &d, &material); |
||
| 4823 | return d <= 1.f; |
||
| 4824 | } |
||
| 4825 | |||
| 4826 | // IDA: void __usercall SetUpPanningCamera(tCar_spec *c@<EAX>) |
||
| 4827 | void SetUpPanningCamera(tCar_spec* c) { |
||
| 4828 | br_vector3 pos; |
||
| 4829 | br_vector3 perp; |
||
| 4830 | br_vector3 dir; |
||
| 4831 | br_vector3 tv; |
||
| 4832 | br_vector3 tv2; |
||
| 4833 | br_scalar ts; |
||
| 4834 | tU32 time; |
||
| 4835 | tU32 t; |
||
| 4836 | tU32 t2; |
||
| 4837 | tU32 time_step; |
||
| 4838 | //br_matrix34* m2; // Pierre-Marie Baty -- unused variable |
||
| 4839 | //br_matrix34* m1; // Pierre-Marie Baty -- unused variable |
||
| 4840 | br_vector3 left; |
||
| 4841 | br_vector3 right; |
||
| 4842 | br_vector3 car_centre; |
||
| 4843 | //int left_score; // Pierre-Marie Baty -- unused variable |
||
| 4844 | //int right_score; // Pierre-Marie Baty -- unused variable |
||
| 4845 | LOG_TRACE("(%p)", c); |
||
| 4846 | |||
| 4847 | ScanCarsPositions(c, &c->pos, 411.6782f, -1, 5000, &car_centre, &t); |
||
| 4848 | BrVector3Sub(&dir, &car_centre, &c->pos); |
||
| 4849 | time_step = ((t > GetTotalTime()) ? t - GetTotalTime() : GetTotalTime() - t) * SRandomBetween(0.8f, 1.5f); |
||
| 4850 | if (BrVector3LengthSquared(&dir) >= .01f && t != 0) { |
||
| 4851 | ScanCarsPositions(c, &c->pos, 102.9196f, -1, time_step / 2, &pos, &t2); |
||
| 4852 | if (t2 == 0) { |
||
| 4853 | BrVector3Copy(&pos, &c->pos); |
||
| 4854 | } |
||
| 4855 | } else { |
||
| 4856 | BrVector3Negate(&dir, (br_vector3*)&c->car_master_actor->t.t.mat.m[2]); |
||
| 4857 | BrVector3Copy(&pos, &c->pos); |
||
| 4858 | time_step = 0; |
||
| 4859 | } |
||
| 4860 | BrVector3SetFloat(&tv, 0.f, 1.f, 0.f); |
||
| 4861 | BrVector3Cross(&perp, &tv, &dir); |
||
| 4862 | ts = BrVector3Length(&perp); |
||
| 4863 | if (ts >= .1f) { |
||
| 4864 | BrVector3Scale(&perp, &perp, 2.f / ts * SRandomBetween(0.3333333f, 1.f)); |
||
| 4865 | BrVector3Set(&tv2, 0.f, 2 * SRandomBetween(0.3333333f, 1.f), 0.f); |
||
| 4866 | BrVector3Add(&tv, &pos, &tv2); |
||
| 4867 | BrVector3Add(&left, &tv, &perp); |
||
| 4868 | BrVector3Sub(&right, &tv, &perp); |
||
| 4869 | CollideCamera2(&pos, &left, NULL, 1); |
||
| 4870 | CollideCamera2(&pos, &right, NULL, 1); |
||
| 4871 | BrVector3Sub(&tv, &left, &pos); |
||
| 4872 | BrVector3Sub(&tv2, &right, &pos); |
||
| 4873 | if (BrVector3LengthSquared(&tv) + SRandomPosNeg(.01f) <= BrVector3LengthSquared(&tv2)) { |
||
| 4874 | BrVector3Copy(&gCamera->t.t.translate.t, &right); |
||
| 4875 | } else { |
||
| 4876 | BrVector3Copy(&gCamera->t.t.translate.t, &left); |
||
| 4877 | } |
||
| 4878 | if (t != 0 && CheckForWall(&c->pos, &gCamera->t.t.translate.t)) { |
||
| 4879 | ScanCarsPositions(c, &c->pos, 10000.f, -1, 1000, &tv, &time); |
||
| 4880 | CollideCamera2(&tv, &gCamera->t.t.translate.t, NULL, 1); |
||
| 4881 | } |
||
| 4882 | if (t != 0 && CheckForWall(&car_centre, &gCamera->t.t.translate.t)) { |
||
| 4883 | time_step = time_step / 16; |
||
| 4884 | BrVector3Copy(&tv, &pos); |
||
| 4885 | while (1) { |
||
| 4886 | ScanCarsPositions(c, &tv, 10000.f, /*abs*/(t2 - GetTotalTime()), time_step, &tv2, &time); // Pierre-Marie Baty -- useless call (already unsigned) |
||
| 4887 | t2 += (GetReplayDirection() ? 1 : -1) * time_step; |
||
| 4888 | BrVector3Copy(&tv, &tv2); |
||
| 4889 | if (CheckForWall(&tv, &gCamera->t.t.translate.t)) { |
||
| 4890 | break; |
||
| 4891 | } |
||
| 4892 | if (t2 >= GetTotalTime() + 5000) { |
||
| 4893 | break; |
||
| 4894 | } |
||
| 4895 | } |
||
| 4896 | gSwitch_time = t2; |
||
| 4897 | } else { |
||
| 4898 | if (t == 0) { |
||
| 4899 | t = 5000; |
||
| 4900 | } |
||
| 4901 | gSwitch_time = t; |
||
| 4902 | } |
||
| 4903 | } |
||
| 4904 | } |
||
| 4905 | |||
| 4906 | // IDA: void __usercall SaveCameraPosition(int i@<EAX>) |
||
| 4907 | void SaveCameraPosition(int i) { |
||
| 4908 | LOG_TRACE("(%d)", i); |
||
| 4909 | |||
| 4910 | if (gSave_camera[i].saved != 1) { |
||
| 4911 | gSave_camera[i].zoom = gCamera_zoom; |
||
| 4912 | gSave_camera[i].yaw = gCamera_yaw; |
||
| 4913 | gSave_camera[i].saved = 1; |
||
| 4914 | } |
||
| 4915 | } |
||
| 4916 | |||
| 4917 | // IDA: void __usercall RestoreCameraPosition(int i@<EAX>) |
||
| 4918 | void RestoreCameraPosition(int i) { |
||
| 4919 | LOG_TRACE("(%d)", i); |
||
| 4920 | |||
| 4921 | if (gSave_camera[i].saved != 0) { |
||
| 4922 | gCamera_zoom = gSave_camera[i].zoom; |
||
| 4923 | gCamera_yaw = gSave_camera[i].yaw; |
||
| 4924 | gSave_camera[i].saved = 0; |
||
| 4925 | } |
||
| 4926 | } |
||
| 4927 | |||
| 4928 | // IDA: void __usercall NormalPositionExternalCamera(tCar_spec *c@<EAX>, tU32 pTime@<EDX>) |
||
| 4929 | void NormalPositionExternalCamera(tCar_spec* c, tU32 pTime) { |
||
| 4930 | br_matrix34* m2; |
||
| 4931 | br_matrix34* m1; |
||
| 4932 | br_scalar time; |
||
| 4933 | //br_scalar ts; // Pierre-Marie Baty -- unused variable |
||
| 4934 | //br_scalar ts2; // Pierre-Marie Baty -- unused variable |
||
| 4935 | br_scalar dist; |
||
| 4936 | br_scalar height_inc; |
||
| 4937 | br_scalar l; |
||
| 4938 | //br_scalar frac; // Pierre-Marie Baty -- unused variable |
||
| 4939 | br_vector3 vn; |
||
| 4940 | br_vector3 a; |
||
| 4941 | //br_vector3 b; // Pierre-Marie Baty -- unused variable |
||
| 4942 | //br_vector3 tv; // Pierre-Marie Baty -- unused variable |
||
| 4943 | //br_angle yaw; // Pierre-Marie Baty -- unused variable |
||
| 4944 | //br_angle theta; // Pierre-Marie Baty -- unused variable |
||
| 4945 | br_scalar d; |
||
| 4946 | //int face; // Pierre-Marie Baty -- unused variable |
||
| 4947 | //int i; // Pierre-Marie Baty -- unused variable |
||
| 4948 | int swoop; |
||
| 4949 | int manual_swing; |
||
| 4950 | int manual_zoom; |
||
| 4951 | br_vector3 old_camera_pos; |
||
| 4952 | //br_scalar scale; // Pierre-Marie Baty -- unused variable |
||
| 4953 | LOG_TRACE("(%p, %d)", c, pTime); |
||
| 4954 | |||
| 4955 | m1 = &gCamera->t.t.mat; |
||
| 4956 | m2 = &c->car_master_actor->t.t.mat; |
||
| 4957 | swoop = gCountdown && c->pos.v[1] + 0.001f < gCamera_height; |
||
| 4958 | manual_swing = gOld_yaw__car != gCamera_yaw || swoop; |
||
| 4959 | manual_zoom = (double)gOld_zoom != gCamera_zoom; |
||
| 4960 | BrVector3Copy(&old_camera_pos, &gCamera->t.t.translate.t); |
||
| 4961 | if (!gProgram_state.cockpit_on) { |
||
| 4962 | if (swoop) { |
||
| 4963 | gCamera_yaw = 0; |
||
| 4964 | manual_swing = 1; |
||
| 4965 | } |
||
| 4966 | if (fabsf(c->speedo_speed) > 0.0006f && gCamera_mode > 0) { |
||
| 4967 | gCamera_mode = -1; |
||
| 4968 | gCamera_sign = BrVector3Dot((br_vector3*)m2->m[2], &c->direction) > 0.0f; |
||
| 4969 | } |
||
| 4970 | if (c->frame_collision_flag && gCamera_mode != -2) { |
||
| 4971 | gCamera_mode = 1; |
||
| 4972 | } |
||
| 4973 | if (gCar_flying || gCamera_reset || gCamera_mode == -2) { |
||
| 4974 | gCamera_mode = 0; |
||
| 4975 | } |
||
| 4976 | d = sqrtf(gCamera_zoom) + 4.f / WORLD_SCALE; |
||
| 4977 | if (!gCamera_mode || gCamera_mode == -1) { |
||
| 4978 | BrVector3Copy(&vn, &c->direction); |
||
| 4979 | MoveWithWheels(c, &vn, manual_swing); |
||
| 4980 | vn.v[1] = 0.0f; |
||
| 4981 | BrVector3Normalise(&vn, &vn); |
||
| 4982 | if (gCar_flying) { |
||
| 4983 | gCamera_sign = 0; |
||
| 4984 | } |
||
| 4985 | SwingCamera(c, m2, m1, &vn, pTime); |
||
| 4986 | BrVector3Scale(&a, &vn, d); |
||
| 4987 | BrVector3Sub(&gCamera->t.t.translate.t, &c->pos, &a); |
||
| 4988 | BrVector3Copy(&gView_direction, &vn); |
||
| 4989 | } |
||
| 4990 | if (gCamera_mode == 1) { |
||
| 4991 | if (manual_swing || manual_zoom) { |
||
| 4992 | BrVector3Copy(&old_camera_pos, &gCamera_pos_before_collide); |
||
| 4993 | } |
||
| 4994 | BrVector3Sub(&a, &c->pos, &old_camera_pos); |
||
| 4995 | a.v[1] = 0.0f; |
||
| 4996 | if (manual_swing) { |
||
| 4997 | DrVector3RotateY(&a, (gCamera_sign == 0 ? 1 : -1) * (gCamera_yaw - gOld_yaw__car)); |
||
| 4998 | gCamera_yaw = gOld_yaw__car; |
||
| 4999 | } |
||
| 5000 | BrVector3Normalise(&vn, &a); |
||
| 5001 | BrVector3Copy(&gView_direction, &vn); |
||
| 5002 | BrVector3Scale(&vn, &vn, -d); |
||
| 5003 | BrVector3Accumulate(&a, &vn); |
||
| 5004 | dist = BrVector3Length(&a); |
||
| 5005 | l = (float)pTime / 1000.0f * (dist + 1.0f) / dist; |
||
| 5006 | if (l < 1.0f && BrVector3Dot(&a, &vn) > 0.0f) { |
||
| 5007 | BrVector3Scale(&a, &a, (l - 1.f)); |
||
| 5008 | BrVector3Accumulate(&vn, &a); |
||
| 5009 | } |
||
| 5010 | BrVector3Add(&gCamera->t.t.translate.t, &c->pos, &vn); |
||
| 5011 | } |
||
| 5012 | height_inc = gCamera_zoom * gCamera_zoom + 0.3f; |
||
| 5013 | time = pTime * 0.001f; |
||
| 5014 | if (!gCamera_frozen || gAction_replay_mode) { |
||
| 5015 | if (pTime >= 5000) { |
||
| 5016 | gCamera_height = c->pos.v[1]; |
||
| 5017 | } else if (swoop) { |
||
| 5018 | if (time > 0.2f) { |
||
| 5019 | time = 0.2f; |
||
| 5020 | } |
||
| 5021 | gCamera_height -= time * 5.0f; |
||
| 5022 | if (gCamera_height < c->pos.v[1]) { |
||
| 5023 | gCamera_height = c->pos.v[1]; |
||
| 5024 | } |
||
| 5025 | } else { |
||
| 5026 | gCamera_height = time * 5.0f * c->pos.v[1] + gCamera_height; |
||
| 5027 | gCamera_height = gCamera_height / (time * 5.0f + 1.0f); |
||
| 5028 | } |
||
| 5029 | } |
||
| 5030 | l = c->direction.v[1] * d; |
||
| 5031 | if (l > 0) { |
||
| 5032 | if (c->pos.v[1] - l - height_inc / 2.0f > gCamera_height) { |
||
| 5033 | gCamera_height = c->pos.v[1] - l - height_inc / 2.0f; |
||
| 5034 | } |
||
| 5035 | } |
||
| 5036 | |||
| 5037 | gCamera->t.t.translate.t.v[1] = height_inc + gCamera_height; |
||
| 5038 | BrVector3Copy(&gCamera_pos_before_collide, &gCamera->t.t.translate.t); |
||
| 5039 | CollideCameraWithOtherCars(&c->pos, &gCamera->t.t.translate.t); |
||
| 5040 | CollideCamera2(&c->pos, &gCamera->t.t.translate.t, &old_camera_pos, manual_swing || manual_zoom); |
||
| 5041 | if (gCamera_has_collided && swoop) { |
||
| 5042 | gCamera_height = c->pos.v[1]; |
||
| 5043 | } |
||
| 5044 | PointCameraAtCar(c, m2, m1); |
||
| 5045 | } |
||
| 5046 | gOld_yaw__car = gCamera_yaw; |
||
| 5047 | gOld_zoom = (br_angle)gCamera_zoom; |
||
| 5048 | } |
||
| 5049 | |||
| 5050 | // IDA: void __usercall MoveWithWheels(tCar_spec *c@<EAX>, br_vector3 *vn@<EDX>, int manual_swing@<EBX>) |
||
| 5051 | void MoveWithWheels(tCar_spec* c, br_vector3* vn, int manual_swing) { |
||
| 5052 | br_angle yaw; |
||
| 5053 | br_angle theta; |
||
| 5054 | static int move_with_wheels; |
||
| 5055 | LOG_TRACE("(%p, %p, %d)", c, vn, manual_swing); |
||
| 5056 | |||
| 5057 | if (c->speed < 0.0001f && !gCamera_mode) { |
||
| 5058 | if (manual_swing) { |
||
| 5059 | if (gCamera_yaw <= 32760u) { |
||
| 5060 | yaw = gCamera_yaw; |
||
| 5061 | } else { |
||
| 5062 | yaw = gCamera_yaw - 32760; |
||
| 5063 | } |
||
| 5064 | if (yaw <= BrDegreeToAngle(45) || yaw >= BrDegreeToAngle(135)) { |
||
| 5065 | if (!move_with_wheels) { |
||
| 5066 | theta = BrRadianToAngle(atan2f(c->wpos[0].v[2] * c->curvature, 1.0f)); |
||
| 5067 | gCamera_yaw -= (-2 * gCamera_sign + 1) * theta; |
||
| 5068 | move_with_wheels = 1; |
||
| 5069 | } |
||
| 5070 | } else if (move_with_wheels) { |
||
| 5071 | theta = BrRadianToAngle(atan2(c->wpos[0].v[2] * c->curvature, 1.0)); |
||
| 5072 | gCamera_yaw += (-2 * gCamera_sign + 1) * theta; |
||
| 5073 | move_with_wheels = 0; |
||
| 5074 | } |
||
| 5075 | } |
||
| 5076 | if (move_with_wheels) { |
||
| 5077 | if (!gCar_flying) { |
||
| 5078 | theta = BrRadianToAngle(atan2(c->wpos[0].v[2] * c->curvature, 1.0)); |
||
| 5079 | DrVector3RotateY(vn, theta); |
||
| 5080 | } |
||
| 5081 | } |
||
| 5082 | } |
||
| 5083 | } |
||
| 5084 | |||
| 5085 | // IDA: void __usercall SwingCamera(tCar_spec *c@<EAX>, br_matrix34 *m1@<EDX>, br_matrix34 *m2@<EBX>, br_vector3 *vn@<ECX>, tU32 pTime) |
||
| 5086 | void SwingCamera(tCar_spec* c, br_matrix34* m1, br_matrix34* m2, br_vector3* vn, tU32 pTime) { |
||
| 5087 | //int i; // Pierre-Marie Baty -- unused variable |
||
| 5088 | br_scalar ts; |
||
| 5089 | br_angle yaw; |
||
| 5090 | br_angle theta; |
||
| 5091 | //br_angle alpha; // Pierre-Marie Baty -- unused variable |
||
| 5092 | br_scalar sin_dtheta; |
||
| 5093 | br_scalar cos_dtheta; |
||
| 5094 | br_scalar sign; |
||
| 5095 | int manual_swing; |
||
| 5096 | static br_angle omega = 0; |
||
| 5097 | static int elapsed_time = -1; |
||
| 5098 | static br_vector3 old_vn; |
||
| 5099 | LOG_TRACE("(%p, %p, %p, %p, %d)", c, m1, m2, vn, pTime); |
||
| 5100 | |||
| 5101 | manual_swing = gOld_yaw__car != gCamera_yaw; |
||
| 5102 | if (elapsed_time > 500) { |
||
| 5103 | elapsed_time = -1; |
||
| 5104 | } |
||
| 5105 | if (elapsed_time >= 0) { |
||
| 5106 | elapsed_time += pTime; |
||
| 5107 | } |
||
| 5108 | sign = -BrVector3Dot((br_vector3*)m1->m[2], vn); |
||
| 5109 | ts = BrVector3Dot(vn, &old_vn); |
||
| 5110 | |||
| 5111 | BrVector3Copy(&old_vn, vn); |
||
| 5112 | if ((sign < 0.0f) == gCamera_sign) { |
||
| 5113 | elapsed_time = -1; |
||
| 5114 | } else if (ts <= 0.0 || elapsed_time >= 0) { |
||
| 5115 | if (elapsed_time < 0) { |
||
| 5116 | elapsed_time = 0; |
||
| 5117 | } |
||
| 5118 | if (elapsed_time < 500 && sign <= 0.0f) { |
||
| 5119 | BrVector3Negate(vn, vn); |
||
| 5120 | } else { |
||
| 5121 | elapsed_time = 500; |
||
| 5122 | if (sign <= 0.0) { |
||
| 5123 | ts = 0.0006f; |
||
| 5124 | } else { |
||
| 5125 | ts = 0.0001f; |
||
| 5126 | } |
||
| 5127 | if (fabsf(c->speedo_speed) <= ts || gCar_flying) { |
||
| 5128 | BrVector3Negate(vn, vn); |
||
| 5129 | } else { |
||
| 5130 | gCamera_sign = gCamera_sign == 0; |
||
| 5131 | omega = BrDegreeToAngle(pTime * 0.03f); |
||
| 5132 | if (gCamera_yaw <= 32760) { |
||
| 5133 | yaw = gCamera_yaw; |
||
| 5134 | } else { |
||
| 5135 | yaw = gCamera_yaw - 32760; |
||
| 5136 | } |
||
| 5137 | if ((uint16_t)(gCamera_yaw + 16380) <= 32760) { |
||
| 5138 | if (yaw > 8190 && yaw < 24570) { |
||
| 5139 | gCamera_yaw = 32760 - gCamera_yaw; |
||
| 5140 | } |
||
| 5141 | } else { |
||
| 5142 | gCamera_yaw = 32760 - gCamera_yaw; |
||
| 5143 | } |
||
| 5144 | } |
||
| 5145 | } |
||
| 5146 | } else { |
||
| 5147 | gCamera_sign = gCamera_sign == 0; |
||
| 5148 | if (gCamera_yaw <= 32760) { |
||
| 5149 | yaw = gCamera_yaw; |
||
| 5150 | } else { |
||
| 5151 | yaw = gCamera_yaw - 32760; |
||
| 5152 | } |
||
| 5153 | if (yaw > 8190 && yaw < 24570) { |
||
| 5154 | gCamera_yaw = -gCamera_yaw; |
||
| 5155 | } |
||
| 5156 | } |
||
| 5157 | if (gCamera_sign) { |
||
| 5158 | yaw = -gCamera_yaw; |
||
| 5159 | } else { |
||
| 5160 | yaw = gCamera_yaw; |
||
| 5161 | } |
||
| 5162 | if (!gCar_flying) { |
||
| 5163 | DrVector3RotateY(vn, yaw); |
||
| 5164 | } |
||
| 5165 | sin_dtheta = 0.0; |
||
| 5166 | br_scalar v16 = vn->v[0] * gView_direction.v[2] - vn->v[2] * gView_direction.v[0]; |
||
| 5167 | br_scalar v17 = vn->v[0] * gView_direction.v[0] + vn->v[2] * gView_direction.v[2]; |
||
| 5168 | |||
| 5169 | br_angle v8 = BrRadianToAngle(sqrt(c->omega.v[2] * c->omega.v[2] + c->omega.v[0] * c->omega.v[0] + c->omega.v[1] * c->omega.v[1]) * pTime / 1000.0); |
||
| 5170 | sin_dtheta = sin(BrAngleToRadian(v8)) + 0.1; |
||
| 5171 | |||
| 5172 | if (omega || gCamera_reset || (c->speed < 0.0001f && !manual_swing) || gCamera_mode == -1 || (v17 > 0.0 && !manual_swing && fabs(v16) > sin_dtheta)) { |
||
| 5173 | if (!gCar_flying) { |
||
| 5174 | theta = BrRadianToAngle(asin(sin_dtheta)); |
||
| 5175 | if (omega < theta) { |
||
| 5176 | omega = theta; |
||
| 5177 | } |
||
| 5178 | if (!omega) { |
||
| 5179 | omega = BrDegreeToAngle(pTime * 0.03); // (__int64)((double)(int)pTime * 0.03 * 182.0444444444445); |
||
| 5180 | } |
||
| 5181 | cos_dtheta = cos(BrAngleToRadian(omega)); |
||
| 5182 | if (cos_dtheta <= v17) { |
||
| 5183 | omega = 0; |
||
| 5184 | gCamera_mode = 0; |
||
| 5185 | } else { |
||
| 5186 | ts = BrAngleToRadian(omega); |
||
| 5187 | if (v16 <= 0.0) { |
||
| 5188 | vn->v[0] = cosf(ts) * gView_direction.v[0] - sinf(ts) * gView_direction.v[2]; |
||
| 5189 | vn->v[2] = sinf(ts) * gView_direction.v[0] + cosf(ts) * gView_direction.v[2]; |
||
| 5190 | } else { |
||
| 5191 | vn->v[0] = sinf(ts) * gView_direction.v[2] + cosf(ts) * gView_direction.v[0]; |
||
| 5192 | vn->v[2] = cosf(ts) * gView_direction.v[2] - sinf(ts) * gView_direction.v[0]; |
||
| 5193 | } |
||
| 5194 | omega += BrDegreeToAngle(pTime * 0.03f); |
||
| 5195 | if (BrDegreeToAngle(pTime * 0.1f) < omega) { |
||
| 5196 | omega = BrDegreeToAngle(pTime * 0.1f); |
||
| 5197 | } |
||
| 5198 | if (omega < theta) { |
||
| 5199 | omega = theta; |
||
| 5200 | } |
||
| 5201 | } |
||
| 5202 | } |
||
| 5203 | } |
||
| 5204 | } |
||
| 5205 | |||
| 5206 | // IDA: void __usercall PointCameraAtCar(tCar_spec *c@<EAX>, br_matrix34 *m1@<EDX>, br_matrix34 *m2@<EBX>) |
||
| 5207 | void PointCameraAtCar(tCar_spec* c, br_matrix34* m1, br_matrix34* m2) { |
||
| 5208 | br_vector3 vn; |
||
| 5209 | br_vector3 tv; |
||
| 5210 | br_vector3 tv2; |
||
| 5211 | br_scalar dist; |
||
| 5212 | br_scalar frac; |
||
| 5213 | br_angle theta; |
||
| 5214 | br_vector3* pos; |
||
| 5215 | br_camera* camera_ptr; |
||
| 5216 | //br_angle off_centre_angle; // Pierre-Marie Baty -- unused variable |
||
| 5217 | int swoop; |
||
| 5218 | //br_scalar scale; // Pierre-Marie Baty -- unused variable |
||
| 5219 | LOG_TRACE("(%p, %p, %p)", c, m1, m2); |
||
| 5220 | |||
| 5221 | camera_ptr = gCamera->type_data; |
||
| 5222 | theta = camera_ptr->field_of_view / 5; |
||
| 5223 | swoop = gCountdown && c->pos.v[1] + 0.01f < gCamera_height; |
||
| 5224 | if (0) { |
||
| 5225 | BrVector3Sub(&tv, &gAverage_grid_position, &c->pos); |
||
| 5226 | frac = (gCamera_height - c->pos.v[1]) / 10.0f; |
||
| 5227 | BrVector3Scale(&tv, &tv, frac); |
||
| 5228 | BrVector3Accumulate(&tv, &c->pos); |
||
| 5229 | pos = &tv; |
||
| 5230 | theta = (1.0f - frac) * (float)theta; |
||
| 5231 | } else { |
||
| 5232 | pos = &c->pos; |
||
| 5233 | } |
||
| 5234 | BrVector3Set(&vn, c->pos.v[0] - m2->m[3][0], 0.f, c->pos.v[2] - m2->m[3][2]); |
||
| 5235 | BrVector3Normalise(&vn, &vn); |
||
| 5236 | m2->m[0][0] = -vn.v[2]; |
||
| 5237 | m2->m[0][1] = 0.0f; |
||
| 5238 | m2->m[0][2] = vn.v[0]; |
||
| 5239 | m2->m[1][0] = 0.0f; |
||
| 5240 | m2->m[1][1] = 1.0f; |
||
| 5241 | m2->m[1][2] = 0.0f; |
||
| 5242 | m2->m[2][0] = -vn.v[0]; |
||
| 5243 | m2->m[2][1] = 0.0f; |
||
| 5244 | m2->m[2][2] = -vn.v[2]; |
||
| 5245 | BrVector3Sub(&tv2, pos, (br_vector3*)m2->m[3]); |
||
| 5246 | dist = BrVector3Dot(&tv2, &vn); |
||
| 5247 | BrMatrix34PreRotateX(m2, theta - BrRadianToAngle(atan2f(m2->m[3][1] - pos->v[1], dist))); |
||
| 5248 | } |
||
| 5249 | |||
| 5250 | // IDA: void __usercall PointCamera(br_vector3 *pos@<EAX>, br_matrix34 *m2@<EDX>) |
||
| 5251 | void PointCamera(br_vector3* pos, br_matrix34* m2) { |
||
| 5252 | br_vector3 vn; |
||
| 5253 | br_scalar dist; |
||
| 5254 | br_angle theta; |
||
| 5255 | br_camera* camera_ptr; |
||
| 5256 | LOG_TRACE("(%p, %p)", pos, m2); |
||
| 5257 | |||
| 5258 | camera_ptr = gCamera->type_data; |
||
| 5259 | BrVector3Sub(&vn, pos, (br_vector3*)m2->m[3]); |
||
| 5260 | vn.v[1] = 0.f; |
||
| 5261 | BrVector3Normalise(&vn, &vn); |
||
| 5262 | m2->m[0][0] = -vn.v[2]; |
||
| 5263 | m2->m[0][1] = 0.f; |
||
| 5264 | m2->m[0][2] = vn.v[0]; |
||
| 5265 | m2->m[1][0] = 0.f; |
||
| 5266 | m2->m[1][1] = 1.f; |
||
| 5267 | m2->m[1][2] = 0.f; |
||
| 5268 | m2->m[2][0] = -vn.v[0]; |
||
| 5269 | m2->m[2][1] = 0.f; |
||
| 5270 | m2->m[2][2] = -vn.v[2]; |
||
| 5271 | dist = BrVector3LengthSquared(&vn); |
||
| 5272 | theta = BR_ATAN2(m2->m[3][1] - pos->v[1], dist); |
||
| 5273 | BrMatrix34PreRotateX(m2, camera_ptr->field_of_view / 5 - theta); |
||
| 5274 | } |
||
| 5275 | |||
| 5276 | // IDA: int __usercall CollideCamera2@<EAX>(br_vector3 *car_pos@<EAX>, br_vector3 *cam_pos@<EDX>, br_vector3 *old_camera_pos@<EBX>, int manual_move@<ECX>) |
||
| 5277 | int CollideCamera2(br_vector3* car_pos, br_vector3* cam_pos, br_vector3* old_camera_pos, int manual_move) { |
||
| 5278 | int i; |
||
| 5279 | int k; |
||
| 5280 | br_vector3 a; |
||
| 5281 | br_vector3 b; |
||
| 5282 | //br_vector3 vn; // Pierre-Marie Baty -- unused variable |
||
| 5283 | br_vector3 tv; |
||
| 5284 | br_vector3 tv2; |
||
| 5285 | br_scalar l; |
||
| 5286 | br_scalar d; |
||
| 5287 | br_scalar ts; |
||
| 5288 | br_scalar ts2; |
||
| 5289 | br_scalar dist; |
||
| 5290 | br_scalar hither; |
||
| 5291 | //br_angle theta; // Pierre-Marie Baty -- unused variable |
||
| 5292 | tBounds bnds; |
||
| 5293 | br_matrix34 mat; |
||
| 5294 | br_material* material; |
||
| 5295 | br_scalar alpha; |
||
| 5296 | br_scalar sa; |
||
| 5297 | br_scalar sb; |
||
| 5298 | br_scalar sc; |
||
| 5299 | tFace_ref face_list[3]; |
||
| 5300 | LOG_TRACE("(%p, %p, %p, %d)", car_pos, cam_pos, old_camera_pos, manual_move); |
||
| 5301 | |||
| 5302 | #ifdef DETHRACE_FIX_BUGS |
||
| 5303 | ts2 = 0.f; |
||
| 5304 | #endif |
||
| 5305 | hither = ((br_camera*)gCamera->type_data)->hither_z * 3.0f; |
||
| 5306 | gCamera_has_collided = 0; |
||
| 5307 | for (i = 0; i < 1; i++) { |
||
| 5308 | BrVector3Sub(&tv, cam_pos, car_pos); |
||
| 5309 | dist = BrVector3Length(&tv); |
||
| 5310 | BrVector3Scale(&tv, &tv, 1.2f); |
||
| 5311 | FindFace(car_pos, &tv, &a, &ts, &material); |
||
| 5312 | if (ts <= 1.0) { |
||
| 5313 | gCamera_has_collided = 1; |
||
| 5314 | if (BrVector3Dot(&a, &tv) > 0.0f) { |
||
| 5315 | BrVector3Negate(&a, &a); |
||
| 5316 | } |
||
| 5317 | if (gCamera_mode == 1 && !manual_move) { |
||
| 5318 | BrVector3Sub(&tv2, car_pos, old_camera_pos); |
||
| 5319 | FindFace(old_camera_pos, &tv2, &b, &ts2, &material); |
||
| 5320 | if (ts2 > 1.0f) { |
||
| 5321 | BrVector3Copy(cam_pos, old_camera_pos); |
||
| 5322 | return i; |
||
| 5323 | } |
||
| 5324 | } |
||
| 5325 | BrVector3Scale(&tv, &tv, ts); |
||
| 5326 | BrVector3Scale(&tv2, &a, hither); |
||
| 5327 | BrVector3Accumulate(&tv, &tv2); |
||
| 5328 | dist = BrVector3Length(&tv); |
||
| 5329 | BrVector3Add(cam_pos, car_pos, &tv); |
||
| 5330 | if (gMin_camera_car_distance > dist && i == 0 && a.v[1] > -0.7) { |
||
| 5331 | BrVector3Scale(&tv2, &a, -a.v[1]); |
||
| 5332 | tv2.v[1] += 1.f; |
||
| 5333 | if (gProgram_state.current_car.car_master_actor->t.t.mat.m[1][1] < 0.f) { |
||
| 5334 | BrVector3Negate(&tv2, &tv2); |
||
| 5335 | } |
||
| 5336 | d = BrVector3LengthSquared(&tv2); |
||
| 5337 | l = BrVector3Dot(&tv2, &tv); |
||
| 5338 | alpha = BrVector3LengthSquared(&tv) - gMin_camera_car_distance * gMin_camera_car_distance; |
||
| 5339 | ts2 = l * l - alpha * d * 4.0; |
||
| 5340 | if (ts2 >= 0.f && d != 0.f) { |
||
| 5341 | sa = (sqrtf(ts2) - l) / (d * 2.0f); |
||
| 5342 | BrVector3Scale(&tv2, &tv2, sa); |
||
| 5343 | FindFace(cam_pos, &tv2, &a, &ts, &material); |
||
| 5344 | if (ts < 1.0f) { |
||
| 5345 | BrVector3Scale(&tv2, &tv2, ts); |
||
| 5346 | } |
||
| 5347 | BrVector3Set(&b, tv.v[0], 0.f, tv.v[2]); |
||
| 5348 | BrVector3Normalise(&b, &b); |
||
| 5349 | BrVector3Accumulate(&tv, &tv2); |
||
| 5350 | ts2 = BrVector3Dot(&tv, &b); |
||
| 5351 | if (ts2 < 0.03f && !gAction_replay_mode) { |
||
| 5352 | BrVector3Normalise(&tv2, &tv2); |
||
| 5353 | alpha = BrVector3Dot(&tv2, &b); |
||
| 5354 | if (alpha < -0.03f) { |
||
| 5355 | alpha = (0.03f - ts2) / alpha; |
||
| 5356 | BrVector3Scale(&tv2, &tv2, alpha); |
||
| 5357 | BrVector3Add(&tv, &tv2, &tv); |
||
| 5358 | } |
||
| 5359 | } |
||
| 5360 | } |
||
| 5361 | BrVector3Add(cam_pos, car_pos, &tv); |
||
| 5362 | } |
||
| 5363 | } |
||
| 5364 | |||
| 5365 | bnds.mat = &mat; |
||
| 5366 | BrMatrix34Identity(&mat); |
||
| 5367 | BrVector3Set(&tv2, hither, hither, hither); |
||
| 5368 | bnds.original_bounds.min.v[0] = cam_pos->v[0] - hither; |
||
| 5369 | bnds.original_bounds.min.v[1] = cam_pos->v[1] - hither; |
||
| 5370 | bnds.original_bounds.min.v[2] = cam_pos->v[2] - hither; |
||
| 5371 | bnds.original_bounds.max.v[0] = cam_pos->v[0] + hither; |
||
| 5372 | bnds.original_bounds.max.v[1] = cam_pos->v[1] + hither; |
||
| 5373 | bnds.original_bounds.max.v[2] = cam_pos->v[2] + hither; |
||
| 5374 | k = FindFacesInBox(&bnds, face_list, 3); |
||
| 5375 | if (k > 0) { |
||
| 5376 | BrVector3Sub(&tv2, cam_pos, &face_list[0].v[0]); |
||
| 5377 | sa = BrVector3Dot(&face_list[0].normal, &tv2); |
||
| 5378 | // ts2 = sa; |
||
| 5379 | if (sa < hither && sa >= 0.0) { |
||
| 5380 | BrVector3Scale(&tv2, &face_list[0].normal, hither - sa); |
||
| 5381 | BrVector3Accumulate(cam_pos, &tv2); |
||
| 5382 | } |
||
| 5383 | if (k > 1) { |
||
| 5384 | sb = BrVector3Dot(&face_list[0].normal, &face_list[1].normal); |
||
| 5385 | if (sb > 0.95f && k > 2) { |
||
| 5386 | BrVector3Copy(&face_list[1].normal, &face_list[2].normal); |
||
| 5387 | BrVector3Copy(&face_list[1].v[0], &face_list[2].v[0]); |
||
| 5388 | sb = BrVector3Dot(&face_list[0].normal, &face_list[2].normal); |
||
| 5389 | k = 2; |
||
| 5390 | } |
||
| 5391 | if (sb <= 0.95f) { |
||
| 5392 | BrVector3Sub(&tv2, cam_pos, &face_list[1].v[0]); |
||
| 5393 | sc = BrVector3Dot(&face_list[1].normal, &tv2); |
||
| 5394 | if (sc < hither && sc >= 0.0) { |
||
| 5395 | sc = BrVector3Dot(&face_list[0].normal, &face_list[1].normal); |
||
| 5396 | BrVector3Scale(&b, &face_list[0].normal, sc); |
||
| 5397 | BrVector3Sub(&face_list[1].normal, &face_list[1].normal, &b); |
||
| 5398 | BrVector3Scale(&tv2, &face_list[1].normal, hither - ts2); |
||
| 5399 | BrVector3Accumulate(cam_pos, &tv2); |
||
| 5400 | } |
||
| 5401 | } |
||
| 5402 | } |
||
| 5403 | } |
||
| 5404 | i += k; |
||
| 5405 | } |
||
| 5406 | return i; |
||
| 5407 | } |
||
| 5408 | |||
| 5409 | // IDA: int __usercall BoundsTest@<EAX>(br_bounds *bnds@<EAX>, br_vector3 *p@<EDX>) |
||
| 5410 | int BoundsTest(br_bounds* bnds, br_vector3* p) { |
||
| 20 | pmbaty | 5411 | //int j; // Pierre-Marie Baty -- unused variable |
| 1 | pmbaty | 5412 | LOG_TRACE("(%p, %p)", bnds, p); |
| 20 | pmbaty | 5413 | NOT_IMPLEMENTED(); |
| 1 | pmbaty | 5414 | } |
| 5415 | |||
| 5416 | // IDA: int __usercall CollideCameraWithOtherCars@<EAX>(br_vector3 *car_pos@<EAX>, br_vector3 *cam_pos@<EDX>) |
||
| 5417 | int CollideCameraWithOtherCars(br_vector3* car_pos, br_vector3* cam_pos) { |
||
| 20 | pmbaty | 5418 | //int i; // Pierre-Marie Baty -- unused variable |
| 5419 | //int plane; // Pierre-Marie Baty -- unused variable |
||
| 5420 | //br_scalar ts; // Pierre-Marie Baty -- unused variable |
||
| 5421 | //tCar_spec* c; // Pierre-Marie Baty -- unused variable |
||
| 5422 | //br_vector3 tv; // Pierre-Marie Baty -- unused variable |
||
| 5423 | //br_vector3 pos_car_space; // Pierre-Marie Baty -- unused variable |
||
| 5424 | //br_vector3 dir; // Pierre-Marie Baty -- unused variable |
||
| 5425 | //br_vector3 p; // Pierre-Marie Baty -- unused variable |
||
| 5426 | //br_vector3 n; // Pierre-Marie Baty -- unused variable |
||
| 5427 | //br_bounds bnds; // Pierre-Marie Baty -- unused variable |
||
| 1 | pmbaty | 5428 | LOG_TRACE("(%p, %p)", car_pos, cam_pos); |
| 5429 | |||
| 20 | pmbaty | 5430 | STUB_ONCE(); |
| 1 | pmbaty | 5431 | return 0; |
| 5432 | } |
||
| 5433 | |||
| 5434 | // IDA: void __cdecl InitialiseExternalCamera() |
||
| 5435 | void InitialiseExternalCamera(void) { |
||
| 5436 | br_scalar ts; |
||
| 5437 | tCar_spec* c; |
||
| 5438 | //br_vector3 r; // Pierre-Marie Baty -- unused variable |
||
| 5439 | br_angle yaw; |
||
| 5440 | LOG_TRACE("()"); |
||
| 5441 | |||
| 5442 | c = gCar_to_view; |
||
| 5443 | if (!gProgram_state.racing) { |
||
| 5444 | c = &gProgram_state.current_car; |
||
| 5445 | } |
||
| 5446 | gCamera_height = c->pos.v[1]; |
||
| 5447 | BrVector3Set(&gView_direction, c->direction.v[0], 0.0f, c->direction.v[2]); |
||
| 5448 | BrVector3Normalise(&gView_direction, &gView_direction); |
||
| 5449 | ts = -BrVector3Dot(&gView_direction, (br_vector3*)c->car_master_actor->t.t.mat.m[2]); |
||
| 5450 | gCamera_sign = ts < 0; |
||
| 5451 | gCamera_mode = 0; |
||
| 5452 | if (gCamera_sign) { |
||
| 5453 | yaw = -gCamera_yaw; |
||
| 5454 | } else { |
||
| 5455 | yaw = gCamera_yaw; |
||
| 5456 | } |
||
| 5457 | DrVector3RotateY(&gView_direction, yaw); |
||
| 5458 | gMin_camera_car_distance = 0.6f; |
||
| 5459 | gCamera_frozen = 0; |
||
| 5460 | gCamera_mode = -2; |
||
| 5461 | if (gCountdown && (gNet_mode == eNet_mode_none || gCurrent_net_game->options.grid_start) && gCountdown > 4) { |
||
| 5462 | gCamera_height = gCamera_height + 10.0f; |
||
| 5463 | } |
||
| 5464 | } |
||
| 5465 | |||
| 5466 | // IDA: void __cdecl FreezeCamera() |
||
| 5467 | void FreezeCamera(void) { |
||
| 5468 | LOG_TRACE("()"); |
||
| 5469 | |||
| 5470 | gCamera_frozen = 1; |
||
| 5471 | } |
||
| 5472 | |||
| 5473 | // IDA: void __usercall FlyCar(tCar_spec *c@<EAX>, br_scalar dt) |
||
| 5474 | void FlyCar(tCar_spec* c, br_scalar dt) { |
||
| 5475 | int accflag; |
||
| 5476 | int turnflag; |
||
| 5477 | br_vector3 step; |
||
| 5478 | br_matrix34* mat; |
||
| 5479 | br_angle theta; |
||
| 5480 | static br_scalar vel = 0.f; |
||
| 5481 | tFace_ref faces[20]; |
||
| 5482 | tBounds bnds; |
||
| 5483 | int i; // Added by DethRace |
||
| 5484 | br_scalar tmp_scalar1; // Added by DethRace |
||
| 5485 | br_scalar tmp_scalar2; // Added by DethRace |
||
| 5486 | br_vector3 tmp1; // Added by DethRace |
||
| 5487 | br_vector3 tmp2; // Added by DethRace |
||
| 5488 | br_vector3 tmp3; // Added by DethRace |
||
| 5489 | LOG_TRACE("(%p, %f)", c, dt); |
||
| 5490 | |||
| 5491 | accflag = 0; |
||
| 5492 | turnflag = 0; |
||
| 5493 | mat = &c->car_master_actor->t.t.mat; |
||
| 5494 | bnds.mat = mat; |
||
| 5495 | BrVector3InvScale(&bnds.original_bounds.min, &c->bounds[1].min, WORLD_SCALE); |
||
| 5496 | BrVector3InvScale(&bnds.original_bounds.max, &c->bounds[1].max, WORLD_SCALE); |
||
| 5497 | BrVector3InvScale((br_vector3*)bnds.mat->m[3], (br_vector3*)bnds.mat->m[3], WORLD_SCALE); |
||
| 5498 | FindFacesInBox(&bnds, faces, COUNT_OF(faces)); |
||
| 5499 | BrVector3Scale((br_vector3*)bnds.mat->m[3], (br_vector3*)bnds.mat->m[3], WORLD_SCALE); |
||
| 5500 | if (c->keys.acc || c->joystick.acc > 0) { |
||
| 5501 | vel += 10.f * dt; |
||
| 5502 | accflag = 1; |
||
| 5503 | } |
||
| 5504 | if (c->keys.dec || c->joystick.dec > 0) { |
||
| 5505 | vel -= 10.f * dt; |
||
| 5506 | accflag = 1; |
||
| 5507 | } |
||
| 5508 | if (!accflag) { |
||
| 5509 | if (vel >= 20.f * dt || vel <= -20.f * dt) { |
||
| 5510 | vel -= 20.f * vel / fabsf(vel) * dt; |
||
| 5511 | } else { |
||
| 5512 | vel = 0.f; |
||
| 5513 | } |
||
| 5514 | } |
||
| 5515 | BrVector3Scale(&step, &c->v, dt); |
||
| 5516 | BrVector3Accumulate((br_vector3*)mat->m[3], &step); |
||
| 5517 | BrVector3Scale(&step, (br_vector3*)mat->m[1], dt); |
||
| 5518 | if (c->keys.left || c->joystick.left > 0) { |
||
| 5519 | BrVector3Accumulate(&c->omega, &step); |
||
| 5520 | turnflag = 1; |
||
| 5521 | } |
||
| 5522 | if (c->keys.right || c->joystick.right > 0) { |
||
| 5523 | BrVector3Sub(&c->omega, &c->omega, &step); |
||
| 5524 | turnflag = 1; |
||
| 5525 | } |
||
| 5526 | if (!turnflag) { |
||
| 5527 | BrVector3SetFloat(&c->omega, 0.f, 0.f, 0.f); |
||
| 5528 | } |
||
| 5529 | theta = BrRadianToAngle(c->omega.v[1] * dt); |
||
| 5530 | DrVector3RotateY(&c->v, theta); |
||
| 5531 | BrMatrix34PreRotateY(mat, theta); |
||
| 5532 | if (c->keys.up) { |
||
| 5533 | BrMatrix34PreRotateX(mat, BrDegreeToAngle(5)); |
||
| 5534 | } |
||
| 5535 | if (c->keys.down) { |
||
| 5536 | BrMatrix34PreRotateX(mat, BrDegreeToAngle(360 - 5)); |
||
| 5537 | } |
||
| 5538 | BrVector3Scale(&c->v, (br_vector3*)mat->m[2], -vel); |
||
| 5539 | BrVector3Scale(&step, &c->v, dt); |
||
| 5540 | BrVector3Accumulate((br_vector3*)&mat->m[3], &step); |
||
| 5541 | if (c->keys.holdw) { |
||
| 5542 | BrVector3Copy(&step, (br_vector3*)mat->m[3]); |
||
| 5543 | BrMatrix34RotateY(mat, BrDegreeToAngle(90) - BrRadianToAngle(atan2f(mat->m[2][2], mat->m[2][0]))); |
||
| 5544 | BrVector3Copy((br_vector3*)mat->m[3], &step); |
||
| 5545 | BrVector3SetFloat(&step, 0.f, -100.f, 0.f); |
||
| 5546 | BrVector3Copy(&tmp1, (br_vector3*)&mat->m[3]); |
||
| 5547 | findfloor(&tmp1, &step, &tmp2, &tmp_scalar1); |
||
| 5548 | tmp1.v[1] += 100.f; |
||
| 5549 | findfloor(&tmp1, &step, &tmp3, &tmp_scalar2); |
||
| 5550 | if (tmp_scalar2 <= 1.f) { |
||
| 5551 | BrVector3SetFloat(&step, 0.f, -5.01f, 0.f); |
||
| 5552 | tmp1.v[1] -= 20 * 5.f; |
||
| 5553 | for (i = 0; i < 20; i++) { |
||
| 5554 | tmp1.v[1] += 5.f; |
||
| 5555 | findfloor(&tmp1, &step, &tmp3, &tmp_scalar2); |
||
| 5556 | if (tmp_scalar2 <= 1.f) { |
||
| 5557 | break; |
||
| 5558 | } |
||
| 5559 | } |
||
| 5560 | tmp_scalar2 = -tmp_scalar2 / 20.f + (i + 1) * 0.05f; |
||
| 5561 | } |
||
| 5562 | if (tmp_scalar2 < tmp_scalar1) { |
||
| 5563 | tmp_scalar1 = -tmp_scalar2; |
||
| 5564 | BrVector3Copy(&tmp2, &tmp3); |
||
| 5565 | } |
||
| 5566 | if (tmp_scalar1 <= 1.f) { |
||
| 5567 | mat->m[3][1] -= tmp_scalar1 * 100.f; |
||
| 5568 | BrMatrix34PreRotateX(mat, BrRadianToAngle(asinf(BrVector3Dot((br_vector3*)mat->m[2], &tmp2)))); |
||
| 5569 | BrMatrix34PreRotateZ(mat, -BrRadianToAngle(asinf(BrVector3Dot((br_vector3*)mat->m[0], &tmp2)))); |
||
| 5570 | } |
||
| 5571 | } |
||
| 5572 | BrVector3Negate((br_vector3*)&c->direction, (br_vector3*)mat->m[2]); |
||
| 5573 | BrMatrix34Copy(&c->oldmat, mat); |
||
| 5574 | BrMatrix34ApplyP(&c->pos, &c->cmpos, mat); |
||
| 5575 | BrVector3InvScale(&c->pos, &c->pos, WORLD_SCALE); |
||
| 5576 | BrVector3InvScale((br_vector3*)bnds.mat->m[3], (br_vector3*)bnds.mat->m[3], WORLD_SCALE); |
||
| 5577 | GetNewBoundingBox(&c->bounds_world_space, c->bounds, bnds.mat); |
||
| 5578 | BrVector3Scale((br_vector3*)bnds.mat->m[3], (br_vector3*)bnds.mat->m[3], WORLD_SCALE); |
||
| 5579 | } |
||
| 5580 | |||
| 5581 | // IDA: void __usercall DrVector3RotateY(br_vector3 *v@<EAX>, br_angle t@<EDX>) |
||
| 5582 | void DrVector3RotateY(br_vector3* v, br_angle t) { |
||
| 5583 | br_scalar c; |
||
| 5584 | br_scalar s; |
||
| 5585 | br_scalar ts; |
||
| 5586 | LOG_TRACE("(%p, %d)", v, t); |
||
| 5587 | |||
| 5588 | c = cos(BrAngleToRadian(t)); |
||
| 5589 | s = sin(BrAngleToRadian(t)); |
||
| 5590 | ts = v->v[0] * c + v->v[2] * s; |
||
| 5591 | v->v[2] = v->v[2] * c - v->v[0] * s; |
||
| 5592 | v->v[0] = ts; |
||
| 5593 | } |
||
| 5594 | |||
| 5595 | // IDA: void __cdecl CrashCarsTogether(br_scalar dt) |
||
| 5596 | void CrashCarsTogether(br_scalar dt) { |
||
| 5597 | int pass; |
||
| 5598 | int k; |
||
| 5599 | int i; |
||
| 5600 | tCollison_data collide_list[32]; |
||
| 5601 | LOG_TRACE("(%f)", dt); |
||
| 5602 | |||
| 5603 | for (i = 0; i < gNum_cars_and_non_cars; i++) { |
||
| 5604 | collide_list[i].car = NULL; |
||
| 5605 | collide_list[i].ref = gNum_cars_and_non_cars - 1; |
||
| 5606 | gActive_car_list[i]->infinite_mass = 0; |
||
| 5607 | } |
||
| 5608 | for (pass = 0; pass < 5; pass++) { |
||
| 5609 | k = CrashCarsTogetherSinglePass(dt, pass, collide_list); |
||
| 5610 | if (k <= 0) { |
||
| 5611 | break; |
||
| 5612 | } |
||
| 5613 | } |
||
| 5614 | if (k > 0) { |
||
| 5615 | for (i = 0; i < gNum_cars_and_non_cars; i++) { |
||
| 5616 | BringCarToAGrindingHalt((tCollision_info*)gActive_car_list[i]); |
||
| 5617 | } |
||
| 5618 | } |
||
| 5619 | } |
||
| 5620 | |||
| 5621 | // IDA: int __cdecl CrashCarsTogetherSinglePass(br_scalar dt, int pPass, tCollison_data *collide_list) |
||
| 5622 | int CrashCarsTogetherSinglePass(br_scalar dt, int pPass, tCollison_data* collide_list) { |
||
| 5623 | int i; |
||
| 5624 | int j; |
||
| 5625 | //int l; // Pierre-Marie Baty -- unused variable |
||
| 5626 | //int m; // Pierre-Marie Baty -- unused variable |
||
| 5627 | //int n; // Pierre-Marie Baty -- unused variable |
||
| 5628 | int collided; |
||
| 5629 | int k; |
||
| 5630 | //int ref1; // Pierre-Marie Baty -- unused variable |
||
| 5631 | //int ref2; // Pierre-Marie Baty -- unused variable |
||
| 5632 | int c1im; |
||
| 5633 | int c2im; |
||
| 5634 | tCollision_info* car_1; |
||
| 5635 | tCollision_info* car_2; |
||
| 5636 | tCollision_info* car_3; |
||
| 5637 | tCollision_info* car_in_middle; |
||
| 5638 | tCollision_info* car_on_wall; |
||
| 5639 | LOG_TRACE("(%f, %d, %p)", dt, pPass, collide_list); |
||
| 5640 | |||
| 5641 | collided = 0; |
||
| 5642 | for (i = 0; i < gNum_cars_and_non_cars - 1; i++) { |
||
| 5643 | car_1 = (tCollision_info*)gActive_car_list[i]; |
||
| 5644 | for (j = i + 1; j < gNum_cars_and_non_cars; j++) { |
||
| 5645 | car_2 = (tCollision_info*)gActive_car_list[j]; |
||
| 5646 | if (collide_list[i].ref > 0 || collide_list[j].ref > 0) { |
||
| 5647 | collide_list[i].ref--; |
||
| 5648 | collide_list[j].ref--; |
||
| 5649 | if (SimpleCarCarCollisionTest(car_1, car_2)) { |
||
| 5650 | if (car_1->infinite_mass == -1 && car_2->infinite_mass > 0) { |
||
| 5651 | if (CollideTwoCars(car_1, car_2, -1)) { |
||
| 5652 | if (car_2->infinite_mass >= 256 || pPass >= 4) { |
||
| 5653 | BringCarToAGrindingHalt(car_2); |
||
| 5654 | } else { |
||
| 5655 | car_2->infinite_mass = 0; |
||
| 5656 | k = CollideTwoCarsWithWalls(car_1, car_2, dt); |
||
| 5657 | car_2->infinite_mass = 256; |
||
| 5658 | if (k < 0) { |
||
| 5659 | BringCarToAGrindingHalt(car_2); |
||
| 5660 | } |
||
| 5661 | } |
||
| 5662 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
| 5663 | collide_list[j].car = car_1; |
||
| 5664 | collided++; |
||
| 5665 | } |
||
| 5666 | } else if (car_2->infinite_mass == -1 && car_1->infinite_mass > 0) { |
||
| 5667 | if (CollideTwoCars(car_1, car_2, -1)) { |
||
| 5668 | if (car_1->infinite_mass >= 256 || pPass >= 4) { |
||
| 5669 | BringCarToAGrindingHalt(car_1); |
||
| 5670 | } else { |
||
| 5671 | car_1->infinite_mass = 0; |
||
| 5672 | k = CollideTwoCarsWithWalls(car_1, car_2, dt); |
||
| 5673 | car_1->infinite_mass = 256; |
||
| 5674 | if (k < 0) { |
||
| 5675 | BringCarToAGrindingHalt(car_1); |
||
| 5676 | } |
||
| 5677 | } |
||
| 5678 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
| 5679 | collide_list[i].car = car_2; |
||
| 5680 | collided++; |
||
| 5681 | } |
||
| 5682 | } else if (collide_list[i].car || collide_list[j].car) { |
||
| 5683 | if ((collide_list[j].car == NULL) == (collide_list[i].car == NULL)) { |
||
| 5684 | if (collide_list[j].car != collide_list[i].car || (car_1->infinite_mass && car_2->infinite_mass)) { |
||
| 5685 | if (collide_list[i].car && collide_list[j].car) { |
||
| 5686 | if (car_1->infinite_mass && car_2->infinite_mass) { |
||
| 5687 | if ((car_1->infinite_mass != -1 || car_2->infinite_mass != -1) && CollideTwoCars(car_1, car_2, -1)) { |
||
| 5688 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
| 5689 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
| 5690 | if (car_1->infinite_mass && car_2->infinite_mass) { |
||
| 5691 | BringCarToAGrindingHalt(car_1); |
||
| 5692 | BringCarToAGrindingHalt(car_2); |
||
| 5693 | } else { |
||
| 5694 | k = CollideTwoCarsWithWalls(car_1, car_2, dt); |
||
| 5695 | if (k >= 0) { |
||
| 5696 | if (k) { |
||
| 5697 | if (car_1->infinite_mass >= 0) { |
||
| 5698 | car_1->infinite_mass++; |
||
| 5699 | } |
||
| 5700 | if (car_2->infinite_mass >= 0) { |
||
| 5701 | car_2->infinite_mass++; |
||
| 5702 | } |
||
| 5703 | collided++; |
||
| 5704 | } |
||
| 5705 | } else { |
||
| 5706 | BringCarToAGrindingHalt(car_1); |
||
| 5707 | BringCarToAGrindingHalt(car_2); |
||
| 5708 | collided++; |
||
| 5709 | } |
||
| 5710 | } |
||
| 5711 | collided++; |
||
| 5712 | } |
||
| 5713 | } else { |
||
| 5714 | c1im = car_1->infinite_mass; |
||
| 5715 | c2im = car_2->infinite_mass; |
||
| 5716 | k = CollideTwoCarsWithWalls(car_1, car_2, dt); |
||
| 5717 | if (k > -1) { |
||
| 5718 | if (k) { |
||
| 5719 | if (!c2im) { |
||
| 5720 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
| 5721 | } |
||
| 5722 | if (!c1im) { |
||
| 5723 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
| 5724 | } |
||
| 5725 | collided++; |
||
| 5726 | if (car_1->infinite_mass >= 0) { |
||
| 5727 | car_1->infinite_mass++; |
||
| 5728 | } |
||
| 5729 | if (car_2->infinite_mass >= 0) { |
||
| 5730 | car_2->infinite_mass++; |
||
| 5731 | } |
||
| 5732 | } |
||
| 5733 | } else { |
||
| 5734 | BringCarToAGrindingHalt(car_1); |
||
| 5735 | BringCarToAGrindingHalt(car_2); |
||
| 5736 | if (c1im >= 0) { |
||
| 5737 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
| 5738 | } |
||
| 5739 | if (c2im >= 0) { |
||
| 5740 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
| 5741 | } |
||
| 5742 | collided++; |
||
| 5743 | } |
||
| 5744 | } |
||
| 5745 | } |
||
| 5746 | } else { |
||
| 5747 | k = CollideTwoCarsWithWalls(car_1, car_2, dt); |
||
| 5748 | if (k) { |
||
| 5749 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
| 5750 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
| 5751 | if (k == -1) { |
||
| 5752 | BringCarToAGrindingHalt(car_1); |
||
| 5753 | BringCarToAGrindingHalt(car_2); |
||
| 5754 | } |
||
| 5755 | collided++; |
||
| 5756 | if (car_1->infinite_mass >= 0) { |
||
| 5757 | car_1->infinite_mass++; |
||
| 5758 | } |
||
| 5759 | if (car_2->infinite_mass >= 0) { |
||
| 5760 | car_2->infinite_mass++; |
||
| 5761 | } |
||
| 5762 | } |
||
| 5763 | } |
||
| 5764 | } else { |
||
| 5765 | c1im = car_1->infinite_mass; |
||
| 5766 | c2im = car_2->infinite_mass; |
||
| 5767 | k = CollideTwoCarsWithWalls(car_1, car_2, dt); |
||
| 5768 | if (k == -1) { |
||
| 5769 | if (collide_list[i].car) { |
||
| 5770 | car_3 = collide_list[i].car; |
||
| 5771 | } else { |
||
| 5772 | car_3 = collide_list[j].car; |
||
| 5773 | } |
||
| 5774 | if (collide_list[i].car) { |
||
| 5775 | car_in_middle = car_1; |
||
| 5776 | } else { |
||
| 5777 | car_in_middle = car_2; |
||
| 5778 | } |
||
| 5779 | if (car_3->infinite_mass > 1 || car_3->infinite_mass == -1 || (tU8)(car_in_middle->infinite_mass) > 1 || car_in_middle->infinite_mass == -1) { |
||
| 5780 | BringCarToAGrindingHalt(car_1); |
||
| 5781 | BringCarToAGrindingHalt(car_2); |
||
| 5782 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
| 5783 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
| 5784 | } else { |
||
| 5785 | if (collide_list[i].car) { |
||
| 5786 | car_on_wall = car_2; |
||
| 5787 | } else { |
||
| 5788 | car_on_wall = car_1; |
||
| 5789 | } |
||
| 5790 | car_in_middle->infinite_mass = 0; |
||
| 5791 | car_3->infinite_mass = 0; |
||
| 5792 | k = CollideTwoCarsWithWalls(car_on_wall, car_in_middle, dt); |
||
| 5793 | car_in_middle->infinite_mass = 2; |
||
| 5794 | car_on_wall->infinite_mass++; |
||
| 5795 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
| 5796 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
| 5797 | if (k < 0) { |
||
| 5798 | BringCarToAGrindingHalt(car_1); |
||
| 5799 | BringCarToAGrindingHalt(car_2); |
||
| 5800 | } |
||
| 5801 | } |
||
| 5802 | collide_list[i].car = car_2; |
||
| 5803 | collide_list[j].car = car_1; |
||
| 5804 | collided++; |
||
| 5805 | } else if (k) { |
||
| 5806 | collide_list[i].car = car_2; |
||
| 5807 | collide_list[j].car = car_1; |
||
| 5808 | if (!c2im) { |
||
| 5809 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
| 5810 | } |
||
| 5811 | if (!c1im) { |
||
| 5812 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
| 5813 | } |
||
| 5814 | collided++; |
||
| 5815 | if (car_1->infinite_mass >= 0) { |
||
| 5816 | car_1->infinite_mass++; |
||
| 5817 | } |
||
| 5818 | if (car_2->infinite_mass >= 0) { |
||
| 5819 | car_2->infinite_mass++; |
||
| 5820 | } |
||
| 5821 | } |
||
| 5822 | } |
||
| 5823 | } else { |
||
| 5824 | k = CollideTwoCarsWithWalls(car_1, car_2, dt); |
||
| 5825 | if (k) { |
||
| 5826 | collide_list[i].car = car_2; |
||
| 5827 | collide_list[j].car = car_1; |
||
| 5828 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
| 5829 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
| 5830 | if (k == -1) { |
||
| 5831 | BringCarToAGrindingHalt(car_1); |
||
| 5832 | BringCarToAGrindingHalt(car_2); |
||
| 5833 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
| 5834 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
| 5835 | } |
||
| 5836 | collided++; |
||
| 5837 | } |
||
| 5838 | } |
||
| 5839 | CrashEarnings((tCar_spec*)car_1, (tCar_spec*)car_2); |
||
| 5840 | } |
||
| 5841 | } |
||
| 5842 | } |
||
| 5843 | } |
||
| 5844 | return collided; |
||
| 5845 | } |
||
| 5846 | |||
| 5847 | // IDA: void __usercall BringCarToAGrindingHalt(tCollision_info *car@<EAX>) |
||
| 5848 | void BringCarToAGrindingHalt(tCollision_info* car) { |
||
| 5849 | LOG_TRACE("(%p)", car); |
||
| 5850 | |||
| 5851 | BrVector3SetFloat(&car->v, 0.0f, 0.0f, 0.0f); |
||
| 5852 | BrVector3SetFloat(&car->omega, 0.0f, 0.0f, 0.0f); |
||
| 5853 | BrVector3SetFloat(&car->oldomega, 0.0f, 0.0f, 0.0f); |
||
| 5854 | BrMatrix34Copy(&car->car_master_actor->t.t.mat, &car->oldmat); |
||
| 5855 | car->infinite_mass = -1; |
||
| 5856 | } |
||
| 5857 | |||
| 5858 | // IDA: int __usercall BoundsOverlapTest@<EAX>(br_bounds *b1@<EAX>, br_bounds *b2@<EDX>) |
||
| 5859 | int BoundsOverlapTest_car(br_bounds* b1, br_bounds* b2) { |
||
| 5860 | LOG_TRACE("(%p, %p)", b1, b2); |
||
| 5861 | |||
| 5862 | return b2->max.v[0] >= b1->min.v[0] |
||
| 5863 | && b1->max.v[0] >= b2->min.v[0] |
||
| 5864 | && b2->max.v[1] >= b1->min.v[1] |
||
| 5865 | && b1->max.v[1] >= b2->min.v[1] |
||
| 5866 | && b2->max.v[2] >= b1->min.v[2] |
||
| 5867 | && b1->max.v[2] >= b2->min.v[2]; |
||
| 5868 | } |
||
| 5869 | |||
| 5870 | // IDA: int __usercall SimpleCarCarCollisionTest@<EAX>(tCollision_info *car1@<EAX>, tCollision_info *car2@<EDX>) |
||
| 5871 | int SimpleCarCarCollisionTest(tCollision_info* car1, tCollision_info* car2) { |
||
| 5872 | LOG_TRACE("(%p, %p)", car1, car2); |
||
| 5873 | |||
| 5874 | if (car1->bounds_ws_type == eBounds_ws && car2->bounds_ws_type == eBounds_ws) { |
||
| 5875 | return BoundsOverlapTest_car(&car1->bounds_world_space, &car2->bounds_world_space); |
||
| 5876 | } else { |
||
| 5877 | return 1; |
||
| 5878 | } |
||
| 5879 | } |
||
| 5880 | |||
| 5881 | // IDA: int __usercall CollideTwoCarsWithWalls@<EAX>(tCollision_info *car1@<EAX>, tCollision_info *car2@<EDX>, br_scalar dt) |
||
| 5882 | int CollideTwoCarsWithWalls(tCollision_info* car1, tCollision_info* car2, br_scalar dt) { |
||
| 5883 | br_vector3 mom1; |
||
| 5884 | br_vector3 mom2; |
||
| 5885 | int l; |
||
| 5886 | int m; |
||
| 5887 | int n; |
||
| 5888 | int p; |
||
| 5889 | int im1; |
||
| 5890 | int im2; |
||
| 5891 | LOG_TRACE("(%p, %p, %f)", car1, car2, dt); |
||
| 5892 | |||
| 5893 | l = 0; |
||
| 5894 | m = 0; |
||
| 5895 | p = 0; |
||
| 5896 | im1 = car1->infinite_mass; |
||
| 5897 | im2 = car2->infinite_mass; |
||
| 5898 | do { |
||
| 5899 | n = CollideTwoCarsRepeatedly(car1, car2, dt); |
||
| 5900 | if (n <= 0) { |
||
| 5901 | if (n == -1) { |
||
| 5902 | return -1; |
||
| 5903 | } |
||
| 5904 | l = 0; |
||
| 5905 | m = 0; |
||
| 5906 | } else { |
||
| 5907 | ++p; |
||
| 5908 | if (n >= 5) { |
||
| 5909 | if (p >= 10 || car1->infinite_mass || car2->infinite_mass) { |
||
| 5910 | return -1; |
||
| 5911 | } |
||
| 5912 | BrVector3Set(&car1->omega, 0.0f, 0.0f, 0.0f); |
||
| 5913 | BrVector3Set(&car2->omega, 0.0f, 0.0f, 0.0f); |
||
| 5914 | BrVector3Scale(&mom1, &car1->v, car1->M); |
||
| 5915 | BrVector3Scale(&mom2, &car2->v, car2->M); |
||
| 5916 | BrVector3Accumulate(&mom1, &mom2); |
||
| 5917 | BrVector3InvScale(&car1->v, &mom1, car2->M + car1->M); |
||
| 5918 | car2->v = car1->v; |
||
| 5919 | RotateCar(car1, dt); |
||
| 5920 | TranslateCar(car1, dt); |
||
| 5921 | RotateCar(car2, dt); |
||
| 5922 | TranslateCar(car2, dt); |
||
| 5923 | if (CollideTwoCars(car1, car2, -1)) { |
||
| 5924 | return -1; |
||
| 5925 | } |
||
| 5926 | if (im1 || im2) { |
||
| 5927 | return -1; |
||
| 5928 | } |
||
| 5929 | } |
||
| 5930 | if (!im1) { |
||
| 5931 | l = CollideCarWithWall(car1, dt); |
||
| 5932 | } |
||
| 5933 | if (!im2) { |
||
| 5934 | m = CollideCarWithWall(car2, dt); |
||
| 5935 | } |
||
| 5936 | if (p < 3) { |
||
| 5937 | car1->infinite_mass = im1; |
||
| 5938 | car2->infinite_mass = im2; |
||
| 5939 | } |
||
| 5940 | if (p > 5) { |
||
| 5941 | if (l) { |
||
| 5942 | car1->infinite_mass |= 0x100u; |
||
| 5943 | } |
||
| 5944 | if (m) { |
||
| 5945 | car2->infinite_mass |= 0x100u; |
||
| 5946 | } |
||
| 5947 | } |
||
| 5948 | if (car1->infinite_mass && car2->infinite_mass) { |
||
| 5949 | return -1; |
||
| 5950 | } |
||
| 5951 | } |
||
| 5952 | } while ((l || m) && p < 10); |
||
| 5953 | if (p < 10) { |
||
| 5954 | return p; |
||
| 5955 | } else { |
||
| 5956 | return -1; |
||
| 5957 | } |
||
| 5958 | } |
||
| 5959 | |||
| 5960 | // IDA: int __usercall CollideTwoCarsRepeatedly@<EAX>(tCollision_info *car1@<EAX>, tCollision_info *car2@<EDX>, br_scalar dt) |
||
| 5961 | int CollideTwoCarsRepeatedly(tCollision_info* car1, tCollision_info* car2, br_scalar dt) { |
||
| 5962 | int l; |
||
| 5963 | int collide; |
||
| 5964 | //br_scalar ts; // Pierre-Marie Baty -- unused variable |
||
| 5965 | LOG_TRACE("(%p, %p, %f)", car1, car2, dt); |
||
| 5966 | |||
| 5967 | l = 0; |
||
| 5968 | ModifyCarsMass(car1, car2); |
||
| 5969 | while (1) { |
||
| 5970 | collide = CollideTwoCars(car1, car2, l); |
||
| 5971 | if (!collide) { |
||
| 5972 | break; |
||
| 5973 | } |
||
| 5974 | if (collide == -1) { |
||
| 5975 | ResetCarsMass(car1, car2); |
||
| 5976 | return -1; |
||
| 5977 | } |
||
| 5978 | if (++l >= 5) { |
||
| 5979 | break; |
||
| 5980 | } |
||
| 5981 | RotateCar(car1, dt); |
||
| 5982 | TranslateCar(car1, dt); |
||
| 5983 | RotateCar(car2, dt); |
||
| 5984 | TranslateCar(car2, dt); |
||
| 5985 | } |
||
| 5986 | if (l > 0) { |
||
| 5987 | car1->frame_collision_flag += 256; |
||
| 5988 | car2->frame_collision_flag += 256; |
||
| 5989 | if (gNet_mode == eNet_mode_host) { |
||
| 5990 | car1->last_car_car_collision = gLast_mechanics_time + 40; |
||
| 5991 | car2->last_car_car_collision = gLast_mechanics_time + 40; |
||
| 5992 | } |
||
| 5993 | } |
||
| 5994 | ResetCarsMass(car1, car2); |
||
| 5995 | return l; |
||
| 5996 | } |
||
| 5997 | |||
| 5998 | // IDA: int __usercall CollideTwoCars@<EAX>(tCollision_info *car1@<EAX>, tCollision_info *car2@<EDX>, int pPass@<EBX>) |
||
| 5999 | int CollideTwoCars(tCollision_info* car1, tCollision_info* car2, int pPass) { |
||
| 6000 | int k; |
||
| 6001 | int old_k; |
||
| 6002 | int i; |
||
| 6003 | int j; |
||
| 6004 | //br_scalar dist; // Pierre-Marie Baty -- unused variable |
||
| 6005 | //br_scalar ts; // Pierre-Marie Baty -- unused variable |
||
| 6006 | br_bounds new_car1_bnds; |
||
| 6007 | br_bounds new_car2_bnds; |
||
| 6008 | br_bounds bnds; |
||
| 6009 | br_matrix34* mat1; |
||
| 6010 | br_matrix34* mat2; |
||
| 6011 | br_matrix34* oldmat1; |
||
| 6012 | br_matrix34* oldmat2; |
||
| 6013 | br_matrix34 inv_mat1; |
||
| 6014 | br_matrix34 inv_mat2; |
||
| 6015 | br_matrix34 inv_oldmat1; |
||
| 6016 | br_matrix34 inv_oldmat2; |
||
| 6017 | br_matrix34 car2_to_car1; |
||
| 6018 | br_matrix34 car1_to_car2; |
||
| 6019 | br_matrix34 old_car2_to_car1; |
||
| 6020 | br_matrix34 old_car1_to_car2; |
||
| 6021 | br_matrix34 car1_to_old_car1; |
||
| 6022 | br_matrix34 car2_to_old_car2; |
||
| 6023 | br_vector3 r[16]; |
||
| 6024 | br_vector3 n[16]; |
||
| 6025 | //br_vector3 sep; // Pierre-Marie Baty -- unused variable |
||
| 6026 | br_vector3 tv; |
||
| 6027 | int add_point; |
||
| 6028 | static br_vector3 oldr1; |
||
| 6029 | static br_vector3 oldr2; |
||
| 6030 | static br_vector3 oldn1; |
||
| 6031 | static br_vector3 oldn2; |
||
| 6032 | static int is_old_point_available; |
||
| 6033 | LOG_TRACE("(%p, %p, %d)", car1, car2, pPass); |
||
| 6034 | |||
| 6035 | #ifdef DETHRACE_FIX_BUGS |
||
| 6036 | // this variable is used uninitialized |
||
| 6037 | add_point = 0; |
||
| 6038 | #endif |
||
| 6039 | |||
| 6040 | if (!gCar_car_collisions) { |
||
| 6041 | return 0; |
||
| 6042 | } |
||
| 6043 | if (pPass < 0 && !SimpleCarCarCollisionTest(car1, car2)) { |
||
| 6044 | return 0; |
||
| 6045 | } |
||
| 6046 | |||
| 6047 | mat1 = &car1->car_master_actor->t.t.mat; |
||
| 6048 | mat2 = &car2->car_master_actor->t.t.mat; |
||
| 6049 | oldmat1 = &car1->oldmat; |
||
| 6050 | oldmat2 = &car2->oldmat; |
||
| 6051 | BrMatrix34LPInverse(&inv_oldmat1, &car1->oldmat); |
||
| 6052 | BrMatrix34LPInverse(&inv_oldmat2, &car2->oldmat); |
||
| 6053 | BrMatrix34Mul(&car1_to_old_car1, mat1, &inv_oldmat1); |
||
| 6054 | BrMatrix34Mul(&car2_to_old_car2, mat2, &inv_oldmat2); |
||
| 6055 | BrMatrix34Mul(&old_car2_to_car1, oldmat2, &inv_oldmat1); |
||
| 6056 | GetNewBoundingBox(&new_car1_bnds, &car1->bounds[1], &car1_to_old_car1); |
||
| 6057 | GetNewBoundingBox(&new_car2_bnds, &car2->bounds[1], &car2_to_old_car2); |
||
| 6058 | |||
| 6059 | for (i = 0; i < 3; ++i) { |
||
| 6060 | new_car1_bnds.min.v[i] = MIN(car1->bounds[1].min.v[i], new_car1_bnds.min.v[i]); |
||
| 6061 | new_car1_bnds.max.v[i] = MAX(car1->bounds[1].max.v[i], new_car1_bnds.max.v[i]); |
||
| 6062 | |||
| 6063 | new_car2_bnds.min.v[i] = MIN(car2->bounds[1].min.v[i], new_car2_bnds.min.v[i]); |
||
| 6064 | new_car2_bnds.max.v[i] = MAX(car2->bounds[1].max.v[i], new_car2_bnds.max.v[i]); |
||
| 6065 | } |
||
| 6066 | GetNewBoundingBox(&bnds, &new_car2_bnds, &old_car2_to_car1); |
||
| 6067 | |||
| 6068 | if (new_car1_bnds.max.v[0] < bnds.min.v[0] |
||
| 6069 | || bnds.max.v[0] < new_car1_bnds.min.v[0] |
||
| 6070 | || new_car1_bnds.max.v[1] < bnds.min.v[1] |
||
| 6071 | || bnds.max.v[1] < new_car1_bnds.min.v[1] |
||
| 6072 | || new_car1_bnds.max.v[2] < bnds.min.v[2] |
||
| 6073 | || bnds.max.v[2] < new_car1_bnds.min.v[2]) { |
||
| 6074 | return 0; |
||
| 6075 | } |
||
| 6076 | BrMatrix34LPInverse(&inv_mat1, mat1); |
||
| 6077 | BrMatrix34LPInverse(&inv_mat2, mat2); |
||
| 6078 | BrMatrix34Mul(&car2_to_car1, mat2, &inv_mat1); |
||
| 6079 | BrMatrix34Mul(&car1_to_car2, mat1, &inv_mat2); |
||
| 6080 | BrMatrix34Mul(&old_car2_to_car1, oldmat2, &inv_oldmat1); |
||
| 6081 | BrMatrix34Mul(&old_car1_to_car2, oldmat1, &inv_oldmat2); |
||
| 6082 | BrMatrix34Mul(&car1_to_old_car1, mat1, &inv_oldmat1); |
||
| 6083 | BrMatrix34Mul(&car2_to_old_car2, mat2, &inv_oldmat2); |
||
| 6084 | do { |
||
| 6085 | k = 0; |
||
| 6086 | k += FacePointCarCarCollide(car1, car2, &car2_to_car1, &old_car2_to_car1, &car1_to_old_car1, r, n, 8, 0); |
||
| 6087 | k += FacePointCarCarCollide(car2, car1, &car1_to_car2, &old_car1_to_car2, &car2_to_old_car2, &r[2 * k], &n[2 * k], 8 - k, 1); |
||
| 6088 | old_k = k; |
||
| 6089 | |||
| 6090 | if (k < 3 || add_point) { |
||
| 6091 | k += GetEdgeEdgeCollisions(&car1->bounds[1], &car2->bounds[1], &car2_to_car1, &car1_to_car2, &old_car2_to_car1, &old_car1_to_car2, &car1_to_old_car1, &r[2 * k], &n[2 * k], 8 - k); |
||
| 6092 | } |
||
| 6093 | if (k == -1) { |
||
| 6094 | TestOldMats(car1, car2, 1); |
||
| 6095 | } |
||
| 6096 | if (!k) { |
||
| 6097 | return 0; |
||
| 6098 | } |
||
| 6099 | if (k > 4) { |
||
| 6100 | i = old_k; |
||
| 6101 | j = old_k; |
||
| 6102 | while (i < k) { |
||
| 6103 | if (BrVector3Dot(&n[2 * i + 1], &r[2 * i + 1]) <= 0.0f || i - j >= k - 4) { |
||
| 6104 | if (j != i) { |
||
| 6105 | r[2 * j] = r[2 * i]; |
||
| 6106 | } |
||
| 6107 | n[2 * j] = n[2 * i]; |
||
| 6108 | r[2 * j + 1] = r[2 * i + 1]; |
||
| 6109 | n[2 * j + 1] = n[2 * i + 1]; |
||
| 6110 | } else { |
||
| 6111 | j--; |
||
| 6112 | } |
||
| 6113 | i++; |
||
| 6114 | j++; |
||
| 6115 | } |
||
| 6116 | k = j; |
||
| 6117 | } |
||
| 6118 | for (i = 0; i < k; ++i) { |
||
| 6119 | BrVector3Sub(&r[2 * i], &r[2 * i], &car1->cmpos); |
||
| 6120 | BrVector3Sub(&r[2 * i + 1], &r[2 * i + 1], &car2->cmpos); |
||
| 6121 | } |
||
| 6122 | if (add_point == -1) { |
||
| 6123 | return k; |
||
| 6124 | } |
||
| 6125 | car1->doing_nothing_flag = 0; |
||
| 6126 | car2->doing_nothing_flag = 0; |
||
| 6127 | if (k < 3 && add_point) { |
||
| 6128 | for (i = 0; i < k; i++) { |
||
| 6129 | BrVector3Sub(&tv, &r[2 * i], &oldr1); |
||
| 6130 | if (BrVector3LengthSquared(&tv) < 0.01f) { |
||
| 6131 | add_point = 0; |
||
| 6132 | } |
||
| 6133 | } |
||
| 6134 | if (add_point) { |
||
| 6135 | r[2 * k] = oldr1; |
||
| 6136 | r[2 * k + 1] = oldr2; |
||
| 6137 | n[2 * k] = oldn1; |
||
| 6138 | n[2 * k + 1] = oldn2; |
||
| 6139 | k++; |
||
| 6140 | } |
||
| 6141 | } |
||
| 6142 | oldr1 = r[0]; |
||
| 6143 | oldr2 = r[1]; |
||
| 6144 | oldn1 = n[0]; |
||
| 6145 | oldn2 = n[1]; |
||
| 6146 | if (k < 3) { |
||
| 6147 | if (car1->collision_flag && !car1->infinite_mass) { |
||
| 6148 | |||
| 6149 | for (i = 0; i < k; i++) { |
||
| 6150 | if (BrVector3Dot(&n[2 * i], &car1->old_norm) < -0.9f) { |
||
| 6151 | car1->infinite_mass |= 0x100u; |
||
| 6152 | } |
||
| 6153 | } |
||
| 6154 | if (!car1->infinite_mass) { |
||
| 6155 | r[2 * k] = car1->old_point; |
||
| 6156 | n[2 * k] = car1->old_norm; |
||
| 6157 | BrVector3SetFloat(&n[2 * k + 1], 0.0f, 0.0f, 0.0f); |
||
| 6158 | BrVector3SetFloat(&r[2 * k + 1], 0.0f, 0.0f, 0.0f); |
||
| 6159 | k++; |
||
| 6160 | } |
||
| 6161 | } |
||
| 6162 | if (car2->collision_flag && !car2->infinite_mass) { |
||
| 6163 | for (i = 0; i < k; i++) { |
||
| 6164 | if (BrVector3Dot(&n[2 * i + 1], &car2->old_norm) < -0.9f) { |
||
| 6165 | car2->infinite_mass |= 0x100u; |
||
| 6166 | } |
||
| 6167 | } |
||
| 6168 | if (!car2->infinite_mass) { |
||
| 6169 | r[2 * k + 1] = car2->old_point; |
||
| 6170 | n[2 * k + 1] = car2->old_norm; |
||
| 6171 | BrVector3SetFloat(&n[2 * k], 0.0f, 0.0f, 0.0f); |
||
| 6172 | BrVector3SetFloat(&r[2 * k], 0.0f, 0.0f, 0.0f); |
||
| 6173 | k++; |
||
| 6174 | } |
||
| 6175 | } |
||
| 6176 | } |
||
| 6177 | if (car1->infinite_mass && car2->infinite_mass) { |
||
| 6178 | return -1; |
||
| 6179 | } |
||
| 6180 | } while (DoCollide(car1, car2, r, n, k, pPass, &car1_to_car2)); |
||
| 6181 | return k; |
||
| 6182 | } |
||
| 6183 | |||
| 6184 | // IDA: int __usercall GetEdgeEdgeCollisions@<EAX>(br_bounds *pB1@<EAX>, br_bounds *pB2@<EDX>, br_matrix34 *pM21@<EBX>, br_matrix34 *pM12@<ECX>, br_matrix34 *pMo21, br_matrix34 *pMo12, br_matrix34 *pM1o1, br_vector3 *pPoint_list, br_vector3 *pNorm_list, int pMax) |
||
| 6185 | int GetEdgeEdgeCollisions(br_bounds* pB1, br_bounds* pB2, br_matrix34* pM21, br_matrix34* pM12, br_matrix34* pMo21, br_matrix34* pMo12, br_matrix34* pM1o1, br_vector3* pPoint_list, br_vector3* pNorm_list, int pMax) { |
||
| 6186 | br_vector3 p1; |
||
| 6187 | br_vector3 p2; |
||
| 6188 | br_vector3 tp1; |
||
| 6189 | br_vector3 tp2; |
||
| 6190 | br_vector3 tp3; |
||
| 6191 | br_vector3 hp1; |
||
| 6192 | br_vector3 hp2; |
||
| 6193 | br_vector3 hp3; |
||
| 6194 | br_vector3 shp1; |
||
| 6195 | br_vector3 shp2; |
||
| 6196 | br_vector3 edge; |
||
| 6197 | int plane1; |
||
| 6198 | int plane2; |
||
| 6199 | int plane3; |
||
| 6200 | br_scalar ts; |
||
| 6201 | int i; |
||
| 6202 | int j; |
||
| 6203 | int n; |
||
| 6204 | LOG_TRACE("(%p, %p, %p, %p, %p, %p, %p, %p, %p, %d)", pB1, pB2, pM21, pM12, pMo21, pMo12, pM1o1, pPoint_list, pNorm_list, pMax); |
||
| 6205 | |||
| 6206 | // EdgeEdge final version |
||
| 6207 | n = 0; |
||
| 6208 | if (pMax < 1) { |
||
| 6209 | return 0; |
||
| 6210 | } |
||
| 6211 | for (i = 0; i < 4; i++) { |
||
| 6212 | if (i == 3) { |
||
| 6213 | tp1 = pB2->min; |
||
| 6214 | } else { |
||
| 6215 | tp1 = pB2->max; |
||
| 6216 | tp1.v[i] = pB2->min.v[i]; |
||
| 6217 | } |
||
| 6218 | for (j = 0; j < 3; j++) { |
||
| 6219 | tp2 = tp1; |
||
| 6220 | if (pB2->max.v[j] == tp2.v[j]) { |
||
| 6221 | tp2.v[j] = pB2->min.v[j]; |
||
| 6222 | } else { |
||
| 6223 | tp2.v[j] = pB2->max.v[j]; |
||
| 6224 | } |
||
| 6225 | |||
| 6226 | BrMatrix34ApplyP(&p1, &tp1, pM21); |
||
| 6227 | BrMatrix34ApplyP(&p2, &tp2, pM21); |
||
| 6228 | plane1 = LineBoxColl(&p1, &p2, pB1, &hp1); |
||
| 6229 | if (plane1 == 0) { |
||
| 6230 | continue; |
||
| 6231 | } |
||
| 6232 | plane2 = LineBoxColl(&p2, &p1, pB1, &hp2); |
||
| 6233 | if (plane1 == 8 || plane2 == 8 || plane2 == 0) { |
||
| 6234 | continue; |
||
| 6235 | } |
||
| 6236 | BrVector3Add(&p1, &hp1, &hp2); |
||
| 6237 | BrVector3Scale(&p1, &p1, 0.5f); |
||
| 6238 | BrMatrix34ApplyP(&tp3, &p1, pM12); |
||
| 6239 | BrMatrix34ApplyP(&p2, &tp3, pMo21); |
||
| 6240 | plane3 = LineBoxColl(&p2, &p1, pB1, &hp3); |
||
| 6241 | // if (plane3 != 8 && plane3 != 0) { |
||
| 6242 | // goto LABEL_25; |
||
| 6243 | // } |
||
| 6244 | if (plane3 == 8 || plane3 == 0) { |
||
| 6245 | BrVector3Sub(&tp3, &p2, &p1); |
||
| 6246 | ts = BrVector3Length(&tp3); |
||
| 6247 | ts = ts / 0.01f; |
||
| 6248 | if (ts == 0.0f) { |
||
| 6249 | continue; |
||
| 6250 | } |
||
| 6251 | BrVector3InvScale(&tp3, &tp3, ts); |
||
| 6252 | BrVector3Accumulate(&p2, &tp3); |
||
| 6253 | plane3 = LineBoxColl(&p2, &p1, pB1, &hp3); |
||
| 6254 | if (plane3 == 8) { |
||
| 6255 | continue; |
||
| 6256 | } |
||
| 6257 | } |
||
| 6258 | if (plane3 == 0) { |
||
| 6259 | continue; |
||
| 6260 | } |
||
| 6261 | |||
| 6262 | BrMatrix34ApplyP(&shp1, &hp1, pM12); |
||
| 6263 | BrMatrix34ApplyP(&shp2, &hp2, pM12); |
||
| 6264 | if ((plane1 ^ plane2) != 4 && (plane3 == plane1 || plane3 == plane2)) { |
||
| 6265 | if (n >= pMax) { |
||
| 6266 | return n; |
||
| 6267 | } |
||
| 6268 | GetBoundsEdge(&pPoint_list[2 * n], &edge, pB1, plane1, plane2, &p2, &hp1, &hp2, 0); |
||
| 6269 | BrVector3Accumulate(&shp1, &shp2); |
||
| 6270 | BrVector3Scale(&pPoint_list[2 * n + 1], &shp1, 0.5f); |
||
| 6271 | BrVector3Sub(&p1, &hp1, &hp2); |
||
| 6272 | BrVector3Cross(&p2, &edge, &p1); |
||
| 6273 | BrVector3Normalise(&p2, &p2); |
||
| 6274 | BrVector3Add(&p1, &pB1->max, &pB1->min); |
||
| 6275 | BrVector3Scale(&p1, &p1, 0.5f); |
||
| 6276 | BrVector3Sub(&p1, &pPoint_list[2 * n], &p1); |
||
| 6277 | if (BrVector3Dot(&p1, &p2) > 0.0) { |
||
| 6278 | BrVector3Negate(&p2, &p2); |
||
| 6279 | } |
||
| 6280 | BrMatrix34ApplyV(&p1, &p2, pM12); |
||
| 6281 | BrMatrix34TApplyV(&pNorm_list[2 * n], &p1, pMo12); |
||
| 6282 | BrMatrix34TApplyV(&pNorm_list[2 * n + 1], &p2, pMo21); |
||
| 6283 | BrVector3Negate(&pNorm_list[2 * n + 1], &pNorm_list[2 * n + 1]); |
||
| 6284 | n++; |
||
| 6285 | } else if ((plane1 ^ plane2) == 4) { |
||
| 6286 | if (pMax - 1 <= n) { |
||
| 6287 | return n; |
||
| 6288 | } |
||
| 6289 | GetBoundsEdge(&pPoint_list[2 * n], &edge, pB1, plane1, plane3, &p2, &hp1, &hp2, 0); |
||
| 6290 | GetBoundsEdge(&pPoint_list[2 * n + 2], &edge, pB1, plane2, plane3, &p2, &hp1, &hp2, 0); |
||
| 6291 | pPoint_list[2 * n + 1] = shp1; |
||
| 6292 | pPoint_list[2 * n + 3] = shp2; |
||
| 6293 | BrVector3Sub(&p1, &hp1, &hp2); |
||
| 6294 | BrMatrix34ApplyV(&p2, &p1, pM12); |
||
| 6295 | BrMatrix34ApplyV(&p1, &p2, pMo21); |
||
| 6296 | BrVector3Cross(&p2, &edge, &p1); |
||
| 6297 | BrVector3Normalise(&pNorm_list[2 * n], &p2); |
||
| 6298 | GetPlaneNormal(&edge, plane3); |
||
| 6299 | if (BrVector3Dot(&pNorm_list[2 * n], &edge) < 0.0f) { |
||
| 6300 | BrVector3Negate(&pNorm_list[2 * n], &pNorm_list[2 * n]); |
||
| 6301 | } |
||
| 6302 | BrMatrix34ApplyV(&pNorm_list[2 * n + 1], &pNorm_list[2 * n], pMo12); |
||
| 6303 | BrVector3Negate(&pNorm_list[2 * n + 1], &pNorm_list[2 * n + 1]); |
||
| 6304 | BrMatrix34ApplyV(&tp3, &pNorm_list[2 * n], pM12); |
||
| 6305 | BrMatrix34ApplyV(&pNorm_list[2 * n], &tp3, pMo21); |
||
| 6306 | pNorm_list[2 * n + 2] = pNorm_list[2 * n]; |
||
| 6307 | pNorm_list[2 * n + 3] = pNorm_list[2 * n + 1]; |
||
| 6308 | n += 2; |
||
| 6309 | } else { |
||
| 6310 | if (pMax - 1 <= n) { |
||
| 6311 | return n; |
||
| 6312 | } |
||
| 6313 | GetBoundsEdge(&pPoint_list[2 * n], &edge, pB1, plane1, plane3, &p2, &hp1, &hp2, 0); |
||
| 6314 | GetBoundsEdge(&pPoint_list[2 * n + 2], &edge, pB1, plane2, plane3, &p2, &hp1, &hp2, 0); |
||
| 6315 | BrMatrix34ApplyP(&pPoint_list[2 * n + 1], &hp1, pM12); |
||
| 6316 | BrMatrix34ApplyP(&pPoint_list[2 * n + 3], &hp2, pM12); |
||
| 6317 | GetPlaneNormal(&pNorm_list[2 * n], plane3); |
||
| 6318 | BrMatrix34ApplyV(&pNorm_list[2 * n + 2], &pNorm_list[2 * n], pM1o1); |
||
| 6319 | BrMatrix34ApplyV(&pNorm_list[2 * n + 1], &pNorm_list[2 * n + 2], pMo12); |
||
| 6320 | pNorm_list[2 * n] = pNorm_list[2 * n + 2]; |
||
| 6321 | BrVector3Negate(&pNorm_list[2 * n + 1], &pNorm_list[2 * n + 1]); |
||
| 6322 | pNorm_list[2 * n + 3] = pNorm_list[2 * n + 1]; |
||
| 6323 | n += 2; |
||
| 6324 | } |
||
| 6325 | } |
||
| 6326 | } |
||
| 6327 | return n; |
||
| 6328 | } |
||
| 6329 | |||
| 6330 | // IDA: int __usercall FacePointCarCarCollide@<EAX>(tCollision_info *car1@<EAX>, tCollision_info *car2@<EDX>, br_matrix34 *pMms@<EBX>, br_matrix34 *pMoms@<ECX>, br_matrix34 *pMsos, br_vector3 *pPoint_list, br_vector3 *pNorm_list, int pMax, int order) |
||
| 6331 | int FacePointCarCarCollide(tCollision_info* car1, tCollision_info* car2, br_matrix34* pMms, br_matrix34* pMoms, br_matrix34* pMsos, br_vector3* pPoint_list, br_vector3* pNorm_list, int pMax, int order) { |
||
| 6332 | int k; |
||
| 6333 | int i; |
||
| 6334 | int j; |
||
| 6335 | int l; |
||
| 6336 | int plane; |
||
| 6337 | br_vector3 a; |
||
| 6338 | br_vector3 a1; |
||
| 6339 | br_vector3 aa; |
||
| 6340 | br_vector3 bb; |
||
| 6341 | br_vector3 norm; |
||
| 6342 | br_vector3 hp; |
||
| 6343 | br_vector3 centre; |
||
| 6344 | br_scalar dist; |
||
| 6345 | br_bounds* pStat_box; |
||
| 6346 | //br_bounds* pMove_box; // Pierre-Marie Baty -- unused variable |
||
| 6347 | LOG_TRACE("(%p, %p, %p, %p, %p, %p, %p, %d, %d)", car1, car2, pMms, pMoms, pMsos, pPoint_list, pNorm_list, pMax, order); |
||
| 6348 | |||
| 6349 | k = 0; |
||
| 6350 | pStat_box = &car2->bounds[1]; |
||
| 6351 | BrVector3Add(¢re, &car2->bounds[1].max, &car2->bounds[1].min); |
||
| 6352 | BrVector3InvScale(¢re, ¢re, 2.0f); |
||
| 6353 | for (i = 0; i < car2->extra_point_num + 8; i++) { |
||
| 6354 | if (i >= 8) { |
||
| 6355 | a = car2->extra_points[i - 8]; |
||
| 6356 | } else { |
||
| 6357 | a.v[0] = ((i & 2) == 0) * pStat_box->min.v[0] + ((i & 2) >> 1) * pStat_box->max.v[0]; |
||
| 6358 | a.v[1] = ((i & 1) == 0) * pStat_box->min.v[1] + (i & 1) * pStat_box->max.v[1]; |
||
| 6359 | a.v[2] = ((i & 4) == 0) * pStat_box->max.v[2] + ((i & 4) >> 2) * pStat_box->min.v[2]; |
||
| 6360 | } |
||
| 6361 | BrMatrix34ApplyP(&aa, &a, pMms); |
||
| 6362 | BrMatrix34ApplyP(&bb, &a, pMoms); |
||
| 6363 | BrVector3Sub(&aa, &aa, &bb); |
||
| 6364 | dist = BrVector3Length(&aa); |
||
| 6365 | if (dist >= 0.00001f) { |
||
| 6366 | BrVector3Scale(&a1, &aa, (0.05f / WORLD_SCALE) / dist); // 0.0072463769 * 6.9 = 0.05 |
||
| 6367 | BrVector3Accumulate(&aa, &a1); |
||
| 6368 | BrVector3Accumulate(&aa, &bb); |
||
| 6369 | plane = LineBoxCollWithSphere(&bb, &aa, &car1->bounds[1], &hp); |
||
| 6370 | if ((plane & 7) != 0) { |
||
| 6371 | GetPlaneNormal(&norm, plane); |
||
| 6372 | |||
| 6373 | j = 2 * k + order; |
||
| 6374 | l = 2 * k + (order == 0); |
||
| 6375 | BrMatrix34ApplyV(&pNorm_list[j], &norm, pMsos); |
||
| 6376 | BrMatrix34TApplyV(&pNorm_list[l], &pNorm_list[j], pMoms); |
||
| 6377 | BrVector3Negate(&pNorm_list[l], &pNorm_list[l]); |
||
| 6378 | if ((pNorm_list[l].v[0] >= 0.0f) != (centre.v[0] <= a.v[0]) || (pNorm_list[l].v[1] >= 0.0f) != (centre.v[1] <= a.v[1]) || (pNorm_list[l].v[2] >= 0.0f) != (a.v[2] >= centre.v[2]) |
||
| 6379 | || !TestOldMats(car1, car2, 0)) { |
||
| 6380 | pPoint_list[l] = a; |
||
| 6381 | pPoint_list[j] = hp; |
||
| 6382 | k++; |
||
| 6383 | if (pMax == k) { |
||
| 6384 | return k; |
||
| 6385 | } |
||
| 6386 | } |
||
| 6387 | } |
||
| 6388 | } |
||
| 6389 | } |
||
| 6390 | return k; |
||
| 6391 | } |
||
| 6392 | |||
| 6393 | // IDA: void __usercall MungeCarsMass(tCollision_info *pCar@<EAX>, br_scalar pFactor) |
||
| 6394 | void MungeCarsMass(tCollision_info* pCar, br_scalar pFactor) { |
||
| 6395 | LOG_TRACE("(%p, %f)", pCar, pFactor); |
||
| 6396 | |||
| 6397 | pCar->M = pCar->M * pFactor; |
||
| 6398 | BrVector3Scale(&pCar->I, &pCar->I, pFactor); |
||
| 6399 | } |
||
| 6400 | |||
| 6401 | // IDA: void __usercall ModifyCarsMass(tCollision_info *pCar_1@<EAX>, tCollision_info *pCar_2@<EDX>) |
||
| 6402 | void ModifyCarsMass(tCollision_info* pCar_1, tCollision_info* pCar_2) { |
||
| 6403 | LOG_TRACE("(%p, %p)", pCar_1, pCar_2); |
||
| 6404 | |||
| 6405 | if (pCar_1->driver > eDriver_non_car && ((tCar_spec*)pCar_1)->collision_mass_multiplier != 1.0f) { |
||
| 6406 | MungeCarsMass(pCar_1, ((tCar_spec*)pCar_1)->collision_mass_multiplier); |
||
| 6407 | } |
||
| 6408 | if (pCar_2->driver > eDriver_non_car && ((tCar_spec*)pCar_2)->collision_mass_multiplier != 1.0f) { |
||
| 6409 | MungeCarsMass(pCar_2, ((tCar_spec*)pCar_2)->collision_mass_multiplier); |
||
| 6410 | } |
||
| 6411 | } |
||
| 6412 | |||
| 6413 | // IDA: void __usercall ResetCarsMass(tCollision_info *pCar_1@<EAX>, tCollision_info *pCar_2@<EDX>) |
||
| 6414 | void ResetCarsMass(tCollision_info* pCar_1, tCollision_info* pCar_2) { |
||
| 6415 | LOG_TRACE("(%p, %p)", pCar_1, pCar_2); |
||
| 6416 | |||
| 6417 | if (pCar_1->driver > eDriver_non_car && ((tCar_spec*)pCar_1)->collision_mass_multiplier != 1.0f) { |
||
| 6418 | MungeCarsMass(pCar_1, 1.0f / ((tCar_spec*)pCar_1)->collision_mass_multiplier); |
||
| 6419 | } |
||
| 6420 | if (pCar_2->driver > eDriver_non_car && ((tCar_spec*)pCar_2)->collision_mass_multiplier != 1.0f) { |
||
| 6421 | MungeCarsMass(pCar_2, 1.0f / ((tCar_spec*)pCar_2)->collision_mass_multiplier); |
||
| 6422 | } |
||
| 6423 | } |
||
| 6424 | |||
| 6425 | // IDA: int __usercall DoCollide@<EAX>(tCollision_info *car1@<EAX>, tCollision_info *car2@<EDX>, br_vector3 *r@<EBX>, br_vector3 *n@<ECX>, int k, int pPass, br_matrix34 *mat1_to_mat2) |
||
| 6426 | int DoCollide(tCollision_info* car1, tCollision_info* car2, br_vector3* r, br_vector3* n, int k, int pPass, br_matrix34* mat1_to_mat2) { |
||
| 6427 | br_matrix34* mat1; |
||
| 6428 | br_matrix34* mat2; |
||
| 6429 | br_matrix34* oldmat1; |
||
| 6430 | br_matrix34* oldmat2; |
||
| 6431 | br_matrix4 M; |
||
| 6432 | br_vector3 tau1[8]; |
||
| 6433 | br_vector3 a; |
||
| 6434 | br_vector3 norm; |
||
| 6435 | br_vector3 f1; |
||
| 6436 | br_vector3 f2; |
||
| 6437 | br_vector3 pos1; |
||
| 6438 | br_vector3 pos2; |
||
| 6439 | br_vector3 max_friction; |
||
| 6440 | br_vector3 tv; |
||
| 6441 | br_vector3 tv2; |
||
| 6442 | br_vector3* tau2; |
||
| 6443 | br_vector3 torque1; |
||
| 6444 | br_vector3 torque2; |
||
| 6445 | br_scalar f[4]; |
||
| 6446 | br_scalar d[4]; |
||
| 6447 | br_scalar ts; |
||
| 6448 | br_scalar tforce; |
||
| 6449 | int i; |
||
| 6450 | int j; |
||
| 6451 | int car1_point; |
||
| 6452 | int car2_point; |
||
| 6453 | int plane; |
||
| 6454 | int move_car1; |
||
| 6455 | int move_car2; |
||
| 6456 | //br_vector3 a2; // Pierre-Marie Baty -- unused variable |
||
| 6457 | br_vector3 f12; |
||
| 6458 | br_vector3 f22; |
||
| 6459 | br_vector3 point_vel1; |
||
| 6460 | br_vector3 point_vel2; |
||
| 6461 | //br_scalar fudge_multiplier; // Pierre-Marie Baty -- unused variable |
||
| 6462 | br_scalar factor; |
||
| 6463 | int need_to_fudge; |
||
| 6464 | LOG_TRACE("(%p, %p, %p, %p, %d, %d, %p)", car1, car2, r, n, k, pPass, mat1_to_mat2); |
||
| 6465 | |||
| 6466 | mat1 = &car1->car_master_actor->t.t.mat; |
||
| 6467 | mat2 = &car2->car_master_actor->t.t.mat; |
||
| 6468 | oldmat1 = &car1->oldmat; |
||
| 6469 | oldmat2 = &car2->oldmat; |
||
| 6470 | tau2 = &tau1[4]; |
||
| 6471 | move_car1 = !car1->infinite_mass && car1->min_torque_squared == 0.0f; |
||
| 6472 | move_car2 = !car2->infinite_mass && car2->min_torque_squared == 0.0f; |
||
| 6473 | if (k > 4) { |
||
| 6474 | k = 4; |
||
| 6475 | } |
||
| 6476 | BrMatrix34Copy(mat1, oldmat1); |
||
| 6477 | BrMatrix34Copy(mat2, oldmat2); |
||
| 6478 | BrVector3Copy(&car1->omega, &car1->oldomega); |
||
| 6479 | BrVector3Copy(&car2->omega, &car2->oldomega); |
||
| 6480 | BrMatrix34TApplyV(&car1->velocity_car_space, &car1->v, mat1); |
||
| 6481 | BrMatrix34TApplyV(&car2->velocity_car_space, &car2->v, mat2); |
||
| 6482 | need_to_fudge = 1; |
||
| 6483 | for (i = 0; i < k; ++i) { |
||
| 6484 | BrVector3Cross(&tau1[i], &r[2 * i], &n[2 * i]); |
||
| 6485 | BrVector3Cross(&tau2[i], &r[2 * i + 1], &n[2 * i + 1]); |
||
| 6486 | Vector3Div(&tau1[i], &tau1[i], &car1->I); |
||
| 6487 | Vector3Div(&tau2[i], &tau2[i], &car2->I); |
||
| 6488 | BrVector3Cross(&tv, &car1->omega, &r[2 * i]); |
||
| 6489 | BrVector3Accumulate(&tv, &car1->velocity_car_space); |
||
| 6490 | d[i] = -BrVector3Dot(&n[2 * i], &tv); |
||
| 6491 | BrVector3Cross(&tv, &car2->omega, &r[2 * i + 1]); |
||
| 6492 | BrVector3Accumulate(&tv, &car2->velocity_car_space); |
||
| 6493 | d[i] -= BrVector3Dot(&n[2 * i + 1], &tv); |
||
| 6494 | if (d[i] > 0.0f) { |
||
| 6495 | need_to_fudge = 0; |
||
| 6496 | } |
||
| 6497 | } |
||
| 6498 | if (need_to_fudge) { |
||
| 6499 | d[0] = 0.5f; |
||
| 6500 | } |
||
| 6501 | factor = 0.0f; |
||
| 6502 | if (move_car1) { |
||
| 6503 | factor = car1->M + factor; |
||
| 6504 | } |
||
| 6505 | if (move_car2) { |
||
| 6506 | factor = car2->M + factor; |
||
| 6507 | } |
||
| 6508 | for (i = 0; i < k; i++) { |
||
| 6509 | for (j = 0; j < k; j++) { |
||
| 6510 | if (move_car1) { |
||
| 6511 | BrVector3Cross(&tv, &tau1[j], &r[2 * i]); |
||
| 6512 | BrVector3InvScale(&norm, &n[2 * j], car1->M); |
||
| 6513 | BrVector3Accumulate(&tv, &norm); |
||
| 6514 | M.m[i][j] = BrVector3Dot(&n[2 * i], &tv); |
||
| 6515 | } else { |
||
| 6516 | M.m[i][j] = 0.0f; |
||
| 6517 | } |
||
| 6518 | if (move_car2) { |
||
| 6519 | BrVector3Cross(&tv, &tau2[j], &r[2 * i + 1]); |
||
| 6520 | BrVector3InvScale(&norm, &n[2 * j + 1], car2->M); |
||
| 6521 | BrVector3Accumulate(&tv, &norm); |
||
| 6522 | M.m[i][j] += BrVector3Dot(&n[2 * i + 1], &tv); |
||
| 6523 | } |
||
| 6524 | M.m[i][j] *= factor; |
||
| 6525 | } |
||
| 6526 | } |
||
| 6527 | switch (k) { |
||
| 6528 | case 1: |
||
| 6529 | ts = SinglePointColl(f, &M, d); |
||
| 6530 | break; |
||
| 6531 | case 2: |
||
| 6532 | ts = TwoPointCollB(f, &M, d, tau1, n); |
||
| 6533 | break; |
||
| 6534 | case 3: |
||
| 6535 | d[3] = 0.f; |
||
| 6536 | ts = ThreePointCollRecB(f, &M, d, tau1, n); |
||
| 6537 | break; |
||
| 6538 | case 4: |
||
| 6539 | ts = FourPointCollB(f, &M, d, tau1, n); |
||
| 6540 | break; |
||
| 6541 | default: |
||
| 6542 | ts = 0; |
||
| 6543 | break; |
||
| 6544 | } |
||
| 6545 | if (k > 3) { |
||
| 6546 | k = 3; |
||
| 6547 | } |
||
| 6548 | if (fabsf(ts) <= 0.000001f) { |
||
| 6549 | return 0; |
||
| 6550 | } |
||
| 6551 | BrVector3SetFloat(&f1, 0.0f, 0.0f, 0.0f); |
||
| 6552 | BrVector3SetFloat(&f2, 0.0f, 0.0f, 0.0f); |
||
| 6553 | BrVector3SetFloat(&pos1, 0.0f, 0.0f, 0.0f); |
||
| 6554 | BrVector3SetFloat(&pos2, 0.0f, 0.0f, 0.0f); |
||
| 6555 | BrVector3SetFloat(&torque1, 0.0f, 0.0f, 0.0f); |
||
| 6556 | BrVector3SetFloat(&torque2, 0.0f, 0.0f, 0.0f); |
||
| 6557 | tforce = 0.0f; |
||
| 6558 | car1_point = -1; |
||
| 6559 | car2_point = -1; |
||
| 6560 | for (i = 0; i < k; i++) { |
||
| 6561 | f[i] = f[i] * factor; |
||
| 6562 | if (f[i] == 0.0f && k != 0) { |
||
| 6563 | break; |
||
| 6564 | } |
||
| 6565 | if (f[i] < 0.001f) { |
||
| 6566 | f[i] = 0.001f; |
||
| 6567 | } |
||
| 6568 | if (f[i] > 10.0f) { |
||
| 6569 | ts = 0.0f; |
||
| 6570 | } |
||
| 6571 | f[i] += 0.1f; |
||
| 6572 | BrVector3Scale(&tau1[i], &tau1[i], f[i]); |
||
| 6573 | BrVector3Scale(&tau2[i], &tau2[i], f[i]); |
||
| 6574 | BrVector3Accumulate(&torque1, &tau1[i]); |
||
| 6575 | BrVector3Accumulate(&torque2, &tau2[i]); |
||
| 6576 | if (!pPass && Vector3IsZero(&n[2 * i])) { |
||
| 6577 | car2_point = i; |
||
| 6578 | } else if (!pPass && Vector3IsZero(&n[2 * i + 1])) { |
||
| 6579 | car1_point = i; |
||
| 6580 | } else { |
||
| 6581 | ts = f[i] / car1->M; |
||
| 6582 | BrVector3Scale(&tv2, &n[2 * i], ts); |
||
| 6583 | BrVector3Accumulate(&f1, &tv2); |
||
| 6584 | ts = f[i] / car2->M; |
||
| 6585 | BrVector3Scale(&tv2, &n[2 * i + 1], ts); |
||
| 6586 | BrVector3Accumulate(&f2, &tv2); |
||
| 6587 | BrVector3Scale(&tv2, &r[2 * i], f[i]); |
||
| 6588 | BrVector3Accumulate(&pos1, &tv2); |
||
| 6589 | BrVector3Scale(&tv2, &r[2 * i + 1], f[i]); |
||
| 6590 | BrVector3Accumulate(&pos2, &tv2); |
||
| 6591 | tforce += f[i]; |
||
| 6592 | } |
||
| 6593 | } |
||
| 6594 | if (car1->min_torque_squared != 0.0f && !car1->infinite_mass && BrVector3LengthSquared(&torque1) > car1->min_torque_squared) { |
||
| 6595 | BrVector3Scale(&car1->omega, &car1->omega, gDt); |
||
| 6596 | car1->omega.v[0] += torque1.v[0] * 0.04f; |
||
| 6597 | car1->omega.v[2] += torque1.v[2] * 0.04f; |
||
| 6598 | if (BrVector3LengthSquared(&car1->omega) > car1->break_off_radians_squared) { |
||
| 6599 | car1->min_torque_squared = 0.0f; |
||
| 6600 | return 1; |
||
| 6601 | } |
||
| 6602 | BrVector3InvScale(&car1->omega, &car1->omega, gDt); |
||
| 6603 | } |
||
| 6604 | if (car2->min_torque_squared != 0.0f && !car2->infinite_mass && BrVector3LengthSquared(&torque2) > car2->min_torque_squared) { |
||
| 6605 | BrVector3Scale(&car2->omega, &car2->omega, gDt); |
||
| 6606 | car2->omega.v[0] += torque2.v[0] * 0.04f; |
||
| 6607 | car2->omega.v[2] += torque2.v[2] * 0.04f; |
||
| 6608 | if (BrVector3LengthSquared(&car2->omega) > car2->break_off_radians_squared) { |
||
| 6609 | car2->min_torque_squared = 0.0f; |
||
| 6610 | return 1; |
||
| 6611 | } |
||
| 6612 | BrVector3InvScale(&car2->omega, &car2->omega, gDt); |
||
| 6613 | } |
||
| 6614 | if (move_car1) { |
||
| 6615 | BrVector3Accumulate(&car1->omega, &torque1); |
||
| 6616 | } |
||
| 6617 | if (move_car2) { |
||
| 6618 | BrVector3Accumulate(&car2->omega, &torque2); |
||
| 6619 | } |
||
| 6620 | BrVector3InvScale(&pos1, &pos1, tforce); |
||
| 6621 | BrVector3InvScale(&pos2, &pos2, tforce); |
||
| 6622 | if (pPass == 0) { |
||
| 6623 | if (car1_point >= 0 && move_car1) { |
||
| 6624 | f[car1_point] = f[car1_point] / car1->M; |
||
| 6625 | BrVector3Scale(&n[2 * car1_point], &n[2 * car1_point], f[car1_point]); |
||
| 6626 | BrVector3Cross(&tv2, &car1->oldomega, &r[2 * car1_point]); |
||
| 6627 | BrVector3Accumulate(&tv2, &car1->velocity_car_space); |
||
| 6628 | ts = BrVector3Length(&tv2); |
||
| 6629 | if (ts > 0.0001f && (car1->driver <= eDriver_non_car || !CAR(car1)->wall_climber_mode)) { |
||
| 6630 | AddFriction(car1, &tv2, &n[2 * car1_point], &r[2 * car1_point], f[car1_point], &max_friction); |
||
| 6631 | BrVector3Accumulate(&n[2 * car1_point], &max_friction); |
||
| 6632 | } |
||
| 6633 | BrMatrix34ApplyV(&tv, &n[2 * car1_point], mat1); |
||
| 6634 | BrVector3Accumulate(&car1->v, &tv); |
||
| 6635 | } |
||
| 6636 | if (car2_point >= 0 && move_car2) { |
||
| 6637 | f[car2_point] = f[car2_point] / car2->M; |
||
| 6638 | BrVector3Scale(&n[2 * car2_point + 1], &n[2 * car2_point + 1], f[car2_point]); |
||
| 6639 | BrVector3Cross(&tv2, &car2->oldomega, &r[2 * car2_point + 1]); |
||
| 6640 | BrVector3Accumulate(&tv2, &car2->velocity_car_space); |
||
| 6641 | ts = BrVector3Length(&tv2); |
||
| 6642 | |||
| 6643 | if (ts > 0.0001f && (car1->driver <= eDriver_non_car || !(CAR(car1)->wall_climber_mode))) { |
||
| 6644 | AddFriction(car2, &tv2, &n[2 * car2_point + 1], &r[2 * car2_point + 1], f[car2_point], &max_friction); |
||
| 6645 | BrVector3Accumulate(&n[2 * car2_point + 1], &max_friction); |
||
| 6646 | } |
||
| 6647 | BrMatrix34ApplyV(&tv, &n[2 * car2_point + 1], mat2); |
||
| 6648 | BrVector3Accumulate(&car2->v, &tv); |
||
| 6649 | } |
||
| 6650 | if (tforce != 0.0f) { |
||
| 6651 | BrVector3Cross(&point_vel1, &car1->oldomega, &pos1); |
||
| 6652 | BrVector3Sub(&a, &car1->v, &car2->v); |
||
| 6653 | BrMatrix34TApplyV(&tv2, &a, mat1); |
||
| 6654 | BrVector3Accumulate(&point_vel1, &tv2); |
||
| 6655 | BrVector3Cross(&point_vel2, &car2->oldomega, &pos2); |
||
| 6656 | AddFrictionCarToCar(car1, car2, &point_vel1, &point_vel2, &f1, &pos1, &pos2, tforce, &max_friction); |
||
| 6657 | if (TestForNan(max_friction.v) || TestForNan(&max_friction.v[1]) || TestForNan(&max_friction.v[2])) { |
||
| 6658 | BrVector3SetFloat(&max_friction, 0.0f, 0.0f, 0.0f); |
||
| 6659 | } |
||
| 6660 | BrVector3InvScale(&tv2, &max_friction, car1->M); |
||
| 6661 | BrVector3Accumulate(&f1, &tv2); |
||
| 6662 | BrMatrix34ApplyV(&tv2, &max_friction, mat1); |
||
| 6663 | BrMatrix34TApplyV(&max_friction, &tv2, mat2); |
||
| 6664 | BrVector3InvScale(&tv2, &max_friction, car2->M); |
||
| 6665 | BrVector3Accumulate(&f2, &tv2); |
||
| 6666 | } |
||
| 6667 | } |
||
| 6668 | if (tforce == 0.0f) { |
||
| 6669 | return 0; |
||
| 6670 | } |
||
| 6671 | BrMatrix34ApplyV(&tv, &f1, mat1); |
||
| 6672 | if (move_car1) { |
||
| 6673 | BrVector3Accumulate(&car1->v, &tv); |
||
| 6674 | } |
||
| 6675 | CrushAndDamageCar(CAR(car1), &pos1, &f1, CAR(car2)); |
||
| 6676 | if ((car1->infinite_mass & 0x100) != 0) { |
||
| 6677 | BrVector3Sub(&tv2, &car1->cmpos, &pos1); |
||
| 6678 | BrVector3Accumulate(&tv2, &car1->cmpos); |
||
| 6679 | ts = BrVector3Length(&f1); |
||
| 6680 | if (ts > 0.0001f) { |
||
| 6681 | ts = 5.0f / ts; |
||
| 6682 | BrVector3Scale(&a, &f1, ts); |
||
| 6683 | BrVector3Accumulate(&tv2, &a); |
||
| 6684 | plane = LineBoxColl(&tv2, &pos1, &car1->bounds[1], &a); |
||
| 6685 | if (plane) { |
||
| 6686 | BrVector3Negate(&f12, &f1); |
||
| 6687 | CrushAndDamageCar(CAR(car1), &a, &f12, CAR(car2)); |
||
| 6688 | } |
||
| 6689 | } |
||
| 6690 | } |
||
| 6691 | BrMatrix34ApplyV(&tv, &f2, mat2); |
||
| 6692 | if (move_car2) { |
||
| 6693 | BrVector3Accumulate(&car2->v, &tv); |
||
| 6694 | } |
||
| 6695 | CrushAndDamageCar(CAR(car2), &pos2, &f2, CAR(car1)); |
||
| 6696 | if ((car2->infinite_mass & 0x100) != 0) { |
||
| 6697 | BrVector3Sub(&tv2, &car2->cmpos, &pos2); |
||
| 6698 | BrVector3Accumulate(&tv2, &car2->cmpos); |
||
| 6699 | ts = BrVector3Length(&f2); |
||
| 6700 | if (ts > 0.0001f) { |
||
| 6701 | ts = 5.0f / ts; |
||
| 6702 | BrVector3Scale(&a, &f2, ts); |
||
| 6703 | BrVector3Accumulate(&tv2, &a); |
||
| 6704 | plane = LineBoxColl(&tv2, &pos2, &car2->bounds[1], &a); |
||
| 6705 | if (plane) { |
||
| 6706 | BrVector3Negate(&f22, &f2); |
||
| 6707 | CrushAndDamageCar(CAR(car2), &a, &f22, CAR(car1)); |
||
| 6708 | } |
||
| 6709 | } |
||
| 6710 | } |
||
| 6711 | BrMatrix34ApplyP(&tv2, &pos1, mat1); |
||
| 6712 | BrVector3InvScale(&tv2, &tv2, WORLD_SCALE); |
||
| 6713 | BrVector3Scale(&f1, &f1, 5.0f); |
||
| 6714 | CrashNoise(&f1, &tv2, 0); |
||
| 6715 | BrVector3Add(&a, &car2->v, &car1->v); |
||
| 6716 | BrVector3Scale(&a, &a, 0.25f / WORLD_SCALE); |
||
| 6717 | BrVector3Scale(&tv, &tv, car2->M * 3.0f); |
||
| 6718 | CreateSparkShower(&tv2, &a, &tv, CAR(car1), CAR(car2)); |
||
| 6719 | return 0; |
||
| 6720 | } |
||
| 6721 | |||
| 6722 | // IDA: br_scalar __usercall TwoPointCollB@<ST0>(br_scalar *f@<EAX>, br_matrix4 *m@<EDX>, br_scalar *d@<EBX>, br_vector3 *tau@<ECX>, br_vector3 *n) |
||
| 6723 | br_scalar TwoPointCollB(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n) { |
||
| 6724 | br_scalar ts; |
||
| 6725 | LOG_TRACE("(%p, %p, %p, %p, %p)", f, m, d, tau, n); |
||
| 6726 | |||
| 6727 | ts = m->m[1][1] * m->m[0][0] - m->m[0][1] * m->m[1][0]; |
||
| 6728 | if (fabsf(ts) > 0.000001f) { |
||
| 6729 | f[0] = (m->m[1][1] * d[0] - m->m[0][1] * d[1]) / ts; |
||
| 6730 | f[1] = (m->m[1][0] * d[0] - m->m[0][0] * d[1]) / -ts; |
||
| 6731 | } |
||
| 6732 | if (f[1] < 0.0f) { |
||
| 6733 | ts = SinglePointColl(f, m, d); |
||
| 6734 | f[1] = 0.f; |
||
| 6735 | } else if (f[0] < 0.f) { |
||
| 6736 | m->m[0][0] = m->m[1][1]; |
||
| 6737 | BrVector3Copy(&tau[0], &tau[1]); |
||
| 6738 | BrVector3Copy(&tau[4], &tau[5]); |
||
| 6739 | BrVector3Copy(&n[0], &n[2]); |
||
| 6740 | BrVector3Copy(&n[1], &n[3]); |
||
| 6741 | d[0] = d[1]; |
||
| 6742 | ts = SinglePointColl(f, m, d); |
||
| 6743 | f[1] = 0.0f; |
||
| 6744 | } |
||
| 6745 | return ts; |
||
| 6746 | } |
||
| 6747 | |||
| 6748 | // IDA: br_scalar __usercall ThreePointCollRecB@<ST0>(br_scalar *f@<EAX>, br_matrix4 *m@<EDX>, br_scalar *d@<EBX>, br_vector3 *tau@<ECX>, br_vector3 *n) |
||
| 6749 | br_scalar ThreePointCollRecB(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n) { |
||
| 6750 | int i; |
||
| 6751 | int j; |
||
| 6752 | br_scalar ts; |
||
| 6753 | LOG_TRACE("(%p, %p, %p, %p, %p)", f, m, d, tau, n); |
||
| 6754 | |||
| 6755 | ts = ThreePointColl(f, m, d); |
||
| 6756 | if (f[0] >= 0.0f && f[1] >= 0.0f && f[2] >= 0.0f) { |
||
| 6757 | return ts; |
||
| 6758 | } |
||
| 6759 | if (f[2] < 0.f) { |
||
| 6760 | i = 0; |
||
| 6761 | j = 1; |
||
| 6762 | } else if (f[1] < 0.f) { |
||
| 6763 | i = 0; |
||
| 6764 | j = 2; |
||
| 6765 | } else if (f[0] < 0.f) { |
||
| 6766 | i = 1; |
||
| 6767 | j = 2; |
||
| 6768 | } else { |
||
| 6769 | return 0.0f; |
||
| 6770 | } |
||
| 6771 | m->m[0][0] = ((br_scalar*)(m->m))[5 * i]; |
||
| 6772 | m->m[1][0] = m->m[j][i]; |
||
| 6773 | m->m[0][1] = m->m[i][j]; |
||
| 6774 | m->m[1][1] = ((br_scalar*)(m->m))[5 * j]; |
||
| 6775 | BrVector3Copy(&tau[0], &tau[i]); |
||
| 6776 | BrVector3Copy(&tau[1], &tau[j]); |
||
| 6777 | BrVector3Copy(&tau[4], &tau[i + 4]); |
||
| 6778 | BrVector3Copy(&tau[5], &tau[j + 4]); |
||
| 6779 | BrVector3Copy(&n[0], &n[2 * i]); |
||
| 6780 | BrVector3Copy(&n[2], &n[2 * j]); |
||
| 6781 | BrVector3Copy(&n[1], &n[2 * i + 1]); |
||
| 6782 | BrVector3Copy(&n[3], &n[2 * j + 1]); |
||
| 6783 | d[0] = d[i]; |
||
| 6784 | d[1] = d[j]; |
||
| 6785 | ts = TwoPointCollB(f, m, d, tau, n); |
||
| 6786 | f[2] = 0.0; |
||
| 6787 | return ts; |
||
| 6788 | } |
||
| 6789 | |||
| 6790 | // IDA: br_scalar __usercall FourPointCollB@<ST0>(br_scalar *f@<EAX>, br_matrix4 *m@<EDX>, br_scalar *d@<EBX>, br_vector3 *tau@<ECX>, br_vector3 *n) |
||
| 6791 | br_scalar FourPointCollB(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n) { |
||
| 6792 | int i; |
||
| 6793 | int j; |
||
| 6794 | int l; |
||
| 6795 | br_scalar ts; |
||
| 6796 | LOG_TRACE("(%p, %p, %p, %p, %p)", f, m, d, tau, n); |
||
| 6797 | |||
| 6798 | ts = ThreePointColl(f, m, d); |
||
| 6799 | if (f[0] >= 0.0f && f[1] >= 0.0f && f[2] >= 0.0f) { |
||
| 6800 | return ts; |
||
| 6801 | } |
||
| 6802 | if (f[0] < 0.0f) { |
||
| 6803 | l = 0; |
||
| 6804 | } else if (f[1] < 0.0f) { |
||
| 6805 | l = 1; |
||
| 6806 | } else { |
||
| 6807 | l = 2; |
||
| 6808 | } |
||
| 6809 | for (i = l; i < 3; i++) { |
||
| 6810 | for (j = 0; j < 4; j++) { |
||
| 6811 | m->m[i][j] = m->m[i + 1][j]; |
||
| 6812 | } |
||
| 6813 | d[i] = d[i + 1]; |
||
| 6814 | tau[i] = tau[i + 1]; |
||
| 6815 | tau[i + 4] = tau[i + 5]; |
||
| 6816 | n[2 * i] = n[2 * i + 2]; |
||
| 6817 | n[2 * i + 1] = n[2 * i + 3]; |
||
| 6818 | d[i] = d[i + 1]; |
||
| 6819 | } |
||
| 6820 | for (i = l; i < 3; i++) { |
||
| 6821 | for (j = 0; j < 3; j++) { |
||
| 6822 | m->m[j][i] = m->m[j][i + 1]; |
||
| 6823 | } |
||
| 6824 | } |
||
| 6825 | return ThreePointCollRecB(f, m, d, tau, n); |
||
| 6826 | } |
||
| 6827 | |||
| 6828 | // IDA: int __usercall TestForNan@<EAX>(float *f@<EAX>) |
||
| 6829 | int TestForNan(float* f) { |
||
| 6830 | //tU32 i; // Pierre-Marie Baty -- unused variable |
||
| 6831 | LOG_TRACE("(%p)", f); |
||
| 6832 | // i = *f; |
||
| 6833 | // LOG_DEBUG("i %x", i); |
||
| 6834 | return isnan(*f); |
||
| 6835 | // return (~i & 0x7F800000) == 0; |
||
| 6836 | } |
||
| 6837 | |||
| 6838 | // IDA: void __cdecl CheckCameraHither() |
||
| 6839 | void CheckCameraHither(void) { |
||
| 6840 | br_camera* cam; |
||
| 6841 | static int old_hither; |
||
| 6842 | LOG_TRACE("()"); |
||
| 6843 | |||
| 6844 | cam = (br_camera*)gCamera->type_data; |
||
| 6845 | if (TestForNan(&cam->hither_z)) { |
||
| 6846 | cam->hither_z = (float)old_hither; |
||
| 6847 | } |
||
| 6848 | old_hither = (int)cam->hither_z; |
||
| 6849 | } |
||
| 6850 | |||
| 6851 | // IDA: void __usercall SetCarSuspGiveAndHeight(tCar_spec *pCar@<EAX>, br_scalar pFront_give_factor, br_scalar pRear_give_factor, br_scalar pDamping_factor, br_scalar pExtra_front_height, br_scalar pExtra_rear_height) |
||
| 6852 | void SetCarSuspGiveAndHeight(tCar_spec* pCar, br_scalar pFront_give_factor, br_scalar pRear_give_factor, br_scalar pDamping_factor, br_scalar pExtra_front_height, br_scalar pExtra_rear_height) { |
||
| 6853 | br_scalar front_give; |
||
| 6854 | br_scalar rear_give; |
||
| 6855 | br_scalar damping; |
||
| 6856 | br_scalar ratio; |
||
| 6857 | //int i; // Pierre-Marie Baty -- unused variable |
||
| 6858 | LOG_TRACE("(%p, %f, %f, %f, %f, %f)", pCar, pFront_give_factor, pRear_give_factor, pDamping_factor, pExtra_front_height, pExtra_rear_height); |
||
| 6859 | |||
| 6860 | #define UNK_SUSPENION_FACTOR 5.0f |
||
| 6861 | |||
| 6862 | front_give = pCar->susp_give[1] * pFront_give_factor * WORLD_SCALE; |
||
| 6863 | rear_give = pCar->susp_give[0] * pRear_give_factor * WORLD_SCALE; |
||
| 6864 | damping = pCar->damping * pDamping_factor; |
||
| 6865 | ratio = fabsf((pCar->wpos[0].v[2] - pCar->cmpos.v[2]) / (pCar->wpos[2].v[2] - pCar->cmpos.v[2])); |
||
| 6866 | pCar->sk[0] = pCar->M / (ratio + 1.0f) * UNK_SUSPENION_FACTOR / rear_give; |
||
| 6867 | pCar->sb[0] = pCar->M / (ratio + 1.0f) * sqrtf(UNK_SUSPENION_FACTOR) / sqrt(rear_give); |
||
| 6868 | ratio = 1.0f / ratio; |
||
| 6869 | pCar->sk[1] = pCar->M / (ratio + 1.0f) * UNK_SUSPENION_FACTOR / front_give; |
||
| 6870 | pCar->sb[1] = pCar->M / (ratio + 1.0f) * sqrtf(UNK_SUSPENION_FACTOR) / sqrt(front_give); |
||
| 6871 | |||
| 6872 | pCar->sb[0] *= damping; |
||
| 6873 | pCar->sb[1] *= damping; |
||
| 6874 | pCar->susp_height[0] = pCar->ride_height + rear_give + pExtra_rear_height; |
||
| 6875 | pCar->susp_height[1] = pCar->ride_height + front_give + pExtra_front_height; |
||
| 6876 | |||
| 6877 | pCar->bounds[0].min.v[1] = -MAX(rear_give, front_give) + -MAX(pExtra_rear_height, pExtra_front_height); |
||
| 6878 | pCar->bounds[0].min.v[1] /= WORLD_SCALE; |
||
| 6879 | |||
| 6880 | #undef UNK_SUSPENION_FACTOR |
||
| 6881 | } |
||
| 6882 | |||
| 6883 | // IDA: int __usercall TestForCarInSensiblePlace@<EAX>(tCar_spec *car@<EAX>) |
||
| 6884 | int TestForCarInSensiblePlace(tCar_spec* car) { |
||
| 6885 | //br_bounds bnds; // Pierre-Marie Baty -- unused variable |
||
| 6886 | //br_matrix34 mat; // Pierre-Marie Baty -- unused variable |
||
| 6887 | br_matrix34* mat1; |
||
| 6888 | br_matrix34* mat2; |
||
| 6889 | int i; |
||
| 6890 | //int j; // Pierre-Marie Baty -- unused variable |
||
| 6891 | int k; |
||
| 6892 | tCollision_info* c2; |
||
| 6893 | tCollision_info* car_info; |
||
| 6894 | br_vector3 sep; |
||
| 6895 | br_vector3 tv; |
||
| 6896 | br_vector3 tv2; |
||
| 6897 | LOG_TRACE("(%p)", car); |
||
| 6898 | |||
| 6899 | car_info = (tCollision_info*)car; |
||
| 6900 | if (!gProgram_state.racing) { |
||
| 6901 | return 1; |
||
| 6902 | } |
||
| 6903 | mat1 = &car_info->car_master_actor->t.t.mat; |
||
| 6904 | if (!gDoing_physics) { |
||
| 6905 | BrVector3Scale((br_vector3*)mat1->m[3], (br_vector3*)mat1->m[3], WORLD_SCALE); |
||
| 6906 | } |
||
| 6907 | GetFacesInBox(car_info); |
||
| 6908 | BrMatrix34ApplyP(&car_info->pos, &car_info->cmpos, mat1); |
||
| 6909 | BrVector3InvScale(&car_info->pos, &car_info->pos, WORLD_SCALE); |
||
| 6910 | k = CollCheck(car_info, -2.f); |
||
| 6911 | if (!k) { |
||
| 6912 | if (gNum_active_non_cars + gNum_active_cars != gNum_cars_and_non_cars) { |
||
| 6913 | GetNonCars(); |
||
| 6914 | } |
||
| 6915 | for (i = 0; i < gNum_cars_and_non_cars; i++) { |
||
| 6916 | c2 = (tCollision_info*)gActive_car_list[i]; |
||
| 6917 | if (car_info != c2) { |
||
| 6918 | mat2 = &c2->car_master_actor->t.t.mat; |
||
| 6919 | BrVector3Scale((br_vector3*)mat2->m[3], (br_vector3*)mat2->m[3], WORLD_SCALE); |
||
| 6920 | BrVector3Sub(&sep, (br_vector3*)mat1->m[3], (br_vector3*)mat2->m[3]); |
||
| 6921 | if (BrVector3LengthSquared(&sep) <= 100.0) { |
||
| 6922 | k += TestOldMats(car_info, c2, 0); |
||
| 6923 | k += TestOldMats(c2, car_info, 0); |
||
| 6924 | } |
||
| 6925 | if (k != 0) { |
||
| 6926 | BrMatrix34ApplyP(&tv, &car_info->cmpos, mat1); |
||
| 6927 | BrMatrix34ApplyP(&tv2, &c2->cmpos, mat2); |
||
| 6928 | BrVector3Sub(&tv, &tv2, &tv); |
||
| 6929 | BrMatrix34TApplyV(&car_info->old_point, &tv, mat1); |
||
| 6930 | BrVector3Normalise(&car_info->old_norm, &car_info->old_point); |
||
| 6931 | BrVector3Negate(&car_info->old_norm, &car_info->old_norm); |
||
| 6932 | } |
||
| 6933 | BrVector3InvScale((br_vector3*)mat2->m[3], (br_vector3*)mat2->m[3], WORLD_SCALE); |
||
| 6934 | if (k != 0) { |
||
| 6935 | break; |
||
| 6936 | } |
||
| 6937 | } |
||
| 6938 | } |
||
| 6939 | } |
||
| 6940 | if (!gDoing_physics) { |
||
| 6941 | BrVector3InvScale((br_vector3*)mat1->m[3], (br_vector3*)mat1->m[3], WORLD_SCALE); |
||
| 6942 | } |
||
| 6943 | if (k != 0) { |
||
| 6944 | return 0; |
||
| 6945 | } else { |
||
| 6946 | return -1; |
||
| 6947 | } |
||
| 6948 | } |
||
| 6949 | |||
| 6950 | // IDA: int __usercall TestOldMats@<EAX>(tCollision_info *c1@<EAX>, tCollision_info *c2@<EDX>, int newmats@<EBX>) |
||
| 6951 | int TestOldMats(tCollision_info* c1, tCollision_info* c2, int newmats) { |
||
| 6952 | br_vector3 p1; |
||
| 6953 | br_vector3 p2; |
||
| 6954 | br_vector3 tp1; |
||
| 6955 | //br_vector3 tp2; // Pierre-Marie Baty -- unused variable |
||
| 6956 | //br_vector3 tp3; // Pierre-Marie Baty -- unused variable |
||
| 6957 | br_vector3 hp1; |
||
| 6958 | //br_vector3 hp2; // Pierre-Marie Baty -- unused variable |
||
| 6959 | //br_vector3 hp3; // Pierre-Marie Baty -- unused variable |
||
| 6960 | //br_vector3 shp1; // Pierre-Marie Baty -- unused variable |
||
| 6961 | //br_vector3 shp2; // Pierre-Marie Baty -- unused variable |
||
| 6962 | br_vector3 edge; |
||
| 6963 | //int plane1; // Pierre-Marie Baty -- unused variable |
||
| 6964 | //int plane2; // Pierre-Marie Baty -- unused variable |
||
| 6965 | //int plane3; // Pierre-Marie Baty -- unused variable |
||
| 6966 | //br_scalar ts; // Pierre-Marie Baty -- unused variable |
||
| 6967 | int i; |
||
| 6968 | int j; |
||
| 6969 | int n; |
||
| 6970 | br_bounds* b1; |
||
| 6971 | br_bounds* b2; |
||
| 6972 | br_matrix34 invmat1; |
||
| 6973 | br_matrix34 mat21; |
||
| 6974 | LOG_TRACE("(%p, %p, %d)", c1, c2, newmats); |
||
| 6975 | |||
| 6976 | n = 0; |
||
| 6977 | b1 = &c1->bounds[1]; |
||
| 6978 | b2 = &c2->bounds[1]; |
||
| 6979 | if (newmats) { |
||
| 6980 | BrMatrix34LPInverse(&invmat1, &c1->car_master_actor->t.t.mat); |
||
| 6981 | BrMatrix34Mul(&mat21, &c2->car_master_actor->t.t.mat, &invmat1); |
||
| 6982 | } else { |
||
| 6983 | BrMatrix34LPInverse(&invmat1, &c1->oldmat); |
||
| 6984 | BrMatrix34Mul(&mat21, &c2->oldmat, &invmat1); |
||
| 6985 | } |
||
| 6986 | for (i = 0; i < 4; i++) { |
||
| 6987 | if (i == 3) { |
||
| 6988 | BrVector3Copy(&edge, &b2->min); |
||
| 6989 | } else { |
||
| 6990 | BrVector3Copy(&edge, &b2->max); |
||
| 6991 | edge.v[i] = b2->min.v[i]; |
||
| 6992 | } |
||
| 6993 | for (j = 0; j < 3; j++) { |
||
| 6994 | BrVector3Copy(&tp1, &edge); |
||
| 6995 | if (b2->max.v[j] == tp1.v[j]) { |
||
| 6996 | tp1.v[j] = b2->min.v[j]; |
||
| 6997 | } else { |
||
| 6998 | tp1.v[j] = b2->max.v[j]; |
||
| 6999 | } |
||
| 7000 | BrMatrix34ApplyP(&p1, &edge, &mat21); |
||
| 7001 | BrMatrix34ApplyP(&p2, &tp1, &mat21); |
||
| 7002 | if (LineBoxColl(&p1, &p2, b1, &hp1)) { |
||
| 7003 | n++; |
||
| 7004 | } |
||
| 7005 | } |
||
| 7006 | } |
||
| 7007 | return n; |
||
| 7008 | } |
||
| 7009 | |||
| 7010 | // IDA: int __usercall PullActorFromWorld@<EAX>(br_actor *pActor@<EAX>) |
||
| 7011 | int PullActorFromWorld(br_actor* pActor) { |
||
| 7012 | LOG_TRACE("(%p)", pActor); |
||
| 7013 | |||
| 7014 | if (gDoing_physics) { |
||
| 7015 | return DoPullActorFromWorld(pActor); |
||
| 7016 | } |
||
| 7017 | return 0; |
||
| 7018 | } |
||
| 7019 | |||
| 7020 | // IDA: int __usercall DoPullActorFromWorld@<EAX>(br_actor *pActor@<EAX>) |
||
| 7021 | int DoPullActorFromWorld(br_actor* pActor) { |
||
| 7022 | int num; |
||
| 7023 | int i; |
||
| 7024 | tCollision_info* c; |
||
| 7025 | tNon_car_spec* non_car; |
||
| 7026 | LOG_TRACE("(%p)", pActor); |
||
| 7027 | |||
| 7028 | non_car = NULL; |
||
| 7029 | num = 10 * (pActor->identifier[1] - '0') + 1 * (pActor->identifier[2] - '0'); |
||
| 7030 | if (gNon_car_spec_list[num]) { |
||
| 7031 | non_car = &gProgram_state.non_cars[gNon_car_spec_list[num] + 4]; |
||
| 7032 | } |
||
| 7033 | if (non_car && non_car->collision_info.driver == eDriver_non_car) { |
||
| 7034 | non_car = gProgram_state.non_cars; |
||
| 7035 | for (i = 0; i < NONCAR_UNUSED_SLOTS; i++) { |
||
| 7036 | if (non_car->collision_info.driver == eDriver_non_car_unused_slot) { |
||
| 7037 | break; |
||
| 7038 | } |
||
| 7039 | non_car++; |
||
| 7040 | } |
||
| 7041 | if (i == NONCAR_UNUSED_SLOTS) { |
||
| 7042 | non_car = NULL; |
||
| 7043 | } else { |
||
| 7044 | memcpy(non_car, &gProgram_state.non_cars[gNon_car_spec_list[num] + NONCAR_UNUSED_SLOTS - 1], sizeof(tNon_car_spec)); |
||
| 7045 | } |
||
| 7046 | } |
||
| 7047 | if (non_car != NULL) { |
||
| 7048 | pActor->type_data = non_car; |
||
| 7049 | c = &non_car->collision_info; |
||
| 7050 | c->driver = eDriver_non_car; |
||
| 7051 | c->doing_nothing_flag = 1; |
||
| 7052 | BrActorRemove(pActor); |
||
| 7053 | BrActorAdd(gNon_track_actor, pActor); |
||
| 7054 | c->car_master_actor = pActor; |
||
| 7055 | c->car_ID = 100 * (pActor->identifier[5] - '0') + 10 * (pActor->identifier[6] - '0') + 1 * (pActor->identifier[7] - '0'); |
||
| 7056 | gActive_non_car_list[gNum_active_non_cars] = non_car; |
||
| 7057 | gNum_active_non_cars++; |
||
| 7058 | gActive_car_list[gNum_cars_and_non_cars] = (tCar_spec*)non_car; |
||
| 7059 | gNum_cars_and_non_cars++; |
||
| 7060 | GetNewBoundingBox(&c->bounds_world_space, c->bounds, &pActor->t.t.mat); |
||
| 7061 | non_car->collision_info.bounds_ws_type = eBounds_ws; |
||
| 7062 | InitialiseNonCar(non_car); |
||
| 7063 | ResetCarSpecialVolume((tCollision_info*)non_car); |
||
| 7064 | if (gDoing_physics) { |
||
| 7065 | BrVector3Scale((br_vector3*)&pActor->t.t.mat.m[3][0], (br_vector3*)&pActor->t.t.mat.m[3][0], WORLD_SCALE); |
||
| 7066 | } |
||
| 7067 | BrMatrix34Copy(&c->oldmat, &pActor->t.t.mat); |
||
| 7068 | if (!gDoing_physics) { |
||
| 7069 | BrVector3Scale((br_vector3*)&c->oldmat.m[3][0], (br_vector3*)&c->oldmat.m[3][0], WORLD_SCALE); |
||
| 7070 | } |
||
| 7071 | PipeSingleNonCar((tCollision_info*)non_car); |
||
| 7072 | return 1; |
||
| 7073 | } else { |
||
| 7074 | pActor->identifier[1] = 'x'; |
||
| 7075 | return 0; |
||
| 7076 | } |
||
| 7077 | } |
||
| 7078 | |||
| 7079 | // IDA: void __usercall CheckForDeAttachmentOfNonCars(tU32 pTime@<EAX>) |
||
| 7080 | void CheckForDeAttachmentOfNonCars(tU32 pTime) { |
||
| 7081 | static tU32 total_time; |
||
| 7082 | br_bounds bnds; |
||
| 7083 | int i; |
||
| 7084 | int j; |
||
| 7085 | int last_free_slot; |
||
| 7086 | int drop; |
||
| 7087 | tCollision_info* c; |
||
| 7088 | tCollision_info* c2; |
||
| 7089 | br_actor* actor; |
||
| 7090 | tU8 cx; |
||
| 7091 | tU8 cz; |
||
| 7092 | tTrack_spec* track_spec; |
||
| 7093 | br_matrix34 mat; |
||
| 7094 | LOG_TRACE("(%d)", pTime); |
||
| 7095 | |||
| 7096 | if (gNum_active_non_cars == 0) { |
||
| 7097 | return; |
||
| 7098 | } |
||
| 7099 | |||
| 7100 | last_free_slot = 0; |
||
| 7101 | track_spec = &gProgram_state.track_spec; |
||
| 7102 | |||
| 7103 | StartPipingSession(ePipe_chunk_non_car); |
||
| 7104 | for (i = 0; i < gNum_active_non_cars; i++) { |
||
| 7105 | if (!gActive_non_car_list[i]->collision_info.doing_nothing_flag) { |
||
| 7106 | AddNonCarToPipingSession(gActive_non_car_list[i]->collision_info.car_ID, gActive_non_car_list[i]->collision_info.car_master_actor); |
||
| 7107 | } |
||
| 7108 | } |
||
| 7109 | EndPipingSession(); |
||
| 7110 | |||
| 7111 | total_time += pTime; |
||
| 7112 | if (total_time < 1000) { |
||
| 7113 | return; |
||
| 7114 | } |
||
| 7115 | total_time = 0; |
||
| 7116 | for (i = 0; i < gNum_active_non_cars; i++) { |
||
| 7117 | c = &gActive_non_car_list[i]->collision_info; |
||
| 7118 | if (c->car_master_actor->t.t.translate.t.v[1] < gMin_world_y) { |
||
| 7119 | c->doing_nothing_flag = 1; |
||
| 7120 | } |
||
| 7121 | if (TestForNan(&c->car_master_actor->t.t.mat.m[3][1])) { |
||
| 7122 | BrVector3Set(&c->omega, 0.0f, 0.0f, 0.0f); |
||
| 7123 | BrMatrix34Identity(&c->car_master_actor->t.t.mat); |
||
| 7124 | BrVector3Set(&c->car_master_actor->t.t.translate.t, 2000.f, 0.f, 0.f); |
||
| 7125 | c->doing_nothing_flag = 1; |
||
| 7126 | } |
||
| 7127 | actor = c->car_master_actor; |
||
| 7128 | gActive_non_car_list[last_free_slot] = gActive_non_car_list[i]; |
||
| 7129 | if (c->doing_nothing_flag) { |
||
| 7130 | drop = 1; |
||
| 7131 | for (j = 0; j < gNum_cars_and_non_cars; j++) { |
||
| 7132 | c2 = (tCollision_info*)gActive_car_list[j]; |
||
| 7133 | if (c2 != c && !c2->doing_nothing_flag) { |
||
| 7134 | BrMatrix34Mul(&mat, &actor->t.t.mat, &c2->last_box_inv_mat); |
||
| 7135 | GetNewBoundingBox(&bnds, &actor->model->bounds, &mat); |
||
| 7136 | if (c2->last_box.max.v[0] >= bnds.min.v[0] |
||
| 7137 | && c2->last_box.max.v[1] >= bnds.min.v[1] |
||
| 7138 | && c2->last_box.max.v[2] >= bnds.min.v[2] |
||
| 7139 | && c2->last_box.min.v[0] <= bnds.max.v[0] |
||
| 7140 | && c2->last_box.min.v[1] <= bnds.max.v[1] |
||
| 7141 | && c2->last_box.min.v[2] <= bnds.max.v[2]) { |
||
| 7142 | drop = 0; |
||
| 7143 | break; |
||
| 7144 | } |
||
| 7145 | } |
||
| 7146 | } |
||
| 7147 | if (drop) { |
||
| 7148 | BrActorRemove(actor); |
||
| 7149 | c->driver = eDriver_non_car_unused_slot; |
||
| 7150 | last_free_slot--; |
||
| 7151 | XZToColumnXZ(&cx, &cz, actor->t.t.mat.m[3][0], actor->t.t.mat.m[3][2], track_spec); |
||
| 7152 | if (track_spec->columns[cz][cx] != NULL) { |
||
| 7153 | BrActorAdd(track_spec->columns[cz][cx], actor); |
||
| 7154 | } else { |
||
| 7155 | BrActorAdd(gTrack_actor, actor); |
||
| 7156 | } |
||
| 7157 | } |
||
| 7158 | } |
||
| 7159 | last_free_slot++; |
||
| 7160 | } |
||
| 7161 | gNum_active_non_cars = last_free_slot; |
||
| 7162 | } |
||
| 7163 | |||
| 7164 | // IDA: void __usercall AdjustNonCar(br_actor *pActor@<EAX>, br_matrix34 *pMat@<EDX>) |
||
| 7165 | void AdjustNonCar(br_actor* pActor, br_matrix34* pMat) { |
||
| 7166 | tU8 cx; |
||
| 7167 | tU8 cz; |
||
| 7168 | tTrack_spec* track_spec; |
||
| 7169 | LOG_TRACE("(%p, %p)", pActor, pMat); |
||
| 7170 | |||
| 7171 | track_spec = &gProgram_state.track_spec; |
||
| 7172 | BrMatrix34Copy(&pActor->t.t.mat, pMat); |
||
| 7173 | if (pActor->parent != gNon_track_actor) { |
||
| 7174 | XZToColumnXZ(&cx, &cz, pActor->t.t.translate.t.v[0], pActor->t.t.translate.t.v[2], track_spec); |
||
| 7175 | if (track_spec->columns[cz][cx] != pActor->parent && track_spec->columns[cz][cx] != NULL) { |
||
| 7176 | BrActorRemove(pActor); |
||
| 7177 | BrActorAdd(track_spec->columns[cz][cx], pActor); |
||
| 7178 | } |
||
| 7179 | } |
||
| 7180 | } |
||
| 7181 | |||
| 7182 | // IDA: void __usercall PipeSingleNonCar(tCollision_info *c@<EAX>) |
||
| 7183 | void PipeSingleNonCar(tCollision_info* c) { |
||
| 7184 | LOG_TRACE("(%p)", c); |
||
| 7185 | |||
| 7186 | StartPipingSession(ePipe_chunk_non_car); |
||
| 7187 | if (gDoing_physics) { |
||
| 7188 | BrVector3InvScale(&c->car_master_actor->t.t.translate.t, &c->car_master_actor->t.t.translate.t, WORLD_SCALE); |
||
| 7189 | } |
||
| 7190 | AddNonCarToPipingSession(c->car_ID, c->car_master_actor); |
||
| 7191 | if (gDoing_physics) { |
||
| 7192 | BrVector3Scale(&c->car_master_actor->t.t.translate.t, &c->car_master_actor->t.t.translate.t, WORLD_SCALE); |
||
| 7193 | } |
||
| 7194 | EndPipingSession(); |
||
| 7195 | } |
||
| 7196 | |||
| 7197 | // IDA: int __usercall GetPrecalculatedFacesUnderCar@<EAX>(tCar_spec *pCar@<EAX>, tFace_ref **pFace_refs@<EDX>) |
||
| 7198 | int GetPrecalculatedFacesUnderCar(tCar_spec* pCar, tFace_ref** pFace_refs) { |
||
| 7199 | LOG_TRACE("(%p, %p)", pCar, pFace_refs); |
||
| 7200 | |||
| 7201 | if (pCar->box_face_ref == gFace_num__car |
||
| 7202 | || (pCar->box_face_ref == gFace_num__car - 1 && pCar->box_face_start > gFace_count)) { |
||
| 7203 | *pFace_refs = &gFace_list__car[pCar->box_face_start]; |
||
| 7204 | return pCar->box_face_end - pCar->box_face_start; |
||
| 7205 | } |
||
| 7206 | return 0; |
||
| 7207 | } |
||
| 7208 | |||
| 7209 | // IDA: br_material* __cdecl SomeNearbyMaterial() |
||
| 7210 | br_material* SomeNearbyMaterial(void) { |
||
| 7211 | LOG_TRACE("()"); |
||
| 7212 | NOT_IMPLEMENTED(); |
||
| 7213 | } |