1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2014-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "time_client.h"
26 #include "nel/misc/events.h"
27 #include "nel/3d/u_texture.h"
28 #include "nel/misc/i18n.h"
29 #include "continent.h"
31 #include "weather_manager_client.h"
32 #include "interface_v3/input_handler_manager.h"
33 #include "interface_v3/interface_manager.h"
35 #include "net_manager.h"
36 #include "client_cfg.h"
37 #include "user_agent.h"
38 #include "bg_downloader_access.h"
39 #include "nel/misc/system_utils.h"
40 #include "nel/3d/stereo_hmd.h"
43 using namespace NLMISC
;
47 extern void selectTipsOfTheDay (uint tips
);
48 extern NL3D::UMaterial LoadingMaterial
;
49 extern NL3D::UMaterial LoadingMaterialFull
;
51 extern std::vector
<UTextureFile
*> LogoBitmaps
;
52 extern uint TipsOfTheDayIndex
;
53 extern string TipsOfTheDay
;
54 extern bool UseEscapeDuringLoading
;
56 CProgress::CProgress ()
58 _LastUpdate
= ryzomGetLocalTime ();
60 pushCropedValues (0, 1);
61 ApplyTextCommands
= false;
62 _TPCancelFlag
= false;
65 CProgress::~CProgress ()
69 void CProgress::setFontFactor(float temp
)
74 void CProgress::newMessage (const string
& message
)
78 pushCropedValues ((float)_CurrentRootStep
/(float)_RootStepCount
, (float)(_CurrentRootStep
+1)/(float)_RootStepCount
);
81 _ProgressMessage
= message
;
83 // Force call to progress
87 void CProgress::reset (uint rootNodeCount
)
90 _RootStepCount
= rootNodeCount
;
92 pushCropedValues (0, 1/(float)_RootStepCount
);
93 ApplyTextCommands
= false;
98 void CProgress::progress (float value
)
101 sint64 newTime
= ryzomGetLocalTime ();
102 if (newTime
- _LastUpdate
> PROGRESS_BAR_UPDATE
)
104 internalProgress (value
);
106 _LastUpdate
= newTime
;
110 float nextLine (uint fontHeight
, uint windowHeight
, float previousY
)
112 if (windowHeight
> 0)
114 return previousY
-(float)fontHeight
/(float)windowHeight
;
119 void drawLoadingBitmap (float progress
)
121 if (!LoadingMaterial
.empty() && !LoadingMaterialFull
.empty())
123 Driver
->setMatrixMode2D11();
124 LoadingMaterialFull
.setAlphaTestThreshold (1.f
-progress
);
127 uint wh
= Driver
->getWindowHeight();
128 uint ww
= Driver
->getWindowWidth();
134 if ((ww
> 1024) || (wh
> 768))
136 if ((ww
- 1024) > (wh
- 768))
137 x1
= ((ww
- (wh
* 1024.f
) / 768.f
) / 2.f
) / ww
;
139 y1
= ((wh
- (ww
* 768.f
) / 1024.f
) / 2.f
) / wh
;
147 quad
.V0
.set (x1
,y1
,0);
148 quad
.V1
.set (x2
,y1
,0);
149 quad
.V2
.set (x2
,y2
,0);
150 quad
.V3
.set (x1
,y2
,0);
161 Driver
->drawQuad(0, 0, 1, 1, CRGBA(0, 0, 0, 255));
162 Driver
->drawQuad(quad
, LoadingMaterial
);
163 Driver
->drawQuad(quad
, LoadingMaterialFull
);
167 void CProgress::internalProgress (float value
)
170 value
= getCropedValue (value
);
172 // can't do anything if no driver
176 if (Driver
->AsyncListener
.isKeyPushed (KeyDOWN
))
177 selectTipsOfTheDay (TipsOfTheDayIndex
-1);
178 if (Driver
->AsyncListener
.isKeyPushed (KeyUP
))
179 selectTipsOfTheDay (TipsOfTheDayIndex
+1);
181 // Create camera for stereo mode
182 bool stereoHMD
= StereoHMD
&& !MainCam
.empty() && (MainCam
.getTransformMode() == UCamera::RotQuat
);
187 MainCam
.getPos(oldPos
);
188 MainCam
.getRotQuat(oldQuat
);
189 StereoHMD
->setInterfaceMatrix(CMatrix()); // identity
190 NLMISC::CQuat hmdOrient
= StereoHMD
->getOrientation();
191 NLMISC::CMatrix camMatrix
;
192 camMatrix
.identity();
193 NLMISC::CMatrix hmdMatrix
;
194 hmdMatrix
.setRot(hmdOrient
);
195 NLMISC::CMatrix posMatrix
; // minimal head modeling, will be changed in the future
196 posMatrix
.translate(StereoHMD
->getEyePosition());
197 NLMISC::CMatrix mat
= ((camMatrix
* hmdMatrix
) * posMatrix
);
198 MainCam
.setPos(mat
.getPos());
199 MainCam
.setRotQuat(mat
.getRot());
200 StereoDisplay
->updateCamera(0, &MainCam
);
203 while ((!stereoHMD
&& i
== 0) || (stereoHMD
&& StereoDisplay
->nextPass()))
208 // modify cameras for stereo display
209 const CViewport
&vp
= StereoDisplay
->getCurrentViewport();
210 Driver
->setViewport(vp
);
211 StereoDisplay
->getCurrentMatrix(0, &MainCam
);
212 StereoDisplay
->getCurrentFrustum(0, &MainCam
);
214 // begin current pass
215 StereoDisplay
->beginRenderTarget();
217 nldebug("Cam pos: %f, %f, %f", MainCam
.getPos().x
, MainCam
.getPos().y
, MainCam
.getPos().z
);
220 if (!stereoHMD
|| StereoDisplay
->wantClear())
222 Driver
->clearBuffers(CRGBA(0, 0, 0, 0));
225 if (stereoHMD
&& StereoDisplay
->wantScene())
227 Driver
->setMatrixMode3D(MainCam
);
230 if (!stereoHMD
|| StereoDisplay
->wantInterface2D())
232 // nldebug("Draw progress 2D");
235 float fontFactor
= 1;
236 if (Driver
->getWindowHeight() > 0)
237 fontFactor
= (float)Driver
->getWindowHeight() / 600.f
;
238 fontFactor
*= _FontFactor
;
241 Driver
->setMatrixMode2D11();
243 // Display the loading background.
244 drawLoadingBitmap(value
);
246 // temporary values for conversions
247 float x
, y
, width
, height
;
249 for(uint i
= 0; i
< ClientCfg
.Logos
.size(); i
++)
251 std::vector
<string
> res
;
252 explode(ClientCfg
.Logos
[i
], string(":"), res
);
253 if(res
.size()==9 && i
<LogoBitmaps
.size() && LogoBitmaps
[i
]!=NULL
)
255 fromString(res
[1], x
);
256 fromString(res
[2], y
);
257 fromString(res
[3], width
);
258 fromString(res
[4], height
);
259 Driver
->drawBitmap(x
/(float)ClientCfg
.Width
, y
/(float)ClientCfg
.Height
, width
/(float)ClientCfg
.Width
, height
/(float)ClientCfg
.Height
, *LogoBitmaps
[i
]);
263 if (TextContext
!= NULL
)
266 TextContext
->setKeep800x600Ratio(false);
267 TextContext
->setColor(CRGBA(255,255,255));
268 TextContext
->setFontSize((uint
)(12.f
* fontFactor
));
269 TextContext
->setHotSpot(UTextContext::TopRight
);
273 TextContext
->printAt(1, 0.98f
, _ProgressMessage
);
275 if( ClientCfg
.LoadingStringCount
> 0 )
277 TextContext
->printAt(1, 0.98f
, _ProgressMessage
);
279 #endif // FINAL_VERSION
281 // Display the build version.
282 TextContext
->setFontSize((uint
)(12.f
* fontFactor
));
283 TextContext
->setHotSpot(UTextContext::TopRight
);
284 string str
= getDisplayVersion();
285 TextContext
->printfAt(1.0f
,1.0f
, str
.c_str());
287 // Display the tips of the day.
288 TextContext
->setFontSize((uint
)(16.f
* fontFactor
));
289 TextContext
->setHotSpot(UTextContext::MiddleTop
);
290 string::size_type index
= 0;
291 string::size_type end
= TipsOfTheDay
.find('\n');
292 if (end
== string::npos
)
293 end
= TipsOfTheDay
.size();
294 float fY
= ClientCfg
.TipsY
;
295 if (!TipsOfTheDay
.empty())
300 string line
= TipsOfTheDay
.substr (index
, end
-index
);
303 TextContext
->printAt(0.5f
, fY
, line
);
304 fY
= nextLine (TextContext
->getFontSize(), Driver
->getWindowHeight(), fY
);
307 end
= TipsOfTheDay
.find('\n', index
);
308 if (end
== string::npos
)
309 end
= TipsOfTheDay
.size();
313 TextContext
->setFontSize((uint
)(12.f
* fontFactor
));
314 /* todo tips of the day uncomment
315 string ucstr = CI18N::get ("uiTipsEnd");
316 TextContext->printAt(0.5f, fY, ucstr); */
317 fY
= nextLine (TextContext
->getFontSize(), Driver
->getWindowHeight(), fY
);
318 fY
= nextLine (TextContext
->getFontSize(), Driver
->getWindowHeight(), fY
);
323 if (!_TPReason
.empty())
325 TextContext
->setHotSpot(UTextContext::MiddleMiddle
);
326 TextContext
->setFontSize((uint
)(14.f
* fontFactor
));
327 TextContext
->printAt(0.5f
, 0.5f
, _TPReason
);
328 TextContext
->setHotSpot(UTextContext::BottomLeft
);
329 TextContext
->setColor(NLMISC::CRGBA::White
);
334 if (!_TPCancelText
.empty())
336 if (ClientCfg
.Width
!= 0 && ClientCfg
.Height
!= 0)
338 TextContext
->setFontSize((uint
)(15.f
* fontFactor
));
339 TextContext
->setHotSpot(UTextContext::BottomLeft
);
341 string uc
= CI18N::get("uiR2EDTPEscapeToInteruptLoading") + " (" + _TPCancelText
+ ") - " + CI18N::get("uiDelayedTPCancel");
342 UTextContext::CStringInfo info
= TextContext
->getStringInfo(uc
);
343 float stringX
= 0.5f
- info
.StringWidth
/(ClientCfg
.Width
*2);
344 TextContext
->printAt(stringX
, 7.f
/ ClientCfg
.Height
, uc
);
350 //fY = ClientCfg.TeleportInfoY;
351 if (!ApplyTextCommands
&& LoadingContinent
&& !LoadingContinent
->Indoor
)
353 TextContext
->setFontSize((uint
)(13.f
* fontFactor
));
355 // Print some more info
356 uint32 day
= RT
.getRyzomDay();
357 str
= toString (CI18N::get ("uiTipsTeleport").c_str(),
358 CI18N::get (LoadingContinent
->LocalizedName
).c_str(),
360 (uint
)RT
.getRyzomTime(),
361 CI18N::get ("uiSeason"+toStringEnum(CRyzomTime::getSeasonByDay(day
))).c_str(),
362 CI18N::get (WeatherManager
.getCurrWeatherState().LocalizedName
).c_str());
363 TextContext
->setHotSpot(UTextContext::MiddleBottom
);
364 TextContext
->setColor(CRGBA(186, 179, 163, 255));
365 TextContext
->printAt(0.5f
, 25/768.f
, str
);
368 // apply text commands
369 if( ApplyTextCommands
)
371 std::vector
<CClientConfig::SPrintfCommand
> printfCommands
= ClientCfg
.PrintfCommands
;
372 if(FreeTrial
) printfCommands
= ClientCfg
.PrintfCommandsFreeTrial
;
374 if( !printfCommands
.empty() )
376 TextContext
->setHotSpot(UTextContext::MiddleBottom
);
378 vector
<CClientConfig::SPrintfCommand
>::iterator itpc
;
379 for( itpc
= printfCommands
.begin(); itpc
!= printfCommands
.end(); ++itpc
)
381 float x
= 0.5f
;//((*itpc).X / 1024.f);
382 float y
= ((*itpc
).Y
/ 768.f
);
383 TextContext
->setColor( (*itpc
).Color
);
384 TextContext
->setFontSize( (uint
)(16.f
* fontFactor
));
386 // build the ucstr(s)
387 string ucstr
= CI18N::get((*itpc
).Text
);
388 vector
<string
> vucstr
;
390 splitString(ucstr
,sep
,vucstr
);
393 UTextContext::CStringInfo si
= TextContext
->getStringInfo("|");
394 uint fontHeight
= (uint
) si
.StringHeight
+ 2; // we add 2 pixels for the gap
398 for( i
=0; i
<vucstr
.size(); ++i
)
400 TextContext
->printAt(x
,newy
, vucstr
[i
]);
401 newy
= nextLine(fontHeight
, Driver
->getWindowHeight(), newy
);
411 StereoDisplay
->endRenderTarget();
417 MainCam
.setPos(oldPos
);
418 MainCam
.setRotQuat(oldQuat
);
422 clamp (value
, 0.f
, 1.f
);
425 Driver
->setMatrixMode2D11 ();
427 // want to receive the 'mouse down' event to deal with the 'cancel tp button'
428 Driver
->EventServer
.addListener(EventMouseDownId
, this);
431 CInputHandlerManager::getInstance()->pumpEventsNoIM();
433 Driver
->EventServer
.removeListener(EventMouseDownId
, this);
436 bool activeDriver
= Driver
->isActive();
437 if ((UseEscapeDuringLoading
&& Driver
->AsyncListener
.isKeyPushed (KeyESCAPE
)) || !activeDriver
)
439 // Release the application
440 releaseMainLoop(true);
442 // Leave the application
443 extern void quitCrashReport ();
448 if(!_TPCancelText
.empty() && Driver
->AsyncListener
.isKeyPushed(KeySHIFT
) && Driver
->AsyncListener
.isKeyPushed(KeyESCAPE
))
450 _TPCancelFlag
= true;
453 #ifdef RYZOM_BG_DOWNLOADER
454 CBGDownloaderAccess::getInstance().update();
456 // Display to screen.
457 Driver
->swapBuffers();
459 // \todo GUIGUI : Remove this when possible.
461 IngameDbMngr
.flushObserverCalls();
462 NLGUI::CDBManager::getInstance()->flushObserverCalls();
464 // update system dependent progress bar
465 static uint previousValue
= 0;
466 uint currentValue
= (uint
)(value
*100.0f
);
468 if (currentValue
!= previousValue
)
470 CSystemUtils::updateProgressBar(currentValue
, 100);
471 previousValue
= currentValue
;
476 void CProgress::setTPMessages(const string
&tpReason
,const string
&tpCancelText
, const string
&/* iconName */)
478 _TPReason
= tpReason
;
479 _TPCancelText
= tpCancelText
;
483 void CProgress::operator ()(const CEvent
& /* event */)
487 bool CProgress::getTPCancelFlag(bool clearFlag
/*=true*/)
489 bool flag
= _TPCancelFlag
;
492 _TPCancelFlag
= false;
497 void CProgress::release()
499 setTPMessages(string(), string(), string());
500 _TPCancelFlag
= false;
503 void CProgress::finish()
505 // stop system dependent progress bar
506 CSystemUtils::updateProgressBar(1, 0);