1 #include "pch.h"
2 #include "Def_Str.h"
3 #include "Gui_Def.h"
4 #include "GuiCom.h"
5 #include "../../road/Road.h"
6 #include "../../vdrift/pathmanager.h"
7 #include "data/SceneXml.h"
8 #include "data/TracksXml.h"
9 #include "data/CData.h"
10 #include "CScene.h"
11 #ifndef SR_EDITOR
12 #include "../../vdrift/game.h"
13 #include "../CGame.h"
14 #include "../CHud.h"
15 #include "../CGui.h"
16 #include "../SplitScreen.h"
17 #else
18 #include "../../editor/CApp.h"
19 #include "../../editor/CGui.h"
20 #include "../../editor/settings.h"
21 #endif
22 #include "MultiList2.h"
23 #include <OgreRoot.h>
24 #include <OgreMaterialManager.h>
25 #include <OgreSceneManager.h>
26 #include <OgreTerrain.h>
27 #include <OgreRenderWindow.h>
28 #include <MyGUI.h>
29 //#include <MyGUI_Delegate.h>
30 //#include <MyGUI_Widget.h>
31 //#include <MyGUI_EditBox.h>
32 //#include <MyGUI_ImageBox.h>
33 //#include <MyGUI_Gui.h>
34 //#include <MyGUI_Window.h>
35 //#include <MyGUI_TabItem.h>
36 using namespace MyGUI;
37 using namespace Ogre;
38 using namespace std;
39
40
41 /// * * * * CONST * * * *
42 //-----------------------------------------------------------------------------------------------------------
43
44 // track difficulties colors from value
45 const String CGuiCom::clrsDiff[9] = // difficulty
46 {"#60C0FF", "#00FF00", "#60FF00", "#C0FF00", "#FFFF00", "#FFC000", "#FF6000", "#FF4040", "#FF7090"};
47 const String CGuiCom::clrsRating[6] = // rating
48 {"#808080", "#606060", "#7090A0", "#60C8D8", "#A0D0F0", "#E0F0FF"};
49 const String CGuiCom::clrsLong[10] = // long
50 {"#E0D0D0", "#E8C0C0", "#F0B0B0", "#F8A0A0", "#FF9090", "#FF8080", "#F07070", "#F06060", "#E04040", "#D03030"};
51
52
53 // * * * * CONST * * * *
54 // column widths in MultiList2, track detailed
55 const int wi = 17; // id name nm N scn ver
56 const int CGuiCom::colTrk[32] = {40, 90, 80, 25, 70, 25, wi, wi, wi, wi, wi, wi, wi, wi, wi, wi, wi, wi, 24};
57 #ifndef SR_EDITOR
58 const int CGui::colCar[16] = {34, 27, 37, 52, 24}; // car
59 const int CGui::colCh [16] = {16, 200, 120, 50, 80, 80, 60, 40}; // champs
60 const int CGui::colChL[16] = {16, 180, 90, 100, 50, 60, 60, 60, 50}; // challs
61 const int CGui::colSt [16] = {30, 170, 100, 90, 50, 80, 70}; // stages
62 #endif
63
64 // get scenery color string from track name
GetSceneryColor(String name,String * sc)65 String CGuiCom::GetSceneryColor(String name, String* sc)
66 {
67 if (name.length() < 3) return "#707070";
68
69 int id = app->scn->data->tracks->trkmap[name];
70 const TrackInfo* pTrk = id==0 ? 0 : &app->scn->data->tracks->trks[id-1];
71
72 char ch = name.c_str()[0]; // vdr
73 if (ch == 'T' && name.c_str()[1] == 'e') // Test,TestC
74 return (name.length() > 5 && name.c_str()[4] == 'C') ? "#A0C0D0" : "#A0A0A0";
75 else
76 if (pTrk)
77 { //if (sc) *sc = pTrk->scenery;
78 return scnClr[pTrk->scenery];
79 }
80 else // user *
81 {
82 if (name.c_str()[0]=='*')
83 name = name.substr(1);
84 String ss;
85 size_t p = name.find_first_of("-0123456789");
86 if (p != string::npos)
87 { ss = name.substr(0, p); //LogO(ss);
88 String s1 = scnN[ss]; if (sc) *sc = s1;
89 return scnClr[s1];
90 }else
91 { ss += name.c_str()[0];
92 String s1 = scnN[ss]; if (sc) *sc = s1;
93 return scnClr[s1];
94 } }
95 }
96 //-----------------------------------------------------------------------------------------------------------
97
98
99 // Add tracks list item
AddTrkL(std::string name,int user,const TrackInfo * ti)100 void CGuiCom::AddTrkL(std::string name, int user, const TrackInfo* ti)
101 {
102 String sc, c = GetSceneryColor(name, &sc);
103 Mli2 li = trkList;
104
105 // split -
106 string pre, shrt;
107 size_t p = name.find("-"); // Test
108 if (p != string::npos /*&& !(name[0]=='T' && name[1]=='e')*/)
109 {
110 pre = name.substr(0,p);
111 shrt = name.substr(p+1); // short name
112 }else
113 { pre = name; shrt = name; }
114
115 // add name = prefix-short
116 li->addItem(c+ pre, 0);
117 int l = li->getItemCount()-1;
118 li->setSubItemNameAt(1,l, c+ name);
119 li->setSubItemNameAt(2,l, c+ shrt);
120
121 if (!ti) // user (or new) trks
122 { if (!sc.empty())
123 li->setSubItemNameAt(4,l, c+ TR("#{SC_"+sc+"}"));
124 return;
125 }
126 // details
127 li->setSubItemNameAt(3,l, c+ toStr(ti->n/10)+toStr(ti->n%10));
128 li->setSubItemNameAt(4,l, c+ TR("#{SC_"+ti->scenery+"}"));
129 li->setSubItemNameAt(5,l, c+ fToStr(ti->crtver,1,3));
130
131 //list->setSubItemNameAt(4,l, ti->created); list->setSubItemNameAt(5,l, ti->modified);
132 #define toS(clr,v) (v > 0) ? (String(clr)+" "+toStr(v)) : " "
133 li->setSubItemNameAt(6,l, toS(clrsDiff[ti->diff], ti->diff));
134 li->setSubItemNameAt(7,l, toS(clrsRating[ti->rating], ti->rating));
135
136 //todo: rateuser drivenlaps
137 li->setSubItemNameAt(8,l, toS("#D070A0",ti->objects));
138 li->setSubItemNameAt(9,l, toS("#C09060",ti->obstacles));
139 li->setSubItemNameAt(10,l,toS("#80C0FF",ti->fluids));
140 li->setSubItemNameAt(11,l,toS("#40FF00",ti->bumps));
141 li->setSubItemNameAt(12,l,toS("#FFA030",ti->jumps));
142 li->setSubItemNameAt(13,l,toS("#00FFFF",ti->loops));
143 li->setSubItemNameAt(14,l,toS("#FFFF00",ti->pipes));
144 li->setSubItemNameAt(15,l,toS("#C0C0C0",ti->banked));
145 li->setSubItemNameAt(16,l,toS("#C080FF",ti->frenzy));
146 li->setSubItemNameAt(17,l,toS(clrsLong[ti->longn], ti->longn));
147 //li->setSubItemNameAt(18,l,clrsDiff[std::min(8, 5*ti->sum/10)]+" "+toStr(ti->sum));
148 }
149
150
initMiniPos(int i)151 void CGuiCom::initMiniPos(int i)
152 {
153 imgMiniPos[i] = fImg(i==0 ? "TrackPos" : "TrackPos2");
154 imgMiniRot[i] = imgMiniPos[i]->getSubWidgetMain()->castType<RotatingSkin>();
155 IntSize si = imgMiniPos[i]->getSize();
156 imgMiniRot[i]->setCenter(IntPoint(si.width*0.7f, si.height*0.7f)); //0.5?
157 }
158
159
160 // Gui Init [Track] once
161 //-----------------------------------------------------------------------------------------------------------
GuiInitTrack()162 void CGuiCom::GuiInitTrack()
163 {
164 Tbi trktab = fTbi("TabTrack");
165 Mli2 li = trktab->createWidget<MultiList2>("MultiListBox",0,0,500,300, Align::Left | Align::VStretch);
166 li->setColour(Colour(0.8,0.9,0.8)); li->setInheritsAlpha(false);
167 trkList = li;
168 li->eventListChangePosition += newDelegate(this, &CGuiCom::listTrackChng);
169 li->setVisible(false);
170
171 // preview images
172 imgPrv[0] = fImg("TrackImg"); imgPrv[0]->setImageTexture("PrvView");
173 imgTer[0] = fImg("TrkTerImg"); imgTer[0]->setImageTexture("PrvTer");
174 imgMini[0] = fImg("TrackMap"); imgMini[0]->setImageTexture("PrvRoad");
175 initMiniPos(0);
176
177 // stats text
178 int i, st;
179 #ifdef SR_EDITOR
180 st = 9;
181 #else
182 st = StTrk;
183 #endif
184 for (i=0; i < st; ++i) stTrk[0][i] = fTxt("st"+toStr(i));
185 for (i=0; i < 4; ++i) imStTrk[0][i] = fImg("ist"+toStr(i));
186 for (i=0; i < InfTrk; ++i){ infTrk[0][i] = fTxt("ti"+toStr(i)); imInfTrk[0][i] = fImg("iti"+toStr(i)); }
187
188 EdC(edTrkFind, "TrkFind", editTrkFind);
189
190 ButtonPtr btn;
191 BtnC("TrkView1", btnTrkView1); imgTrkIco1 = fImg("TrkView2icons1");
192 BtnC("TrkView2", btnTrkView2); imgTrkIco2 = fImg("TrkView2icons2");
193 BtnC("TrkFilter", btnTrkFilter);
194 SV* sv; Ck* ck;
195 ck= &ckTrkFilter; ck->Init("TracksFilter", &pSet->tracks_filter); CevC(TrkFilter);
196 txtTracksFAll = fTxt("TracksFAll");
197 txtTracksFCur = fTxt("TracksFCur");
198
199 // columns ----
200 li->removeAllColumns(); int c=0;
201 li->addColumn("#C0E0C0""id", colTrk[c++]); // prefix
202 li->addColumn("#D0FFD0"+TR("#{Name}"), colTrk[c++]); // full
203 li->addColumn("#E0FFE0"+TR("#{Name}"), colTrk[c++]); // short
204
205 li->addColumn("#80FF80""N", colTrk[c++]);
206 li->addColumn("#80FFC0"+TR("#{Scenery}"), colTrk[c++]);
207 li->addColumn("#80FF80""ver", colTrk[c++]); // created- modified-
208
209 li->addColumn("#C0D0FF""diff", colTrk[c++]); //todo: rateuser, drivenlaps ..
210 li->addColumn("#C0E0FF""*", colTrk[c++]); // rating
211
212 li->addColumn("#FF80C0""o", colTrk[c++]); // objects
213 li->addColumn("#C09060""c", colTrk[c++]); // obstacles
214 li->addColumn("#80C0FF""f", colTrk[c++]); // fluids
215 li->addColumn("#40FF00""B", colTrk[c++]); // Bumps
216 li->addColumn("#FFA030""J", colTrk[c++]); // Jumps
217 li->addColumn("#00FFFF""L", colTrk[c++]); // Loops
218 li->addColumn("#FFFF00""P", colTrk[c++]); // Pipes
219 li->addColumn("#C0C0C0""b", colTrk[c++]); // banked
220 li->addColumn("#C080FF""f", colTrk[c++]); // frenzy
221 li->addColumn("#FFA0A0""l", colTrk[c++]); // longn
222 //li->addColumn("#9060FF""E", colTrk[c++]); // sigma
223 li->addColumn(" ", colTrk[c++]);
224
225 // columns, filters ---
226 for (i=0; i < COL_VIS; ++i)
227 {
228 ck= &ckTrkColVis[i]; ck->Init("col"+toStr(i), &pSet->col_vis[pSet->tracks_view][i]); CevC(TrkColVis);
229 }
230 //ChkUpd_Col();
231 for (i=0; i < COL_FIL; ++i)
232 { string si = toStr(i);
233 int a = pSet->colFil[0][i], b = pSet->colFil[1][i];
234 sv= &svTrkFilMin[i]; sv->Init("min"+si, &pSet->col_fil[0][i], a,b); sv->DefaultI(a); SevC(TrkFil);
235 sv= &svTrkFilMax[i]; sv->Init("max"+si, &pSet->col_fil[1][i], a,b); sv->DefaultI(b); SevC(TrkFil);
236 }
237
238 FillTrackLists(); //once
239
240 li->mSortColumnIndex = pSet->tracks_sort;
241 li->mSortUp = pSet->tracks_sortup;
242
243 TrackListUpd(true); //upd
244 listTrackChng(trkList,0); //-
245
246 ChangeTrackView();
247 }
248
ChkUpd_Col()249 void CGuiCom::ChkUpd_Col()
250 {
251 for (int i=0; i < COL_VIS; ++i)
252 ckTrkColVis[i].Upd(&pSet->col_vis[pSet->tracks_view][i]);
253 }
254
255
256 // done once to fill tracks list from dirs
257 //-----------------------------------------------------------------------------------------------------------
FillTrackLists()258 void CGuiCom::FillTrackLists()
259 {
260 liTracks.clear(); liTracksUser.clear();
261 std::string chkfile = "/scene.xml";
262
263 PATHMANAGER::DirList(pathTrk[0], liTracks);
264 PATHMANAGER::DirList(pathTrk[1], liTracksUser); //name duplicates
265 if (liTracks.size() == 0)
266 LogO("Error: NO tracks !!! in data/tracks/ crashing.");
267
268 // original
269 strlist::iterator i;
270 i = liTracks.begin();
271 while (i != liTracks.end())
272 {
273 std::string s = pathTrk[0] + *i + chkfile;
274 if (!PATHMANAGER::FileExists(s))
275 i = liTracks.erase(i);
276 else ++i;
277 }
278 // user
279 i = liTracksUser.begin();
280 while (i != liTracksUser.end())
281 {
282 std::string s = pathTrk[1] + *i + chkfile;
283 if (!PATHMANAGER::FileExists(s))
284 i = liTracksUser.erase(i);
285 else ++i;
286 }
287
288 // get info for track name, from data->tracks
289 liTrk.clear();
290 for (strlist::iterator i = liTracks.begin(); i != liTracks.end(); ++i)
291 {
292 TrkL trl; trl.name = *i; //trl.pA = this;
293 int id = app->scn->data->tracks->trkmap[*i];
294 const TrackInfo* pTrk = id==0 ? 0 : &app->scn->data->tracks->trks[id-1];
295 trl.ti = pTrk; // 0 if not in data->tracks
296 liTrk.push_back(trl);
297 }
298 }
299
300
301 /// . . util tracks stats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
302 //----------------------------------------------------------------------------------------------------------------
303
ReadTrkStats()304 void CGuiCom::ReadTrkStats()
305 {
306 String sRd = PathListTrk() + "/road.xml";
307 String sSc = PathListTrk() + "/scene.xml";
308
309 Scene* sc = new Scene(); sc->LoadXml(sSc); // fails to defaults
310 #ifndef SR_EDITOR // game
311 SplineRoad rd(app->pGame); rd.LoadFile(sRd,false); // load
312
313 TIMER tim; tim.Load(PATHMANAGER::Records()+"/"+ pSet->gui.sim_mode+"/"+ sListTrack+".txt", 0.f);
314 tim.AddCar(app->gui->sListCar);
315
316 bool reverse = sc->denyReversed ? false : pSet->gui.trackreverse;
317 app->gui->ckReverse.setVisible(!sc->denyReversed); //
318 UpdGuiRdStats(&rd,sc, sListTrack, tim.GetBestLap(0, reverse), reverse, 0);
319 #else
320 SplineRoad rd(app); rd.LoadFile(sRd,false); // load
321 UpdGuiRdStats(&rd,sc, sListTrack, 0.f, false, 0);
322 #endif
323 delete sc;
324 }
325
326 #ifndef SR_EDITOR // game
ReadTrkStatsChamp(String track,bool reverse)327 void CGui::ReadTrkStatsChamp(String track, bool reverse)
328 {
329 String sRd = gcom->pathTrk[0] + track + "/road.xml";
330 String sSc = gcom->pathTrk[0] + track + "/scene.xml";
331
332 Scene* sc = new Scene(); sc->LoadXml(sSc); // fails to defaults
333 SplineRoad rd(pGame); rd.LoadFile(sRd,false); // load
334
335 TIMER tim; tim.Load(PATHMANAGER::Records()+"/"+ pSet->gui.sim_mode+"/"+ track+".txt", 0.f);
336 tim.AddCar(sListCar);
337
338 gcom->UpdGuiRdStats(&rd,sc, track, tim.GetBestLap(0, reverse), reverse, 1);
339 }
340 #endif
341
342
343 #ifndef SR_EDITOR // game
TrkDir()344 String CGuiCom::TrkDir() {
345 int u = pSet->game.track_user ? 1 : 0; return pathTrk[u] + pSet->game.track + "/"; }
346 #else
TrkDir()347 String CGuiCom::TrkDir() {
348 int u = pSet->gui.track_user ? 1 : 0; return pathTrk[u] + pSet->gui.track + "/"; }
349 #endif
350
PathListTrk(int user)351 String CGuiCom::PathListTrk(int user) {
352 int u = user == -1 ? bListTrackU : user; return pathTrk[u] + sListTrack; }
353
PathListTrkPrv(int user,String track)354 String CGuiCom::PathListTrkPrv(int user, String track) {
355 int u = user == -1 ? bListTrackU : user; return pathTrk[u] + track + "/preview/"; }
356
357
TrackExists(String name)358 bool CGuiCom::TrackExists(String name/*, bool user*/)
359 {
360 // ignore letters case..
361 for (strlist::const_iterator it = liTracks.begin(); it != liTracks.end(); ++it)
362 if (*it == name) return true;
363 for (strlist::const_iterator it = liTracksUser.begin(); it != liTracksUser.end(); ++it)
364 if (*it == name) return true;
365 return false;
366 }
367
368
UpdGuiRdStats(const SplineRoad * rd,const Scene * sc,const String & sTrack,float timeCur,bool reverse,int ch)369 void CGuiCom::UpdGuiRdStats(const SplineRoad* rd, const Scene* sc, const String& sTrack,
370 float timeCur, bool reverse, int ch)
371 {
372 #ifndef SR_EDITOR // game
373 bool mph = pSet->show_mph;
374 #else
375 bool mph = false;
376 #endif
377 float m = mph ? 0.621371f : 1.f;
378 String km = mph ? TR(" #{UnitMi}") : TR(" #{UnitKm}");
379 String sm = TR(" #{UnitM}");
380
381 // road stats
382 //---------------------------------------------------------------------------
383 stTrk[ch][1]->setCaption(fToStr(sc->td.fTerWorldSize*0.001f*m ,1,3) + km);
384 if (!rd) return;
385 float len = rd->st.Length; //3,5
386 stTrk[ch][0]->setCaption(fToStr(len*0.001f*m ,1,3) + km);
387
388 stTrk[ch][2]->setCaption(fToStr(rd->st.WidthAvg ,1,3) + sm);
389 stTrk[ch][3]->setCaption(fToStr(rd->st.HeightDiff ,0,2) + sm);
390
391 bool h = rd->st.Pipes > 99.f && rd->st.OnTer > 99.f; // hide bridge 100% when pipe is 100%
392 float a;
393 stTrk[ch][4]->setCaption(fToStr(rd->st.OnTer ,0,1)/*+"%"*/);
394 a = h || rd->st.OnTer < 1.f ? 0.f : (0.5f + 0.5f * rd->st.OnTer / 100.f);
395 stTrk[ch][4]->setAlpha(a); imStTrk[ch][0]->setAlpha(a);
396
397 stTrk[ch][5]->setCaption(fToStr(rd->st.Pipes ,0,1)/*+"%"*/);
398 a = rd->st.Pipes < 1.f ? 0.f : (0.4f + 0.4f * rd->st.Pipes / 100.f);
399 stTrk[ch][5]->setAlpha(a); imStTrk[ch][1]->setAlpha(a);
400
401 stTrk[ch][6]->setCaption(fToStr(rd->st.bankAvg,0,1)+"\'");
402 stTrk[ch][7]->setCaption(fToStr(rd->st.bankMax,0,1)+"\'");
403 a = std::min(1.f, 0.3f + 0.7f * rd->st.bankMax / 80.f); //rd->st.bankAvg / 30.f);
404 stTrk[ch][6]->setAlpha(a); stTrk[ch][7]->setAlpha(a); imStTrk[ch][2]->setAlpha(a);
405
406 stTrk[ch][8]->setCaption(fToStr(rd->st.OnPipe,0,1)/*+"%"*/);
407 a = rd->st.OnPipe < 0.1f ? 0.f : (0.5f + 0.5f * rd->st.OnPipe / 100.f);
408 stTrk[ch][8]->setAlpha(a); imStTrk[ch][3]->setAlpha(a);
409
410 #ifndef SR_EDITOR
411 if (app->gui->txTrackAuthor)
412 app->gui->txTrackAuthor->setCaption(""); // user trks
413 #endif
414
415 int id = app->scn->data->tracks->trkmap[sTrack];
416 for (int i=0; i < InfTrk; ++i)
417 if (infTrk[ch][i]) infTrk[ch][i]->setCaption("");
418 if (id > 0)
419 { const TrackInfo& ti = app->scn->data->tracks->trks[id-1];
420
421 #define str0(v) ((v)==0 ? "" : toStr(v))
422 #define inf(i,t,m) infTrk[ch][i]->setCaption(str0(t));\
423 imInfTrk[ch][i]->setAlpha(t==0 ? 0.f : std::min(1.f, 0.2f + 0.8f * float(t)/m))
424
425 inf(0, ti.fluids,5); inf(1, ti.bumps, 4);
426 inf(2, ti.jumps, 3); inf(3, ti.loops, 4); inf(4, ti.pipes, 5);
427 inf(5, ti.banked,4); inf(6, ti.frenzy,4);
428 inf(7, ti.obstacles,3); inf(8, ti.objects,3);
429
430 infTrk[ch][11]->setCaption(clrsLong[ti.longn] + str0(ti.longn));
431 a = ti.longn / 9.f;
432 imInfTrk[ch][11]->setAlpha(a); infTrk[ch][11]->setAlpha(0.5f + 0.5f * a);
433 infTrk[ch][9]->setCaption(ti.diff==0 ? "" : (clrsDiff[ti.diff] + toStr(ti.diff)));
434 imInfTrk[ch][9]->setAlpha(0.2f + 0.8f * ti.diff / 6.f);
435 infTrk[ch][10]->setCaption(ti.rating==0 ? "" : (clrsRating[ti.rating] + toStr(ti.rating)));
436 imInfTrk[ch][10]->setAlpha(0.2f + 0.8f * ti.rating / 5.f);
437
438 #ifndef SR_EDITOR
439 if (app->gui->txTrackAuthor)
440 app->gui->txTrackAuthor->setCaption(ti.author=="CH" ? "CryHam" : ti.author);
441 #endif
442 }
443
444 #ifndef SR_EDITOR // game
445 // best time, avg vel
446 std::string unit = mph ? TR(" #{UnitMph}") : TR(" #{UnitKmh}");
447 m = pSet->show_mph ? 2.23693629f : 3.6f;
448
449 // track time
450 float carMul = app->GetCarTimeMul(pSet->gui.car[0], pSet->gui.sim_mode);
451 float timeTrk = app->scn->data->tracks->times[sTrack];
452 bool noTrk = timeTrk < 2.f;
453 std::string speedTrk = fToStr(len / timeTrk * m, 0,3) + unit;
454 float timeT = (/*place*/1 * app->scn->data->cars->magic * timeTrk + timeTrk) / carMul;
455 bool no = timeCur < 0.1f || !rd;
456 if (ch==1) no = false; // show track's not current
457
458 stTrk[ch][9]->setCaption(StrTime(noTrk ? 0.f : timeT));
459 stTrk[ch][10]->setCaption(noTrk ? "--" : speedTrk);
460
461 if (ch==0)
462 if (no)
463 { stTrk[ch][11]->setCaption(StrTime(0.f));
464 stTrk[ch][12]->setCaption("--");
465 stTrk[ch][13]->setCaption("--");
466 }else
467 { // car record
468 std::string speed = fToStr(len / timeCur * m, 0,3) + unit;
469 stTrk[ch][11]->setCaption(StrTime(timeCur));
470 stTrk[ch][12]->setCaption(speed);
471 // points
472 float points = 0.f;
473 app->GetRacePos(timeCur, timeTrk, carMul, false, &points);
474 stTrk[ch][13]->setCaption(fToStr(points ,1,3));
475 }
476 #else
477 if (app->gui->trkName) //
478 app->gui->trkName->setCaption(sTrack.c_str());
479 #endif
480 if (trkDesc[ch]) // desc
481 trkDesc[ch]->setCaption(rd->sTxtDesc.c_str());
482
483
484 // preview images
485 //---------------------------------------------------------------------------
486 #ifndef SR_EDITOR
487 if (pSet->dev_no_prvs) return;
488 bool any = pSet->inMenu == MNU_Tutorial || pSet->inMenu == MNU_Champ || pSet->inMenu == MNU_Challenge;
489 #else
490 bool any = false;
491 #endif
492 String path = PathListTrkPrv(any ? 0 : -1, sTrack);
493
494 app->prvView.Load(path+"view.jpg");
495 app->prvRoad.Load(path+"road.png");
496 app->prvTer.Load(path+"terrain.jpg");
497
498
499 // start pos on minimap
500 //---------------------------------------------------------------------------
501 float t = sc->td.fTerWorldSize,
502 xp = sc->startPos[1]/t, yp = sc->startPos[0]/t;
503 const IntSize& si = imgTer[ch]->getSize(), st = imgMiniPos[ch]->getSize();
504 int x = (xp + 0.5f) * si.width - st.width *0.5f,
505 y = (yp + 0.5f) * si.height - st.height*0.5f;
506 imgMiniPos[ch]->setPosition(IntPoint(x,y));
507
508 // rot
509 const float* rot = &sc->startRot[0];
510 Quaternion q(rot[0],rot[1],rot[2],rot[3]);
511 a = q.getPitch().valueRadians();
512 if (reverse) a += PI_d;
513 //static float a=0.f; a+=0.1f; //test center
514 imgMiniRot[ch]->setAngle(a);
515 }
516