#ifndef _CAR_H_
 
#define _CAR_H_
 
 
 
#include "brender/br_types.h"
 
#include "dr_types.h"
 
 
 
#define CAR_MAX_SIMPLIFICATION_LEVEL 4
 
 
 
extern int gDoing_physics;
 
extern br_scalar gDt;
 
extern int gCollision_detection_on__car; // suffix added to avoid duplicate symbol
 
extern br_vector3 gGround_normal__car; // suffix added to avoid duplicate symbol
 
extern void (*ControlCar__car[6])(tCar_spec*, br_scalar); // suffix added to avoid duplicate symbol
 
extern int gControl__car; // suffix added to avoid duplicate symbol
 
extern int gFace_num__car; // suffix added to avoid duplicate symbol
 
extern br_angle gOld_yaw__car; // suffix added to avoid duplicate symbol
 
extern br_angle gOld_zoom;
 
extern br_vector3 gCamera_pos_before_collide;
 
extern int gMetal_crunch_sound_id__car[5]; // suffix added to avoid duplicate symbol
 
extern int gMetal_scrape_sound_id__car[3]; // suffix added to avoid duplicate symbol
 
extern int gCar_car_collisions;
 
extern int gFreeze_mechanics;
 
extern tU32 gLast_cunning_stunt;
 
extern tU32 gWild_start;
 
extern tU32 gQuite_wild_start;
 
extern tU32 gQuite_wild_end;
 
extern tU32 gOn_me_wheels_start;
 
extern int gWoz_upside_down_at_all;
 
extern tS3_sound_tag gSkid_tag[2];
 
extern tCar_spec* gLast_car_to_skid[2];
 
extern int gEliminate_faces;
 
extern br_vector3 gZero_v__car; // suffix added to avoid duplicate symbol
 
extern tU32 gSwitch_time;
 
extern tSave_camera gSave_camera[2];
 
extern tU32 gLast_mechanics_time;
 
extern int gOpponent_viewing_mode;
 
extern int gNet_player_to_view_index;
 
extern int gDouble_pling_water;
 
extern int gStop_opponents_moving;
 
extern float gDefensive_powerup_factor[6];
 
extern float gOffensive_powerup_factor[6];
 
extern float gEngine_powerup_factor[6];
 
extern br_angle gPanning_camera_angle;
 
extern br_scalar gPanning_camera_height;
 
extern int gFace_count;
 
extern float gCar_simplification_factor[2][5];
 
extern int gCar_simplification_level;
 
extern int gNum_active_non_cars;
 
extern int gCamera_has_collided;
 
extern tFace_ref gFace_list__car[150]; // suffix added to avoid duplicate symbol
 
extern tNon_car_spec* gActive_non_car_list[50];
 
extern int gOver_shoot;
 
extern br_scalar gMin_world_y;
 
extern br_scalar gAccel;
 
extern br_vector3 gAverage_grid_position;
 
extern br_actor* gPed_actor;
 
extern int gCollision_count;
 
extern int gCamera_frozen;
 
extern int gMaterial_index;
 
extern int gInTheSea;
 
extern int gCamera_mode;
 
extern br_scalar gOur_yaw__car; // suffix added to avoid duplicate symbol
 
extern br_scalar gGravity__car; // suffix added to avoid duplicate symbol
 
extern br_vector3 gNew_ground_normal__car; // suffix added to avoid duplicate symbol
 
extern char gNon_car_spec_list[100];
 
extern tU32 gMechanics_time_sync;
 
extern int gNum_cars_and_non_cars;
 
 
 
void DamageUnit(tCar_spec* pCar, int pUnit_type, int pDamage_amount);
 
 
 
void DamageUnitWithSmoke(tCar_spec* pCar, int pUnit_type, int pDamage_amount);
 
 
 
void DamageEngine(int pDamage_amount);
 
 
 
void DamageTrans(int pDamage_amount);
 
 
 
void DamageSteering(int pDamage_amount);
 
 
 
void DamageLFWheel(int pDamage_amount);
 
 
 
void DamageLFBrake(int pDamage_amount);
 
 
 
void DamageLRBrake(int pDamage_amount);
 
 
 
