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 | } |