1 #include "pch.h"
2 #include "common/Def_Str.h"
3 #include "common/RenderConst.h"
4 #include "common/data/CData.h"
5 #include "common/data/SceneXml.h"
6 #include "common/CScene.h"
7 #include "common/GuiCom.h"
8 #include "CGame.h"
9 #include "CHud.h"
10 #include "CGui.h"
11 #include "../vdrift/game.h"
12 #include "../road/Road.h"
13 #include "../road/PaceNotes.h"
14 #include "../sound/SoundMgr.h"
15 #include "../sound/SoundBaseMgr.h"
16 #include "LoadingBar.h"
17 #include "FollowCamera.h"
18 #include "SplitScreen.h"
19 #include "common/GraphView.h"
20 #include "../network/gameclient.hpp"
21 #include "../paged-geom/PagedGeometry.h"
22 #include "../shiny/Main/Factory.hpp"
23 #include <boost/thread.hpp>
24 #include <MyGUI_OgrePlatform.h>
25 #include "common/MyGUI_D3D11.h"
26 #include <MyGUI_PointerManager.h>
27 #include <OgreTerrainGroup.h>
28 #include <OgreParticleSystem.h>
29 using namespace MyGUI;
30 using namespace Ogre;
31 
32 
33 //  Create Scene
34 //-------------------------------------------------------------------------------------
createScene()35 void App::createScene()
36 {
37 	//  prv tex
38 	int k = 1024;
39 	prvView.Create(k,k,"PrvView");
40 	prvRoad.Create(k,k,"PrvRoad");
41 	 prvTer.Create(k,k,"PrvTer");
42 	//  ch stage
43 	prvStCh.Create(k,k,"PrvStCh");
44 
45 	scn->roadDens.Create(k+1,k+1,"RoadDens");
46 
47 	///  ter lay tex
48 	for (int i=0; i < 6; ++i)
49 	{	String si = toStr(i);
50 		scn->texLayD[i].SetName("layD"+si);
51 		scn->texLayN[i].SetName("layN"+si);
52 	}
53 
54 	mLoadingBar->loadTex.Create(1920,1200,"LoadingTex");
55 
56 	//  tex fil
57 	MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC);
58 	MaterialManager::getSingleton().setDefaultAnisotropy(pSet->anisotropy);
59 
60 	//  restore camNums
61 	for (int i=0; i<4; ++i)
62 		if (pSet->cam_view[i] >= 0)
63 			carsCamNum[i] = pSet->cam_view[i];
64 
65 	Ogre::Timer ti;
66 
67 
68 	//  data xmls
69 	pGame->ReloadSimData();  // need surfaces
70 
71 	///  _Tool_ check champs and challs  ............
72 	bool check = 0;
73 	scn->data->Load(&pGame->surf_map, check);
74 	scn->sc->pFluidsXml = scn->data->fluids;
75 	scn->sc->pReverbsXml = scn->data->reverbs;
76 
77 	//  championships.xml, progress.xml
78 	gui->Ch_XmlLoad();
79 
80 	//  user.xml
81 	#if 0
82 	userXml.LoadXml(PATHMANAGER::UserConfigDir() + "/user.xml");
83 	for (int i=0; i < data->tracks->trks.size(); ++i)
84 	{
85 		const TrackInfo& ti = data->tracks->trks[i];
86 		if (userXml.trkmap[ti.name]==0)
87 		{	// not found, add
88 			UserTrkInfo tu;  tu.name = ti.name;
89 
90 			userXml.trks.push_back(tu);
91 			userXml.trkmap[ti.name] = userXml.trks.size();
92 	}	}
93 	userXml.SaveXml(PATHMANAGER::UserConfigDir() + "/user.xml");
94 	#endif
95 
96 	//  rpl sizes
97 	ushort u(0x1020);
98 	struct SV{  std::vector<int> v;  };
99 	int sr = sizeof(ReplayFrame), sv = sizeof(SV), sr2 = sizeof(ReplayFrame2)-3*sv, wh2 = sizeof(RWheel);
100 
101 	LogO(String("**** ReplayFrame size old: ") + toStr(sr)+"  new: "+toStr(sr2)+"+ wh: "+toStr(wh2)+"= "+toStr(sr2+4*wh2));
102 	LogO(String("**** Replay test sizes: 12244: ") + toStr(sizeof(char))+","+toStr(sizeof(short))+
103 		","+toStr(sizeof(half))+","+toStr(sizeof(float))+","+toStr(sizeof(int))+"  sv: "+toStr(sv)+
104 		"   hi,lo 16,32: h "+toStr(*((uchar*)&u+1))+" l "+toStr(*((uchar*)&u)));
105 
106 	LogO(String("::: Time load xmls: ") + fToStr(ti.getMilliseconds(),0,3) + " ms");  ti.reset();
107 
108 
109 	///  rpl test-
110 	#if 0
111 	std::string file = PATHMANAGER::Ghosts() + "/normal/TestC4-ow_V2.rpl";
112 	replay.LoadFile(file);
113 	exit(0);
114 	#endif
115 
116 
117 	///  _Tool_ ghosts times .......
118 	#if 0
119 	gui->ToolGhosts();
120 	//ShutDown();  return;
121 	exit(0);
122 	#endif
123 
124 	///  _Tool_ convert to track's ghosts ..............
125 	#if 0
126 	gui->ToolGhostsConv();
127 	exit(0);
128 	#endif
129 
130 	///  _Tool_ test track's ghosts ..............
131 	#if 0
132 	gui->ToolTestTrkGhosts();
133 	exit(0);
134 	#endif
135 
136 	///  _Tool_ presets .......
137 	#if 0
138 	gui->ToolPresets();
139 	exit(0);
140 	#endif
141 
142 
143 	//  gui  * * *
144 	if (pSet->startInMain)
145 		pSet->isMain = true;
146 
147 	if (!pSet->autostart)
148 		isFocGui = true;
149 
150 	pSet->gui.champ_num = -1;  //dont auto start old chs
151 	pSet->gui.chall_num = -1;
152 
153 	bRplRec = pSet->rpl_rec;  // startup setting
154 
155 	gui->InitGui();
156 
157     //  bullet Debug drawing
158     //------------------------------------
159     if (pSet->bltLines)
160 	{	dbgdraw = new BtOgre::DebugDrawer(
161 			mSceneMgr->getRootSceneNode(),
162 			pGame->collision.world);
163 		pGame->collision.world->setDebugDrawer(dbgdraw);
164 		pGame->collision.world->getDebugDrawer()->setDebugMode(
165 			1 /*0xfe/*8+(1<<13)*/);
166 	}
167 
168 	//  load
169 	if (pSet->autostart)
170 		NewGame();
171 }
172 
173 
174 //---------------------------------------------------------------------------------------------------------------
175 ///  New Game
176 //---------------------------------------------------------------------------------------------------------------
NewGame(bool force)177 void App::NewGame(bool force)
178 {
179 	//  actual loading isn't done here
180 	isFocGui = false;
181 	gui->toggleGui(false);  // hide gui
182 	mWndNetEnd->setVisible(false);
183 
184 	bLoading = true;  iLoad1stFrames = 0;
185 	carIdWin = 1;  iRplCarOfs = 0;
186 
187 	//  wait until sim finishes
188 	while (bSimulating)
189 		boost::this_thread::sleep(boost::posix_time::milliseconds(pSet->thread_sleep));
190 
191 	bRplPlay = 0;  iRplSkip = 0;
192 	pSet->rpl_rec = bRplRec;  // changed only at new game
193 	gui->pChall = 0;
194 
195 
196 	if (!newGameRpl)  // if from replay, dont
197 	{
198 		pSet->game = pSet->gui;  // copy game config from gui
199 		Ch_NewGame();
200 
201 		if (mClient && mLobbyState != HOSTING)  // all but host
202 			gui->updateGameSet();  // override gameset params for networked game (from host gameset)
203 		if (mClient)  // for all, including host
204 			pSet->game.local_players = 1;
205 	}
206 	newGameRpl = false;
207 
208 	///<>  same track
209 	dstTrk = force || oldTrack != pSet->game.track || oldTrkUser != pSet->gui.track_user;
210 
211 	///  check if track exist ..
212 	if (!PATHMANAGER::FileExists(gcom->TrkDir()+"scene.xml"))
213 	{
214 		bLoading = false;  //iLoad1stFrames = -2;
215 		gui->BackFromChs();
216 		//toggleGui(true);  // show gui
217 		Message::createMessageBox("Message", TR("#{Track}"),
218 			TR("#{TrackNotFound}")+"\n" + pSet->game.track +
219 			(pSet->game.track_user ? " *"+TR("#{TweakUser}")+"*" :"") + "\nPath: " + gcom->TrkDir(),
220 			MessageBoxStyle::IconError | MessageBoxStyle::Ok);
221 		//todo: gui is stuck..
222 		return;
223 	}
224 	mWndRpl->setVisible(false);  // hide rpl ctrl
225 
226 	LoadingOn();
227 	hud->Show(true);  // hide HUD
228 	//mFpsOverlay->hide();  // hide FPS
229 	hideMouse();
230 
231 	curLoadState = 0;
232 }
233 
234 
235 /* *  Loading steps (in this order)  * */
236 //---------------------------------------------------------------------------------------------------------------
237 
LoadCleanUp()238 void App::LoadCleanUp()  // 1 first
239 {
240 	updMouse();
241 
242 	if (dstTrk)
243 	{	scn->DestroyFluids();  DestroyObjects(true);  }
244 
245 	DestroyGraphs();  hud->Destroy();
246 
247 	//  hide hud arrow,beam,pace
248 	bool rplRd = bRplPlay /*|| scn->road && scn->road->getNumPoints() < 2/**/;
249 	bHideHudBeam = rplRd;
250 	bHideHudArr = rplRd || pSet->game.local_players > 1;
251 	bool denyPace = gui->pChall && !gui->pChall->pacenotes;
252 	bHideHudPace = bHideHudArr || denyPace;
253 
254 
255 	// rem old track
256 	if (dstTrk)
257 	{
258 		if (resTrk != "")  mRoot->removeResourceLocation(resTrk);
259 		LogO("------  Loading track: "+pSet->game.track);
260 		resTrk = gcom->TrkDir() + "objects";
261 		mRoot->addResourceLocation(resTrk, "FileSystem");
262 	}
263 
264 	//  Delete all cars
265 	for (int i=0; i < carModels.size(); ++i)
266 	{
267 		CarModel* c = carModels[i];
268 		if (c && c->fCam)
269 		{
270 			carsCamNum[i] =
271 				c->iLoopLastCam != -1 ? c->iLoopLastCam +1 :  //o
272 				c->fCam->miCurrent +1;  // save which cam view
273 			if (i < 4)
274 				pSet->cam_view[i] = carsCamNum[i];
275 		}
276 		delete c;
277 	}
278 	carModels.clear();  //carPoses.clear();
279 
280 
281 	if (dstTrk)
282 	{
283 		scn->DestroyTrees();
284 		scn->DestroyWeather();
285 
286 		scn->DestroyTerrain();
287 		scn->DestroyRoad();
288 	}
289 
290 	///  destroy all
291 	///  todo: check if track/car changed, dont recreate if same..
292 	if (dstTrk)
293 	{
294 		//mSceneMgr->getRootSceneNode()->removeAndDestroyAllChildren();  // destroy all scenenodes
295 		mSceneMgr->destroyAllManualObjects();
296 		mSceneMgr->destroyAllEntities();
297 		mSceneMgr->destroyAllStaticGeometry();
298 		scn->vdrTrack = 0;
299 		//mSceneMgr->destroyAllParticleSystems();
300 		mSceneMgr->destroyAllRibbonTrails();
301 		mSplitMgr->mGuiSceneMgr->destroyAllManualObjects(); // !?..
302 	}
303 
304 	// remove junk from previous tracks
305 	MeshManager::getSingleton().unloadUnreferencedResources();
306 	sh::Factory::getInstance().unloadUnreferencedMaterials();
307 	Ogre::TextureManager::getSingleton().unloadUnreferencedResources();
308 }
309 
310 
311 //---------------------------------------------------------------------------------------------------------------
LoadGame()312 void App::LoadGame()  // 2
313 {
314 	//  viewports
315 	int numRplViews = std::max(1, std::min( int(replay.header.numPlayers), pSet->rpl_numViews ));
316 	mSplitMgr->mNumViewports = bRplPlay ? numRplViews : pSet->game.local_players;  // set num players
317 	mSplitMgr->Align();
318 	mPlatform->getRenderManagerPtr()->setActiveViewport(mSplitMgr->mNumViewports);
319 
320 	pGame->LeaveGame(dstTrk);
321 
322 	if (gui->bReloadSim)
323 	{	gui->bReloadSim = false;
324 		pGame->ReloadSimData();
325 
326 		static bool f1 = true;
327 		if (f1) {  f1 = false;
328 			gui->updSld_TwkSurf(0);  }
329 	}
330 
331 	///<>  save old track
332 	oldTrack = pSet->game.track;  oldTrkUser = pSet->game.track_user;
333 
334 
335 	//  load scene.xml - default if not found
336 	//  need to know sc->asphalt before vdrift car load
337 	if (dstTrk)
338 	{
339 		bool vdr = IsVdrTrack();
340 		scn->sc->pGame = pGame;
341 		scn->sc->LoadXml(gcom->TrkDir()+"scene.xml", !vdr/*for asphalt*/);
342 		scn->sc->vdr = vdr;
343 		pGame->track.asphalt = scn->sc->asphalt;  //*
344 		pGame->track.sDefaultTire = scn->sc->asphalt ? "asphalt" : "gravel";  //*
345 		if (scn->sc->denyReversed)
346 			pSet->game.trackreverse = false;
347 
348 		pGame->NewGameDoLoadTrack();
349 
350 		if (!scn->sc->ter)
351 			scn->sc->td.hfHeight = NULL;  // sc->td.layerRoad.smoke = 1.f;
352 	}
353 	//  set normal reverb
354 	pGame->snd->sound_mgr->SetReverb(scn->sc->revSet.normal);
355 
356 	//  upd car abs,tcs,sss
357 	pGame->ProcessNewSettings();
358 
359 
360 	///  init car models
361 	///--------------------------------------------
362 	//  will create vdrift cars, actual car loading will be done later in LoadCar()
363 	//  this is just here because vdrift car has to be created first
364 	std::list<Camera*>::iterator camIt = mSplitMgr->mCameras.begin();
365 
366 	int numCars = mClient ? mClient->getPeerCount()+1 : pSet->game.local_players;  // networked or splitscreen
367 	int i;
368 	for (i = 0; i < numCars; ++i)
369 	{
370 		// TODO: This only handles one local player
371 		CarModel::eCarType et = CarModel::CT_LOCAL;
372 		int startId = i;
373 		std::string carName = pSet->game.car[std::min(3,i)], nick = "";
374 		if (mClient)
375 		{
376 			// FIXME: Various places assume carModels[0] is local
377 			// so we swap 0 and local's id but preserve starting position
378 			if (i == 0)  startId = mClient->getId();
379 			else  et = CarModel::CT_REMOTE;
380 
381 			if (i == mClient->getId())  startId = 0;
382 			if (i != 0)  carName = mClient->getPeer(startId).car;
383 
384 			//  get nick name
385 			if (i == 0)  nick = pSet->nickname;
386 			else  nick = mClient->getPeer(startId).name;
387 		}
388 		Camera* cam = 0;
389 		if (et == CarModel::CT_LOCAL && camIt != mSplitMgr->mCameras.end())
390 		{	cam = *camIt;  ++camIt;  }
391 
392 		CarModel* car = new CarModel(i, i, et, carName, mSceneMgr, pSet, pGame, scn->sc, cam, this);
393 		car->Load(startId);
394 		carModels.push_back(car);
395 
396 		if (nick != "")  // set remote nickname
397 		{	car->sDispName = nick;
398 			if (i != 0)  // not for local
399 				car->pNickTxt = hud->CreateNickText(i, car->sDispName);
400 		}
401 	}
402 
403 	///  ghost car - last in carModels
404 	///--------------------------------------------
405 	ghplay.Clear();
406 	if (!bRplPlay/*|| pSet->rpl_show_ghost)*/ && pSet->rpl_ghost && !mClient)
407 	{
408 		std::string ghCar = pSet->game.car[0], orgCar = ghCar;
409 		ghplay.LoadFile(gui->GetGhostFile(pSet->rpl_ghostother ? &ghCar : 0));
410 		isGhost2nd = ghCar != orgCar;
411 
412 		//  always because ghplay can appear during play after best lap
413 		// 1st ghost = orgCar
414 		CarModel* c = new CarModel(i, 4, CarModel::CT_GHOST, orgCar, mSceneMgr, pSet, pGame, scn->sc, 0, this);
415 		c->Load();
416 		c->pCar = (*carModels.begin())->pCar;  // based on 1st car
417 		carModels.push_back(c);
418 
419 		//  2st ghost - other car
420 		if (isGhost2nd)
421 		{
422 			CarModel* c = new CarModel(i, 4, CarModel::CT_GHOST2, ghCar, mSceneMgr, pSet, pGame, scn->sc, 0, this);
423 			c->Load();
424 			c->pCar = (*carModels.begin())->pCar;
425 			carModels.push_back(c);
426 		}
427 	}
428 	///  track's ghost  . . .
429 	///--------------------------------------------
430 	ghtrk.Clear();  vTimeAtChks.clear();
431 	bool deny = gui->pChall && !gui->pChall->trk_ghost;
432 	if (!bRplPlay /*&& pSet->rpl_trackghost?*/ && !mClient && !pSet->game.track_user && !deny)
433 	{
434 		std::string sRev = pSet->game.trackreverse ? "_r" : "";
435 		std::string file = PATHMANAGER::TrkGhosts()+"/"+ pSet->game.track + sRev + ".gho";
436 		if (ghtrk.LoadFile(file))
437 		{
438 			CarModel* c = new CarModel(i, 5, CarModel::CT_TRACK, "ES", mSceneMgr, pSet, pGame, scn->sc, 0, this);
439 			c->Load();
440 			c->pCar = (*carModels.begin())->pCar;  // based on 1st car
441 			carModels.push_back(c);
442 	}	}
443 
444 	float pretime = mClient ? 2.0f : pSet->game.pre_time;  // same for all multi players
445 	if (bRplPlay)  pretime = 0.f;
446 	if (mClient)
447 	{	pGame->timer.waiting = true;  //+
448 		pGame->timer.end_sim = false;
449 	}
450 
451 	pGame->NewGameDoLoadMisc(pretime);
452 }
453 //---------------------------------------------------------------------------------------------------------------
454 
455 
LoadScene()456 void App::LoadScene()  // 3
457 {
458 	//  water RTT
459 	scn->UpdateWaterRTT(mSplitMgr->mCameras.front());
460 
461 	/// generate materials
462 	refreshCompositor();
463 
464 	//  fluids
465 	if (dstTrk)
466 		scn->CreateFluids();
467 
468 	if (dstTrk)
469 		pGame->collision.world->setGravity(btVector3(0.0, 0.0, -scn->sc->gravity));
470 
471 
472 	//  set sky tex name for water
473 	sh::MaterialInstance* m = mFactory->getMaterialInstance(scn->sc->skyMtr);
474 	std::string skyTex = sh::retrieveValue<sh::StringValue>(m->getProperty("texture"), 0).get();
475 	sh::Factory::getInstance().setTextureAlias("SkyReflection", skyTex);
476 
477 
478 	//  weather
479 	if (dstTrk)
480 		scn->CreateWeather();
481 
482 	//  checkpoint arrow
483 	bool deny = gui->pChall && !gui->pChall->chk_arr;
484 	if (!bHideHudArr && !deny)
485 		hud->arrow.Create(mSceneMgr, pSet);
486 }
487 
488 
489 //---------------------------------------------------------------------------------------------------------------
LoadCar()490 void App::LoadCar()  // 4
491 {
492 	//  Create all cars
493 	for (int i=0; i < carModels.size(); ++i)
494 	{
495 		CarModel* c = carModels[i];
496 		c->Create();
497 
498 		///  challenge off abs,tcs
499 		if (gui->pChall && c->pCar)
500 		{
501 			if (!gui->pChall->abs)  c->pCar->dynamics.SetABS(false);
502 			if (!gui->pChall->tcs)  c->pCar->dynamics.SetTCS(false);
503 		}
504 
505 		//  restore which cam view
506 		if (c->fCam && carsCamNum[i] != 0)
507 		{
508 			c->fCam->setCamera(carsCamNum[i] -1);
509 
510 			int visMask = c->fCam->ca->mHideGlass ? RV_MaskAll-RV_CarGlass : RV_MaskAll;
511 			for (std::list<Viewport*>::iterator it = mSplitMgr->mViewports.begin();
512 				it != mSplitMgr->mViewports.end(); ++it)
513 				(*it)->setVisibilityMask(visMask);
514 		}
515 		iCurPoses[i] = 0;
516 	}
517 	if (!dstTrk)  // reset objects if same track
518 		pGame->bResetObj = true;
519 
520 
521 	///  Init Replay  header, once
522 	///=================----------------
523 	ReplayHeader2& rh = replay.header, &gh = ghost.header;
524 	if (!bRplPlay)
525 	{
526 		replay.InitHeader(pSet->game.track.c_str(), pSet->game.track_user, !bRplPlay);
527 		rh.numPlayers = mClient ? (int)mClient->getPeerCount()+1 : pSet->game.local_players;  // networked or splitscreen
528 		replay.Clear();  replay.ClearCars();  // upd num plr
529 		rh.trees = pSet->game.trees;
530 
531 		rh.networked = mClient ? 1 : 0;
532 		rh.num_laps = pSet->game.num_laps;
533 		rh.sim_mode = pSet->game.sim_mode;
534 	}
535 	rewind.Clear();
536 
537 	ghost.InitHeader(pSet->game.track.c_str(), pSet->game.track_user, !bRplPlay);
538 	gh.numPlayers = 1;  // ghost always 1 car
539 	ghost.Clear();  ghost.ClearCars();
540 	gh.cars[0] = pSet->game.car[0];  gh.numWh[0] = carModels[0]->numWheels;
541 	gh.networked = 0;  gh.num_laps = 1;
542 	gh.sim_mode = pSet->game.sim_mode;
543 	gh.trees = pSet->game.trees;
544 
545 	//  fill other cars (names, nicks, colors)
546 	int p, pp = pSet->game.local_players;
547 	if (mClient)  // networked, 0 is local car
548 		pp = (int)mClient->getPeerCount()+1;
549 
550 	if (!bRplPlay)
551 	for (p=0; p < pp; ++p)
552 	{
553 		const CarModel* cm = carModels[p];
554 		rh.cars[p] = cm->sDirname;  rh.nicks[p] = cm->sDispName;
555 		rh.numWh[p] = cm->numWheels;
556 	}
557 
558 	//  set carModel nicks from networked replay
559 	if (bRplPlay && rh.networked)
560 	for (p=0; p < pp; ++p)
561 	{
562 		CarModel* cm = carModels[p];
563 		cm->sDispName = rh.nicks[p];
564 		cm->pNickTxt = hud->CreateNickText(p, cm->sDispName);
565 	}
566 }
567 //---------------------------------------------------------------------------------------------------------------
568 
569 
LoadTerrain()570 void App::LoadTerrain()  // 5
571 {
572 	if (dstTrk)
573 	{
574 		scn->CreateTerrain(false, scn->sc->ter);  // common
575 		GetTerMtrIds();
576 		if (scn->sc->ter)
577 			scn->CreateBltTerrain();
578 	}
579 
580 	for (int c=0; c < carModels.size(); ++c)
581 		carModels[c]->terrain = scn->terrain;
582 
583 	sh::Factory::getInstance().setTextureAlias("CubeReflection", "ReflectionCube");
584 
585 
586 	if (dstTrk)
587 	if (scn->sc->vdr)  // vdrift track
588 		CreateVdrTrack(pSet->game.track, &pGame->track);
589 }
590 
LoadRoad()591 void App::LoadRoad()  // 6
592 {
593 	CreateRoad();   // dstTrk inside
594 
595 	if (hud->arrow.nodeRot)
596 		hud->arrow.nodeRot->setVisible(pSet->check_arrow && !bHideHudArr);
597 
598 	//  boost fuel at start  . . .
599 	//  based on road length
600 	float boost_start = std::min(pSet->game.boost_max, std::max(pSet->game.boost_min,
601 		scn->road->st.Length * 0.001f * pSet->game.boost_per_km));
602 
603 	for (int i=0; i < carModels.size(); ++i)
604 	{	CAR* car = carModels[i]->pCar;
605 		if (car)
606 		{	car->dynamics.boostFuelStart = boost_start;
607 			car->dynamics.boostFuel = boost_start;
608 	}	}
609 
610 
611 	///  Run track's ghost
612 	//  to get times at checkpoints
613 	fLastTime = 1.f;
614 	if (!scn->road || ghtrk.GetTimeLength() < 1.f)  return;
615 	int ncs = scn->road->mChks.size();
616 	if (ncs == 0)  return;
617 
618 	vTimeAtChks.resize(ncs);
619 	int i,c;  // clear
620 	for (c=0; c < ncs; ++c)
621 		vTimeAtChks[c] = 0.f;
622 
623 	int si = ghtrk.frames.size();
624 	for (i=0; i < si; ++i)
625 	{
626 		const TrackFrame& tf = ghtrk.frames[i];  // car
627 		if (tf.time > fLastTime)
628 			fLastTime = tf.time;
629 		for (c=0; c < ncs; ++c)  // test if in any checkpoint
630 		{
631 			const CheckSphere& cs = scn->road->mChks[c];
632 			Vector3 pos(tf.pos[0],tf.pos[2],-tf.pos[1]);
633 			Real d2 = cs.pos.squaredDistance(pos);
634 			if (d2 < cs.r2)  // inside
635 			if (vTimeAtChks[c] == 0.f)
636 			{	vTimeAtChks[c] = tf.time;
637 				//LogO("Chk "+toStr(c)+" ti "+fToStr(tf.time,1,4));
638 		}	}
639 	}
640 }
641 
LoadObjects()642 void App::LoadObjects()  // 7
643 {
644 	if (dstTrk)
645 		CreateObjects();
646 }
647 
LoadTrees()648 void App::LoadTrees()  // 8
649 {
650 	if (!dstTrk)
651 		scn->UpdCamera();  // paged cam
652 	else
653 	if (scn->sc->ter)
654 		scn->CreateTrees();
655 
656 
657 	//  check for cars inside terrain ___
658 	if (scn->terrain)
659 	for (int i=0; i < carModels.size(); ++i)
660 	{
661 		CAR* car = carModels[i]->pCar;
662 		if (car)
663 		{
664 			MATHVECTOR<float,3> pos = car->posAtStart;
665 			Vector3 stPos(pos[0],pos[2],-pos[1]);
666 			float yt = scn->terrain->getHeightAtWorldPosition(stPos), yd = stPos.y - yt - 0.5f;
667 			//todo: either sweep test car body, or world->CastRay x4 at wheels -for bridges, pipes
668 			//pGame->collision.world->;  //car->dynamics.chassis
669 			if (yd < 0.f)
670 				pos[2] += -yd + (pSet->game.sim_mode == "easy" ? -0.1f : 0.9f);
671 			car->SetPosition1(pos);
672 	}	}
673 }
674 
675 
LoadMisc()676 void App::LoadMisc()  // 9 last
677 {
678 	bool rev = pSet->game.trackreverse;
679 	if (pGame && !pGame->cars.empty())  //todo: move this into gui track tab chg evt, for cur game type
680 		gcom->UpdGuiRdStats(scn->road, scn->sc, gcom->sListTrack,
681 			pGame->timer.GetBestLap(0, rev), rev, 0);  // current
682 
683 
684 	hud->Create();
685 	hud->Show(true);  // hide
686 
687 	// Camera settings
688 	for (std::vector<CarModel*>::iterator it=carModels.begin(); it!=carModels.end(); ++it)
689 	{	(*it)->First();
690 		if ((*it)->fCam)
691 		{	(*it)->fCam->mTerrain = scn->mTerrainGroup;
692 			//(*it)->fCam->mWorld = &(pGame->collision);
693 	}	}
694 
695 	if (dstTrk)
696 	try {
697 	TexturePtr tex = Ogre::TextureManager::getSingleton().getByName("waterDepth.png");
698 	if (!tex.isNull())
699 		tex->reload();
700 	} catch(...) {  }
701 
702 
703 	/// rendertextures debug
704 	#if 0
705 	// init overlay elements
706 	OverlayManager& mgr = OverlayManager::getSingleton();
707 	Overlay* overlay;
708 	// destroy if already exists
709 	if (overlay = mgr.getByName("DebugOverlay"))
710 		mgr.destroy(overlay);
711 	overlay = mgr.create("DebugOverlay");
712 	//Ogre::CompositorInstance  *compositor= CompositorManager::getSingleton().getCompositorChain(mSplitMgr->mViewports.front())->getCompositor("HDR");
713 	for (int i=0; i<3; ++i)
714 	{
715 		// Set up a debug panel
716 		if (MaterialManager::getSingleton().resourceExists("Ogre/DebugTexture" + toStr(i)))
717 			MaterialManager::getSingleton().remove("Ogre/DebugTexture" + toStr(i));
718 		MaterialPtr debugMat = MaterialManager::getSingleton().create(
719 			"Ogre/DebugTexture" + toStr(i),
720 			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
721 		debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false);
722 		//TexturePtr depthTexture = compositor->getTextureInstance("mrt_output",i);
723 		//TexturePtr depthTexture = compositor->getTextureInstance("rt_bloom0",0);
724 		TexturePtr depthTexture = mSceneMgr->getShadowTexture(i);
725 		if(!depthTexture.isNull())
726 		{
727 			TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(depthTexture->getName());
728 			t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
729 		}
730 		OverlayContainer* debugPanel;
731 		// destroy container if exists
732 		try
733 		{
734 			if (debugPanel =
735 				static_cast<OverlayContainer*>(
736 					mgr.getOverlayElement("Ogre/DebugTexPanel" + toStr(i)
737 				)))
738 				mgr.destroyOverlayElement(debugPanel);
739 		}
740 		catch (Ogre::Exception&) {}
741 		debugPanel = (OverlayContainer*)
742 			(OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexPanel" + StringConverter::toString(i)));
743 		debugPanel->_setPosition(0.67, i*0.33);
744 		debugPanel->_setDimensions(0.33, 0.33);
745 		debugPanel->setMaterialName(debugMat->getName());
746 		debugPanel->show();
747 		overlay->add2D(debugPanel);
748 		overlay->show();
749 	}
750 	#endif
751 }
752 
753 
754 //  Performs a single loading step.  Actual loading procedure that gets called every frame during load.
755 //---------------------------------------------------------------------------------------------------------------
756 String App::cStrLoad[LS_ALL+1] =
757 	{"LS_CLEANUP","LS_GAME","LS_SCENE","LS_CAR","LS_TER","LS_ROAD","LS_OBJS","LS_TREES","LS_MISC","LS_ALL"};
758 
NewGameDoLoad()759 void App::NewGameDoLoad()
760 {
761 	if (curLoadState == LS_ALL)
762 	{
763 		// Loading finished
764 		bLoading = false;
765 		#ifdef DEBUG  //todo: doesnt hide later, why?
766 		LoadingOff();
767 		#endif
768 		mLoadingBar->SetWidth(100.f);
769 
770 		//-  cars need update
771 		for (int i=0; i < carModels.size(); ++i)
772 		{	CarModel* cm = carModels[i];
773 			cm->updTimes = true;
774 			cm->updLap = true;  cm->fLapAlpha = 1.f;
775 		}
776 
777 		//if (pSet->show_fps)
778 		//	mFpsOverlay->show();
779 		//.mSplitMgr->mGuiViewport->setClearEveryFrame(true, FBT_DEPTH);
780 
781 		//.ChampLoadEnd();
782 		/**if (mClient)
783 			boost::this_thread::sleep(boost::posix_time::milliseconds(
784 				3000 * mClient->getId()));  /**/  // Test loading synchronization
785 		//.bLoadingEnd = true;
786 		return;
787 	}
788 	//  Do the next loading step
789 	int perc = 0;
790 	switch (curLoadState)
791 	{
792 		case LS_CLEANUP:	LoadCleanUp();	perc = 3;	break;
793 		case LS_GAME:		LoadGame();		perc = 10;	break;
794 		case LS_SCENE:		LoadScene();	perc = 20;	break;
795 		case LS_CAR:		LoadCar();		perc = 30;	break;
796 
797 		case LS_TERRAIN:	LoadTerrain();	perc = 40;	break;
798 		case LS_ROAD:		LoadRoad();		perc = 50;	break;
799 		case LS_OBJECTS:	LoadObjects();	perc = 60;	break;
800 		case LS_TREES:		LoadTrees();	perc = 70;	break;
801 
802 		case LS_MISC:		LoadMisc();		perc = 80;	break;
803 	}
804 
805 	//  Update bar,txt
806 	txLoad->setCaption(TR("#{"+cStrLoad[curLoadState]+"}"));
807 	mLoadingBar->SetWidth(perc);
808 
809 	//  next loading step
810 	++curLoadState;
811 }
812 
813 
814 //---------------------------------------------------------------------------------------------------------------
815 ///  Road  * * * * * * *
816 //---------------------------------------------------------------------------------------------------------------
817 
CreateRoad()818 void App::CreateRoad()
819 {
820 	///  road  ~ ~ ~
821 	SplineRoad*& road = scn->road;
822 	Camera* cam = *mSplitMgr->mCameras.begin();
823 
824 	//  road
825 	if (dstTrk)
826 	{
827 		scn->DestroyRoad();//
828 
829 		road = new SplineRoad(pGame);  // sphere.mesh
830 		road->Setup("", 0.7,  scn->terrain, mSceneMgr, cam);
831 
832 		String sr = gcom->TrkDir()+"road.xml";
833 		road->LoadFile(gcom->TrkDir()+"road.xml");
834 	}else
835 		road->mCamera = cam;  // upd
836 
837 
838 	//  pace ~ ~
839 	scn->DestroyPace();
840 
841 	if (!bHideHudPace)
842 	{
843 		scn->pace = new PaceNotes(pSet);
844 		scn->pace->Setup(mSceneMgr, cam, scn->terrain, gui->mGui, mWindow);
845 	}
846 
847 
848 	//  after road load we have iChk1 so set it for carModels
849 	for (int i=0; i < carModels.size(); ++i)
850 		carModels[i]->ResetChecks(true);
851 
852 	if (dstTrk)
853 	{
854 		scn->UpdPSSMMaterials();  ///+~-
855 
856 		road->bCastShadow = pSet->shadow_type >= Sh_Depth;
857 		road->bRoadWFullCol = pSet->gui.collis_roadw;
858 
859 		road->RebuildRoadInt();
860 		road->SetChecks();  // 2nd, upd
861 	}
862 
863 
864 	//  pace ~ ~
865 	if (scn->pace)
866 	{
867 		road->RebuildRoadPace();  //todo: load only..
868 		scn->pace->Rebuild(road, scn->sc, pSet->game.trackreverse);
869 	}
870 }
871