void DamageLRWheel(int pDamage_amount);
 
 
 
void DamageRFWheel(int pDamage_amount);
 
 
 
void DamageRFBrake(int pDamage_amount);
 
 
 
void DamageRRBrake(int pDamage_amount);
 
 
 
void DamageRRWheel(int pDamage_amount);
 
 
 
void CalculatePlaneNormal(br_vector3* pP1, br_vector3* pP2, br_vector3* pP3, br_vector3* pNormal);
 
 
 
void CalculateGroundNormal(br_model* pThe_model, int pFace_index);
 
 
 
void ChangeYCoordinate(br_scalar pNew_y, tU32 pTime_taken, br_model* pThe_model, int pFace_index);
 
 
 
void SwitchCarActor(tCar_spec* pCar_spec, int pModel_index);
 
 
 
void InitialiseCar2(tCar_spec* pCar, int pClear_disabled_flag);
 
 
 
void InitialiseCar(tCar_spec* pCar);
 
 
 
void InitialiseCarsEtc(tRace_info* pThe_race);
 
 
 
void GetAverageGridPosition(tRace_info* pThe_race);
 
 
 
void SetInitialPosition(tRace_info* pThe_race, int pCar_index, int pGrid_index);
 
 
 
void SetInitialPositions(tRace_info* pThe_race);
 
 
 
void InitialiseNonCar(tNon_car_spec* non_car);
 
 
 
void GetFacesInBox(tCollision_info* c);
 
 
 
int IsCarInTheSea(void);
 
 
 
void RememberSafePosition(tCar_spec* car, tU32 pTime);
 
 
 
void ControlOurCar(tU32 pTime_difference);
 
 
 
void CalcEngineForce(tCar_spec* c, br_scalar dt);
 
 
 
void PrepareCars(tU32 pFrame_start_time);
 
 
 
void FinishCars(tU32 pLast_frame_time, tU32 pTime);
 
 
 
void InterpolateCars(tU32 pLast_frame_time, tU32 pTime);
 
 
 
void ResetOldmat(void);
 
 
 
void GetNonCars(void);
 
 
 
void GetNetPos(tCar_spec* pCar);
 
 
 
void ApplyPhysicsToCars(tU32 last_frame_time, tU32 pTime_difference);
 
 
 
void MungeSpecialVolume(tCollision_info* pCar);
 
 
 
void ResetCarSpecialVolume(tCollision_info* pCar);
 
 
 
void TestAutoSpecialVolume(tCollision_info* pCar);
 
 
 
void MoveAndCollideCar(tCar_spec* car, br_scalar dt);
 
 
 
void MoveAndCollideNonCar(tNon_car_spec* non_car, br_scalar dt);
 
 
 
int CollideCarWithWall(tCollision_info* car, br_scalar dt);
 
 
 
void ToggleControls(void);
 
 
 
void ControlCar2(tCar_spec* c, br_scalar dt);
 
 
 
void ControlCar3(tCar_spec* c, br_scalar dt);
 
 
 
void ControlCar4(tCar_spec* c, br_scalar dt);
 
 
 
void ControlCar5(tCar_spec* c, br_scalar dt);
 
 
 
void ControlCar1(tCar_spec* c, br_scalar dt);
 
 
 
void setrotate(br_vector3* wdt, br_matrix34* m);
 
 
 
void RotateCar2(tCollision_info* c, br_scalar dt);
 
 
 
void RotateCarSecondOrder(tCollision_info* c, br_scalar dt);
 
 
 
void RotateCarFirstOrder(tCollision_info* c, br_scalar dt);
 
 
 
void SimpleRotate(tCollision_info* c, br_scalar dt);
 
 
 
void RotateCar(tCollision_info* c, br_scalar dt);
 
 
 
void SteeringSelfCentre(tCar_spec* c, br_scalar dt, br_vector3* n);
 
 
 
void NonCarCalcForce(tNon_car_spec* nc, br_scalar dt);
 
 
 
void AddDrag(tCar_spec* c, br_scalar dt);
 
 
 
void DoBumpiness(tCar_spec* c, br_vector3* wheel_pos, br_vector3* norm, br_scalar* d, int n);
 
 
 
