1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2020 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 string NewsAtProgress
;
55 extern bool UseEscapeDuringLoading
;
57 CProgress::CProgress ()
59 _LastUpdate
= ryzomGetLocalTime ();
61 pushCropedValues (0, 1);
62 ApplyTextCommands
= false;
63 _TPCancelFlag
= false;
66 CProgress::~CProgress ()
70 void CProgress::setFontFactor(float temp
)
75 void CProgress::newMessage (const string
& message
)
79 pushCropedValues ((float)_CurrentRootStep
/(float)_RootStepCount
, (float)(_CurrentRootStep
+1)/(float)_RootStepCount
);
82 _ProgressMessage
= message
;
84 // Force call to progress
88 void CProgress::reset (uint rootNodeCount
)
91 _RootStepCount
= rootNodeCount
;
93 pushCropedValues (0, 1/(float)_RootStepCount
);
94 ApplyTextCommands
= false;
99 void CProgress::progress (float value
)
102 sint64 newTime
= ryzomGetLocalTime ();
103 if (newTime
- _LastUpdate
> PROGRESS_BAR_UPDATE
)
105 internalProgress (value
);
107 _LastUpdate
= newTime
;
111 float nextLine (uint fontHeight
, uint windowHeight
, float previousY
)
113 if (windowHeight
> 0)
115 return previousY
-(float)fontHeight
/(float)windowHeight
;
120 void drawLoadingBitmap (float progress
)
122 if (!LoadingMaterial
.empty() && !LoadingMaterialFull
.empty())
124 Driver
->setMatrixMode2D11();
125 LoadingMaterialFull
.setAlphaTestThreshold (1.f
-progress
);
128 uint wh
= Driver
->getWindowHeight();
129 uint ww
= Driver
->getWindowWidth();
135 if ((ww
> 1024) || (wh
> 768))
137 if ((ww
- 1024) > (wh
- 768))
138 x1
= ((ww
- (wh
* 1024.f
) / 768.f
) / 2.f
) / ww
;
140 y1
= ((wh
- (ww
* 768.f
) / 1024.f
) / 2.f
) / wh
;
148 quad
.V0
.set (x1
,y1
,0);
149 quad
.V1
.set (x2
,y1
,0);
150 quad
.V2
.set (x2
,y2
,0);
151 quad
.V3
.set (x1
,y2
,0);
162 Driver
->drawQuad(0, 0, 1, 1, CRGBA(0, 0, 0, 255));
163 Driver
->drawQuad(quad
, LoadingMaterial
);
164 Driver
->drawQuad(quad
, LoadingMaterialFull
);
168 void CProgress::internalProgress (float value
)
171 value
= getCropedValue (value
);
173 // can't do anything if no driver
177 if (Driver
->AsyncListener
.isKeyPushed (KeyDOWN
))
178 selectTipsOfTheDay (TipsOfTheDayIndex
-1);
179 if (Driver
->AsyncListener
.isKeyPushed (KeyUP
))
180 selectTipsOfTheDay (TipsOfTheDayIndex
+1);
182 // Create camera for stereo mode
183 bool stereoHMD
= StereoHMD
&& !MainCam
.empty() && (MainCam
.getTransformMode() == UCamera::RotQuat
);
188 MainCam
.getPos(oldPos
);
189 MainCam
.getRotQuat(oldQuat
);
190 StereoHMD
->setInterfaceMatrix(CMatrix()); // identity
191 NLMISC::CQuat hmdOrient
= StereoHMD
->getOrientation();
192 NLMISC::CMatrix camMatrix
;
193 camMatrix
.identity();
194 NLMISC::CMatrix hmdMatrix
;
195 hmdMatrix
.setRot(hmdOrient
);
196 NLMISC::CMatrix posMatrix
; // minimal head modeling, will be changed in the future
197 posMatrix
.translate(StereoHMD
->getEyePosition());
198 NLMISC::CMatrix mat
= ((camMatrix
* hmdMatrix
) * posMatrix
);
199 MainCam
.setPos(mat
.getPos());
200 MainCam
.setRotQuat(mat
.getRot());
201 StereoDisplay
->updateCamera(0, &MainCam
);
204 while ((!stereoHMD
&& i
== 0) || (stereoHMD
&& StereoDisplay
->nextPass()))
209 // modify cameras for stereo display
210 const CViewport
&vp
= StereoDisplay
->getCurrentViewport();
211 Driver
->setViewport(vp
);
212 StereoDisplay
->getCurrentMatrix(0, &MainCam
);
213 StereoDisplay
->getCurrentFrustum(0, &MainCam
);
215 // begin current pass
216 StereoDisplay
->beginRenderTarget();
218 nldebug("Cam pos: %f, %f, %f", MainCam
.getPos().x
, MainCam
.getPos().y
, MainCam
.getPos().z
);
221 if (!stereoHMD
|| StereoDisplay
->wantClear())
223 Driver
->clearBuffers(CRGBA(0, 0, 0, 0));
226 if (stereoHMD
&& StereoDisplay
->wantScene())
228 Driver
->setMatrixMode3D(MainCam
);
231 if (!stereoHMD
|| StereoDisplay
->wantInterface2D())
233 // nldebug("Draw progress 2D");
236 float fontFactor
= 1;
237 if (Driver
->getWindowHeight() > 0)
238 fontFactor
= (float)Driver
->getWindowHeight() / 600.f
;
239 fontFactor
*= _FontFactor
;
242 Driver
->setMatrixMode2D11();
244 // Display the loading background.
245 drawLoadingBitmap(value
);
247 // temporary values for conversions
248 float x
, y
, width
, height
;
250 for(uint i
= 0; i
< ClientCfg
.Logos
.size(); i
++)
252 std::vector
<string
> res
;
253 explode(ClientCfg
.Logos
[i
], string(":"), res
);
254 if(res
.size()==9 && i
<LogoBitmaps
.size() && LogoBitmaps
[i
]!=NULL
)
256 fromString(res
[1], x
);
257 fromString(res
[2], y
);
258 fromString(res
[3], width
);
259 fromString(res
[4], height
);
260 Driver
->drawBitmap(x
/(float)ClientCfg
.Width
, y
/(float)ClientCfg
.Height
, width
/(float)ClientCfg
.Width
, height
/(float)ClientCfg
.Height
, *LogoBitmaps
[i
]);
264 if (TextContext
!= NULL
)
267 TextContext
->setKeep800x600Ratio(false);
268 TextContext
->setColor(CRGBA(255,255,255));
269 TextContext
->setFontSize((uint
)(12.f
* fontFactor
));
270 TextContext
->setHotSpot(UTextContext::TopRight
);
274 TextContext
->printAt(1, 0.98f
, _ProgressMessage
);
276 if( ClientCfg
.LoadingStringCount
> 0 )
278 TextContext
->printAt(1, 0.98f
, _ProgressMessage
);
280 #endif // FINAL_VERSION
282 // Display the build version.
283 TextContext
->setFontSize((uint
)(12.f
* fontFactor
));
284 TextContext
->setHotSpot(UTextContext::TopRight
);
285 string str
= getDisplayVersion();
286 TextContext
->printfAt(1.0f
,1.0f
, str
.c_str());
288 // Display the tips of the day.
289 TextContext
->setFontSize((uint
)(16.f
* fontFactor
));
290 TextContext
->setHotSpot(UTextContext::MiddleTop
);
291 string::size_type index
= 0;
292 string::size_type end
= TipsOfTheDay
.find('\n');
293 if (end
== string::npos
)
294 end
= TipsOfTheDay
.size();
295 float fY
= ClientCfg
.TipsY
;
296 if (!TipsOfTheDay
.empty())
301 string line
= TipsOfTheDay
.substr (index
, end
-index
);
304 TextContext
->printAt(0.5f
, fY
, line
);
305 fY
= nextLine (TextContext
->getFontSize(), Driver
->getWindowHeight(), fY
);
308 end
= TipsOfTheDay
.find('\n', index
);
309 if (end
== string::npos
)
310 end
= TipsOfTheDay
.size();
314 TextContext
->setFontSize((uint
)(12.f
* fontFactor
));
315 /* todo tips of the day uncomment
316 string ucstr = CI18N::get ("uiTipsEnd");
317 TextContext->printAt(0.5f, fY, ucstr); */
318 fY
= nextLine (TextContext
->getFontSize(), Driver
->getWindowHeight(), fY
);
319 fY
= nextLine (TextContext
->getFontSize(), Driver
->getWindowHeight(), fY
);
324 if (!_TPReason
.empty())
326 TextContext
->setHotSpot(UTextContext::MiddleMiddle
);
327 TextContext
->setFontSize((uint
)(14.f
* fontFactor
));
328 TextContext
->printAt(0.5f
, 0.5f
, _TPReason
);
329 TextContext
->setHotSpot(UTextContext::BottomLeft
);
330 TextContext
->setColor(NLMISC::CRGBA::White
);
335 if (!_TPCancelText
.empty())
337 if (ClientCfg
.Width
!= 0 && ClientCfg
.Height
!= 0)
339 TextContext
->setFontSize((uint
)(15.f
* fontFactor
));
340 TextContext
->setHotSpot(UTextContext::BottomLeft
);
342 string uc
= CI18N::get("uiR2EDTPEscapeToInteruptLoading") + " (" + _TPCancelText
+ ") - " + CI18N::get("uiDelayedTPCancel");
343 UTextContext::CStringInfo info
= TextContext
->getStringInfo(uc
);
344 float stringX
= 0.5f
- info
.StringWidth
/(ClientCfg
.Width
*2);
345 TextContext
->printAt(stringX
, 7.f
/ ClientCfg
.Height
, uc
);
351 //fY = ClientCfg.TeleportInfoY;
352 if (!ApplyTextCommands
&& LoadingContinent
&& !LoadingContinent
->Indoor
)
354 TextContext
->setFontSize((uint
)(13.f
* fontFactor
));
356 // Print some more info
357 uint32 day
= RT
.getRyzomDay();
358 str
= toString (CI18N::get ("uiTipsTeleport").c_str(),
359 CI18N::get (LoadingContinent
->LocalizedName
).c_str(),
361 (uint
)RT
.getRyzomTime(),
362 CI18N::get ("uiSeason"+toStringEnum(CRyzomTime::getSeasonByDay(day
))).c_str(),
363 CI18N::get (WeatherManager
.getCurrWeatherState().LocalizedName
).c_str());
364 TextContext
->setHotSpot(UTextContext::MiddleBottom
);
365 TextContext
->setColor(CRGBA(186, 179, 163, 255));
366 TextContext
->printAt(0.5f
, 25/768.f
, str
);
369 // apply text commands
370 if( ApplyTextCommands
)
372 std::vector
<CClientConfig::SPrintfCommand
> loadingTexts
= ClientCfg
.loadingTexts
;
374 if( !loadingTexts
.empty() )
376 TextContext
->setHotSpot(UTextContext::MiddleBottom
);
378 vector
<CClientConfig::SPrintfCommand
>::iterator itpc
;
379 for( itpc
= loadingTexts
.begin(); itpc
!= loadingTexts
.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
)((*itpc
).FontSize
* fontFactor
));
386 // build the ucstr(s)
387 string text
= (*itpc
).Text
;
390 ucstr
= NewsAtProgress
;
392 ucstr
= CI18N::get(text
);
393 vector
<string
> vucstr
;
395 splitString(ucstr
,sep
,vucstr
);
398 UTextContext::CStringInfo si
= TextContext
->getStringInfo("|");
399 uint fontHeight
= (uint
) si
.StringHeight
+ 2; // we add 2 pixels for the gap
403 for( i
=0; i
<vucstr
.size(); ++i
)
405 TextContext
->printAt(x
,newy
, vucstr
[i
]);
406 newy
= nextLine(fontHeight
, Driver
->getWindowHeight(), newy
);
416 StereoDisplay
->endRenderTarget();
422 MainCam
.setPos(oldPos
);
423 MainCam
.setRotQuat(oldQuat
);
427 clamp (value
, 0.f
, 1.f
);
430 Driver
->setMatrixMode2D11 ();
432 // want to receive the 'mouse down' event to deal with the 'cancel tp button'
433 Driver
->EventServer
.addListener(EventMouseDownId
, this);
436 CInputHandlerManager::getInstance()->pumpEventsNoIM();
438 Driver
->EventServer
.removeListener(EventMouseDownId
, this);
441 bool activeDriver
= Driver
->isActive();
442 if ((UseEscapeDuringLoading
&& Driver
->AsyncListener
.isKeyPushed (KeyESCAPE
)) || !activeDriver
)
444 // Release the application
445 releaseMainLoop(true);
447 // Leave the application
448 extern void quitCrashReport ();
453 if(!_TPCancelText
.empty() && Driver
->AsyncListener
.isKeyPushed(KeySHIFT
) && Driver
->AsyncListener
.isKeyPushed(KeyESCAPE
))
455 _TPCancelFlag
= true;
458 #ifdef RYZOM_BG_DOWNLOADER
459 CBGDownloaderAccess::getInstance().update();
461 // Display to screen.
462 Driver
->swapBuffers();
464 // \todo GUIGUI : Remove this when possible.
466 IngameDbMngr
.flushObserverCalls();
467 NLGUI::CDBManager::getInstance()->flushObserverCalls();
469 // update system dependent progress bar
470 static uint previousValue
= 0;
471 uint currentValue
= (uint
)(value
*100.0f
);
473 if (currentValue
!= previousValue
)
475 CSystemUtils::updateProgressBar(currentValue
, 100);
476 previousValue
= currentValue
;
481 void CProgress::setTPMessages(const string
&tpReason
,const string
&tpCancelText
, const string
&/* iconName */)
483 _TPReason
= tpReason
;
484 _TPCancelText
= tpCancelText
;
488 void CProgress::operator ()(const CEvent
& /* event */)
492 bool CProgress::getTPCancelFlag(bool clearFlag
/*=true*/)
494 bool flag
= _TPCancelFlag
;
497 _TPCancelFlag
= false;
502 void CProgress::release()
504 setTPMessages(string(), string(), string());
505 _TPCancelFlag
= false;
508 void CProgress::finish()
510 // stop system dependent progress bar
511 CSystemUtils::updateProgressBar(1, 0);