Rev 1 | Rev 20 | Go to most recent revision | 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" |
||
18 | pmbaty | 4 | #include "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" |
||
18 | pmbaty | 32 | #include "structur.h" |
1 | pmbaty | 33 | #include "trig.h" |
34 | #include "utility.h" |
||
35 | #include "world.h" |
||
36 | #include <math.h> |
||
37 | #include <stdlib.h> |
||
38 | |||
39 | int gDoing_physics = 0; |
||
40 | br_scalar gDt = 0.f; |
||
41 | // suffix added to avoid duplicate symbol |
||
42 | int gCollision_detection_on__car = 1; |
||
43 | // suffix added to avoid duplicate symbol |
||
44 | br_vector3 gGround_normal__car = { { 0.0f, 1.0f, 0.0f } }; |
||
45 | // suffix added to avoid duplicate symbol |
||
46 | void (*ControlCar[6])(tCar_spec*, br_scalar) = { |
||
47 | &ControlCar1, |
||
48 | &ControlCar2, |
||
49 | &ControlCar3, |
||
50 | &ControlCar4, |
||
51 | &ControlCar5, |
||
52 | NULL, |
||
53 | }; |
||
54 | int gControl__car = 3; // suffix added to avoid duplicate symbol |
||
55 | int gFace_num__car = 1; // suffix added to avoid duplicate symbol |
||
56 | br_angle gOld_yaw__car = 0; // suffix added to avoid duplicate symbol |
||
57 | br_angle gOld_zoom = 0; |
||
58 | br_vector3 gCamera_pos_before_collide = { { 0 } }; |
||
59 | int gMetal_crunch_sound_id__car[5] = { |
||
60 | // suffix added to avoid duplicate symbol |
||
61 | 5000, |
||
62 | 5001, |
||
63 | 5002, |
||
64 | 5003, |
||
65 | 5004, |
||
66 | }; |
||
67 | int gMetal_scrape_sound_id__car[3] = { |
||
68 | // suffix added to avoid duplicate symbol |
||
69 | 5010, |
||
70 | 5011, |
||
71 | 5012, |
||
72 | }; |
||
73 | int gCar_car_collisions = 1; |
||
74 | int gFreeze_mechanics = 0; |
||
75 | tU32 gLast_cunning_stunt = 0; |
||
76 | tU32 gWild_start = 0; |
||
77 | tU32 gQuite_wild_start = 0; |
||
78 | tU32 gQuite_wild_end = 0; |
||
79 | tU32 gOn_me_wheels_start = 0; |
||
80 | int gWoz_upside_down_at_all = 0; |
||
81 | tS3_sound_tag gSkid_tag[2] = { 0, 0 }; |
||
82 | tCar_spec* gLast_car_to_skid[2] = { NULL, NULL }; |
||
83 | int gEliminate_faces = 0; |
||
84 | br_vector3 gZero_v__car = { { 0 } }; // suffix added to avoid duplicate symbol |
||
85 | tU32 gSwitch_time = 0; |
||
86 | tSave_camera gSave_camera[2]; |
||
87 | tU32 gLast_mechanics_time; |
||
88 | int gOpponent_viewing_mode; |
||
89 | int gNet_player_to_view_index = -1; |
||
90 | int gDouble_pling_water = 0; |
||
91 | int gStop_opponents_moving = 0; |
||
92 | float gDefensive_powerup_factor[6] = { 1.0f, 0.825f, 0.65f, 0.475f, 0.3f, 0.01f }; |
||
93 | float gOffensive_powerup_factor[6] = { 1.0f, 1.5f, 2.0f, 3.0f, 5.0f, 10.0f }; |
||
94 | float gEngine_powerup_factor[6] = { 1.3f, 1.9f, 2.5f, 3.2f, 4.0f, 10.0f }; |
||
95 | br_angle gPanning_camera_angle; |
||
96 | br_scalar gPanning_camera_height; |
||
97 | int gFace_count; |
||
98 | float gCar_simplification_factor[2][5] = { |
||
99 | { 10.0f, 3.0f, 1.5f, 0.75f, 0.0f }, |
||
100 | { 10.0f, 5.0f, 2.5f, 1.5f, 0.0f } |
||
101 | }; |
||
102 | int gCar_simplification_level = 0; |
||
103 | int gNum_active_non_cars = 0; |
||
104 | int gCamera_has_collided = 0; |
||
105 | tFace_ref gFace_list__car[150]; // suffix added to avoid duplicate symbol |
||
106 | tNon_car_spec* gActive_non_car_list[50]; |
||
107 | int gOver_shoot; |
||
108 | br_scalar gMin_world_y; |
||
109 | br_scalar gAccel; |
||
110 | br_vector3 gAverage_grid_position; |
||
111 | br_actor* gPed_actor; |
||
112 | int gCollision_count; |
||
113 | int gCamera_frozen; |
||
114 | int gMaterial_index; |
||
115 | int gInTheSea; |
||
116 | int gCamera_mode; |
||
117 | br_scalar gOur_yaw__car; // suffix added to avoid duplicate symbol |
||
118 | br_scalar gGravity__car; // suffix added to avoid duplicate symbol |
||
119 | br_vector3 gNew_ground_normal__car; // suffix added to avoid duplicate symbol |
||
120 | char gNon_car_spec_list[100]; |
||
121 | tU32 gMechanics_time_sync; |
||
122 | int gNum_cars_and_non_cars; |
||
123 | |||
124 | // IDA: void __usercall DamageUnit(tCar_spec *pCar@<EAX>, int pUnit_type@<EDX>, int pDamage_amount@<EBX>) |
||
125 | void DamageUnit(tCar_spec* pCar, int pUnit_type, int pDamage_amount) { |
||
126 | tDamage_unit* the_damage; |
||
127 | LOG_TRACE("(%p, %d, %d)", pCar, pUnit_type, pDamage_amount); |
||
128 | |||
129 | if (pDamage_amount > 0) { |
||
130 | the_damage = &pCar->damage_units[pUnit_type]; |
||
131 | the_damage->damage_level += pDamage_amount; |
||
132 | if (the_damage->damage_level >= 100) { |
||
133 | the_damage->damage_level = 99; |
||
134 | } |
||
135 | } |
||
136 | } |
||
137 | |||
138 | // IDA: void __usercall DamageUnitWithSmoke(tCar_spec *pCar@<EAX>, int pUnit_type@<EDX>, int pDamage_amount@<EBX>) |
||
139 | void DamageUnitWithSmoke(tCar_spec* pCar, int pUnit_type, int pDamage_amount) { |
||
140 | LOG_TRACE("(%p, %d, %d)", pCar, pUnit_type, pDamage_amount); |
||
141 | |||
142 | DamageUnit(pCar, pUnit_type, pDamage_amount); |
||
143 | SortOutSmoke(pCar); |
||
144 | } |
||
145 | |||
146 | // IDA: void __usercall DamageEngine(int pDamage_amount@<EAX>) |
||
147 | void DamageEngine(int pDamage_amount) { |
||
148 | LOG_TRACE("(%d)", pDamage_amount); |
||
149 | |||
150 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_engine, pDamage_amount); |
||
151 | } |
||
152 | |||
153 | // IDA: void __usercall DamageTrans(int pDamage_amount@<EAX>) |
||
154 | void DamageTrans(int pDamage_amount) { |
||
155 | LOG_TRACE("(%d)", pDamage_amount); |
||
156 | |||
157 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_transmission, pDamage_amount); |
||
158 | } |
||
159 | |||
160 | // IDA: void __usercall DamageSteering(int pDamage_amount@<EAX>) |
||
161 | void DamageSteering(int pDamage_amount) { |
||
162 | LOG_TRACE("(%d)", pDamage_amount); |
||
163 | |||
164 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_steering, pDamage_amount); |
||
165 | } |
||
166 | |||
167 | // IDA: void __usercall DamageLFWheel(int pDamage_amount@<EAX>) |
||
168 | void DamageLFWheel(int pDamage_amount) { |
||
169 | LOG_TRACE("(%d)", pDamage_amount); |
||
170 | |||
171 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_lf_wheel, pDamage_amount); |
||
172 | } |
||
173 | |||
174 | // IDA: void __usercall DamageLFBrake(int pDamage_amount@<EAX>) |
||
175 | void DamageLFBrake(int pDamage_amount) { |
||
176 | LOG_TRACE("(%d)", pDamage_amount); |
||
177 | |||
178 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_lf_brake, pDamage_amount); |
||
179 | } |
||
180 | |||
181 | // IDA: void __usercall DamageLRBrake(int pDamage_amount@<EAX>) |
||
182 | void DamageLRBrake(int pDamage_amount) { |
||
183 | LOG_TRACE("(%d)", pDamage_amount); |
||
184 | |||
185 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_lr_brake, pDamage_amount); |
||
186 | } |
||
187 | |||
188 | // IDA: void __usercall DamageLRWheel(int pDamage_amount@<EAX>) |
||
189 | void DamageLRWheel(int pDamage_amount) { |
||
190 | LOG_TRACE("(%d)", pDamage_amount); |
||
191 | |||
192 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_lr_wheel, pDamage_amount); |
||
193 | } |
||
194 | |||
195 | // IDA: void __usercall DamageRFWheel(int pDamage_amount@<EAX>) |
||
196 | void DamageRFWheel(int pDamage_amount) { |
||
197 | LOG_TRACE("(%d)", pDamage_amount); |
||
198 | |||
199 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_rf_wheel, pDamage_amount); |
||
200 | } |
||
201 | |||
202 | // IDA: void __usercall DamageRFBrake(int pDamage_amount@<EAX>) |
||
203 | void DamageRFBrake(int pDamage_amount) { |
||
204 | LOG_TRACE("(%d)", pDamage_amount); |
||
205 | |||
206 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_rf_brake, pDamage_amount); |
||
207 | } |
||
208 | |||
209 | // IDA: void __usercall DamageRRBrake(int pDamage_amount@<EAX>) |
||
210 | void DamageRRBrake(int pDamage_amount) { |
||
211 | LOG_TRACE("(%d)", pDamage_amount); |
||
212 | |||
213 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_rr_brake, pDamage_amount); |
||
214 | } |
||
215 | |||
216 | // IDA: void __usercall DamageRRWheel(int pDamage_amount@<EAX>) |
||
217 | void DamageRRWheel(int pDamage_amount) { |
||
218 | LOG_TRACE("(%d)", pDamage_amount); |
||
219 | |||
220 | DamageUnitWithSmoke(&gProgram_state.current_car, eDamage_rr_wheel, pDamage_amount); |
||
221 | } |
||
222 | |||
223 | // IDA: void __usercall CalculatePlaneNormal(br_vector3 *pP1@<EAX>, br_vector3 *pP2@<EDX>, br_vector3 *pP3@<EBX>, br_vector3 *pNormal@<ECX>) |
||
224 | void CalculatePlaneNormal(br_vector3* pP1, br_vector3* pP2, br_vector3* pP3, br_vector3* pNormal) { |
||
225 | //br_vector3 p0; // Pierre-Marie Baty -- unused variable |
||
226 | //br_vector3 p1; // Pierre-Marie Baty -- unused variable |
||
227 | //br_vector3 cross_product; // Pierre-Marie Baty -- unused variable |
||
228 | //br_vector3 temp_vector; // Pierre-Marie Baty -- unused variable |
||
229 | LOG_TRACE("(%p, %p, %p, %p)", pP1, pP2, pP3, pNormal); |
||
230 | NOT_IMPLEMENTED(); |
||
231 | } |
||
232 | |||
233 | // IDA: void __usercall CalculateGroundNormal(br_model *pThe_model@<EAX>, int pFace_index@<EDX>) |
||
234 | void CalculateGroundNormal(br_model* pThe_model, int pFace_index) { |
||
235 | LOG_TRACE("(%p, %d)", pThe_model, pFace_index); |
||
236 | NOT_IMPLEMENTED(); |
||
237 | } |
||
238 | |||
239 | // IDA: void __cdecl ChangeYCoordinate(br_scalar pNew_y, tU32 pTime_taken, br_model *pThe_model, int pFace_index) |
||
240 | void ChangeYCoordinate(br_scalar pNew_y, tU32 pTime_taken, br_model* pThe_model, int pFace_index) { |
||
241 | //br_scalar y_change; // Pierre-Marie Baty -- unused variable |
||
242 | //br_transform new_transform; // Pierre-Marie Baty -- unused variable |
||
243 | //br_vector3 side_window; // Pierre-Marie Baty -- unused variable |
||
244 | LOG_TRACE("(%f, %d, %p, %d)", pNew_y, pTime_taken, pThe_model, pFace_index); |
||
245 | NOT_IMPLEMENTED(); |
||
246 | } |
||
247 | |||
248 | // IDA: void __usercall SwitchCarActor(tCar_spec *pCar_spec@<EAX>, int pModel_index@<EDX>) |
||
249 | void SwitchCarActor(tCar_spec* pCar_spec, int pModel_index) { |
||
250 | int i; |
||
251 | LOG_TRACE("(%p, %d)", pCar_spec, pModel_index); |
||
252 | |||
253 | for (i = 0; i < pCar_spec->car_actor_count; i++) { |
||
254 | if (i == pModel_index) { |
||
255 | pCar_spec->car_model_actors[i].actor->render_style = BR_RSTYLE_FACES; |
||
256 | } else { |
||
257 | pCar_spec->car_model_actors[i].actor->render_style = BR_RSTYLE_NONE; |
||
258 | } |
||
259 | } |
||
260 | pCar_spec->current_car_actor = pModel_index; |
||
261 | } |
||
262 | |||
263 | // IDA: void __usercall InitialiseCar2(tCar_spec *pCar@<EAX>, int pClear_disabled_flag@<EDX>) |
||
264 | void InitialiseCar2(tCar_spec* pCar, int pClear_disabled_flag) { |
||
265 | int index; |
||
266 | int j; |
||
267 | //int cat; // Pierre-Marie Baty -- unused variable |
||
268 | //int car_count; // Pierre-Marie Baty -- unused variable |
||
269 | br_actor* car_actor; |
||
270 | //br_angle initial_yaw; // Pierre-Marie Baty -- unused variable |
||
271 | //br_scalar nearest_y_above; // Pierre-Marie Baty -- unused variable |
||
272 | //br_scalar nearest_y_below; // Pierre-Marie Baty -- unused variable |
||
273 | //br_scalar speed; // Pierre-Marie Baty -- unused variable |
||
274 | //int below_face_index; // Pierre-Marie Baty -- unused variable |
||
275 | //int above_face_index; // Pierre-Marie Baty -- unused variable |
||
276 | //br_model* below_model; // Pierre-Marie Baty -- unused variable |
||
277 | //br_model* above_model; // Pierre-Marie Baty -- unused variable |
||
278 | //br_vector3 grid_offset; // Pierre-Marie Baty -- unused variable |
||
279 | //br_matrix34 initial_yaw_matrix; // Pierre-Marie Baty -- unused variable |
||
280 | br_matrix34 safe_position; |
||
281 | LOG_TRACE("(%p, %d)", pCar, pClear_disabled_flag); |
||
282 | |||
283 | PossibleService(); |
||
284 | if (pCar->disabled && pClear_disabled_flag) { |
||
285 | EnableCar(pCar); |
||
286 | } |
||
287 | car_actor = pCar->car_master_actor; |
||
288 | InitCarSkidStuff(pCar); |
||
289 | if (pCar->current_car_actor >= 0) { |
||
290 | pCar->car_model_actors[pCar->current_car_actor].actor->render_style = BR_RSTYLE_NONE; |
||
291 | } |
||
292 | SwitchCarActor(pCar, pCar->current_car_actor); |
||
293 | if (strcmp(pCar->name, "STELLA.TXT") == 0) { |
||
294 | pCar->proxy_ray_distance = 6.0f; |
||
295 | } else { |
||
296 | pCar->proxy_ray_distance = 0.0f; |
||
297 | } |
||
298 | pCar->last_special_volume = NULL; |
||
299 | pCar->auto_special_volume = NULL; |
||
300 | pCar->num_smoke_columns = 0; |
||
301 | pCar->who_last_hit_me = NULL; |
||
302 | pCar->screen_material_source = NULL; |
||
303 | if (pCar->screen_material != NULL) { |
||
304 | pCar->screen_material->colour_map = NULL; |
||
305 | pCar->screen_material->index_shade = gRender_shade_table; |
||
306 | BrMaterialUpdate(pCar->screen_material, BR_MATU_ALL); |
||
307 | } |
||
308 | if (pCar->driver == eDriver_local_human) { |
||
309 | ResetRecoveryVouchers(); |
||
310 | } |
||
311 | BrVector3SetFloat(&pCar->v, 0.0f, 0.0f, 0.0f); |
||
312 | BrVector3SetFloat(&pCar->omega, 0.0f, 0.0f, 0.0f); |
||
313 | pCar->curvature = 0.0f; |
||
314 | BrMatrix34Copy(&safe_position, &car_actor->t.t.mat); |
||
315 | if (safe_position.m[3][0] > 500.0f) { |
||
316 | safe_position.m[3][0] -= 1000.0f; |
||
317 | safe_position.m[3][1] -= 1000.0f; |
||
318 | safe_position.m[3][2] -= 1000.0f; |
||
319 | } |
||
320 | BrMatrix34Copy(&pCar->old_frame_mat, &safe_position); |
||
321 | BrMatrix34Copy(&pCar->oldmat, &safe_position); |
||
322 | BrVector3Scale((br_vector3*)pCar->oldmat.m[3], (br_vector3*)pCar->oldmat.m[3], WORLD_SCALE); |
||
323 | BrMatrix34ApplyP(&pCar->pos, &pCar->cmpos, &pCar->oldmat); |
||
324 | BrVector3InvScale(&pCar->pos, &pCar->pos, WORLD_SCALE); |
||
325 | for (j = 0; j < COUNT_OF(pCar->oldd); j++) { |
||
326 | pCar->oldd[j] = pCar->ride_height; |
||
327 | } |
||
328 | pCar->gear = 0; |
||
329 | pCar->revs = 0.f; |
||
330 | pCar->traction_control = 1; |
||
331 | BrVector3Negate(&pCar->direction, (br_vector3*)car_actor->t.t.mat.m[2]); |
||
332 | for (j = 0; j < COUNT_OF(pCar->last_safe_positions); j++) { |
||
333 | BrMatrix34Copy(&pCar->last_safe_positions[j], &safe_position); |
||
334 | } |
||
335 | pCar->message.type = 0; |
||
336 | pCar->message.time = 0; |
||
337 | pCar->dt = -1.f; |
||
338 | pCar->last_car_car_collision = 1; |
||
339 | pCar->time_to_recover = 0; |
||
340 | pCar->repair_time = 0; |
||
341 | |||
342 | switch (pCar->driver) { |
||
343 | |||
344 | case eDriver_oppo: |
||
345 | index = 0; |
||
346 | for (j = 0; j < gCurrent_race.number_of_racers; j++) { |
||
347 | if (gCurrent_race.opponent_list[j].car_spec->driver == eDriver_oppo) { |
||
348 | if (gCurrent_race.opponent_list[j].car_spec == pCar) { |
||
349 | pCar->car_ID = index + 512; |
||
350 | } |
||
351 | index++; |
||
352 | } |
||
353 | } |
||
354 | break; |
||
355 | |||
356 | case eDriver_net_human: |
||
357 | index = 0; |
||
358 | for (j = 0; j < gCurrent_race.number_of_racers; j++) { |
||
359 | if (gCurrent_race.opponent_list[j].car_spec |
||
360 | && gCurrent_race.opponent_list[j].car_spec->driver == eDriver_net_human) { |
||
361 | if (gCurrent_race.opponent_list[j].car_spec == pCar) { |
||
362 | pCar->car_ID = index + 256; |
||
363 | } |
||
364 | index++; |
||
365 | } |
||
366 | } |
||
367 | break; |
||
368 | |||
369 | case eDriver_local_human: |
||
370 | pCar->car_ID = 0; |
||
371 | break; |
||
372 | |||
373 | default: |
||
374 | LOG_WARN("Case %d not handled", pCar->driver); |
||
375 | break; |
||
376 | } |
||
377 | PossibleService(); |
||
378 | pCar->box_face_ref = gFace_num__car - 2; |
||
379 | pCar->doing_nothing_flag = 0; |
||
380 | pCar->end_steering_damage_effect = 0; |
||
381 | pCar->end_trans_damage_effect = 0; |
||
382 | pCar->wheel_dam_offset[0] = 0.f; |
||
383 | pCar->wheel_dam_offset[1] = 0.f; |
||
384 | pCar->wheel_dam_offset[2] = 0.f; |
||
385 | pCar->wheel_dam_offset[3] = 0.f; |
||
386 | pCar->shadow_intersection_flags = 0; |
||
387 | pCar->underwater_ability = 0; |
||
388 | pCar->invulnerable = 0; |
||
389 | pCar->wall_climber_mode = 0; |
||
390 | pCar->grip_multiplier = 1.f; |
||
391 | pCar->damage_multiplier = 1.f; |
||
392 | pCar->collision_mass_multiplier = 1.f; |
||
393 | pCar->engine_power_multiplier = 1.f; |
||
394 | pCar->bounce_rate = 0.f; |
||
395 | pCar->bounce_amount = 0.f; |
||
396 | pCar->knackered = 0; |
||
397 | TotallyRepairACar(pCar); |
||
398 | SetCarSuspGiveAndHeight(pCar, 1.f, 1.f, 1.f, 0.f, 0.f); |
||
399 | for (j = 0; j < COUNT_OF(pCar->powerups); ++j) { |
||
400 | pCar->powerups[j] = 0; |
||
401 | } |
||
402 | if (gNet_mode != eNet_mode_none) { |
||
403 | for (j = 0; j < COUNT_OF(pCar->power_up_levels); j++) { |
||
404 | pCar->power_up_levels[j] = 0; |
||
405 | } |
||
406 | } |
||
407 | } |
||
408 | |||
409 | // IDA: void __usercall InitialiseCar(tCar_spec *pCar@<EAX>) |
||
410 | void InitialiseCar(tCar_spec* pCar) { |
||
411 | LOG_TRACE("(%p)", pCar); |
||
412 | |||
413 | InitialiseCar2(pCar, 1); |
||
414 | } |
||
415 | |||
416 | // IDA: void __usercall InitialiseCarsEtc(tRace_info *pThe_race@<EAX>) |
||
417 | void InitialiseCarsEtc(tRace_info* pThe_race) { |
||
418 | int i; |
||
419 | int cat; |
||
420 | int car_count; |
||
421 | tCar_spec* car; |
||
422 | br_bounds bnds; |
||
423 | LOG_TRACE("(%p)", pThe_race); |
||
424 | |||
425 | gProgram_state.initial_position = pThe_race->initial_position; |
||
426 | gProgram_state.initial_yaw = pThe_race->initial_yaw; |
||
427 | BrActorToBounds(&bnds, gProgram_state.track_spec.the_actor); |
||
428 | gMin_world_y = bnds.min.v[1]; |
||
429 | gNum_active_non_cars = 0; |
||
430 | for (cat = eVehicle_self; cat <= eVehicle_not_really; cat++) { |
||
431 | if (cat == eVehicle_self) { |
||
432 | car_count = 1; |
||
433 | } else { |
||
434 | car_count = GetCarCount(cat); |
||
435 | } |
||
436 | for (i = 0; i < car_count; i++) { |
||
437 | PossibleService(); |
||
438 | if (cat == eVehicle_self) { |
||
439 | car = &gProgram_state.current_car; |
||
440 | } else { |
||
441 | car = GetCarSpec(cat, i); |
||
442 | } |
||
443 | if (cat != eVehicle_not_really) { |
||
444 | InitialiseCar(car); |
||
445 | } |
||
446 | } |
||
447 | } |
||
448 | gCamera_yaw = 0; |
||
449 | InitialiseExternalCamera(); |
||
450 | gLast_mechanics_time = 0; |
||
451 | } |
||
452 | |||
453 | // IDA: void __usercall GetAverageGridPosition(tRace_info *pThe_race@<EAX>) |
||
454 | void GetAverageGridPosition(tRace_info* pThe_race) { |
||
455 | int i; |
||
456 | br_scalar total_cars; |
||
457 | tCar_spec* car; |
||
458 | LOG_TRACE("(%p)", pThe_race); |
||
459 | |||
460 | total_cars = 0.0f; |
||
461 | BrVector3SetFloat(&gAverage_grid_position, 0.0f, 0.0f, 0.0f); |
||
462 | for (i = 0; i < pThe_race->number_of_racers; i++) { |
||
463 | car = pThe_race->opponent_list[i].car_spec; |
||
464 | BrVector3Accumulate(&gAverage_grid_position, &car->pos); |
||
465 | total_cars += 1.0f; |
||
466 | } |
||
467 | BrVector3InvScale(&gAverage_grid_position, &gAverage_grid_position, total_cars); |
||
468 | } |
||
469 | |||
470 | // IDA: void __usercall SetInitialPosition(tRace_info *pThe_race@<EAX>, int pCar_index@<EDX>, int pGrid_index@<EBX>) |
||
471 | void SetInitialPosition(tRace_info* pThe_race, int pCar_index, int pGrid_index) { |
||
472 | int place_on_grid; |
||
473 | int i; |
||
474 | int start_i; |
||
475 | int j; |
||
476 | br_actor* car_actor; |
||
477 | br_angle initial_yaw; |
||
478 | br_scalar nearest_y_above; |
||
479 | br_scalar nearest_y_below; |
||
480 | //br_scalar speed; // Pierre-Marie Baty -- unused variable |
||
481 | int below_face_index; |
||
482 | int above_face_index; |
||
483 | br_model* below_model; |
||
484 | br_model* above_model; |
||
485 | tCar_spec* car; |
||
486 | br_vector3 grid_offset; |
||
487 | br_vector3 dist; |
||
488 | br_vector3 real_pos; |
||
489 | br_matrix34 initial_yaw_matrix; |
||
490 | //br_bounds bnds; // Pierre-Marie Baty -- unused variable |
||
491 | LOG_TRACE("(%p, %d, %d)", pThe_race, pCar_index, pGrid_index); |
||
492 | |||
493 | initial_yaw = 0; |
||
494 | car_actor = pThe_race->opponent_list[pCar_index].car_spec->car_master_actor; |
||
495 | car = pThe_race->opponent_list[pCar_index].car_spec; |
||
496 | BrMatrix34Identity(&car_actor->t.t.mat); |
||
497 | place_on_grid = 1; |
||
498 | if (gNet_mode != eNet_mode_none && !gCurrent_net_game->options.grid_start && pThe_race->number_of_net_start_points != 0) { |
||
499 | start_i = i = IRandomBetween(0, pThe_race->number_of_net_start_points - 1); |
||
500 | do { |
||
501 | PossibleService(); |
||
502 | for (j = 0; j < gNumber_of_net_players; j++) { |
||
503 | if (j != pCar_index) { |
||
504 | BrVector3Copy(&real_pos, &pThe_race->opponent_list[j].car_spec->car_master_actor->t.t.translate.t); |
||
505 | if (real_pos.v[0] > 500.f) { |
||
506 | real_pos.v[0] -= 1000.f; |
||
507 | real_pos.v[1] -= 1000.f; |
||
508 | real_pos.v[2] -= 1000.f; |
||
509 | } |
||
510 | BrVector3Sub(&dist, &real_pos, &pThe_race->net_starts[i].pos); |
||
511 | if (BrVector3LengthSquared(&dist) < 16.f) { |
||
512 | break; |
||
513 | } |
||
514 | } |
||
515 | } |
||
516 | if (j == gNumber_of_net_players) { |
||
517 | BrVector3Copy(&car_actor->t.t.translate.t, &pThe_race->net_starts[i].pos); |
||
518 | initial_yaw = BrDegreeToAngle(pThe_race->net_starts[i].yaw); |
||
519 | place_on_grid = 0; |
||
520 | } |
||
521 | i++; |
||
522 | if (i == pThe_race->number_of_net_start_points) { |
||
523 | i = 0; |
||
524 | } |
||
525 | } while (start_i != i); |
||
526 | } |
||
527 | if (place_on_grid) { |
||
528 | initial_yaw = BrDegreeToAngle(pThe_race->initial_yaw); |
||
529 | BrMatrix34RotateY(&initial_yaw_matrix, initial_yaw); |
||
530 | grid_offset.v[0] = 0.0f - pGrid_index % 2; |
||
531 | grid_offset.v[1] = 0.0f; |
||
532 | grid_offset.v[2] = (br_scalar)(pGrid_index / 2) * 2.0f + (br_scalar)(pGrid_index % 2) * 0.4f; |
||
533 | BrMatrix34ApplyV(&car_actor->t.t.translate.t, &grid_offset, &initial_yaw_matrix); |
||
534 | BrVector3Accumulate(&car_actor->t.t.translate.t, &pThe_race->initial_position); |
||
535 | } |
||
536 | FindBestY( |
||
537 | &car_actor->t.t.translate.t, |
||
538 | gTrack_actor, |
||
539 | 10.0f, |
||
540 | &nearest_y_above, |
||
541 | &nearest_y_below, |
||
542 | &above_model, |
||
543 | &below_model, |
||
544 | &above_face_index, |
||
545 | &below_face_index); |
||
546 | if (nearest_y_above != 30000.0f) { |
||
547 | car_actor->t.t.translate.t.v[1] = nearest_y_above; |
||
548 | } else if (nearest_y_below != -30000.0f) { |
||
549 | car_actor->t.t.translate.t.v[1] = nearest_y_below; |
||
550 | } else { |
||
551 | car_actor->t.t.translate.t.v[1] = 0.0f; |
||
552 | } |
||
553 | BrMatrix34PreRotateY(&car_actor->t.t.mat, initial_yaw); |
||
554 | if (gNet_mode) { |
||
555 | BrMatrix34Copy( |
||
556 | &gNet_players[pThe_race->opponent_list[pCar_index].net_player_index].initial_position, |
||
557 | &car->car_master_actor->t.t.mat); |
||
558 | } |
||
559 | if (gNet_mode != eNet_mode_none && car->disabled && car_actor->t.t.translate.t.v[0] < 500.0f) { |
||
560 | DisableCar(car); |
||
561 | } |
||
562 | // Enable to start all opponent cars upside down ;) |
||
563 | // if (strstr(car->name, "EAGLE") == 0) { |
||
564 | // car_actor->t.t.translate.t.v[1] += 2; |
||
565 | // car_actor->t.t.look_up.up.v[1] = -1; |
||
566 | // } |
||
567 | } |
||
568 | |||
569 | // IDA: void __usercall SetInitialPositions(tRace_info *pThe_race@<EAX>) |
||
570 | void SetInitialPositions(tRace_info* pThe_race) { |
||
571 | int i; |
||
572 | LOG_TRACE("(%p)", pThe_race); |
||
573 | |||
574 | for (i = 0; i < pThe_race->number_of_racers; i++) { |
||
575 | SetInitialPosition(pThe_race, i, i); |
||
576 | } |
||
577 | } |
||
578 | |||
579 | // IDA: void __usercall InitialiseNonCar(tNon_car_spec *non_car@<EAX>) |
||
580 | void InitialiseNonCar(tNon_car_spec* non_car) { |
||
581 | tCollision_info* c; |
||
582 | LOG_TRACE("(%p)", non_car); |
||
583 | |||
584 | c = &non_car->collision_info; |
||
585 | BrMatrix34Copy(&c->oldmat, &c->car_master_actor->t.t.mat); |
||
586 | non_car->collision_info.box_face_ref = gFace_num__car - 2; |
||
587 | non_car->collision_info.doing_nothing_flag = 1; |
||
588 | non_car->collision_info.disabled = 0; |
||
589 | BrVector3SetFloat(&c->v, 0.0f, 0.0f, 0.0f); |
||
590 | BrVector3SetFloat(&c->omega, 0.0f, 0.0f, 0.0f); |
||
591 | BrVector3SetFloat(&c->oldomega, 0.0f, 0.0f, 0.0f); |
||
592 | non_car->collision_info.box_face_ref = gFace_num__car - 2; |
||
593 | c->collision_flag = 0; |
||
594 | c->who_last_hit_me = NULL; |
||
595 | if (c->car_master_actor->identifier[3] == '!') { |
||
596 | c->M = non_car->free_mass; |
||
597 | c->min_torque_squared = 0.0f; |
||
598 | BrVector3Copy(&c->cmpos, &non_car->free_cmpos); |
||
599 | } else { |
||
600 | c->M = non_car->attached_mass; |
||
601 | BrVector3Copy(&c->cmpos, &non_car->attached_cmpos); |
||
602 | c->min_torque_squared = non_car->min_torque_squared; |
||
603 | } |
||
604 | BrVector3Scale(&c->I, &non_car->I_over_M, c->M); |
||
605 | c->message.type = 0; |
||
606 | c->message.time = 0; |
||
607 | c->dt = -1.0f; |
||
608 | c->last_car_car_collision = 1; |
||
609 | } |
||
610 | |||
611 | // IDA: void __usercall GetFacesInBox(tCollision_info *c@<EAX>) |
||
612 | void GetFacesInBox(tCollision_info* c) { |
||
613 | tBounds bnds; |
||
614 | br_bounds new_in_old; |
||
615 | br_bounds predicted_bounds; |
||
616 | br_matrix34 mat; |
||
617 | br_matrix34 mat2; |
||
618 | br_matrix34 mat3; |
||
619 | br_matrix34 mat4; |
||
620 | br_matrix34 mat5; |
||
621 | br_matrix34 mat6; |
||
622 | br_scalar old_d; |
||
623 | int i; |
||
624 | br_bounds current_bounds; |
||
625 | LOG_TRACE("(%p)", c); |
||
626 | |||
627 | BrMatrix34Copy(&mat, &c->car_master_actor->t.t.mat); |
||
628 | BrMatrix34Copy(&mat2, &c->oldmat); |
||
629 | BrVector3InvScale((br_vector3*)mat.m[3], (br_vector3*)mat.m[3], WORLD_SCALE); |
||
630 | BrVector3InvScale((br_vector3*)mat2.m[3], (br_vector3*)mat2.m[3], WORLD_SCALE); |
||
631 | BrMatrix34LPInverse(&mat3, &mat); |
||
632 | BrMatrix34Mul(&mat4, &mat2, &mat3); |
||
633 | GetNewBoundingBox(&bnds.original_bounds, c->bounds, &mat4); |
||
634 | for (i = 0; i < 3; i++) { |
||
635 | if (bnds.original_bounds.min.v[i] > c->bounds[0].min.v[i]) { |
||
636 | bnds.original_bounds.min.v[i] = c->bounds[0].min.v[i]; |
||
637 | } |
||
638 | if (bnds.original_bounds.max.v[i] < c->bounds[0].max.v[i]) { |
||
639 | bnds.original_bounds.max.v[i] = c->bounds[0].max.v[i]; |
||
640 | } |
||
641 | bnds.original_bounds.min.v[i] -= 0.002f; |
||
642 | bnds.original_bounds.max.v[i] += 0.002f; |
||
643 | } |
||
644 | GetNewBoundingBox(&c->bounds_world_space, &bnds.original_bounds, &mat); |
||
645 | c->bounds_ws_type = eBounds_ws; |
||
646 | if ((c->box_face_ref != gFace_num__car && (c->box_face_ref != gFace_num__car - 1 || c->box_face_start <= gFace_count)) |
||
647 | || (BrMatrix34Mul(&mat5, &mat, &c->last_box_inv_mat), |
||
648 | GetNewBoundingBox(&new_in_old, &bnds.original_bounds, &mat5), |
||
649 | c->last_box.max.v[0] <= new_in_old.max.v[0]) |
||
650 | || c->last_box.max.v[1] <= new_in_old.max.v[1] |
||
651 | || c->last_box.max.v[2] <= new_in_old.max.v[2] |
||
652 | || c->last_box.min.v[0] >= new_in_old.min.v[0] |
||
653 | || c->last_box.min.v[1] >= new_in_old.min.v[1] |
||
654 | || c->last_box.min.v[2] >= new_in_old.min.v[2]) { |
||
655 | BrMatrix34Mul(&mat5, &mat4, &mat4); |
||
656 | BrMatrix34Mul(&mat6, &mat5, &mat4); |
||
657 | BrMatrix34LPInverse(&mat5, &mat6); |
||
658 | GetNewBoundingBox(&predicted_bounds, c->bounds, &mat5); |
||
659 | for (i = 0; i < 3; i++) { |
||
660 | if (bnds.original_bounds.min.v[i] > predicted_bounds.min.v[i]) { |
||
661 | bnds.original_bounds.min.v[i] = predicted_bounds.min.v[i]; |
||
662 | } |
||
663 | if (bnds.original_bounds.max.v[i] < predicted_bounds.max.v[i]) { |
||
664 | bnds.original_bounds.max.v[i] = predicted_bounds.max.v[i]; |
||
665 | } |
||
666 | bnds.original_bounds.min.v[i] -= 0.02f; |
||
667 | bnds.original_bounds.max.v[i] += 0.02f; |
||
668 | } |
||
669 | c->last_box = bnds.original_bounds; |
||
670 | BrMatrix34Copy(&c->last_box_inv_mat, &mat3); |
||
671 | bnds.mat = &mat; |
||
672 | c->box_face_start = gFace_count; |
||
673 | gPling_face = NULL; |
||
674 | gFace_count += FindFacesInBox(&bnds, &gFace_list__car[gFace_count], COUNT_OF(gFace_list__car) - gFace_count); |
||
675 | if (gFace_count >= COUNT_OF(gFace_list__car)) { |
||
676 | c->box_face_start = 0; |
||
677 | gFace_count = FindFacesInBox(&bnds, gFace_list__car, COUNT_OF(gFace_list__car)); |
||
678 | gFace_num__car++; |
||
679 | } |
||
680 | old_d = c->water_d; |
||
681 | if (c->driver == eDriver_local_human |
||
682 | && c->water_d != 10000.f |
||
683 | && gDouble_pling_water |
||
684 | && BrVector3Dot(&c->bounds_world_space.max, &c->water_normal) - c->water_d <= 0.f) { |
||
685 | gInTheSea = 1; |
||
686 | FreezeCamera(); |
||
687 | } |
||
688 | if (gPling_face != NULL && fabsf(gPling_face->normal.v[1]) >= 0.9f) { |
||
689 | BrVector3Copy(&c->water_normal, &gPling_face->normal); |
||
690 | if (c->water_normal.v[1] < 0.f) { |
||
691 | BrVector3Negate(&c->water_normal, &c->water_normal); |
||
692 | } |
||
693 | c->water_d = BrVector3Dot(&gPling_face->v[0], &c->water_normal); |
||
694 | if (c->driver == eDriver_local_human) { |
||
695 | if (gPling_face->material->identifier[1] != '!') { |
||
696 | gDouble_pling_water = 0; |
||
697 | } else { |
||
698 | if (BrVector3Dot(&c->bounds_world_space.min, &c->water_normal) - c->water_d < 0.0f) { |
||
699 | GetNewBoundingBox(¤t_bounds, &c->bounds[1], &c->car_master_actor->t.t.mat); |
||
700 | if (BrVector3Dot(¤t_bounds.min, &c->water_normal) / WORLD_SCALE - c->water_d < 0.0f) { |
||
701 | gInTheSea = 1; |
||
702 | FreezeCamera(); |
||
703 | } |
||
704 | } |
||
705 | gDouble_pling_water = 1; |
||
706 | } |
||
707 | } |
||
708 | } else { |
||
709 | c->water_d = 10000.0; |
||
710 | if (c->driver == eDriver_local_human) { |
||
711 | if (gInTheSea == 1) { |
||
712 | gInTheSea = 2; |
||
713 | } else { |
||
714 | gInTheSea = 0; |
||
715 | } |
||
716 | } |
||
717 | } |
||
718 | if (c->water_d != old_d) { |
||
719 | StartPipingSession(ePipe_chunk_splash); |
||
720 | AddSplashToPipingSession(c); |
||
721 | EndPipingSession(); |
||
722 | } |
||
723 | c->box_face_end = gFace_count; |
||
724 | c->box_face_ref = gFace_num__car; |
||
725 | } |
||
726 | } |
||
727 | |||
728 | // IDA: int __cdecl IsCarInTheSea() |
||
729 | int IsCarInTheSea(void) { |
||
730 | LOG_TRACE("()"); |
||
731 | |||
732 | return gInTheSea; |
||
733 | } |
||
734 | |||
735 | // IDA: void __usercall RememberSafePosition(tCar_spec *car@<EAX>, tU32 pTime@<EDX>) |
||
736 | void RememberSafePosition(tCar_spec* car, tU32 pTime) { |
||
737 | static tU32 time_count; |
||
738 | int j; |
||
739 | br_vector3 r; |
||
740 | //br_scalar ts; // Pierre-Marie Baty -- unused variable |
||
741 | LOG_TRACE("(%p, %d)", car, pTime); |
||
742 | |||
743 | if (car->disabled) { |
||
744 | return; |
||
745 | } |
||
746 | time_count += pTime; |
||
747 | if (time_count < 5000) { |
||
748 | return; |
||
749 | } |
||
750 | time_count = 4000; |
||
751 | for (j = 0; j < 4; j++) { |
||
752 | if (car->susp_height[j >> 1] <= car->oldd[j]) { |
||
753 | return; |
||
754 | } |
||
755 | } |
||
756 | if ((car->last_special_volume == NULL || car->last_special_volume->gravity_multiplier == 1.f) |
||
757 | && gCurrent_race.material_modifiers[car->material_index[0]].tyre_road_friction >= 0.1f |
||
758 | && gCurrent_race.material_modifiers[car->material_index[1]].tyre_road_friction >= 0.1f |
||
759 | && gCurrent_race.material_modifiers[car->material_index[2]].tyre_road_friction >= 0.1f |
||
760 | && gCurrent_race.material_modifiers[car->material_index[3]].tyre_road_friction >= 0.1f |
||
761 | && car->car_master_actor->t.t.mat.m[1][1] > 0.8f) { |
||
762 | |||
763 | for (j = 0; j < 5; j++) { |
||
764 | BrVector3Sub(&r, &car->car_master_actor->t.t.translate.t, (br_vector3*)car->last_safe_positions[j].m[3]); |
||
765 | |||
766 | if (BrVector3LengthSquared(&r) < 8.4015961f) { |
||
767 | return; |
||
768 | } |
||
769 | } |
||
770 | for (j = 3; j > 0; j--) { |
||
771 | BrMatrix34Copy(&car->last_safe_positions[j], &car->last_safe_positions[j - 1]); |
||
772 | } |
||
773 | BrMatrix34Copy(&car->last_safe_positions[0], &car->car_master_actor->t.t.mat); |
||
774 | time_count = 0; |
||
775 | } |
||
776 | } |
||
777 | |||
778 | // IDA: void __usercall ControlOurCar(tU32 pTime_difference@<EAX>) |
||
779 | void ControlOurCar(tU32 pTime_difference) { |
||
780 | br_scalar ts; |
||
781 | br_vector3 minus_k; |
||
782 | tCar_spec* car; |
||
783 | static int steering_locked; |
||
784 | //int i; // Pierre-Marie Baty -- unused variable |
||
785 | tU32 time; |
||
786 | LOG_TRACE("(%d)", pTime_difference); |
||
787 | |||
788 | car = &gProgram_state.current_car; |
||
789 | if (gCar_flying) { |
||
790 | if (gNet_mode != eNet_mode_none) { |
||
791 | gCar_flying = 0; |
||
792 | } else { |
||
793 | BrVector3Scale(&car->car_master_actor->t.t.translate.t, &car->car_master_actor->t.t.translate.t, WORLD_SCALE); |
||
794 | FlyCar(car, pTime_difference / 1000.f); |
||
795 | BrVector3InvScale(&car->car_master_actor->t.t.translate.t, &car->car_master_actor->t.t.translate.t, WORLD_SCALE); |
||
796 | } |
||
797 | return; |
||
798 | } |
||
799 | time = GetTotalTime(); |
||
800 | if (car->damage_units[eDamage_steering].damage_level > 40) { |
||
801 | if (car->end_steering_damage_effect) { |
||
802 | if (time < car->end_steering_damage_effect || car->damage_units[eDamage_steering].damage_level == 99) { |
||
803 | car->keys.left = car->false_key_left; |
||
804 | car->keys.right = car->false_key_right; |
||
805 | } else { |
||
806 | car->end_steering_damage_effect = 0; |
||
807 | } |
||
808 | } else { |
||
809 | ts = pTime_difference * (car->damage_units[eDamage_steering].damage_level - 40) * 0.0045f; |
||
810 | if (PercentageChance(ts) && fabsf(car->velocity_car_space.v[2]) > 0.0001f) { |
||
811 | if (car->keys.left || car->keys.right) { |
||
812 | car->false_key_left = !car->keys.left; |
||
813 | car->false_key_right = !car->keys.right; |
||
814 | } else if (PercentageChance(50)) { |
||
815 | car->false_key_left = 1; |
||
816 | } else { |
||
817 | car->false_key_right = 1; |
||
818 | } |
||
819 | ts = 5 * (5 * car->damage_units[eDamage_steering].damage_level - 200); |
||
820 | car->end_steering_damage_effect = FRandomBetween(0.0f, ts) + time; |
||
821 | } |
||
822 | } |
||
823 | } |
||
824 | if (car->damage_units[eDamage_transmission].damage_level > 40) { |
||
825 | if (car->end_trans_damage_effect) { |
||
826 | if (time < car->end_trans_damage_effect || car->damage_units[eDamage_transmission].damage_level == 99) { |
||
827 | car->gear = 0; |
||
828 | car->just_changed_gear = 1; |
||
829 | } else { |
||
830 | car->end_trans_damage_effect = 0; |
||
831 | } |
||
832 | } else { |
||
833 | ts = pTime_difference * (car->damage_units[eDamage_transmission].damage_level - 40) * 0.006; |
||
834 | if (PercentageChance(ts) != 0) { |
||
835 | ts = 10 * (5 * car->damage_units[eDamage_transmission].damage_level - 200); |
||
836 | car->end_trans_damage_effect = FRandomBetween(0.f, ts) + time; |
||
837 | } |
||
838 | } |
||
839 | } |
||
840 | ts = pTime_difference / 1000.0f; |
||
841 | ControlCar[gControl__car](car, ts); |
||
842 | RememberSafePosition(car, pTime_difference); |
||
843 | if (gCamera_reset) { |
||
844 | BrVector3SetFloat(&minus_k, 0.0f, 0.0f, -1.0f); |
||
845 | gCamera_sign = 0; |
||
846 | BrMatrix34ApplyV(&car->direction, &minus_k, &car->car_master_actor->t.t.mat); |
||
847 | } |
||
848 | } |
||
849 | |||
850 | // IDA: void __usercall CalcEngineForce(tCar_spec *c@<EAX>, br_scalar dt) |
||
851 | void CalcEngineForce(tCar_spec* c, br_scalar dt) { |
||
852 | br_scalar torque; |
||
853 | br_scalar ts; |
||
854 | br_scalar ts2; |
||
855 | //br_scalar brake_temp; // Pierre-Marie Baty -- unused variable |
||
856 | int sign; |
||
857 | tS32 temp_for_swap; |
||
858 | LOG_TRACE("(%p, %f)", c, dt); |
||
859 | |||
860 | c->acc_force = 0.0f; |
||
861 | if (c->revs == 0.0f) { |
||
862 | c->gear = 0; |
||
863 | } |
||
864 | sign = c->gear < 0 || (c->gear == 0 && c->velocity_car_space.v[2] > 0.5f); |
||
865 | if (c->keys.backwards != sign) { |
||
866 | c->keys.backwards = !c->keys.backwards; |
||
867 | temp_for_swap = c->keys.acc; |
||
868 | c->keys.acc = c->keys.dec; |
||
869 | c->keys.dec = temp_for_swap; |
||
870 | |||
871 | temp_for_swap = c->joystick.acc; |
||
872 | c->joystick.acc = c->joystick.dec; |
||
873 | c->joystick.dec = temp_for_swap; |
||
874 | } |
||
875 | 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) { |
||
876 | c->keys.backwards = 1; |
||
877 | c->keys.acc = c->keys.dec; |
||
878 | c->keys.dec = 0; |
||
879 | temp_for_swap = c->joystick.acc; |
||
880 | c->joystick.acc = c->joystick.dec; |
||
881 | c->joystick.dec = temp_for_swap; |
||
882 | } |
||
883 | c->torque = -(c->revs * c->revs / 100000000.0f) - 0.2f; |
||
884 | if (c->keys.acc || c->joystick.acc >= 0) { |
||
885 | if (fabsf(c->curvature) > c->maxcurve / 2.0f && c->gear < 2 && c->gear && c->traction_control) { |
||
886 | ts = 0.7f; |
||
887 | } else if (c->joystick.acc < 0) { |
||
888 | ts = (br_scalar) 1.2; // Pierre-Marie Baty -- added type cast |
||
889 | } else { |
||
18 | pmbaty | 890 | ts = c->joystick.acc / 54613.0f; |
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) { |
||
18 | pmbaty | 1084 | int j; |
1085 | float amount; |
||
1086 | br_scalar total_deflection; |
||
1 | pmbaty | 1087 | LOG_TRACE("(%p)", pCar); |
18 | pmbaty | 1088 | |
1089 | if (gNet_mode == eNet_mode_host && pCar->last_car_car_collision > pCar->message.cc_coll_time) { |
||
1090 | pCar->message.type = 0; |
||
1091 | pCar->dt = -1.0f; |
||
1092 | return; |
||
1093 | } |
||
1094 | if (fabsf(pCar->message.omega.v[0]) > 10000.0 |
||
1095 | || fabsf(pCar->message.omega.v[1]) > 10000.0 |
||
1096 | || fabsf(pCar->message.omega.v[2]) > 10000.0 |
||
1097 | || fabsf(pCar->message.omega.v[0]) > 10000.0 |
||
1098 | || fabsf(pCar->message.omega.v[1]) > 10000.0 |
||
1099 | || fabsf(pCar->message.omega.v[2]) > 10000.0) { |
||
1100 | BrVector3SetFloat(&pCar->message.omega, 0.0, 0.0, 0.0); |
||
1101 | BrVector3SetFloat(&pCar->message.v, 0.0, 0.0, 0.0); |
||
1102 | } |
||
1103 | GetExpandedMatrix(&pCar->car_master_actor->t.t.mat, &pCar->message.mat); |
||
1104 | if (gNet_mode == eNet_mode_client) { |
||
1105 | BrMatrix34Copy(&pCar->oldmat, &pCar->car_master_actor->t.t.mat); |
||
1106 | } |
||
1107 | BrVector3Copy(&pCar->v, &pCar->message.v); |
||
1108 | BrVector3Copy(&pCar->omega, &pCar->message.omega); |
||
1109 | |||
1110 | if (pCar->driver > eDriver_non_car) { |
||
1111 | pCar->curvature = pCar->message.curvature * pCar->maxcurve / 32767.0f; |
||
1112 | |||
1113 | for (j = 0; j < COUNT_OF(pCar->oldd); j++) { |
||
1114 | pCar->oldd[j] = (pCar->message.d[j] * pCar->susp_height[j >> 1]) / 255.0f; |
||
1115 | } |
||
1116 | if (pCar->driver == eDriver_oppo || pCar->repair_time >= pCar->message.repair_time) { |
||
1117 | for (j = 0; j < COUNT_OF(pCar->damage_units); j++) { |
||
1118 | pCar->damage_units[j].damage_level = pCar->message.damage[j]; |
||
1119 | } |
||
1120 | SortOutSmoke(pCar); |
||
1121 | } else { |
||
1122 | if (pCar->message.repair_time - pCar->repair_time < 100000) { |
||
1123 | amount = RepairCar2(pCar, pCar->message.repair_time - pCar->repair_time, &total_deflection); |
||
1124 | } else { |
||
1125 | TotallyRepairACar(pCar); |
||
1126 | pCar->repair_time = pCar->message.repair_time; |
||
1127 | } |
||
1128 | for (j = 0; j < COUNT_OF(pCar->damage_units); j++) { |
||
1129 | pCar->damage_units[j].damage_level = pCar->message.damage[j]; |
||
1130 | } |
||
1131 | SetSmokeLastDamageLevel(pCar); |
||
1132 | StopCarSmoking(pCar); |
||
1133 | } |
||
1134 | if (pCar->driver == eDriver_net_human) { |
||
1135 | pCar->revs = pCar->message.revs; |
||
1136 | } |
||
1137 | if (pCar->driver >= eDriver_net_human) { |
||
1138 | pCar->bounds[1].min.v[2] = pCar->message.front; |
||
1139 | pCar->bounds[1].max.v[2] = pCar->message.back; |
||
1140 | } |
||
1141 | if (pCar->driver != eDriver_local_human) { |
||
1142 | for (j = 0; j < COUNT_OF(pCar->wheel_dam_offset); j++) { |
||
1143 | pCar->wheel_dam_offset[j] = pCar->message.wheel_dam_offset[j]; |
||
1144 | } |
||
1145 | } |
||
1146 | GetFacesInBox((tCollision_info*)pCar); |
||
1147 | } |
||
1148 | |||
1149 | pCar->message.type = 0; |
||
1150 | pCar->last_car_car_collision = pCar->message.cc_coll_time; |
||
1 | pmbaty | 1151 | } |
1152 | |||
1153 | // IDA: void __usercall ApplyPhysicsToCars(tU32 last_frame_time@<EAX>, tU32 pTime_difference@<EDX>) |
||
1154 | void ApplyPhysicsToCars(tU32 last_frame_time, tU32 pTime_difference) { |
||
1155 | //br_vector3 minus_k; // Pierre-Marie Baty -- unused variable |
||
1156 | int i; |
||
1157 | int old_num_cars; |
||
1158 | int step_number; |
||
1159 | int dam_index; |
||
1160 | static int steering_locked; |
||
1161 | tCar_spec* car = NULL; |
||
1162 | tCollision_info* car_info; |
||
1163 | tNon_car_spec* non_car; |
||
1164 | //tU32 time_step; // Pierre-Marie Baty -- unused variable |
||
1165 | tU32 frame_end_time; |
||
1166 | LOG_TRACE("(%d, %d)", last_frame_time, pTime_difference); |
||
1167 | |||
1168 | step_number = 0; |
||
1169 | frame_end_time = last_frame_time + pTime_difference; |
||
1170 | if (gFreeze_mechanics) { |
||
1171 | return; |
||
1172 | } |
||
1173 | if (gNet_mode == eNet_mode_client) { |
||
1174 | ForceRebuildActiveCarList(); |
||
1175 | } |
||
1176 | if (gLast_mechanics_time < last_frame_time) { |
||
1177 | gLast_mechanics_time = harness_game_config.physics_step_time * (last_frame_time / harness_game_config.physics_step_time); |
||
1178 | } |
||
1179 | GetNonCars(); |
||
1180 | if (frame_end_time <= gLast_mechanics_time) { |
||
1181 | PrepareCars(last_frame_time); |
||
1182 | InterpolateCars(frame_end_time, pTime_difference); |
||
1183 | FinishCars(frame_end_time, pTime_difference); |
||
1184 | return; |
||
1185 | } |
||
1186 | |||
1187 | gDoing_physics = 1; |
||
1188 | PrepareCars(last_frame_time); |
||
1189 | gDt = harness_game_config.physics_step_time / 1000.0; // 0.04; |
||
1190 | gMechanics_time_sync = pTime_difference - (gLast_mechanics_time - last_frame_time); |
||
1191 | while (gLast_mechanics_time < frame_end_time && step_number < 5) { |
||
1192 | step_number++; |
||
1193 | ResetOldmat(); |
||
1194 | BrVector3Copy(&gProgram_state.current_car.old_v, &gProgram_state.current_car.v); |
||
1195 | if (&gProgram_state.current_car != gCar_to_view) { |
||
1196 | BrVector3Copy(&gCar_to_view->old_v, &gCar_to_view->v); |
||
1197 | } |
||
1198 | for (i = 0; i < gNum_active_cars; i++) { |
||
1199 | car = gActive_car_list[i]; |
||
1200 | car->dt = -1.f; |
||
18 | pmbaty | 1201 | if (car->message.type == NETMSGID_MECHANICS && car->message.time >= gLast_mechanics_time && car->message.time <= gLast_mechanics_time + harness_game_config.physics_step_time) { |
1202 | // time between car message and next mechanics |
||
1203 | car->dt = (gLast_mechanics_time + harness_game_config.physics_step_time - car->message.time) / 1000.0f; |
||
1204 | // if the time between car message and next mechanics is about equal to timestep |
||
1205 | if (car->dt >= gDt - 0.0001f) { |
||
1 | pmbaty | 1206 | GetNetPos(car); |
1207 | } else if (gNet_mode == eNet_mode_host) { |
||
1208 | car->dt = -1.f; |
||
1209 | } else { |
||
1210 | for (dam_index = 0; dam_index < COUNT_OF(car->damage_units); dam_index++) { |
||
1211 | if (car->damage_units[dam_index].damage_level < car->message.damage[dam_index]) { |
||
1212 | car->dt = -1.f; |
||
1213 | break; |
||
1214 | } |
||
1215 | } |
||
1216 | if (car->dt >= 0.f) { |
||
1217 | GetNetPos(car); |
||
1218 | } |
||
1219 | } |
||
1220 | } |
||
1221 | if (!car->disabled |
||
1222 | && (!car->doing_nothing_flag || (car->driver >= eDriver_net_human && (!gPalette_fade_time || car->driver != eDriver_local_human)))) { |
||
1223 | if (car->box_face_ref != gFace_num__car |
||
1224 | && (car->box_face_ref != gFace_num__car - 1 || car->box_face_start <= gFace_count)) { |
||
1225 | car_info = (tCollision_info*)car; |
||
1226 | GetFacesInBox(car_info); |
||
1227 | } |
||
1228 | if (car->dt != 0.f) { |
||
1229 | MoveAndCollideCar(car, gDt); |
||
1230 | } |
||
1231 | } |
||
1232 | } |
||
1233 | for (i = 0; i < gNum_active_non_cars; i++) { |
||
1234 | non_car = gActive_non_car_list[i]; |
||
1235 | if (!non_car->collision_info.doing_nothing_flag) { |
||
1236 | non_car->collision_info.dt = -1.f; |
||
18 | pmbaty | 1237 | if (non_car->collision_info.message.type == NETMSGID_NONCAR_INFO && 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 | 1238 | non_car->collision_info.dt = (gLast_mechanics_time + harness_game_config.physics_step_time - non_car->collision_info.message.time) / 1000.0f; |
1239 | GetNetPos((tCar_spec*)non_car); |
||
1240 | } |
||
1241 | if (non_car->collision_info.box_face_ref != gFace_num__car |
||
1242 | && (non_car->collision_info.box_face_ref != gFace_num__car - 1 |
||
1243 | || non_car->collision_info.box_face_start <= gFace_count)) { |
||
1244 | GetFacesInBox(&non_car->collision_info); |
||
1245 | } |
||
1246 | if (non_car->collision_info.dt != 0.0f) { |
||
1247 | MoveAndCollideNonCar(non_car, gDt); |
||
1248 | } |
||
1249 | } |
||
1250 | } |
||
1251 | do { |
||
1252 | old_num_cars = gNum_cars_and_non_cars; |
||
1253 | CrashCarsTogether(gDt); |
||
1254 | } while (old_num_cars < gNum_cars_and_non_cars); |
||
1255 | gMechanics_time_sync -= harness_game_config.physics_step_time; |
||
1256 | gLast_mechanics_time += harness_game_config.physics_step_time; |
||
1257 | } |
||
1258 | gMechanics_time_sync = 1; |
||
1259 | SendCarData(gLast_mechanics_time); |
||
1260 | InterpolateCars(frame_end_time, pTime_difference); |
||
1261 | FinishCars(frame_end_time, pTime_difference); |
||
1262 | gDoing_physics = 0; |
||
1263 | CheckForDeAttachmentOfNonCars(pTime_difference); |
||
1264 | } |
||
1265 | |||
1266 | // IDA: void __usercall MungeSpecialVolume(tCollision_info *pCar@<EAX>) |
||
1267 | void MungeSpecialVolume(tCollision_info* pCar) { |
||
1268 | tSpecial_volume* new_special_volume; |
||
1269 | //tCar_spec* car; // Pierre-Marie Baty -- unused variable |
||
1270 | LOG_TRACE("(%p)", pCar); |
||
1271 | |||
1272 | new_special_volume = FindSpecialVolume(&pCar->pos, pCar->last_special_volume); |
||
1273 | if (pCar->auto_special_volume != NULL && (new_special_volume == NULL || new_special_volume->gravity_multiplier == 1.f)) { |
||
1274 | if (pCar->water_d == 10000.f && pCar->water_depth_factor != 1.f) { |
||
1275 | pCar->auto_special_volume = NULL; |
||
1276 | } else { |
||
1277 | new_special_volume = pCar->auto_special_volume; |
||
1278 | } |
||
1279 | } |
||
1280 | if (pCar->last_special_volume != new_special_volume && pCar->driver == eDriver_local_human) { |
||
1281 | 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)) { |
||
1282 | DRS3StartSound(gCar_outlet, pCar->last_special_volume->exit_noise); |
||
1283 | } |
||
1284 | 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)) { |
||
1285 | DRS3StartSound(gCar_outlet, new_special_volume->entry_noise); |
||
1286 | } |
||
1287 | } |
||
1288 | pCar->last_special_volume = new_special_volume; |
||
1289 | if (new_special_volume != NULL && pCar->num_smoke_columns != 0 && pCar->last_special_volume != NULL && pCar->last_special_volume->gravity_multiplier < 1.f) { |
||
1290 | StopCarSmoking((tCar_spec*)pCar); |
||
1291 | } |
||
1292 | } |
||
1293 | |||
1294 | // IDA: void __usercall ResetCarSpecialVolume(tCollision_info *pCar@<EAX>) |
||
1295 | void ResetCarSpecialVolume(tCollision_info* pCar) { |
||
1296 | br_vector3 cast_v; |
||
1297 | br_vector3 norm; |
||
1298 | br_scalar t; |
||
1299 | int id_len; |
||
1300 | char* mat_id; |
||
1301 | tSpecial_volume* new_special_volume; |
||
1302 | br_material* material; |
||
1303 | LOG_TRACE("(%p)", pCar); |
||
1304 | |||
1305 | new_special_volume = NULL; |
||
1306 | BrVector3Set(&cast_v, 0.f, 200.f, 0.f); |
||
1307 | DisablePlingMaterials(); |
||
1308 | FindFace(&pCar->car_master_actor->t.t.translate.t, &cast_v, &norm, &t, &material); |
||
1309 | EnablePlingMaterials(); |
||
1310 | if (t < 100.0f && material != NULL) { |
||
1311 | mat_id = material->identifier; |
||
1312 | if (mat_id) { |
||
1313 | id_len = strlen(mat_id); |
||
1314 | if (id_len > 0 && (*mat_id == '!' || *mat_id == '#')) { |
||
1315 | new_special_volume = GetDefaultSpecialVolumeForWater(); |
||
1316 | } |
||
1317 | } |
||
1318 | } |
||
1319 | pCar->auto_special_volume = new_special_volume; |
||
1320 | pCar->water_depth_factor = 1.0f; |
||
1321 | } |
||
1322 | |||
1323 | // IDA: void __usercall TestAutoSpecialVolume(tCollision_info *pCar@<EAX>) |
||
1324 | void TestAutoSpecialVolume(tCollision_info* pCar) { |
||
1325 | br_vector3 pos; |
||
1326 | //br_scalar car_d; // Pierre-Marie Baty -- unused variable |
||
1327 | br_scalar d; |
||
1328 | br_scalar d2; |
||
1329 | br_vector3 dir; |
||
1330 | br_vector3 tv; |
||
1331 | br_vector3 lp; |
||
1332 | br_vector3 hp; |
||
1333 | tSpecial_volume* vol; |
||
1334 | br_matrix34* mat; |
||
1335 | br_scalar lowest_p; |
||
1336 | br_scalar highest_p; |
||
1337 | br_scalar val; |
||
1338 | int i; |
||
1339 | LOG_TRACE("(%p)", pCar); |
||
1340 | |||
1341 | mat = &pCar->car_master_actor->t.t.mat; |
||
1342 | highest_p = 0.f; |
||
1343 | for (i = 0; i < 3; i++) { |
||
1344 | highest_p += BrVector3Dot((br_vector3*)mat->m[i], &pCar->water_normal) * pCar->bounds[0].min.v[i]; |
||
1345 | } |
||
1346 | highest_p += BrVector3Dot((br_vector3*)mat->m[3], &pCar->water_normal) / WORLD_SCALE; |
||
1347 | lowest_p = highest_p; |
||
1348 | for (i = 0; i < 3; i++) { |
||
1349 | val = (pCar->bounds[0].max.v[i] - pCar->bounds[0].min.v[i]) * BrVector3Dot((br_vector3*)mat->m[i], &pCar->water_normal); |
||
1350 | if (val >= 0.f) { |
||
1351 | highest_p += val; |
||
1352 | } else { |
||
1353 | lowest_p += val; |
||
1354 | } |
||
1355 | } |
||
1356 | |||
1357 | if (pCar->water_d > lowest_p) { |
||
1358 | if (pCar->water_d >= highest_p) { |
||
1359 | pCar->water_depth_factor = 1.f; |
||
1360 | } else { |
||
1361 | pCar->water_depth_factor = (pCar->water_d - lowest_p) / (highest_p - lowest_p); |
||
1362 | } |
||
1363 | if (pCar->auto_special_volume == NULL) { |
||
1364 | vol = GetDefaultSpecialVolumeForWater(); |
||
1365 | if (vol == NULL) { |
||
1366 | pCar->water_depth_factor = 1.f; |
||
1367 | pCar->auto_special_volume = NULL; |
||
1368 | } else { |
||
1369 | BrVector3Scale(&tv, &pCar->bounds[0].min, WORLD_SCALE); |
||
1370 | BrMatrix34ApplyP(&lp, &tv, mat); |
||
1371 | BrVector3InvScale(&lp, &lp, WORLD_SCALE); |
||
1372 | BrVector3Copy(&hp, &lp); |
||
1373 | for (i = 0; i < 3; i++) { |
||
1374 | val = pCar->bounds[0].max.v[i] - pCar->bounds[0].min.v[i]; |
||
1375 | BrVector3Scale(&tv, (br_vector3*)mat->m[i], val); |
||
1376 | if (BrVector3Dot(&pCar->water_normal, &tv) > 0.f) { |
||
1377 | BrVector3Accumulate(&hp, &tv); |
||
1378 | } else { |
||
1379 | BrVector3Accumulate(&lp, &tv); |
||
1380 | } |
||
1381 | } |
||
1382 | BrVector3Sub(&dir, &hp, &lp); |
||
1383 | DisablePlingMaterials(); |
||
1384 | FindFloorInBoxBU(&lp, &dir, &tv, &d, pCar); |
||
1385 | EnablePlingMaterials(); |
||
1386 | FindFloorInBoxBU(&pos, &dir, &tv, &d2, pCar); |
||
1387 | if (d2 <= d) { |
||
1388 | pCar->water_depth_factor = 1.f; |
||
1389 | pCar->auto_special_volume = NULL; |
||
1390 | } else { |
||
1391 | pCar->auto_special_volume = vol; |
||
1392 | } |
||
1393 | } |
||
1394 | } |
||
1395 | } else { |
||
1396 | pCar->auto_special_volume = NULL; |
||
1397 | pCar->water_depth_factor = 1.f; |
||
1398 | } |
||
1399 | } |
||
1400 | |||
1401 | // IDA: void __usercall MoveAndCollideCar(tCar_spec *car@<EAX>, br_scalar dt) |
||
1402 | void MoveAndCollideCar(tCar_spec* car, br_scalar dt) { |
||
1403 | tCollision_info* car_info; |
||
1404 | int wheel; |
||
1405 | LOG_TRACE("(%p, %f)", car, dt); |
||
1406 | |||
1407 | if (car->dt >= 0.f) { |
||
1408 | dt = car->dt; |
||
1409 | } |
||
1410 | if (dt != 0.f && (!gCar_flying || &gProgram_state.current_car != car)) { |
||
1411 | car_info = (tCollision_info*)car; |
||
1412 | car->new_skidding = 0; |
||
1413 | if (car->water_d != 10000.0f) { |
||
1414 | TestAutoSpecialVolume(car_info); |
||
1415 | } |
||
1416 | MungeSpecialVolume(car_info); |
||
1417 | if (car->driver <= eDriver_oppo) { |
||
1418 | CalcForce(car, dt); |
||
1419 | } else { |
||
1420 | CalcEngineForce(car, dt); |
||
1421 | CalcForce(car, dt); |
||
1422 | DoRevs(car, dt); |
||
1423 | } |
||
1424 | RotateCar(car_info, dt); |
||
1425 | TranslateCar(car_info, dt); |
||
1426 | CollideCarWithWall(car_info, dt); |
||
1427 | BrMatrix34ApplyP(&car->pos, &car->cmpos, &car->car_master_actor->t.t.mat); |
||
1428 | BrVector3InvScale(&car->pos, &car->pos, WORLD_SCALE); |
||
1429 | for (wheel = 0; wheel < 4; wheel++) { |
||
1430 | SkidMark(car, wheel); |
||
1431 | } |
||
1432 | } |
||
1433 | } |
||
1434 | |||
1435 | // IDA: void __usercall MoveAndCollideNonCar(tNon_car_spec *non_car@<EAX>, br_scalar dt) |
||
1436 | void MoveAndCollideNonCar(tNon_car_spec* non_car, br_scalar dt) { |
||
1437 | tCollision_info* car_info; |
||
1438 | LOG_TRACE("(%p, %f)", non_car, dt); |
||
1439 | |||
1440 | car_info = &non_car->collision_info; |
||
1441 | if (car_info->water_d != 10000.f) { |
||
1442 | TestAutoSpecialVolume(&non_car->collision_info); |
||
1443 | } |
||
1444 | MungeSpecialVolume(&non_car->collision_info); |
||
1445 | if (car_info->dt >= 0.f) { |
||
1446 | dt = car_info->dt; |
||
1447 | } |
||
1448 | NonCarCalcForce(non_car, dt); |
||
1449 | RotateCar(&non_car->collision_info, dt); |
||
1450 | TranslateCar(&non_car->collision_info, dt); |
||
1451 | CollideCarWithWall(&non_car->collision_info, dt); |
||
1452 | BrMatrix34ApplyP(&car_info->pos, &car_info->cmpos, &car_info->car_master_actor->t.t.mat); |
||
1453 | BrVector3InvScale(&car_info->pos, &car_info->pos, WORLD_SCALE); |
||
1454 | } |
||
1455 | |||
1456 | // IDA: int __usercall CollideCarWithWall@<EAX>(tCollision_info *car@<EAX>, br_scalar dt) |
||
1457 | int CollideCarWithWall(tCollision_info* car, br_scalar dt) { |
||
1458 | LOG_TRACE("(%p, %f)", car, dt); |
||
1459 | |||
1460 | GetFacesInBox(car); |
||
1461 | if (gCollision_detection_on__car) { |
||
1462 | car->collision_flag = 0; |
||
1463 | while (CollCheck(car, dt)) { |
||
1464 | car->collision_flag++; |
||
1465 | if (car->collision_flag - 1 > 20) { |
||
1466 | car->collision_flag = 1; |
||
1467 | BrVector3Set(&car->v, 0.f, 0.f, 0.f); |
||
1468 | BrVector3Set(&car->omega, 0.f, 0.f, 0.f); |
||
1469 | break; |
||
1470 | } |
||
1471 | RotateCar(car, dt); |
||
1472 | TranslateCar(car, dt); |
||
1473 | GetFacesInBox(car); |
||
1474 | } |
||
1475 | if (car->collision_flag) { |
||
1476 | CrashEarnings(CAR(car), NULL); |
||
1477 | } |
||
1478 | BrMatrix34TApplyV(&car->velocity_car_space, &car->v, &car->oldmat); |
||
1479 | car->frame_collision_flag += car->collision_flag; |
||
1480 | } |
||
1481 | return car->collision_flag; |
||
1482 | } |
||
1483 | |||
1484 | // IDA: void __cdecl ToggleControls() |
||
1485 | void ToggleControls(void) { |
||
1486 | LOG_TRACE("()"); |
||
1487 | |||
1488 | gControl__car++; |
||
18 | pmbaty | 1489 | if (ControlCar[gControl__car] == NULL) { |
1 | pmbaty | 1490 | gControl__car = 0; |
1491 | } |
||
1492 | switch (gControl__car) { |
||
1493 | case 0: |
||
1494 | NewTextHeadupSlot(4, 0, 500, -1, "Original Controls"); |
||
1495 | break; |
||
1496 | case 1: |
||
1497 | NewTextHeadupSlot(4, 0, 500, -1, "Accelerated steering"); |
||
1498 | break; |
||
1499 | case 2: |
||
1500 | NewTextHeadupSlot(4, 0, 500, -1, "0.75 Accelerated"); |
||
1501 | break; |
||
1502 | case 3: |
||
1503 | NewTextHeadupSlot(4, 0, 500, -1, "0.5 Accelerated"); |
||
1504 | break; |
||
1505 | default: |
||
1506 | NewTextHeadupSlot(4, 0, 500, -1, "New controls"); |
||
1507 | break; |
||
1508 | } |
||
1509 | } |
||
1510 | |||
1511 | // IDA: void __usercall ControlCar2(tCar_spec *c@<EAX>, br_scalar dt) |
||
1512 | void ControlCar2(tCar_spec* c, br_scalar dt) { |
||
1513 | LOG_TRACE("(%p, %f)", c, dt); |
||
18 | pmbaty | 1514 | |
1515 | c->acc_force = 0.f; |
||
1516 | if (c->keys.acc) { |
||
1517 | c->acc_force = 7.f * c->M; |
||
1518 | } |
||
1519 | if (c->keys.dec) { |
||
1520 | c->acc_force = -7.f * c->M; |
||
1521 | } |
||
1522 | if (c->keys.left) { |
||
1523 | if (c->turn_speed < 0.f) { |
||
1524 | c->turn_speed = 0.f; |
||
1525 | } |
||
1526 | if (c->curvature >= 0.f) { |
||
1527 | c->turn_speed += dt / 0.04f * (0.05f / (5.f + BrVector3Length(&c->v)) / 2.f); |
||
1528 | } else { |
||
1529 | c->turn_speed += 0.01f * dt / 0.04f / 2.f; |
||
1530 | } |
||
1531 | } |
||
1532 | if (c->keys.right) { |
||
1533 | if (c->turn_speed > 0.f) { |
||
1534 | c->turn_speed = 0.f; |
||
1535 | } |
||
1536 | if (c->curvature <= 0.f) { |
||
1537 | c->turn_speed -= dt / 0.04f * (0.05f / (5.f + BrVector3Length(&c->v)) / 2.f); |
||
1538 | } else { |
||
1539 | c->turn_speed -= 0.01f * dt / 0.04f / 2.f; |
||
1540 | } |
||
1541 | } |
||
1542 | if (!c->keys.left && !c->keys.right) { |
||
1543 | c->turn_speed = 0.f; |
||
1544 | } |
||
1545 | c->curvature += c->turn_speed; |
||
1546 | if (c->curvature > c->maxcurve) { |
||
1547 | c->curvature = c->maxcurve; |
||
1548 | } |
||
1549 | if (c->curvature < -c->maxcurve) { |
||
1550 | c->curvature = -c->maxcurve; |
||
1551 | } |
||
1 | pmbaty | 1552 | } |
1553 | |||
1554 | // IDA: void __usercall ControlCar3(tCar_spec *c@<EAX>, br_scalar dt) |
||
1555 | void ControlCar3(tCar_spec* c, br_scalar dt) { |
||
1556 | LOG_TRACE("(%p, %f)", c, dt); |
||
18 | pmbaty | 1557 | |
1558 | if (c->keys.left) { |
||
1559 | if (c->turn_speed < 0.f) { |
||
1560 | c->turn_speed = 0.f; |
||
1561 | } |
||
1562 | if (c->curvature >= 0.f && c->omega.v[1] >= 0.f) { |
||
1563 | c->turn_speed += dt / 0.04f * (0.05f / (5.f + BrVector3Length(&c->v)) / 2.f) * 0.75f; |
||
1564 | } else { |
||
1565 | c->turn_speed += 0.01f * dt / 0.04f / 2.f * 3.f; |
||
1566 | } |
||
1567 | } |
||
1568 | |||
1569 | if (c->keys.right) { |
||
1570 | if (c->turn_speed > 0.f) { |
||
1571 | c->turn_speed = 0.f; |
||
1572 | } |
||
1573 | if (c->curvature <= 0.f && c->omega.v[1] <= 0.f) { |
||
1574 | c->turn_speed -= dt / 0.04f * (0.05f / (5.f + BrVector3Length(&c->v)) / 2.f) * 0.75f; |
||
1575 | } else { |
||
1576 | c->turn_speed -= 0.01f * dt / 0.04f / 2.f * 3.f; |
||
1577 | } |
||
1578 | } |
||
1579 | if (!c->keys.left && !c->keys.right) { |
||
1580 | c->turn_speed = 0.f; |
||
1581 | } |
||
1582 | c->curvature += c->turn_speed; |
||
1583 | if (c->curvature > c->maxcurve) { |
||
1584 | c->curvature = c->maxcurve; |
||
1585 | } |
||
1586 | if (c->curvature < -c->maxcurve) { |
||
1587 | c->curvature = -c->maxcurve; |
||
1588 | } |
||
1 | pmbaty | 1589 | } |
1590 | |||
1591 | // IDA: void __usercall ControlCar4(tCar_spec *c@<EAX>, br_scalar dt) |
||
1592 | void ControlCar4(tCar_spec* c, br_scalar dt) { |
||
1593 | //br_scalar ts; // Pierre-Marie Baty -- unused variable |
||
1594 | LOG_TRACE("(%p, %f)", c, dt); |
||
1595 | |||
1596 | if (c->keys.left) { |
||
1597 | if (c->turn_speed < 0.f) { |
||
1598 | c->turn_speed = 0.f; |
||
1599 | } |
||
1600 | if (c->velocity_car_space.v[2] > 0.f) { |
||
1601 | c->turn_speed += dt * 0.01f / .04f / 2.f * 2.f; |
||
1602 | } else if ((c->curvature >= 0.f && c->omega.v[1] >= -.001f) || c->turn_speed != 0.f) { |
||
1603 | c->turn_speed += dt / .04f * (0.05f / (BrVector3Length(&c->v) + 5.f)) / 2.f * .5f; |
||
1604 | } else { |
||
1605 | c->turn_speed = dt / .04f * (.05f / (BrVector3Length(&c->v) + 5.f)) * 4.f / 2.f * .5f; |
||
1606 | if (c->omega.v[1] < -.01f) { |
||
1607 | c->turn_speed -= dt * .01f / (harness_game_config.physics_step_time / 1000.f) / 2.f * c->omega.v[1] * 2.f; |
||
1608 | } |
||
1609 | } |
||
1610 | } |
||
1611 | if (c->keys.right) { |
||
1612 | if (c->turn_speed > 0.f) { |
||
1613 | c->turn_speed = 0.f; |
||
1614 | } |
||
1615 | if (c->velocity_car_space.v[2] > 0.f) { |
||
1616 | c->turn_speed -= dt * .01f / .04f / 2.f * 2.f; |
||
1617 | } else if ((c->curvature <= 0.f && c->omega.v[1] <= .001f) || c->turn_speed != 0.f) { |
||
1618 | c->turn_speed -= dt / .04f * (.05f / (BrVector3Length(&c->v) + 5.f)) / 2.f * .5f; |
||
1619 | } else { |
||
1620 | c->turn_speed = dt / .04f * (.05f / (BrVector3Length(&c->v) + 5.f)) * -4.f / 2.f * .5f; |
||
1621 | if (c->omega.v[1] < -.01f) { |
||
1622 | c->turn_speed -= dt * .01f / (harness_game_config.physics_step_time / 1000.f) / 2.f * c->omega.v[1] * 2.f; |
||
1623 | } |
||
1624 | } |
||
1625 | } |
||
1626 | if (!c->keys.left && !c->keys.right) { |
||
1627 | c->turn_speed = 0.f; |
||
1628 | } else if (fabsf(c->turn_speed) < fabsf(dt * 2.f * c->curvature) && c->curvature * c->turn_speed < 0.f) { |
||
1629 | c->turn_speed = -(dt * 2.f * c->curvature); |
||
1630 | } |
||
1631 | c->curvature += c->turn_speed; |
||
1632 | if (c->joystick.left > 0) { |
||
1633 | c->curvature = (float)c->joystick.left * (float)c->joystick.left / 4294967300.f * c->maxcurve; |
||
1634 | } else if (c->joystick.right >= 0) { |
||
1635 | c->curvature = -((float)c->joystick.right * (float)c->joystick.right / 4294967300.f) * c->maxcurve; |
||
1636 | } |
||
1637 | if (c->curvature > c->maxcurve) { |
||
1638 | c->curvature = c->maxcurve; |
||
1639 | } |
||
1640 | if (c->curvature < -c->maxcurve) { |
||
1641 | c->curvature = -c->maxcurve; |
||
1642 | } |
||
1643 | } |
||
1644 | |||
1645 | // IDA: void __usercall ControlCar5(tCar_spec *c@<EAX>, br_scalar dt) |
||
1646 | void ControlCar5(tCar_spec* c, br_scalar dt) { |
||
1647 | LOG_TRACE("(%p, %f)", c, dt); |
||
18 | pmbaty | 1648 | |
1649 | c->acc_force = 0.f; |
||
1650 | if (c->keys.acc) { |
||
1651 | c->acc_force = 7.f * c->M; |
||
1652 | } |
||
1653 | if (c->keys.dec) { |
||
1654 | c->acc_force = -7.f * c->M; |
||
1655 | } |
||
1656 | if (c->keys.left) { |
||
1657 | if (c->turn_speed < 0.f) { |
||
1658 | c->turn_speed = 0.f; |
||
1659 | } |
||
1660 | if (c->curvature >= 0) { |
||
1661 | c->turn_speed += dt / 0.04f * (0.05f / (5.f + BrVector3Length(&c->v)) / 2.f) * 0.5f; |
||
1662 | } else { |
||
1663 | c->turn_speed += 0.01f * dt / 0.04f / 2.f * .5f; |
||
1664 | } |
||
1665 | } |
||
1666 | if (c->keys.right) { |
||
1667 | if (c->turn_speed > 0.f) { |
||
1668 | c->turn_speed = 0.f; |
||
1669 | } |
||
1670 | if (c->curvature <= 0) { |
||
1671 | c->turn_speed -= dt / 0.04f * (0.05f / (5.f + BrVector3Length(&c->v)) / 2.f) * 0.5f; |
||
1672 | } else { |
||
1673 | c->turn_speed -= 0.01f * dt / 0.04f / 2.f * .5f; |
||
1674 | } |
||
1675 | } |
||
1676 | if (!c->keys.left && !c->keys.right) { |
||
1677 | c->turn_speed = 0.f; |
||
1678 | if (c->curvature < 0.f && !c->keys.holdw) { |
||
1679 | c->curvature += dt / 0.04f * 0.05f / (5.f + BrVector3Length(&c->v)) / 2.f * 4.f; |
||
1680 | if (c->curvature > 0.f) { |
||
1681 | c->curvature = 0.f; |
||
1682 | } |
||
1683 | } else if (c->curvature > 0.f && !c->keys.holdw) { |
||
1684 | c->curvature -= dt / 0.04f * 0.05f / (5.f + BrVector3Length(&c->v)) / 2.f * 4.f; |
||
1685 | if (c->curvature < 0.f) { |
||
1686 | c->curvature = 0.f; |
||
1687 | } |
||
1688 | } |
||
1689 | } |
||
1690 | c->curvature += c->turn_speed; |
||
1691 | if (c->curvature > c->maxcurve) { |
||
1692 | c->curvature = c->maxcurve; |
||
1693 | } |
||
1694 | if (c->curvature < -c->maxcurve) { |
||
1695 | c->curvature = -c->maxcurve; |
||
1696 | } |
||
1697 | c->keys.left = 1; |
||
1 | pmbaty | 1698 | } |
1699 | |||
1700 | // IDA: void __usercall ControlCar1(tCar_spec *c@<EAX>, br_scalar dt) |
||
1701 | void ControlCar1(tCar_spec* c, br_scalar dt) { |
||
1702 | LOG_TRACE("(%p, %f)", c, dt); |
||
18 | pmbaty | 1703 | |
1704 | c->acc_force = 0.f; |
||
1705 | if (c->keys.acc) { |
||
1706 | c->acc_force = 7.f * c->M; |
||
1707 | } |
||
1708 | if (c->keys.dec) { |
||
1709 | c->acc_force = -7.f * c->M; |
||
1710 | } |
||
1711 | if (c->keys.left) { |
||
1712 | if (c->curvature >= 0.f) { |
||
1713 | c->curvature += dt / 0.04f * 0.05f / (5.f + BrVector3Length(&c->v)); |
||
1714 | } else { |
||
1715 | c->curvature += 0.01f * dt / 0.04f; |
||
1716 | } |
||
1717 | } |
||
1718 | if (c->keys.right) { |
||
1719 | if (c->curvature <= 0.f) { |
||
1720 | c->curvature -= dt / 0.04f * 0.05f / (5.f + BrVector3Length(&c->v)); |
||
1721 | } else { |
||
1722 | c->curvature -= 0.01f * dt / 0.04f; |
||
1723 | } |
||
1724 | } |
||
1725 | if (c->curvature > c->maxcurve) { |
||
1726 | c->curvature = c->maxcurve; |
||
1727 | } |
||
1728 | if (c->curvature < -c->maxcurve) { |
||
1729 | c->curvature = -c->maxcurve; |
||
1730 | } |
||
1 | pmbaty | 1731 | } |
1732 | |||
1733 | // IDA: void __usercall setrotate(br_vector3 *wdt@<EAX>, br_matrix34 *m@<EDX>) |
||
1734 | void setrotate(br_vector3* wdt, br_matrix34* m) { |
||
18 | pmbaty | 1735 | br_euler e; |
1 | pmbaty | 1736 | LOG_TRACE("(%p, %p)", wdt, m); |
18 | pmbaty | 1737 | |
1738 | e.a = BR_ANGLE_RAD(wdt->v[0]); |
||
1739 | e.b = BR_ANGLE_RAD(wdt->v[1]); |
||
1740 | e.c = BR_ANGLE_RAD(wdt->v[2]); |
||
1741 | e.order = 0; |
||
1742 | BrEulerToMatrix34(m, &e); |
||
1 | pmbaty | 1743 | } |
1744 | |||
1745 | // IDA: void __usercall RotateCar2(tCollision_info *c@<EAX>, br_scalar dt) |
||
1746 | void RotateCar2(tCollision_info* c, br_scalar dt) { |
||
18 | pmbaty | 1747 | br_vector3 wdt; |
1748 | br_vector3 wdt2; |
||
1749 | br_vector3 L; |
||
1750 | br_vector3 L2; |
||
1751 | br_matrix34 m; |
||
1 | pmbaty | 1752 | LOG_TRACE("(%p, %f)", c, dt); |
18 | pmbaty | 1753 | |
1754 | BrVector3Scale(&wdt, &c->omega, dt); |
||
1755 | BrVector3Negate(&wdt2, &wdt); |
||
1756 | BrVector3Mul(&L, &c->I, &c->omega); |
||
1757 | setrotate(&wdt2, &m); |
||
1758 | BrMatrix34ApplyV(&L2, &L, &m); |
||
1759 | setrotate(&wdt, &m); |
||
1760 | BrMatrix34PreTranslate(&m, -c->cmpos.v[0], -c->cmpos.v[1], -c->cmpos.v[2]); |
||
1761 | BrMatrix34PostTranslate(&m, c->cmpos.v[0], c->cmpos.v[1], c->cmpos.v[2]); |
||
1762 | BrMatrix34Pre(&c->car_master_actor->t.t.mat, &m); |
||
1763 | BrVector3Copy(&c->oldomega, &c->omega); |
||
1764 | Vector3Div(&c->omega, &L2, &c->I); |
||
1 | pmbaty | 1765 | } |
1766 | |||
1767 | // IDA: void __usercall RotateCarSecondOrder(tCollision_info *c@<EAX>, br_scalar dt) |
||
1768 | void RotateCarSecondOrder(tCollision_info* c, br_scalar dt) { |
||
1769 | br_vector3 L; |
||
1770 | br_vector3 L2; |
||
1771 | br_vector3 axis; |
||
1772 | br_vector3 omega; |
||
1773 | br_scalar rad; |
||
1774 | br_scalar rad_rate; |
||
1775 | br_matrix34 m; |
||
1776 | LOG_TRACE("(%p, %f)", c, dt); |
||
1777 | |||
1778 | rad_rate = BrVector3Length(&c->omega); |
||
1779 | rad = rad_rate * dt; |
||
1780 | |||
1781 | BrVector3InvScale(&axis, &c->omega, rad_rate); |
||
1782 | BrVector3Mul(&L, &c->I, &c->omega); |
||
1783 | |||
1784 | BrMatrix34Rotate(&m, BrRadianToAngle(rad) / 2, &axis); |
||
1785 | BrMatrix34TApplyV(&L2, &L, &m); |
||
1786 | omega.v[0] = L2.v[0] / c->I.v[0]; |
||
1787 | omega.v[1] = L2.v[1] / c->I.v[1]; |
||
1788 | omega.v[2] = L2.v[2] / c->I.v[2]; |
||
1789 | |||
1790 | rad_rate = BrVector3Length(&omega); |
||
1791 | rad = rad_rate * dt; |
||
1792 | |||
1793 | BrVector3InvScale(&axis, &omega, rad_rate); |
||
1794 | BrMatrix34Rotate(&m, BrRadianToAngle(rad), &axis); |
||
1795 | BrMatrix34PreTranslate(&m, -c->cmpos.v[0], -c->cmpos.v[1], -c->cmpos.v[2]); |
||
1796 | BrMatrix34PostTranslate(&m, c->cmpos.v[0], c->cmpos.v[1], c->cmpos.v[2]); |
||
1797 | BrMatrix34Pre(&c->car_master_actor->t.t.mat, &m); |
||
1798 | BrMatrix34TApplyV(&L2, &L, &m); |
||
1799 | c->omega.v[0] = L2.v[0] / c->I.v[0]; |
||
1800 | c->omega.v[1] = L2.v[1] / c->I.v[1]; |
||
1801 | c->omega.v[2] = L2.v[2] / c->I.v[2]; |
||
1802 | } |
||
1803 | |||
1804 | // IDA: void __usercall RotateCarFirstOrder(tCollision_info *c@<EAX>, br_scalar dt) |
||
1805 | void RotateCarFirstOrder(tCollision_info* c, br_scalar dt) { |
||
1806 | br_vector3 axis; |
||
1807 | br_vector3 L; |
||
1808 | br_vector3 L2; |
||
1809 | br_matrix34 m; |
||
1810 | br_scalar rad_rate; |
||
1811 | br_scalar rad; |
||
1812 | //br_scalar e1; // Pierre-Marie Baty -- unused variable |
||
1813 | //br_scalar e2; // Pierre-Marie Baty -- unused variable |
||
1814 | static br_scalar max_rad; |
||
1815 | LOG_TRACE("(%p, %f)", c, dt); |
||
1816 | |||
1817 | rad_rate = BrVector3Length(&c->omega); |
||
1818 | rad = rad_rate * dt; |
||
1819 | |||
1820 | if (rad < .0001f) { |
||
1821 | return; |
||
1822 | } |
||
1823 | BrVector3InvScale(&axis, &c->omega, rad_rate); |
||
1824 | BrVector3Mul(&L, &c->I, &c->omega); |
||
1825 | BrMatrix34Rotate(&m, BrRadianToAngle(rad), &axis); |
||
1826 | BrMatrix34TApplyV(&L2, &L, &m); |
||
1827 | BrMatrix34PreTranslate(&m, -c->cmpos.v[0], -c->cmpos.v[1], -c->cmpos.v[2]); |
||
1828 | BrMatrix34PostTranslate(&m, c->cmpos.v[0], c->cmpos.v[1], c->cmpos.v[2]); |
||
1829 | BrMatrix34Pre(&c->car_master_actor->t.t.mat, &m); |
||
1830 | c->omega.v[0] = L2.v[0] / c->I.v[0]; |
||
1831 | c->omega.v[1] = L2.v[1] / c->I.v[1]; |
||
1832 | c->omega.v[2] = L2.v[2] / c->I.v[2]; |
||
1833 | } |
||
1834 | |||
1835 | // IDA: void __usercall SimpleRotate(tCollision_info *c@<EAX>, br_scalar dt) |
||
1836 | void SimpleRotate(tCollision_info* c, br_scalar dt) { |
||
1837 | br_vector3 axis; |
||
1838 | br_scalar rad_rate; |
||
1839 | br_scalar rad; |
||
1840 | LOG_TRACE("(%p, %f)", c, dt); |
||
1841 | |||
1842 | rad_rate = BrVector3Length(&c->omega); |
||
1843 | BrVector3InvScale(&axis, &c->omega, rad_rate); |
||
1844 | rad = rad_rate * dt; |
||
1845 | if (rad >= 0.0001) { |
||
1846 | BrMatrix34PreRotate(&c->car_master_actor->t.t.mat, BrRadianToAngle(rad), &axis); |
||
1847 | } |
||
1848 | } |
||
1849 | |||
1850 | // IDA: void __usercall RotateCar(tCollision_info *c@<EAX>, br_scalar dt) |
||
1851 | void RotateCar(tCollision_info* c, br_scalar dt) { |
||
1852 | br_scalar rad_squared; |
||
1853 | int steps; |
||
1854 | int i; |
||
1855 | LOG_TRACE("(%p, %f)", c, dt); |
||
1856 | |||
1857 | rad_squared = BrVector3LengthSquared(&c->omega) * dt; |
||
1858 | BrVector3Copy(&c->oldomega, &c->omega); |
||
1859 | |||
1860 | if (rad_squared < .0000001f) { |
||
1861 | return; |
||
1862 | } |
||
1863 | |||
1864 | if (rad_squared > .008f) { |
||
1865 | steps = sqrtf(rad_squared / .032f) + 1; |
||
1866 | dt = dt / steps; |
||
1867 | |||
1868 | for (i = 0; i < steps && i < 20; i++) { |
||
1869 | RotateCarSecondOrder(c, dt); |
||
1870 | } |
||
1871 | } else { |
||
1872 | RotateCarFirstOrder(c, dt); |
||
1873 | } |
||
1874 | } |
||
1875 | |||
1876 | // IDA: void __usercall SteeringSelfCentre(tCar_spec *c@<EAX>, br_scalar dt, br_vector3 *n) |
||
1877 | void SteeringSelfCentre(tCar_spec* c, br_scalar dt, br_vector3* n) { |
||
1878 | br_scalar ts; |
||
1879 | br_scalar ts2; |
||
1880 | LOG_TRACE("(%p, %f, %p)", c, dt, n); |
||
1881 | |||
1882 | if (c->curvature > c->maxcurve) { |
||
1883 | c->curvature = c->maxcurve; |
||
1884 | } |
||
1885 | if (-c->maxcurve > c->curvature) { |
||
1886 | c->curvature = -c->maxcurve; |
||
1887 | } |
||
1888 | if (!c->keys.left && c->joystick.left <= 0 && !c->keys.right && c->joystick.right <= 0 && !c->keys.holdw) { |
||
1889 | if (c->susp_height[1] > c->oldd[2] || c->susp_height[1] > c->oldd[3]) { |
||
1890 | 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]))); |
||
1891 | ts2 = -(c->curvature * dt); |
||
1892 | if (fabs(ts) < fabs(ts2) || (ts * ts2 < 0.0)) { |
||
1893 | ts = ts2; |
||
1894 | } |
||
1895 | c->curvature = c->curvature + ts; |
||
1896 | if (c->curvature * ts > 0.0) { |
||
1897 | c->curvature = 0.0; |
||
1898 | } |
||
1899 | } |
||
1900 | } |
||
1901 | } |
||
1902 | |||
1903 | // IDA: void __usercall NonCarCalcForce(tNon_car_spec *nc@<EAX>, br_scalar dt) |
||
1904 | void NonCarCalcForce(tNon_car_spec* nc, br_scalar dt) { |
||
1905 | tCollision_info* c; |
||
1906 | tSpecial_volume* vol; |
||
1907 | br_scalar ts; |
||
1908 | br_vector3 tv; |
||
1909 | br_vector3 v; |
||
1910 | LOG_TRACE("(%p, %f)", nc, dt); |
||
1911 | |||
1912 | c = &nc->collision_info; |
||
1913 | vol = nc->collision_info.last_special_volume; |
||
1914 | if (nc->collision_info.car_master_actor->identifier[3] != '!') { |
||
1915 | if (c->car_master_actor->t.t.mat.m[1][1] < nc->snap_off_cosine || c->min_torque_squared == 0.0f) { |
||
1916 | c->car_master_actor->identifier[3] = '!'; |
||
1917 | c->M = nc->free_mass; |
||
1918 | c->min_torque_squared = 0.0f; |
||
1919 | BrVector3Sub(&v, &nc->free_cmpos, &c->cmpos); |
||
1920 | BrVector3Cross(&tv, &c->omega, &v); |
||
1921 | BrMatrix34ApplyV(&v, &tv, &c->car_master_actor->t.t.mat); |
||
1922 | BrVector3Accumulate(&c->v, &v); |
||
1923 | c->cmpos = nc->free_cmpos; |
||
1924 | } else { |
||
1925 | BrVector3SetFloat(&c->v, 0.0f, 0.0f, 0.0f); |
||
1926 | ts = BrVector3LengthSquared(&c->omega); |
||
1927 | BrVector3SetFloat(&c->omega, 0.0f, 0.0f, 0.0f); |
||
1928 | c->doing_nothing_flag = 1; |
||
1929 | } |
||
1930 | } |
||
1931 | if (c->car_master_actor->identifier[3] == '!') { |
||
1932 | if (vol != NULL) { |
||
1933 | c->v.v[1] = c->v.v[1] - dt * 10.0f * vol->gravity_multiplier; |
||
1934 | } else { |
||
1935 | c->v.v[1] = c->v.v[1] - dt * 10.0f; |
||
1936 | } |
||
1937 | ts = BrVector3Length(&c->v); |
||
1938 | if (vol != NULL) { |
||
1939 | ts = vol->viscosity_multiplier * ts; |
||
1940 | } |
||
1941 | ts = -(dt * 0.0005f * ts) / c->M; |
||
1942 | BrVector3Scale(&v, &c->v, ts); |
||
1943 | BrVector3Accumulate(&c->v, &v); |
||
1944 | ts = BrVector3Length(&c->omega); |
||
1945 | if (vol != NULL) { |
||
1946 | ts = vol->viscosity_multiplier * ts; |
||
1947 | } |
||
1948 | ts = -(dt * 0.0005 * ts); |
||
1949 | BrVector3Scale(&v, &c->omega, ts); |
||
1950 | ApplyTorque(CAR(c), &v); |
||
1951 | } |
||
1952 | } |
||
1953 | |||
1954 | // IDA: void __usercall AddDrag(tCar_spec *c@<EAX>, br_scalar dt) |
||
1955 | void AddDrag(tCar_spec* c, br_scalar dt) { |
||
1956 | br_scalar drag_multiplier; |
||
1957 | br_scalar ts; |
||
1958 | tSpecial_volume* vol; |
||
1959 | br_vector3 b; |
||
1960 | LOG_TRACE("(%p, %f)", c, dt); |
||
1961 | |||
1962 | vol = c->last_special_volume; |
||
1963 | drag_multiplier = -(dt * TIME_CONV_THING); |
||
1964 | if (vol != NULL) { |
||
1965 | if (c->underwater_ability) { |
||
1966 | drag_multiplier = vol->viscosity_multiplier * drag_multiplier * .6f; |
||
1967 | } else { |
||
1968 | drag_multiplier = vol->viscosity_multiplier * drag_multiplier; |
||
1969 | } |
||
1970 | drag_multiplier = c->water_depth_factor * drag_multiplier; |
||
1971 | } |
||
1972 | ts = BrVector3Length(&c->v) * drag_multiplier / c->M; |
||
1973 | BrVector3Scale(&b, &c->v, ts); |
||
1974 | BrVector3Accumulate(&c->v, &b); |
||
1975 | ts = BrVector3Length(&c->omega) * drag_multiplier; |
||
1976 | BrVector3Scale(&b, &c->omega, ts); |
||
1977 | ApplyTorque(c, &b); |
||
1978 | } |
||
1979 | |||
1980 | // IDA: void __usercall DoBumpiness(tCar_spec *c@<EAX>, br_vector3 *wheel_pos@<EDX>, br_vector3 *norm@<EBX>, br_scalar *d@<ECX>, int n) |
||
1981 | void DoBumpiness(tCar_spec* c, br_vector3* wheel_pos, br_vector3* norm, br_scalar* d, int n) { |
||
1982 | br_vector3 tv; |
||
1983 | int delta; |
||
1984 | int x; |
||
1985 | int y; |
||
1986 | tMaterial_modifiers* mat_list; |
||
1987 | LOG_TRACE("(%p, %p, %p, %p, %d)", c, wheel_pos, norm, d, n); |
||
1988 | |||
1989 | tv.v[0] = c->nor[n].v[0] * d[n] + wheel_pos[n].v[0]; |
||
1990 | tv.v[2] = c->nor[n].v[2] * d[n] + wheel_pos[n].v[2]; |
||
1991 | |||
1992 | x = abs((int)(512.0f * tv.v[0])) % 2048; |
||
1993 | y = abs((int)(512.0f * tv.v[2])) % 2048; |
||
1994 | |||
1995 | if (x > 1024) { |
||
1996 | x = 2048 - x; |
||
1997 | } |
||
1998 | if (y > 1024) { |
||
1999 | y = 2048 - y; |
||
2000 | } |
||
2001 | if (x + y <= 1024) { |
||
2002 | delta = x + y; |
||
2003 | } else { |
||
2004 | delta = 2048 - x - y; |
||
2005 | } |
||
2006 | delta -= 400; |
||
2007 | if (delta < 0) { |
||
2008 | delta = 0; |
||
2009 | } |
||
2010 | mat_list = gCurrent_race.material_modifiers; |
||
2011 | d[n] = delta * mat_list[c->material_index[n]].bumpiness / 42400.0f * norm[n].v[1] + d[n]; |
||
2012 | } |
||
2013 | |||
2014 | // IDA: void __usercall CalcForce(tCar_spec *c@<EAX>, br_scalar dt) |
||
2015 | void CalcForce(tCar_spec* c, br_scalar dt) { |
||
2016 | //int n; // Pierre-Marie Baty -- unused variable |
||
2017 | int normnum; |
||
2018 | int i; |
||
2019 | //int x; // Pierre-Marie Baty -- unused variable |
||
2020 | //int y; // Pierre-Marie Baty -- unused variable |
||
2021 | br_scalar force[4]; |
||
2022 | br_scalar d[4]; |
||
2023 | br_scalar ts; |
||
2024 | br_scalar ts2; |
||
2025 | br_scalar ts3; |
||
2026 | br_scalar ts4; |
||
2027 | //br_scalar ts5; // Pierre-Marie Baty -- unused variable |
||
2028 | //br_scalar ts6; // Pierre-Marie Baty -- unused variable |
||
2029 | br_scalar deltaomega; |
||
2030 | br_scalar wheelratio; |
||
2031 | //br_scalar modf; // Pierre-Marie Baty -- unused variable |
||
2032 | br_scalar maxfl; |
||
2033 | br_scalar maxfr; |
||
2034 | //br_scalar max_retardation; // Pierre-Marie Baty -- unused variable |
||
2035 | //br_scalar front_retardation; // Pierre-Marie Baty -- unused variable |
||
2036 | br_scalar friction_number; |
||
2037 | br_vector3 a; |
||
2038 | br_vector3 b; |
||
2039 | //br_vector3 tv; // Pierre-Marie Baty -- unused variable |
||
2040 | //br_vector3 tv2; // Pierre-Marie Baty -- unused variable |
||
2041 | br_vector3 norm[4]; |
||
2042 | //br_vector3 v_batwick; // Pierre-Marie Baty -- unused variable |
||
2043 | br_vector3 vplane; |
||
2044 | br_vector3 rightplane; |
||
2045 | //br_vector3 t; // Pierre-Marie Baty -- unused variable |
||
2046 | br_vector3 f; |
||
2047 | //br_vector3 ff; // Pierre-Marie Baty -- unused variable |
||
2048 | //br_vector3 fb; // Pierre-Marie Baty -- unused variable |
||
2049 | //br_scalar ffi; // Pierre-Marie Baty -- unused variable |
||
2050 | //br_scalar ffk; // Pierre-Marie Baty -- unused variable |
||
2051 | //br_scalar fbi; // Pierre-Marie Baty -- unused variable |
||
2052 | //br_scalar fbk; // Pierre-Marie Baty -- unused variable |
||
2053 | br_vector3 wheel_pos[4]; |
||
2054 | //br_scalar direction; // Pierre-Marie Baty -- unused variable |
||
2055 | //br_scalar wheel_spin_force; // Pierre-Marie Baty -- unused variable |
||
2056 | //br_scalar d_damage; // Pierre-Marie Baty -- unused variable |
||
2057 | br_scalar fl_oil_factor; |
||
2058 | br_scalar fr_oil_factor; |
||
2059 | br_scalar rl_oil_factor; |
||
2060 | br_scalar rr_oil_factor; |
||
2061 | br_matrix34* mat; |
||
2062 | tMaterial_modifiers* mat_list; |
||
2063 | static br_scalar stop_timer; |
||
2064 | static br_scalar slide_dist; |
||
2065 | //tDamage_type dam; // Pierre-Marie Baty -- unused variable |
||
2066 | //br_scalar v; // Pierre-Marie Baty -- unused variable |
||
2067 | tSpecial_volume* vol; |
||
2068 | //br_scalar scale; // Pierre-Marie Baty -- unused variable |
||
2069 | LOG_TRACE("(%p, %f)", c, dt); |
||
2070 | |||
2071 | int v72; // [esp+24h] [ebp-1C8h] |
||
2072 | double v73; // [esp+2Ch] [ebp-1C0h] |
||
2073 | float v74; // [esp+34h] [ebp-1B8h] |
||
2074 | float v75; // [esp+38h] [ebp-1B4h] |
||
2075 | float v76; // [esp+3Ch] [ebp-1B0h] |
||
2076 | float v77; // [esp+40h] [ebp-1ACh] |
||
2077 | float v78; // [esp+44h] [ebp-1A8h] |
||
2078 | float v79; // [esp+48h] [ebp-1A4h] |
||
2079 | //float v80; // [esp+4Ch] [ebp-1A0h] MAPDST // Pierre-Marie Baty -- unused variable |
||
2080 | //float v82; // [esp+50h] [ebp-19Ch] MAPDST // Pierre-Marie Baty -- unused variable |
||
2081 | //float v84; // [esp+54h] [ebp-198h] // Pierre-Marie Baty -- unused variable |
||
2082 | //float v85; // [esp+58h] [ebp-194h] MAPDST // Pierre-Marie Baty -- unused variable |
||
2083 | float v87; // [esp+5Ch] [ebp-190h] MAPDST |
||
2084 | float v98; // [esp+88h] [ebp-164h] |
||
2085 | float v99; // [esp+8Ch] [ebp-160h] |
||
2086 | br_vector3 v102; // [esp+98h] [ebp-154h] |
||
2087 | br_vector3 v103; // [esp+A4h] [ebp-148h] |
||
2088 | int v105; // [esp+B8h] [ebp-134h] |
||
2089 | float v106; // [esp+C0h] [ebp-12Ch] |
||
2090 | br_vector3 v107; // [esp+C4h] [ebp-128h] |
||
2091 | float v108; // [esp+D0h] [ebp-11Ch] |
||
2092 | float v109; // [esp+D4h] [ebp-118h] |
||
2093 | float v116; // [esp+F8h] [ebp-F4h] |
||
2094 | br_vector3 B; // [esp+FCh] [ebp-F0h] BYREF |
||
2095 | br_scalar pV; // [esp+10Ch] [ebp-E0h] |
||
2096 | br_vector3 v123; // [esp+130h] [ebp-BCh] |
||
2097 | float v125; // [esp+16Ch] [ebp-80h] |
||
2098 | float v128; // [esp+18Ch] [ebp-60h] |
||
2099 | float v129; // [esp+190h] [ebp-5Ch] |
||
2100 | float v134; // [esp+1D8h] [ebp-14h] |
||
2101 | float v135; // [esp+1DCh] [ebp-10h] |
||
2102 | br_vector3 v136; // [esp+1E0h] [ebp-Ch] |
||
2103 | |||
2104 | BrVector3Set(&v136, 0, 0, 0); |
||
2105 | normnum = 0; |
||
2106 | BrVector3Set(&f, 0, 0, 0); |
||
2107 | BrVector3Set(&B, 0, 0, 0); |
||
2108 | mat = &c->car_master_actor->t.t.mat; |
||
2109 | mat_list = gCurrent_race.material_modifiers; |
||
2110 | vol = c->last_special_volume; |
||
2111 | b.v[0] = -mat->m[1][0]; |
||
2112 | b.v[1] = -mat->m[1][1]; |
||
2113 | b.v[2] = -mat->m[1][2]; |
||
2114 | c->material_index[0] = 0; |
||
2115 | c->material_index[1] = 0; |
||
2116 | c->material_index[2] = 0; |
||
2117 | c->material_index[3] = 0; |
||
2118 | wheelratio = (c->wpos[2].v[2] - c->cmpos.v[2]) / (c->wpos[0].v[2] - c->cmpos.v[2]); |
||
2119 | BrVector3Set(&c->road_normal, 0, 0, 0); |
||
2120 | for (i = 0; i < 4; ++i) { |
||
2121 | BrMatrix34ApplyP(&wheel_pos[i], &c->wpos[i], mat); |
||
2122 | } |
||
2123 | MultiFindFloorInBoxM(4, wheel_pos, &b, c->nor, d, c, c->material_index); |
||
2124 | if (c->last_special_volume && c->last_special_volume->material_modifier_index) { |
||
2125 | c->material_index[0] = c->last_special_volume->material_modifier_index; |
||
2126 | c->material_index[1] = c->material_index[0]; |
||
2127 | c->material_index[2] = c->material_index[1]; |
||
2128 | c->material_index[3] = c->material_index[2]; |
||
2129 | } |
||
2130 | for (i = 0; i < 4; ++i) { |
||
2131 | BrMatrix34TApplyV(&norm[i], &c->nor[i], mat); |
||
2132 | if (mat_list[c->material_index[i]].bumpiness != 0.0) { |
||
2133 | DoBumpiness(c, wheel_pos, norm, d, i); |
||
2134 | } |
||
2135 | if (d[i] < -0.5 || c->wheel_dam_offset[i ^ 2] * 6.9 + c->susp_height[i / 2] < d[i]) { |
||
2136 | force[i] = 0.0; |
||
2137 | d[i] = c->susp_height[i / 2]; |
||
2138 | } else { |
||
2139 | BrVector3Accumulate(&c->road_normal, &norm[i]); |
||
2140 | normnum++; |
||
2141 | d[i] = d[i] - c->wheel_dam_offset[i ^ 2] * 6.9; |
||
2142 | force[i] = (c->susp_height[i / 2] - d[i]) * c->sk[1 / 2]; |
||
2143 | force[i] = force[i] - (d[i] - c->oldd[i]) / dt * c->sb[i / 2]; |
||
2144 | if (c->susp_height[i / 2] == c->oldd[i] |
||
2145 | && 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 |
||
2146 | && c->M * 20.0 / 4.0 < force[i]) { |
||
2147 | d[i] = c->susp_height[i / 2]; |
||
2148 | force[i] = c->M * 20.0 / 4.0; |
||
2149 | } |
||
2150 | if (force[i] < 0.0) { |
||
2151 | force[i] = 0.0; |
||
2152 | } |
||
2153 | B.v[1] = force[i] + B.v[1]; |
||
2154 | f.v[0] = f.v[0] - (c->wpos[i].v[2] - c->cmpos.v[2]) * force[i]; |
||
2155 | f.v[2] = (c->wpos[i].v[0] - c->cmpos.v[0]) * force[i] + f.v[2]; |
||
2156 | } |
||
2157 | c->oldd[i] = d[i]; |
||
2158 | } |
||
2159 | 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)) { |
||
2160 | if (vol) { |
||
2161 | friction_number = (1.0 - vol->gravity_multiplier) * c->water_depth_factor; |
||
2162 | if (c->underwater_ability) { |
||
2163 | friction_number = friction_number * 0.6; |
||
2164 | } |
||
2165 | friction_number = (1.0 - friction_number) * c->M; |
||
2166 | } else { |
||
2167 | friction_number = c->M; |
||
2168 | } |
||
2169 | friction_number = friction_number * gGravity_multiplier * 10.0; |
||
2170 | B.v[0] = B.v[0] - mat->m[0][1] * friction_number; |
||
2171 | B.v[1] = B.v[1] - mat->m[1][1] * friction_number; |
||
2172 | B.v[2] = B.v[2] - mat->m[2][1] * friction_number; |
||
2173 | } else { |
||
2174 | BrVector3Normalise(&v107, &c->road_normal); |
||
2175 | BrVector3Scale(&v107, &v107, -(c->M * 10.0)); |
||
2176 | BrVector3Accumulate(&B, &v107); |
||
2177 | } |
||
2178 | if (c->driver >= eDriver_net_human) { |
||
2179 | SteeringSelfCentre(c, dt, &c->road_normal); |
||
2180 | } |
||
2181 | if (normnum) { |
||
2182 | // ts = 1.0 / sqrt(1.0); <- looked like this in the windows build definitely wrong |
||
2183 | // 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]); |
||
2184 | // c->road_normal.v[0] = c->road_normal.v[0] * ts; |
||
2185 | // c->road_normal.v[1] = c->road_normal.v[1] * ts; |
||
2186 | // c->road_normal.v[2] = c->road_normal.v[2] * ts; |
||
2187 | BrVector3NormaliseQuick(&c->road_normal, &c->road_normal); |
||
2188 | |||
2189 | 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]; |
||
2190 | if (c->driver > eDriver_non_car && c->wall_climber_mode) { |
||
2191 | friction_number = 1.0; |
||
2192 | } |
||
2193 | friction_number = gCurrent_race.material_modifiers[c->material_index[0]].down_force * friction_number; |
||
2194 | if (friction_number > 0.0f) { |
||
2195 | friction_number = fabs(c->velocity_car_space.v[2]) * c->M * 10.0 * friction_number / c->down_force_speed; |
||
2196 | if (c->M * 10.0 < friction_number) { |
||
2197 | friction_number = c->M * 10.0; |
||
2198 | } |
||
2199 | if (c->number_of_wheels_on_ground == 4 && c->oldd[2] == c->susp_height[1] && c->oldd[3] == c->susp_height[1]) { |
||
2200 | a.v[0] = c->wpos[2].v[2] * mat->m[2][0]; |
||
2201 | a.v[1] = c->wpos[2].v[2] * mat->m[2][1]; |
||
2202 | a.v[2] = c->wpos[2].v[2] * mat->m[2][2]; |
||
2203 | a.v[0] = mat->m[3][0] + a.v[0]; |
||
2204 | a.v[1] = mat->m[3][1] + a.v[1]; |
||
2205 | a.v[2] = mat->m[3][2] + a.v[2]; |
||
2206 | BrVector3Scale(&b, &b, (c->wpos[0].v[2] - c->wpos[2].v[2])); |
||
2207 | findfloor(&a, &b, norm, &ts2); |
||
2208 | if (ts2 > 1.0) { |
||
2209 | c->down_force_flag = 1; |
||
2210 | } |
||
2211 | } else if (c->down_force_flag && (c->oldd[2] < c->susp_height[1] || c->oldd[3] < c->susp_height[1])) { |
||
2212 | c->down_force_flag = 0; |
||
2213 | } |
||
2214 | if (c->down_force_flag) { |
||
2215 | friction_number = (c->wpos[2].v[2] - c->cmpos.v[2]) / (c->wpos[2].v[2] - c->wpos[0].v[2]) * friction_number; |
||
2216 | f.v[0] = (c->wpos[0].v[2] - c->cmpos.v[2]) * friction_number + f.v[0]; |
||
2217 | } |
||
2218 | B.v[1] = B.v[1] - friction_number; |
||
2219 | } |
||
2220 | vplane.v[0] = BrVector3Dot(&c->velocity_car_space, &c->road_normal) * c->road_normal.v[0]; |
||
2221 | vplane.v[1] = BrVector3Dot(&c->velocity_car_space, &c->road_normal) * c->road_normal.v[1]; |
||
2222 | vplane.v[2] = BrVector3Dot(&c->velocity_car_space, &c->road_normal) * c->road_normal.v[2]; |
||
2223 | BrVector3Sub(&vplane, &c->velocity_car_space, &vplane); |
||
2224 | if (vplane.v[2] < 0.0) { |
||
2225 | ts = 1.0; |
||
2226 | } else { |
||
2227 | ts = -1.0; |
||
2228 | } |
||
2229 | ts3 = BrVector3Length(&vplane); |
||
2230 | deltaomega = ts3 * c->curvature * ts; |
||
2231 | deltaomega = deltaomega - BrVector3Dot(&c->omega, &c->road_normal); |
||
2232 | BrVector3Set(&v103, c->road_normal.v[1], -c->road_normal.v[0], 0); |
||
2233 | BrVector3Normalise(&v103, &v103); |
||
2234 | |||
2235 | friction_number = c->I.v[1] / dt * deltaomega; |
||
2236 | ts = friction_number / (c->wpos[2].v[2] - c->wpos[0].v[2]); |
||
2237 | v108 = ts; |
||
2238 | v109 = -ts; |
||
2239 | BrVector3Set(&rightplane, 0, c->road_normal.v[2], -c->road_normal.v[1]); |
||
2240 | BrVector3Normalise(&rightplane, &rightplane); |
||
2241 | v99 = c->acc_force; |
||
2242 | friction_number = BrVector3Dot(&rightplane, &vplane); |
||
2243 | v87 = BrVector3Dot(&v103, &vplane); |
||
2244 | ts2 = fabs(v87); |
||
2245 | friction_number = (c->wpos[0].v[2] - c->cmpos.v[2]) * friction_number * fabs(c->curvature); |
||
2246 | if (c->curvature <= 0.0) { |
||
2247 | friction_number = v87 - friction_number; |
||
2248 | } else { |
||
2249 | friction_number = v87 + friction_number; |
||
2250 | } |
||
2251 | friction_number = -(c->M / dt * friction_number); |
||
2252 | friction_number = friction_number - BrVector3Dot(&B, &v103); |
||
2253 | |||
2254 | friction_number = friction_number / (1.0 - wheelratio); |
||
2255 | v108 = friction_number + v108; |
||
2256 | v109 = -wheelratio * friction_number + v109; |
||
2257 | friction_number = (c->wpos[0].v[2] - c->wpos[2].v[2]) * v108; |
||
2258 | v98 = friction_number * c->curvature; |
||
2259 | friction_number = BrVector3Dot(&c->velocity_car_space, &rightplane) * c->M / dt; |
||
2260 | v129 = BrVector3Dot(&rightplane, &B) + friction_number; |
||
2261 | v128 = c->mu[0] * c->brake_force / (c->mu[1] / c->friction_elipticity + c->mu[0]); |
||
2262 | v125 = c->brake_force - v128; |
||
2263 | v105 = (c->damage_units[7].damage_level + c->damage_units[6].damage_level) / 2; |
||
2264 | if (v105 > 20) { |
||
2265 | v128 = (1.0 - (double)(v105 - 20) / 80.0) * (1.0 - (double)(v105 - 20) / 80.0) * v128; |
||
2266 | } |
||
2267 | v105 = (c->damage_units[5].damage_level + c->damage_units[4].damage_level) / 2; |
||
2268 | if (v105 > 20) { |
||
2269 | v125 = (1.0 - (double)(v105 - 20) / 80.0) * (1.0 - (double)(v105 - 20) / 80.0) * v125; |
||
2270 | } |
||
2271 | ts2 = (force[1] + force[0]) * c->rolling_r_back + v128; |
||
2272 | v87 = (force[2] + force[3]) * c->rolling_r_front + v125; |
||
2273 | v128 = c->wpos[0].v[2] - c->wpos[2].v[2]; |
||
2274 | v128 = sqrt(v128 * v128 * c->curvature * c->curvature + 1.0); |
||
2275 | v106 = v87 / v128; |
||
2276 | v134 = v106 + ts2; |
||
2277 | if (fabs(v129) < fabs(v134)) { |
||
2278 | ts2 = v129 / v134 * ts2; |
||
2279 | v106 = v129 / v134 * v106; |
||
2280 | } |
||
2281 | if ((v87 + ts2) * v129 < 0.0) { |
||
2282 | ts2 = -ts2; |
||
2283 | v106 = -v106; |
||
2284 | } |
||
2285 | v129 = v129 - (ts2 + v106); |
||
2286 | v99 = v99 - ts2; |
||
2287 | if (c->keys.brake && c->damage_units[eDamage_lr_brake].damage_level < 60 && c->damage_units[eDamage_rr_brake].damage_level < 60) { |
||
2288 | v99 = v99 - v129; |
||
2289 | c->gear = 0; |
||
2290 | } |
||
2291 | v99 = v99 / c->friction_elipticity; |
||
2292 | v135 = sqrt(v99 * v99 + v109 * v109) / 2.0; |
||
2293 | |||
2294 | GetOilFrictionFactors(c, &fl_oil_factor, &fr_oil_factor, &rl_oil_factor, &rr_oil_factor); |
||
2295 | if (c->driver <= eDriver_non_car) { |
||
2296 | v116 = 1.0; |
||
2297 | } else { |
||
2298 | v116 = c->grip_multiplier; |
||
2299 | } |
||
2300 | BrVector3Sub(&v102, &c->wpos[0], &c->cmpos); |
||
2301 | BrVector3Cross(&a, &c->omega, &v102); |
||
2302 | BrVector3Accumulate(&a, &c->velocity_car_space); |
||
2303 | if (c->driver >= eDriver_net_human |
||
2304 | && (((c->keys.left || c->joystick.left > 0x8000) && c->curvature > 0.0 && deltaomega > 0.1 && a.v[0] > 0.0) |
||
2305 | || ((c->keys.right || c->joystick.right > 0x8000) && c->curvature < 0.0 && deltaomega < 0.1 && a.v[0] < 0.0)) |
||
2306 | && ts > 0.0) { |
||
2307 | friction_number = c->mu[0]; |
||
2308 | } else { |
||
2309 | friction_number = c->mu[2]; |
||
2310 | ts2 = fabs(a.v[0]) / 10.0; |
||
2311 | if (ts2 > 1) { |
||
2312 | ts2 = 1.0; |
||
2313 | } |
||
2314 | friction_number = (c->mu[2] - c->mu[0]) * ts2 + friction_number; |
||
2315 | } |
||
2316 | |||
2317 | maxfl = sqrt(force[0]) * friction_number * (rl_oil_factor * v116) * mat_list[c->material_index[0]].tyre_road_friction; |
||
2318 | maxfr = sqrt(force[1]) * friction_number * (rr_oil_factor * v116) * mat_list[c->material_index[1]].tyre_road_friction; |
||
2319 | c->max_force_rear = maxfr + maxfl; |
||
2320 | 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 |
||
2321 | && (c->driver < eDriver_net_human || (c->target_revs > 1000.0 && c->gear > 0))) { |
||
2322 | ts2 = v99; |
||
2323 | if (v99 * v99 <= v135 * v135 * 4.0) { |
||
2324 | v87 = sqrt(v135 * v135 * 4.0 - v99 * v99); |
||
2325 | } else { |
||
2326 | v87 = 0.0; |
||
2327 | } |
||
2328 | if (c->max_force_rear <= v87) { |
||
2329 | c->torque = -(c->revs * c->revs / 100000000.0) - 0.1; |
||
2330 | } else { |
||
2331 | float v177 = sqrt(c->max_force_rear * c->max_force_rear - v87 * v87); |
||
2332 | ts3 = ts2 < 0.0 ? -1.0 : 1.0; |
||
2333 | // ts4 = (ts2 - ts3 * sqrt(ts3)) * 1.01; |
||
2334 | // if (fabs(ts2) > fabs(ts4)) { |
||
2335 | // v87 = ts4; |
||
2336 | // ts2 = v87; |
||
2337 | // } |
||
2338 | |||
2339 | ts4 = (ts2 - ts3 * v177) * 1.01; |
||
2340 | if (fabs(ts2) > fabs(ts4)) { |
||
2341 | ts2 = ts4; |
||
2342 | } |
||
2343 | } |
||
2344 | v99 = v99 - ts2; |
||
2345 | v135 = sqrt(v99 * v99 + v109 * v109) / 2.0; |
||
2346 | |||
2347 | } else if (c->driver >= eDriver_net_human && c->gear > 0 && c->revs > c->target_revs && !c->traction_control) { |
||
2348 | if (!c->keys.change_down) { |
||
2349 | c->traction_control = 1; |
||
2350 | } |
||
2351 | friction_number = 1.0 - (c->revs - c->target_revs) / (double)(400 * c->gear); |
||
2352 | if (friction_number < 0.40000001) { |
||
2353 | friction_number = (br_scalar) 0.40000001; // Pierre-Marie Baty -- added type cast |
||
2354 | } |
||
2355 | maxfl = friction_number * maxfl; |
||
2356 | maxfr = friction_number * maxfr; |
||
2357 | } |
||
2358 | if (fabs(v109) > maxfr + maxfl && maxfr + maxfl > 0.1) { |
||
2359 | v87 = (maxfr + maxfl) / fabs(v109) * dt; |
||
2360 | v109 = v87 * v109; |
||
2361 | v99 = c->friction_elipticity * v87 * v99; |
||
2362 | 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); |
||
2363 | ts2 = (BrVector3Dot(&v103, &vplane) + v109 / c->M) * v108; |
||
2364 | ts2 = BrVector3Dot(&rightplane, &vplane) * v98 + ts2; |
||
2365 | ts2 = BrVector3Dot(&c->omega, &c->road_normal) * (c->wpos[2].v[2] - c->cmpos.v[2]) * v108 + ts2; |
||
2366 | 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; |
||
2367 | if (fabs(friction_number) > 0.1) { |
||
2368 | friction_number = ts2 / (friction_number * dt); |
||
2369 | v108 = friction_number * v108; |
||
2370 | v98 = friction_number * v98; |
||
2371 | } |
||
2372 | v109 = v109 / v87; |
||
2373 | v99 = v99 / (c->friction_elipticity * v87); |
||
2374 | } |
||
2375 | v98 = v98 - v106; |
||
2376 | v108 = (c->wpos[0].v[2] - c->wpos[2].v[2]) * c->curvature * v106 + v108; |
||
2377 | if (v135 > 0.000099999997) { |
||
2378 | v109 = v109 / (v135 * 2.0); |
||
2379 | v99 = v99 / (v135 * 2.0); |
||
2380 | } |
||
2381 | v99 = c->friction_elipticity * v99; |
||
2382 | force[0] = v135; |
||
2383 | force[1] = v135; |
||
2384 | c->wheel_slip = 0; |
||
2385 | switch ((force[0] > maxfl) + 2 * (force[1] > maxfr)) { |
||
2386 | case 0: |
||
2387 | slide_dist = 0; |
||
2388 | break; |
||
2389 | case 1: |
||
2390 | force[0] = c->freduction * maxfl; |
||
2391 | force[1] = v135 - force[0] + force[1]; |
||
2392 | if (force[1] <= maxfr) { |
||
2393 | slide_dist = 0; |
||
2394 | } else { |
||
2395 | if (maxfr > 0.1) { |
||
2396 | pV = (force[1] - maxfr) / maxfr; |
||
2397 | if (&gProgram_state.current_car == c) { |
||
2398 | v78 = 20.0; |
||
2399 | } else { |
||
2400 | v78 = 60.0; |
||
2401 | } |
||
2402 | if (v78 <= pV) { |
||
2403 | c->new_skidding |= 2u; |
||
2404 | } |
||
2405 | SkidNoise(c, 1, pV, c->material_index[1]); |
||
2406 | } |
||
2407 | force[1] = c->freduction * maxfr; |
||
2408 | c->wheel_slip |= 2u; |
||
2409 | } |
||
2410 | break; |
||
2411 | case 2: |
||
2412 | force[1] = c->freduction * maxfr; |
||
2413 | force[0] = v135 - force[1] + force[0]; |
||
2414 | if (force[0] <= maxfl) { |
||
2415 | slide_dist = 0; |
||
2416 | } else { |
||
2417 | if (maxfl > 0.1) { |
||
2418 | pV = (force[0] - maxfl) / maxfl; |
||
2419 | if (&gProgram_state.current_car == c) { |
||
2420 | v77 = 20.0; |
||
2421 | } else { |
||
2422 | v77 = 60.0; |
||
2423 | } |
||
2424 | if (v77 <= pV) { |
||
2425 | c->new_skidding |= 1u; |
||
2426 | } |
||
2427 | SkidNoise(c, 0, pV, c->material_index[0]); |
||
2428 | } |
||
2429 | force[0] = c->freduction * maxfl; |
||
2430 | c->wheel_slip |= 2u; |
||
2431 | } |
||
2432 | break; |
||
2433 | case 3: |
||
2434 | force[0] = c->freduction * maxfl; |
||
2435 | force[1] = c->freduction * maxfr; |
||
2436 | c->wheel_slip |= 2u; |
||
2437 | pV = (v135 * 2.0 - maxfl - maxfr) / (maxfr + maxfl); |
||
2438 | if (&gProgram_state.current_car == c) { |
||
2439 | v79 = 20.0; |
||
2440 | } else { |
||
2441 | v79 = 60.0; |
||
2442 | } |
||
2443 | if (v79 <= pV) { |
||
2444 | if (maxfl > 0.1) { |
||
2445 | c->new_skidding |= 1u; |
||
2446 | } |
||
2447 | if (maxfr > 0.1) { |
||
2448 | c->new_skidding |= 2u; |
||
2449 | } |
||
2450 | } |
||
2451 | if (IRandomBetween(0, 1)) { |
||
2452 | if (maxfl > 0.1) { |
||
2453 | SkidNoise(c, 0, pV, c->material_index[0]); |
||
2454 | } |
||
2455 | } else if (maxfr > 0.1) { |
||
2456 | SkidNoise(c, 1, pV, c->material_index[1]); |
||
2457 | } |
||
2458 | break; |
||
2459 | default: |
||
2460 | break; |
||
2461 | } |
||
2462 | 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) { |
||
2463 | c->turn_speed = 0.0; |
||
2464 | } |
||
2465 | v135 = sqrt(v108 * v108 + v98 * v98) / 2.0; |
||
2466 | if (v135 > 0.000099999997) { |
||
2467 | v108 = v108 / (v135 * 2.0); |
||
2468 | v98 = v98 / (v135 * 2.0); |
||
2469 | } |
||
2470 | maxfl = sqrt(force[2]) * c->mu[1] * (fl_oil_factor * v116) * mat_list[c->material_index[2]].tyre_road_friction; |
||
2471 | maxfr = sqrt(force[3]) * c->mu[1] * (fr_oil_factor * v116) * mat_list[c->material_index[3]].tyre_road_friction; |
||
2472 | c->max_force_front = maxfr + maxfl; |
||
2473 | force[2] = v135; |
||
2474 | force[3] = v135; |
||
2475 | v72 = (v135 > maxfl) + 2 * (v135 > maxfr); |
||
2476 | switch (v72) { |
||
2477 | case 1: |
||
2478 | force[2] = c->freduction * maxfl; |
||
2479 | force[3] = v135 - force[2] + force[3]; |
||
2480 | if (force[3] > maxfr) { |
||
2481 | if (maxfr > 0.1) { |
||
2482 | pV = (force[3] - maxfr) / maxfr; |
||
2483 | if (&gProgram_state.current_car == c) { |
||
2484 | v75 = 20.0; |
||
2485 | } else { |
||
2486 | v75 = 60.0; |
||
2487 | } |
||
2488 | if (v75 <= pV) { |
||
2489 | c->new_skidding |= 8u; |
||
2490 | } |
||
2491 | SkidNoise(c, 3, pV, c->material_index[3]); |
||
2492 | } |
||
2493 | force[3] = c->freduction * maxfr; |
||
2494 | c->wheel_slip |= 1u; |
||
2495 | } |
||
2496 | break; |
||
2497 | case 2: |
||
2498 | force[3] = c->freduction * maxfr; |
||
2499 | force[2] = v135 - force[3] + force[2]; |
||
2500 | if (force[2] > maxfl) { |
||
2501 | if (maxfl > 0.1) { |
||
2502 | pV = (force[2] - maxfl) / maxfl; |
||
2503 | if (&gProgram_state.current_car == c) { |
||
2504 | v74 = 20.0; |
||
2505 | } else { |
||
2506 | v74 = 60.0; |
||
2507 | } |
||
2508 | if (v74 <= pV) { |
||
2509 | c->new_skidding |= 4u; |
||
2510 | } |
||
2511 | SkidNoise(c, 2, pV, c->material_index[2]); |
||
2512 | } |
||
2513 | force[2] = c->freduction * maxfl; |
||
2514 | c->wheel_slip |= 1u; |
||
2515 | } |
||
2516 | break; |
||
2517 | case 3: |
||
2518 | force[2] = c->freduction * maxfl; |
||
2519 | force[3] = c->freduction * maxfr; |
||
2520 | c->wheel_slip |= 1u; |
||
2521 | pV = (v135 * 2.0 - maxfl - maxfr) / (maxfr + maxfl); |
||
2522 | if (&gProgram_state.current_car == c) { |
||
2523 | v76 = 20.0; |
||
2524 | } else { |
||
2525 | v76 = 60.0; |
||
2526 | } |
||
2527 | if (v76 <= pV) { |
||
2528 | if (maxfl > 0.1) { |
||
2529 | c->new_skidding |= 4u; |
||
2530 | } |
||
2531 | if (maxfr > 0.1) { |
||
2532 | c->new_skidding |= 8u; |
||
2533 | } |
||
2534 | } |
||
2535 | if (IRandomBetween(0, 1)) { |
||
2536 | if (maxfl > 0.1) { |
||
2537 | SkidNoise(c, 2, pV, c->material_index[2]); |
||
2538 | } |
||
2539 | } else if (maxfr > 0.1) { |
||
2540 | SkidNoise(c, 3, pV, c->material_index[3]); |
||
2541 | } |
||
2542 | break; |
||
2543 | } |
||
2544 | BrVector3Scale(&v136, &rightplane, v99); |
||
2545 | BrVector3Scale(&a, &v103, v109); |
||
2546 | BrVector3Accumulate(&v136, &a); |
||
2547 | BrVector3Scale(&v123, &rightplane, v98); |
||
2548 | BrVector3Scale(&a, &v103, v108); |
||
2549 | BrVector3Accumulate(&v123, &a); |
||
2550 | |||
2551 | rightplane = c->wpos[0]; |
||
2552 | rightplane.v[1] = rightplane.v[1] - c->oldd[0]; |
||
2553 | BrVector3Sub(&rightplane, &rightplane, &c->cmpos); |
||
2554 | BrVector3Scale(&b, &v136, force[0]); |
||
2555 | BrVector3Accumulate(&B, &b); |
||
2556 | BrVector3Cross(&a, &rightplane, &b); |
||
2557 | BrVector3Accumulate(&f, &a); |
||
2558 | |||
2559 | rightplane = c->wpos[1]; |
||
2560 | rightplane.v[1] = rightplane.v[1] - c->oldd[1]; |
||
2561 | BrVector3Sub(&rightplane, &rightplane, &c->cmpos); |
||
2562 | BrVector3Scale(&b, &v136, force[1]); |
||
2563 | BrVector3Accumulate(&B, &b); |
||
2564 | BrVector3Cross(&a, &rightplane, &b); |
||
2565 | BrVector3Accumulate(&f, &a); |
||
2566 | |||
2567 | rightplane = c->wpos[2]; |
||
2568 | rightplane.v[1] = rightplane.v[1] - c->oldd[2]; |
||
2569 | BrVector3Sub(&rightplane, &rightplane, &c->cmpos); |
||
2570 | BrVector3Scale(&b, &v123, force[2]); |
||
2571 | BrVector3Accumulate(&B, &b); |
||
2572 | BrVector3Cross(&a, &rightplane, &b); |
||
2573 | BrVector3Accumulate(&f, &a); |
||
2574 | |||
2575 | rightplane = c->wpos[3]; |
||
2576 | rightplane.v[1] = rightplane.v[1] - c->oldd[3]; |
||
2577 | BrVector3Sub(&rightplane, &rightplane, &c->cmpos); |
||
2578 | BrVector3Scale(&b, &v123, force[3]); |
||
2579 | BrVector3Accumulate(&B, &b); |
||
2580 | BrVector3Cross(&a, &rightplane, &b); |
||
2581 | BrVector3Accumulate(&f, &a); |
||
2582 | |||
2583 | } else { |
||
2584 | c->max_force_front = 0.0; |
||
2585 | c->max_force_rear = 0.0; |
||
2586 | StopSkid(c); |
||
2587 | } |
||
2588 | c->number_of_wheels_on_ground = normnum; |
||
2589 | BrMatrix34ApplyV(&b, &B, mat); |
||
2590 | BrVector3Scale(&rightplane, &f, dt); |
||
2591 | ApplyTorque(c, &rightplane); |
||
2592 | BrVector3Scale(&rightplane, &b, dt / c->M); |
||
2593 | BrVector3Accumulate(&c->v, &rightplane); |
||
2594 | if (c->speed < 0.000099999997 |
||
2595 | && ((!c->keys.acc && c->joystick.acc <= 0) || !c->gear) |
||
2596 | && !c->keys.dec |
||
2597 | && c->joystick.dec <= 0 |
||
2598 | && c->bounce_rate == 0.0 |
||
2599 | && BrVector3Length(&c->omega) < 0.05) { |
||
2600 | if (vol) { |
||
2601 | v73 = c->driver > eDriver_non_car && c->underwater_ability ? 1.0 - (1.0 - vol->gravity_multiplier) * 0.6 : vol->gravity_multiplier; |
||
2602 | friction_number = BrVector3Length(&b) / v73 / gGravity_multiplier; |
||
2603 | } else { |
||
2604 | friction_number = BrVector3Length(&b); |
||
2605 | } |
||
2606 | if (c->M > friction_number || (c->keys.brake && normnum >= 3)) { |
||
2607 | if (stop_timer == 100.0) { |
||
2608 | stop_timer = 0.0; |
||
2609 | } |
||
2610 | if (stop_timer > 0.5) { |
||
2611 | BrVector3SetFloat(&c->v, 0.0, 0.0, 0.0); |
||
2612 | BrVector3SetFloat(&c->omega, 0.0, 0.0, 0.0); |
||
2613 | stop_timer = 0.5; |
||
2614 | } |
||
2615 | } |
||
2616 | } |
||
2617 | stop_timer = dt + stop_timer; |
||
2618 | if (stop_timer > 1.0) { |
||
2619 | stop_timer = 100.0; |
||
2620 | } |
||
2621 | AddDrag(c, dt); |
||
2622 | if (c->driver >= eDriver_net_human) { |
||
2623 | c->acc_force = -(v136.v[2] * force[0]) - v136.v[2] * force[1]; |
||
2624 | // LOG_DEBUG("old %f new %f", old, c->acc_force); |
||
2625 | } |
||
2626 | } |
||
2627 | |||
2628 | // IDA: void __usercall DoRevs(tCar_spec *c@<EAX>, br_scalar dt) |
||
2629 | void DoRevs(tCar_spec* c, br_scalar dt) { |
||
2630 | br_scalar wheel_spin_force; |
||
2631 | br_scalar ts; |
||
2632 | //int revs_increase; // Pierre-Marie Baty -- unused variable |
||
2633 | LOG_TRACE("(%p, %f)", c, dt); |
||
2634 | |||
2635 | ts = -BrVector3Dot((br_vector3*)c->car_master_actor->t.t.mat.m[2], &c->v); |
||
2636 | |||
2637 | if (c->gear) { |
||
2638 | c->target_revs = ts / c->speed_revs_ratio / (double)c->gear; |
||
2639 | } else { |
||
2640 | c->target_revs = 0.0; |
||
2641 | } |
||
2642 | if (c->target_revs < 0.0) { |
||
2643 | c->target_revs = 0.0; |
||
2644 | c->gear = 0; |
||
2645 | } |
||
2646 | if (!c->number_of_wheels_on_ground || ((c->wheel_slip & 2) + 1) != 0 || !c->gear) { |
||
2647 | if (c->number_of_wheels_on_ground) { |
||
2648 | wheel_spin_force = c->force_torque_ratio * c->torque - (double)c->gear * c->acc_force; |
||
2649 | } else { |
||
2650 | wheel_spin_force = c->force_torque_ratio * c->torque; |
||
2651 | } |
||
2652 | if (c->gear) { |
||
2653 | if (c->gear < 2 && (c->keys.dec || c->joystick.dec > 0) && fabs(ts) < 1.0 && c->revs > 1000.0) { |
||
2654 | c->gear = -c->gear; |
||
2655 | } |
||
2656 | } else { |
||
2657 | if (c->revs > 1000.0 && !c->keys.brake && (c->keys.acc || c->joystick.acc > 0) && !gCountdown) { |
||
2658 | if (c->keys.backwards) { |
||
2659 | c->gear = -1; |
||
2660 | } else { |
||
2661 | c->gear = 1; |
||
2662 | } |
||
2663 | } |
||
2664 | wheel_spin_force = c->force_torque_ratio * c->torque; |
||
2665 | } |
||
2666 | c->revs = wheel_spin_force / c->force_torque_ratio * dt / 0.0002 + c->revs; |
||
2667 | |||
2668 | if (c->traction_control && wheel_spin_force > 0.0 && c->revs > c->target_revs && c->gear && c->target_revs > 1000.0) { |
||
2669 | c->revs = c->target_revs; |
||
2670 | } |
||
2671 | if (c->revs <= 0.0) { |
||
2672 | c->revs = 0.0; |
||
2673 | } |
||
2674 | } |
||
2675 | 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) { |
||
2676 | c->gear++; |
||
2677 | } |
||
2678 | if (c->gear > 1 && c->target_revs < 3000.0 && !c->just_changed_gear) { |
||
2679 | c->gear--; |
||
2680 | } |
||
2681 | if (c->revs < 200.0 && c->target_revs < 200.0 && c->gear <= 1 && !c->keys.acc && c->joystick.acc <= 0 && !c->just_changed_gear) { |
||
2682 | c->gear = 0; |
||
2683 | } |
||
2684 | if (c->just_changed_gear && c->revs < 6000.0 && c->revs > 200.0 && (c->gear < 2 || c->revs >= 3000.0)) { |
||
2685 | c->just_changed_gear = 0; |
||
2686 | } |
||
2687 | if (c->revs >= 6000.0 && (c->keys.acc || c->joystick.acc > 0)) { |
||
2688 | c->just_changed_gear = 0; |
||
2689 | } |
||
2690 | } |
||
2691 | |||
2692 | // IDA: void __usercall ApplyTorque(tCar_spec *c@<EAX>, br_vector3 *tdt@<EDX>) |
||
2693 | void ApplyTorque(tCar_spec* c, br_vector3* tdt) { |
||
2694 | LOG_TRACE("(%p, %p)", c, tdt); |
||
2695 | |||
2696 | c->omega.v[0] = tdt->v[0] / c->I.v[0] + c->omega.v[0]; |
||
2697 | c->omega.v[1] = tdt->v[1] / c->I.v[1] + c->omega.v[1]; |
||
2698 | c->omega.v[2] = tdt->v[2] / c->I.v[2] + c->omega.v[2]; |
||
2699 | } |
||
2700 | |||
2701 | // IDA: void __usercall TranslateCar(tCollision_info *c@<EAX>, br_scalar dt) |
||
2702 | void TranslateCar(tCollision_info* c, br_scalar dt) { |
||
2703 | br_vector3 t; |
||
2704 | LOG_TRACE("(%p, %f)", c, dt); |
||
2705 | |||
2706 | t.v[0] = c->v.v[0] * dt; |
||
2707 | t.v[1] = c->v.v[1] * dt; |
||
2708 | t.v[2] = c->v.v[2] * dt; |
||
2709 | c->car_master_actor->t.t.mat.m[3][0] = c->car_master_actor->t.t.mat.m[3][0] + t.v[0]; |
||
2710 | c->car_master_actor->t.t.mat.m[3][1] = c->car_master_actor->t.t.mat.m[3][1] + t.v[1]; |
||
2711 | c->car_master_actor->t.t.mat.m[3][2] = c->car_master_actor->t.t.mat.m[3][2] + t.v[2]; |
||
2712 | } |
||
2713 | |||
2714 | // IDA: int __usercall CollCheck@<EAX>(tCollision_info *c@<EAX>, br_scalar dt) |
||
2715 | int CollCheck(tCollision_info* c, br_scalar dt) { |
||
2716 | br_vector3 a; |
||
2717 | br_vector3 a1; |
||
2718 | br_vector3 aa; |
||
2719 | br_vector3 bb; |
||
2720 | br_vector3 cc; |
||
2721 | br_vector3 pos; |
||
2722 | br_vector3 r[8]; |
||
2723 | br_vector3 norm; |
||
2724 | br_vector3 n[8]; |
||
2725 | br_vector3 dir; |
||
2726 | br_vector3 tv; |
||
2727 | br_vector3 tv2; |
||
2728 | br_vector3 tau[4]; |
||
2729 | //br_vector3 old_val; // Pierre-Marie Baty -- unused variable |
||
2730 | //br_vector3 ftau; // Pierre-Marie Baty -- unused variable |
||
2731 | br_vector3 max_friction; |
||
2732 | br_vector3 vel; |
||
2733 | br_vector3 p_vel; |
||
2734 | br_vector3 normal_force; |
||
2735 | br_vector3 friction_force; |
||
2736 | br_scalar d[4]; |
||
2737 | br_scalar f[4]; |
||
2738 | br_scalar total_force; |
||
2739 | br_scalar point_vel; |
||
2740 | br_scalar batwick_length; |
||
2741 | br_matrix4 M; |
||
2742 | br_scalar dist; |
||
2743 | //br_scalar min_d; // Pierre-Marie Baty -- unused variable |
||
2744 | br_scalar ts; |
||
2745 | br_scalar ts2; |
||
2746 | br_scalar v_diff; |
||
2747 | br_matrix34* mat; |
||
2748 | br_matrix34* oldmat; |
||
2749 | br_matrix34 mat_to_oldmat; |
||
2750 | br_matrix34 oldmat_to_mat; |
||
2751 | br_matrix34 tm; |
||
2752 | int collision; |
||
2753 | br_bounds bnds; |
||
2754 | tFace_ref* f_ref; |
||
2755 | int i; |
||
2756 | int j; |
||
2757 | //int l; // Pierre-Marie Baty -- unused variable |
||
2758 | int k; |
||
2759 | int material; |
||
2760 | int noise_defeat; |
||
2761 | static int oldk; |
||
2762 | br_scalar min; |
||
2763 | br_scalar max; |
||
2764 | br_vector3 edges[3]; |
||
2765 | //br_vector3 corner; // Pierre-Marie Baty -- unused variable |
||
2766 | //br_vector3 test_dir; // Pierre-Marie Baty -- unused variable |
||
2767 | //br_scalar min_acc; // Pierre-Marie Baty -- unused variable |
||
2768 | //br_scalar max_acc; // Pierre-Marie Baty -- unused variable |
||
2769 | br_matrix34 message_mat; |
||
2770 | LOG_TRACE("(%p, %f)", c, dt); |
||
2771 | |||
2772 | tCar_spec* car_spec; // added for readability |
||
2773 | |||
2774 | // v34 = 0; |
||
2775 | // v35 = 0; |
||
2776 | // v36 = 0x3F800000; |
||
2777 | // v48 = 0x3F800347; |
||
2778 | car_spec = (tCar_spec*)c; |
||
2779 | mat = &c->car_master_actor->t.t.mat; |
||
2780 | oldmat = &c->oldmat; |
||
2781 | k = 0; |
||
2782 | gMaterial_index = 0; |
||
2783 | if (c->dt >= 0.0f && gNet_mode == eNet_mode_host) { |
||
2784 | oldmat = &message_mat; |
||
2785 | GetExpandedMatrix(&message_mat, &c->message.mat); |
||
2786 | } |
||
2787 | if (dt < 0.0f) { |
||
2788 | mat = oldmat; |
||
2789 | } |
||
2790 | BrMatrix34LPInverse(&tm, mat); |
||
2791 | BrMatrix34Mul(&oldmat_to_mat, oldmat, &tm); |
||
2792 | |||
2793 | oldmat_to_mat.m[3][0] = oldmat_to_mat.m[3][0] / WORLD_SCALE; |
||
2794 | oldmat_to_mat.m[3][1] = oldmat_to_mat.m[3][1] / WORLD_SCALE; |
||
2795 | oldmat_to_mat.m[3][2] = oldmat_to_mat.m[3][2] / WORLD_SCALE; |
||
2796 | GetNewBoundingBox(&bnds, &c->bounds[2], &oldmat_to_mat); |
||
2797 | for (i = 0; i < 3; ++i) { |
||
2798 | if (c->bounds[2].min.v[i] < bnds.min.v[i]) { |
||
2799 | bnds.min.v[i] = c->bounds[2].min.v[i]; |
||
2800 | } |
||
2801 | if (c->bounds[2].max.v[i] > bnds.max.v[i]) { |
||
2802 | bnds.max.v[i] = c->bounds[2].max.v[i]; |
||
2803 | } |
||
2804 | } |
||
2805 | a1.v[0] = mat->m[3][0] / WORLD_SCALE; |
||
2806 | a1.v[1] = mat->m[3][1] / WORLD_SCALE; |
||
2807 | a1.v[2] = mat->m[3][2] / WORLD_SCALE; |
||
2808 | BrMatrix34ApplyV(&aa, &bnds.min, mat); |
||
2809 | BrVector3Accumulate(&aa, &a1); |
||
2810 | for (j = 0; j < 3; ++j) { |
||
2811 | edges[j].v[0] = (bnds.max.v[j] - bnds.min.v[j]) * mat->m[j][0]; |
||
2812 | edges[j].v[1] = (bnds.max.v[j] - bnds.min.v[j]) * mat->m[j][1]; |
||
2813 | edges[j].v[2] = (bnds.max.v[j] - bnds.min.v[j]) * mat->m[j][2]; |
||
2814 | } |
||
2815 | for (i = 0; i < 50 && i < c->box_face_end - c->box_face_start; i++) { |
||
2816 | f_ref = &gFace_list__car[c->box_face_start + i]; |
||
2817 | BrVector3Sub(&bb, &aa, &f_ref->v[0]); |
||
2818 | max = BrVector3Dot(&bb, &f_ref->normal); |
||
2819 | min = max; |
||
2820 | for (j = 0; j < 3; ++j) { |
||
2821 | ts = BrVector3Dot(&edges[j], &f_ref->normal); |
||
2822 | if (ts >= 0) { |
||
2823 | max = max + ts; |
||
2824 | } else { |
||
2825 | min = min + ts; |
||
2826 | } |
||
2827 | } |
||
2828 | if ((max <= 0.001f || min <= 0.001f) && (max >= -0.001f || min >= -0.001f)) { |
||
2829 | f_ref->flags &= ~0x80u; |
||
2830 | k++; |
||
2831 | } else { |
||
2832 | f_ref->flags |= 0x80u; |
||
2833 | } |
||
2834 | } |
||
2835 | if (k == 0) { |
||
2836 | return 0; |
||
2837 | } |
||
2838 | k = 0; |
||
2839 | BrMatrix34LPInverse(&tm, oldmat); |
||
2840 | BrMatrix34Mul(&mat_to_oldmat, mat, &tm); |
||
2841 | gEliminate_faces = 1; |
||
2842 | for (i = 0; i < 8 + c->extra_point_num; i++) { |
||
2843 | if (i >= 8) { |
||
2844 | tv = c->extra_points[i - 8]; |
||
2845 | } else { |
||
2846 | tv.v[0] = ((i & 2) == 0) * c->bounds[1].min.v[0] + ((i & 2) >> 1) * c->bounds[1].max.v[0]; |
||
2847 | tv.v[1] = ((i & 1) == 0) * c->bounds[1].min.v[1] + ((i & 1) >> 0) * c->bounds[1].max.v[1]; |
||
2848 | tv.v[2] = ((i & 4) == 0) * c->bounds[1].max.v[2] + ((i & 4) >> 2) * c->bounds[1].min.v[2]; |
||
2849 | } |
||
2850 | BrMatrix34ApplyP(&dir, &tv, mat); |
||
2851 | if (dt >= 0.0f) { |
||
2852 | BrMatrix34ApplyP(&a, &tv, oldmat); |
||
2853 | } else { |
||
2854 | BrVector3Scale(&a, &c->pos, WORLD_SCALE); |
||
2855 | } |
||
2856 | BrVector3Sub(&dir, &dir, &a); |
||
2857 | BrVector3Normalise(&normal_force, &dir); |
||
2858 | BrVector3Scale(&normal_force, &normal_force, 0.0072463769f); |
||
2859 | BrVector3Accumulate(&dir, &normal_force); |
||
2860 | material = FindFloorInBoxM2(&a, &dir, &norm, &dist, c); |
||
2861 | if (dist >= 0.0f && dist < 1.0001f) { |
||
2862 | BrVector3Scale(&cc, &c->pos, WORLD_SCALE); |
||
2863 | BrVector3Sub(&cc, &cc, &a); |
||
2864 | FindFloorInBoxM(&a, &cc, &bb, &ts, c); |
||
2865 | if (i < 8 || ts > 1.0f) { |
||
2866 | BrMatrix34TApplyV(&a, &norm, oldmat); |
||
2867 | AddCollPoint(dist, &tv, &a, r, n, &dir, k, c); |
||
2868 | k++; |
||
2869 | if (gMaterial_index == 0) { |
||
2870 | gMaterial_index = material; |
||
2871 | } |
||
2872 | } |
||
2873 | } |
||
2874 | } |
||
2875 | gEliminate_faces = 0; |
||
2876 | if (k < 1) { |
||
2877 | k += BoxFaceIntersect(&c->bounds[1], mat, &mat_to_oldmat, &r[k], &n[k], &d[k], 8 - k, c); |
||
2878 | } |
||
2879 | if (k > 4) { |
||
2880 | k = 4; |
||
2881 | } |
||
2882 | for (i = 0; i < k; i++) { |
||
2883 | if (fabsf(r[i].v[1]) + fabsf(r[i].v[2]) + fabsf(r[i].v[0]) > 500.0f) { |
||
2884 | for (j = i + 1; j < k; j++) { |
||
2885 | if (fabsf(r[j].v[1]) + fabsf(r[j].v[2]) + fabsf(r[j].v[0]) < 500.0f) { |
||
2886 | r[i] = r[j]; |
||
2887 | n[i] = n[j]; |
||
2888 | i++; |
||
2889 | } |
||
2890 | } |
||
2891 | k = i; |
||
2892 | break; |
||
2893 | } |
||
2894 | } |
||
2895 | if (dt >= 0.0f) { |
||
2896 | if (k > 0 && c->collision_flag && k < 4 |
||
2897 | && (fabsf(r[0].v[0] - c->old_point.v[0]) > 0.05f |
||
2898 | || fabsf(r[0].v[1] - c->old_point.v[1]) > 0.05f |
||
2899 | || fabsf(r[0].v[2] - c->old_point.v[2]) > 0.05f)) { |
||
2900 | r[k] = c->old_point; |
||
2901 | n[k] = c->old_norm; |
||
2902 | k++; |
||
2903 | } |
||
2904 | if (k > 0) { |
||
2905 | c->old_point = r[0]; |
||
2906 | c->old_norm = n[0]; |
||
2907 | BrMatrix34Copy(mat, oldmat); |
||
2908 | c->omega = c->oldomega; |
||
2909 | BrMatrix34TApplyV(&c->velocity_car_space, &c->v, mat); |
||
2910 | memset(&norm, 0, sizeof(norm)); |
||
2911 | collision = 0; |
||
2912 | for (i = 0; i < k; i++) { |
||
2913 | BrVector3Cross(&tau[i], &r[i], &n[i]); |
||
2914 | tau[i].v[0] = tau[i].v[0] / c->I.v[0]; |
||
2915 | tau[i].v[1] = tau[i].v[1] / c->I.v[1]; |
||
2916 | tau[i].v[2] = tau[i].v[2] / c->I.v[2]; |
||
2917 | BrVector3Cross(&normal_force, &c->omega, &r[i]); |
||
2918 | BrVector3Accumulate(&normal_force, &c->velocity_car_space); |
||
2919 | d[i] = -(BrVector3Dot(&n[i], &normal_force)); |
||
2920 | BrVector3Add(&normal_force, &r[i], &c->cmpos); |
||
2921 | BrMatrix34ApplyP(&dir, &normal_force, &mat_to_oldmat); |
||
2922 | BrVector3Sub(&dir, &dir, &normal_force); |
||
2923 | ts = -(BrVector3Dot(&n[i], &dir) / dt); |
||
2924 | if (ts > d[i]) { |
||
2925 | d[i] = ts; |
||
2926 | } |
||
2927 | if (d[i] > 0.0f) { |
||
2928 | collision = 1; |
||
2929 | } |
||
2930 | } |
||
2931 | if (!collision) { |
||
2932 | d[0] = 0.5f; |
||
2933 | } |
||
2934 | for (i = 0; i < k; i++) { |
||
2935 | for (j = 0; j < k; j++) { |
||
2936 | BrVector3Cross(&normal_force, &tau[j], &r[i]); |
||
2937 | BrVector3InvScale(&norm, &n[j], c->M); |
||
2938 | BrVector3Accumulate(&normal_force, &norm); |
||
2939 | M.m[i][j] = BrVector3Dot(&n[i], &normal_force); |
||
2940 | } |
||
2941 | } |
||
2942 | switch (k) { |
||
2943 | case 1: |
||
2944 | ts = SinglePointColl(f, &M, d); |
||
2945 | break; |
||
2946 | case 2: |
||
2947 | ts = TwoPointColl(f, &M, d, tau, n); |
||
2948 | break; |
||
2949 | case 3: |
||
2950 | d[3] = 0.0f; |
||
2951 | ts = ThreePointCollRec(f, &M, d, tau, n, c); |
||
2952 | break; |
||
2953 | case 4: |
||
2954 | ts = FourPointColl(f, &M, d, tau, n, c); |
||
2955 | break; |
||
2956 | default: |
||
2957 | break; |
||
2958 | } |
||
2959 | if (k > 3) { |
||
2960 | k = 3; |
||
2961 | } |
||
2962 | // if (f[0] > 10.0f || f[1] > 10.0f || f[2] > 10.0f) { |
||
2963 | // v31 = 0; |
||
2964 | // } |
||
2965 | if (fabsf(ts) <= 0.000001f) { |
||
2966 | BrVector3Set(&c->v, 0.f, 0.f, 0.f); |
||
2967 | BrVector3Set(&c->omega, 0.f, 0.f, 0.f); |
||
2968 | BrVector3Set(&c->oldomega, 0.f, 0.f, 0.f); |
||
2969 | return k; |
||
2970 | } |
||
2971 | BrVector3Set(&p_vel, 0.f, 0.f, 0.f); |
||
2972 | BrVector3Set(&dir, 0.f, 0.f, 0.f); |
||
2973 | BrVector3Set(&friction_force, 0.f, 0.f, 0.f); |
||
2974 | total_force = 0.f; |
||
2975 | for (i = 0; i < k; i++) { |
||
2976 | if (f[i] < 0.001f) { |
||
2977 | f[i] = 0.001f; |
||
2978 | } |
||
2979 | f[i] = f[i] * 1.001f; |
||
2980 | BrVector3Scale(&tau[i], &tau[i], f[i]); |
||
2981 | BrVector3Accumulate(&c->omega, &tau[i]); |
||
2982 | f[i] = f[i] / c->M; |
||
2983 | BrVector3Scale(&n[i], &n[i], f[i]); |
||
2984 | BrVector3Accumulate(&p_vel, &n[i]); |
||
2985 | BrVector3Add(&bb, &r[i], &c->cmpos); |
||
2986 | BrVector3Scale(&bb, &bb, f[i]); |
||
2987 | BrVector3Accumulate(&dir, &bb); |
||
2988 | total_force = f[i] + total_force; |
||
2989 | } |
||
2990 | if (gPinball_factor != 0.0f) { |
||
2991 | BrVector3Scale(&p_vel, &p_vel, gPinball_factor); |
||
2992 | point_vel = BrVector3LengthSquared(&p_vel); |
||
2993 | if (point_vel > 10.0f) { |
||
2994 | noise_defeat = 1; |
||
2995 | if (c->driver == eDriver_local_human) { |
||
2996 | DRS3StartSound(gCar_outlet, 9011); |
||
2997 | } else { |
||
2998 | DRS3StartSound3D(gCar_outlet, 9011, &c->pos, &gZero_v__car, 1, 255, 0x10000, 0x10000); |
||
2999 | } |
||
3000 | if (point_vel > 10000.0f) { |
||
3001 | BrVector3Normalise(&p_vel, &p_vel); |
||
3002 | BrVector3Scale(&p_vel, &p_vel, 100); |
||
3003 | } |
||
3004 | } |
||
3005 | } |
||
3006 | BrVector3Accumulate(&c->velocity_car_space, &p_vel); |
||
3007 | BrVector3InvScale(&dir, &dir, total_force); |
||
3008 | BrVector3Cross(&tv, &c->omega, &dir); |
||
3009 | BrVector3Accumulate(&tv, &c->velocity_car_space); |
||
3010 | batwick_length = BrVector3Length(&tv); |
||
3011 | if (!c->collision_flag || (c->collision_flag == 1 && oldk < k)) { |
||
3012 | for (i = 0; i < k; i++) { |
||
3013 | BrVector3Cross(&vel, &c->omega, &r[i]); |
||
3014 | BrVector3Accumulate(&vel, &c->velocity_car_space); |
||
3015 | AddFriction(c, &vel, &n[i], &r[i], f[i], &max_friction); |
||
3016 | BrVector3Accumulate(&friction_force, &max_friction); |
||
3017 | BrVector3Accumulate(&c->velocity_car_space, &max_friction); |
||
3018 | } |
||
3019 | } |
||
3020 | oldk = k; |
||
3021 | BrMatrix34ApplyP(&pos, &dir, &c->car_master_actor->t.t.mat); |
||
3022 | BrVector3InvScale(&pos, &pos, WORLD_SCALE); |
||
3023 | noise_defeat = 0; |
||
3024 | BrVector3Add(&normal_force, &friction_force, &p_vel); |
||
3025 | BrMatrix34ApplyV(&norm, &normal_force, mat); |
||
3026 | min = dt * 90.0f / 10.0f; |
||
3027 | max = dt * 110.0f / 10.0f; |
||
3028 | if (c->last_special_volume != NULL) { |
||
3029 | min *= c->last_special_volume->gravity_multiplier; |
||
3030 | max *= c->last_special_volume->gravity_multiplier; |
||
3031 | } |
||
3032 | if (BrVector3LengthSquared(&c->velocity_car_space) < 0.05f |
||
3033 | && 0.1f * total_force > BrVector3Dot(&c->omega, &tv) |
||
3034 | && k >= 3 |
||
3035 | && norm.v[1] > min |
||
3036 | && norm.v[1] < max) { |
||
3037 | if (c->driver <= eDriver_non_car || fabsf(normal_force.v[2]) <= total_force * 0.9f) { |
||
3038 | BrVector3Set(&c->v, 0.f, 0.f, 0.f); |
||
3039 | BrVector3Set(&norm, 0.f, 0.f, 0.f); |
||
3040 | BrVector3Set(&normal_force, 0.f, 0.f, 0.f); |
||
3041 | BrVector3Set(&c->omega, 0.f, 0.f, 0.f); |
||
3042 | BrVector3Set(&c->oldomega, 0.f, 0.f, 0.f); |
||
3043 | if (c->driver <= eDriver_non_car || car_spec->max_force_rear == 0.0f) { |
||
3044 | if (c->driver <= eDriver_non_car) { |
||
3045 | PipeSingleNonCar(c); |
||
3046 | } |
||
3047 | c->doing_nothing_flag = 1; |
||
3048 | } |
||
3049 | } else { |
||
3050 | BrVector3SetFloat(&tv2, 0.0f, -1.0f, 0.0f); |
||
3051 | bb.v[0] = mat->m[1][2] * tv2.v[1] - mat->m[1][1] * tv2.v[2]; |
||
3052 | bb.v[1] = mat->m[1][0] * tv2.v[2] - mat->m[1][2] * tv2.v[0]; |
||
3053 | bb.v[2] = mat->m[1][1] * tv2.v[0] - mat->m[1][0] * tv2.v[1]; |
||
3054 | if (BrVector3Dot(&bb, (br_vector3*)&mat->m[0][1]) <= 0.0f) { |
||
3055 | c->omega.v[0] = -0.5f; |
||
3056 | } else { |
||
3057 | c->omega.v[0] = 0.5f; |
||
3058 | } |
||
3059 | } |
||
3060 | } |
||
3061 | BrVector3Accumulate(&c->v, &norm); |
||
3062 | if (c->driver >= eDriver_net_human) { |
||
3063 | BrVector3Scale(&normal_force, &normal_force, gDefensive_powerup_factor[car_spec->power_up_levels[0]]); |
||
3064 | } |
||
3065 | if (c->driver < eDriver_net_human) { |
||
3066 | BrVector3Scale(&normal_force, &normal_force, 0.01f); |
||
3067 | } else { |
||
3068 | BrVector3Scale(&normal_force, &normal_force, 0.75f); |
||
3069 | } |
||
3070 | if (CAR(c)->invulnerable |
||
3071 | || (c->driver < eDriver_net_human && (c->driver != eDriver_oppo || PointOutOfSight(&c->pos, 150.0f))) |
||
3072 | || ((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) |
||
3073 | || CAR(c)->number_of_wheels_on_ground >= 3) { |
||
3074 | CrushAndDamageCar(CAR(c), &dir, &normal_force, NULL); |
||
3075 | } else { |
||
3076 | // Cops Special Forces is always stolen if destroyed! |
||
3077 | if (c->driver == eDriver_oppo && c->index == 4 && v_diff < -40.0f) { |
||
3078 | KnackerThisCar(CAR(c)); |
||
3079 | StealCar(CAR(c)); |
||
3080 | v_diff = v_diff * 5.0f; |
||
3081 | } |
||
3082 | for (i = 0; i < CAR(c)->car_actor_count; i++) { |
||
3083 | ts2 = (v_diff + 20.0f) * -0.01f; |
||
3084 | TotallySpamTheModel(CAR(c), i, CAR(c)->car_model_actors[i].actor, &CAR(c)->car_model_actors[i].crush_data, ts2); |
||
3085 | } |
||
3086 | for (i = 0; i < COUNT_OF(CAR(c)->damage_units); i++) { |
||
3087 | DamageUnit(CAR(c), i, IRandomPosNeg(5) + (v_diff + 20.0f) * -1.5f); |
||
3088 | } |
||
3089 | } |
||
3090 | if (!noise_defeat) { |
||
3091 | CrashNoise(&norm, &pos, gMaterial_index); |
||
3092 | ScrapeNoise(batwick_length, &pos, gMaterial_index); |
||
3093 | } |
||
3094 | BrVector3InvScale(&tv, &tv, WORLD_SCALE); |
||
3095 | BrMatrix34ApplyV(&bb, &tv, &c->car_master_actor->t.t.mat); |
||
3096 | BrMatrix34ApplyV(&norm, &p_vel, &c->car_master_actor->t.t.mat); |
||
3097 | CreateSparks(&pos, &bb, &norm, gCurrent_race.material_modifiers[gMaterial_index].sparkiness, car_spec); |
||
3098 | } |
||
3099 | return k; |
||
3100 | } else { |
||
3101 | if (k != 0) { |
||
3102 | c->old_point = r[0]; |
||
3103 | c->old_norm = n[0]; |
||
3104 | } |
||
3105 | return k; |
||
3106 | } |
||
3107 | } |
||
3108 | |||
3109 | // 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) |
||
3110 | br_scalar AddFriction(tCollision_info* c, br_vector3* vel, br_vector3* normal_force, br_vector3* pos, br_scalar total_force, br_vector3* max_friction) { |
||
3111 | br_vector3 norm; |
||
3112 | br_vector3 tv; |
||
3113 | br_vector3 ftau; |
||
3114 | br_scalar ts; |
||
3115 | br_scalar point_vel; |
||
3116 | LOG_TRACE("(%p, %p, %p, %p, %f, %p)", c, vel, normal_force, pos, total_force, max_friction); |
||
3117 | |||
3118 | ts = BrVector3Dot(normal_force, vel) / BrVector3Dot(normal_force, normal_force); |
||
3119 | BrVector3Scale(&tv, normal_force, ts); |
||
3120 | BrVector3Sub(vel, vel, &tv); |
||
3121 | point_vel = total_force * 0.35f * gCurrent_race.material_modifiers[gMaterial_index].car_wall_friction; |
||
3122 | ts = BrVector3Length(vel); |
||
3123 | if (ts < 0.0001f) { |
||
3124 | BrVector3Set(max_friction, 0.f, 0.f, 0.f); |
||
3125 | return 0.0; |
||
3126 | } |
||
3127 | BrVector3InvScale(max_friction, vel, -ts); |
||
3128 | BrVector3Cross(&ftau, pos, max_friction); |
||
3129 | BrVector3Scale(&ftau, &ftau, c->M); |
||
3130 | ftau.v[0] = ftau.v[0] / c->I.v[0]; |
||
3131 | ftau.v[1] = ftau.v[1] / c->I.v[1]; |
||
3132 | ftau.v[2] = ftau.v[2] / c->I.v[2]; |
||
3133 | ts = 1.0 / c->M; |
||
3134 | norm.v[0] = pos->v[2] * ftau.v[1] - pos->v[1] * ftau.v[2]; |
||
3135 | norm.v[1] = pos->v[0] * ftau.v[2] - pos->v[2] * ftau.v[0]; |
||
3136 | norm.v[2] = pos->v[1] * ftau.v[0] - pos->v[0] * ftau.v[1]; |
||
3137 | ts = max_friction->v[0] * norm.v[0] + max_friction->v[1] * norm.v[1] + max_friction->v[2] * norm.v[2] + ts; |
||
3138 | if (fabsf(ts) <= 0.0001f) { |
||
3139 | ts = 0.0f; |
||
3140 | } else { |
||
3141 | ts = -BrVector3Dot(max_friction, vel) / ts; |
||
3142 | } |
||
3143 | if (ts > point_vel) { |
||
3144 | ts = point_vel; |
||
3145 | } |
||
3146 | BrVector3Scale(max_friction, max_friction, ts); |
||
3147 | BrVector3Cross(&tv, pos, max_friction); |
||
3148 | BrVector3Scale(&tv, &tv, c->M); |
||
3149 | ApplyTorque((tCar_spec*)c, &tv); |
||
3150 | return point_vel; |
||
3151 | } |
||
3152 | |||
3153 | // 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) |
||
3154 | 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) { |
||
3155 | br_vector3 v_diff1; |
||
3156 | br_vector3 v_diff2; |
||
3157 | br_vector3 tau1; |
||
3158 | br_vector3 tau2; |
||
3159 | br_vector3 tv; |
||
3160 | br_vector3 tv2; |
||
3161 | br_vector3 vel2_in_frame_1; |
||
3162 | br_scalar ts; |
||
3163 | br_scalar ts2; |
||
3164 | br_scalar v_diff; |
||
3165 | br_scalar stopping_impulse; |
||
3166 | br_scalar total_friction; |
||
3167 | int i; |
||
3168 | LOG_TRACE("(%p, %p, %p, %p, %p, %p, %p, %f, %p)", car1, car2, vel1, vel2, normal_force1, pos1, pos2, total_force, max_friction); |
||
3169 | |||
3170 | BrMatrix34TApplyV(&tv, vel2, &car2->oldmat); |
||
3171 | BrMatrix34ApplyV(&vel2_in_frame_1, &tv, &car1->oldmat); |
||
3172 | BrVector3Sub(&v_diff1, &vel2_in_frame_1, vel1); |
||
3173 | ts = BrVector3LengthSquared(normal_force1); |
||
3174 | ts2 = BrVector3Dot(normal_force1, &v_diff1) / ts; |
||
3175 | BrVector3Scale(&tv, normal_force1, ts2); |
||
3176 | BrVector3Sub(&v_diff1, &v_diff1, &tv); |
||
3177 | v_diff = BrVector3Length(&v_diff1); |
||
3178 | if (v_diff < 0.01f) { |
||
3179 | BrVector3Set(max_friction, 0.f, 0.f, 0.f); |
||
3180 | } else { |
||
3181 | BrVector3InvScale(&v_diff1, &v_diff1, v_diff); |
||
3182 | BrMatrix34ApplyV(&tv, &v_diff1, &car1->oldmat); |
||
3183 | BrMatrix34TApplyV(&v_diff2, &tv, &car2->oldmat); |
||
3184 | BrVector3Negate(&v_diff2, &v_diff2); |
||
3185 | BrVector3Cross(&tau1, pos1, &v_diff1); |
||
3186 | BrVector3Cross(&tau2, pos2, &v_diff2); |
||
3187 | for (i = 0; i < 3; ++i) { |
||
3188 | tau1.v[i] /= car1->I.v[i]; |
||
3189 | tau2.v[i] /= car2->I.v[i]; |
||
3190 | } |
||
3191 | BrVector3Cross(&tv, &tau1, pos1); |
||
3192 | BrVector3Cross(&tv2, &tau2, pos2); |
||
3193 | ts = BrVector3Dot(&tv, &v_diff1) + BrVector3Dot(&tv2, &v_diff2) + 1.f / car2->M + 1.f / car1->M; |
||
3194 | if (ts < 0.0001f) { |
||
3195 | BrVector3Set(max_friction, 0.f, 0.f, 0.f); |
||
3196 | } else { |
||
3197 | stopping_impulse = v_diff / ts; |
||
3198 | total_friction = total_force * 0.35f; |
||
3199 | if (stopping_impulse < total_friction) { |
||
3200 | total_friction = stopping_impulse; |
||
3201 | } |
||
3202 | if (!car1->infinite_mass) { |
||
3203 | BrVector3Scale(&tau1, &tau1, total_friction); |
||
3204 | BrVector3Accumulate(&car1->omega, &tau1); |
||
3205 | } |
||
3206 | if (!car2->infinite_mass) { |
||
3207 | BrVector3Scale(&tau2, &tau2, total_friction); |
||
3208 | BrVector3Accumulate(&car2->omega, &tau2); |
||
3209 | } |
||
3210 | BrVector3Scale(max_friction, &v_diff1, total_friction); |
||
3211 | } |
||
3212 | } |
||
3213 | } |
||
3214 | |||
3215 | // IDA: void __cdecl ScrapeNoise(br_scalar vel, br_vector3 *position, int material) |
||
3216 | void ScrapeNoise(br_scalar vel, br_vector3* position, int material) { |
||
3217 | tS3_volume vol; |
||
3218 | static tS3_sound_tag scrape_tag; |
||
3219 | static tS3_volume last_scrape_vol; |
||
3220 | br_vector3 velocity; |
||
3221 | //br_vector3 position_in_br; // Pierre-Marie Baty -- unused variable |
||
3222 | LOG_TRACE("(%f, %p, %d)", vel, position, material); |
||
3223 | |||
3224 | vol = vel * 7.0; |
||
3225 | if (gCurrent_race.material_modifiers[material].scrape_noise_index == -1) { |
||
3226 | return; |
||
3227 | } |
||
3228 | if ((scrape_tag && DRS3SoundStillPlaying(scrape_tag)) || vol <= 30) { |
||
3229 | if (last_scrape_vol < vol) { |
||
3230 | DRS3ChangeVolume(scrape_tag, vol); |
||
3231 | last_scrape_vol = vol; |
||
3232 | } |
||
3233 | } else { |
||
3234 | BrVector3Set(&velocity, 0.f, 0.f, 0.f); |
||
3235 | scrape_tag = DRS3StartSound3D( |
||
3236 | gCar_outlet, |
||
3237 | gMetal_scrape_sound_id__car[IRandomBetween(0, COUNT_OF(gMetal_scrape_sound_id__car) - 1)], |
||
3238 | position, |
||
3239 | &velocity, |
||
3240 | 1, |
||
3241 | vol, |
||
3242 | IRandomBetween(49152, 81920), |
||
3243 | 0x10000); |
||
3244 | last_scrape_vol = vol; |
||
3245 | } |
||
3246 | } |
||
3247 | |||
3248 | // IDA: void __usercall SkidNoise(tCar_spec *pC@<EAX>, int pWheel_num@<EDX>, br_scalar pV, int material) |
||
3249 | void SkidNoise(tCar_spec* pC, int pWheel_num, br_scalar pV, int material) { |
||
3250 | br_vector3 pos; |
||
3251 | br_vector3 world_pos; |
||
3252 | br_vector3 wv; |
||
3253 | br_vector3 wvw; |
||
3254 | br_scalar ts; |
||
3255 | static tS3_volume last_skid_vol[2]; |
||
3256 | int i; |
||
3257 | LOG_TRACE("(%p, %d, %f, %d)", pC, pWheel_num, pV, material); |
||
3258 | |||
3259 | i = IRandomBetween(0, 1); |
||
3260 | if (gCurrent_race.material_modifiers[material].tyre_noise_index == -1) { |
||
3261 | return; |
||
3262 | } |
||
3263 | if (IRandomBetween(0, 4) != 0) { |
||
3264 | return; |
||
3265 | } |
||
3266 | |||
3267 | last_skid_vol[i] = pV * 10.0; |
||
3268 | if ((pWheel_num & 1) != 0) { |
||
3269 | pos.v[0] = pC->bounds[1].max.v[0]; |
||
3270 | } else { |
||
3271 | pos.v[0] = pC->bounds[1].min.v[0]; |
||
3272 | } |
||
3273 | pos.v[1] = pC->wpos[pWheel_num].v[1] - pC->oldd[pWheel_num]; |
||
3274 | pos.v[2] = pC->wpos[pWheel_num].v[2]; |
||
3275 | BrMatrix34ApplyP(&world_pos, &pos, &pC->car_master_actor->t.t.mat); |
||
3276 | BrVector3InvScale(&world_pos, &world_pos, WORLD_SCALE); |
||
3277 | if (!DRS3SoundStillPlaying(gSkid_tag[i]) || (pC->driver == eDriver_local_human && gLast_car_to_skid[i] != pC)) { |
||
3278 | gSkid_tag[i] = DRS3StartSound3D( |
||
3279 | gCar_outlet, |
||
3280 | IRandomBetween(0, 4) + 9000, |
||
3281 | &world_pos, |
||
3282 | &pC->velocity_bu_per_sec, |
||
3283 | 1, |
||
3284 | last_skid_vol[i], |
||
3285 | IRandomBetween(49152, 81920), |
||
3286 | 0x10000); |
||
3287 | gLast_car_to_skid[i] = pC; |
||
3288 | } |
||
3289 | if (gCurrent_race.material_modifiers[material].smoke_type == 1) { |
||
3290 | BrVector3Cross(&wv, &pC->omega, &pos); |
||
3291 | BrVector3Add(&wv, &wv, &pC->velocity_car_space); |
||
3292 | ts = -(BrVector3Dot(&wv, &pC->road_normal)); |
||
3293 | BrVector3Scale(&wvw, &pC->road_normal, ts); |
||
3294 | BrVector3Add(&wv, &wv, &wvw); |
||
3295 | BrMatrix34ApplyV(&wvw, &wv, &pC->car_master_actor->t.t.mat); |
||
3296 | CreatePuffOfSmoke(&world_pos, &wvw, pV / 25.0, 1.0, 4, pC); |
||
3297 | } |
||
3298 | } |
||
3299 | |||
3300 | // IDA: void __usercall StopSkid(tCar_spec *pC@<EAX>) |
||
3301 | void StopSkid(tCar_spec* pC) { |
||
3302 | LOG_TRACE("(%p)", pC); |
||
3303 | |||
3304 | if (gLast_car_to_skid[0] == pC) { |
||
3305 | DRS3StopSound(gSkid_tag[0]); |
||
3306 | } |
||
3307 | if (gLast_car_to_skid[1] == pC) { |
||
3308 | DRS3StopSound(gSkid_tag[1]); |
||
3309 | } |
||
3310 | } |
||
3311 | |||
3312 | // IDA: void __usercall CrashNoise(br_vector3 *pForce@<EAX>, br_vector3 *position@<EDX>, int material@<EBX>) |
||
3313 | void CrashNoise(br_vector3* pForce, br_vector3* position, int material) { |
||
3314 | static tS3_sound_tag crunch_tag; |
||
3315 | static tS3_volume last_crunch_vol; |
||
3316 | tS3_volume vol; |
||
3317 | br_vector3 velocity; |
||
3318 | LOG_TRACE("(%p, %p, %d)", pForce, position, material); |
||
3319 | |||
3320 | vol = 60.f * BrVector3Length(pForce); |
||
3321 | if (gCurrent_race.material_modifiers[material].crash_noise_index != -1) { |
||
3322 | if (vol >= 256) { |
||
3323 | vol = 255; |
||
3324 | } |
||
3325 | if (crunch_tag == 0 || (!DRS3SoundStillPlaying(crunch_tag) && vol > 30)) { |
||
3326 | last_crunch_vol = vol; |
||
3327 | (void)last_crunch_vol; |
||
3328 | BrVector3Set(&velocity, 0.f, 0.f, 0.f); |
||
3329 | crunch_tag = DRS3StartSound3D(gCar_outlet, |
||
3330 | gMetal_crunch_sound_id__car[IRandomBetween(0, COUNT_OF(gMetal_crunch_sound_id__car) - 1)], |
||
3331 | position, &velocity, 1, vol, IRandomBetween(49152, 81920), 0x10000); |
||
3332 | } |
||
3333 | } |
||
3334 | } |
||
3335 | |||
3336 | // IDA: void __usercall CrushAndDamageCar(tCar_spec *c@<EAX>, br_vector3 *pPosition@<EDX>, br_vector3 *pForce_car_space@<EBX>, tCar_spec *car2@<ECX>) |
||
3337 | void CrushAndDamageCar(tCar_spec* c, br_vector3* pPosition, br_vector3* pForce_car_space, tCar_spec* car2) { |
||
3338 | br_vector3 force; |
||
3339 | //br_vector3 force2; // Pierre-Marie Baty -- unused variable |
||
3340 | br_vector3 position; |
||
3341 | br_vector3 pos_w; |
||
3342 | br_vector3 car_to_cam; |
||
3343 | br_vector3 force_for_bodywork; |
||
3344 | br_scalar ts; |
||
3345 | int i; |
||
3346 | br_matrix34 m; |
||
3347 | br_scalar fudge_multiplier; |
||
3348 | LOG_TRACE("(%p, %p, %p, %p)", c, pPosition, pForce_car_space, car2); |
||
3349 | |||
3350 | if (car2 != NULL) { |
||
3351 | car2->who_last_hit_me = c; |
||
3352 | c->who_last_hit_me = car2; |
||
3353 | } |
||
3354 | |||
3355 | if (c->driver == eDriver_non_car_unused_slot || c->driver == eDriver_non_car) { |
||
3356 | return; |
||
3357 | } |
||
3358 | fudge_multiplier = gNet_mode == eNet_mode_none || gNet_softness[gCurrent_net_game->type] == 1.0f ? 1.0f : gNet_softness[gCurrent_net_game->type]; |
||
3359 | BrVector3Sub(&car_to_cam, &c->pos, (br_vector3*)gCamera_to_world.m[3]); |
||
3360 | ts = BrVector3LengthSquared(&car_to_cam); |
||
3361 | if (c->driver == eDriver_oppo && ts > 200.0f) { |
||
3362 | return; |
||
3363 | } |
||
3364 | if (car2 != NULL) { |
||
3365 | if (car2->driver > eDriver_non_car) { |
||
3366 | TwoCarsHitEachOther(c, car2); |
||
3367 | } |
||
3368 | if (c->driver >= eDriver_net_human) { |
||
3369 | fudge_multiplier = gDefensive_powerup_factor[c->power_up_levels[0]] * 1.2f * fudge_multiplier; |
||
3370 | } |
||
3371 | if (car2->driver >= eDriver_net_human) { |
||
3372 | if (gNet_mode != eNet_mode_none |
||
3373 | && (gCurrent_net_game->type == eNet_game_type_fight_to_death || gCurrent_net_game->type == eNet_game_type_car_crusher)) { |
||
3374 | fudge_multiplier = gOffensive_powerup_factor[car2->power_up_levels[2]] * gNet_offensive[gCurrent_net_game->type] * car2->damage_multiplier * fudge_multiplier; |
||
3375 | } else { |
||
3376 | fudge_multiplier = gOffensive_powerup_factor[car2->power_up_levels[2]] * car2->damage_multiplier * fudge_multiplier; |
||
3377 | } |
||
3378 | } |
||
3379 | if (c->driver == eDriver_oppo && car2->driver == eDriver_oppo) { |
||
3380 | fudge_multiplier = fudge_multiplier * 0.2f; |
||
3381 | } |
||
3382 | if (car2->driver <= eDriver_non_car) { |
||
3383 | car2 = NULL; |
||
3384 | } else { |
||
3385 | fudge_multiplier /= ((car2->car_model_actors[car2->principal_car_actor].crush_data.softness_factor + 0.7f) / 0.7f); |
||
3386 | } |
||
3387 | } |
||
3388 | BrVector3InvScale(&position, pPosition, WORLD_SCALE); |
||
3389 | BrVector3Scale(&force, pForce_car_space, fudge_multiplier * 0.03f); |
||
3390 | ts = BrVector3LengthSquared(&force); |
||
3391 | if (c->driver <= eDriver_non_car || !c->invulnerable) { |
||
3392 | c->damage_magnitude_accumulator += ts; |
||
3393 | } |
||
3394 | if (c->driver < eDriver_net_human) { |
||
3395 | BrVector3Scale(&force_for_bodywork, &force, 1.5f); |
||
3396 | } else { |
||
3397 | if (c->collision_mass_multiplier != 1.0) { |
||
3398 | BrVector3InvScale(&force, &force, c->collision_mass_multiplier); |
||
3399 | } |
||
3400 | BrVector3Scale(&force_for_bodywork, &force, 0.5f); |
||
3401 | if (c->driver == eDriver_local_human) { |
||
3402 | DoPratcamHit(&force); |
||
3403 | } |
||
3404 | } |
||
3405 | if (gNet_mode == eNet_mode_host && (gCurrent_net_game->type == eNet_game_type_tag || gCurrent_net_game->type == eNet_game_type_foxy) && car2 != NULL |
||
3406 | && c->driver >= eDriver_net_human && car2->driver >= eDriver_net_human) { |
||
3407 | if (gNet_players[gIt_or_fox].car == c && car2->knackered) { |
||
3408 | CarInContactWithItOrFox(NetPlayerFromCar(car2)); |
||
3409 | } else if (gNet_players[gIt_or_fox].car == car2 && !c->knackered) { |
||
3410 | CarInContactWithItOrFox(NetPlayerFromCar(c)); |
||
3411 | } |
||
3412 | } |
||
3413 | if (gNet_mode != eNet_mode_client || car2 == NULL) { |
||
3414 | DamageSystems(c, &position, &force, car2 != NULL); |
||
3415 | } |
||
3416 | if (c->driver <= eDriver_non_car || !c->invulnerable) { |
||
3417 | for (i = 0; i < c->car_actor_count; i++) { |
||
3418 | 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)) { |
||
3419 | CrushModel(c, i, c->car_model_actors[i].actor, &position, &force_for_bodywork, &c->car_model_actors[i].crush_data); |
||
3420 | } |
||
3421 | } |
||
3422 | if (car2 && car2->driver == eDriver_local_human && ts > 0.003f) { |
||
3423 | PipeSingleCarIncident(ts, c, &position); |
||
3424 | } |
||
3425 | if (!car2 && c->driver == eDriver_local_human && ts > 0.003f) { |
||
3426 | BrMatrix34Copy(&m, &c->car_master_actor->t.t.mat); |
||
3427 | m.m[3][0] /= WORLD_SCALE; |
||
3428 | m.m[3][1] /= WORLD_SCALE; |
||
3429 | m.m[3][2] /= WORLD_SCALE; |
||
3430 | BrMatrix34ApplyP(&pos_w, &position, &m); |
||
3431 | PipeSingleWallIncident(ts, &pos_w); |
||
3432 | } |
||
3433 | } |
||
3434 | if (car2 != NULL && car2->driver == eDriver_local_human && ts > 0.003f) { |
||
3435 | PipeSingleCarIncident(ts, c, &position); |
||
3436 | } |
||
3437 | if (car2 == NULL && c->driver == eDriver_local_human && ts > 0.003f) { |
||
3438 | BrMatrix34Copy(&m, &c->car_master_actor->t.t.mat); |
||
3439 | m.m[3][0] /= WORLD_SCALE; |
||
3440 | m.m[3][1] /= WORLD_SCALE; |
||
3441 | m.m[3][2] /= WORLD_SCALE; |
||
3442 | BrMatrix34ApplyP(&pos_w, &position, &m); |
||
3443 | PipeSingleWallIncident(ts, &pos_w); |
||
3444 | } |
||
3445 | } |
||
3446 | |||
3447 | // IDA: int __usercall ExpandBoundingBox@<EAX>(tCar_spec *c@<EAX>) |
||
3448 | int ExpandBoundingBox(tCar_spec* c) { |
||
3449 | br_scalar min_z; |
||
3450 | br_scalar max_z; |
||
3451 | br_scalar dist; |
||
3452 | br_vector3 tv; |
||
3453 | br_vector3 old_pos; |
||
3454 | int l; |
||
3455 | //br_matrix34 mat; // Pierre-Marie Baty -- unused variable |
||
3456 | LOG_TRACE("(%p)", c); |
||
3457 | |||
3458 | l = 0; |
||
3459 | min_z = c->bounds[1].min.v[2]; |
||
3460 | max_z = c->bounds[1].max.v[2]; |
||
3461 | old_pos = *(br_vector3*)&c->oldmat.m[3][0]; |
||
3462 | CrushBoundingBox(c, 0); |
||
3463 | for (l = 0; l < 5; l++) { |
||
3464 | if (TestForCarInSensiblePlace(c)) { |
||
3465 | break; |
||
3466 | } |
||
3467 | if (c->old_point.v[2] <= 0.0f) { |
||
3468 | dist = min_z - c->bounds[1].min.v[2]; |
||
3469 | } else { |
||
3470 | dist = c->bounds[1].max.v[2] - max_z; |
||
3471 | } |
||
3472 | if (dist >= 0.0f) { |
||
3473 | dist += 0.005f; |
||
3474 | BrVector3Scale(&c->old_norm, &c->old_norm, dist); |
||
3475 | BrMatrix34ApplyV(&tv, &c->old_norm, &c->car_master_actor->t.t.mat); |
||
3476 | c->oldmat.m[3][0] += tv.v[0]; |
||
3477 | c->oldmat.m[3][1] += tv.v[1]; |
||
3478 | c->oldmat.m[3][2] += tv.v[2]; |
||
3479 | l++; |
||
3480 | } else { |
||
3481 | l = 5; |
||
3482 | } |
||
3483 | } |
||
3484 | if (l < 5) { |
||
3485 | return 1; |
||
3486 | } |
||
3487 | *(br_vector3*)&c->oldmat.m[3][0] = old_pos; |
||
3488 | c->bounds[1].min.v[2] = min_z; |
||
3489 | c->bounds[1].max.v[2] = max_z; |
||
3490 | if (c->driver == eDriver_local_human) { |
||
3491 | NewTextHeadupSlot(4, 0, 1000, -4, GetMiscString(kMiscString_RepairObstructed)); |
||
3492 | } |
||
3493 | return 0; |
||
3494 | } |
||
3495 | |||
3496 | // IDA: void __usercall CrushBoundingBox(tCar_spec *c@<EAX>, int crush_only@<EDX>) |
||
3497 | void CrushBoundingBox(tCar_spec* c, int crush_only) { |
||
3498 | br_vector3 min; |
||
3499 | br_vector3 max; |
||
3500 | int i; |
||
3501 | br_actor* actor; |
||
3502 | LOG_TRACE("(%p, %d)", c, crush_only); |
||
3503 | |||
3504 | if (c == NULL) { |
||
3505 | return; |
||
3506 | } |
||
3507 | actor = c->car_model_actors[c->principal_car_actor].actor; |
||
3508 | max.v[0] = c->wpos[2].v[2] - c->non_driven_wheels_circum / 6.2f; |
||
3509 | min.v[0] = c->driven_wheels_circum / 6.2f + c->wpos[0].v[2]; |
||
3510 | max.v[0] /= WORLD_SCALE; |
||
3511 | min.v[0] /= WORLD_SCALE; |
||
3512 | for (i = 0; i < actor->model->nvertices; i++) { |
||
3513 | if (actor->model->vertices[i].p.v[2] < max.v[0]) { |
||
3514 | max.v[0] = actor->model->vertices[i].p.v[2]; |
||
3515 | } |
||
3516 | if (actor->model->vertices[i].p.v[2] > min.v[0]) { |
||
3517 | min.v[0] = actor->model->vertices[i].p.v[2]; |
||
3518 | } |
||
3519 | } |
||
3520 | max.v[0] *= WORLD_SCALE; |
||
3521 | min.v[0] *= WORLD_SCALE; |
||
3522 | if (crush_only) { |
||
3523 | if (c->bounds[1].min.v[2] > max.v[0]) { |
||
3524 | max.v[0] = c->bounds[1].min.v[2]; |
||
3525 | } |
||
3526 | if (c->bounds[1].max.v[2] < min.v[0]) { |
||
3527 | min.v[0] = c->bounds[1].max.v[2]; |
||
3528 | } |
||
3529 | } else { |
||
3530 | if (c->max_bounds[1].min.v[2] > max.v[0]) { |
||
3531 | max.v[0] = c->max_bounds[1].min.v[2]; |
||
3532 | } |
||
3533 | if (c->max_bounds[1].max.v[2] < min.v[0]) { |
||
3534 | min.v[0] = c->max_bounds[1].max.v[2]; |
||
3535 | } |
||
3536 | } |
||
3537 | c->bounds[1].min.v[2] = max.v[0]; |
||
3538 | c->bounds[1].max.v[2] = min.v[0]; |
||
3539 | for (i = 0; i < c->extra_point_num; i++) { |
||
3540 | 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]) { |
||
3541 | if (c->original_extra_points_z[i] > min.v[0]) { |
||
3542 | c->extra_points[i].v[2] = min.v[0]; |
||
3543 | } else if (c->original_extra_points_z[i] >= max.v[0]) { |
||
3544 | c->extra_points[i].v[2] = c->original_extra_points_z[i]; |
||
3545 | } else { |
||
3546 | c->extra_points[i].v[2] = max.v[0]; |
||
3547 | } |
||
3548 | if (c->extra_points[i].v[2] > min.v[0]) { |
||
3549 | c->extra_points[i].v[2] = min.v[0]; |
||
3550 | } |
||
3551 | if (c->extra_points[i].v[2] < max.v[0]) { |
||
3552 | c->extra_points[i].v[2] = max.v[0]; |
||
3553 | } |
||
3554 | } else { |
||
3555 | c->extra_points[i].v[2] = c->original_extra_points_z[i]; |
||
3556 | } |
||
3557 | } |
||
3558 | } |
||
3559 | |||
3560 | // 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) |
||
3561 | 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) { |
||
3562 | static br_scalar d[4]; |
||
3563 | int i; |
||
3564 | int furthest; |
||
3565 | LOG_TRACE("(%f, %p, %p, %p, %p, %p, %d, %p)", dist, p, norm, r, n, dir, num, c); |
||
3566 | |||
3567 | if (num < 4) { |
||
3568 | d[num] = dist; |
||
3569 | n[num] = *norm; |
||
3570 | BrVector3Sub(&r[num], p, &c->cmpos); |
||
3571 | return; |
||
3572 | } |
||
3573 | furthest = 0; |
||
3574 | for (i = 1; i < 4; i++) { |
||
3575 | if (d[furthest] < d[i]) { |
||
3576 | furthest = i; |
||
3577 | } |
||
3578 | } |
||
3579 | if (d[furthest] >= dist) { |
||
3580 | num = furthest; |
||
3581 | d[num] = dist; |
||
3582 | n[num] = *norm; |
||
3583 | BrVector3Sub(&r[num], p, &c->cmpos); |
||
3584 | } |
||
3585 | } |
||
3586 | |||
3587 | // IDA: br_scalar __usercall SinglePointColl@<ST0>(br_scalar *f@<EAX>, br_matrix4 *m@<EDX>, br_scalar *d@<EBX>) |
||
3588 | br_scalar SinglePointColl(br_scalar* f, br_matrix4* m, br_scalar* d) { |
||
3589 | LOG_TRACE("(%p, %p, %p)", f, m, d); |
||
3590 | |||
3591 | f[0] = d[0] / m->m[0][0]; |
||
3592 | if (f[0] < 0.0f) { |
||
3593 | f[0] = 0.f; |
||
3594 | } |
||
3595 | return fabsf(m->m[0][0]); |
||
3596 | } |
||
3597 | |||
3598 | // 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) |
||
3599 | br_scalar TwoPointColl(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n) { |
||
3600 | br_scalar ts; |
||
3601 | LOG_TRACE("(%p, %p, %p, %p, %p)", f, m, d, tau, n); |
||
3602 | |||
3603 | ts = m->m[1][1] * m->m[0][0] - m->m[0][1] * m->m[1][0]; |
||
3604 | |||
3605 | if (fabsf(ts) >= 0.000001f) { |
||
3606 | f[0] = (m->m[1][1] * d[0] - m->m[0][1] * d[1]) / ts; |
||
3607 | f[1] = (m->m[1][0] * d[0] - m->m[0][0] * d[1]) / -ts; |
||
3608 | } |
||
3609 | if (f[1] < 0.0f || fabs(ts) < 0.000001f) { |
||
3610 | ts = SinglePointColl(f, m, d); |
||
3611 | f[1] = 0.0f; |
||
3612 | } else if (f[0] < 0.0f) { |
||
3613 | m->m[0][0] = m->m[1][1]; |
||
3614 | tau[0] = tau[1]; |
||
3615 | n[0] = n[1]; |
||
3616 | d[0] = d[1]; |
||
3617 | ts = SinglePointColl(f, m, d); |
||
3618 | f[1] = 0.0; |
||
3619 | } |
||
3620 | return fabsf(ts); |
||
3621 | } |
||
3622 | |||
3623 | // IDA: br_scalar __usercall DrMatrix4Inverse@<ST0>(br_matrix4 *mi@<EAX>, br_matrix4 *mc@<EDX>) |
||
3624 | br_scalar DrMatrix4Inverse(br_matrix4* mi, br_matrix4* mc) { |
||
3625 | LOG_TRACE("(%p, %p)", mi, mc); |
||
3626 | |||
3627 | return BrMatrix4Inverse(mi, mc); |
||
3628 | } |
||
3629 | |||
3630 | // IDA: br_scalar __usercall ThreePointColl@<ST0>(br_scalar *f@<EAX>, br_matrix4 *m@<EDX>, br_scalar *d@<EBX>) |
||
3631 | br_scalar ThreePointColl(br_scalar* f, br_matrix4* m, br_scalar* d) { |
||
3632 | br_matrix4 mc; |
||
3633 | br_matrix4 mi; |
||
3634 | br_scalar ts; |
||
3635 | LOG_TRACE("(%p, %p, %p)", f, m, d); |
||
3636 | |||
3637 | BrMatrix4Copy(&mc, m); |
||
3638 | memset(&mc.m[2][3], 0, 16); |
||
3639 | mc.m[1][3] = 0.0f; |
||
3640 | mc.m[0][3] = 0.0f; |
||
3641 | mc.m[3][3] = 1.0f; |
||
3642 | ts = DrMatrix4Inverse(&mi, &mc); |
||
3643 | BrMatrix4TApply((br_vector4*)f, (br_vector4*)d, &mi); |
||
3644 | f[3] = 0.0f; |
||
3645 | return fabs(ts); |
||
3646 | } |
||
3647 | |||
3648 | // 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) |
||
3649 | br_scalar ThreePointCollRec(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n, tCollision_info* c) { |
||
3650 | int i; |
||
3651 | int j; |
||
3652 | br_scalar ts; |
||
3653 | LOG_TRACE("(%p, %p, %p, %p, %p, %p)", f, m, d, tau, n, c); |
||
3654 | |||
3655 | ts = ThreePointColl(f, m, d); |
||
3656 | if (f[0] >= 0.0f && f[1] >= 0.0f && f[2] >= 0.0f && ts >= 0.000001f) { |
||
3657 | c->infinite_mass = 256; |
||
3658 | return ts; |
||
3659 | } |
||
3660 | if (ts < 0.000001f) { |
||
3661 | i = 0; |
||
3662 | j = 1; |
||
3663 | } else if (f[0] < 0.0f) { |
||
3664 | i = 1; |
||
3665 | j = 2; |
||
3666 | } else if (f[1] < 0.0f) { |
||
3667 | i = 0; |
||
3668 | j = 2; |
||
3669 | } else if (f[2] < 0.0f) { |
||
3670 | i = 0; |
||
3671 | j = 1; |
||
3672 | } else { |
||
3673 | return 0.0f; |
||
3674 | } |
||
3675 | m->m[0][0] = ((float*)m->m)[5 * i]; |
||
3676 | m->m[1][0] = m->m[j][i]; |
||
3677 | m->m[0][1] = m->m[i][j]; |
||
3678 | m->m[1][1] = ((float*)m->m)[5 * j]; |
||
3679 | tau[0] = tau[i]; |
||
3680 | tau[1] = tau[j]; |
||
3681 | n[0] = n[i]; |
||
3682 | n[1] = n[j]; |
||
3683 | d[0] = d[i]; |
||
3684 | d[1] = d[j]; |
||
3685 | ts = TwoPointColl(f, m, d, tau, n); |
||
3686 | f[2] = 0.0f; |
||
3687 | return ts; |
||
3688 | } |
||
3689 | |||
3690 | // 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) |
||
3691 | br_scalar FourPointColl(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n, tCollision_info* c) { |
||
3692 | int i; |
||
3693 | int j; |
||
3694 | int l; |
||
3695 | br_scalar ts; |
||
3696 | LOG_TRACE("(%p, %p, %p, %p, %p, %p)", f, m, d, tau, n, c); |
||
3697 | |||
3698 | ts = ThreePointColl(f, m, d); |
||
3699 | if (f[0] < 0.0 || f[1] < 0.0 || f[2] < 0.0 || ts < 0.000001) { |
||
3700 | if (ts < 0.000001) { |
||
3701 | j = 3; |
||
3702 | } else if (f[0] < 0.0) { |
||
3703 | j = 0; |
||
3704 | } else if (f[1] >= 0.0) { |
||
3705 | j = 2; |
||
3706 | } else { |
||
3707 | j = 1; |
||
3708 | } |
||
3709 | for (i = j; i < 3; ++i) { |
||
3710 | for (l = 0; l < 4; ++l) { |
||
3711 | m->m[i][l] = m->m[i + 1][l]; |
||
3712 | } |
||
3713 | d[i] = d[i + 1]; |
||
3714 | tau[i] = tau[i + 1]; |
||
3715 | n[i] = n[i + 1]; |
||
3716 | d[i] = d[i + 1]; |
||
3717 | } |
||
3718 | for (i = j; i < 3; ++i) { |
||
3719 | for (l = 0; l < 3; ++l) { |
||
3720 | m->m[l][i] = m->m[l][i + 1]; |
||
3721 | } |
||
3722 | } |
||
3723 | return ThreePointCollRec(f, m, d, tau, n, c); |
||
3724 | } else { |
||
3725 | c->infinite_mass = 256; |
||
3726 | return ts; |
||
3727 | } |
||
3728 | } |
||
3729 | |||
3730 | // 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) |
||
3731 | void MultiFindFloorInBoxM(int pNum_rays, br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, tCar_spec* c, int* mat_ref) { |
||
3732 | br_vector3 aa[4]; |
||
3733 | br_vector3 bb; |
||
3734 | int i; |
||
3735 | LOG_TRACE("(%d, %p, %p, %p, %p, %p, %p)", pNum_rays, a, b, nor, d, c, mat_ref); |
||
3736 | |||
3737 | for (i = 0; i < pNum_rays; i++) { |
||
3738 | aa[i].v[0] = a[i].v[0] / WORLD_SCALE; |
||
3739 | aa[i].v[1] = a[i].v[1] / WORLD_SCALE; |
||
3740 | aa[i].v[2] = a[i].v[2] / WORLD_SCALE; |
||
3741 | d[i] = 2.0; |
||
3742 | } |
||
3743 | bb.v[0] = b->v[0] / WORLD_SCALE; |
||
3744 | bb.v[1] = b->v[1] / WORLD_SCALE; |
||
3745 | bb.v[2] = b->v[2] / WORLD_SCALE; |
||
3746 | MultiFindFloorInBoxBU(pNum_rays, aa, &bb, nor, d, c, mat_ref); |
||
3747 | } |
||
3748 | |||
3749 | // 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) |
||
3750 | void MultiFindFloorInBoxBU(int pNum_rays, br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, tCar_spec* c, int* mat_ref) { |
||
3751 | br_vector3 nor2; |
||
3752 | int i; |
||
3753 | int j; |
||
3754 | int l; |
||
3755 | br_scalar dist[4]; |
||
3756 | tFace_ref* face_ref; |
||
3757 | LOG_TRACE("(%d, %p, %p, %p, %p, %p, %p)", pNum_rays, a, b, nor, d, c, mat_ref); |
||
3758 | |||
3759 | for (i = c->box_face_start; i < c->box_face_end; i++) { |
||
3760 | face_ref = &gFace_list__car[i]; |
||
3761 | if (!gEliminate_faces || (face_ref->flags & 0x80) == 0x0) { |
||
3762 | MultiRayCheckSingleFace(pNum_rays, face_ref, a, b, &nor2, dist); |
||
3763 | for (j = 0; j < pNum_rays; ++j) { |
||
3764 | if (d[j] > dist[j]) { |
||
3765 | d[j] = dist[j]; |
||
3766 | nor[j] = nor2; |
||
3767 | l = *gFace_list__car[i].material->identifier - 47; |
||
3768 | if (l >= 0 && l < 11) { |
||
3769 | mat_ref[j] = l; |
||
3770 | } |
||
3771 | } |
||
3772 | } |
||
3773 | } |
||
3774 | } |
||
3775 | } |
||
3776 | |||
3777 | // IDA: void __usercall findfloor(br_vector3 *a@<EAX>, br_vector3 *b@<EDX>, br_vector3 *nor@<EBX>, br_scalar *d@<ECX>) |
||
3778 | void findfloor(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d) { |
||
3779 | br_material* material; |
||
3780 | br_vector3 aa; |
||
3781 | br_vector3 bb; |
||
3782 | LOG_TRACE("(%p, %p, %p, %p)", a, b, nor, d); |
||
3783 | |||
3784 | BrVector3InvScale(&aa, a, WORLD_SCALE); |
||
3785 | BrVector3InvScale(&bb, b, WORLD_SCALE); |
||
3786 | FindFace(&aa, &bb, nor, d, &material); |
||
3787 | } |
||
3788 | |||
3789 | // IDA: int __usercall FindFloorInBoxM@<EAX>(br_vector3 *a@<EAX>, br_vector3 *b@<EDX>, br_vector3 *nor@<EBX>, br_scalar *d@<ECX>, tCollision_info *c) |
||
3790 | int FindFloorInBoxM(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, tCollision_info* c) { |
||
3791 | br_vector3 aa; |
||
3792 | br_vector3 bb; |
||
3793 | LOG_TRACE("(%p, %p, %p, %p, %p)", a, b, nor, d, c); |
||
3794 | |||
3795 | aa.v[0] = a->v[0] / WORLD_SCALE; |
||
3796 | aa.v[1] = a->v[1] / WORLD_SCALE; |
||
3797 | aa.v[2] = a->v[2] / WORLD_SCALE; |
||
3798 | bb.v[0] = b->v[0] / WORLD_SCALE; |
||
3799 | bb.v[1] = b->v[1] / WORLD_SCALE; |
||
3800 | bb.v[2] = b->v[2] / WORLD_SCALE; |
||
3801 | return FindFloorInBoxBU(&aa, &bb, nor, d, c); |
||
3802 | } |
||
3803 | |||
3804 | // IDA: int __usercall FindFloorInBoxBU@<EAX>(br_vector3 *a@<EAX>, br_vector3 *b@<EDX>, br_vector3 *nor@<EBX>, br_scalar *d@<ECX>, tCollision_info *c) |
||
3805 | int FindFloorInBoxBU(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, tCollision_info* c) { |
||
3806 | br_vector3 nor2; |
||
3807 | int i; |
||
3808 | int j; |
||
3809 | br_scalar dist; |
||
3810 | tFace_ref* face_ref; |
||
3811 | LOG_TRACE("(%p, %p, %p, %p, %p)", a, b, nor, d, c); |
||
3812 | |||
3813 | #if defined(DETHRACE_FIX_BUGS) |
||
3814 | j = 0; // added to keep compiler happy |
||
3815 | #endif |
||
3816 | *d = 2.0; |
||
3817 | for (i = c->box_face_start; i < c->box_face_end; i++) { |
||
3818 | face_ref = &gFace_list__car[i]; |
||
3819 | if (!gEliminate_faces || SLOBYTE(face_ref->flags) >= 0) { |
||
3820 | CheckSingleFace(face_ref, a, b, &nor2, &dist); |
||
3821 | if (*d > dist) { |
||
3822 | *d = dist; |
||
3823 | j = i; |
||
3824 | BrVector3Copy(nor, &nor2); |
||
3825 | } |
||
3826 | } |
||
3827 | } |
||
3828 | if (*d >= 2.f) { |
||
3829 | return 0; |
||
3830 | } |
||
3831 | i = gFace_list__car[j].material->identifier[0] - ('0' - 1); |
||
3832 | if (i < 0 || i >= 11) { |
||
3833 | return 0; |
||
3834 | } else { |
||
3835 | return i; |
||
3836 | } |
||
3837 | } |
||
3838 | |||
3839 | // IDA: int __usercall FindFloorInBoxBU2@<EAX>(br_vector3 *a@<EAX>, br_vector3 *b@<EDX>, br_vector3 *nor@<EBX>, br_scalar *d@<ECX>, tCollision_info *c) |
||
3840 | int FindFloorInBoxBU2(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, tCollision_info* c) { |
||
3841 | br_vector3 nor2; |
||
3842 | br_vector3 tv; |
||
3843 | int i; |
||
3844 | int j; |
||
3845 | br_scalar dist; |
||
3846 | tFace_ref* face_ref; |
||
3847 | LOG_TRACE("(%p, %p, %p, %p, %p)", a, b, nor, d, c); |
||
3848 | |||
3849 | #if defined(DETHRACE_FIX_BUGS) |
||
3850 | j = 0; // added to keep compiler happy |
||
3851 | #endif |
||
3852 | *d = 2.f; |
||
3853 | for (i = c->box_face_start; i < c->box_face_end; i++) { |
||
3854 | face_ref = &gFace_list__car[i]; |
||
3855 | if (!gEliminate_faces || SLOBYTE(face_ref->flags) >= 0) { |
||
3856 | CheckSingleFace(face_ref, a, b, &nor2, &dist); |
||
3857 | if (*d > dist) { |
||
3858 | if (face_ref->material->user == DOUBLESIDED_USER_FLAG || (face_ref->material->flags & (BR_MATF_ALWAYS_VISIBLE | BR_MATF_TWO_SIDED)) != 0) { |
||
3859 | BrVector3Sub(&tv, &c->pos, a); |
||
3860 | if (BrVector3Dot(&tv, &nor2) >= 0.f) { |
||
3861 | *d = dist; |
||
3862 | j = i; |
||
3863 | BrVector3Copy(nor, &nor2); |
||
3864 | } |
||
3865 | } else { |
||
3866 | *d = dist; |
||
3867 | j = i; |
||
3868 | BrVector3Copy(nor, &nor2); |
||
3869 | } |
||
3870 | } |
||
3871 | } |
||
3872 | face_ref++; |
||
3873 | } |
||
3874 | if (*d >= 2.f) { |
||
3875 | return 0; |
||
3876 | } |
||
3877 | i = gFace_list__car[j].material->identifier[0] - ('0' - 1); |
||
3878 | if (i < 0 || i >= 11) { |
||
3879 | return 0; |
||
3880 | } else { |
||
3881 | return i; |
||
3882 | } |
||
3883 | } |
||
3884 | |||
3885 | // IDA: int __usercall FindFloorInBoxM2@<EAX>(br_vector3 *a@<EAX>, br_vector3 *b@<EDX>, br_vector3 *nor@<EBX>, br_scalar *d@<ECX>, tCollision_info *c) |
||
3886 | int FindFloorInBoxM2(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, tCollision_info* c) { |
||
3887 | br_vector3 aa; |
||
3888 | br_vector3 bb; |
||
3889 | LOG_TRACE("(%p, %p, %p, %p, %p)", a, b, nor, d, c); |
||
3890 | |||
3891 | aa.v[0] = a->v[0] / WORLD_SCALE; |
||
3892 | aa.v[1] = a->v[1] / WORLD_SCALE; |
||
3893 | aa.v[2] = a->v[2] / WORLD_SCALE; |
||
3894 | bb.v[0] = b->v[0] / WORLD_SCALE; |
||
3895 | bb.v[1] = b->v[1] / WORLD_SCALE; |
||
3896 | bb.v[2] = b->v[2] / WORLD_SCALE; |
||
3897 | return FindFloorInBoxBU2(&aa, &bb, nor, d, c); |
||
3898 | } |
||
3899 | |||
3900 | // 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) |
||
3901 | 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) { |
||
3902 | br_vector3 p[3]; |
||
3903 | br_vector3 tv; |
||
3904 | br_vector3 pos; |
||
3905 | br_bounds bnds; |
||
3906 | int i; |
||
3907 | int j; |
||
3908 | int n; |
||
3909 | int flag; |
||
3910 | int m; |
||
3911 | tFace_ref* f_ref; |
||
3912 | //br_face* face; // Pierre-Marie Baty -- unused variable |
||
3913 | LOG_TRACE("(%p, %p, %p, %p, %p, %p, %d, %p)", pB, pM, pMold, pPoint_list, pNorm_list, pDist_list, pMax_pnts, c); |
||
3914 | |||
3915 | n = 0; |
||
3916 | BrVector3InvScale(&bnds.min, &pB->min, WORLD_SCALE); |
||
3917 | BrVector3InvScale(&bnds.max, &pB->max, WORLD_SCALE); |
||
3918 | BrVector3InvScale(&pos, (br_vector3*)pM->m[3], WORLD_SCALE); |
||
3919 | BrVector3InvScale((br_vector3*)pMold->m[3], (br_vector3*)pMold->m[3], WORLD_SCALE); |
||
3920 | |||
3921 | for (i = c->box_face_start; i < c->box_face_end && i < c->box_face_start + 50; i++) { |
||
3922 | f_ref = &gFace_list__car[i]; |
||
3923 | if (SLOBYTE(f_ref->flags) >= 0 && f_ref->material->identifier[0] != '!') { |
||
3924 | BrVector3Sub(&tv, &f_ref->v[0], &pos); |
||
3925 | BrMatrix34TApplyV(&p[0], &tv, pM); |
||
3926 | BrVector3Sub(&tv, &f_ref->v[1], &pos); |
||
3927 | BrMatrix34TApplyV(&p[1], &tv, pM); |
||
3928 | BrVector3Sub(&tv, &f_ref->v[2], &pos); |
||
3929 | BrMatrix34TApplyV(&p[2], &tv, pM); |
||
3930 | j = n; |
||
3931 | if ((f_ref->flags & 1) == 0) { |
||
3932 | n += AddEdgeCollPoints(&p[0], &p[1], &bnds, pMold, pPoint_list, pNorm_list, n, pMax_pnts, c); |
||
3933 | } |
||
3934 | if ((f_ref->flags & 2) == 0) { |
||
3935 | n += AddEdgeCollPoints(&p[1], &p[2], &bnds, pMold, pPoint_list, pNorm_list, n, pMax_pnts, c); |
||
3936 | } |
||
3937 | if ((f_ref->flags & 4) == 0) { |
||
3938 | n += AddEdgeCollPoints(&p[2], &p[0], &bnds, pMold, pPoint_list, pNorm_list, n, pMax_pnts, c); |
||
3939 | } |
||
3940 | if (n > j) { |
||
3941 | if (gMaterial_index == 0) { |
||
3942 | m = f_ref->material->identifier[0] - '/'; |
||
3943 | if (m > 0 && m < 11) { |
||
3944 | gMaterial_index = m; |
||
3945 | } |
||
3946 | } |
||
3947 | while (j < n) { |
||
3948 | BrVector3Scale(&pPoint_list[j], &pPoint_list[j], WORLD_SCALE); |
||
3949 | BrVector3Sub(&pPoint_list[j], &pPoint_list[j], &c->cmpos); |
||
3950 | j++; |
||
3951 | } |
||
3952 | } |
||
3953 | } |
||
3954 | } |
||
3955 | if (n) { |
||
3956 | m = 0; |
||
3957 | for (i = 0; i < n - 1; i++) { |
||
3958 | flag = 1; |
||
3959 | for (j = i + 1; j < n; j++) { |
||
3960 | if (fabsf(pPoint_list[i].v[0] - pPoint_list[j].v[0]) <= 0.001f |
||
3961 | && fabsf(pPoint_list[i].v[1] - pPoint_list[j].v[1]) <= 0.001f |
||
3962 | && fabsf(pPoint_list[i].v[2] - pPoint_list[j].v[2]) <= 0.001f) { |
||
3963 | flag = 0; |
||
3964 | break; |
||
3965 | } |
||
3966 | } |
||
3967 | if (flag) { |
||
3968 | BrVector3Copy(&pPoint_list[m], &pPoint_list[i]); |
||
3969 | m++; |
||
3970 | } |
||
3971 | } |
||
3972 | BrVector3Copy(&pPoint_list[m], &pPoint_list[n - 1]); |
||
3973 | n = m + 1; |
||
3974 | } |
||
3975 | BrVector3Scale((br_vector3*)pMold->m[3], (br_vector3*)pMold->m[3], WORLD_SCALE); |
||
3976 | return n; |
||
3977 | } |
||
3978 | |||
3979 | // 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) |
||
3980 | 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) { |
||
3981 | br_vector3 op1; |
||
3982 | br_vector3 op2; |
||
3983 | br_vector3 a; |
||
3984 | br_vector3 b; |
||
3985 | br_vector3 edge; |
||
3986 | br_vector3 hp1; |
||
3987 | br_vector3 hp2; |
||
3988 | br_vector3 hp3; |
||
3989 | int plane1; |
||
3990 | int plane2; |
||
3991 | int plane3; |
||
3992 | int d; |
||
3993 | LOG_TRACE("(%p, %p, %p, %p, %p, %p, %d, %d, %p)", p1, p2, pB, pMold, pPoint_list, pNorm_list, n, pMax_pnts, c); |
||
3994 | |||
3995 | //float scale; // Pierre-Marie Baty -- unused variable |
||
3996 | |||
3997 | plane1 = LineBoxColl(p1, p2, pB, &hp1); |
||
3998 | if (plane1 == 0) { |
||
3999 | return 0; |
||
4000 | } |
||
4001 | if (n + 2 > pMax_pnts) { |
||
4002 | return 0; |
||
4003 | } |
||
4004 | plane2 = LineBoxColl(p2, p1, pB, &hp2); |
||
4005 | if (plane2 == 0) { |
||
4006 | return 0; |
||
4007 | } |
||
4008 | if (plane1 != 8 && plane2 != 8 && (plane1 ^ plane2) == 4) { |
||
4009 | BrVector3Add(&op1, &hp2, &hp1); |
||
4010 | BrVector3Scale(&op1, &op1, .5f); |
||
4011 | BrMatrix34ApplyP(&op2, &op1, pMold); |
||
4012 | plane3 = LineBoxColl(&op2, &op1, pB, &hp3); |
||
4013 | if (plane3 == 8) { |
||
4014 | return 0; |
||
4015 | } |
||
4016 | GetBoundsEdge(&pPoint_list[n], &edge, pB, plane1, plane3, &op2, &hp1, &hp2, c->collision_flag); |
||
4017 | GetBoundsEdge(&pPoint_list[n + 1], &edge, pB, plane2, plane3, &op2, &hp1, &hp2, c->collision_flag); |
||
4018 | GetPlaneNormal(&pNorm_list[n], plane3); |
||
4019 | BrVector3Copy(&pNorm_list[n + 1], &pNorm_list[n]); |
||
4020 | return 2; |
||
4021 | } else if (plane1 == 8 && plane2 != 8) { |
||
4022 | BrMatrix34ApplyP(&a, p1, pMold); |
||
4023 | plane3 = LineBoxColl(&a, p1, pB, &hp3); |
||
4024 | if (plane3 == 8) { |
||
4025 | return 0; |
||
4026 | } |
||
4027 | BrVector3Copy(&pPoint_list[n], &hp3); |
||
4028 | GetPlaneNormal(&pNorm_list[n], plane2); |
||
4029 | if (plane2 == plane3 || (plane3 ^ plane2) == 4) { |
||
4030 | return 1; |
||
4031 | } |
||
4032 | GetBoundsEdge(&pPoint_list[n + 1], &edge, pB, plane2, plane3, p1, &hp2, &hp3, c->collision_flag); |
||
4033 | BrVector3Sub(&op1, p1, p2); |
||
4034 | BrVector3Cross(&pNorm_list[n + 1], &edge, &op1); |
||
4035 | BrVector3Normalise(&pNorm_list[n + 1], &pNorm_list[n + 1]); |
||
4036 | d = (plane2 - 1) & 3; |
||
4037 | if ((pNorm_list[n + 1].v[d] < 0.f) == (plane2 & 4) >> 2) { |
||
4038 | BrVector3Negate(&pNorm_list[n + 1], &pNorm_list[n + 1]); |
||
4039 | } |
||
4040 | BrVector3Copy(&op1, &pNorm_list[n + 1]); |
||
4041 | BrMatrix34ApplyV(&pNorm_list[n + 1], &op1, pMold); |
||
4042 | return 2; |
||
4043 | } else if (plane2 == 8 && plane1 != 8) { |
||
4044 | BrMatrix34ApplyP(&b, p2, pMold); |
||
4045 | plane3 = LineBoxColl(&b, p2, pB, &hp3); |
||
4046 | if (plane3 == 8) { |
||
4047 | return 0; |
||
4048 | } |
||
4049 | pPoint_list[n] = hp3; |
||
4050 | GetPlaneNormal(&pNorm_list[n], plane1); |
||
4051 | if (plane1 == plane3 || (plane3 ^ plane1) == 4) { |
||
4052 | return 1; |
||
4053 | } |
||
4054 | GetBoundsEdge(&pPoint_list[n + 1], &edge, pB, plane1, plane3, p2, &hp1, &hp3, c->collision_flag); |
||
4055 | BrVector3Sub(&op1, p1, p2); |
||
4056 | BrVector3Cross(&pNorm_list[n + 1], &edge, &op1); |
||
4057 | BrVector3Normalise(&pNorm_list[n + 1], &pNorm_list[n + 1]); |
||
4058 | d = (plane1 - 1) & 3; |
||
4059 | if ((pNorm_list[n + 1].v[d] < 0.f) == (plane1 & 4) >> 2) { |
||
4060 | BrVector3Negate(&pNorm_list[n + 1], &pNorm_list[n + 1]); |
||
4061 | } |
||
4062 | BrVector3Copy(&op1, &pNorm_list[n + 1]); |
||
4063 | BrMatrix34ApplyV(&pNorm_list[n + 1], &op1, pMold); |
||
4064 | return 2; |
||
4065 | } else if (plane1 != 8 && plane2 != 8) { |
||
4066 | BrVector3Add(&op1, &hp2, &hp1); |
||
4067 | BrVector3Scale(&op1, &op1, .5f); |
||
4068 | BrMatrix34ApplyP(&op2, &op1, pMold); |
||
4069 | plane3 = LineBoxColl(&op2, &op1, pB, &hp3); |
||
4070 | if (plane3 == 8 || plane3 == 0) { |
||
4071 | return 0; |
||
4072 | } |
||
4073 | if (plane1 == plane3 || plane2 == plane3) { |
||
4074 | GetBoundsEdge(&pPoint_list[n], &edge, pB, plane1, plane2, &op2, &hp1, &hp2, c->collision_flag); |
||
4075 | BrVector3Sub(&op1, &hp1, &hp2); |
||
4076 | BrVector3Cross(&op2, &edge, &op1); |
||
4077 | BrVector3Normalise(&pNorm_list[n], &op2); |
||
4078 | BrVector3Add(&op1, &pB->max, &pB->min); |
||
4079 | BrVector3Scale(&op1, &op1, .5f); |
||
4080 | BrVector3Sub(&op1, &pPoint_list[n], &op1); |
||
4081 | if (BrVector3Dot(&pNorm_list[n], &op1) > 0.f) { |
||
4082 | BrVector3Negate(&pNorm_list[n], &pNorm_list[n]); |
||
4083 | } |
||
4084 | BrVector3Copy(&op1, &pNorm_list[n]); |
||
4085 | BrMatrix34ApplyV(&pNorm_list[n], &op1, pMold); |
||
4086 | return 1; |
||
4087 | } else { |
||
4088 | GetBoundsEdge(&pPoint_list[n], &edge, pB, plane1, plane3, &hp3, &hp1, &hp2, c->collision_flag); |
||
4089 | GetBoundsEdge(&pPoint_list[n + 1], &edge, pB, plane2, plane3, &hp3, &hp1, &hp2, c->collision_flag); |
||
4090 | GetPlaneNormal(&pNorm_list[n], plane3); |
||
4091 | BrVector3Copy(&pNorm_list[n + 1], &pNorm_list[n]); |
||
4092 | return 2; |
||
4093 | } |
||
4094 | } else if (plane1 == 8 && plane2 == 8) { |
||
4095 | BrMatrix34ApplyP(&op1, p1, pMold); |
||
4096 | plane3 = LineBoxColl(&op1, p1, pB, &pPoint_list[n]); |
||
4097 | GetPlaneNormal(&pNorm_list[n], plane3); |
||
4098 | d = n + (plane3 != 8); |
||
4099 | BrMatrix34ApplyP(&op1, p2, pMold); |
||
4100 | plane3 = LineBoxColl(&op1, p2, pB, &pPoint_list[d]); |
||
4101 | GetPlaneNormal(&pNorm_list[d], plane3); |
||
4102 | return (n != d) + (plane3 != 8); |
||
4103 | } else { |
||
4104 | return 0; |
||
4105 | } |
||
4106 | } |
||
4107 | |||
4108 | // IDA: void __usercall GetPlaneNormal(br_vector3 *n@<EAX>, int p@<EDX>) |
||
4109 | void GetPlaneNormal(br_vector3* n, int p) { |
||
4110 | int d; |
||
4111 | LOG_TRACE("(%p, %d)", n, p); |
||
4112 | |||
4113 | d = (p - 1) & 3; |
||
4114 | BrVector3Set(n, 0.f, 0.f, 0.f); |
||
4115 | if ((p & 4) != 0) { |
||
4116 | n->v[d] = 1.0f; |
||
4117 | } else { |
||
4118 | n->v[d] = -1.0f; |
||
4119 | } |
||
4120 | } |
||
4121 | |||
4122 | // 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) |
||
4123 | 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) { |
||
4124 | int d1; |
||
4125 | int d2; |
||
4126 | int d3; |
||
4127 | br_vector3 n; |
||
4128 | br_vector3 p; |
||
4129 | br_vector3 q; |
||
4130 | LOG_TRACE("(%p, %p, %p, %d, %d, %p, %p, %p, %d)", pos, edge, pB, plane1, plane2, a, b, c, flag); |
||
4131 | |||
4132 | d1 = (plane1 - 1) & 3; |
||
4133 | d2 = (plane2 - 1) & 3; |
||
4134 | BrVector3Sub(&n, b, a); |
||
4135 | BrVector3Sub(&p, c, a); |
||
4136 | BrVector3Cross(&q, &n, &p); |
||
4137 | if ((plane1 & 4) != 0) { |
||
4138 | pos->v[d1] = pB->min.v[d1]; |
||
4139 | } else { |
||
4140 | pos->v[d1] = pB->max.v[d1]; |
||
4141 | } |
||
4142 | if ((plane2 & 4) != 0) { |
||
4143 | pos->v[d2] = pB->min.v[d2]; |
||
4144 | } else { |
||
4145 | pos->v[d2] = pB->max.v[d2]; |
||
4146 | } |
||
4147 | d3 = 3 - d1 - d2; |
||
4148 | edge->v[d1] = 0.f; |
||
4149 | edge->v[d2] = 0.f; |
||
4150 | edge->v[d3] = 1.f; |
||
4151 | if ((flag & 1) != 0) { |
||
4152 | pos->v[d3] = (c->v[d3] + b->v[d3]) / 2.f; |
||
4153 | } else { |
||
4154 | 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]; |
||
4155 | } |
||
4156 | return 1; |
||
4157 | } |
||
4158 | |||
4159 | // IDA: void __usercall oldMoveOurCar(tU32 pTime_difference@<EAX>) |
||
4160 | void oldMoveOurCar(tU32 pTime_difference) { |
||
4161 | //br_vector3 thrust_vector; // Pierre-Marie Baty -- unused variable |
||
4162 | //br_matrix34 direction_matrix; // Pierre-Marie Baty -- unused variable |
||
4163 | //br_matrix34 old_mat; // Pierre-Marie Baty -- unused variable |
||
4164 | //double rotate_amount; // Pierre-Marie Baty -- unused variable |
||
4165 | //br_scalar nearest_y_above; // Pierre-Marie Baty -- unused variable |
||
4166 | //br_scalar nearest_y_below; // Pierre-Marie Baty -- unused variable |
||
4167 | //br_scalar speed; // Pierre-Marie Baty -- unused variable |
||
4168 | //int below_face_index; // Pierre-Marie Baty -- unused variable |
||
4169 | //int above_face_index; // Pierre-Marie Baty -- unused variable |
||
4170 | //br_model* below_model; // Pierre-Marie Baty -- unused variable |
||
4171 | //br_model* above_model; // Pierre-Marie Baty -- unused variable |
||
4172 | LOG_TRACE("(%d)", pTime_difference); |
||
4173 | NOT_IMPLEMENTED(); |
||
4174 | } |
||
4175 | |||
4176 | // IDA: void __cdecl ToggleCollisionDetection() |
||
4177 | void ToggleCollisionDetection(void) { |
||
4178 | LOG_TRACE("()"); |
||
4179 | NOT_IMPLEMENTED(); |
||
4180 | } |
||
4181 | |||
4182 | // IDA: void __cdecl CancelPendingCunningStunt() |
||
4183 | void CancelPendingCunningStunt(void) { |
||
4184 | LOG_TRACE("()"); |
||
4185 | |||
4186 | gQuite_wild_end = 0; |
||
4187 | gQuite_wild_start = 0; |
||
4188 | gOn_me_wheels_start = 0; |
||
4189 | gWoz_upside_down_at_all = 0; |
||
4190 | gWild_start = 0; |
||
4191 | } |
||
4192 | |||
4193 | // IDA: float __cdecl frac(float pN) |
||
4194 | float frac(float pN) { |
||
4195 | LOG_TRACE("(%f)", pN); |
||
4196 | |||
4197 | return pN - (float)(int)pN; |
||
4198 | } |
||
4199 | |||
4200 | // IDA: void __usercall SetAmbientPratCam(tCar_spec *pCar@<EAX>) |
||
4201 | void SetAmbientPratCam(tCar_spec* pCar) { |
||
4202 | br_scalar vcs_x; |
||
4203 | br_scalar vcs_y; |
||
4204 | br_scalar vcs_z; |
||
4205 | br_scalar abs_vcs_x; |
||
4206 | br_scalar abs_vcs_y; |
||
4207 | br_scalar abs_vcs_z; |
||
4208 | br_scalar abs_omega_x; |
||
4209 | br_scalar abs_omega_y; |
||
4210 | br_scalar abs_omega_z; |
||
4211 | tU32 the_time; |
||
4212 | static tU32 last_time_on_ground; |
||
4213 | LOG_TRACE("(%p)", pCar); |
||
4214 | |||
4215 | if (gRace_finished) { |
||
4216 | return; |
||
4217 | } |
||
4218 | the_time = GetTotalTime(); |
||
4219 | if (pCar->number_of_wheels_on_ground != 0) { |
||
4220 | last_time_on_ground = the_time; |
||
4221 | } |
||
4222 | vcs_x = pCar->velocity_car_space.v[0]; |
||
4223 | vcs_y = pCar->velocity_car_space.v[1]; |
||
4224 | vcs_z = pCar->velocity_car_space.v[2]; |
||
4225 | abs_vcs_x = fabsf(vcs_x); |
||
4226 | abs_vcs_y = fabsf(vcs_y); |
||
4227 | abs_vcs_z = fabsf(vcs_z); |
||
4228 | abs_omega_x = fabsf(pCar->omega.v[0]); |
||
4229 | abs_omega_y = fabsf(pCar->omega.v[1]); |
||
4230 | abs_omega_z = fabsf(pCar->omega.v[2]); |
||
4231 | |||
4232 | if (abs_omega_x > 4.5f || abs_omega_z > 4.5f) { |
||
4233 | ChangeAmbientPratcam(9); |
||
4234 | } else if (abs_omega_y > 4.5f) { |
||
4235 | ChangeAmbientPratcam(12); |
||
4236 | } else if (abs_omega_x > 3.f || abs_omega_z > 3.f) { |
||
4237 | ChangeAmbientPratcam(8); |
||
4238 | } else if (abs_omega_y > 3.f) { |
||
4239 | ChangeAmbientPratcam(11); |
||
4240 | } else if (pCar->car_master_actor->t.t.mat.m[1][1] < 0.1f) { |
||
4241 | ChangeAmbientPratcam(44); |
||
4242 | } else if (abs_vcs_y > abs_vcs_z && abs_vcs_y > abs_vcs_x && vcs_y < -.004f) { |
||
4243 | ChangeAmbientPratcam(6); |
||
4244 | } else if (the_time - last_time_on_ground > 500) { |
||
4245 | ChangeAmbientPratcam(5); |
||
4246 | } else if (abs_vcs_x > abs_vcs_z && vcs_x > .001f) { |
||
4247 | ChangeAmbientPratcam(26); |
||
4248 | } else if (abs_vcs_x > abs_vcs_z && vcs_x < -.001f) { |
||
4249 | ChangeAmbientPratcam(25); |
||
4250 | } else if (abs_omega_x > 1.5f || abs_omega_z > 1.5f) { |
||
4251 | ChangeAmbientPratcam(7); |
||
4252 | } else if (abs_omega_y > 1.5f) { |
||
4253 | ChangeAmbientPratcam(10); |
||
4254 | } else if (abs_vcs_z > .01f) { |
||
4255 | ChangeAmbientPratcam(3); |
||
4256 | } else if (abs_vcs_z > .004f) { |
||
4257 | ChangeAmbientPratcam(2); |
||
4258 | } else if (abs_vcs_z > .0015f) { |
||
4259 | ChangeAmbientPratcam(1); |
||
4260 | } else { |
||
4261 | ChangeAmbientPratcam(0); |
||
4262 | } |
||
4263 | } |
||
4264 | |||
4265 | // IDA: void __usercall MungeCarGraphics(tU32 pFrame_period@<EAX>) |
||
4266 | void MungeCarGraphics(tU32 pFrame_period) { |
||
4267 | int i; |
||
4268 | //int j; // Pierre-Marie Baty -- unused variable |
||
4269 | int update_mat; |
||
4270 | int spinning_wildly; |
||
4271 | int spinning_mildly; |
||
4272 | int car_count; |
||
4273 | int oily_count; |
||
4274 | int car; |
||
4275 | int cat; |
||
4276 | //int new_special_screen; // Pierre-Marie Baty -- unused variable |
||
4277 | tCar_spec* the_car; |
||
4278 | br_scalar distance_from_camera; |
||
4279 | br_scalar car_x; |
||
4280 | br_scalar car_z; |
||
4281 | br_scalar oily_size; |
||
4282 | br_scalar car_radius; |
||
4283 | br_scalar abs_omega_x; |
||
4284 | br_scalar abs_omega_y; |
||
4285 | br_scalar abs_omega_z; |
||
4286 | float wheel_speed; |
||
4287 | //float speed_mph; // Pierre-Marie Baty -- unused variable |
||
4288 | //float rev_angle; // Pierre-Marie Baty -- unused variable |
||
4289 | float sine_angle; |
||
4290 | float raw_revs; |
||
4291 | float rev_reducer; |
||
4292 | //tSpecial_screen* the_special_screen; // Pierre-Marie Baty -- unused variable |
||
4293 | br_material* the_material; |
||
4294 | tU32 the_time; |
||
4295 | br_actor* oily_actor; |
||
4296 | LOG_TRACE("(%d)", pFrame_period); |
||
4297 | |||
4298 | if (gNet_mode != eNet_mode_none |
||
4299 | && ((gCurrent_net_game->type == eNet_game_type_foxy && gThis_net_player_index == gIt_or_fox) |
||
4300 | || (gCurrent_net_game->type == eNet_game_type_tag && gThis_net_player_index != gIt_or_fox))) { |
||
4301 | gProgram_state.current_car.power_up_levels[1] = 0; |
||
4302 | } |
||
4303 | SetAmbientPratCam(&gProgram_state.current_car); |
||
4304 | if (gProgram_state.cockpit_on) { |
||
4305 | SwitchCarActor(&gProgram_state.current_car, gProgram_state.current_car.car_actor_count - 1); |
||
4306 | } else { |
||
4307 | SwitchCarActor(&gProgram_state.current_car, gProgram_state.current_car.car_actor_count - 2); |
||
4308 | } |
||
4309 | |||
4310 | the_time = PDGetTotalTime(); |
||
4311 | for (cat = eVehicle_self; cat <= eVehicle_rozzer; cat++) { |
||
4312 | if (cat == eVehicle_self) { |
||
4313 | car_count = 1; |
||
4314 | } else { |
||
4315 | car_count = GetCarCount(cat); |
||
4316 | } |
||
4317 | for (car = 0; car < car_count; car++) { |
||
4318 | if (cat == eVehicle_self) { |
||
4319 | the_car = &gProgram_state.current_car; |
||
4320 | } else { |
||
4321 | the_car = GetCarSpec(cat, car); |
||
4322 | } |
||
4323 | 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; |
||
4324 | } |
||
4325 | } |
||
4326 | for (car = 0; car < gNum_active_cars; car++) { |
||
4327 | the_car = gActive_car_list[car]; |
||
4328 | if (the_car->car_master_actor->render_style != BR_RSTYLE_NONE) { |
||
4329 | car_x = the_car->car_master_actor->t.t.translate.t.v[0]; |
||
4330 | car_z = the_car->car_master_actor->t.t.translate.t.v[2]; |
||
4331 | the_car->shadow_intersection_flags = 0; |
||
4332 | oily_count = GetOilSpillCount(); |
||
4333 | for (i = 0; i < oily_count; i++) { |
||
4334 | GetOilSpillDetails(i, &oily_actor, &oily_size); |
||
4335 | if (oily_actor != NULL) { |
||
4336 | car_radius = the_car->bounds[1].max.v[2] / WORLD_SCALE * 1.5f; |
||
4337 | if (oily_actor->t.t.translate.t.v[0] - oily_size < car_x + car_radius |
||
4338 | && oily_actor->t.t.translate.t.v[0] + oily_size > car_x - car_radius |
||
4339 | && oily_actor->t.t.translate.t.v[2] - oily_size < car_z + car_radius |
||
4340 | && oily_actor->t.t.translate.t.v[2] + oily_size > car_z - car_radius) { |
||
4341 | the_car->shadow_intersection_flags |= 1 << i; |
||
4342 | } |
||
4343 | } |
||
4344 | } |
||
4345 | if (the_car->driver < eDriver_net_human && (!gAction_replay_mode || !ReplayIsPaused())) { |
||
4346 | if (gCountdown) { |
||
4347 | sine_angle = FRandomBetween(0.4f, 1.6f) * ((double)GetTotalTime() / ((double)gCountdown * 100.0f)); |
||
4348 | sine_angle = frac(sine_angle) * 360.0f; |
||
4349 | sine_angle = FastScalarSin(sine_angle); |
||
4350 | raw_revs = the_car->red_line * fabsf(sine_angle); |
||
4351 | rev_reducer = (11.0 - (double)gCountdown) / 10.0; |
||
4352 | the_car->revs = rev_reducer * raw_revs; |
||
4353 | } else { |
||
4354 | the_car->revs = (the_car->speedo_speed / 0.003 |
||
4355 | - (double)(int)(the_car->speedo_speed / 0.003)) |
||
4356 | * (double)(the_car->red_line - 800) |
||
4357 | + 800.0; |
||
4358 | } |
||
4359 | } |
||
4360 | for (i = 0; i < the_car->number_of_steerable_wheels; i++) { |
||
4361 | ControlBoundFunkGroove(the_car->steering_ref[i], the_car->steering_angle); |
||
4362 | } |
||
4363 | for (i = 0; i < COUNT_OF(the_car->rf_sus_ref); i++) { |
||
4364 | ControlBoundFunkGroove(the_car->rf_sus_ref[i], the_car->rf_sus_position); |
||
4365 | if ((i & 1) != 0) { |
||
4366 | ControlBoundFunkGroove(the_car->lf_sus_ref[i], -the_car->lf_sus_position); |
||
4367 | } else { |
||
4368 | ControlBoundFunkGroove(the_car->lf_sus_ref[i], the_car->lf_sus_position); |
||
4369 | } |
||
4370 | } |
||
4371 | for (i = 0; i < COUNT_OF(the_car->rr_sus_ref); i++) { |
||
4372 | ControlBoundFunkGroove(the_car->rr_sus_ref[i], the_car->rr_sus_position); |
||
4373 | if ((i & 1) != 0) { |
||
4374 | ControlBoundFunkGroove(the_car->lr_sus_ref[i], -the_car->lr_sus_position); |
||
4375 | } else { |
||
4376 | ControlBoundFunkGroove(the_car->lr_sus_ref[i], the_car->lr_sus_position); |
||
4377 | } |
||
4378 | } |
||
4379 | if (!gAction_replay_mode || !ReplayIsPaused()) { |
||
4380 | wheel_speed = -(the_car->speedo_speed / the_car->non_driven_wheels_circum * (float)gFrame_period); |
||
4381 | ControlBoundFunkGroovePlus(the_car->non_driven_wheels_spin_ref_1, wheel_speed); |
||
4382 | ControlBoundFunkGroovePlus(the_car->non_driven_wheels_spin_ref_2, wheel_speed); |
||
4383 | ControlBoundFunkGroovePlus(the_car->non_driven_wheels_spin_ref_3, wheel_speed); |
||
4384 | ControlBoundFunkGroovePlus(the_car->non_driven_wheels_spin_ref_4, wheel_speed); |
||
4385 | if (the_car->driver >= eDriver_net_human) { |
||
4386 | if (the_car->gear) { |
||
4387 | wheel_speed = -(the_car->revs |
||
4388 | * the_car->speed_revs_ratio |
||
4389 | / 6900.f |
||
4390 | * (double)the_car->gear |
||
4391 | / the_car->driven_wheels_circum |
||
4392 | * (double)gFrame_period); |
||
4393 | } else if (the_car->keys.brake) { |
||
4394 | wheel_speed = 0.0; |
||
4395 | } else { |
||
4396 | wheel_speed = -(the_car->speedo_speed / the_car->driven_wheels_circum * (double)gFrame_period); |
||
4397 | } |
||
4398 | } |
||
4399 | ControlBoundFunkGroovePlus(the_car->driven_wheels_spin_ref_1, wheel_speed); |
||
4400 | ControlBoundFunkGroovePlus(the_car->driven_wheels_spin_ref_2, wheel_speed); |
||
4401 | ControlBoundFunkGroovePlus(the_car->driven_wheels_spin_ref_3, wheel_speed); |
||
4402 | ControlBoundFunkGroovePlus(the_car->driven_wheels_spin_ref_4, wheel_speed); |
||
4403 | } |
||
4404 | if (gAction_replay_mode) { |
||
4405 | MungeSpecialVolume((tCollision_info*)the_car); |
||
4406 | } else if (the_car->driver == eDriver_local_human) { |
||
4407 | abs_omega_x = (fabsf(the_car->I.v[0]) + 3.3f) / 2.0f * fabsf(the_car->omega.v[0]); |
||
4408 | abs_omega_y = (fabsf(the_car->I.v[1]) + 3.57f) / 2.0f * fabsf(the_car->omega.v[1]); |
||
4409 | abs_omega_z = (fabsf(the_car->I.v[2]) + 0.44f) / 2.0f * fabsf(the_car->omega.v[2]); |
||
4410 | spinning_wildly = abs_omega_x > 26.4f || abs_omega_y > 49.98f || abs_omega_z > 3.52f; |
||
4411 | if (spinning_wildly && the_time - gLast_cunning_stunt > 10000) { |
||
4412 | if (!gWild_start |
||
4413 | || (the_car->last_special_volume != NULL && the_car->last_special_volume->gravity_multiplier != 1.f)) { |
||
4414 | gWild_start = the_time; |
||
4415 | } else if (the_time - gWild_start >= 500) { |
||
4416 | DoFancyHeadup(kFancyHeadupCunningStuntBonus); |
||
4417 | EarnCredits(gCunning_stunt_bonus[gProgram_state.skill_level]); |
||
4418 | gLast_cunning_stunt = the_time; |
||
4419 | gOn_me_wheels_start = 0; |
||
4420 | gQuite_wild_end = 0; |
||
4421 | gQuite_wild_start = 0; |
||
4422 | gWoz_upside_down_at_all = 0; |
||
4423 | } |
||
4424 | } else { |
||
4425 | gWild_start = 0; |
||
4426 | spinning_mildly = abs_omega_x > 1.65f || abs_omega_z > 0.22f; |
||
4427 | if (the_car->number_of_wheels_on_ground <= 3) { |
||
4428 | gOn_me_wheels_start = 0; |
||
4429 | if (the_car->number_of_wheels_on_ground || !spinning_mildly) { |
||
4430 | gQuite_wild_end = the_time; |
||
4431 | } else { |
||
4432 | if (!gQuite_wild_start) { |
||
4433 | gQuite_wild_start = the_time; |
||
4434 | } |
||
4435 | if (the_car->car_master_actor->t.t.mat.m[1][1] < -0.8f) { |
||
4436 | gWoz_upside_down_at_all = the_time; |
||
4437 | } |
||
4438 | } |
||
4439 | } else { |
||
4440 | if (!gQuite_wild_end) { |
||
4441 | gQuite_wild_end = the_time; |
||
4442 | } |
||
4443 | if (!gQuite_wild_start |
||
4444 | || the_time - gLast_cunning_stunt <= 10000 |
||
4445 | || gQuite_wild_end - gQuite_wild_start < 2000 |
||
4446 | || gWoz_upside_down_at_all < (int) gQuite_wild_start // Pierre-Marie Baty -- added type cast |
||
4447 | || gWoz_upside_down_at_all > (int) gQuite_wild_end // Pierre-Marie Baty -- added type cast |
||
4448 | || (!gOn_me_wheels_start && the_time - gQuite_wild_end >= 300)) { |
||
4449 | gQuite_wild_end = 0; |
||
4450 | gQuite_wild_start = 0; |
||
4451 | gOn_me_wheels_start = 0; |
||
4452 | gWoz_upside_down_at_all = 0; |
||
4453 | } else if (!gOn_me_wheels_start) { |
||
4454 | gOn_me_wheels_start = the_time; |
||
4455 | } else if (the_time - gOn_me_wheels_start > 500 |
||
4456 | && (the_car->last_special_volume == NULL |
||
4457 | || the_car->last_special_volume->gravity_multiplier == 1.0f)) { |
||
4458 | DoFancyHeadup(kFancyHeadupCunningStuntBonus); |
||
4459 | EarnCredits(gCunning_stunt_bonus[gProgram_state.skill_level]); |
||
4460 | gLast_cunning_stunt = PDGetTotalTime(); |
||
4461 | gQuite_wild_end = 0; |
||
4462 | gQuite_wild_start = 0; |
||
4463 | gOn_me_wheels_start = 0; |
||
4464 | gWoz_upside_down_at_all = 0; |
||
4465 | } |
||
4466 | } |
||
4467 | } |
||
4468 | } |
||
4469 | if (the_car->driver != eDriver_local_human && the_car->car_model_variable) { |
||
4470 | distance_from_camera = Vector3DistanceSquared(&the_car->car_master_actor->t.t.translate.t, |
||
4471 | (br_vector3*)gCamera_to_world.m[3]) |
||
4472 | / gCar_simplification_factor[gGraf_spec_index][gCar_simplification_level]; |
||
4473 | if (gNet_mode != eNet_mode_none && gNet_players[gIt_or_fox].car == the_car) { |
||
4474 | distance_from_camera = 0.f; |
||
4475 | } |
||
4476 | for (i = 0; i < the_car->car_actor_count; i++) { |
||
4477 | if (the_car->car_model_actors[i].min_distance_squared <= distance_from_camera) { |
||
4478 | SwitchCarActor(the_car, i); |
||
4479 | break; |
||
4480 | } |
||
4481 | } |
||
4482 | } |
||
4483 | if (the_car->screen_material != NULL) { |
||
4484 | the_material = NULL; |
||
4485 | if (the_car->last_special_volume != NULL && the_car->last_special_volume->screen_material != NULL) { |
||
4486 | if (!gAction_replay_mode && the_car->last_special_volume != gDefault_water_spec_vol) { |
||
4487 | the_material = the_car->last_special_volume->screen_material; |
||
4488 | } else if (gProgram_state.current_depth_effect.type == eDepth_effect_fog) { |
||
4489 | the_material = gProgram_state.standard_screen_fog; |
||
4490 | } else if (gProgram_state.current_depth_effect.sky_texture != NULL) { |
||
4491 | the_material = gProgram_state.standard_screen; |
||
4492 | } else { |
||
4493 | the_material = gProgram_state.standard_screen_dark; |
||
4494 | } |
||
4495 | } else { |
||
4496 | if (gProgram_state.current_depth_effect.type == eDepth_effect_fog) { |
||
4497 | the_material = gProgram_state.standard_screen_fog; |
||
4498 | } else if (gProgram_state.current_depth_effect.sky_texture != NULL) { |
||
4499 | the_material = gProgram_state.standard_screen; |
||
4500 | } else { |
||
4501 | the_material = gProgram_state.standard_screen_dark; |
||
4502 | } |
||
4503 | } |
||
4504 | update_mat = 0; |
||
4505 | if (the_material != NULL && the_car->screen_material_source != the_material) { |
||
4506 | the_car->screen_material->flags = the_material->flags; |
||
4507 | the_car->screen_material->ka = the_material->ka; |
||
4508 | the_car->screen_material->kd = the_material->kd; |
||
4509 | the_car->screen_material->ks = the_material->ks; |
||
4510 | the_car->screen_material->power = the_material->power; |
||
4511 | the_car->screen_material->index_base = the_material->index_base; |
||
4512 | the_car->screen_material->index_range = the_material->index_range; |
||
4513 | the_car->screen_material->colour_map = the_material->colour_map; |
||
4514 | |||
4515 | the_car->screen_material->map_transform = the_material->map_transform; |
||
4516 | the_car->screen_material->index_shade = gRender_shade_table; |
||
4517 | the_car->screen_material_source = the_material; |
||
4518 | update_mat = 1; |
||
4519 | } |
||
4520 | if (the_car->screen_material->colour_map != NULL) { |
||
4521 | the_car->screen_material->map_transform.m[2][0] = fmodf(car_x, 1.f); |
||
4522 | the_car->screen_material->map_transform.m[2][1] = fmodf(car_z, 1.f); |
||
4523 | if (!update_mat) { |
||
4524 | BrMaterialUpdate(the_car->screen_material, BR_MATU_MAP_TRANSFORM); |
||
4525 | } |
||
4526 | } |
||
4527 | if (update_mat) { |
||
4528 | BrMaterialUpdate(the_car->screen_material, BR_MATU_ALL); |
||
4529 | } |
||
4530 | } |
||
4531 | } |
||
4532 | } |
||
4533 | } |
||
4534 | |||
4535 | // IDA: void __cdecl ResetCarScreens() |
||
4536 | void ResetCarScreens(void) { |
||
4537 | int cat; |
||
4538 | int car_count; |
||
4539 | int i; |
||
4540 | tCar_spec* the_car; |
||
4541 | LOG_TRACE("()"); |
||
4542 | |||
4543 | for (cat = eVehicle_self; cat < eVehicle_drone; cat++) { |
||
4544 | car_count = (cat == eVehicle_self) ? 1 : GetCarCount(cat); |
||
4545 | for (i = 0; i < car_count; i++) { |
||
4546 | the_car = (cat == eVehicle_self) ? &gProgram_state.current_car : GetCarSpec(cat, i); |
||
4547 | the_car->last_special_volume = NULL; |
||
4548 | } |
||
4549 | } |
||
4550 | MungeCarGraphics(gFrame_period); |
||
4551 | } |
||
4552 | |||
4553 | // IDA: tCar_spec* __cdecl GetRaceLeader() |
||
4554 | tCar_spec* GetRaceLeader(void) { |
||
18 | pmbaty | 4555 | int i; |
4556 | int score; |
||
4557 | tCar_spec* car; |
||
1 | pmbaty | 4558 | LOG_TRACE("()"); |
18 | pmbaty | 4559 | |
4560 | if ((gCurrent_net_game->type == eNet_game_type_foxy || gCurrent_net_game->type == eNet_game_type_tag) && gIt_or_fox >= 0 && gIt_or_fox < gNumber_of_net_players) { |
||
4561 | car = gNet_players[gIt_or_fox].car; |
||
4562 | } else { |
||
4563 | car = gNet_players[0].car; |
||
4564 | score = gNet_players[0].last_score_index; |
||
4565 | for (i = 1; i < gNumber_of_net_players; i++) { |
||
4566 | if (score > gNet_players[i].last_score_index) { |
||
4567 | score = gNet_players[i].last_score_index; |
||
4568 | car = gNet_players[i].car; |
||
4569 | } |
||
4570 | } |
||
4571 | } |
||
4572 | return car; |
||
1 | pmbaty | 4573 | } |
4574 | |||
4575 | // IDA: void __cdecl AmIGettingBoredWatchingCameraSpin() |
||
4576 | void AmIGettingBoredWatchingCameraSpin(void) { |
||
18 | pmbaty | 4577 | static tU32 time_of_death; |
4578 | static tU32 headup_timer; |
||
4579 | tCar_spec* car; |
||
4580 | char s[256]; |
||
1 | pmbaty | 4581 | LOG_TRACE("()"); |
4582 | |||
18 | pmbaty | 4583 | if (gNet_mode == eNet_mode_none |
4584 | || (gCurrent_net_game->type != eNet_game_type_sudden_death |
||
4585 | && gCurrent_net_game->type != eNet_game_type_tag |
||
4586 | && gCurrent_net_game->type != eNet_game_type_fight_to_death)) { |
||
4587 | gOpponent_viewing_mode = 0; |
||
4588 | } else if (!gRace_finished) { |
||
4589 | time_of_death = 0; |
||
4590 | gOpponent_viewing_mode = 0; |
||
4591 | } else if (time_of_death == 0) { |
||
4592 | time_of_death = GetRaceTime(); |
||
4593 | } else { |
||
4594 | if (GetRaceTime() >= time_of_death + 10000) { |
||
4595 | if (gOpponent_viewing_mode == 0) { |
||
4596 | gOpponent_viewing_mode = 1; |
||
4597 | gNet_player_to_view_index = -2; |
||
4598 | ViewNetPlayer(); |
||
4599 | } |
||
4600 | if (gNet_player_to_view_index >= gNumber_of_net_players) { |
||
4601 | gNet_player_to_view_index = -2; |
||
4602 | ViewNetPlayer(); |
||
4603 | } |
||
4604 | if (gNet_player_to_view_index < 0 && gCar_to_view != GetRaceLeader()) { |
||
4605 | gNet_player_to_view_index = -2; |
||
4606 | ViewNetPlayer(); |
||
4607 | } |
||
4608 | if ((GetRaceTime() > headup_timer + 1000 || headup_timer > GetRaceTime()) && gRace_over_reason == eRace_not_over_yet) { |
||
4609 | strcpy(s, GetMiscString(kMiscString_WATCHING)); |
||
4610 | strcat(s, " "); |
||
4611 | if (gNet_player_to_view_index >= 0) { |
||
4612 | strcat(s, gNet_players[gNet_player_to_view_index].player_name); |
||
4613 | } else if (gCurrent_net_game->type == eNet_game_type_tag) { |
||
4614 | strcat(s, GetMiscString(kMiscString_QUOTE_IT_QUOTE)); |
||
4615 | } else { |
||
4616 | strcat(s, GetMiscString(kMiscString_RACE_LEADER)); |
||
4617 | } |
||
4618 | headup_timer = GetRaceTime(); |
||
4619 | NewTextHeadupSlot(6, 0, 500, -4, s); |
||
4620 | } |
||
4621 | } |
||
4622 | } |
||
1 | pmbaty | 4623 | } |
4624 | |||
4625 | // IDA: void __cdecl ViewNetPlayer() |
||
4626 | void ViewNetPlayer(void) { |
||
4627 | LOG_TRACE("()"); |
||
4628 | |||
4629 | if (gOpponent_viewing_mode) { |
||
4630 | if (gProgram_state.cockpit_on) { |
||
4631 | ToggleCockpit(); |
||
4632 | } |
||
4633 | gNet_player_to_view_index++; |
||
4634 | if (gNumber_of_net_players <= gNet_player_to_view_index) { |
||
4635 | gNet_player_to_view_index = -1; |
||
4636 | } |
||
4637 | if (gNet_player_to_view_index < 0) { |
||
4638 | gCar_to_view = GetRaceLeader(); |
||
4639 | } else { |
||
4640 | gCar_to_view = gNet_players[gNet_player_to_view_index].car; |
||
4641 | } |
||
4642 | gCamera_yaw = 0; |
||
4643 | InitialiseExternalCamera(); |
||
4644 | PositionExternalCamera(gCar_to_view, 200u); |
||
4645 | } |
||
4646 | } |
||
4647 | |||
4648 | // IDA: void __cdecl ViewOpponent() |
||
4649 | void ViewOpponent(void) { |
||
4650 | static int n; |
||
4651 | LOG_TRACE("()"); |
||
4652 | |||
4653 | n++; |
||
4654 | if (gNet_mode != eNet_mode_none) { |
||
4655 | if (n >= gNumber_of_net_players) { |
||
4656 | n = 0; |
||
4657 | } |
||
4658 | gCar_to_view = gNet_players[n].car; |
||
4659 | NewTextHeadupSlot(4, 0, 2000, -3, gNet_players[n].player_name); |
||
4660 | } else { |
||
4661 | if (n >= gNum_viewable_cars) { |
||
4662 | n = 0; |
||
4663 | } |
||
4664 | gCar_to_view = gViewable_car_list[n]; |
||
4665 | NewTextHeadupSlot(4, 0, 2000, -3, gViewable_car_list[n]->driver_name); |
||
4666 | } |
||
4667 | gCamera_yaw = 0; |
||
4668 | InitialiseExternalCamera(); |
||
4669 | PositionExternalCamera(gCar_to_view, 200); |
||
4670 | } |
||
4671 | |||
4672 | // IDA: void __cdecl ToggleCarToCarCollisions() |
||
4673 | void ToggleCarToCarCollisions(void) { |
||
4674 | LOG_TRACE("()"); |
||
4675 | |||
4676 | gCar_car_collisions = !gCar_car_collisions; |
||
4677 | if (gCar_car_collisions) { |
||
4678 | NewTextHeadupSlot(4, 0, 3000, -4, "Car Car Collisions"); |
||
4679 | } else { |
||
4680 | NewTextHeadupSlot(4, 0, 3000, -4, "Ghost Cars"); |
||
4681 | } |
||
4682 | } |
||
4683 | |||
4684 | // IDA: void __cdecl SwapCar() |
||
4685 | void SwapCar(void) { |
||
4686 | LOG_TRACE("()"); |
||
4687 | } |
||
4688 | |||
4689 | // IDA: void __cdecl AdjustDownForce() |
||
4690 | void AdjustDownForce(void) { |
||
4691 | char s[100]; |
||
4692 | tCar_spec* c; |
||
4693 | LOG_TRACE("()"); |
||
4694 | |||
4695 | c = gCar_to_view; |
||
4696 | c->down_force_speed += 50.f; |
||
4697 | if (c->down_force_speed > 2000.f) { |
||
4698 | c->down_force_speed = 50.f; |
||
4699 | } |
||
4700 | if (c->down_force_speed > 300.f) { |
||
4701 | c->down_force_speed = 2000.0; |
||
4702 | } |
||
4703 | sprintf(s, "DownForceSpeed %f", c->down_force_speed); |
||
4704 | NewTextHeadupSlot(4, 0, 1500, -4, s); |
||
4705 | } |
||
4706 | |||
4707 | // IDA: void __cdecl FreezeMechanics() |
||
4708 | void FreezeMechanics(void) { |
||
4709 | LOG_TRACE("()"); |
||
4710 | |||
4711 | gFreeze_mechanics = !gFreeze_mechanics; |
||
4712 | if (gFreeze_mechanics) { |
||
4713 | NewTextHeadupSlot(4, 0, 3000, -4, "Mechanics Frozen"); |
||
4714 | } else { |
||
4715 | NewTextHeadupSlot(4, 0, 3000, -4, "Thawed Mechanics"); |
||
4716 | } |
||
4717 | } |
||
4718 | |||
4719 | // IDA: void __cdecl PutOpponentsInNeutral() |
||
4720 | void PutOpponentsInNeutral(void) { |
||
4721 | LOG_TRACE("()"); |
||
4722 | |||
4723 | gStop_opponents_moving = !gStop_opponents_moving; |
||
4724 | if (gStop_opponents_moving == 0) { |
||
4725 | NewTextHeadupSlot(4, 0, 3000, -4, "Opponents in neutral"); |
||
4726 | } else { |
||
4727 | NewTextHeadupSlot(4, 0, 3000, -4, "Back in gear"); |
||
4728 | } |
||
4729 | } |
||
4730 | |||
4731 | // IDA: void __cdecl SetPanningFieldOfView() |
||
4732 | void SetPanningFieldOfView(void) { |
||
4733 | br_camera* camera_ptr; |
||
4734 | static br_angle panning_angle = 0; // Added by DethRace |
||
4735 | LOG_TRACE("()"); |
||
4736 | |||
4737 | camera_ptr = gCamera->type_data; |
||
4738 | if (panning_angle == 0) { |
||
4739 | panning_angle = BrDegreeToAngle(gCamera_angle) * 0.7f; |
||
4740 | } |
||
4741 | camera_ptr->field_of_view = panning_angle; |
||
4742 | } |
||
4743 | |||
4744 | // IDA: void __usercall CheckDisablePlingMaterials(tCar_spec *pCar@<EAX>) |
||
4745 | void CheckDisablePlingMaterials(tCar_spec* pCar) { |
||
4746 | br_matrix34* mat; |
||
4747 | br_scalar height; |
||
4748 | int i; |
||
4749 | LOG_TRACE("(%p)", pCar); |
||
4750 | |||
4751 | height = 0.f; |
||
4752 | if (pCar->water_d == 10000.f) { |
||
4753 | DisablePlingMaterials(); |
||
4754 | } else { |
||
4755 | mat = &pCar->car_master_actor->t.t.mat; |
||
4756 | for (i = 0; i < 3; i++) { |
||
4757 | if (mat->m[i][1] > 0.f) { |
||
4758 | height += pCar->bounds[0].max.v[i] * mat->m[i][1]; |
||
4759 | } else { |
||
4760 | height += pCar->bounds[0].min.v[i] * mat->m[i][1]; |
||
4761 | } |
||
4762 | } |
||
4763 | if (mat->m[3][1] / WORLD_SCALE + height < pCar->water_d) { |
||
4764 | DisablePlingMaterials(); |
||
4765 | } |
||
4766 | } |
||
4767 | } |
||
4768 | |||
4769 | // IDA: void __usercall PositionExternalCamera(tCar_spec *c@<EAX>, tU32 pTime@<EDX>) |
||
4770 | void PositionExternalCamera(tCar_spec* c, tU32 pTime) { |
||
4771 | static int old_camera_mode; |
||
4772 | br_camera* camera_ptr; |
||
4773 | LOG_TRACE("(%p, %d)", c, pTime); |
||
4774 | |||
4775 | camera_ptr = (br_camera*)gCamera->type_data; |
||
4776 | CheckCameraHither(); |
||
4777 | AmIGettingBoredWatchingCameraSpin(); |
||
4778 | if ((!gAction_replay_mode || gAction_replay_camera_mode == eAction_replay_standard) && old_camera_mode != -1) { |
||
4779 | camera_ptr->field_of_view = BrDegreeToAngle(gCamera_angle); |
||
4780 | old_camera_mode = -1; |
||
4781 | } |
||
4782 | if (!gProgram_state.cockpit_on) { |
||
4783 | if (gOpponent_viewing_mode && gAction_replay_mode) { |
||
4784 | c = &gProgram_state.current_car; |
||
4785 | } else { |
||
4786 | c = gCar_to_view; |
||
4787 | } |
||
4788 | if (c->car_master_actor->t.t.translate.t.v[0] <= 500.0) { |
||
4789 | if (gAction_replay_mode && gAction_replay_camera_mode) { |
||
4790 | if (gAction_replay_camera_mode == eAction_replay_action) { |
||
4791 | CheckDisablePlingMaterials(c); |
||
4792 | if (IncidentCam(c, pTime)) { |
||
4793 | SetPanningFieldOfView(); |
||
4794 | EnablePlingMaterials(); |
||
4795 | old_camera_mode = gAction_replay_camera_mode; |
||
4796 | return; |
||
4797 | } |
||
4798 | } |
||
4799 | CheckDisablePlingMaterials(c); |
||
4800 | SetPanningFieldOfView(); |
||
4801 | if (gAction_replay_camera_mode != old_camera_mode) { |
||
4802 | SetUpPanningCamera(c); |
||
4803 | old_camera_mode = gAction_replay_camera_mode; |
||
4804 | } |
||
4805 | PanningExternalCamera(c, pTime); |
||
4806 | EnablePlingMaterials(); |
||
4807 | } else { |
||
4808 | NormalPositionExternalCamera(c, pTime); |
||
4809 | } |
||
4810 | } |
||
4811 | } |
||
4812 | } |
||
4813 | |||
4814 | // IDA: void __usercall CameraBugFix(tCar_spec *c@<EAX>, tU32 pTime@<EDX>) |
||
4815 | void CameraBugFix(tCar_spec* c, tU32 pTime) { |
||
4816 | //br_matrix34 mat; // Pierre-Marie Baty -- unused variable |
||
4817 | //br_matrix34* m2; // Pierre-Marie Baty -- unused variable |
||
4818 | //br_vector3 tv; // Pierre-Marie Baty -- unused variable |
||
4819 | LOG_TRACE("(%p, %d)", c, pTime); |
||
4820 | |||
4821 | if (gAction_replay_mode && gAction_replay_camera_mode != eAction_replay_standard && gPed_actor != NULL && !gProgram_state.cockpit_on) { |
||
4822 | IncidentCam(c, pTime); |
||
4823 | } |
||
4824 | } |
||
4825 | // IDA: int __usercall PossibleRemoveNonCarFromWorld@<EAX>(br_actor *pActor@<EAX>) |
||
4826 | int PossibleRemoveNonCarFromWorld(br_actor* pActor) { |
||
4827 | tU8 cx; |
||
4828 | tU8 cz; |
||
4829 | tTrack_spec* track_spec; |
||
4830 | LOG_TRACE("(%p)", pActor); |
||
4831 | |||
4832 | track_spec = &gProgram_state.track_spec; |
||
4833 | XZToColumnXZ(&cx, &cz, pActor->t.t.translate.t.v[0], pActor->t.t.translate.t.v[2], track_spec); |
||
4834 | if (track_spec->columns[cz][cx] == pActor->parent) { |
||
4835 | BrActorRemove(pActor); |
||
4836 | return 1; |
||
4837 | } |
||
4838 | return 0; |
||
4839 | } |
||
4840 | |||
4841 | // IDA: void __usercall PutNonCarBackInWorld(br_actor *pActor@<EAX>) |
||
4842 | void PutNonCarBackInWorld(br_actor* pActor) { |
||
4843 | tU8 cx; |
||
4844 | tU8 cz; |
||
4845 | tTrack_spec* track_spec; |
||
4846 | LOG_TRACE("(%p)", pActor); |
||
4847 | |||
4848 | track_spec = &gProgram_state.track_spec; |
||
4849 | XZToColumnXZ(&cx, &cz, pActor->t.t.translate.t.v[0], pActor->t.t.translate.t.v[2], track_spec); |
||
4850 | BrActorAdd(track_spec->columns[cz][cx], pActor); |
||
4851 | } |
||
4852 | |||
4853 | // IDA: int __usercall IncidentCam@<EAX>(tCar_spec *c@<EAX>, tU32 pTime@<EDX>) |
||
4854 | int IncidentCam(tCar_spec* c, tU32 pTime) { |
||
4855 | br_matrix34* m2; |
||
4856 | br_matrix34 mat; |
||
4857 | br_vector3 tv; |
||
4858 | //br_vector3 tv2; // Pierre-Marie Baty -- unused variable |
||
4859 | br_vector3 perp; |
||
4860 | br_vector3 vertical; |
||
4861 | br_vector3 murderer_pos; |
||
4862 | br_scalar ts; |
||
4863 | //tCar_spec* car2; // Pierre-Marie Baty -- unused variable |
||
4864 | static tU32 next_incident_time = 0; |
||
4865 | static tIncident_type type = eNo_incident; |
||
4866 | static float severity; |
||
4867 | static tIncident_info info; |
||
4868 | static int random = 1; |
||
4869 | static int count = 0; |
||
4870 | //br_scalar temp; // Pierre-Marie Baty -- unused variable |
||
4871 | br_vector3 old_cam_pos; |
||
4872 | int removed; |
||
4873 | LOG_TRACE("(%p, %d)", c, pTime); |
||
4874 | |||
4875 | gPed_actor = NULL; |
||
4876 | m2 = &gCamera->t.t.mat; |
||
4877 | if (type == eNo_incident) { |
||
4878 | MoveCamToIncident(c, &type, &severity, &info, &next_incident_time); |
||
4879 | } |
||
4880 | if (type == eNo_incident) { |
||
4881 | return 0; |
||
4882 | } |
||
4883 | if (type == eIncident_ped) { |
||
4884 | BrVector3Copy(&old_cam_pos, &gCamera->t.t.translate.t); |
||
4885 | gPed_actor = info.ped_info.ped_actor; |
||
4886 | removed = PossibleRemoveNonCarFromWorld(info.ped_info.murderer_actor); |
||
4887 | BrMatrix34Mul(&mat, &gPed_actor->t.t.mat, &gPed_actor->parent->t.t.mat); |
||
4888 | info.ped_info.murderer_actor = c->car_master_actor; |
||
4889 | if (info.ped_info.murderer_actor != NULL) { |
||
4890 | BrVector3Copy(&murderer_pos, &c->pos); |
||
4891 | } else if (info.ped_info.murderer_actor->model != NULL) { |
||
4892 | BrVector3Add(&murderer_pos, &info.ped_info.murderer_actor->model->bounds.max, &info.ped_info.murderer_actor->model->bounds.min); |
||
4893 | BrVector3Scale(&murderer_pos, &murderer_pos, 0.5f); |
||
4894 | BrMatrix34ApplyP(&murderer_pos, &murderer_pos, &info.ped_info.murderer_actor->t.t.mat); |
||
4895 | } else { |
||
4896 | BrVector3Copy(&murderer_pos, &info.ped_info.murderer_actor->t.t.translate.t); |
||
4897 | } |
||
4898 | BrVector3Normalise(&vertical, (br_vector3*)mat.m[1]); |
||
4899 | BrVector3Scale(&vertical, &vertical, PedHeightFromActor(info.ped_info.ped_actor) / 2.f); |
||
4900 | BrVector3Accumulate((br_vector3*)mat.m[3], &vertical); |
||
4901 | if (next_incident_time > GetTotalTime() || !PipeSearchForwards()) { |
||
4902 | BrVector3Sub(&tv, (br_vector3*)mat.m[3], &murderer_pos); |
||
4903 | tv.v[1] = 0.f; |
||
4904 | BrVector3Normalise(&tv, &tv); |
||
4905 | BrVector3Set(&vertical, .0f, .4f, .0f); |
||
4906 | BrVector3Cross(&perp, &tv, &vertical); |
||
4907 | if (random) { |
||
4908 | BrVector3Negate(&perp, &perp); |
||
4909 | } |
||
4910 | if (PipeSearchForwards()) { |
||
4911 | BrVector3Accumulate(&perp, &tv); |
||
4912 | } |
||
4913 | BrVector3Add(&gCamera->t.t.translate.t, (br_vector3*)mat.m[3], &perp); |
||
4914 | CollideCamera2(&murderer_pos, &gCamera->t.t.translate.t, NULL, 1); |
||
4915 | } |
||
4916 | PointCamera((br_vector3*)mat.m[3], m2); |
||
4917 | BrVector3Sub(&tv, &gCamera->t.t.translate.t, &info.ped_info.murderer_actor->t.t.translate.t); |
||
4918 | ts = BrVector3LengthSquared(&tv); |
||
4919 | if (/*abs*/(GetTotalTime() - next_incident_time) > 2500) { // Pierre-Marie Baty -- useless call (already unsigned) |
||
4920 | type = eNo_incident; |
||
4921 | } |
||
4922 | if ((PipeSearchForwards() ? (next_incident_time < GetTotalTime()) : (next_incident_time > GetTotalTime())) |
||
4923 | && (ts > 25.f || CheckForWall(&info.ped_info.murderer_actor->t.t.translate.t, &gCamera->t.t.translate.t))) { |
||
4924 | type = eNo_incident; |
||
4925 | } |
||
4926 | if (removed) { |
||
4927 | PutNonCarBackInWorld(info.ped_info.murderer_actor); |
||
4928 | } |
||
4929 | if (Vector3DistanceSquared((br_vector3*)mat.m[3], &gCamera->t.t.translate.t) < .15f * .15f) { |
||
4930 | BrVector3Copy(&gCamera->t.t.translate.t, &old_cam_pos); |
||
4931 | gPed_actor = NULL; |
||
4932 | return 0; |
||
4933 | } |
||
4934 | } else if (type == eIncident_car) { |
||
4935 | BrVector3Sub(&tv, &info.car_info.car->pos, &c->pos); |
||
4936 | tv.v[1] = 0.f; |
||
4937 | BrVector3Normalise(&tv, &tv); |
||
4938 | BrVector3Scale(&tv, &tv, 2.f); |
||
4939 | BrVector3Add(&gCamera->t.t.translate.t, &info.car_info.car->pos, &tv); |
||
4940 | gCamera->t.t.translate.t.v[1] += 1.f; |
||
4941 | CollideCamera2(&info.car_info.car->pos, &gCamera->t.t.translate.t, NULL, 1); |
||
4942 | PointCamera(&info.car_info.car->pos, m2); |
||
4943 | BrVector3Sub(&tv, &gCamera->t.t.translate.t, &c->pos); |
||
4944 | ts = BrVector3LengthSquared(&tv); |
||
4945 | if (/*abs*/(GetTotalTime() - next_incident_time) > 2500) { // Pierre-Marie Baty -- useless call (already unsigned) |
||
4946 | type = eNo_incident; |
||
4947 | } |
||
4948 | if ((PipeSearchForwards() ? (next_incident_time < GetTotalTime()) : (next_incident_time > GetTotalTime())) |
||
4949 | && (ts > 25.f || CheckForWall(&c->pos, &gCamera->t.t.translate.t))) { |
||
4950 | type = eNo_incident; |
||
4951 | } |
||
4952 | } else if (type == eIncident_wall) { |
||
4953 | PointCamera(&c->pos, m2); |
||
4954 | BrVector3Sub(&tv, &gCamera->t.t.translate.t, &c->pos); |
||
4955 | ts = BrVector3LengthSquared(&tv); |
||
4956 | if (/*abs*/(GetTotalTime() - next_incident_time) > 2500) { // Pierre-Marie Baty -- useless call (already unsigned) |
||
4957 | type = eNo_incident; |
||
4958 | } |
||
4959 | if ((PipeSearchForwards() ? (next_incident_time < GetTotalTime()) : (next_incident_time > GetTotalTime())) |
||
4960 | && (ts > 25.f || CheckForWall(&c->pos, &gCamera->t.t.translate.t))) { |
||
4961 | type = eNo_incident; |
||
4962 | } |
||
4963 | } else { |
||
4964 | type = eNo_incident; |
||
4965 | } |
||
4966 | if (type == eNo_incident) { |
||
4967 | if (count > 1) { |
||
4968 | SetUpPanningCamera(c); |
||
4969 | return 0; |
||
4970 | } else { |
||
4971 | count++; |
||
4972 | if (IncidentCam(c, pTime)) { |
||
4973 | count--; |
||
4974 | return 1; |
||
4975 | } else { |
||
4976 | count--; |
||
4977 | return 0; |
||
4978 | } |
||
4979 | } |
||
4980 | } else { |
||
4981 | return 1; |
||
4982 | } |
||
4983 | } |
||
4984 | |||
4985 | // IDA: int __usercall MoveCamToIncident@<EAX>(tCar_spec *c@<EAX>, tIncident_type *type@<EDX>, float *severity@<EBX>, tIncident_info *info@<ECX>, tU32 *next_incident_time) |
||
4986 | int MoveCamToIncident(tCar_spec* c, tIncident_type* type, float* severity, tIncident_info* info, tU32* next_incident_time) { |
||
4987 | tU32 next_incident_time2; |
||
4988 | tU32 t; |
||
4989 | tIncident_type type2; |
||
4990 | float severity2; |
||
4991 | tIncident_info info2; |
||
4992 | br_vector3 pos; |
||
4993 | br_vector3 left; |
||
4994 | br_vector3 right; |
||
4995 | br_vector3 vertical; |
||
4996 | br_vector3 tv; |
||
4997 | //br_vector3 tv2; // Pierre-Marie Baty -- unused variable |
||
4998 | br_vector3 perp; |
||
4999 | int test; |
||
5000 | LOG_TRACE("(%p, %p, %p, %p, %p)", c, type, severity, info, next_incident_time); |
||
5001 | |||
5002 | test = 0; |
||
5003 | if (!GetNextIncident(-1, type, severity, info, next_incident_time)) { |
||
5004 | *type = eNo_incident; |
||
5005 | } else { |
||
5006 | if (/*abs*/(*next_incident_time) > 2500) { // Pierre-Marie Baty -- useless call (already unsigned) |
||
5007 | *type = eNo_incident; |
||
5008 | } else { |
||
5009 | t = *next_incident_time; |
||
5010 | 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) |
||
5011 | if ((*type != type2 && type2 < *type) || (*type == type2 && *severity <= severity2)) { |
||
5012 | *info = info2; |
||
5013 | *severity = severity2; |
||
5014 | *type = type2; |
||
5015 | *next_incident_time = next_incident_time2; |
||
5016 | } |
||
5017 | t = next_incident_time2; |
||
5018 | } |
||
5019 | if (/*abs*/(*next_incident_time) > 2500) { // Pierre-Marie Baty -- useless call (already unsigned) |
||
5020 | *type = eNo_incident; |
||
5021 | } else { |
||
5022 | if (*type == eIncident_wall) { |
||
5023 | if (*severity < 0.1f) { |
||
5024 | *type = eNo_incident; |
||
5025 | return 0; |
||
5026 | } |
||
5027 | ScanCarsPositions(c, &c->pos, 100000.f, -1, /*abs*/(*next_incident_time), &pos, &t); // Pierre-Marie Baty -- useless call (already unsigned) |
||
5028 | if (t == 0) { |
||
5029 | *type = eNo_incident; |
||
5030 | } else { |
||
5031 | BrVector3Sub(&tv, &pos, &c->pos); |
||
5032 | if (BrVector3LengthSquared(&tv) > 102.91955471539592f) { |
||
5033 | *type = eNo_incident; |
||
5034 | } else { |
||
5035 | BrVector3Sub(&tv, &pos, &info->wall_info.pos); |
||
5036 | BrVector3Normalise(&tv, &tv); |
||
5037 | BrVector3Scale(&tv, &tv, 2.f); |
||
5038 | BrVector3Set(&vertical, 0.f, 1.f, 0.f); |
||
5039 | BrVector3Cross(&perp, &vertical, &tv); |
||
5040 | BrVector3Add(&left, &pos, &tv); |
||
5041 | BrVector3Add(&left, &left, &perp); |
||
5042 | left.v[1] += 2.f; |
||
5043 | BrVector3Add(&right, &pos, &tv); |
||
5044 | BrVector3Sub(&right, &right, &perp); |
||
5045 | right.v[1] += 2.f; |
||
5046 | CollideCamera2(&pos, &left, NULL, 1); |
||
5047 | CollideCamera2(&pos, &right, NULL, 1); |
||
5048 | if (Vector3DistanceSquared(&left, &pos) <= Vector3DistanceSquared(&right, &pos)) { |
||
5049 | BrVector3Copy(&tv, &right); |
||
5050 | } else { |
||
5051 | BrVector3Copy(&tv, &left); |
||
5052 | } |
||
5053 | BrVector3Copy(&gCamera->t.t.translate.t, &tv); |
||
5054 | } |
||
5055 | } |
||
5056 | } |
||
5057 | *next_incident_time += GetTotalTime(); |
||
5058 | } |
||
5059 | } |
||
5060 | } |
||
5061 | return 0; |
||
5062 | } |
||
5063 | |||
5064 | // IDA: void __usercall PanningExternalCamera(tCar_spec *c@<EAX>, tU32 pTime@<EDX>) |
||
5065 | void PanningExternalCamera(tCar_spec* c, tU32 pTime) { |
||
5066 | br_matrix34* m2; |
||
5067 | br_matrix34* m1; |
||
5068 | br_vector3 tv; |
||
5069 | br_scalar ts; |
||
5070 | static int inside_camera_zone = 1; |
||
5071 | LOG_TRACE("(%p, %d)", c, pTime); |
||
5072 | |||
5073 | BrVector3Sub(&tv, &gCamera->t.t.translate.t, &c->pos); |
||
5074 | ts = BrVector3LengthSquared(&tv); |
||
5075 | if (ts > 102.91955471539592f || (gSwitch_time != 0 && (PipeSearchForwards() ? (gSwitch_time <= GetTotalTime()) : (gSwitch_time >= GetTotalTime())))) { |
||
5076 | if ((inside_camera_zone || ts > 205.83910943079184f) && (ts > 25.f || CheckForWall(&c->pos, &gCamera->t.t.translate.t))) { |
||
5077 | SetUpPanningCamera(c); |
||
5078 | inside_camera_zone = 0; |
||
5079 | } |
||
5080 | } else { |
||
5081 | inside_camera_zone = 1; |
||
5082 | } |
||
5083 | m1 = &c->car_master_actor->t.t.mat; |
||
5084 | m2 = &gCamera->t.t.mat; |
||
5085 | PointCameraAtCar(c, m1, m2); |
||
5086 | } |
||
5087 | |||
5088 | // IDA: int __usercall CheckForWall@<EAX>(br_vector3 *start@<EAX>, br_vector3 *end@<EDX>) |
||
5089 | int CheckForWall(br_vector3* start, br_vector3* end) { |
||
5090 | br_vector3 dir; |
||
5091 | br_material* material; |
||
5092 | br_vector3 normal; |
||
5093 | br_scalar d; |
||
5094 | LOG_TRACE("(%p, %p)", start, end); |
||
5095 | |||
5096 | BrVector3Sub(&dir, end, start); |
||
5097 | FindFace(start, &dir, &normal, &d, &material); |
||
5098 | return d <= 1.f; |
||
5099 | } |
||
5100 | |||
5101 | // IDA: void __usercall SetUpPanningCamera(tCar_spec *c@<EAX>) |
||
5102 | void SetUpPanningCamera(tCar_spec* c) { |
||
5103 | br_vector3 pos; |
||
5104 | br_vector3 perp; |
||
5105 | br_vector3 dir; |
||
5106 | br_vector3 tv; |
||
5107 | br_vector3 tv2; |
||
5108 | br_scalar ts; |
||
5109 | tU32 time; |
||
5110 | tU32 t; |
||
5111 | tU32 t2; |
||
5112 | tU32 time_step; |
||
5113 | //br_matrix34* m2; // Pierre-Marie Baty -- unused variable |
||
5114 | //br_matrix34* m1; // Pierre-Marie Baty -- unused variable |
||
5115 | br_vector3 left; |
||
5116 | br_vector3 right; |
||
5117 | br_vector3 car_centre; |
||
5118 | //int left_score; // Pierre-Marie Baty -- unused variable |
||
5119 | //int right_score; // Pierre-Marie Baty -- unused variable |
||
5120 | LOG_TRACE("(%p)", c); |
||
5121 | |||
5122 | ScanCarsPositions(c, &c->pos, 411.6782f, -1, 5000, &car_centre, &t); |
||
5123 | BrVector3Sub(&dir, &car_centre, &c->pos); |
||
5124 | time_step = ((t > GetTotalTime()) ? t - GetTotalTime() : GetTotalTime() - t) * SRandomBetween(0.8f, 1.5f); |
||
5125 | if (BrVector3LengthSquared(&dir) >= .01f && t != 0) { |
||
5126 | ScanCarsPositions(c, &c->pos, 102.9196f, -1, time_step / 2, &pos, &t2); |
||
5127 | if (t2 == 0) { |
||
5128 | BrVector3Copy(&pos, &c->pos); |
||
5129 | } |
||
5130 | } else { |
||
5131 | BrVector3Negate(&dir, (br_vector3*)&c->car_master_actor->t.t.mat.m[2]); |
||
5132 | BrVector3Copy(&pos, &c->pos); |
||
5133 | time_step = 0; |
||
5134 | } |
||
5135 | BrVector3SetFloat(&tv, 0.f, 1.f, 0.f); |
||
5136 | BrVector3Cross(&perp, &tv, &dir); |
||
5137 | ts = BrVector3Length(&perp); |
||
5138 | if (ts >= .1f) { |
||
5139 | BrVector3Scale(&perp, &perp, 2.f / ts * SRandomBetween(0.3333333f, 1.f)); |
||
5140 | BrVector3Set(&tv2, 0.f, 2 * SRandomBetween(0.3333333f, 1.f), 0.f); |
||
5141 | BrVector3Add(&tv, &pos, &tv2); |
||
5142 | BrVector3Add(&left, &tv, &perp); |
||
5143 | BrVector3Sub(&right, &tv, &perp); |
||
5144 | CollideCamera2(&pos, &left, NULL, 1); |
||
5145 | CollideCamera2(&pos, &right, NULL, 1); |
||
5146 | BrVector3Sub(&tv, &left, &pos); |
||
5147 | BrVector3Sub(&tv2, &right, &pos); |
||
5148 | if (BrVector3LengthSquared(&tv) + SRandomPosNeg(.01f) <= BrVector3LengthSquared(&tv2)) { |
||
5149 | BrVector3Copy(&gCamera->t.t.translate.t, &right); |
||
5150 | } else { |
||
5151 | BrVector3Copy(&gCamera->t.t.translate.t, &left); |
||
5152 | } |
||
5153 | if (t != 0 && CheckForWall(&c->pos, &gCamera->t.t.translate.t)) { |
||
5154 | ScanCarsPositions(c, &c->pos, 10000.f, -1, 1000, &tv, &time); |
||
5155 | CollideCamera2(&tv, &gCamera->t.t.translate.t, NULL, 1); |
||
5156 | } |
||
5157 | if (t != 0 && CheckForWall(&car_centre, &gCamera->t.t.translate.t)) { |
||
5158 | time_step = time_step / 16; |
||
5159 | BrVector3Copy(&tv, &pos); |
||
5160 | while (1) { |
||
5161 | ScanCarsPositions(c, &tv, 10000.f, /*abs*/(t2 - GetTotalTime()), time_step, &tv2, &time); // Pierre-Marie Baty -- useless call (already unsigned) |
||
5162 | t2 += (GetReplayDirection() ? 1 : -1) * time_step; |
||
5163 | BrVector3Copy(&tv, &tv2); |
||
5164 | if (CheckForWall(&tv, &gCamera->t.t.translate.t)) { |
||
5165 | break; |
||
5166 | } |
||
5167 | if (t2 >= GetTotalTime() + 5000) { |
||
5168 | break; |
||
5169 | } |
||
5170 | } |
||
5171 | gSwitch_time = t2; |
||
5172 | } else { |
||
5173 | if (t == 0) { |
||
5174 | t = 5000; |
||
5175 | } |
||
5176 | gSwitch_time = t; |
||
5177 | } |
||
5178 | } |
||
5179 | } |
||
5180 | |||
5181 | // IDA: void __usercall SaveCameraPosition(int i@<EAX>) |
||
5182 | void SaveCameraPosition(int i) { |
||
5183 | LOG_TRACE("(%d)", i); |
||
5184 | |||
5185 | if (gSave_camera[i].saved != 1) { |
||
5186 | gSave_camera[i].zoom = gCamera_zoom; |
||
5187 | gSave_camera[i].yaw = gCamera_yaw; |
||
5188 | gSave_camera[i].saved = 1; |
||
5189 | } |
||
5190 | } |
||
5191 | |||
5192 | // IDA: void __usercall RestoreCameraPosition(int i@<EAX>) |
||
5193 | void RestoreCameraPosition(int i) { |
||
5194 | LOG_TRACE("(%d)", i); |
||
5195 | |||
5196 | if (gSave_camera[i].saved != 0) { |
||
5197 | gCamera_zoom = gSave_camera[i].zoom; |
||
5198 | gCamera_yaw = gSave_camera[i].yaw; |
||
5199 | gSave_camera[i].saved = 0; |
||
5200 | } |
||
5201 | } |
||
5202 | |||
5203 | // IDA: void __usercall NormalPositionExternalCamera(tCar_spec *c@<EAX>, tU32 pTime@<EDX>) |
||
5204 | void NormalPositionExternalCamera(tCar_spec* c, tU32 pTime) { |
||
5205 | br_matrix34* m2; |
||
5206 | br_matrix34* m1; |
||
5207 | br_scalar time; |
||
5208 | //br_scalar ts; // Pierre-Marie Baty -- unused variable |
||
5209 | //br_scalar ts2; // Pierre-Marie Baty -- unused variable |
||
5210 | br_scalar dist; |
||
5211 | br_scalar height_inc; |
||
5212 | br_scalar l; |
||
5213 | //br_scalar frac; // Pierre-Marie Baty -- unused variable |
||
5214 | br_vector3 vn; |
||
5215 | br_vector3 a; |
||
5216 | //br_vector3 b; // Pierre-Marie Baty -- unused variable |
||
5217 | //br_vector3 tv; // Pierre-Marie Baty -- unused variable |
||
5218 | //br_angle yaw; // Pierre-Marie Baty -- unused variable |
||
5219 | //br_angle theta; // Pierre-Marie Baty -- unused variable |
||
5220 | br_scalar d; |
||
5221 | //int face; // Pierre-Marie Baty -- unused variable |
||
5222 | //int i; // Pierre-Marie Baty -- unused variable |
||
5223 | int swoop; |
||
5224 | int manual_swing; |
||
5225 | int manual_zoom; |
||
5226 | br_vector3 old_camera_pos; |
||
5227 | //br_scalar scale; // Pierre-Marie Baty -- unused variable |
||
5228 | LOG_TRACE("(%p, %d)", c, pTime); |
||
5229 | |||
5230 | m1 = &gCamera->t.t.mat; |
||
5231 | m2 = &c->car_master_actor->t.t.mat; |
||
5232 | swoop = gCountdown && c->pos.v[1] + 0.001f < gCamera_height; |
||
5233 | manual_swing = gOld_yaw__car != gCamera_yaw || swoop; |
||
5234 | manual_zoom = (double)gOld_zoom != gCamera_zoom; |
||
5235 | BrVector3Copy(&old_camera_pos, &gCamera->t.t.translate.t); |
||
5236 | if (!gProgram_state.cockpit_on) { |
||
5237 | if (swoop) { |
||
5238 | gCamera_yaw = 0; |
||
5239 | manual_swing = 1; |
||
5240 | } |
||
5241 | if (fabsf(c->speedo_speed) > 0.0006f && gCamera_mode > 0) { |
||
5242 | gCamera_mode = -1; |
||
5243 | gCamera_sign = BrVector3Dot((br_vector3*)m2->m[2], &c->direction) > 0.0f; |
||
5244 | } |
||
5245 | if (c->frame_collision_flag && gCamera_mode != -2) { |
||
5246 | gCamera_mode = 1; |
||
5247 | } |
||
5248 | if (gCar_flying || gCamera_reset || gCamera_mode == -2) { |
||
5249 | gCamera_mode = 0; |
||
5250 | } |
||
5251 | d = sqrtf(gCamera_zoom) + 4.f / WORLD_SCALE; |
||
5252 | if (!gCamera_mode || gCamera_mode == -1) { |
||
5253 | BrVector3Copy(&vn, &c->direction); |
||
5254 | MoveWithWheels(c, &vn, manual_swing); |
||
5255 | vn.v[1] = 0.0f; |
||
5256 | BrVector3Normalise(&vn, &vn); |
||
5257 | if (gCar_flying) { |
||
5258 | gCamera_sign = 0; |
||
5259 | } |
||
5260 | SwingCamera(c, m2, m1, &vn, pTime); |
||
5261 | BrVector3Scale(&a, &vn, d); |
||
5262 | BrVector3Sub(&gCamera->t.t.translate.t, &c->pos, &a); |
||
5263 | BrVector3Copy(&gView_direction, &vn); |
||
5264 | } |
||
5265 | if (gCamera_mode == 1) { |
||
5266 | if (manual_swing || manual_zoom) { |
||
5267 | BrVector3Copy(&old_camera_pos, &gCamera_pos_before_collide); |
||
5268 | } |
||
5269 | BrVector3Sub(&a, &c->pos, &old_camera_pos); |
||
5270 | a.v[1] = 0.0f; |
||
5271 | if (manual_swing) { |
||
5272 | DrVector3RotateY(&a, (gCamera_sign == 0 ? 1 : -1) * (gCamera_yaw - gOld_yaw__car)); |
||
5273 | gCamera_yaw = gOld_yaw__car; |
||
5274 | } |
||
5275 | BrVector3Normalise(&vn, &a); |
||
5276 | BrVector3Copy(&gView_direction, &vn); |
||
5277 | BrVector3Scale(&vn, &vn, -d); |
||
5278 | BrVector3Accumulate(&a, &vn); |
||
5279 | dist = BrVector3Length(&a); |
||
5280 | l = (float)pTime / 1000.0f * (dist + 1.0f) / dist; |
||
5281 | if (l < 1.0f && BrVector3Dot(&a, &vn) > 0.0f) { |
||
5282 | BrVector3Scale(&a, &a, (l - 1.f)); |
||
5283 | BrVector3Accumulate(&vn, &a); |
||
5284 | } |
||
5285 | BrVector3Add(&gCamera->t.t.translate.t, &c->pos, &vn); |
||
5286 | } |
||
5287 | height_inc = gCamera_zoom * gCamera_zoom + 0.3f; |
||
5288 | time = pTime * 0.001f; |
||
5289 | if (!gCamera_frozen || gAction_replay_mode) { |
||
5290 | if (pTime >= 5000) { |
||
5291 | gCamera_height = c->pos.v[1]; |
||
5292 | } else if (swoop) { |
||
5293 | if (time > 0.2f) { |
||
5294 | time = 0.2f; |
||
5295 | } |
||
5296 | gCamera_height -= time * 5.0f; |
||
5297 | if (gCamera_height < c->pos.v[1]) { |
||
5298 | gCamera_height = c->pos.v[1]; |
||
5299 | } |
||
5300 | } else { |
||
5301 | gCamera_height = time * 5.0f * c->pos.v[1] + gCamera_height; |
||
5302 | gCamera_height = gCamera_height / (time * 5.0f + 1.0f); |
||
5303 | } |
||
5304 | } |
||
5305 | l = c->direction.v[1] * d; |
||
5306 | if (l > 0) { |
||
5307 | if (c->pos.v[1] - l - height_inc / 2.0f > gCamera_height) { |
||
5308 | gCamera_height = c->pos.v[1] - l - height_inc / 2.0f; |
||
5309 | } |
||
5310 | } |
||
5311 | |||
5312 | gCamera->t.t.translate.t.v[1] = height_inc + gCamera_height; |
||
5313 | BrVector3Copy(&gCamera_pos_before_collide, &gCamera->t.t.translate.t); |
||
5314 | CollideCameraWithOtherCars(&c->pos, &gCamera->t.t.translate.t); |
||
5315 | CollideCamera2(&c->pos, &gCamera->t.t.translate.t, &old_camera_pos, manual_swing || manual_zoom); |
||
5316 | if (gCamera_has_collided && swoop) { |
||
5317 | gCamera_height = c->pos.v[1]; |
||
5318 | } |
||
5319 | PointCameraAtCar(c, m2, m1); |
||
5320 | } |
||
5321 | gOld_yaw__car = gCamera_yaw; |
||
5322 | gOld_zoom = (br_angle)gCamera_zoom; |
||
5323 | } |
||
5324 | |||
5325 | // IDA: void __usercall MoveWithWheels(tCar_spec *c@<EAX>, br_vector3 *vn@<EDX>, int manual_swing@<EBX>) |
||
5326 | void MoveWithWheels(tCar_spec* c, br_vector3* vn, int manual_swing) { |
||
5327 | br_angle yaw; |
||
5328 | br_angle theta; |
||
5329 | static int move_with_wheels; |
||
5330 | LOG_TRACE("(%p, %p, %d)", c, vn, manual_swing); |
||
5331 | |||
5332 | if (c->speed < 0.0001f && !gCamera_mode) { |
||
5333 | if (manual_swing) { |
||
5334 | if (gCamera_yaw <= 32760u) { |
||
5335 | yaw = gCamera_yaw; |
||
5336 | } else { |
||
5337 | yaw = gCamera_yaw - 32760; |
||
5338 | } |
||
5339 | if (yaw <= BrDegreeToAngle(45) || yaw >= BrDegreeToAngle(135)) { |
||
5340 | if (!move_with_wheels) { |
||
5341 | theta = BrRadianToAngle(atan2f(c->wpos[0].v[2] * c->curvature, 1.0f)); |
||
5342 | gCamera_yaw -= (-2 * gCamera_sign + 1) * theta; |
||
5343 | move_with_wheels = 1; |
||
5344 | } |
||
5345 | } else if (move_with_wheels) { |
||
5346 | theta = BrRadianToAngle(atan2(c->wpos[0].v[2] * c->curvature, 1.0)); |
||
5347 | gCamera_yaw += (-2 * gCamera_sign + 1) * theta; |
||
5348 | move_with_wheels = 0; |
||
5349 | } |
||
5350 | } |
||
5351 | if (move_with_wheels) { |
||
5352 | if (!gCar_flying) { |
||
5353 | theta = BrRadianToAngle(atan2(c->wpos[0].v[2] * c->curvature, 1.0)); |
||
5354 | DrVector3RotateY(vn, theta); |
||
5355 | } |
||
5356 | } |
||
5357 | } |
||
5358 | } |
||
5359 | |||
5360 | // IDA: void __usercall SwingCamera(tCar_spec *c@<EAX>, br_matrix34 *m1@<EDX>, br_matrix34 *m2@<EBX>, br_vector3 *vn@<ECX>, tU32 pTime) |
||
5361 | void SwingCamera(tCar_spec* c, br_matrix34* m1, br_matrix34* m2, br_vector3* vn, tU32 pTime) { |
||
5362 | //int i; // Pierre-Marie Baty -- unused variable |
||
5363 | br_scalar ts; |
||
5364 | br_angle yaw; |
||
5365 | br_angle theta; |
||
5366 | //br_angle alpha; // Pierre-Marie Baty -- unused variable |
||
5367 | br_scalar sin_dtheta; |
||
5368 | br_scalar cos_dtheta; |
||
5369 | br_scalar sign; |
||
5370 | int manual_swing; |
||
5371 | static br_angle omega = 0; |
||
5372 | static int elapsed_time = -1; |
||
5373 | static br_vector3 old_vn; |
||
5374 | LOG_TRACE("(%p, %p, %p, %p, %d)", c, m1, m2, vn, pTime); |
||
5375 | |||
5376 | manual_swing = gOld_yaw__car != gCamera_yaw; |
||
5377 | if (elapsed_time > 500) { |
||
5378 | elapsed_time = -1; |
||
5379 | } |
||
5380 | if (elapsed_time >= 0) { |
||
5381 | elapsed_time += pTime; |
||
5382 | } |
||
5383 | sign = -BrVector3Dot((br_vector3*)m1->m[2], vn); |
||
5384 | ts = BrVector3Dot(vn, &old_vn); |
||
5385 | |||
5386 | BrVector3Copy(&old_vn, vn); |
||
5387 | if ((sign < 0.0f) == gCamera_sign) { |
||
5388 | elapsed_time = -1; |
||
5389 | } else if (ts <= 0.0 || elapsed_time >= 0) { |
||
5390 | if (elapsed_time < 0) { |
||
5391 | elapsed_time = 0; |
||
5392 | } |
||
5393 | if (elapsed_time < 500 && sign <= 0.0f) { |
||
5394 | BrVector3Negate(vn, vn); |
||
5395 | } else { |
||
5396 | elapsed_time = 500; |
||
5397 | if (sign <= 0.0) { |
||
5398 | ts = 0.0006f; |
||
5399 | } else { |
||
5400 | ts = 0.0001f; |
||
5401 | } |
||
5402 | if (fabsf(c->speedo_speed) <= ts || gCar_flying) { |
||
5403 | BrVector3Negate(vn, vn); |
||
5404 | } else { |
||
5405 | gCamera_sign = gCamera_sign == 0; |
||
5406 | omega = BrDegreeToAngle(pTime * 0.03f); |
||
5407 | if (gCamera_yaw <= 32760) { |
||
5408 | yaw = gCamera_yaw; |
||
5409 | } else { |
||
5410 | yaw = gCamera_yaw - 32760; |
||
5411 | } |
||
5412 | if ((uint16_t)(gCamera_yaw + 16380) <= 32760) { |
||
5413 | if (yaw > 8190 && yaw < 24570) { |
||
5414 | gCamera_yaw = 32760 - gCamera_yaw; |
||
5415 | } |
||
5416 | } else { |
||
5417 | gCamera_yaw = 32760 - gCamera_yaw; |
||
5418 | } |
||
5419 | } |
||
5420 | } |
||
5421 | } else { |
||
5422 | gCamera_sign = gCamera_sign == 0; |
||
5423 | if (gCamera_yaw <= 32760) { |
||
5424 | yaw = gCamera_yaw; |
||
5425 | } else { |
||
5426 | yaw = gCamera_yaw - 32760; |
||
5427 | } |
||
5428 | if (yaw > 8190 && yaw < 24570) { |
||
5429 | gCamera_yaw = -gCamera_yaw; |
||
5430 | } |
||
5431 | } |
||
5432 | if (gCamera_sign) { |
||
5433 | yaw = -gCamera_yaw; |
||
5434 | } else { |
||
5435 | yaw = gCamera_yaw; |
||
5436 | } |
||
5437 | if (!gCar_flying) { |
||
5438 | DrVector3RotateY(vn, yaw); |
||
5439 | } |
||
5440 | sin_dtheta = 0.0; |
||
5441 | br_scalar v16 = vn->v[0] * gView_direction.v[2] - vn->v[2] * gView_direction.v[0]; |
||
5442 | br_scalar v17 = vn->v[0] * gView_direction.v[0] + vn->v[2] * gView_direction.v[2]; |
||
5443 | |||
5444 | 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); |
||
5445 | sin_dtheta = sin(BrAngleToRadian(v8)) + 0.1; |
||
5446 | |||
5447 | if (omega || gCamera_reset || (c->speed < 0.0001f && !manual_swing) || gCamera_mode == -1 || (v17 > 0.0 && !manual_swing && fabs(v16) > sin_dtheta)) { |
||
5448 | if (!gCar_flying) { |
||
5449 | theta = BrRadianToAngle(asin(sin_dtheta)); |
||
5450 | if (omega < theta) { |
||
5451 | omega = theta; |
||
5452 | } |
||
5453 | if (!omega) { |
||
5454 | omega = BrDegreeToAngle(pTime * 0.03); // (__int64)((double)(int)pTime * 0.03 * 182.0444444444445); |
||
5455 | } |
||
5456 | cos_dtheta = cos(BrAngleToRadian(omega)); |
||
5457 | if (cos_dtheta <= v17) { |
||
5458 | omega = 0; |
||
5459 | gCamera_mode = 0; |
||
5460 | } else { |
||
5461 | ts = BrAngleToRadian(omega); |
||
5462 | if (v16 <= 0.0) { |
||
5463 | vn->v[0] = cosf(ts) * gView_direction.v[0] - sinf(ts) * gView_direction.v[2]; |
||
5464 | vn->v[2] = sinf(ts) * gView_direction.v[0] + cosf(ts) * gView_direction.v[2]; |
||
5465 | } else { |
||
5466 | vn->v[0] = sinf(ts) * gView_direction.v[2] + cosf(ts) * gView_direction.v[0]; |
||
5467 | vn->v[2] = cosf(ts) * gView_direction.v[2] - sinf(ts) * gView_direction.v[0]; |
||
5468 | } |
||
5469 | omega += BrDegreeToAngle(pTime * 0.03f); |
||
5470 | if (BrDegreeToAngle(pTime * 0.1f) < omega) { |
||
5471 | omega = BrDegreeToAngle(pTime * 0.1f); |
||
5472 | } |
||
5473 | if (omega < theta) { |
||
5474 | omega = theta; |
||
5475 | } |
||
5476 | } |
||
5477 | } |
||
5478 | } |
||
5479 | } |
||
5480 | |||
5481 | // IDA: void __usercall PointCameraAtCar(tCar_spec *c@<EAX>, br_matrix34 *m1@<EDX>, br_matrix34 *m2@<EBX>) |
||
5482 | void PointCameraAtCar(tCar_spec* c, br_matrix34* m1, br_matrix34* m2) { |
||
5483 | br_vector3 vn; |
||
5484 | br_vector3 tv; |
||
5485 | br_vector3 tv2; |
||
5486 | br_scalar dist; |
||
5487 | br_scalar frac; |
||
5488 | br_angle theta; |
||
5489 | br_vector3* pos; |
||
5490 | br_camera* camera_ptr; |
||
5491 | //br_angle off_centre_angle; // Pierre-Marie Baty -- unused variable |
||
5492 | int swoop; |
||
5493 | //br_scalar scale; // Pierre-Marie Baty -- unused variable |
||
5494 | LOG_TRACE("(%p, %p, %p)", c, m1, m2); |
||
5495 | |||
5496 | camera_ptr = gCamera->type_data; |
||
5497 | theta = camera_ptr->field_of_view / 5; |
||
5498 | swoop = gCountdown && c->pos.v[1] + 0.01f < gCamera_height; |
||
5499 | if (0) { |
||
5500 | BrVector3Sub(&tv, &gAverage_grid_position, &c->pos); |
||
5501 | frac = (gCamera_height - c->pos.v[1]) / 10.0f; |
||
5502 | BrVector3Scale(&tv, &tv, frac); |
||
5503 | BrVector3Accumulate(&tv, &c->pos); |
||
5504 | pos = &tv; |
||
5505 | theta = (1.0f - frac) * (float)theta; |
||
5506 | } else { |
||
5507 | pos = &c->pos; |
||
5508 | } |
||
5509 | BrVector3Set(&vn, c->pos.v[0] - m2->m[3][0], 0.f, c->pos.v[2] - m2->m[3][2]); |
||
5510 | BrVector3Normalise(&vn, &vn); |
||
5511 | m2->m[0][0] = -vn.v[2]; |
||
5512 | m2->m[0][1] = 0.0f; |
||
5513 | m2->m[0][2] = vn.v[0]; |
||
5514 | m2->m[1][0] = 0.0f; |
||
5515 | m2->m[1][1] = 1.0f; |
||
5516 | m2->m[1][2] = 0.0f; |
||
5517 | m2->m[2][0] = -vn.v[0]; |
||
5518 | m2->m[2][1] = 0.0f; |
||
5519 | m2->m[2][2] = -vn.v[2]; |
||
5520 | BrVector3Sub(&tv2, pos, (br_vector3*)m2->m[3]); |
||
5521 | dist = BrVector3Dot(&tv2, &vn); |
||
5522 | BrMatrix34PreRotateX(m2, theta - BrRadianToAngle(atan2f(m2->m[3][1] - pos->v[1], dist))); |
||
5523 | } |
||
5524 | |||
5525 | // IDA: void __usercall PointCamera(br_vector3 *pos@<EAX>, br_matrix34 *m2@<EDX>) |
||
5526 | void PointCamera(br_vector3* pos, br_matrix34* m2) { |
||
5527 | br_vector3 vn; |
||
5528 | br_scalar dist; |
||
5529 | br_angle theta; |
||
5530 | br_camera* camera_ptr; |
||
5531 | LOG_TRACE("(%p, %p)", pos, m2); |
||
5532 | |||
5533 | camera_ptr = gCamera->type_data; |
||
5534 | BrVector3Sub(&vn, pos, (br_vector3*)m2->m[3]); |
||
5535 | vn.v[1] = 0.f; |
||
5536 | BrVector3Normalise(&vn, &vn); |
||
5537 | m2->m[0][0] = -vn.v[2]; |
||
5538 | m2->m[0][1] = 0.f; |
||
5539 | m2->m[0][2] = vn.v[0]; |
||
5540 | m2->m[1][0] = 0.f; |
||
5541 | m2->m[1][1] = 1.f; |
||
5542 | m2->m[1][2] = 0.f; |
||
5543 | m2->m[2][0] = -vn.v[0]; |
||
5544 | m2->m[2][1] = 0.f; |
||
5545 | m2->m[2][2] = -vn.v[2]; |
||
5546 | dist = BrVector3LengthSquared(&vn); |
||
5547 | theta = BR_ATAN2(m2->m[3][1] - pos->v[1], dist); |
||
5548 | BrMatrix34PreRotateX(m2, camera_ptr->field_of_view / 5 - theta); |
||
5549 | } |
||
5550 | |||
5551 | // 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>) |
||
5552 | int CollideCamera2(br_vector3* car_pos, br_vector3* cam_pos, br_vector3* old_camera_pos, int manual_move) { |
||
5553 | int i; |
||
5554 | int k; |
||
5555 | br_vector3 a; |
||
5556 | br_vector3 b; |
||
5557 | //br_vector3 vn; // Pierre-Marie Baty -- unused variable |
||
5558 | br_vector3 tv; |
||
5559 | br_vector3 tv2; |
||
5560 | br_scalar l; |
||
5561 | br_scalar d; |
||
5562 | br_scalar ts; |
||
5563 | br_scalar ts2; |
||
5564 | br_scalar dist; |
||
5565 | br_scalar hither; |
||
5566 | //br_angle theta; // Pierre-Marie Baty -- unused variable |
||
5567 | tBounds bnds; |
||
5568 | br_matrix34 mat; |
||
5569 | br_material* material; |
||
5570 | br_scalar alpha; |
||
5571 | br_scalar sa; |
||
5572 | br_scalar sb; |
||
5573 | br_scalar sc; |
||
5574 | tFace_ref face_list[3]; |
||
5575 | LOG_TRACE("(%p, %p, %p, %d)", car_pos, cam_pos, old_camera_pos, manual_move); |
||
5576 | |||
5577 | #ifdef DETHRACE_FIX_BUGS |
||
5578 | ts2 = 0.f; |
||
5579 | #endif |
||
5580 | hither = ((br_camera*)gCamera->type_data)->hither_z * 3.0f; |
||
5581 | gCamera_has_collided = 0; |
||
5582 | for (i = 0; i < 1; i++) { |
||
5583 | BrVector3Sub(&tv, cam_pos, car_pos); |
||
5584 | dist = BrVector3Length(&tv); |
||
5585 | BrVector3Scale(&tv, &tv, 1.2f); |
||
5586 | FindFace(car_pos, &tv, &a, &ts, &material); |
||
5587 | if (ts <= 1.0) { |
||
5588 | gCamera_has_collided = 1; |
||
5589 | if (BrVector3Dot(&a, &tv) > 0.0f) { |
||
5590 | BrVector3Negate(&a, &a); |
||
5591 | } |
||
5592 | if (gCamera_mode == 1 && !manual_move) { |
||
5593 | BrVector3Sub(&tv2, car_pos, old_camera_pos); |
||
5594 | FindFace(old_camera_pos, &tv2, &b, &ts2, &material); |
||
5595 | if (ts2 > 1.0f) { |
||
5596 | BrVector3Copy(cam_pos, old_camera_pos); |
||
5597 | return i; |
||
5598 | } |
||
5599 | } |
||
5600 | BrVector3Scale(&tv, &tv, ts); |
||
5601 | BrVector3Scale(&tv2, &a, hither); |
||
5602 | BrVector3Accumulate(&tv, &tv2); |
||
5603 | dist = BrVector3Length(&tv); |
||
5604 | BrVector3Add(cam_pos, car_pos, &tv); |
||
5605 | if (gMin_camera_car_distance > dist && i == 0 && a.v[1] > -0.7) { |
||
5606 | BrVector3Scale(&tv2, &a, -a.v[1]); |
||
5607 | tv2.v[1] += 1.f; |
||
5608 | if (gProgram_state.current_car.car_master_actor->t.t.mat.m[1][1] < 0.f) { |
||
5609 | BrVector3Negate(&tv2, &tv2); |
||
5610 | } |
||
5611 | d = BrVector3LengthSquared(&tv2); |
||
5612 | l = BrVector3Dot(&tv2, &tv); |
||
5613 | alpha = BrVector3LengthSquared(&tv) - gMin_camera_car_distance * gMin_camera_car_distance; |
||
5614 | ts2 = l * l - alpha * d * 4.0; |
||
5615 | if (ts2 >= 0.f && d != 0.f) { |
||
5616 | sa = (sqrtf(ts2) - l) / (d * 2.0f); |
||
5617 | BrVector3Scale(&tv2, &tv2, sa); |
||
5618 | FindFace(cam_pos, &tv2, &a, &ts, &material); |
||
5619 | if (ts < 1.0f) { |
||
5620 | BrVector3Scale(&tv2, &tv2, ts); |
||
5621 | } |
||
5622 | BrVector3Set(&b, tv.v[0], 0.f, tv.v[2]); |
||
5623 | BrVector3Normalise(&b, &b); |
||
5624 | BrVector3Accumulate(&tv, &tv2); |
||
5625 | ts2 = BrVector3Dot(&tv, &b); |
||
5626 | if (ts2 < 0.03f && !gAction_replay_mode) { |
||
5627 | BrVector3Normalise(&tv2, &tv2); |
||
5628 | alpha = BrVector3Dot(&tv2, &b); |
||
5629 | if (alpha < -0.03f) { |
||
5630 | alpha = (0.03f - ts2) / alpha; |
||
5631 | BrVector3Scale(&tv2, &tv2, alpha); |
||
5632 | BrVector3Add(&tv, &tv2, &tv); |
||
5633 | } |
||
5634 | } |
||
5635 | } |
||
5636 | BrVector3Add(cam_pos, car_pos, &tv); |
||
5637 | } |
||
5638 | } |
||
5639 | |||
5640 | bnds.mat = &mat; |
||
5641 | BrMatrix34Identity(&mat); |
||
5642 | BrVector3Set(&tv2, hither, hither, hither); |
||
5643 | bnds.original_bounds.min.v[0] = cam_pos->v[0] - hither; |
||
5644 | bnds.original_bounds.min.v[1] = cam_pos->v[1] - hither; |
||
5645 | bnds.original_bounds.min.v[2] = cam_pos->v[2] - hither; |
||
5646 | bnds.original_bounds.max.v[0] = cam_pos->v[0] + hither; |
||
5647 | bnds.original_bounds.max.v[1] = cam_pos->v[1] + hither; |
||
5648 | bnds.original_bounds.max.v[2] = cam_pos->v[2] + hither; |
||
5649 | k = FindFacesInBox(&bnds, face_list, 3); |
||
5650 | if (k > 0) { |
||
5651 | BrVector3Sub(&tv2, cam_pos, &face_list[0].v[0]); |
||
5652 | sa = BrVector3Dot(&face_list[0].normal, &tv2); |
||
5653 | // ts2 = sa; |
||
5654 | if (sa < hither && sa >= 0.0) { |
||
5655 | BrVector3Scale(&tv2, &face_list[0].normal, hither - sa); |
||
5656 | BrVector3Accumulate(cam_pos, &tv2); |
||
5657 | } |
||
5658 | if (k > 1) { |
||
5659 | sb = BrVector3Dot(&face_list[0].normal, &face_list[1].normal); |
||
5660 | if (sb > 0.95f && k > 2) { |
||
5661 | BrVector3Copy(&face_list[1].normal, &face_list[2].normal); |
||
5662 | BrVector3Copy(&face_list[1].v[0], &face_list[2].v[0]); |
||
5663 | sb = BrVector3Dot(&face_list[0].normal, &face_list[2].normal); |
||
5664 | k = 2; |
||
5665 | } |
||
5666 | if (sb <= 0.95f) { |
||
5667 | BrVector3Sub(&tv2, cam_pos, &face_list[1].v[0]); |
||
5668 | sc = BrVector3Dot(&face_list[1].normal, &tv2); |
||
5669 | if (sc < hither && sc >= 0.0) { |
||
5670 | sc = BrVector3Dot(&face_list[0].normal, &face_list[1].normal); |
||
5671 | BrVector3Scale(&b, &face_list[0].normal, sc); |
||
5672 | BrVector3Sub(&face_list[1].normal, &face_list[1].normal, &b); |
||
5673 | BrVector3Scale(&tv2, &face_list[1].normal, hither - ts2); |
||
5674 | BrVector3Accumulate(cam_pos, &tv2); |
||
5675 | } |
||
5676 | } |
||
5677 | } |
||
5678 | } |
||
5679 | i += k; |
||
5680 | } |
||
5681 | return i; |
||
5682 | } |
||
5683 | |||
5684 | // IDA: int __usercall BoundsTest@<EAX>(br_bounds *bnds@<EAX>, br_vector3 *p@<EDX>) |
||
5685 | int BoundsTest(br_bounds* bnds, br_vector3* p) { |
||
18 | pmbaty | 5686 | int j; |
1 | pmbaty | 5687 | LOG_TRACE("(%p, %p)", bnds, p); |
18 | pmbaty | 5688 | |
5689 | for (j = 0; j < 3; j++) { |
||
5690 | if (p->v[j] > bnds->max.v[j] || p->v[j] < bnds->min.v[j]) { |
||
5691 | return 0; |
||
5692 | } |
||
5693 | } |
||
5694 | return 1; |
||
1 | pmbaty | 5695 | } |
5696 | |||
5697 | // IDA: int __usercall CollideCameraWithOtherCars@<EAX>(br_vector3 *car_pos@<EAX>, br_vector3 *cam_pos@<EDX>) |
||
5698 | int CollideCameraWithOtherCars(br_vector3* car_pos, br_vector3* cam_pos) { |
||
18 | pmbaty | 5699 | int i; |
5700 | int plane; |
||
5701 | br_scalar ts; |
||
5702 | tCar_spec* c; |
||
5703 | br_vector3 tv; |
||
5704 | br_vector3 pos_car_space; |
||
5705 | br_vector3 dir; |
||
5706 | br_vector3 p; |
||
5707 | br_vector3 n; |
||
5708 | br_bounds bnds; |
||
1 | pmbaty | 5709 | LOG_TRACE("(%p, %p)", car_pos, cam_pos); |
5710 | |||
18 | pmbaty | 5711 | for (i = 0; i < gNum_cars_and_non_cars; i++) { |
5712 | if (BoundsTest(&gActive_car_list[i]->bounds_world_space, cam_pos)) { |
||
5713 | c = gActive_car_list[i]; |
||
5714 | BrVector3Sub(&tv, cam_pos, &c->car_master_actor->t.t.translate.t); |
||
5715 | BrMatrix34TApplyV(&p, &tv, &c->car_master_actor->t.t.mat); |
||
5716 | if (BoundsTest(&c->bounds[0], &p)) { |
||
5717 | BrVector3Sub(&tv, cam_pos, car_pos); |
||
5718 | BrMatrix34TApplyV(&dir, &tv, &c->car_master_actor->t.t.mat); |
||
5719 | BrVector3Add(&pos_car_space, &p, &dir); |
||
5720 | BrVector3SetFloat(&tv, 0.03f, 0.03f, 0.03f); |
||
5721 | BrVector3Sub(&bnds.min, &c->bounds[0].min, &tv); |
||
5722 | BrVector3Add(&bnds.max, &c->bounds[0].max, &tv); |
||
5723 | plane = LineBoxColl(&pos_car_space, &p, &bnds, &tv); |
||
5724 | BrMatrix34ApplyP(cam_pos, &tv, &c->car_master_actor->t.t.mat); |
||
5725 | return 1; |
||
5726 | } |
||
5727 | } |
||
5728 | } |
||
1 | pmbaty | 5729 | return 0; |
5730 | } |
||
5731 | |||
5732 | // IDA: void __cdecl InitialiseExternalCamera() |
||
5733 | void InitialiseExternalCamera(void) { |
||
5734 | br_scalar ts; |
||
5735 | tCar_spec* c; |
||
5736 | //br_vector3 r; // Pierre-Marie Baty -- unused variable |
||
5737 | br_angle yaw; |
||
5738 | LOG_TRACE("()"); |
||
5739 | |||
5740 | c = gCar_to_view; |
||
5741 | if (!gProgram_state.racing) { |
||
5742 | c = &gProgram_state.current_car; |
||
5743 | } |
||
5744 | gCamera_height = c->pos.v[1]; |
||
5745 | BrVector3Set(&gView_direction, c->direction.v[0], 0.0f, c->direction.v[2]); |
||
5746 | BrVector3Normalise(&gView_direction, &gView_direction); |
||
5747 | ts = -BrVector3Dot(&gView_direction, (br_vector3*)c->car_master_actor->t.t.mat.m[2]); |
||
5748 | gCamera_sign = ts < 0; |
||
5749 | gCamera_mode = 0; |
||
5750 | if (gCamera_sign) { |
||
5751 | yaw = -gCamera_yaw; |
||
5752 | } else { |
||
5753 | yaw = gCamera_yaw; |
||
5754 | } |
||
5755 | DrVector3RotateY(&gView_direction, yaw); |
||
5756 | gMin_camera_car_distance = 0.6f; |
||
5757 | gCamera_frozen = 0; |
||
5758 | gCamera_mode = -2; |
||
5759 | if (gCountdown && (gNet_mode == eNet_mode_none || gCurrent_net_game->options.grid_start) && gCountdown > 4) { |
||
5760 | gCamera_height = gCamera_height + 10.0f; |
||
5761 | } |
||
5762 | } |
||
5763 | |||
5764 | // IDA: void __cdecl FreezeCamera() |
||
5765 | void FreezeCamera(void) { |
||
5766 | LOG_TRACE("()"); |
||
5767 | |||
5768 | gCamera_frozen = 1; |
||
5769 | } |
||
5770 | |||
5771 | // IDA: void __usercall FlyCar(tCar_spec *c@<EAX>, br_scalar dt) |
||
5772 | void FlyCar(tCar_spec* c, br_scalar dt) { |
||
5773 | int accflag; |
||
5774 | int turnflag; |
||
5775 | br_vector3 step; |
||
5776 | br_matrix34* mat; |
||
5777 | br_angle theta; |
||
5778 | static br_scalar vel = 0.f; |
||
5779 | tFace_ref faces[20]; |
||
5780 | tBounds bnds; |
||
5781 | int i; // Added by DethRace |
||
5782 | br_scalar tmp_scalar1; // Added by DethRace |
||
5783 | br_scalar tmp_scalar2; // Added by DethRace |
||
5784 | br_vector3 tmp1; // Added by DethRace |
||
5785 | br_vector3 tmp2; // Added by DethRace |
||
5786 | br_vector3 tmp3; // Added by DethRace |
||
5787 | LOG_TRACE("(%p, %f)", c, dt); |
||
5788 | |||
5789 | accflag = 0; |
||
5790 | turnflag = 0; |
||
5791 | mat = &c->car_master_actor->t.t.mat; |
||
5792 | bnds.mat = mat; |
||
5793 | BrVector3InvScale(&bnds.original_bounds.min, &c->bounds[1].min, WORLD_SCALE); |
||
5794 | BrVector3InvScale(&bnds.original_bounds.max, &c->bounds[1].max, WORLD_SCALE); |
||
5795 | BrVector3InvScale((br_vector3*)bnds.mat->m[3], (br_vector3*)bnds.mat->m[3], WORLD_SCALE); |
||
5796 | FindFacesInBox(&bnds, faces, COUNT_OF(faces)); |
||
5797 | BrVector3Scale((br_vector3*)bnds.mat->m[3], (br_vector3*)bnds.mat->m[3], WORLD_SCALE); |
||
5798 | if (c->keys.acc || c->joystick.acc > 0) { |
||
5799 | vel += 10.f * dt; |
||
5800 | accflag = 1; |
||
5801 | } |
||
5802 | if (c->keys.dec || c->joystick.dec > 0) { |
||
5803 | vel -= 10.f * dt; |
||
5804 | accflag = 1; |
||
5805 | } |
||
5806 | if (!accflag) { |
||
5807 | if (vel >= 20.f * dt || vel <= -20.f * dt) { |
||
5808 | vel -= 20.f * vel / fabsf(vel) * dt; |
||
5809 | } else { |
||
5810 | vel = 0.f; |
||
5811 | } |
||
5812 | } |
||
5813 | BrVector3Scale(&step, &c->v, dt); |
||
5814 | BrVector3Accumulate((br_vector3*)mat->m[3], &step); |
||
5815 | BrVector3Scale(&step, (br_vector3*)mat->m[1], dt); |
||
5816 | if (c->keys.left || c->joystick.left > 0) { |
||
5817 | BrVector3Accumulate(&c->omega, &step); |
||
5818 | turnflag = 1; |
||
5819 | } |
||
5820 | if (c->keys.right || c->joystick.right > 0) { |
||
5821 | BrVector3Sub(&c->omega, &c->omega, &step); |
||
5822 | turnflag = 1; |
||
5823 | } |
||
5824 | if (!turnflag) { |
||
5825 | BrVector3SetFloat(&c->omega, 0.f, 0.f, 0.f); |
||
5826 | } |
||
5827 | theta = BrRadianToAngle(c->omega.v[1] * dt); |
||
5828 | DrVector3RotateY(&c->v, theta); |
||
5829 | BrMatrix34PreRotateY(mat, theta); |
||
5830 | if (c->keys.up) { |
||
5831 | BrMatrix34PreRotateX(mat, BrDegreeToAngle(5)); |
||
5832 | } |
||
5833 | if (c->keys.down) { |
||
5834 | BrMatrix34PreRotateX(mat, BrDegreeToAngle(360 - 5)); |
||
5835 | } |
||
5836 | BrVector3Scale(&c->v, (br_vector3*)mat->m[2], -vel); |
||
5837 | BrVector3Scale(&step, &c->v, dt); |
||
5838 | BrVector3Accumulate((br_vector3*)&mat->m[3], &step); |
||
5839 | if (c->keys.holdw) { |
||
5840 | BrVector3Copy(&step, (br_vector3*)mat->m[3]); |
||
5841 | BrMatrix34RotateY(mat, BrDegreeToAngle(90) - BrRadianToAngle(atan2f(mat->m[2][2], mat->m[2][0]))); |
||
5842 | BrVector3Copy((br_vector3*)mat->m[3], &step); |
||
5843 | BrVector3SetFloat(&step, 0.f, -100.f, 0.f); |
||
5844 | BrVector3Copy(&tmp1, (br_vector3*)&mat->m[3]); |
||
5845 | findfloor(&tmp1, &step, &tmp2, &tmp_scalar1); |
||
5846 | tmp1.v[1] += 100.f; |
||
5847 | findfloor(&tmp1, &step, &tmp3, &tmp_scalar2); |
||
5848 | if (tmp_scalar2 <= 1.f) { |
||
5849 | BrVector3SetFloat(&step, 0.f, -5.01f, 0.f); |
||
5850 | tmp1.v[1] -= 20 * 5.f; |
||
5851 | for (i = 0; i < 20; i++) { |
||
5852 | tmp1.v[1] += 5.f; |
||
5853 | findfloor(&tmp1, &step, &tmp3, &tmp_scalar2); |
||
5854 | if (tmp_scalar2 <= 1.f) { |
||
5855 | break; |
||
5856 | } |
||
5857 | } |
||
5858 | tmp_scalar2 = -tmp_scalar2 / 20.f + (i + 1) * 0.05f; |
||
5859 | } |
||
5860 | if (tmp_scalar2 < tmp_scalar1) { |
||
5861 | tmp_scalar1 = -tmp_scalar2; |
||
5862 | BrVector3Copy(&tmp2, &tmp3); |
||
5863 | } |
||
5864 | if (tmp_scalar1 <= 1.f) { |
||
5865 | mat->m[3][1] -= tmp_scalar1 * 100.f; |
||
5866 | BrMatrix34PreRotateX(mat, BrRadianToAngle(asinf(BrVector3Dot((br_vector3*)mat->m[2], &tmp2)))); |
||
5867 | BrMatrix34PreRotateZ(mat, -BrRadianToAngle(asinf(BrVector3Dot((br_vector3*)mat->m[0], &tmp2)))); |
||
5868 | } |
||
5869 | } |
||
5870 | BrVector3Negate((br_vector3*)&c->direction, (br_vector3*)mat->m[2]); |
||
5871 | BrMatrix34Copy(&c->oldmat, mat); |
||
5872 | BrMatrix34ApplyP(&c->pos, &c->cmpos, mat); |
||
5873 | BrVector3InvScale(&c->pos, &c->pos, WORLD_SCALE); |
||
5874 | BrVector3InvScale((br_vector3*)bnds.mat->m[3], (br_vector3*)bnds.mat->m[3], WORLD_SCALE); |
||
5875 | GetNewBoundingBox(&c->bounds_world_space, c->bounds, bnds.mat); |
||
5876 | BrVector3Scale((br_vector3*)bnds.mat->m[3], (br_vector3*)bnds.mat->m[3], WORLD_SCALE); |
||
5877 | } |
||
5878 | |||
5879 | // IDA: void __usercall DrVector3RotateY(br_vector3 *v@<EAX>, br_angle t@<EDX>) |
||
5880 | void DrVector3RotateY(br_vector3* v, br_angle t) { |
||
5881 | br_scalar c; |
||
5882 | br_scalar s; |
||
5883 | br_scalar ts; |
||
5884 | LOG_TRACE("(%p, %d)", v, t); |
||
5885 | |||
5886 | c = cos(BrAngleToRadian(t)); |
||
5887 | s = sin(BrAngleToRadian(t)); |
||
5888 | ts = v->v[0] * c + v->v[2] * s; |
||
5889 | v->v[2] = v->v[2] * c - v->v[0] * s; |
||
5890 | v->v[0] = ts; |
||
5891 | } |
||
5892 | |||
5893 | // IDA: void __cdecl CrashCarsTogether(br_scalar dt) |
||
5894 | void CrashCarsTogether(br_scalar dt) { |
||
5895 | int pass; |
||
5896 | int k; |
||
5897 | int i; |
||
5898 | tCollison_data collide_list[32]; |
||
5899 | LOG_TRACE("(%f)", dt); |
||
5900 | |||
5901 | for (i = 0; i < gNum_cars_and_non_cars; i++) { |
||
5902 | collide_list[i].car = NULL; |
||
5903 | collide_list[i].ref = gNum_cars_and_non_cars - 1; |
||
5904 | gActive_car_list[i]->infinite_mass = 0; |
||
5905 | } |
||
5906 | for (pass = 0; pass < 5; pass++) { |
||
5907 | k = CrashCarsTogetherSinglePass(dt, pass, collide_list); |
||
5908 | if (k <= 0) { |
||
5909 | break; |
||
5910 | } |
||
5911 | } |
||
5912 | if (k > 0) { |
||
5913 | for (i = 0; i < gNum_cars_and_non_cars; i++) { |
||
5914 | BringCarToAGrindingHalt((tCollision_info*)gActive_car_list[i]); |
||
5915 | } |
||
5916 | } |
||
5917 | } |
||
5918 | |||
5919 | // IDA: int __cdecl CrashCarsTogetherSinglePass(br_scalar dt, int pPass, tCollison_data *collide_list) |
||
5920 | int CrashCarsTogetherSinglePass(br_scalar dt, int pPass, tCollison_data* collide_list) { |
||
5921 | int i; |
||
5922 | int j; |
||
5923 | //int l; // Pierre-Marie Baty -- unused variable |
||
5924 | //int m; // Pierre-Marie Baty -- unused variable |
||
5925 | //int n; // Pierre-Marie Baty -- unused variable |
||
5926 | int collided; |
||
5927 | int k; |
||
5928 | //int ref1; // Pierre-Marie Baty -- unused variable |
||
5929 | //int ref2; // Pierre-Marie Baty -- unused variable |
||
5930 | int c1im; |
||
5931 | int c2im; |
||
5932 | tCollision_info* car_1; |
||
5933 | tCollision_info* car_2; |
||
5934 | tCollision_info* car_3; |
||
5935 | tCollision_info* car_in_middle; |
||
5936 | tCollision_info* car_on_wall; |
||
5937 | LOG_TRACE("(%f, %d, %p)", dt, pPass, collide_list); |
||
5938 | |||
5939 | collided = 0; |
||
5940 | for (i = 0; i < gNum_cars_and_non_cars - 1; i++) { |
||
5941 | car_1 = (tCollision_info*)gActive_car_list[i]; |
||
5942 | for (j = i + 1; j < gNum_cars_and_non_cars; j++) { |
||
5943 | car_2 = (tCollision_info*)gActive_car_list[j]; |
||
5944 | if (collide_list[i].ref > 0 || collide_list[j].ref > 0) { |
||
5945 | collide_list[i].ref--; |
||
5946 | collide_list[j].ref--; |
||
5947 | if (SimpleCarCarCollisionTest(car_1, car_2)) { |
||
5948 | if (car_1->infinite_mass == -1 && car_2->infinite_mass > 0) { |
||
5949 | if (CollideTwoCars(car_1, car_2, -1)) { |
||
5950 | if (car_2->infinite_mass >= 256 || pPass >= 4) { |
||
5951 | BringCarToAGrindingHalt(car_2); |
||
5952 | } else { |
||
5953 | car_2->infinite_mass = 0; |
||
5954 | k = CollideTwoCarsWithWalls(car_1, car_2, dt); |
||
5955 | car_2->infinite_mass = 256; |
||
5956 | if (k < 0) { |
||
5957 | BringCarToAGrindingHalt(car_2); |
||
5958 | } |
||
5959 | } |
||
5960 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
5961 | collide_list[j].car = car_1; |
||
5962 | collided++; |
||
5963 | } |
||
5964 | } else if (car_2->infinite_mass == -1 && car_1->infinite_mass > 0) { |
||
5965 | if (CollideTwoCars(car_1, car_2, -1)) { |
||
5966 | if (car_1->infinite_mass >= 256 || pPass >= 4) { |
||
5967 | BringCarToAGrindingHalt(car_1); |
||
5968 | } else { |
||
5969 | car_1->infinite_mass = 0; |
||
5970 | k = CollideTwoCarsWithWalls(car_1, car_2, dt); |
||
5971 | car_1->infinite_mass = 256; |
||
5972 | if (k < 0) { |
||
5973 | BringCarToAGrindingHalt(car_1); |
||
5974 | } |
||
5975 | } |
||
5976 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
5977 | collide_list[i].car = car_2; |
||
5978 | collided++; |
||
5979 | } |
||
5980 | } else if (collide_list[i].car || collide_list[j].car) { |
||
5981 | if ((collide_list[j].car == NULL) == (collide_list[i].car == NULL)) { |
||
5982 | if (collide_list[j].car != collide_list[i].car || (car_1->infinite_mass && car_2->infinite_mass)) { |
||
5983 | if (collide_list[i].car && collide_list[j].car) { |
||
5984 | if (car_1->infinite_mass && car_2->infinite_mass) { |
||
5985 | if ((car_1->infinite_mass != -1 || car_2->infinite_mass != -1) && CollideTwoCars(car_1, car_2, -1)) { |
||
5986 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
5987 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
5988 | if (car_1->infinite_mass && car_2->infinite_mass) { |
||
5989 | BringCarToAGrindingHalt(car_1); |
||
5990 | BringCarToAGrindingHalt(car_2); |
||
5991 | } else { |
||
5992 | k = CollideTwoCarsWithWalls(car_1, car_2, dt); |
||
5993 | if (k >= 0) { |
||
5994 | if (k) { |
||
5995 | if (car_1->infinite_mass >= 0) { |
||
5996 | car_1->infinite_mass++; |
||
5997 | } |
||
5998 | if (car_2->infinite_mass >= 0) { |
||
5999 | car_2->infinite_mass++; |
||
6000 | } |
||
6001 | collided++; |
||
6002 | } |
||
6003 | } else { |
||
6004 | BringCarToAGrindingHalt(car_1); |
||
6005 | BringCarToAGrindingHalt(car_2); |
||
6006 | collided++; |
||
6007 | } |
||
6008 | } |
||
6009 | collided++; |
||
6010 | } |
||
6011 | } else { |
||
6012 | c1im = car_1->infinite_mass; |
||
6013 | c2im = car_2->infinite_mass; |
||
6014 | k = CollideTwoCarsWithWalls(car_1, car_2, dt); |
||
6015 | if (k > -1) { |
||
6016 | if (k) { |
||
6017 | if (!c2im) { |
||
6018 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
6019 | } |
||
6020 | if (!c1im) { |
||
6021 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
6022 | } |
||
6023 | collided++; |
||
6024 | if (car_1->infinite_mass >= 0) { |
||
6025 | car_1->infinite_mass++; |
||
6026 | } |
||
6027 | if (car_2->infinite_mass >= 0) { |
||
6028 | car_2->infinite_mass++; |
||
6029 | } |
||
6030 | } |
||
6031 | } else { |
||
6032 | BringCarToAGrindingHalt(car_1); |
||
6033 | BringCarToAGrindingHalt(car_2); |
||
6034 | if (c1im >= 0) { |
||
6035 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
6036 | } |
||
6037 | if (c2im >= 0) { |
||
6038 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
6039 | } |
||
6040 | collided++; |
||
6041 | } |
||
6042 | } |
||
6043 | } |
||
6044 | } else { |
||
6045 | k = CollideTwoCarsWithWalls(car_1, car_2, dt); |
||
6046 | if (k) { |
||
6047 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
6048 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
6049 | if (k == -1) { |
||
6050 | BringCarToAGrindingHalt(car_1); |
||
6051 | BringCarToAGrindingHalt(car_2); |
||
6052 | } |
||
6053 | collided++; |
||
6054 | if (car_1->infinite_mass >= 0) { |
||
6055 | car_1->infinite_mass++; |
||
6056 | } |
||
6057 | if (car_2->infinite_mass >= 0) { |
||
6058 | car_2->infinite_mass++; |
||
6059 | } |
||
6060 | } |
||
6061 | } |
||
6062 | } else { |
||
6063 | c1im = car_1->infinite_mass; |
||
6064 | c2im = car_2->infinite_mass; |
||
6065 | k = CollideTwoCarsWithWalls(car_1, car_2, dt); |
||
6066 | if (k == -1) { |
||
6067 | if (collide_list[i].car) { |
||
6068 | car_3 = collide_list[i].car; |
||
6069 | } else { |
||
6070 | car_3 = collide_list[j].car; |
||
6071 | } |
||
6072 | if (collide_list[i].car) { |
||
6073 | car_in_middle = car_1; |
||
6074 | } else { |
||
6075 | car_in_middle = car_2; |
||
6076 | } |
||
6077 | if (car_3->infinite_mass > 1 || car_3->infinite_mass == -1 || (tU8)(car_in_middle->infinite_mass) > 1 || car_in_middle->infinite_mass == -1) { |
||
6078 | BringCarToAGrindingHalt(car_1); |
||
6079 | BringCarToAGrindingHalt(car_2); |
||
6080 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
6081 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
6082 | } else { |
||
6083 | if (collide_list[i].car) { |
||
6084 | car_on_wall = car_2; |
||
6085 | } else { |
||
6086 | car_on_wall = car_1; |
||
6087 | } |
||
6088 | car_in_middle->infinite_mass = 0; |
||
6089 | car_3->infinite_mass = 0; |
||
6090 | k = CollideTwoCarsWithWalls(car_on_wall, car_in_middle, dt); |
||
6091 | car_in_middle->infinite_mass = 2; |
||
6092 | car_on_wall->infinite_mass++; |
||
6093 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
6094 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
6095 | if (k < 0) { |
||
6096 | BringCarToAGrindingHalt(car_1); |
||
6097 | BringCarToAGrindingHalt(car_2); |
||
6098 | } |
||
6099 | } |
||
6100 | collide_list[i].car = car_2; |
||
6101 | collide_list[j].car = car_1; |
||
6102 | collided++; |
||
6103 | } else if (k) { |
||
6104 | collide_list[i].car = car_2; |
||
6105 | collide_list[j].car = car_1; |
||
6106 | if (!c2im) { |
||
6107 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
6108 | } |
||
6109 | if (!c1im) { |
||
6110 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
6111 | } |
||
6112 | collided++; |
||
6113 | if (car_1->infinite_mass >= 0) { |
||
6114 | car_1->infinite_mass++; |
||
6115 | } |
||
6116 | if (car_2->infinite_mass >= 0) { |
||
6117 | car_2->infinite_mass++; |
||
6118 | } |
||
6119 | } |
||
6120 | } |
||
6121 | } else { |
||
6122 | k = CollideTwoCarsWithWalls(car_1, car_2, dt); |
||
6123 | if (k) { |
||
6124 | collide_list[i].car = car_2; |
||
6125 | collide_list[j].car = car_1; |
||
6126 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
6127 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
6128 | if (k == -1) { |
||
6129 | BringCarToAGrindingHalt(car_1); |
||
6130 | BringCarToAGrindingHalt(car_2); |
||
6131 | collide_list[i].ref = gNum_cars_and_non_cars - 2; |
||
6132 | collide_list[j].ref = gNum_cars_and_non_cars - 2; |
||
6133 | } |
||
6134 | collided++; |
||
6135 | } |
||
6136 | } |
||
6137 | CrashEarnings((tCar_spec*)car_1, (tCar_spec*)car_2); |
||
6138 | } |
||
6139 | } |
||
6140 | } |
||
6141 | } |
||
6142 | return collided; |
||
6143 | } |
||
6144 | |||
6145 | // IDA: void __usercall BringCarToAGrindingHalt(tCollision_info *car@<EAX>) |
||
6146 | void BringCarToAGrindingHalt(tCollision_info* car) { |
||
6147 | LOG_TRACE("(%p)", car); |
||
6148 | |||
6149 | BrVector3SetFloat(&car->v, 0.0f, 0.0f, 0.0f); |
||
6150 | BrVector3SetFloat(&car->omega, 0.0f, 0.0f, 0.0f); |
||
6151 | BrVector3SetFloat(&car->oldomega, 0.0f, 0.0f, 0.0f); |
||
6152 | BrMatrix34Copy(&car->car_master_actor->t.t.mat, &car->oldmat); |
||
6153 | car->infinite_mass = -1; |
||
6154 | } |
||
6155 | |||
6156 | // IDA: int __usercall BoundsOverlapTest@<EAX>(br_bounds *b1@<EAX>, br_bounds *b2@<EDX>) |
||
6157 | int BoundsOverlapTest_car(br_bounds* b1, br_bounds* b2) { |
||
6158 | LOG_TRACE("(%p, %p)", b1, b2); |
||
6159 | |||
6160 | return b2->max.v[0] >= b1->min.v[0] |
||
6161 | && b1->max.v[0] >= b2->min.v[0] |
||
6162 | && b2->max.v[1] >= b1->min.v[1] |
||
6163 | && b1->max.v[1] >= b2->min.v[1] |
||
6164 | && b2->max.v[2] >= b1->min.v[2] |
||
6165 | && b1->max.v[2] >= b2->min.v[2]; |
||
6166 | } |
||
6167 | |||
6168 | // IDA: int __usercall SimpleCarCarCollisionTest@<EAX>(tCollision_info *car1@<EAX>, tCollision_info *car2@<EDX>) |
||
6169 | int SimpleCarCarCollisionTest(tCollision_info* car1, tCollision_info* car2) { |
||
6170 | LOG_TRACE("(%p, %p)", car1, car2); |
||
6171 | |||
6172 | if (car1->bounds_ws_type == eBounds_ws && car2->bounds_ws_type == eBounds_ws) { |
||
6173 | return BoundsOverlapTest_car(&car1->bounds_world_space, &car2->bounds_world_space); |
||
6174 | } else { |
||
6175 | return 1; |
||
6176 | } |
||
6177 | } |
||
6178 | |||
6179 | // IDA: int __usercall CollideTwoCarsWithWalls@<EAX>(tCollision_info *car1@<EAX>, tCollision_info *car2@<EDX>, br_scalar dt) |
||
6180 | int CollideTwoCarsWithWalls(tCollision_info* car1, tCollision_info* car2, br_scalar dt) { |
||
6181 | br_vector3 mom1; |
||
6182 | br_vector3 mom2; |
||
6183 | int l; |
||
6184 | int m; |
||
6185 | int n; |
||
6186 | int p; |
||
6187 | int im1; |
||
6188 | int im2; |
||
6189 | LOG_TRACE("(%p, %p, %f)", car1, car2, dt); |
||
6190 | |||
6191 | l = 0; |
||
6192 | m = 0; |
||
6193 | p = 0; |
||
6194 | im1 = car1->infinite_mass; |
||
6195 | im2 = car2->infinite_mass; |
||
6196 | do { |
||
6197 | n = CollideTwoCarsRepeatedly(car1, car2, dt); |
||
6198 | if (n <= 0) { |
||
6199 | if (n == -1) { |
||
6200 | return -1; |
||
6201 | } |
||
6202 | l = 0; |
||
6203 | m = 0; |
||
6204 | } else { |
||
6205 | ++p; |
||
6206 | if (n >= 5) { |
||
6207 | if (p >= 10 || car1->infinite_mass || car2->infinite_mass) { |
||
6208 | return -1; |
||
6209 | } |
||
6210 | BrVector3Set(&car1->omega, 0.0f, 0.0f, 0.0f); |
||
6211 | BrVector3Set(&car2->omega, 0.0f, 0.0f, 0.0f); |
||
6212 | BrVector3Scale(&mom1, &car1->v, car1->M); |
||
6213 | BrVector3Scale(&mom2, &car2->v, car2->M); |
||
6214 | BrVector3Accumulate(&mom1, &mom2); |
||
6215 | BrVector3InvScale(&car1->v, &mom1, car2->M + car1->M); |
||
6216 | car2->v = car1->v; |
||
6217 | RotateCar(car1, dt); |
||
6218 | TranslateCar(car1, dt); |
||
6219 | RotateCar(car2, dt); |
||
6220 | TranslateCar(car2, dt); |
||
6221 | if (CollideTwoCars(car1, car2, -1)) { |
||
6222 | return -1; |
||
6223 | } |
||
6224 | if (im1 || im2) { |
||
6225 | return -1; |
||
6226 | } |
||
6227 | } |
||
6228 | if (!im1) { |
||
6229 | l = CollideCarWithWall(car1, dt); |
||
6230 | } |
||
6231 | if (!im2) { |
||
6232 | m = CollideCarWithWall(car2, dt); |
||
6233 | } |
||
6234 | if (p < 3) { |
||
6235 | car1->infinite_mass = im1; |
||
6236 | car2->infinite_mass = im2; |
||
6237 | } |
||
6238 | if (p > 5) { |
||
6239 | if (l) { |
||
6240 | car1->infinite_mass |= 0x100u; |
||
6241 | } |
||
6242 | if (m) { |
||
6243 | car2->infinite_mass |= 0x100u; |
||
6244 | } |
||
6245 | } |
||
6246 | if (car1->infinite_mass && car2->infinite_mass) { |
||
6247 | return -1; |
||
6248 | } |
||
6249 | } |
||
6250 | } while ((l || m) && p < 10); |
||
6251 | if (p < 10) { |
||
6252 | return p; |
||
6253 | } else { |
||
6254 | return -1; |
||
6255 | } |
||
6256 | } |
||
6257 | |||
6258 | // IDA: int __usercall CollideTwoCarsRepeatedly@<EAX>(tCollision_info *car1@<EAX>, tCollision_info *car2@<EDX>, br_scalar dt) |
||
6259 | int CollideTwoCarsRepeatedly(tCollision_info* car1, tCollision_info* car2, br_scalar dt) { |
||
6260 | int l; |
||
6261 | int collide; |
||
6262 | //br_scalar ts; // Pierre-Marie Baty -- unused variable |
||
6263 | LOG_TRACE("(%p, %p, %f)", car1, car2, dt); |
||
6264 | |||
6265 | l = 0; |
||
6266 | ModifyCarsMass(car1, car2); |
||
6267 | while (1) { |
||
6268 | collide = CollideTwoCars(car1, car2, l); |
||
6269 | if (!collide) { |
||
6270 | break; |
||
6271 | } |
||
6272 | if (collide == -1) { |
||
6273 | ResetCarsMass(car1, car2); |
||
6274 | return -1; |
||
6275 | } |
||
6276 | if (++l >= 5) { |
||
6277 | break; |
||
6278 | } |
||
6279 | RotateCar(car1, dt); |
||
6280 | TranslateCar(car1, dt); |
||
6281 | RotateCar(car2, dt); |
||
6282 | TranslateCar(car2, dt); |
||
6283 | } |
||
6284 | if (l > 0) { |
||
6285 | car1->frame_collision_flag += 256; |
||
6286 | car2->frame_collision_flag += 256; |
||
6287 | if (gNet_mode == eNet_mode_host) { |
||
6288 | car1->last_car_car_collision = gLast_mechanics_time + 40; |
||
6289 | car2->last_car_car_collision = gLast_mechanics_time + 40; |
||
6290 | } |
||
6291 | } |
||
6292 | ResetCarsMass(car1, car2); |
||
6293 | return l; |
||
6294 | } |
||
6295 | |||
6296 | // IDA: int __usercall CollideTwoCars@<EAX>(tCollision_info *car1@<EAX>, tCollision_info *car2@<EDX>, int pPass@<EBX>) |
||
6297 | int CollideTwoCars(tCollision_info* car1, tCollision_info* car2, int pPass) { |
||
6298 | int k; |
||
6299 | int old_k; |
||
6300 | int i; |
||
6301 | int j; |
||
6302 | //br_scalar dist; // Pierre-Marie Baty -- unused variable |
||
6303 | //br_scalar ts; // Pierre-Marie Baty -- unused variable |
||
6304 | br_bounds new_car1_bnds; |
||
6305 | br_bounds new_car2_bnds; |
||
6306 | br_bounds bnds; |
||
6307 | br_matrix34* mat1; |
||
6308 | br_matrix34* mat2; |
||
6309 | br_matrix34* oldmat1; |
||
6310 | br_matrix34* oldmat2; |
||
6311 | br_matrix34 inv_mat1; |
||
6312 | br_matrix34 inv_mat2; |
||
6313 | br_matrix34 inv_oldmat1; |
||
6314 | br_matrix34 inv_oldmat2; |
||
6315 | br_matrix34 car2_to_car1; |
||
6316 | br_matrix34 car1_to_car2; |
||
6317 | br_matrix34 old_car2_to_car1; |
||
6318 | br_matrix34 old_car1_to_car2; |
||
6319 | br_matrix34 car1_to_old_car1; |
||
6320 | br_matrix34 car2_to_old_car2; |
||
6321 | br_vector3 r[16]; |
||
6322 | br_vector3 n[16]; |
||
6323 | //br_vector3 sep; // Pierre-Marie Baty -- unused variable |
||
6324 | br_vector3 tv; |
||
6325 | int add_point; |
||
6326 | static br_vector3 oldr1; |
||
6327 | static br_vector3 oldr2; |
||
6328 | static br_vector3 oldn1; |
||
6329 | static br_vector3 oldn2; |
||
6330 | static int is_old_point_available; |
||
6331 | LOG_TRACE("(%p, %p, %d)", car1, car2, pPass); |
||
6332 | |||
6333 | #ifdef DETHRACE_FIX_BUGS |
||
6334 | // this variable is used uninitialized |
||
6335 | add_point = 0; |
||
6336 | #endif |
||
6337 | |||
6338 | if (!gCar_car_collisions) { |
||
6339 | return 0; |
||
6340 | } |
||
6341 | if (pPass < 0 && !SimpleCarCarCollisionTest(car1, car2)) { |
||
6342 | return 0; |
||
6343 | } |
||
6344 | |||
6345 | mat1 = &car1->car_master_actor->t.t.mat; |
||
6346 | mat2 = &car2->car_master_actor->t.t.mat; |
||
6347 | oldmat1 = &car1->oldmat; |
||
6348 | oldmat2 = &car2->oldmat; |
||
6349 | BrMatrix34LPInverse(&inv_oldmat1, &car1->oldmat); |
||
6350 | BrMatrix34LPInverse(&inv_oldmat2, &car2->oldmat); |
||
6351 | BrMatrix34Mul(&car1_to_old_car1, mat1, &inv_oldmat1); |
||
6352 | BrMatrix34Mul(&car2_to_old_car2, mat2, &inv_oldmat2); |
||
6353 | BrMatrix34Mul(&old_car2_to_car1, oldmat2, &inv_oldmat1); |
||
6354 | GetNewBoundingBox(&new_car1_bnds, &car1->bounds[1], &car1_to_old_car1); |
||
6355 | GetNewBoundingBox(&new_car2_bnds, &car2->bounds[1], &car2_to_old_car2); |
||
6356 | |||
6357 | for (i = 0; i < 3; ++i) { |
||
6358 | new_car1_bnds.min.v[i] = MIN(car1->bounds[1].min.v[i], new_car1_bnds.min.v[i]); |
||
6359 | new_car1_bnds.max.v[i] = MAX(car1->bounds[1].max.v[i], new_car1_bnds.max.v[i]); |
||
6360 | |||
6361 | new_car2_bnds.min.v[i] = MIN(car2->bounds[1].min.v[i], new_car2_bnds.min.v[i]); |
||
6362 | new_car2_bnds.max.v[i] = MAX(car2->bounds[1].max.v[i], new_car2_bnds.max.v[i]); |
||
6363 | } |
||
6364 | GetNewBoundingBox(&bnds, &new_car2_bnds, &old_car2_to_car1); |
||
6365 | |||
6366 | if (new_car1_bnds.max.v[0] < bnds.min.v[0] |
||
6367 | || bnds.max.v[0] < new_car1_bnds.min.v[0] |
||
6368 | || new_car1_bnds.max.v[1] < bnds.min.v[1] |
||
6369 | || bnds.max.v[1] < new_car1_bnds.min.v[1] |
||
6370 | || new_car1_bnds.max.v[2] < bnds.min.v[2] |
||
6371 | || bnds.max.v[2] < new_car1_bnds.min.v[2]) { |
||
6372 | return 0; |
||
6373 | } |
||
6374 | BrMatrix34LPInverse(&inv_mat1, mat1); |
||
6375 | BrMatrix34LPInverse(&inv_mat2, mat2); |
||
6376 | BrMatrix34Mul(&car2_to_car1, mat2, &inv_mat1); |
||
6377 | BrMatrix34Mul(&car1_to_car2, mat1, &inv_mat2); |
||
6378 | BrMatrix34Mul(&old_car2_to_car1, oldmat2, &inv_oldmat1); |
||
6379 | BrMatrix34Mul(&old_car1_to_car2, oldmat1, &inv_oldmat2); |
||
6380 | BrMatrix34Mul(&car1_to_old_car1, mat1, &inv_oldmat1); |
||
6381 | BrMatrix34Mul(&car2_to_old_car2, mat2, &inv_oldmat2); |
||
6382 | do { |
||
6383 | k = 0; |
||
6384 | k += FacePointCarCarCollide(car1, car2, &car2_to_car1, &old_car2_to_car1, &car1_to_old_car1, r, n, 8, 0); |
||
6385 | k += FacePointCarCarCollide(car2, car1, &car1_to_car2, &old_car1_to_car2, &car2_to_old_car2, &r[2 * k], &n[2 * k], 8 - k, 1); |
||
6386 | old_k = k; |
||
6387 | |||
6388 | if (k < 3 || add_point) { |
||
6389 | 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); |
||
6390 | } |
||
6391 | if (k == -1) { |
||
6392 | TestOldMats(car1, car2, 1); |
||
6393 | } |
||
6394 | if (!k) { |
||
6395 | return 0; |
||
6396 | } |
||
6397 | if (k > 4) { |
||
6398 | i = old_k; |
||
6399 | j = old_k; |
||
6400 | while (i < k) { |
||
6401 | if (BrVector3Dot(&n[2 * i + 1], &r[2 * i + 1]) <= 0.0f || i - j >= k - 4) { |
||
6402 | if (j != i) { |
||
6403 | r[2 * j] = r[2 * i]; |
||
6404 | } |
||
6405 | n[2 * j] = n[2 * i]; |
||
6406 | r[2 * j + 1] = r[2 * i + 1]; |
||
6407 | n[2 * j + 1] = n[2 * i + 1]; |
||
6408 | } else { |
||
6409 | j--; |
||
6410 | } |
||
6411 | i++; |
||
6412 | j++; |
||
6413 | } |
||
6414 | k = j; |
||
6415 | } |
||
6416 | for (i = 0; i < k; ++i) { |
||
6417 | BrVector3Sub(&r[2 * i], &r[2 * i], &car1->cmpos); |
||
6418 | BrVector3Sub(&r[2 * i + 1], &r[2 * i + 1], &car2->cmpos); |
||
6419 | } |
||
6420 | if (add_point == -1) { |
||
6421 | return k; |
||
6422 | } |
||
6423 | car1->doing_nothing_flag = 0; |
||
6424 | car2->doing_nothing_flag = 0; |
||
6425 | if (k < 3 && add_point) { |
||
6426 | for (i = 0; i < k; i++) { |
||
6427 | BrVector3Sub(&tv, &r[2 * i], &oldr1); |
||
6428 | if (BrVector3LengthSquared(&tv) < 0.01f) { |
||
6429 | add_point = 0; |
||
6430 | } |
||
6431 | } |
||
6432 | if (add_point) { |
||
6433 | r[2 * k] = oldr1; |
||
6434 | r[2 * k + 1] = oldr2; |
||
6435 | n[2 * k] = oldn1; |
||
6436 | n[2 * k + 1] = oldn2; |
||
6437 | k++; |
||
6438 | } |
||
6439 | } |
||
6440 | oldr1 = r[0]; |
||
6441 | oldr2 = r[1]; |
||
6442 | oldn1 = n[0]; |
||
6443 | oldn2 = n[1]; |
||
6444 | if (k < 3) { |
||
6445 | if (car1->collision_flag && !car1->infinite_mass) { |
||
6446 | |||
6447 | for (i = 0; i < k; i++) { |
||
6448 | if (BrVector3Dot(&n[2 * i], &car1->old_norm) < -0.9f) { |
||
6449 | car1->infinite_mass |= 0x100u; |
||
6450 | } |
||
6451 | } |
||
6452 | if (!car1->infinite_mass) { |
||
6453 | r[2 * k] = car1->old_point; |
||
6454 | n[2 * k] = car1->old_norm; |
||
6455 | BrVector3SetFloat(&n[2 * k + 1], 0.0f, 0.0f, 0.0f); |
||
6456 | BrVector3SetFloat(&r[2 * k + 1], 0.0f, 0.0f, 0.0f); |
||
6457 | k++; |
||
6458 | } |
||
6459 | } |
||
6460 | if (car2->collision_flag && !car2->infinite_mass) { |
||
6461 | for (i = 0; i < k; i++) { |
||
6462 | if (BrVector3Dot(&n[2 * i + 1], &car2->old_norm) < -0.9f) { |
||
6463 | car2->infinite_mass |= 0x100u; |
||
6464 | } |
||
6465 | } |
||
6466 | if (!car2->infinite_mass) { |
||
6467 | r[2 * k + 1] = car2->old_point; |
||
6468 | n[2 * k + 1] = car2->old_norm; |
||
6469 | BrVector3SetFloat(&n[2 * k], 0.0f, 0.0f, 0.0f); |
||
6470 | BrVector3SetFloat(&r[2 * k], 0.0f, 0.0f, 0.0f); |
||
6471 | k++; |
||
6472 | } |
||
6473 | } |
||
6474 | } |
||
6475 | if (car1->infinite_mass && car2->infinite_mass) { |
||
6476 | return -1; |
||
6477 | } |
||
6478 | } while (DoCollide(car1, car2, r, n, k, pPass, &car1_to_car2)); |
||
6479 | return k; |
||
6480 | } |
||
6481 | |||
6482 | // 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) |
||
6483 | 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) { |
||
6484 | br_vector3 p1; |
||
6485 | br_vector3 p2; |
||
6486 | br_vector3 tp1; |
||
6487 | br_vector3 tp2; |
||
6488 | br_vector3 tp3; |
||
6489 | br_vector3 hp1; |
||
6490 | br_vector3 hp2; |
||
6491 | br_vector3 hp3; |
||
6492 | br_vector3 shp1; |
||
6493 | br_vector3 shp2; |
||
6494 | br_vector3 edge; |
||
6495 | int plane1; |
||
6496 | int plane2; |
||
6497 | int plane3; |
||
6498 | br_scalar ts; |
||
6499 | int i; |
||
6500 | int j; |
||
6501 | int n; |
||
6502 | LOG_TRACE("(%p, %p, %p, %p, %p, %p, %p, %p, %p, %d)", pB1, pB2, pM21, pM12, pMo21, pMo12, pM1o1, pPoint_list, pNorm_list, pMax); |
||
6503 | |||
6504 | // EdgeEdge final version |
||
6505 | n = 0; |
||
6506 | if (pMax < 1) { |
||
6507 | return 0; |
||
6508 | } |
||
6509 | for (i = 0; i < 4; i++) { |
||
6510 | if (i == 3) { |
||
6511 | tp1 = pB2->min; |
||
6512 | } else { |
||
6513 | tp1 = pB2->max; |
||
6514 | tp1.v[i] = pB2->min.v[i]; |
||
6515 | } |
||
6516 | for (j = 0; j < 3; j++) { |
||
6517 | tp2 = tp1; |
||
6518 | if (pB2->max.v[j] == tp2.v[j]) { |
||
6519 | tp2.v[j] = pB2->min.v[j]; |
||
6520 | } else { |
||
6521 | tp2.v[j] = pB2->max.v[j]; |
||
6522 | } |
||
6523 | |||
6524 | BrMatrix34ApplyP(&p1, &tp1, pM21); |
||
6525 | BrMatrix34ApplyP(&p2, &tp2, pM21); |
||
6526 | plane1 = LineBoxColl(&p1, &p2, pB1, &hp1); |
||
6527 | if (plane1 == 0) { |
||
6528 | continue; |
||
6529 | } |
||
6530 | plane2 = LineBoxColl(&p2, &p1, pB1, &hp2); |
||
6531 | if (plane1 == 8 || plane2 == 8 || plane2 == 0) { |
||
6532 | continue; |
||
6533 | } |
||
6534 | BrVector3Add(&p1, &hp1, &hp2); |
||
6535 | BrVector3Scale(&p1, &p1, 0.5f); |
||
6536 | BrMatrix34ApplyP(&tp3, &p1, pM12); |
||
6537 | BrMatrix34ApplyP(&p2, &tp3, pMo21); |
||
6538 | plane3 = LineBoxColl(&p2, &p1, pB1, &hp3); |
||
6539 | // if (plane3 != 8 && plane3 != 0) { |
||
6540 | // goto LABEL_25; |
||
6541 | // } |
||
6542 | if (plane3 == 8 || plane3 == 0) { |
||
6543 | BrVector3Sub(&tp3, &p2, &p1); |
||
6544 | ts = BrVector3Length(&tp3); |
||
6545 | ts = ts / 0.01f; |
||
6546 | if (ts == 0.0f) { |
||
6547 | continue; |
||
6548 | } |
||
6549 | BrVector3InvScale(&tp3, &tp3, ts); |
||
6550 | BrVector3Accumulate(&p2, &tp3); |
||
6551 | plane3 = LineBoxColl(&p2, &p1, pB1, &hp3); |
||
6552 | if (plane3 == 8) { |
||
6553 | continue; |
||
6554 | } |
||
6555 | } |
||
6556 | if (plane3 == 0) { |
||
6557 | continue; |
||
6558 | } |
||
6559 | |||
6560 | BrMatrix34ApplyP(&shp1, &hp1, pM12); |
||
6561 | BrMatrix34ApplyP(&shp2, &hp2, pM12); |
||
6562 | if ((plane1 ^ plane2) != 4 && (plane3 == plane1 || plane3 == plane2)) { |
||
6563 | if (n >= pMax) { |
||
6564 | return n; |
||
6565 | } |
||
6566 | GetBoundsEdge(&pPoint_list[2 * n], &edge, pB1, plane1, plane2, &p2, &hp1, &hp2, 0); |
||
6567 | BrVector3Accumulate(&shp1, &shp2); |
||
6568 | BrVector3Scale(&pPoint_list[2 * n + 1], &shp1, 0.5f); |
||
6569 | BrVector3Sub(&p1, &hp1, &hp2); |
||
6570 | BrVector3Cross(&p2, &edge, &p1); |
||
6571 | BrVector3Normalise(&p2, &p2); |
||
6572 | BrVector3Add(&p1, &pB1->max, &pB1->min); |
||
6573 | BrVector3Scale(&p1, &p1, 0.5f); |
||
6574 | BrVector3Sub(&p1, &pPoint_list[2 * n], &p1); |
||
6575 | if (BrVector3Dot(&p1, &p2) > 0.0) { |
||
6576 | BrVector3Negate(&p2, &p2); |
||
6577 | } |
||
6578 | BrMatrix34ApplyV(&p1, &p2, pM12); |
||
6579 | BrMatrix34TApplyV(&pNorm_list[2 * n], &p1, pMo12); |
||
6580 | BrMatrix34TApplyV(&pNorm_list[2 * n + 1], &p2, pMo21); |
||
6581 | BrVector3Negate(&pNorm_list[2 * n + 1], &pNorm_list[2 * n + 1]); |
||
6582 | n++; |
||
6583 | } else if ((plane1 ^ plane2) == 4) { |
||
6584 | if (pMax - 1 <= n) { |
||
6585 | return n; |
||
6586 | } |
||
6587 | GetBoundsEdge(&pPoint_list[2 * n], &edge, pB1, plane1, plane3, &p2, &hp1, &hp2, 0); |
||
6588 | GetBoundsEdge(&pPoint_list[2 * n + 2], &edge, pB1, plane2, plane3, &p2, &hp1, &hp2, 0); |
||
6589 | pPoint_list[2 * n + 1] = shp1; |
||
6590 | pPoint_list[2 * n + 3] = shp2; |
||
6591 | BrVector3Sub(&p1, &hp1, &hp2); |
||
6592 | BrMatrix34ApplyV(&p2, &p1, pM12); |
||
6593 | BrMatrix34ApplyV(&p1, &p2, pMo21); |
||
6594 | BrVector3Cross(&p2, &edge, &p1); |
||
6595 | BrVector3Normalise(&pNorm_list[2 * n], &p2); |
||
6596 | GetPlaneNormal(&edge, plane3); |
||
6597 | if (BrVector3Dot(&pNorm_list[2 * n], &edge) < 0.0f) { |
||
6598 | BrVector3Negate(&pNorm_list[2 * n], &pNorm_list[2 * n]); |
||
6599 | } |
||
6600 | BrMatrix34ApplyV(&pNorm_list[2 * n + 1], &pNorm_list[2 * n], pMo12); |
||
6601 | BrVector3Negate(&pNorm_list[2 * n + 1], &pNorm_list[2 * n + 1]); |
||
6602 | BrMatrix34ApplyV(&tp3, &pNorm_list[2 * n], pM12); |
||
6603 | BrMatrix34ApplyV(&pNorm_list[2 * n], &tp3, pMo21); |
||
6604 | pNorm_list[2 * n + 2] = pNorm_list[2 * n]; |
||
6605 | pNorm_list[2 * n + 3] = pNorm_list[2 * n + 1]; |
||
6606 | n += 2; |
||
6607 | } else { |
||
6608 | if (pMax - 1 <= n) { |
||
6609 | return n; |
||
6610 | } |
||
6611 | GetBoundsEdge(&pPoint_list[2 * n], &edge, pB1, plane1, plane3, &p2, &hp1, &hp2, 0); |
||
6612 | GetBoundsEdge(&pPoint_list[2 * n + 2], &edge, pB1, plane2, plane3, &p2, &hp1, &hp2, 0); |
||
6613 | BrMatrix34ApplyP(&pPoint_list[2 * n + 1], &hp1, pM12); |
||
6614 | BrMatrix34ApplyP(&pPoint_list[2 * n + 3], &hp2, pM12); |
||
6615 | GetPlaneNormal(&pNorm_list[2 * n], plane3); |
||
6616 | BrMatrix34ApplyV(&pNorm_list[2 * n + 2], &pNorm_list[2 * n], pM1o1); |
||
6617 | BrMatrix34ApplyV(&pNorm_list[2 * n + 1], &pNorm_list[2 * n + 2], pMo12); |
||
6618 | pNorm_list[2 * n] = pNorm_list[2 * n + 2]; |
||
6619 | BrVector3Negate(&pNorm_list[2 * n + 1], &pNorm_list[2 * n + 1]); |
||
6620 | pNorm_list[2 * n + 3] = pNorm_list[2 * n + 1]; |
||
6621 | n += 2; |
||
6622 | } |
||
6623 | } |
||
6624 | } |
||
6625 | return n; |
||
6626 | } |
||
6627 | |||
6628 | // 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) |
||
6629 | 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) { |
||
6630 | int k; |
||
6631 | int i; |
||
6632 | int j; |
||
6633 | int l; |
||
6634 | int plane; |
||
6635 | br_vector3 a; |
||
6636 | br_vector3 a1; |
||
6637 | br_vector3 aa; |
||
6638 | br_vector3 bb; |
||
6639 | br_vector3 norm; |
||
6640 | br_vector3 hp; |
||
6641 | br_vector3 centre; |
||
6642 | br_scalar dist; |
||
6643 | br_bounds* pStat_box; |
||
6644 | //br_bounds* pMove_box; // Pierre-Marie Baty -- unused variable |
||
6645 | LOG_TRACE("(%p, %p, %p, %p, %p, %p, %p, %d, %d)", car1, car2, pMms, pMoms, pMsos, pPoint_list, pNorm_list, pMax, order); |
||
6646 | |||
6647 | k = 0; |
||
6648 | pStat_box = &car2->bounds[1]; |
||
6649 | BrVector3Add(¢re, &car2->bounds[1].max, &car2->bounds[1].min); |
||
6650 | BrVector3InvScale(¢re, ¢re, 2.0f); |
||
6651 | for (i = 0; i < car2->extra_point_num + 8; i++) { |
||
6652 | if (i >= 8) { |
||
6653 | a = car2->extra_points[i - 8]; |
||
6654 | } else { |
||
6655 | a.v[0] = ((i & 2) == 0) * pStat_box->min.v[0] + ((i & 2) >> 1) * pStat_box->max.v[0]; |
||
6656 | a.v[1] = ((i & 1) == 0) * pStat_box->min.v[1] + (i & 1) * pStat_box->max.v[1]; |
||
6657 | a.v[2] = ((i & 4) == 0) * pStat_box->max.v[2] + ((i & 4) >> 2) * pStat_box->min.v[2]; |
||
6658 | } |
||
6659 | BrMatrix34ApplyP(&aa, &a, pMms); |
||
6660 | BrMatrix34ApplyP(&bb, &a, pMoms); |
||
6661 | BrVector3Sub(&aa, &aa, &bb); |
||
6662 | dist = BrVector3Length(&aa); |
||
6663 | if (dist >= 0.00001f) { |
||
6664 | BrVector3Scale(&a1, &aa, (0.05f / WORLD_SCALE) / dist); // 0.0072463769 * 6.9 = 0.05 |
||
6665 | BrVector3Accumulate(&aa, &a1); |
||
6666 | BrVector3Accumulate(&aa, &bb); |
||
6667 | plane = LineBoxCollWithSphere(&bb, &aa, &car1->bounds[1], &hp); |
||
6668 | if ((plane & 7) != 0) { |
||
6669 | GetPlaneNormal(&norm, plane); |
||
6670 | |||
6671 | j = 2 * k + order; |
||
6672 | l = 2 * k + (order == 0); |
||
6673 | BrMatrix34ApplyV(&pNorm_list[j], &norm, pMsos); |
||
6674 | BrMatrix34TApplyV(&pNorm_list[l], &pNorm_list[j], pMoms); |
||
6675 | BrVector3Negate(&pNorm_list[l], &pNorm_list[l]); |
||
6676 | 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]) |
||
6677 | || !TestOldMats(car1, car2, 0)) { |
||
6678 | pPoint_list[l] = a; |
||
6679 | pPoint_list[j] = hp; |
||
6680 | k++; |
||
6681 | if (pMax == k) { |
||
6682 | return k; |
||
6683 | } |
||
6684 | } |
||
6685 | } |
||
6686 | } |
||
6687 | } |
||
6688 | return k; |
||
6689 | } |
||
6690 | |||
6691 | // IDA: void __usercall MungeCarsMass(tCollision_info *pCar@<EAX>, br_scalar pFactor) |
||
6692 | void MungeCarsMass(tCollision_info* pCar, br_scalar pFactor) { |
||
6693 | LOG_TRACE("(%p, %f)", pCar, pFactor); |
||
6694 | |||
6695 | pCar->M = pCar->M * pFactor; |
||
6696 | BrVector3Scale(&pCar->I, &pCar->I, pFactor); |
||
6697 | } |
||
6698 | |||
6699 | // IDA: void __usercall ModifyCarsMass(tCollision_info *pCar_1@<EAX>, tCollision_info *pCar_2@<EDX>) |
||
6700 | void ModifyCarsMass(tCollision_info* pCar_1, tCollision_info* pCar_2) { |
||
6701 | LOG_TRACE("(%p, %p)", pCar_1, pCar_2); |
||
6702 | |||
6703 | if (pCar_1->driver > eDriver_non_car && ((tCar_spec*)pCar_1)->collision_mass_multiplier != 1.0f) { |
||
6704 | MungeCarsMass(pCar_1, ((tCar_spec*)pCar_1)->collision_mass_multiplier); |
||
6705 | } |
||
6706 | if (pCar_2->driver > eDriver_non_car && ((tCar_spec*)pCar_2)->collision_mass_multiplier != 1.0f) { |
||
6707 | MungeCarsMass(pCar_2, ((tCar_spec*)pCar_2)->collision_mass_multiplier); |
||
6708 | } |
||
6709 | } |
||
6710 | |||
6711 | // IDA: void __usercall ResetCarsMass(tCollision_info *pCar_1@<EAX>, tCollision_info *pCar_2@<EDX>) |
||
6712 | void ResetCarsMass(tCollision_info* pCar_1, tCollision_info* pCar_2) { |
||
6713 | LOG_TRACE("(%p, %p)", pCar_1, pCar_2); |
||
6714 | |||
6715 | if (pCar_1->driver > eDriver_non_car && ((tCar_spec*)pCar_1)->collision_mass_multiplier != 1.0f) { |
||
6716 | MungeCarsMass(pCar_1, 1.0f / ((tCar_spec*)pCar_1)->collision_mass_multiplier); |
||
6717 | } |
||
6718 | if (pCar_2->driver > eDriver_non_car && ((tCar_spec*)pCar_2)->collision_mass_multiplier != 1.0f) { |
||
6719 | MungeCarsMass(pCar_2, 1.0f / ((tCar_spec*)pCar_2)->collision_mass_multiplier); |
||
6720 | } |
||
6721 | } |
||
6722 | |||
6723 | // 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) |
||
6724 | int DoCollide(tCollision_info* car1, tCollision_info* car2, br_vector3* r, br_vector3* n, int k, int pPass, br_matrix34* mat1_to_mat2) { |
||
6725 | br_matrix34* mat1; |
||
6726 | br_matrix34* mat2; |
||
6727 | br_matrix34* oldmat1; |
||
6728 | br_matrix34* oldmat2; |
||
6729 | br_matrix4 M; |
||
6730 | br_vector3 tau1[8]; |
||
6731 | br_vector3 a; |
||
6732 | br_vector3 norm; |
||
6733 | br_vector3 f1; |
||
6734 | br_vector3 f2; |
||
6735 | br_vector3 pos1; |
||
6736 | br_vector3 pos2; |
||
6737 | br_vector3 max_friction; |
||
6738 | br_vector3 tv; |
||
6739 | br_vector3 tv2; |
||
6740 | br_vector3* tau2; |
||
6741 | br_vector3 torque1; |
||
6742 | br_vector3 torque2; |
||
6743 | br_scalar f[4]; |
||
6744 | br_scalar d[4]; |
||
6745 | br_scalar ts; |
||
6746 | br_scalar tforce; |
||
6747 | int i; |
||
6748 | int j; |
||
6749 | int car1_point; |
||
6750 | int car2_point; |
||
6751 | int plane; |
||
6752 | int move_car1; |
||
6753 | int move_car2; |
||
6754 | //br_vector3 a2; // Pierre-Marie Baty -- unused variable |
||
6755 | br_vector3 f12; |
||
6756 | br_vector3 f22; |
||
6757 | br_vector3 point_vel1; |
||
6758 | br_vector3 point_vel2; |
||
6759 | //br_scalar fudge_multiplier; // Pierre-Marie Baty -- unused variable |
||
6760 | br_scalar factor; |
||
6761 | int need_to_fudge; |
||
6762 | LOG_TRACE("(%p, %p, %p, %p, %d, %d, %p)", car1, car2, r, n, k, pPass, mat1_to_mat2); |
||
6763 | |||
6764 | mat1 = &car1->car_master_actor->t.t.mat; |
||
6765 | mat2 = &car2->car_master_actor->t.t.mat; |
||
6766 | oldmat1 = &car1->oldmat; |
||
6767 | oldmat2 = &car2->oldmat; |
||
6768 | tau2 = &tau1[4]; |
||
6769 | move_car1 = !car1->infinite_mass && car1->min_torque_squared == 0.0f; |
||
6770 | move_car2 = !car2->infinite_mass && car2->min_torque_squared == 0.0f; |
||
6771 | if (k > 4) { |
||
6772 | k = 4; |
||
6773 | } |
||
6774 | BrMatrix34Copy(mat1, oldmat1); |
||
6775 | BrMatrix34Copy(mat2, oldmat2); |
||
6776 | BrVector3Copy(&car1->omega, &car1->oldomega); |
||
6777 | BrVector3Copy(&car2->omega, &car2->oldomega); |
||
6778 | BrMatrix34TApplyV(&car1->velocity_car_space, &car1->v, mat1); |
||
6779 | BrMatrix34TApplyV(&car2->velocity_car_space, &car2->v, mat2); |
||
6780 | need_to_fudge = 1; |
||
6781 | for (i = 0; i < k; ++i) { |
||
6782 | BrVector3Cross(&tau1[i], &r[2 * i], &n[2 * i]); |
||
6783 | BrVector3Cross(&tau2[i], &r[2 * i + 1], &n[2 * i + 1]); |
||
6784 | Vector3Div(&tau1[i], &tau1[i], &car1->I); |
||
6785 | Vector3Div(&tau2[i], &tau2[i], &car2->I); |
||
6786 | BrVector3Cross(&tv, &car1->omega, &r[2 * i]); |
||
6787 | BrVector3Accumulate(&tv, &car1->velocity_car_space); |
||
6788 | d[i] = -BrVector3Dot(&n[2 * i], &tv); |
||
6789 | BrVector3Cross(&tv, &car2->omega, &r[2 * i + 1]); |
||
6790 | BrVector3Accumulate(&tv, &car2->velocity_car_space); |
||
6791 | d[i] -= BrVector3Dot(&n[2 * i + 1], &tv); |
||
6792 | if (d[i] > 0.0f) { |
||
6793 | need_to_fudge = 0; |
||
6794 | } |
||
6795 | } |
||
6796 | if (need_to_fudge) { |
||
6797 | d[0] = 0.5f; |
||
6798 | } |
||
6799 | factor = 0.0f; |
||
6800 | if (move_car1) { |
||
6801 | factor = car1->M + factor; |
||
6802 | } |
||
6803 | if (move_car2) { |
||
6804 | factor = car2->M + factor; |
||
6805 | } |
||
6806 | for (i = 0; i < k; i++) { |
||
6807 | for (j = 0; j < k; j++) { |
||
6808 | if (move_car1) { |
||
6809 | BrVector3Cross(&tv, &tau1[j], &r[2 * i]); |
||
6810 | BrVector3InvScale(&norm, &n[2 * j], car1->M); |
||
6811 | BrVector3Accumulate(&tv, &norm); |
||
6812 | M.m[i][j] = BrVector3Dot(&n[2 * i], &tv); |
||
6813 | } else { |
||
6814 | M.m[i][j] = 0.0f; |
||
6815 | } |
||
6816 | if (move_car2) { |
||
6817 | BrVector3Cross(&tv, &tau2[j], &r[2 * i + 1]); |
||
6818 | BrVector3InvScale(&norm, &n[2 * j + 1], car2->M); |
||
6819 | BrVector3Accumulate(&tv, &norm); |
||
6820 | M.m[i][j] += BrVector3Dot(&n[2 * i + 1], &tv); |
||
6821 | } |
||
6822 | M.m[i][j] *= factor; |
||
6823 | } |
||
6824 | } |
||
6825 | switch (k) { |
||
6826 | case 1: |
||
6827 | ts = SinglePointColl(f, &M, d); |
||
6828 | break; |
||
6829 | case 2: |
||
6830 | ts = TwoPointCollB(f, &M, d, tau1, n); |
||
6831 | break; |
||
6832 | case 3: |
||
6833 | d[3] = 0.f; |
||
6834 | ts = ThreePointCollRecB(f, &M, d, tau1, n); |
||
6835 | break; |
||
6836 | case 4: |
||
6837 | ts = FourPointCollB(f, &M, d, tau1, n); |
||
6838 | break; |
||
6839 | default: |
||
6840 | ts = 0; |
||
6841 | break; |
||
6842 | } |
||
6843 | if (k > 3) { |
||
6844 | k = 3; |
||
6845 | } |
||
6846 | if (fabsf(ts) <= 0.000001f) { |
||
6847 | return 0; |
||
6848 | } |
||
6849 | BrVector3SetFloat(&f1, 0.0f, 0.0f, 0.0f); |
||
6850 | BrVector3SetFloat(&f2, 0.0f, 0.0f, 0.0f); |
||
6851 | BrVector3SetFloat(&pos1, 0.0f, 0.0f, 0.0f); |
||
6852 | BrVector3SetFloat(&pos2, 0.0f, 0.0f, 0.0f); |
||
6853 | BrVector3SetFloat(&torque1, 0.0f, 0.0f, 0.0f); |
||
6854 | BrVector3SetFloat(&torque2, 0.0f, 0.0f, 0.0f); |
||
6855 | tforce = 0.0f; |
||
6856 | car1_point = -1; |
||
6857 | car2_point = -1; |
||
6858 | for (i = 0; i < k; i++) { |
||
6859 | f[i] = f[i] * factor; |
||
6860 | if (f[i] == 0.0f && k != 0) { |
||
6861 | break; |
||
6862 | } |
||
6863 | if (f[i] < 0.001f) { |
||
6864 | f[i] = 0.001f; |
||
6865 | } |
||
6866 | if (f[i] > 10.0f) { |
||
6867 | ts = 0.0f; |
||
6868 | } |
||
6869 | f[i] += 0.1f; |
||
6870 | BrVector3Scale(&tau1[i], &tau1[i], f[i]); |
||
6871 | BrVector3Scale(&tau2[i], &tau2[i], f[i]); |
||
6872 | BrVector3Accumulate(&torque1, &tau1[i]); |
||
6873 | BrVector3Accumulate(&torque2, &tau2[i]); |
||
6874 | if (!pPass && Vector3IsZero(&n[2 * i])) { |
||
6875 | car2_point = i; |
||
6876 | } else if (!pPass && Vector3IsZero(&n[2 * i + 1])) { |
||
6877 | car1_point = i; |
||
6878 | } else { |
||
6879 | ts = f[i] / car1->M; |
||
6880 | BrVector3Scale(&tv2, &n[2 * i], ts); |
||
6881 | BrVector3Accumulate(&f1, &tv2); |
||
6882 | ts = f[i] / car2->M; |
||
6883 | BrVector3Scale(&tv2, &n[2 * i + 1], ts); |
||
6884 | BrVector3Accumulate(&f2, &tv2); |
||
6885 | BrVector3Scale(&tv2, &r[2 * i], f[i]); |
||
6886 | BrVector3Accumulate(&pos1, &tv2); |
||
6887 | BrVector3Scale(&tv2, &r[2 * i + 1], f[i]); |
||
6888 | BrVector3Accumulate(&pos2, &tv2); |
||
6889 | tforce += f[i]; |
||
6890 | } |
||
6891 | } |
||
6892 | if (car1->min_torque_squared != 0.0f && !car1->infinite_mass && BrVector3LengthSquared(&torque1) > car1->min_torque_squared) { |
||
6893 | BrVector3Scale(&car1->omega, &car1->omega, gDt); |
||
6894 | car1->omega.v[0] += torque1.v[0] * 0.04f; |
||
6895 | car1->omega.v[2] += torque1.v[2] * 0.04f; |
||
6896 | if (BrVector3LengthSquared(&car1->omega) > car1->break_off_radians_squared) { |
||
6897 | car1->min_torque_squared = 0.0f; |
||
6898 | return 1; |
||
6899 | } |
||
6900 | BrVector3InvScale(&car1->omega, &car1->omega, gDt); |
||
6901 | } |
||
6902 | if (car2->min_torque_squared != 0.0f && !car2->infinite_mass && BrVector3LengthSquared(&torque2) > car2->min_torque_squared) { |
||
6903 | BrVector3Scale(&car2->omega, &car2->omega, gDt); |
||
6904 | car2->omega.v[0] += torque2.v[0] * 0.04f; |
||
6905 | car2->omega.v[2] += torque2.v[2] * 0.04f; |
||
6906 | if (BrVector3LengthSquared(&car2->omega) > car2->break_off_radians_squared) { |
||
6907 | car2->min_torque_squared = 0.0f; |
||
6908 | return 1; |
||
6909 | } |
||
6910 | BrVector3InvScale(&car2->omega, &car2->omega, gDt); |
||
6911 | } |
||
6912 | if (move_car1) { |
||
6913 | BrVector3Accumulate(&car1->omega, &torque1); |
||
6914 | } |
||
6915 | if (move_car2) { |
||
6916 | BrVector3Accumulate(&car2->omega, &torque2); |
||
6917 | } |
||
6918 | BrVector3InvScale(&pos1, &pos1, tforce); |
||
6919 | BrVector3InvScale(&pos2, &pos2, tforce); |
||
6920 | if (pPass == 0) { |
||
6921 | if (car1_point >= 0 && move_car1) { |
||
6922 | f[car1_point] = f[car1_point] / car1->M; |
||
6923 | BrVector3Scale(&n[2 * car1_point], &n[2 * car1_point], f[car1_point]); |
||
6924 | BrVector3Cross(&tv2, &car1->oldomega, &r[2 * car1_point]); |
||
6925 | BrVector3Accumulate(&tv2, &car1->velocity_car_space); |
||
6926 | ts = BrVector3Length(&tv2); |
||
6927 | if (ts > 0.0001f && (car1->driver <= eDriver_non_car || !CAR(car1)->wall_climber_mode)) { |
||
6928 | AddFriction(car1, &tv2, &n[2 * car1_point], &r[2 * car1_point], f[car1_point], &max_friction); |
||
6929 | BrVector3Accumulate(&n[2 * car1_point], &max_friction); |
||
6930 | } |
||
6931 | BrMatrix34ApplyV(&tv, &n[2 * car1_point], mat1); |
||
6932 | BrVector3Accumulate(&car1->v, &tv); |
||
6933 | } |
||
6934 | if (car2_point >= 0 && move_car2) { |
||
6935 | f[car2_point] = f[car2_point] / car2->M; |
||
6936 | BrVector3Scale(&n[2 * car2_point + 1], &n[2 * car2_point + 1], f[car2_point]); |
||
6937 | BrVector3Cross(&tv2, &car2->oldomega, &r[2 * car2_point + 1]); |
||
6938 | BrVector3Accumulate(&tv2, &car2->velocity_car_space); |
||
6939 | ts = BrVector3Length(&tv2); |
||
6940 | |||
6941 | if (ts > 0.0001f && (car1->driver <= eDriver_non_car || !(CAR(car1)->wall_climber_mode))) { |
||
6942 | AddFriction(car2, &tv2, &n[2 * car2_point + 1], &r[2 * car2_point + 1], f[car2_point], &max_friction); |
||
6943 | BrVector3Accumulate(&n[2 * car2_point + 1], &max_friction); |
||
6944 | } |
||
6945 | BrMatrix34ApplyV(&tv, &n[2 * car2_point + 1], mat2); |
||
6946 | BrVector3Accumulate(&car2->v, &tv); |
||
6947 | } |
||
6948 | if (tforce != 0.0f) { |
||
6949 | BrVector3Cross(&point_vel1, &car1->oldomega, &pos1); |
||
6950 | BrVector3Sub(&a, &car1->v, &car2->v); |
||
6951 | BrMatrix34TApplyV(&tv2, &a, mat1); |
||
6952 | BrVector3Accumulate(&point_vel1, &tv2); |
||
6953 | BrVector3Cross(&point_vel2, &car2->oldomega, &pos2); |
||
6954 | AddFrictionCarToCar(car1, car2, &point_vel1, &point_vel2, &f1, &pos1, &pos2, tforce, &max_friction); |
||
6955 | if (TestForNan(max_friction.v) || TestForNan(&max_friction.v[1]) || TestForNan(&max_friction.v[2])) { |
||
6956 | BrVector3SetFloat(&max_friction, 0.0f, 0.0f, 0.0f); |
||
6957 | } |
||
6958 | BrVector3InvScale(&tv2, &max_friction, car1->M); |
||
6959 | BrVector3Accumulate(&f1, &tv2); |
||
6960 | BrMatrix34ApplyV(&tv2, &max_friction, mat1); |
||
6961 | BrMatrix34TApplyV(&max_friction, &tv2, mat2); |
||
6962 | BrVector3InvScale(&tv2, &max_friction, car2->M); |
||
6963 | BrVector3Accumulate(&f2, &tv2); |
||
6964 | } |
||
6965 | } |
||
6966 | if (tforce == 0.0f) { |
||
6967 | return 0; |
||
6968 | } |
||
6969 | BrMatrix34ApplyV(&tv, &f1, mat1); |
||
6970 | if (move_car1) { |
||
6971 | BrVector3Accumulate(&car1->v, &tv); |
||
6972 | } |
||
6973 | CrushAndDamageCar(CAR(car1), &pos1, &f1, CAR(car2)); |
||
6974 | if ((car1->infinite_mass & 0x100) != 0) { |
||
6975 | BrVector3Sub(&tv2, &car1->cmpos, &pos1); |
||
6976 | BrVector3Accumulate(&tv2, &car1->cmpos); |
||
6977 | ts = BrVector3Length(&f1); |
||
6978 | if (ts > 0.0001f) { |
||
6979 | ts = 5.0f / ts; |
||
6980 | BrVector3Scale(&a, &f1, ts); |
||
6981 | BrVector3Accumulate(&tv2, &a); |
||
6982 | plane = LineBoxColl(&tv2, &pos1, &car1->bounds[1], &a); |
||
6983 | if (plane) { |
||
6984 | BrVector3Negate(&f12, &f1); |
||
6985 | CrushAndDamageCar(CAR(car1), &a, &f12, CAR(car2)); |
||
6986 | } |
||
6987 | } |
||
6988 | } |
||
6989 | BrMatrix34ApplyV(&tv, &f2, mat2); |
||
6990 | if (move_car2) { |
||
6991 | BrVector3Accumulate(&car2->v, &tv); |
||
6992 | } |
||
6993 | CrushAndDamageCar(CAR(car2), &pos2, &f2, CAR(car1)); |
||
6994 | if ((car2->infinite_mass & 0x100) != 0) { |
||
6995 | BrVector3Sub(&tv2, &car2->cmpos, &pos2); |
||
6996 | BrVector3Accumulate(&tv2, &car2->cmpos); |
||
6997 | ts = BrVector3Length(&f2); |
||
6998 | if (ts > 0.0001f) { |
||
6999 | ts = 5.0f / ts; |
||
7000 | BrVector3Scale(&a, &f2, ts); |
||
7001 | BrVector3Accumulate(&tv2, &a); |
||
7002 | plane = LineBoxColl(&tv2, &pos2, &car2->bounds[1], &a); |
||
7003 | if (plane) { |
||
7004 | BrVector3Negate(&f22, &f2); |
||
7005 | CrushAndDamageCar(CAR(car2), &a, &f22, CAR(car1)); |
||
7006 | } |
||
7007 | } |
||
7008 | } |
||
7009 | BrMatrix34ApplyP(&tv2, &pos1, mat1); |
||
7010 | BrVector3InvScale(&tv2, &tv2, WORLD_SCALE); |
||
7011 | BrVector3Scale(&f1, &f1, 5.0f); |
||
7012 | CrashNoise(&f1, &tv2, 0); |
||
7013 | BrVector3Add(&a, &car2->v, &car1->v); |
||
7014 | BrVector3Scale(&a, &a, 0.25f / WORLD_SCALE); |
||
7015 | BrVector3Scale(&tv, &tv, car2->M * 3.0f); |
||
7016 | CreateSparkShower(&tv2, &a, &tv, CAR(car1), CAR(car2)); |
||
7017 | return 0; |
||
7018 | } |
||
7019 | |||
7020 | // 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) |
||
7021 | br_scalar TwoPointCollB(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n) { |
||
7022 | br_scalar ts; |
||
7023 | LOG_TRACE("(%p, %p, %p, %p, %p)", f, m, d, tau, n); |
||
7024 | |||
7025 | ts = m->m[1][1] * m->m[0][0] - m->m[0][1] * m->m[1][0]; |
||
7026 | if (fabsf(ts) > 0.000001f) { |
||
7027 | f[0] = (m->m[1][1] * d[0] - m->m[0][1] * d[1]) / ts; |
||
7028 | f[1] = (m->m[1][0] * d[0] - m->m[0][0] * d[1]) / -ts; |
||
7029 | } |
||
7030 | if (f[1] < 0.0f) { |
||
7031 | ts = SinglePointColl(f, m, d); |
||
7032 | f[1] = 0.f; |
||
7033 | } else if (f[0] < 0.f) { |
||
7034 | m->m[0][0] = m->m[1][1]; |
||
7035 | BrVector3Copy(&tau[0], &tau[1]); |
||
7036 | BrVector3Copy(&tau[4], &tau[5]); |
||
7037 | BrVector3Copy(&n[0], &n[2]); |
||
7038 | BrVector3Copy(&n[1], &n[3]); |
||
7039 | d[0] = d[1]; |
||
7040 | ts = SinglePointColl(f, m, d); |
||
7041 | f[1] = 0.0f; |
||
7042 | } |
||
7043 | return ts; |
||
7044 | } |
||
7045 | |||
7046 | // 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) |
||
7047 | br_scalar ThreePointCollRecB(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n) { |
||
7048 | int i; |
||
7049 | int j; |
||
7050 | br_scalar ts; |
||
7051 | LOG_TRACE("(%p, %p, %p, %p, %p)", f, m, d, tau, n); |
||
7052 | |||
7053 | ts = ThreePointColl(f, m, d); |
||
7054 | if (f[0] >= 0.0f && f[1] >= 0.0f && f[2] >= 0.0f) { |
||
7055 | return ts; |
||
7056 | } |
||
7057 | if (f[2] < 0.f) { |
||
7058 | i = 0; |
||
7059 | j = 1; |
||
7060 | } else if (f[1] < 0.f) { |
||
7061 | i = 0; |
||
7062 | j = 2; |
||
7063 | } else if (f[0] < 0.f) { |
||
7064 | i = 1; |
||
7065 | j = 2; |
||
7066 | } else { |
||
7067 | return 0.0f; |
||
7068 | } |
||
7069 | m->m[0][0] = ((br_scalar*)(m->m))[5 * i]; |
||
7070 | m->m[1][0] = m->m[j][i]; |
||
7071 | m->m[0][1] = m->m[i][j]; |
||
7072 | m->m[1][1] = ((br_scalar*)(m->m))[5 * j]; |
||
7073 | BrVector3Copy(&tau[0], &tau[i]); |
||
7074 | BrVector3Copy(&tau[1], &tau[j]); |
||
7075 | BrVector3Copy(&tau[4], &tau[i + 4]); |
||
7076 | BrVector3Copy(&tau[5], &tau[j + 4]); |
||
7077 | BrVector3Copy(&n[0], &n[2 * i]); |
||
7078 | BrVector3Copy(&n[2], &n[2 * j]); |
||
7079 | BrVector3Copy(&n[1], &n[2 * i + 1]); |
||
7080 | BrVector3Copy(&n[3], &n[2 * j + 1]); |
||
7081 | d[0] = d[i]; |
||
7082 | d[1] = d[j]; |
||
7083 | ts = TwoPointCollB(f, m, d, tau, n); |
||
7084 | f[2] = 0.0; |
||
7085 | return ts; |
||
7086 | } |
||
7087 | |||
7088 | // 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) |
||
7089 | br_scalar FourPointCollB(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n) { |
||
7090 | int i; |
||
7091 | int j; |
||
7092 | int l; |
||
7093 | br_scalar ts; |
||
7094 | LOG_TRACE("(%p, %p, %p, %p, %p)", f, m, d, tau, n); |
||
7095 | |||
7096 | ts = ThreePointColl(f, m, d); |
||
7097 | if (f[0] >= 0.0f && f[1] >= 0.0f && f[2] >= 0.0f) { |
||
7098 | return ts; |
||
7099 | } |
||
7100 | if (f[0] < 0.0f) { |
||
7101 | l = 0; |
||
7102 | } else if (f[1] < 0.0f) { |
||
7103 | l = 1; |
||
7104 | } else { |
||
7105 | l = 2; |
||
7106 | } |
||
7107 | for (i = l; i < 3; i++) { |
||
7108 | for (j = 0; j < 4; j++) { |
||
7109 | m->m[i][j] = m->m[i + 1][j]; |
||
7110 | } |
||
7111 | d[i] = d[i + 1]; |
||
7112 | tau[i] = tau[i + 1]; |
||
7113 | tau[i + 4] = tau[i + 5]; |
||
7114 | n[2 * i] = n[2 * i + 2]; |
||
7115 | n[2 * i + 1] = n[2 * i + 3]; |
||
7116 | d[i] = d[i + 1]; |
||
7117 | } |
||
7118 | for (i = l; i < 3; i++) { |
||
7119 | for (j = 0; j < 3; j++) { |
||
7120 | m->m[j][i] = m->m[j][i + 1]; |
||
7121 | } |
||
7122 | } |
||
7123 | return ThreePointCollRecB(f, m, d, tau, n); |
||
7124 | } |
||
7125 | |||
7126 | // IDA: int __usercall TestForNan@<EAX>(float *f@<EAX>) |
||
7127 | int TestForNan(float* f) { |
||
7128 | //tU32 i; // Pierre-Marie Baty -- unused variable |
||
7129 | LOG_TRACE("(%p)", f); |
||
7130 | // i = *f; |
||
7131 | // LOG_DEBUG("i %x", i); |
||
7132 | return isnan(*f); |
||
7133 | // return (~i & 0x7F800000) == 0; |
||
7134 | } |
||
7135 | |||
7136 | // IDA: void __cdecl CheckCameraHither() |
||
7137 | void CheckCameraHither(void) { |
||
7138 | br_camera* cam; |
||
7139 | static int old_hither; |
||
7140 | LOG_TRACE("()"); |
||
7141 | |||
7142 | cam = (br_camera*)gCamera->type_data; |
||
7143 | if (TestForNan(&cam->hither_z)) { |
||
7144 | cam->hither_z = (float)old_hither; |
||
7145 | } |
||
7146 | old_hither = (int)cam->hither_z; |
||
7147 | } |
||
7148 | |||
7149 | // 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) |
||
7150 | 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) { |
||
7151 | br_scalar front_give; |
||
7152 | br_scalar rear_give; |
||
7153 | br_scalar damping; |
||
7154 | br_scalar ratio; |
||
7155 | //int i; // Pierre-Marie Baty -- unused variable |
||
7156 | LOG_TRACE("(%p, %f, %f, %f, %f, %f)", pCar, pFront_give_factor, pRear_give_factor, pDamping_factor, pExtra_front_height, pExtra_rear_height); |
||
7157 | |||
7158 | #define UNK_SUSPENION_FACTOR 5.0f |
||
7159 | |||
7160 | front_give = pCar->susp_give[1] * pFront_give_factor * WORLD_SCALE; |
||
7161 | rear_give = pCar->susp_give[0] * pRear_give_factor * WORLD_SCALE; |
||
7162 | damping = pCar->damping * pDamping_factor; |
||
7163 | ratio = fabsf((pCar->wpos[0].v[2] - pCar->cmpos.v[2]) / (pCar->wpos[2].v[2] - pCar->cmpos.v[2])); |
||
7164 | pCar->sk[0] = pCar->M / (ratio + 1.0f) * UNK_SUSPENION_FACTOR / rear_give; |
||
7165 | pCar->sb[0] = pCar->M / (ratio + 1.0f) * sqrtf(UNK_SUSPENION_FACTOR) / sqrt(rear_give); |
||
7166 | ratio = 1.0f / ratio; |
||
7167 | pCar->sk[1] = pCar->M / (ratio + 1.0f) * UNK_SUSPENION_FACTOR / front_give; |
||
7168 | pCar->sb[1] = pCar->M / (ratio + 1.0f) * sqrtf(UNK_SUSPENION_FACTOR) / sqrt(front_give); |
||
7169 | |||
7170 | pCar->sb[0] *= damping; |
||
7171 | pCar->sb[1] *= damping; |
||
7172 | pCar->susp_height[0] = pCar->ride_height + rear_give + pExtra_rear_height; |
||
7173 | pCar->susp_height[1] = pCar->ride_height + front_give + pExtra_front_height; |
||
7174 | |||
7175 | pCar->bounds[0].min.v[1] = -MAX(rear_give, front_give) + -MAX(pExtra_rear_height, pExtra_front_height); |
||
7176 | pCar->bounds[0].min.v[1] /= WORLD_SCALE; |
||
7177 | |||
7178 | #undef UNK_SUSPENION_FACTOR |
||
7179 | } |
||
7180 | |||
7181 | // IDA: int __usercall TestForCarInSensiblePlace@<EAX>(tCar_spec *car@<EAX>) |
||
7182 | int TestForCarInSensiblePlace(tCar_spec* car) { |
||
7183 | //br_bounds bnds; // Pierre-Marie Baty -- unused variable |
||
7184 | //br_matrix34 mat; // Pierre-Marie Baty -- unused variable |
||
7185 | br_matrix34* mat1; |
||
7186 | br_matrix34* mat2; |
||
7187 | int i; |
||
7188 | //int j; // Pierre-Marie Baty -- unused variable |
||
7189 | int k; |
||
7190 | tCollision_info* c2; |
||
7191 | tCollision_info* car_info; |
||
7192 | br_vector3 sep; |
||
7193 | br_vector3 tv; |
||
7194 | br_vector3 tv2; |
||
7195 | LOG_TRACE("(%p)", car); |
||
7196 | |||
7197 | car_info = (tCollision_info*)car; |
||
7198 | if (!gProgram_state.racing) { |
||
7199 | return 1; |
||
7200 | } |
||
7201 | mat1 = &car_info->car_master_actor->t.t.mat; |
||
7202 | if (!gDoing_physics) { |
||
7203 | BrVector3Scale((br_vector3*)mat1->m[3], (br_vector3*)mat1->m[3], WORLD_SCALE); |
||
7204 | } |
||
7205 | GetFacesInBox(car_info); |
||
7206 | BrMatrix34ApplyP(&car_info->pos, &car_info->cmpos, mat1); |
||
7207 | BrVector3InvScale(&car_info->pos, &car_info->pos, WORLD_SCALE); |
||
7208 | k = CollCheck(car_info, -2.f); |
||
7209 | if (!k) { |
||
7210 | if (gNum_active_non_cars + gNum_active_cars != gNum_cars_and_non_cars) { |
||
7211 | GetNonCars(); |
||
7212 | } |
||
7213 | for (i = 0; i < gNum_cars_and_non_cars; i++) { |
||
7214 | c2 = (tCollision_info*)gActive_car_list[i]; |
||
7215 | if (car_info != c2) { |
||
7216 | mat2 = &c2->car_master_actor->t.t.mat; |
||
7217 | BrVector3Scale((br_vector3*)mat2->m[3], (br_vector3*)mat2->m[3], WORLD_SCALE); |
||
7218 | BrVector3Sub(&sep, (br_vector3*)mat1->m[3], (br_vector3*)mat2->m[3]); |
||
7219 | if (BrVector3LengthSquared(&sep) <= 100.0) { |
||
7220 | k += TestOldMats(car_info, c2, 0); |
||
7221 | k += TestOldMats(c2, car_info, 0); |
||
7222 | } |
||
7223 | if (k != 0) { |
||
7224 | BrMatrix34ApplyP(&tv, &car_info->cmpos, mat1); |
||
7225 | BrMatrix34ApplyP(&tv2, &c2->cmpos, mat2); |
||
7226 | BrVector3Sub(&tv, &tv2, &tv); |
||
7227 | BrMatrix34TApplyV(&car_info->old_point, &tv, mat1); |
||
7228 | BrVector3Normalise(&car_info->old_norm, &car_info->old_point); |
||
7229 | BrVector3Negate(&car_info->old_norm, &car_info->old_norm); |
||
7230 | } |
||
7231 | BrVector3InvScale((br_vector3*)mat2->m[3], (br_vector3*)mat2->m[3], WORLD_SCALE); |
||
7232 | if (k != 0) { |
||
7233 | break; |
||
7234 | } |
||
7235 | } |
||
7236 | } |
||
7237 | } |
||
7238 | if (!gDoing_physics) { |
||
7239 | BrVector3InvScale((br_vector3*)mat1->m[3], (br_vector3*)mat1->m[3], WORLD_SCALE); |
||
7240 | } |
||
7241 | if (k != 0) { |
||
7242 | return 0; |
||
7243 | } else { |
||
7244 | return -1; |
||
7245 | } |
||
7246 | } |
||
7247 | |||
7248 | // IDA: int __usercall TestOldMats@<EAX>(tCollision_info *c1@<EAX>, tCollision_info *c2@<EDX>, int newmats@<EBX>) |
||
7249 | int TestOldMats(tCollision_info* c1, tCollision_info* c2, int newmats) { |
||
7250 | br_vector3 p1; |
||
7251 | br_vector3 p2; |
||
7252 | br_vector3 tp1; |
||
7253 | //br_vector3 tp2; // Pierre-Marie Baty -- unused variable |
||
7254 | //br_vector3 tp3; // Pierre-Marie Baty -- unused variable |
||
7255 | br_vector3 hp1; |
||
7256 | //br_vector3 hp2; // Pierre-Marie Baty -- unused variable |
||
7257 | //br_vector3 hp3; // Pierre-Marie Baty -- unused variable |
||
7258 | //br_vector3 shp1; // Pierre-Marie Baty -- unused variable |
||
7259 | //br_vector3 shp2; // Pierre-Marie Baty -- unused variable |
||
7260 | br_vector3 edge; |
||
7261 | //int plane1; // Pierre-Marie Baty -- unused variable |
||
7262 | //int plane2; // Pierre-Marie Baty -- unused variable |
||
7263 | //int plane3; // Pierre-Marie Baty -- unused variable |
||
7264 | //br_scalar ts; // Pierre-Marie Baty -- unused variable |
||
7265 | int i; |
||
7266 | int j; |
||
7267 | int n; |
||
7268 | br_bounds* b1; |
||
7269 | br_bounds* b2; |
||
7270 | br_matrix34 invmat1; |
||
7271 | br_matrix34 mat21; |
||
7272 | LOG_TRACE("(%p, %p, %d)", c1, c2, newmats); |
||
7273 | |||
7274 | n = 0; |
||
7275 | b1 = &c1->bounds[1]; |
||
7276 | b2 = &c2->bounds[1]; |
||
7277 | if (newmats) { |
||
7278 | BrMatrix34LPInverse(&invmat1, &c1->car_master_actor->t.t.mat); |
||
7279 | BrMatrix34Mul(&mat21, &c2->car_master_actor->t.t.mat, &invmat1); |
||
7280 | } else { |
||
7281 | BrMatrix34LPInverse(&invmat1, &c1->oldmat); |
||
7282 | BrMatrix34Mul(&mat21, &c2->oldmat, &invmat1); |
||
7283 | } |
||
7284 | for (i = 0; i < 4; i++) { |
||
7285 | if (i == 3) { |
||
7286 | BrVector3Copy(&edge, &b2->min); |
||
7287 | } else { |
||
7288 | BrVector3Copy(&edge, &b2->max); |
||
7289 | edge.v[i] = b2->min.v[i]; |
||
7290 | } |
||
7291 | for (j = 0; j < 3; j++) { |
||
7292 | BrVector3Copy(&tp1, &edge); |
||
7293 | if (b2->max.v[j] == tp1.v[j]) { |
||
7294 | tp1.v[j] = b2->min.v[j]; |
||
7295 | } else { |
||
7296 | tp1.v[j] = b2->max.v[j]; |
||
7297 | } |
||
7298 | BrMatrix34ApplyP(&p1, &edge, &mat21); |
||
7299 | BrMatrix34ApplyP(&p2, &tp1, &mat21); |
||
7300 | if (LineBoxColl(&p1, &p2, b1, &hp1)) { |
||
7301 | n++; |
||
7302 | } |
||
7303 | } |
||
7304 | } |
||
7305 | return n; |
||
7306 | } |
||
7307 | |||
7308 | // IDA: int __usercall PullActorFromWorld@<EAX>(br_actor *pActor@<EAX>) |
||
7309 | int PullActorFromWorld(br_actor* pActor) { |
||
7310 | LOG_TRACE("(%p)", pActor); |
||
7311 | |||
7312 | if (gDoing_physics) { |
||
7313 | return DoPullActorFromWorld(pActor); |
||
7314 | } |
||
7315 | return 0; |
||
7316 | } |
||
7317 | |||
7318 | // IDA: int __usercall DoPullActorFromWorld@<EAX>(br_actor *pActor@<EAX>) |
||
7319 | int DoPullActorFromWorld(br_actor* pActor) { |
||
7320 | int num; |
||
7321 | int i; |
||
7322 | tCollision_info* c; |
||
7323 | tNon_car_spec* non_car; |
||
7324 | LOG_TRACE("(%p)", pActor); |
||
7325 | |||
7326 | non_car = NULL; |
||
7327 | num = 10 * (pActor->identifier[1] - '0') + 1 * (pActor->identifier[2] - '0'); |
||
7328 | if (gNon_car_spec_list[num]) { |
||
7329 | non_car = &gProgram_state.non_cars[gNon_car_spec_list[num] + 4]; |
||
7330 | } |
||
7331 | if (non_car && non_car->collision_info.driver == eDriver_non_car) { |
||
7332 | non_car = gProgram_state.non_cars; |
||
7333 | for (i = 0; i < NONCAR_UNUSED_SLOTS; i++) { |
||
7334 | if (non_car->collision_info.driver == eDriver_non_car_unused_slot) { |
||
7335 | break; |
||
7336 | } |
||
7337 | non_car++; |
||
7338 | } |
||
7339 | if (i == NONCAR_UNUSED_SLOTS) { |
||
7340 | non_car = NULL; |
||
7341 | } else { |
||
7342 | memcpy(non_car, &gProgram_state.non_cars[gNon_car_spec_list[num] + NONCAR_UNUSED_SLOTS - 1], sizeof(tNon_car_spec)); |
||
7343 | } |
||
7344 | } |
||
7345 | if (non_car != NULL) { |
||
7346 | pActor->type_data = non_car; |
||
7347 | c = &non_car->collision_info; |
||
7348 | c->driver = eDriver_non_car; |
||
7349 | c->doing_nothing_flag = 1; |
||
7350 | BrActorRemove(pActor); |
||
7351 | BrActorAdd(gNon_track_actor, pActor); |
||
7352 | c->car_master_actor = pActor; |
||
7353 | c->car_ID = 100 * (pActor->identifier[5] - '0') + 10 * (pActor->identifier[6] - '0') + 1 * (pActor->identifier[7] - '0'); |
||
7354 | gActive_non_car_list[gNum_active_non_cars] = non_car; |
||
7355 | gNum_active_non_cars++; |
||
7356 | gActive_car_list[gNum_cars_and_non_cars] = (tCar_spec*)non_car; |
||
7357 | gNum_cars_and_non_cars++; |
||
7358 | GetNewBoundingBox(&c->bounds_world_space, c->bounds, &pActor->t.t.mat); |
||
7359 | non_car->collision_info.bounds_ws_type = eBounds_ws; |
||
7360 | InitialiseNonCar(non_car); |
||
7361 | ResetCarSpecialVolume((tCollision_info*)non_car); |
||
7362 | if (gDoing_physics) { |
||
7363 | BrVector3Scale((br_vector3*)&pActor->t.t.mat.m[3][0], (br_vector3*)&pActor->t.t.mat.m[3][0], WORLD_SCALE); |
||
7364 | } |
||
7365 | BrMatrix34Copy(&c->oldmat, &pActor->t.t.mat); |
||
7366 | if (!gDoing_physics) { |
||
7367 | BrVector3Scale((br_vector3*)&c->oldmat.m[3][0], (br_vector3*)&c->oldmat.m[3][0], WORLD_SCALE); |
||
7368 | } |
||
7369 | PipeSingleNonCar((tCollision_info*)non_car); |
||
7370 | return 1; |
||
7371 | } else { |
||
7372 | pActor->identifier[1] = 'x'; |
||
7373 | return 0; |
||
7374 | } |
||
7375 | } |
||
7376 | |||
7377 | // IDA: void __usercall CheckForDeAttachmentOfNonCars(tU32 pTime@<EAX>) |
||
7378 | void CheckForDeAttachmentOfNonCars(tU32 pTime) { |
||
7379 | static tU32 total_time; |
||
7380 | br_bounds bnds; |
||
7381 | int i; |
||
7382 | int j; |
||
7383 | int last_free_slot; |
||
7384 | int drop; |
||
7385 | tCollision_info* c; |
||
7386 | tCollision_info* c2; |
||
7387 | br_actor* actor; |
||
7388 | tU8 cx; |
||
7389 | tU8 cz; |
||
7390 | tTrack_spec* track_spec; |
||
7391 | br_matrix34 mat; |
||
7392 | LOG_TRACE("(%d)", pTime); |
||
7393 | |||
7394 | if (gNum_active_non_cars == 0) { |
||
7395 | return; |
||
7396 | } |
||
7397 | |||
7398 | last_free_slot = 0; |
||
7399 | track_spec = &gProgram_state.track_spec; |
||
7400 | |||
7401 | StartPipingSession(ePipe_chunk_non_car); |
||
7402 | for (i = 0; i < gNum_active_non_cars; i++) { |
||
7403 | if (!gActive_non_car_list[i]->collision_info.doing_nothing_flag) { |
||
7404 | AddNonCarToPipingSession(gActive_non_car_list[i]->collision_info.car_ID, gActive_non_car_list[i]->collision_info.car_master_actor); |
||
7405 | } |
||
7406 | } |
||
7407 | EndPipingSession(); |
||
7408 | |||
7409 | total_time += pTime; |
||
7410 | if (total_time < 1000) { |
||
7411 | return; |
||
7412 | } |
||
7413 | total_time = 0; |
||
7414 | for (i = 0; i < gNum_active_non_cars; i++) { |
||
7415 | c = &gActive_non_car_list[i]->collision_info; |
||
7416 | if (c->car_master_actor->t.t.translate.t.v[1] < gMin_world_y) { |
||
7417 | c->doing_nothing_flag = 1; |
||
7418 | } |
||
7419 | if (TestForNan(&c->car_master_actor->t.t.mat.m[3][1])) { |
||
7420 | BrVector3Set(&c->omega, 0.0f, 0.0f, 0.0f); |
||
7421 | BrMatrix34Identity(&c->car_master_actor->t.t.mat); |
||
7422 | BrVector3Set(&c->car_master_actor->t.t.translate.t, 2000.f, 0.f, 0.f); |
||
7423 | c->doing_nothing_flag = 1; |
||
7424 | } |
||
7425 | actor = c->car_master_actor; |
||
7426 | gActive_non_car_list[last_free_slot] = gActive_non_car_list[i]; |
||
7427 | if (c->doing_nothing_flag) { |
||
7428 | drop = 1; |
||
7429 | for (j = 0; j < gNum_cars_and_non_cars; j++) { |
||
7430 | c2 = (tCollision_info*)gActive_car_list[j]; |
||
7431 | if (c2 != c && !c2->doing_nothing_flag) { |
||
7432 | BrMatrix34Mul(&mat, &actor->t.t.mat, &c2->last_box_inv_mat); |
||
7433 | GetNewBoundingBox(&bnds, &actor->model->bounds, &mat); |
||
7434 | if (c2->last_box.max.v[0] >= bnds.min.v[0] |
||
7435 | && c2->last_box.max.v[1] >= bnds.min.v[1] |
||
7436 | && c2->last_box.max.v[2] >= bnds.min.v[2] |
||
7437 | && c2->last_box.min.v[0] <= bnds.max.v[0] |
||
7438 | && c2->last_box.min.v[1] <= bnds.max.v[1] |
||
7439 | && c2->last_box.min.v[2] <= bnds.max.v[2]) { |
||
7440 | drop = 0; |
||
7441 | break; |
||
7442 | } |
||
7443 | } |
||
7444 | } |
||
7445 | if (drop) { |
||
7446 | BrActorRemove(actor); |
||
7447 | c->driver = eDriver_non_car_unused_slot; |
||
7448 | last_free_slot--; |
||
7449 | XZToColumnXZ(&cx, &cz, actor->t.t.mat.m[3][0], actor->t.t.mat.m[3][2], track_spec); |
||
7450 | if (track_spec->columns[cz][cx] != NULL) { |
||
7451 | BrActorAdd(track_spec->columns[cz][cx], actor); |
||
7452 | } else { |
||
7453 | BrActorAdd(gTrack_actor, actor); |
||
7454 | } |
||
7455 | } |
||
7456 | } |
||
7457 | last_free_slot++; |
||
7458 | } |
||
7459 | gNum_active_non_cars = last_free_slot; |
||
7460 | } |
||
7461 | |||
7462 | // IDA: void __usercall AdjustNonCar(br_actor *pActor@<EAX>, br_matrix34 *pMat@<EDX>) |
||
7463 | void AdjustNonCar(br_actor* pActor, br_matrix34* pMat) { |
||
7464 | tU8 cx; |
||
7465 | tU8 cz; |
||
7466 | tTrack_spec* track_spec; |
||
7467 | LOG_TRACE("(%p, %p)", pActor, pMat); |
||
7468 | |||
7469 | track_spec = &gProgram_state.track_spec; |
||
7470 | BrMatrix34Copy(&pActor->t.t.mat, pMat); |
||
7471 | if (pActor->parent != gNon_track_actor) { |
||
7472 | XZToColumnXZ(&cx, &cz, pActor->t.t.translate.t.v[0], pActor->t.t.translate.t.v[2], track_spec); |
||
7473 | if (track_spec->columns[cz][cx] != pActor->parent && track_spec->columns[cz][cx] != NULL) { |
||
7474 | BrActorRemove(pActor); |
||
7475 | BrActorAdd(track_spec->columns[cz][cx], pActor); |
||
7476 | } |
||
7477 | } |
||
7478 | } |
||
7479 | |||
7480 | // IDA: void __usercall PipeSingleNonCar(tCollision_info *c@<EAX>) |
||
7481 | void PipeSingleNonCar(tCollision_info* c) { |
||
7482 | LOG_TRACE("(%p)", c); |
||
7483 | |||
7484 | StartPipingSession(ePipe_chunk_non_car); |
||
7485 | if (gDoing_physics) { |
||
7486 | BrVector3InvScale(&c->car_master_actor->t.t.translate.t, &c->car_master_actor->t.t.translate.t, WORLD_SCALE); |
||
7487 | } |
||
7488 | AddNonCarToPipingSession(c->car_ID, c->car_master_actor); |
||
7489 | if (gDoing_physics) { |
||
7490 | BrVector3Scale(&c->car_master_actor->t.t.translate.t, &c->car_master_actor->t.t.translate.t, WORLD_SCALE); |
||
7491 | } |
||
7492 | EndPipingSession(); |
||
7493 | } |
||
7494 | |||
7495 | // IDA: int __usercall GetPrecalculatedFacesUnderCar@<EAX>(tCar_spec *pCar@<EAX>, tFace_ref **pFace_refs@<EDX>) |
||
7496 | int GetPrecalculatedFacesUnderCar(tCar_spec* pCar, tFace_ref** pFace_refs) { |
||
7497 | LOG_TRACE("(%p, %p)", pCar, pFace_refs); |
||
7498 | |||
7499 | if (pCar->box_face_ref == gFace_num__car |
||
7500 | || (pCar->box_face_ref == gFace_num__car - 1 && pCar->box_face_start > gFace_count)) { |
||
7501 | *pFace_refs = &gFace_list__car[pCar->box_face_start]; |
||
7502 | return pCar->box_face_end - pCar->box_face_start; |
||
7503 | } |
||
7504 | return 0; |
||
7505 | } |
||
7506 | |||
7507 | // IDA: br_material* __cdecl SomeNearbyMaterial() |
||
7508 | br_material* SomeNearbyMaterial(void) { |
||
7509 | LOG_TRACE("()"); |
||
7510 | NOT_IMPLEMENTED(); |
||
7511 | } |