void CalcForce(tCar_spec* c, br_scalar dt);
 
 
 
void DoRevs(tCar_spec* c, br_scalar dt);
 
 
 
void ApplyTorque(tCar_spec* c, br_vector3* tdt);
 
 
 
void TranslateCar(tCollision_info* c, br_scalar dt);
 
 
 
int CollCheck(tCollision_info* c, br_scalar dt);
 
 
 
br_scalar AddFriction(tCollision_info* c, br_vector3* vel, br_vector3* normal_force, br_vector3* pos, br_scalar total_force, br_vector3* max_friction);
 
 
 
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);
 
 
 
void ScrapeNoise(br_scalar vel, br_vector3* position, int material);
 
 
 
void SkidNoise(tCar_spec* pC, int pWheel_num, br_scalar pV, int material);
 
 
 
void StopSkid(tCar_spec* pC);
 
 
 
void CrashNoise(br_vector3* pForce, br_vector3* position, int material);
 
 
 
void CrushAndDamageCar(tCar_spec* c, br_vector3* pPosition, br_vector3* pForce_car_space, tCar_spec* car2);
 
 
 
int ExpandBoundingBox(tCar_spec* c);
 
 
 
void CrushBoundingBox(tCar_spec* c, int crush_only);
 
 
 
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);
 
 
 
br_scalar SinglePointColl(br_scalar* f, br_matrix4* m, br_scalar* d);
 
 
 
br_scalar TwoPointColl(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n);
 
 
 
br_scalar DrMatrix4Inverse(br_matrix4* mi, br_matrix4* mc);
 
 
 
br_scalar ThreePointColl(br_scalar* f, br_matrix4* m, br_scalar* d);
 
 
 
br_scalar ThreePointCollRec(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n, tCollision_info* c);
 
 
 
br_scalar FourPointColl(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n, tCollision_info* c);
 
 
 
void MultiFindFloorInBoxM(int pNum_rays, br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, tCar_spec* c, int* mat_ref);
 
 
 
void MultiFindFloorInBoxBU(int pNum_rays, br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, tCar_spec* c, int* mat_ref);
 
 
 
void findfloor(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d);
 
 
 
int FindFloorInBoxM(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, tCollision_info* c);
 
 
 
int FindFloorInBoxBU(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, tCollision_info* c);
 
 
 
int FindFloorInBoxBU2(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, tCollision_info* c);
 
 
 
int FindFloorInBoxM2(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, tCollision_info* c);
 
 
 
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);
 
 
 
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);
 
 
 
void GetPlaneNormal(br_vector3* n, int p);
 
 
 
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);
 
 
 
void oldMoveOurCar(tU32 pTime_difference);
 
 
 
void ToggleCollisionDetection(void);
 
 
 
void CancelPendingCunningStunt(void);
 
 
 
float frac(float pN);
 
 
 
void SetAmbientPratCam(tCar_spec* pCar);
 
 
 
void MungeCarGraphics(tU32 pFrame_period);
 
 
 
void ResetCarScreens(void);
 
 
 
tCar_spec* GetRaceLeader(void);
 
 
 
void AmIGettingBoredWatchingCameraSpin(void);
 
 
 
void ViewNetPlayer(void);
 
 
 
void ViewOpponent(void);
 
 
 
void ToggleCarToCarCollisions(void);
 
 
 
void SwapCar(void);
 
 
 
void AdjustDownForce(void);
 
 
 
void FreezeMechanics(void);
 
 
 
void PutOpponentsInNeutral(void);
 
 
 
void SetPanningFieldOfView(void);
 
 
 
void CheckDisablePlingMaterials(tCar_spec* pCar);
 
 
 
void PositionExternalCamera(tCar_spec* c, tU32 pTime);
 
 
 
void CameraBugFix(tCar_spec* c, tU32 pTime);
 
 
 
int PossibleRemoveNonCarFromWorld(br_actor* pActor);
 
 
 
void PutNonCarBackInWorld(br_actor* pActor);
 
 
 
int IncidentCam(tCar_spec* c, tU32 pTime);
 
 
 
