1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2018 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/>.
29 #include <curl/curl.h>
32 #include "nel/misc/path.h"
33 #include "nel/misc/sheet_id.h"
34 #include "nel/misc/big_file.h"
35 #include "nel/web/curl_certificates.h"
37 #include "nel/3d/bloom_effect.h"
38 #include "nel/3d/u_driver.h"
39 #include "nel/3d/u_scene.h"
40 #include "nel/3d/u_landscape.h"
41 #include "nel/3d/u_camera.h"
42 #include "nel/3d/u_instance.h"
43 #include "nel/3d/u_text_context.h"
44 #include "nel/3d/u_visual_collision_manager.h"
45 #include "nel/3d/u_cloud_scape.h"
46 #include "nel/3d/u_shape_bank.h"
47 #include "nel/3d/u_water_env_map.h"
48 #include "nel/3d/material.h"
49 #include "nel/3d/fxaa.h"
51 #include "nel/sound/u_audio_mixer.h"
53 #include "init_main_loop.h"
55 #include "client_cfg.h"
57 #include "entity_animation_manager.h"
58 #include "actions_client.h"
60 #include "interface_v3/interface_manager.h"
61 #include "interface_v3/people_interraction.h"
63 #include "nel/gui/view_bitmap.h"
65 #include "nel/gui/interface_link.h"
66 #include "cursor_functions.h"
67 #include "pacs_client.h"
68 #include "ig_client.h"
69 #include "light_cycle_manager.h"
70 #include "weather_manager_client.h"
72 #include "nel/3d/u_cloud_scape.h"
74 #include "time_client.h"
75 #include "connection.h"
76 #include "sheet_manager.h"
77 #include "world_database_manager.h"
78 #include "continent_manager.h"
79 #include "continent.h"
80 #include "sky_render.h"
81 #include "nel/gui/group_editbox.h"
82 #include "interface_v3/inventory_manager.h"
83 #include "interface_v3/bot_chat_page_all.h"
84 #include "main_loop.h"
86 #include "net_manager.h"
87 #include "ig_callback.h"
88 #include "lod_character_user_manager.h"
89 //#include "color_slot_manager.h"
91 #include "movie_shooter.h"
92 #include "interface_v3/input_handler_manager.h"
93 #include "item_group_manager.h"
94 #include "time_client.h"
95 #include "auto_anim.h"
97 #include "ig_season_callback.h"
98 #include "ground_fx_manager.h"
99 #include "animation_fx_misc.h"
100 #include "attack_list.h"
101 #include "water_env_map_rdr.h"
103 #include "nel/sound/sound_anim_manager.h"
105 #include "game_share/light_cycle.h"
106 #include "sound_manager.h"
107 #include "precipitation_clip_grid.h"
109 #include "nel/misc/check_fpu.h"
111 #include "landscape_poly_drawer.h"
112 #include "session_browser_impl.h"
113 #include "nel/gui/lua_manager.h"
116 // ProgressBar steps in init main loop
117 #define BAR_STEP_INIT_MAIN_LOOP 22
122 using namespace NLMISC
;
123 using namespace NL3D
;
131 extern bool ReloadUIFlag
;
134 extern bool SetMousePosFirstTime
;
136 extern EGSPD::CSeason::TSeason ManualSeasonValue
;
137 UTextureFile
*LoadingBitmap
= NULL
;
138 UTextureFile
*LoadingBitmapFull
= NULL
;
139 UMaterial LoadingMaterial
;
140 UMaterial LoadingMaterialFull
= NULL
;
141 std::string LoadingBitmapFilename
;
142 uint64 StartInitTime
= 0;
143 uint64 StartPlayTime
= 0;
146 // texture for the logos
147 std::vector
<UTextureFile
*> LogoBitmaps
;
149 // Use the ESCAPE key during loading, in dev version only
151 bool UseEscapeDuringLoading
= USE_ESCAPE_DURING_LOADING
;
154 // ***************************************************************************
155 // MipMap level setup. Don't modify.
156 #define ENTITY_TEXTURE_COARSE_LEVEL 3
157 #define ENTITY_TEXTURE_NORMAL_LEVEL 1
158 #define ENTITY_TEXTURE_HIGH_LEVEL 0
159 // Size in MB of the cache for entity texturing.
160 #define ENTITY_TEXTURE_LOW_MEMORY 10 // 64, 32 or less
161 #define ENTITY_TEXTURE_NORMAL_MEMORY 40 // 128
162 #define ENTITY_TEXTURE_HIGH_MEMORY 80 // 256
163 #define ENTITY_TEXTURE_VERY_HIGH_MEMORY 160 // 512 and more
164 // Size in KB of max upload per frame
165 #define ENTITY_TEXTURE_LOW_MAXUP 64
166 #define ENTITY_TEXTURE_NORMAL_MAXUP 128
167 #define ENTITY_TEXTURE_HIGH_MAXUP 256
169 // Don't Modify, set true for debug purpose only
170 const bool DBG_DisablePreloadShape
= false;
177 struct CStatThread
: public NLMISC::IRunnable
181 //nlinfo("ctor CStatThread");
186 void get(const std::string
&url
)
188 //nlinfo("get '%s'", url.c_str());
189 CURL
*curl
= curl_easy_init();
191 curl_easy_setopt(curl
, CURLOPT_NOPROGRESS
, 1);
192 curl_easy_setopt(curl
, CURLOPT_USERAGENT
, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10 (.NET CLR 3.5.30729)");
193 curl_easy_setopt(curl
, CURLOPT_REFERER
, string("http://www.ryzom.com/" + referer
).c_str());
194 curl_easy_setopt(curl
, CURLOPT_URL
, url
.c_str());
195 if (url
.length() > 8 && (url
[4] == 's' || url
[4] == 'S')) // 01234 https
197 NLWEB::CCurlCertificates::addCertificateFile("cacert.pem");
198 NLWEB::CCurlCertificates::useCertificates(curl
);
199 curl_easy_setopt(curl
, CURLOPT_SSL_VERIFYPEER
, 1L);
200 curl_easy_setopt(curl
, CURLOPT_SSL_VERIFYHOST
, 2L);
202 CURLcode res
= curl_easy_perform(curl
);
203 curl_easy_cleanup(curl
);
204 //curl_global_cleanup();
207 std::string
randomString()
209 std::string chars
= "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
211 for (int i
= 0; i
< 32; i
++)
213 s
+= chars
[uint(frand(float(chars
.size())))];
218 void addParam(std::string
¶ms
, const std::string
&name
, const std::string
&val
)
220 if(val
.empty()) return;
221 if(!params
.empty()) params
+= "&";
222 params
+= name
+"="+val
;
228 if(UserEntity
&& !UserEntity
->getEntityName().empty())
229 name
= UserEntity
->getEntityName();
231 std::string userid
= toString("u%d", NetMngr
.getUserId())+name
;
232 return toUpperAscii(getMD5((const uint8
*)userid
.c_str(), (uint32
)userid
.size()).toString());
235 // return true if we sent the connect because we have all information
239 if(!UserEntity
|| UserEntity
->getEntityName().empty())
242 referer
= ContinentMngr
.getCurrentContinentSelectName();
245 addParam(params
, "ra", randomString());
246 std::string session
= toString("%d%d", NetMngr
.getUserId(), CTime::getSecondsSince1970());
247 addParam(params
, "sessioncookie", toUpperAscii(getMD5((const uint8
*)session
.c_str(), (uint32
)session
.size()).toString()));
248 addParam(params
, "cookie", cookie());
249 addParam(params
, "browsertoken", "X");
250 addParam(params
, "platformtoken", "Win32");
251 addParam(params
, "language", CI18N::getCurrentLanguageCode());
252 addParam(params
, "page", "");
253 addParam(params
, "pagetitle", referer
);
254 addParam(params
, "screen", toString("%dx%d", ClientCfg
.ConfigFile
.getVar("Width").asInt(), ClientCfg
.ConfigFile
.getVar("Height").asInt()));
255 addParam(params
, "referer", "http%3A%2F%2Fwww.ryzom.com%2F" + referer
);
257 struct tm
* timeinfo
;
260 timeinfo
= localtime ( &rawtime
);
261 strftime (buffer
,80,"%H%%3A%M", timeinfo
);
262 addParam(params
, "localtime", buffer
);
263 addParam(params
, "cv_name", UserEntity
->getEntityName());
264 //addParam(params, "cv_email", "");
265 //addParam(params, "cv_avatar", "");
266 addParam(params
, "cv_Userid", toString(NetMngr
.getUserId()));
267 extern TSessionId HighestMainlandSessionId
;
269 switch(HighestMainlandSessionId
.asInt())
271 case 101: shard
= "Aniro"; break; // fr
272 case 102: shard
= "Leanon"; break; // de
273 case 103: shard
= "Arispotle"; break; // en
274 case 301: shard
= "Yubo"; break; // yubo
275 default: shard
= "unknown"; break;
277 addParam(params
, "cv_Shard", shard
);
278 get("http://ryzom.com.woopra-ns.com/visit/"+params
);
286 addParam(params
, "cookie", cookie());
287 addParam(params
, "ra", randomString());
288 get("http://ryzom.com.woopra-ns.com/ping/"+params
);
293 //nlinfo("run CStatThread");
294 bool connected
= false;
300 // connect the first time and every 5 minutes
301 if(!connected
|| t
== 5*60/20)
303 connected
= connect();
307 if(connected
) ping();
313 bool startStat
= false;
315 void startStatThread()
319 curl_global_init(CURL_GLOBAL_ALL
);
320 //nlinfo("startStatThread");
321 CStatThread
*statThread
= new CStatThread();
322 IThread
*thread
= IThread::create (statThread
);
323 nlassert (thread
!= NULL
);
328 //---------------------------------------------------
329 // Generic method to wait for Server Initialisation messages:
330 //---------------------------------------------------
331 inline void waitForNetworkMessage(bool &var
)
335 // Event server get events
336 CInputHandlerManager::getInstance()->pumpEventsNoIM();
339 IngameDbMngr
.flushObserverCalls();
340 NLGUI::CDBManager::getInstance()->flushObserverCalls();
343 // Do not take all the CPU.
348 //---------------------------------------------------
349 // Wait for the user position and ring information
350 //---------------------------------------------------
351 void waitForUserCharReceived()
353 if ((!ClientCfg
.Local
)/*ace&&(!ClientCfg.Light)*/)
355 // Get the position from the server (will fill either UserEntity or UserEntityInitPos/Front)
356 waitForNetworkMessage(UserCharPosReceived
);
360 // Get the position from the cfg.
363 UserEntity
->pos(ClientCfg
.Position
);
364 UserEntity
->front(ClientCfg
.Heading
);
368 UserEntityInitPos
= ClientCfg
.Position
;
369 UserEntityInitFront
= ClientCfg
.Heading
;
372 // Display the start position for the user.
373 const CVectorD
& p
= UserEntity
? UserEntity
->pos() : UserEntityInitPos
;
374 //nlinfo("Start Position: %f %f %f", p.x, p.y, p.z);
378 //---------------------------------------------------
380 // Get the user position at the beginning.
381 //---------------------------------------------------
382 inline void getRyzomTime()
385 // Get the position from the server.
386 if(!ClientCfg.Local && !ClientCfg.Light)
388 while(RT.getRyzomTime() == 0)
390 // Event server get events
391 CInputHandlerManager::getInstance()->pumpEventsNoIM();
394 CCDBNodeBranch::flushObserversCalls();
397 // Do not take all the CPU.
405 //---------------------------------------------------
407 // Get the phrase book at the beginning.
408 //---------------------------------------------------
409 inline void getSabrinaPhraseBook()
411 // Get the position from the server.
412 if ((!ClientCfg
.Local
)/*ace&&(!ClientCfg.Light)*/)
414 waitForNetworkMessage(SabrinaPhraseBookLoaded
);
419 //----------------------------------
420 // Init the weather / day/night mgt
421 //----------------------------------
422 static void initWeather()
424 WeatherManager
.init();
425 // Load description of light cycles for each season.
426 loadWorldLightCycle();
427 // Load global weather function parameters
428 loadWeatherFunctionParams();
430 LightCycleManager
.create();
431 // direction of wind remains the same
432 WeatherManager
.setWindDir(CVector::I
);
436 //---------------------------------------------------
438 // Initialize the main loop.
440 // If you add something in this function, check CFarTP,
441 // some kind of reinitialization might be useful over there.
442 //---------------------------------------------------
445 StartInitTime
= NLMISC::CTime::getLocalTime();
447 Driver
->clearBuffers(CRGBA::Black
);
448 Driver
->swapBuffers();
449 CNiceInputAuto niceInputs
;
450 bool WantStartupProfiling
= false;
453 if( WantStartupProfiling
)
456 NLMISC::CHTimer::startBench();
457 Driver
->startBench();
459 #endif // _PROFILE_ON_
460 { // profile init mainloop
462 H_AUTO ( RZ_Client_InitMainLoop
);
466 NLMISC::TTime initStart
= ryzomGetLocalTime();
467 NLMISC::TTime initLast
= initStart
;
468 NLMISC::TTime initCurrent
= initLast
;
470 // Progress bar for init_main_loop()
471 ProgressBar
.reset (BAR_STEP_INIT_MAIN_LOOP
);
479 LoadingMusic
= ClientCfg
.LoadingMusic
;
481 // SoundMngr->playEventMusic(LoadingMusic, CSoundManager::LoadingMusicXFade, true);
482 // no fadein, and not async because don't work well because of loading in the main thread
483 // Force use GameMusic volume
484 const uint fadeInTime
= 500;
485 SoundMngr
->playMusic(LoadingMusic
, fadeInTime
, false, true, true);
486 // Because of blocking loading, force the fadeIn
487 TTime t0
= ryzomGetLocalTime();
491 ProgressBar
.progress(0);
492 SoundMngr
->updateAudioMixerOnly();
494 } while ((t1
= ryzomGetLocalTime()) < t0
+ fadeInTime
);
497 // Get the interface manager
498 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
502 pIM
->uninitOutGame();
505 initLast
= initCurrent
;
506 initCurrent
= ryzomGetLocalTime();
507 //nlinfo ("PROFILE: %d seconds (%d total) for Uninitializing outgame", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
509 // Create the game interface database
513 // Initialize the Database.
514 nmsg
= "Initializing XML Database ...";
515 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
517 IngameDbMngr
.init(CPath::lookup("database.xml"), ProgressBar
);
518 ICDBNode::CTextId
textId("SERVER");
519 if( NLGUI::CDBManager::getInstance()->getDB()->getNode(textId
, false) )
520 NLGUI::CDBManager::getInstance()->getDB()->removeNode(textId
);
521 NLGUI::CDBManager::getInstance()->getDB()->attachChild(IngameDbMngr
.getNodePtr(),"SERVER");
524 NetMngr
.setDataBase (IngameDbMngr
.getNodePtr());
526 initLast
= initCurrent
;
527 initCurrent
= ryzomGetLocalTime();
528 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing XML database", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
531 // Create interface database
535 // Initialize interface v3 should be done after IngameDbMngr.init()
536 nmsg
= "Initializing Interface Database ...";
537 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
539 // Add the LOCAL branch
540 ICDBNode::CTextId
textId("LOCAL");
541 if( NLGUI::CDBManager::getInstance()->getDB()->getNode(textId
, false) )
542 NLGUI::CDBManager::getInstance()->getDB()->removeNode(textId
);
543 pIM
->createLocalBranch(CPath::lookup("local_database.xml"), ProgressBar
);
545 initLast
= initCurrent
;
546 initCurrent
= ryzomGetLocalTime();
547 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing interface", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
551 // Ask and receive the user position to start (Olivier: moved here because needed by initInGame())
552 nmsg
= "Awaiting Start Position ...";
553 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
554 waitForUserCharReceived();
556 initLast
= initCurrent
;
557 initCurrent
= ryzomGetLocalTime();
558 //nlinfo ("PROFILE: %d seconds (%d total) for Awaiting start position", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
563 // display text messages defined in client.cfg
564 ProgressBar
.ApplyTextCommands
= true;
566 // Starting to load data.
567 nmsg
= "Loading data ...";
568 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
573 // Initialize Sound System
574 if(NLSOUND::CSoundAnimManager::instance() == 0)
575 nlwarning("initMainLoop : Sound System not Initialized.");
577 // During load of the game, fade completely out SFX, and leave outgame music
578 // When the game will begin, it will fade in slowly
580 SoundMngr
->setupFadeSound(0.f
, 1.f
);
582 initLast
= initCurrent
;
583 initCurrent
= ryzomGetLocalTime();
584 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing sound", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
589 // Initializing Entities Manager.
590 EntitiesMngr
.release();
591 EntitiesMngr
.initialize(256);
593 initLast
= initCurrent
;
594 initCurrent
= ryzomGetLocalTime();
595 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing Entities manager", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
601 nmsg
= "Creating Scene ...";
602 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
603 Scene
= Driver
->createScene(false);
605 nlerror("initMainLoop : Cannot create a Scene.");
608 if (ClientCfg
.FXAA
&& !FXAA
) FXAA
= new NL3D::CFXAA(Driver
);
610 // use this scene for bloom effect
611 CBloomEffect::getInstance().setScene(Scene
);
613 CLandscapePolyDrawer::getInstance().initLandscapePolyDrawingCallback();
616 // init ground fx manager
617 EntitiesMngr
.getGroundFXManager().init(Scene
, ClientCfg
.GroundFXMaxDist
, ClientCfg
.GroundFXMaxNB
, ClientCfg
.GroundFXCacheSize
);
619 // Get the main camera and check if valid.
620 MainCam
= Scene
->getCam();
622 nlerror("initMainLoop: Cannot Create the main camera.");
624 // setup load balancing
625 Scene
->setPolygonBalancingMode(UScene::PolygonBalancingClamp
);
626 Scene
->setGroupLoadMaxPolygon("Skin", ClientCfg
.SkinNbMaxPoly
);
627 Scene
->setGroupLoadMaxPolygon("Fx", ClientCfg
.FxNbMaxPoly
);
628 Scene
->setMaxSkeletonsInNotCLodForm(ClientCfg
.NbMaxSkeletonNotCLod
);
629 // separate group for mouse/target selection reticle
630 Scene
->setGroupLoadMaxPolygon("SelectionFx", 10000);
631 // enable Scene Lighting
632 Scene
->enableLightingSystem(true);
633 Scene
->setAmbientGlobal(CRGBA::Black
);
635 // Setup the global Wind from cfg.
636 Scene
->setGlobalWindPower(ClientCfg
.GlobalWindPower
);
637 Scene
->setGlobalWindDirection(ClientCfg
.GlobalWindDirection
);
639 // init the clustered sound system
640 if (SoundMngr
!= NULL
)
641 SoundMngr
->getMixer()->initClusteredSound(Scene
, 0.01f
, 100.0f
, 1.0f
);
643 // Create the background scene
644 SceneRoot
= Driver
->createScene(true);
645 // enable Scene Lighting
646 SceneRoot
->enableLightingSystem(true);
647 SceneRoot
->setAmbientGlobal(CRGBA::Black
);
649 initLast
= initCurrent
;
650 initCurrent
= ryzomGetLocalTime();
651 //nlinfo ("PROFILE: %d seconds (%d total) for Creating scene", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
659 // Initialize automatic animation
660 releaseAutoAnimation();
663 // Animate the scene once
666 initLast
= initCurrent
;
667 initCurrent
= ryzomGetLocalTime();
668 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing animation", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
671 UCamera cam2
= SceneRoot
->getCam();
676 computeCurrentFovAspectRatio(fov
, aspectRatio
);
677 cam2
.setPerspective(fov
, aspectRatio
, SceneRootCameraZNear
, SceneRootCameraZFar
);
678 cam2
.setTransformMode(UTransform::RotQuat
);
680 // Initialize the timer.
681 T1
= ryzomGetLocalTime ();
683 // Create the collision manager (Continent has to do some init with it..)
684 CollisionManager
= Scene
->createVisualCollisionManager();
685 if(CollisionManager
== 0)
686 nlwarning("initMainLoop: createVisualCollisionManager had returned 0.");
687 // Set this collision manager the one the scene must use for Shadow Reception on Buildings
688 Scene
->setVisualCollisionManagerForShadow(CollisionManager
);
692 nmsg
= "Initialize Entity Animation Manager ...";
693 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
696 #if FINAL_VERSION == 0
697 if (ClientCfg
.EAMEnabled
)
701 // Create the Entity Animation Manager
702 EAM
= CEntityAnimationManager::getInstance();
703 EAM
->load(ProgressBar
);
707 // init attack list manager
708 CAttackListManager::getInstance().init();
710 // init misc. anim fxs
711 if(!ClientCfg
.Light
&& Scene
)
713 H_AUTO(InitRZAnimFXMisc
)
714 UAnimationSet
*as
= Driver
->createAnimationSet();
715 AnimFXMisc
.init("anim_fx_misc.id_to_string_array", as
, true);
718 initLast
= initCurrent
;
719 initCurrent
= ryzomGetLocalTime();
720 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing Entity Animation Manager", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
725 // Parse the interface InGame
726 nmsg
= "Building Interface ...";
727 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
728 //nlinfo("****** InGame Interface Parsing and Init START ******");
729 pIM
->initInGame(); // must be called after waitForUserCharReceived() because Ring information is used by initInGame()
730 CItemGroupManager::getInstance()->init(); // Init at the same time keys.xml is loaded
731 initLast
= initCurrent
;
732 initCurrent
= ryzomGetLocalTime();
733 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing ingame", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
735 //nlinfo("****** InGame Interface Parsing and Init END ******");
739 // Get the sheet for the user from the CFG.
740 // Initialize the user and add him into the entity manager.
741 // DO IT AFTER: Database, Collision Manager, PACS, scene, animations loaded.
742 CSheetId
userSheet(ClientCfg
.UserSheet
);
743 TNewEntityInfo emptyEntityInfo
;
744 emptyEntityInfo
.reset();
745 EntitiesMngr
.create(0, userSheet
.asInt(), emptyEntityInfo
);
746 nlinfo("Created the user with the sheet %s", ClientCfg
.UserSheet
.c_str());
748 initLast
= initCurrent
;
749 initCurrent
= ryzomGetLocalTime();
750 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing User sheet", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
757 WarningLog
->addNegativeFilter ("findCollisionChains");
758 WarningLog
->addNegativeFilter ("Primitives have moved");
765 initLast
= initCurrent
;
766 initCurrent
= ryzomGetLocalTime();
767 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing Weather", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
771 // Creating Landscape.
774 #if FINAL_VERSION == 0
775 if (ClientCfg
.LandscapeEnabled
)
778 nmsg
= "Creating Landscape ...";
779 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
780 Landscape
= Scene
->createLandscape();
781 if(Landscape
== NULL
)
782 nlerror("initMainLoop : Cannot create a Landscape.");
784 if (!ClientCfg
.Light
)
786 // Setting Landscape UpdateLighting Frequency
787 // Default setup: 1/20. should work well for night/day transition in 30 minutes.
788 // Because all patchs will be updated every 20 seconds => 90 steps.
789 // But enable it only when we enter Night/Day transition, because landscape updateLighting is
790 // still slow (+10% if 1/20).
791 // Hence disable update lighting by default
792 Landscape
->setUpdateLightingFrequency(0);
794 // Enable Additive tiles.
795 Landscape
->enableAdditive(true);
798 if(ClientCfg
.Shadows
)
800 Landscape
->enableReceiveShadowMap(true);
803 // RefineCenter not auto, because ThirdPerson => refine slower
804 Landscape
->setRefineCenterAuto(false);
809 initLast
= initCurrent
;
810 initCurrent
= ryzomGetLocalTime();
811 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing Landscape", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
814 if (!ClientCfg
.Light
)
816 // Create the cloud scape
819 CloudScape
= Scene
->createCloudScape();
822 nlwarning("Can't create cloud scape");
826 initLast
= initCurrent
;
827 initCurrent
= ryzomGetLocalTime();
828 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing Cloudscape", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
834 // setup good day / season before ig are added.
835 RT
.updateRyzomClock(NetMngr
.getCurrentServerTick());
836 updateDayNightCycleHour();
837 StartupSeason
= CurrSeason
= RT
.getRyzomSeason();
838 RT
.updateRyzomClock(NetMngr
.getCurrentServerTick());
839 updateDayNightCycleHour();
840 ManualSeasonValue
= RT
.getRyzomSeason();
842 initLast
= initCurrent
;
843 initCurrent
= ryzomGetLocalTime();
844 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing season", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
849 H_AUTO(InitRZTimedFX
)
851 nmsg
= "Initializing Timed FX...";
852 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
854 CTimedFXManager::getInstance().reset();
855 CTimedFXManager::getInstance().init(Scene
, CClientDate(RT
.getRyzomDay(), (float) RT
.getRyzomTime()),
856 WorldLightCycle
.NumHours
, 15.45646f
, ClientCfg
.MaxNumberOfTimedFXInstances
, 2.f
, // roughly, the size of a tile
857 300.f
); // no env fx should be seen farther than that
859 initLast
= initCurrent
;
860 initCurrent
= ryzomGetLocalTime();
861 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing Timed FX", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
868 // Initialize World and select the right continent.
869 nmsg
= "Loading World ...";
870 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
871 ContinentMngr
.load();
872 ContinentMngr
.select(UserEntity
->pos(), ProgressBar
);
874 initLast
= initCurrent
;
875 initCurrent
= ryzomGetLocalTime();
876 //nlinfo ("PROFILE: %d seconds (%d total) for Loading continent", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
881 // Initialize the collision manager.
885 nmsg
= "Initializing collision manager ...";
886 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
887 CollisionManager
->setLandscape( Landscape
);
889 initLast
= initCurrent
;
890 initCurrent
= ryzomGetLocalTime();
891 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing collision manager", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
897 // Creating Load systems.
898 if (!ClientCfg
.Light
)
900 nmsg
= "Creating LOD managers ...";
901 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
902 // init the LodCharacter Manager. Must do it before SheetMngr.load()
905 LodCharacterUserManager
.init();
908 // init the hlsBankManager.
914 Driver
->loadHLSBank("characters.hlsbank");
916 catch(const Exception
&e
)
918 nlwarning("Can't load HLSBank: %s", e
.what());
921 // setup according to client
922 if (ClientCfg
.HDTextureInstalled
)
926 // only detect amount of video memory if using HD textures
927 if (ClientCfg
.HDEntityTexture
)
929 if (ClientCfg
.VideoMemory
<= 0)
931 // determine video memory using 3D driver
932 videoMemory
= Driver
->getTotalVideoMemory();
934 // if unable to determine, use plaform methods
935 if (videoMemory
<= 0) videoMemory
= CSystemUtils::getTotalVideoMemory();
937 // in the worst case, use default value of 128 MiB
938 if (videoMemory
<= 0) videoMemory
= 128 * 1024;
940 videoMemory
/= 1024; // size in MiB
942 nlinfo("Video memory detected: %d MiB", videoMemory
);
946 // force video memory (at least 32 MiB)
947 videoMemory
= ClientCfg
.VideoMemory
< 32 ? 32:ClientCfg
.VideoMemory
;
949 nlinfo("Video memory forced: %d MiB", videoMemory
);
954 // 32 MiB of VRAM if DivideTextureSizeBy2 else 64 MiB
955 videoMemory
= ClientCfg
.DivideTextureSizeBy2
? 32:64;
958 uint maxText
, maxLevel
, maxup
;
960 if (videoMemory
> 256)
963 maxLevel
= ENTITY_TEXTURE_HIGH_LEVEL
;
964 maxText
= ENTITY_TEXTURE_VERY_HIGH_MEMORY
;
965 maxup
= ENTITY_TEXTURE_HIGH_MAXUP
;
967 else if (videoMemory
> 128)
970 maxLevel
= ENTITY_TEXTURE_HIGH_LEVEL
;
971 maxText
= ENTITY_TEXTURE_HIGH_MEMORY
;
972 maxup
= ENTITY_TEXTURE_HIGH_MAXUP
;
974 else if (videoMemory
> 64)
977 maxLevel
= ENTITY_TEXTURE_NORMAL_LEVEL
;
978 maxText
= ENTITY_TEXTURE_NORMAL_MEMORY
;
979 maxup
= ENTITY_TEXTURE_HIGH_MAXUP
;
984 maxLevel
= ENTITY_TEXTURE_NORMAL_LEVEL
;
985 maxText
= ENTITY_TEXTURE_LOW_MEMORY
;
986 maxup
= ENTITY_TEXTURE_NORMAL_MAXUP
;
989 // setup "v2 texture" (or 512*512) or "v1 texture" (or 256*256)
990 Driver
->setupAsyncTextureLod(ENTITY_TEXTURE_COARSE_LEVEL
, maxLevel
);
991 // Allow a big cache for them
992 Driver
->setupMaxTotalAsyncTextureSize(maxText
*1024*1024);
993 // Allow normal or high upload
994 Driver
->setupAsyncTextureMaxUploadPerFrame(maxup
*1024);
998 /* setup "v1 texture" (or 256*256), but take into account that they are already stored as V1...
999 => remove 1 from the right shit (=> 0,2)
1001 Driver
->setupAsyncTextureLod(ENTITY_TEXTURE_COARSE_LEVEL
-1, ENTITY_TEXTURE_NORMAL_LEVEL
-1);
1002 // Allow a big cache for them
1003 Driver
->setupMaxTotalAsyncTextureSize(ENTITY_TEXTURE_LOW_MEMORY
*1024*1024);
1005 Driver
->setupAsyncTextureMaxUploadPerFrame(ENTITY_TEXTURE_LOW_MAXUP
*1024);
1009 initLast
= initCurrent
;
1010 initCurrent
= ryzomGetLocalTime();
1011 //nlinfo ("PROFILE: %d seconds (%d total) for Creating LOD managers", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1017 // PreLoad Fauna and Characters
1018 if (!ClientCfg
.Light
&& ClientCfg
.PreCacheShapes
)
1020 string
nmsg("Loading character shapes ...");
1021 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1024 // Add a PreLoad Cache the shape bank, with a maximum cache Size => never deleted
1025 const string PreLoadCacheName
= "PreLoad";
1026 Driver
->getShapeBank()->addShapeCache(PreLoadCacheName
);
1027 Driver
->getShapeBank()->setShapeCacheSize(PreLoadCacheName
, 1000000);
1030 H_AUTO(InitRZCharacters
)
1031 // **** Load Characters shapes from BNP
1032 if( CBigFile::getInstance().isBigFileAdded("characters.bnp") )
1034 ProgressBar
.progress (0);
1035 ProgressBar
.pushCropedValues (0, 0.25f
);
1036 if(!DBG_DisablePreloadShape
)
1038 Driver
->getShapeBank()->preLoadShapesFromBNP(PreLoadCacheName
, "characters.bnp", "*.shape", &ProgressBar
);
1040 ProgressBar
.popCropedValues ();
1041 ProgressBar
.progress (0.25f
);
1042 ProgressBar
.pushCropedValues (0.25f
,0.5f
);
1043 if(!DBG_DisablePreloadShape
)
1045 Driver
->getShapeBank()->preLoadShapesFromBNP(PreLoadCacheName
, "characters.bnp", "*.skel", &ProgressBar
);
1047 ProgressBar
.popCropedValues ();
1049 // else Load Characters shapes from the new BNP
1050 else if( CBigFile::getInstance().isBigFileAdded("characters_shapes.bnp") )
1052 ProgressBar
.progress (0);
1053 ProgressBar
.pushCropedValues (0, 0.25f
);
1054 if(!DBG_DisablePreloadShape
)
1056 Driver
->getShapeBank()->preLoadShapesFromBNP(PreLoadCacheName
, "characters_shapes.bnp", "*.shape", &ProgressBar
);
1058 ProgressBar
.popCropedValues ();
1059 ProgressBar
.progress (0.25f
);
1060 ProgressBar
.pushCropedValues (0.25f
,0.5f
);
1061 if(!DBG_DisablePreloadShape
)
1063 Driver
->getShapeBank()->preLoadShapesFromBNP(PreLoadCacheName
, "characters_skeletons.bnp", "*.skel", &ProgressBar
);
1065 ProgressBar
.popCropedValues ();
1067 // else load from shapes dir
1070 ProgressBar
.progress (0);
1071 ProgressBar
.pushCropedValues (0, 0.25f
);
1072 if(!DBG_DisablePreloadShape
)
1074 Driver
->getShapeBank()->preLoadShapesFromDirectory(PreLoadCacheName
,
1075 ClientCfg
.PreLoadPath
.empty() ? "data/3d/common/characters/shapes" : ClientCfg
.PreLoadPath
+ "/characters_shapes",
1076 "*.shape", false, &ProgressBar
);
1078 ProgressBar
.popCropedValues ();
1079 ProgressBar
.progress (0.25f
);
1080 ProgressBar
.pushCropedValues (0.25f
,0.5f
);
1081 if(!DBG_DisablePreloadShape
)
1083 Driver
->getShapeBank()->preLoadShapesFromDirectory(PreLoadCacheName
,
1084 ClientCfg
.PreLoadPath
.empty() ? "data/3d/common/characters/skeletons" : ClientCfg
.PreLoadPath
+ "/characters_skeletons",
1085 "*.skel", false, &ProgressBar
);
1087 ProgressBar
.popCropedValues ();
1093 // **** Same for fauna
1094 if( CBigFile::getInstance().isBigFileAdded("fauna.bnp") )
1096 ProgressBar
.pushCropedValues (0.5f
, 0.75f
);
1097 if(!DBG_DisablePreloadShape
)
1099 Driver
->getShapeBank()->preLoadShapesFromBNP(PreLoadCacheName
, "fauna.bnp", "*.shape", &ProgressBar
);
1101 ProgressBar
.popCropedValues ();
1102 ProgressBar
.progress (0.75f
);
1103 ProgressBar
.pushCropedValues (0.75f
,1);
1104 if(!DBG_DisablePreloadShape
)
1106 Driver
->getShapeBank()->preLoadShapesFromBNP(PreLoadCacheName
, "fauna.bnp", "*.skel", &ProgressBar
);
1108 ProgressBar
.popCropedValues ();
1110 // else load from shapes dir
1111 else if( CBigFile::getInstance().isBigFileAdded("fauna_shapes.bnp") )
1113 ProgressBar
.pushCropedValues (0.5f
, 0.75f
);
1114 if(!DBG_DisablePreloadShape
)
1116 Driver
->getShapeBank()->preLoadShapesFromBNP(PreLoadCacheName
, "fauna_shapes.bnp", "*.shape", &ProgressBar
);
1118 ProgressBar
.popCropedValues ();
1119 ProgressBar
.progress (0.75f
);
1120 ProgressBar
.pushCropedValues (0.75f
,1);
1121 if(!DBG_DisablePreloadShape
)
1123 Driver
->getShapeBank()->preLoadShapesFromBNP(PreLoadCacheName
, "fauna_skeletons.bnp", "*.skel", &ProgressBar
);
1125 ProgressBar
.popCropedValues ();
1127 // else load from shapes dir
1130 ProgressBar
.pushCropedValues (0.5f
, 0.75f
);
1131 if(!DBG_DisablePreloadShape
)
1133 Driver
->getShapeBank()->preLoadShapesFromDirectory(PreLoadCacheName
,
1134 ClientCfg
.PreLoadPath
.empty() ? "data/3d/common/fauna/shapes" : ClientCfg
.PreLoadPath
+ "/fauna_shapes",
1135 "*.shape", false, &ProgressBar
);
1137 ProgressBar
.popCropedValues ();
1138 ProgressBar
.progress (0.75f
);
1139 ProgressBar
.pushCropedValues (0.75f
,1);
1140 if(!DBG_DisablePreloadShape
)
1142 Driver
->getShapeBank()->preLoadShapesFromDirectory(PreLoadCacheName
,
1143 ClientCfg
.PreLoadPath
.empty() ? "data/3d/common/fauna/skeletons" : ClientCfg
.PreLoadPath
+ "/fauna_skeletons",
1144 "*.skel", false, &ProgressBar
);
1146 ProgressBar
.popCropedValues ();
1150 initLast
= initCurrent
;
1151 initCurrent
= ryzomGetLocalTime();
1152 //nlinfo ("PROFILE: %d seconds (%d total) for Loading characters shapes", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1155 bool preloadFXTextures
= true;
1158 nmsg
= "Load FX ...";
1159 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1160 const string PreLoadCacheNameFX
= "PreLoadFX";
1161 Driver
->getShapeBank()->addShapeCache(PreLoadCacheNameFX
);
1162 Driver
->getShapeBank()->setShapeCacheSize(PreLoadCacheNameFX
, 1000000);
1163 if( CBigFile::getInstance().isBigFileAdded("sfx.bnp") )
1165 ProgressBar
.pushCropedValues (0.0f
, 0.5f
);
1166 if(!DBG_DisablePreloadShape
)
1168 Driver
->getShapeBank()->preLoadShapesFromBNP(PreLoadCacheNameFX
, "sfx.bnp", "*.ps", &ProgressBar
, preloadFXTextures
);
1170 ProgressBar
.popCropedValues ();
1171 ProgressBar
.progress (0.5f
);
1172 ProgressBar
.pushCropedValues (0.5f
,1);
1173 if(!DBG_DisablePreloadShape
)
1175 Driver
->getShapeBank()->preLoadShapesFromBNP(PreLoadCacheNameFX
, "sfx.bnp", "*.shape", &ProgressBar
, preloadFXTextures
);
1177 ProgressBar
.popCropedValues ();
1179 // else load from shapes dir
1182 ProgressBar
.pushCropedValues (0.0f
, 0.5f
);
1183 if(!DBG_DisablePreloadShape
)
1185 Driver
->getShapeBank()->preLoadShapesFromDirectory(PreLoadCacheNameFX
,
1186 ClientCfg
.PreLoadPath
.empty() ? "data/3d/common/sfx" : ClientCfg
.PreLoadPath
+ "/sfx",
1187 "*.ps", true, &ProgressBar
, preloadFXTextures
);
1189 ProgressBar
.popCropedValues ();
1190 ProgressBar
.progress (0.5f
);
1191 ProgressBar
.pushCropedValues (0.5f
,1);
1192 if(!DBG_DisablePreloadShape
)
1194 Driver
->getShapeBank()->preLoadShapesFromDirectory(PreLoadCacheNameFX
,
1195 ClientCfg
.PreLoadPath
.empty() ? "data/3d/common/sfx" : ClientCfg
.PreLoadPath
+ "/sfx",
1196 "*.shape", true, &ProgressBar
, preloadFXTextures
);
1198 ProgressBar
.popCropedValues ();
1201 initLast
= initCurrent
;
1202 initCurrent
= ryzomGetLocalTime();
1203 //nlinfo ("PROFILE: %d seconds (%d total) for Loading FX", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1206 bool preloadObjectTextures
= true;
1208 // **** Same for objects
1209 nmsg
= "Load Objects ...";
1210 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1211 const string PreLoadCacheNameObjects
= "PreLoadObjects";
1212 Driver
->getShapeBank()->addShapeCache(PreLoadCacheNameObjects
);
1213 Driver
->getShapeBank()->setShapeCacheSize(PreLoadCacheNameObjects
, 1000000);
1214 if( CBigFile::getInstance().isBigFileAdded("objects.bnp") )
1216 ProgressBar
.pushCropedValues (0.0f
, 1.f
);
1217 if(!DBG_DisablePreloadShape
)
1219 Driver
->getShapeBank()->preLoadShapesFromBNP(PreLoadCacheNameObjects
, "objects.bnp", "*.shape", &ProgressBar
, preloadObjectTextures
);
1221 ProgressBar
.popCropedValues ();
1223 // else load from shapes dir
1226 ProgressBar
.pushCropedValues (0.0f
, 1.f
);
1227 if(!DBG_DisablePreloadShape
)
1229 Driver
->getShapeBank()->preLoadShapesFromDirectory(PreLoadCacheNameObjects
,
1230 ClientCfg
.PreLoadPath
.empty() ? "data/3d/common/objects" : ClientCfg
.PreLoadPath
+ "/objects",
1231 "*.shape", true, &ProgressBar
, preloadObjectTextures
);
1233 ProgressBar
.popCropedValues ();
1236 initLast
= initCurrent
;
1237 initCurrent
= ryzomGetLocalTime();
1238 //nlinfo ("PROFILE: %d seconds (%d total) for Loading object shapes", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1244 ProgressBar
.newMessage (nmsg
);
1245 ProgressBar
.newMessage (nmsg
);
1254 // Initialize Contextual Cursor.
1255 nmsg
= "Initializing Contextual Cursor ...";
1256 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1257 initContextualCursor();
1259 initLast
= initCurrent
;
1260 initCurrent
= ryzomGetLocalTime();
1261 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing Contextual Cursor", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1264 TextContext
->setColor( CRGBA(255,255,255) );
1267 // Load Instance Group.
1268 nmsg
= "Initializing Instances group ...";
1269 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1272 initLast
= initCurrent
;
1273 initCurrent
= ryzomGetLocalTime();
1274 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing Instances group", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1278 // Initialize some other parameters.
1279 nmsg
= "Initializing other parameters ...";
1280 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1282 // Set the Main Camera.
1283 MainCam
.setPerspective(fov
, aspectRatio
, CameraSetupZNear
, ClientCfg
.Vision
);
1284 MainCam
.setTransformMode(UTransform::RotQuat
);
1286 // Initialize the Landscape Parameters.
1287 if (!ClientCfg
.Light
)
1291 Landscape
->setTileNear(ClientCfg
.LandscapeTileNear
); // Set Tile Near.
1292 Landscape
->setThreshold(ClientCfg
.getActualLandscapeThreshold()); // Set Threshold.
1297 Driver
->setAmbientColor(CRGBA(0,0,0));
1302 // temp : update all interface links
1303 CInterfaceLink::updateAllLinks();
1305 // Initialize new interfaces.
1306 nmsg
= "Initialize New Interfaces ...";
1307 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1309 //dbg.init(&Driver->EventServer);
1310 CWidgetManager::getInstance()->activateMasterGroup("ui:login", false);
1311 CWidgetManager::getInstance()->activateMasterGroup("ui:interface", true);
1315 if ( ClientCfg
.R2EDEnabled
)
1317 R2::ReloadUIFlag
= true; // make sure the R2 UI gets reloaded
1320 initLast
= initCurrent
;
1321 initCurrent
= ryzomGetLocalTime();
1322 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing other parameters", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1324 // Display Launching Message.
1325 nmsg
= "Sending \"Ready\" ...";
1326 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1328 if(!ClientCfg
.Local
)
1333 // Update Network till current tick increase.
1334 LastGameCycle
= NetMngr
.getCurrentServerTick();
1335 while(LastGameCycle
== NetMngr
.getCurrentServerTick())
1337 // Event server get events
1338 CInputHandlerManager::getInstance()->pumpEventsNoIM();
1341 IngameDbMngr
.flushObserverCalls();
1342 NLGUI::CDBManager::getInstance()->flushObserverCalls();
1345 // Set the LastGameCycle
1346 LastGameCycle
= NetMngr
.getCurrentServerTick();
1348 // Create the message for the server to create the character.
1350 if(GenericMsgHeaderMngr
.pushNameToStream("CONNECTION:READY", out
))
1352 // transmit language to IOS
1353 out
.serial(ClientCfg
.LanguageCode
);
1355 NetMngr
.send(NetMngr
.getCurrentServerTick());
1358 nlwarning("initMainLoop : unknown message name : 'CONNECTION:READY'.");
1362 // to be sure server crash is not fault of client
1363 ConnectionReadySent
= true;
1365 initLast
= initCurrent
;
1366 initCurrent
= ryzomGetLocalTime();
1367 //nlinfo ("PROFILE: %d seconds (%d total) for Sending \"Ready\"", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1369 // Display Launching Message.
1370 nmsg
= "Launching ...";
1371 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1373 // NLMEMORY::CheckHeap (true);
1375 // Re-initialise the mouse (will be now in hardware mode, if required)
1376 SetMousePosFirstTime
= true;
1377 InitMouseWithCursor (ClientCfg
.HardwareCursor
&& !StereoDisplayAttached
); // the return value of enableLowLevelMouse() has already been tested at startup
1379 // Re-initialise the keyboard, now in low-level mode, if required
1380 // NB nico : done at end of loading
1382 if (!ClientCfg.DisableDirectInput)
1384 Driver->enableLowLevelKeyboard (true); // the return value has already been tested at startup
1388 SetMouseSpeed (ClientCfg
.CursorSpeed
);
1389 SetMouseAcceleration (ClientCfg
.CursorAcceleration
);
1393 // To reset the inputs.
1394 CInputHandlerManager::getInstance()->pumpEventsNoIM();
1396 // Set the default edit box for the enter key
1397 // if (PeopleInterraction.MainChat.Window)
1398 // CWidgetManager::getInstance()->setCaptureKeyboard(PeopleInterraction.MainChat.Window->getEditBox());
1399 if (PeopleInterraction
.ChatGroup
.Window
)
1401 CGroupEditBox
*eb
= dynamic_cast<CGroupEditBox
*>(PeopleInterraction
.ChatGroup
.Window
->getEditBox());
1402 CWidgetManager::getInstance()->setCaptureKeyboard(eb
);
1403 // For user help, set a default input string.
1404 // NB: must do it after interface loadConfig, else it is reseted
1405 // NB: it is reseted also on first mode switch
1407 eb
->setDefaultInputString(CI18N::get("uiDefaultChatInput"));
1410 CWidgetManager::getInstance()->setCaptureKeyboard(NULL
);
1411 CWidgetManager::getInstance()->setCaptureKeyboard(NULL
); // previous set editbox becomes '_OldCaptureKeyboard'
1413 // Some init after connection ready sent
1414 if(BotChatPageAll
&& (!ClientCfg
.R2EDEnabled
))
1415 BotChatPageAll
->initAfterConnectionReady();
1417 initLast
= initCurrent
;
1418 initCurrent
= ryzomGetLocalTime();
1419 //nlinfo ("PROFILE: %d seconds (%d total) for Launching", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1421 nlinfo ("PROFILE: %d seconds for init main loop", (uint32
)(ryzomGetLocalTime ()-initStart
)/1000);
1423 ProgressBar
.ApplyTextCommands
= false;
1424 } // profile init mainloop
1426 if( WantStartupProfiling
)
1429 NLMISC::CHTimer::endBench();
1432 // Display and save profile to a File.
1434 CFileDisplayer
fileDisplayer(NLMISC::CFile::findNewFile(getLogDirectory() + "profile_startup.log"));
1435 log
.addDisplayer(&fileDisplayer
);
1437 NLMISC::CHTimer::displayHierarchicalByExecutionPathSorted(&log
, CHTimer::TotalTime
, true, 48, 2);
1438 NLMISC::CHTimer::display(&log
, CHTimer::TotalTime
);
1439 Driver
->displayBench(&log
);
1441 #endif // _PROFILE_ON_
1444 // init CSessionBrowserImpl
1445 CSessionBrowserImpl::getInstance().init(CLuaManager::getInstance().getLuaState());
1447 // enable/disable welcome window
1448 initWelcomeWindow();
1450 // enable/disable bloom config interface
1451 initBloomConfigUI();
1453 // popup to offer hardware cursor activation
1454 initHardwareCursor();
1456 // disable woopra stats
1457 //startStatThread();
1462 // ***************************************************************************
1464 void destroyLoadingBitmap ()
1466 if (LoadingBitmap
&& Driver
)
1468 // Destroy the Loading Background.
1469 Driver
->deleteTextureFile(LoadingBitmap
);
1470 LoadingBitmap
= NULL
;
1471 LoadingBitmapFilename
.clear();
1472 LoadingMaterial
.setTexture (0, NULL
);
1474 if (LoadingBitmapFull
&& Driver
)
1476 // Destroy the Loading Background.
1477 Driver
->deleteTextureFile(LoadingBitmapFull
);
1478 LoadingBitmapFull
= NULL
;
1479 LoadingMaterialFull
.setTexture (0, NULL
);
1484 // ***************************************************************************
1486 void loadBackgroundBitmap (TBackground background
)
1488 string name
= CFile::getFilenameWithoutExtension (ClientCfg
.Launch_BG
);
1489 string ext
= CFile::getExtension (ClientCfg
.Launch_BG
);
1493 filename
= name
+"_0."+ext
;
1495 filename
= name
+"_1."+ext
;
1498 case ElevatorBackground
:
1499 filename
= ClientCfg
.Elevator_BG
;
1501 case TeleportKamiBackground
:
1502 filename
= ClientCfg
.TeleportKami_BG
;
1504 case TeleportKaravanBackground
:
1505 filename
= ClientCfg
.TeleportKaravan_BG
;
1507 case ResurectKamiBackground
:
1508 filename
= ClientCfg
.ResurectKami_BG
;
1510 case ResurectKaravanBackground
:
1511 filename
= ClientCfg
.ResurectKaravan_BG
;
1514 filename
= ClientCfg
.End_BG
;
1516 case CustomBackground
: // SpecialCase
1517 filename
= LoadingBackgroundBG
;
1520 filename
= ClientCfg
.IntroNVidia_BG
;
1522 case LoadBackground
:
1524 filename
= ClientCfg
.LoadingFreeTrial_BG
;
1526 filename
= ClientCfg
.Loading_BG
;
1532 // Setup the materials
1533 if (LoadingMaterial
.empty())
1535 LoadingMaterial
= Driver
->createMaterial();
1536 LoadingMaterial
.initUnlit();
1538 if (LoadingMaterialFull
.empty())
1540 LoadingMaterialFull
= Driver
->createMaterial();
1541 LoadingMaterialFull
.initUnlit();
1542 LoadingMaterialFull
.setAlphaTest (true);
1545 // Bitmap is not the same ?
1546 if ((filename
!= LoadingBitmapFilename
) && Driver
)
1548 destroyLoadingBitmap ();
1549 LoadingBitmapFilename
= filename
;
1551 // Build a background filename
1552 name
= CFile::getFilenameWithoutExtension (filename
);
1553 ext
= CFile::getExtension (filename
);
1555 if (!CPath::lookup (name
+"_0."+ext
, false, false).empty())
1557 LoadingBitmap
= Driver
->createTextureFile(name
+"_0."+ext
);
1558 LoadingBitmapFull
= Driver
->createTextureFile(name
+"_1."+ext
);
1562 LoadingBitmap
= Driver
->createTextureFile(filename
);
1563 LoadingBitmapFull
= Driver
->createTextureFile(filename
);
1565 LoadingMaterial
.setTexture (0, LoadingBitmap
);
1566 LoadingMaterialFull
.setTexture (0, LoadingBitmapFull
);
1567 nlassert(LoadingBitmap
);
1568 nlassert(LoadingBitmapFull
);
1569 LoadingBitmap
->setAllowDegradation(false);
1570 LoadingBitmapFull
->setAllowDegradation(false);
1572 for(uint i
= 0; i
< ClientCfg
.Logos
.size(); i
++)
1574 std::vector
<string
> res
;
1575 explode(ClientCfg
.Logos
[i
], std::string(":"), res
);
1576 if(res
.size()==9) LogoBitmaps
.push_back(Driver
->createTextureFile(res
[0]));
1582 // ***************************************************************************
1584 void beginLoading (TBackground background
)
1586 LoadingContinent
= NULL
;
1587 if (!LoadingBackgroundBG
.empty())
1589 loadBackgroundBitmap(CustomBackground
);
1590 LoadingBackgroundBG
= "";
1594 loadBackgroundBitmap (background
);
1598 // ***************************************************************************
1602 destroyLoadingBitmap ();
1605 // ***************************************************************************
1607 void setLoadingContinent (CContinent
*continent
)
1609 LoadingContinent
= continent
;
1612 // ***************************************************************************
1614 void initWelcomeWindow()
1616 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1617 CInterfaceGroup
* welcomeWnd
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:welcome_info"));
1620 bool welcomeDbProp
= NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:WELCOME")->getValueBool();
1621 CSessionBrowserImpl
&sb
= CSessionBrowserImpl::getInstance();
1622 welcomeWnd
->setActive((sb
.CurrentJoinMode
!=CFarTP::LaunchEditor
) && welcomeDbProp
);
1626 // ***************************************************************************
1628 // NOTE: This feature is not really used anymore, it is a patch transition
1629 void initHardwareCursor(bool secondCall
)
1631 CInterfaceManager
* pIM
= CInterfaceManager::getInstance();
1632 CSessionBrowserImpl
&sb
= CSessionBrowserImpl::getInstance();
1634 string nodeName
= "UI:SAVE:HARDWARE_CURSOR";
1635 CCDBNodeLeaf
* node
= NLGUI::CDBManager::getInstance()->getDbProp(nodeName
);
1639 if(!ClientCfg
.HardwareCursor
&& !node
->getValueBool())
1641 // if save cfg file, just crush HardwareCursor variable value
1642 if(ClientCfg
.SaveConfig
)
1644 ClientCfg
.writeBool("HardwareCursor", true);
1645 ClientCfg
.ConfigFile
.save ();
1646 ClientCfg
.IsInvalidated
= true;
1648 // else, only the first time after this patch, open popup to propose hardare cursor mode
1651 CInterfaceGroup
* cursorWnd
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:hardware_cursor"));
1654 cursorWnd
->setActive((sb
.CurrentJoinMode
!=CFarTP::LaunchEditor
) || secondCall
);
1655 CWidgetManager::getInstance()->setTopWindow(cursorWnd
);
1656 cursorWnd
->updateCoords();
1657 cursorWnd
->center();
1662 if(!node
->getValueBool() && ((sb
.CurrentJoinMode
!=CFarTP::LaunchEditor
) || secondCall
))
1664 node
->setValueBool(true);
1669 nlwarning("setDbProp(): '%s' dbProp Not found", nodeName
.c_str());
1673 // ***************************************************************************
1674 void initBloomConfigUI()
1676 bool supportBloom
= Driver
->supportBloomEffect();
1678 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1680 CCtrlBaseButton
* button
= dynamic_cast<CCtrlBaseButton
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:game_config:content:fx:bloom_gr:bloom:c"));
1683 button
->setFrozen(!supportBloom
);
1686 button
= dynamic_cast<CCtrlBaseButton
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:game_config:content:fx:bloom_gr:square_bloom:c"));
1689 button
->setFrozen(!supportBloom
);
1692 button
= dynamic_cast<CCtrlBaseButton
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:game_config:content:fx:fxaa:c"));
1695 button
->setFrozen(!supportBloom
);
1698 CCtrlScroll
* scroll
= dynamic_cast<CCtrlScroll
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:game_config:content:fx:bloom_gr:density_bloom:c"));
1701 scroll
->setFrozen(!supportBloom
);
1704 CInterfaceGroup
* group
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:game_config:content:fx:bloom_gr"));
1709 group
->setDefaultContextHelp(CI18N::get("uiFxTooltipBloom"));
1711 ClientCfg
.writeBool("FXAA", false);
1712 ClientCfg
.writeBool("Bloom", false);
1713 ClientCfg
.writeBool("SquareBloom", false);
1714 ClientCfg
.writeInt("DensityBloom", 0);
1719 group
->setDefaultContextHelp(std::string());