1 #pragma once
2 #include "configfile.h"
3 #include "dbl.h"
4 
5 
6 class TIMER
7 {
8 private:
9 
10 	class LAPTIME
11 	{
12 		private:
13 			bool havetime;
14 			double time;
15 
16 		public:
LAPTIME()17 			LAPTIME()
18 			{	Reset();  }
Reset()19 			void Reset()
20 			{
21 				havetime = false;
22 				time = 0;
23 			}
24 
HaveTime()25 			bool HaveTime() const {  return havetime;  }
GetTimeInSeconds()26 			double GetTimeInSeconds() const {  return time;  }
27 
28 			//  convert time in seconds into output min and secs
GetTimeInMinutesSeconds(float & secs,int & min)29 			void GetTimeInMinutesSeconds(float & secs, int & min) const
30 			{
31 				min = (int) time / 60;
32 				secs = time - min*60;
33 			}
Set(double newtime)34 			void Set(double newtime)
35 			{
36 				time = newtime;
37 				havetime = true;
38 			}
39 			//  only set the time if we don't have a time or if the new time is faster than the current time
SetIfFaster(double newtime)40 			void SetIfFaster(double newtime)
41 			{
42 				if (!havetime || newtime < time)
43 					time = newtime;
44 				havetime = true;
45 			}
46 	};
47 
48 	class LAPINFO
49 	{
50 		private:
51 			double time_rpl;  // time from race start (for replay)
52 			double time;      // lap time
53 
54 			LAPTIME lastlap;  // last lap time
55 			LAPTIME bestlap;  // best lap time (also from local records)
56 			LAPTIME bestlapRace;  // best lap time, for current race only
57 
58 			double totaltime; // total time of a race (>=1 laps)
59 			int num_laps;     // current lap
60 			std::string cartype;
61 
62 		public:
63 			double time_rewind;  // time from race start (for rewind, goes back when rewinding)
64 			double time_rewGh;   // lap time for ghost (goes back when rewinding)
LAPINFO(const std::string & newcartype)65 			LAPINFO(const std::string & newcartype) : cartype(newcartype) {Reset();}
66 
Reset()67 			void Reset()
68 			{
69 				time = totaltime = time_rpl = time_rewind = time_rewGh = 0.0;
70 				lastlap.Reset();
71 				bestlap.Reset();
72 				bestlapRace.Reset();
73 				num_laps = 0;
74 			}
75 
Tick(float dt)76 			void Tick(float dt)
77 			{
78 				time += dt;  time_rpl += dt;  time_rewind += dt;  time_rewGh += dt;
79 			}
80 
Back(float dt)81 			void Back(float dt)  //-
82 			{
83 				time += dt;  time_rpl += dt;
84 				if (time < 0.0)  time = 0.0;
85 				if (time_rpl < 0.0)  time_rpl = 0.0;
86 			}
87 
88 
Lap(bool countit)89 			void Lap(bool countit)
90 			{
91 				if (countit)
92 				{
93 					lastlap.Set(time);
94 					bestlap.SetIfFaster(time);
95 					bestlapRace.SetIfFaster(time);
96 				}
97 
98 				totaltime += time;
99 				time = 0.0;  time_rewGh = 0.0;
100 				num_laps++;
101 			}
102 
LapWithTime(bool countit,double curtime)103 			void LapWithTime(bool countit, double curtime)
104 			{
105 				if (countit)
106 				{
107 					lastlap.Set(curtime);
108 					bestlap.SetIfFaster(curtime);
109 					bestlapRace.SetIfFaster(time);
110 				}
111 
112 				totaltime += curtime;
113 				time = 0.0;  time_rewGh = 0.0;
114 				num_laps++;
115 			}
116 
GetCarType()117 			const std::string & GetCarType() const {return cartype;}
118 
DebugPrint(std::ostream & out)119 			void DebugPrint(std::ostream & out)
120 			{
121 				out << "car=" << cartype << ", t=" << totaltime << ", tlap=" << time << ", last=" <<
122 					lastlap.GetTimeInSeconds() << ", best=" << bestlap.GetTimeInSeconds() <<
123 					", lap=" << num_laps << std::endl;
124 			}
125 
RestartReplay()126 			void RestartReplay()  // replay play restart
127 			{
128 				time = time_rpl = time_rewGh = 0.0;
129 			}
130 
SetTimeReplay(double t)131 			void SetTimeReplay(double t)  // replay play
132 			{
133 				time = time_rpl = time_rewGh = t;
134 			}
135 
GetTimeReplay()136 			double GetTimeReplay() const{	return time_rpl;  }
GetTime()137 			double GetTime() const		{	return time;  }
138 
GetTimeTotal()139 			double GetTimeTotal() const	{	return totaltime;	}
GetLastLap()140 			double GetLastLap() const	{	return lastlap.GetTimeInSeconds();	}
GetBestLap()141 			double GetBestLap() const	{	return bestlap.GetTimeInSeconds();	}
GetBestLapRace()142 			double GetBestLapRace() const{	return bestlapRace.GetTimeInSeconds();	}
GetCurrentLap()143 			int GetCurrentLap() const	{	return num_laps;	}
144 	};
145 
146 	std::vector <LAPINFO> car;
147 
148 	// variables for drawing text
149 
150 	bool loaded;
151 	CONFIGFILE trackrecords; //the track records configfile
152 	std::string trackrecordsfile; //the filename for the track records
153 	//unsigned int carId; //the index for the player's car; defaults to zero
154 
155 public:
TIMER()156 	TIMER()
157 		:loaded(false), pretime(0.0)/*,carId(0)*/
158 		,waiting(false), end_sim(false)
159 		,netw_lap(1)
160 	{	}
~TIMER()161 	~TIMER()
162 	{	Unload();  }
163 
164 	float pretime; // amount of time left in staging
165 	bool waiting;  // for other players in multi or in champs to close info wnd
166 	bool end_sim;  // simulate at end of champ, no input, wnd shown
167 
168 	bool Load(const std::string & trackrecordspath, float stagingtime);
169 	///add a car of the given type and return the integer identifier that the track system will use
AddCar(const std::string & cartype)170 	int AddCar(const std::string & cartype) {  car.push_back(LAPINFO(cartype));  return car.size()-1;  }
171 
172 	void Unload();
173 
174 	void Tick(float dt);
175 	bool Lap(const int carId, const bool countit, bool bTrackReverse);
176 
177 	int netw_lap;
178 	bool LapNetworkTime(const int carId, int lap, const double curtime);  ///+
179 
DebugPrint(std::ostream & out)180 	void DebugPrint(std::ostream & out)
181 	{
182 		for (size_t i = 0; i < car.size(); ++i)
183 		{
184 			out << i << ". ";
185 			car[i].DebugPrint(out);
186 		}
187 	}
188 
GetPlayerTimeTot(const int carId)189 	double GetPlayerTimeTot(const int carId) {	assert(carId<car.size());	return car[carId].GetTimeTotal();	}
GetPlayerTime(const int carId)190 	double GetPlayerTime(const int carId) {		assert(carId<car.size());	return car[carId].GetTime();	}
GetReplayTime(const int carId)191 	double GetReplayTime(const int carId) {		assert(carId<car.size());	return car[carId].GetTimeReplay();  }  // replay
SetReplayTime(const int carId,double t)192 	void SetReplayTime(const int carId, double t){assert(carId<car.size());	car[carId].SetTimeReplay(t);  }
RestartReplay(const int carId)193 	void RestartReplay(const int carId)   {		assert(carId<car.size());	car[carId].RestartReplay();  }
GetRewindTime(const int carId)194 	double& GetRewindTime(const int carId) {	assert(carId<car.size());	return car[carId].time_rewind;  }  // rewind
GetRewindTimeGh(const int carId)195 	double& GetRewindTimeGh(const int carId) {	assert(carId<car.size());	return car[carId].time_rewGh;  }  // rewind
196 
Back(const int carId,double time)197 	void Back(const int carId,double time) {	assert(carId<car.size());	car[carId].Back(time);  }  // back
198 
199 	void Reset(int id = -1)
200 	{
201 		if (id == -1)
202 		{
203 			for (int i=0; i < car.size(); ++i)
204 				car[i].Reset();
205 		}else{
206 			if (car.size() > id)
207 				car[id].Reset();
208 		}
209 	}
210 
GetLastLap(const int carId)211 	float GetLastLap(const int carId)	{		assert(carId<car.size());	return car[carId].GetLastLap();  }
GetBestLapRace(const int carId)212 	float GetBestLapRace(const int carId)	{	assert(carId<car.size());	return car[carId].GetBestLapRace();  }
GetBestLap(const int carId,bool bTrackReverse)213 	float GetBestLap(const int carId, bool bTrackReverse)
214 	{
215 		assert(carId<car.size());
216 		float curbestlap = car[carId].GetBestLap();
217 		float prevbest(0);
218 
219 		bool haveprevbest = trackrecords.GetParam(
220 			car[carId].GetCarType() + (bTrackReverse ? "_rev" : "") + ".sector 0", prevbest);
221 		if (haveprevbest)
222 		{
223 			if (curbestlap == 0)
224 				return prevbest;
225 			else
226 				if (prevbest < curbestlap)
227 					return prevbest;
228 				else
229 					return curbestlap;
230 		}else
231 			return curbestlap;
232 	}
GetPlayerCurrentLap(const int carId)233 	int GetPlayerCurrentLap(const int carId) {  return GetCurrentLap(carId);  }
GetCurrentLap(unsigned int index)234 	int GetCurrentLap(unsigned int index)    {  assert(index<car.size());  return car[index].GetCurrentLap();  }
235 
236 };
237