int MoveCamToIncident(tCar_spec* c, tIncident_type* type, float* severity, tIncident_info* info, tU32* next_incident_time);
 
 
 
void PanningExternalCamera(tCar_spec* c, tU32 pTime);
 
 
 
int CheckForWall(br_vector3* start, br_vector3* end);
 
 
 
void SetUpPanningCamera(tCar_spec* c);
 
 
 
void SaveCameraPosition(int i);
 
 
 
void RestoreCameraPosition(int i);
 
 
 
void NormalPositionExternalCamera(tCar_spec* c, tU32 pTime);
 
 
 
void MoveWithWheels(tCar_spec* c, br_vector3* vn, int manual_swing);
 
 
 
void SwingCamera(tCar_spec* c, br_matrix34* m1, br_matrix34* m2, br_vector3* vn, tU32 pTime);
 
 
 
void PointCameraAtCar(tCar_spec* c, br_matrix34* m1, br_matrix34* m2);
 
 
 
void PointCamera(br_vector3* pos, br_matrix34* m2);
 
 
 
int CollideCamera2(br_vector3* car_pos, br_vector3* cam_pos, br_vector3* old_camera_pos, int manual_move);
 
 
 
int BoundsTest(br_bounds* bnds, br_vector3* p);
 
 
 
int CollideCameraWithOtherCars(br_vector3* car_pos, br_vector3* cam_pos);
 
 
 
void InitialiseExternalCamera(void);
 
 
 
void FreezeCamera(void);
 
 
 
void FlyCar(tCar_spec* c, br_scalar dt);
 
 
 
void DrVector3RotateY(br_vector3* v, br_angle t);
 
 
 
void CrashCarsTogether(br_scalar dt);
 
 
 
int CrashCarsTogetherSinglePass(br_scalar dt, int pPass, tCollison_data* collide_list);
 
 
 
void BringCarToAGrindingHalt(tCollision_info* car);
 
 
 
int BoundsOverlapTest_car(br_bounds* b1, br_bounds* b2);
 
 
 
int SimpleCarCarCollisionTest(tCollision_info* car1, tCollision_info* car2);
 
 
 
int CollideTwoCarsWithWalls(tCollision_info* car1, tCollision_info* car2, br_scalar dt);
 
 
 
int CollideTwoCarsRepeatedly(tCollision_info* car1, tCollision_info* car2, br_scalar dt);
 
 
 
int CollideTwoCars(tCollision_info* car1, tCollision_info* car2, int pPass);
 
 
 
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);
 
 
 
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);
 
 
 
void MungeCarsMass(tCollision_info* pCar, br_scalar pFactor);
 
 
 
void ModifyCarsMass(tCollision_info* pCar_1, tCollision_info* pCar_2);
 
 
 
void ResetCarsMass(tCollision_info* pCar_1, tCollision_info* pCar_2);
 
 
 
int DoCollide(tCollision_info* car1, tCollision_info* car2, br_vector3* r, br_vector3* n, int k, int pPass, br_matrix34* mat1_to_mat2);
 
 
 
br_scalar TwoPointCollB(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n);
 
 
 
br_scalar ThreePointCollRecB(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n);
 
 
 
br_scalar FourPointCollB(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n);
 
 
 
int TestForNan(float* f);
 
 
 
void CheckCameraHither(void);
 
 
 
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);
 
 
 
int TestForCarInSensiblePlace(tCar_spec* car);
 
 
 
int TestOldMats(tCollision_info* c1, tCollision_info* c2, int newmats);
 
 
 
int PullActorFromWorld(br_actor* pActor);
 
 
 
int DoPullActorFromWorld(br_actor* pActor);
 
 
 
void CheckForDeAttachmentOfNonCars(tU32 pTime);
 
 
 
void AdjustNonCar(br_actor* pActor, br_matrix34* pMat);
 
 
 
void PipeSingleNonCar(tCollision_info* c);
 
 
 
int GetPrecalculatedFacesUnderCar(tCar_spec* pCar, tFace_ref** pFace_refs);
 
 
 
br_material* SomeNearbyMaterial(void);
 
 
 
#endif