Fix css style order when using external css files
[ryzomcore.git] / ryzom / client / src / init.cpp
blob88a2cbb51b45ac46b30c8e60ff42b90250fb0cdb
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2011 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2010 Robert TIMM (rti) <mail@rtti.de>
6 // Copyright (C) 2010-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
8 //
9 // This program is free software: you can redistribute it and/or modify
10 // it under the terms of the GNU Affero General Public License as
11 // published by the Free Software Foundation, either version 3 of the
12 // License, or (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU Affero General Public License for more details.
19 // You should have received a copy of the GNU Affero General Public License
20 // along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "stdpch.h"
27 //////////////
28 // INCLUDES //
29 //////////////
30 // Misc.
31 #include "nel/misc/debug.h"
32 #include "nel/misc/displayer.h"
33 #include "nel/misc/path.h"
34 #include "nel/misc/i18n.h"
35 #include "nel/misc/log.h"
36 #include "nel/misc/sheet_id.h"
37 #include "nel/misc/report.h"
38 #include "nel/misc/class_registry.h"
39 #include "nel/misc/system_info.h"
40 #include "nel/misc/block_memory.h"
41 #include "nel/misc/system_utils.h"
42 #include "nel/misc/streamed_package_manager.h"
43 #include "nel/web/http_package_provider.h"
44 #include "nel/misc/cmd_args.h"
45 // 3D Interface.
46 #include "nel/3d/bloom_effect.h"
47 #include "nel/3d/u_driver.h"
48 #include "nel/3d/u_text_context.h"
49 #include "nel/3d/u_shape_bank.h"
50 #include "nel/3d/stereo_hmd.h"
51 // Net.
52 #include "nel/net/email.h"
53 // Ligo.
54 #include "nel/ligo/ligo_config.h"
56 // Client
57 #include "init.h"
58 #include "input.h"
59 #include "client_cfg.h" // Configuration of the client.
60 #include "actions_client.h"
61 #include "color_slot_manager.h"
62 #include "movie_shooter.h"
63 #include "continent_manager.h"
64 #include "interface_v3/animal_position_state.h"
65 //#include "osd_client.h"
66 #include "debug_client.h"
67 #include "ingame_database_manager.h"
68 #include "client_chat_manager.h"
69 #include "interface_v3/input_handler_manager.h"
70 #include "interface_v3/interface_manager.h"
71 //#include "crtdbg.h"
72 #include "sound_manager.h"
73 #include "net_manager.h"
74 #include "sheet_manager.h"
76 #include "interface_v3/sbrick_manager.h"
77 #include "nel/gui/widget_manager.h"
78 #include "nel/gui/http_cache.h"
79 #include "nel/gui/http_hsts.h"
81 #include "gabarit.h"
82 #include "hair_set.h"
83 //#include "starting_roles.h"
85 #include "init_main_loop.h"
87 #include "resource.h"
89 #include "time_client.h"
90 #include "pacs_client.h"
91 #include "interface_v3/music_player.h"
93 #include "input.h"
94 #include "interface_v3/add_on_manager.h"
96 #include "bg_downloader_access.h"
97 #include "user_agent.h"
99 #include "nel/misc/check_fpu.h"
101 #include "login_progress_post_thread.h"
103 #include "browse_faq.h"
105 // XMLLib
106 #include <libxml/xmlmemory.h>
108 #ifdef NL_OS_WINDOWS
109 #include <windows.h>
110 extern HINSTANCE HInstance;
111 extern HWND SlashScreen;
112 #endif // NL_OS_WINDOWS
114 #ifdef NL_OS_MAC
115 #include <stdio.h>
116 #include <sys/resource.h>
117 #include "nel/misc/dynloadlib.h"
118 #endif
120 #include "app_bundle_utils.h"
122 #include <new>
124 #ifdef DEBUG_NEW
125 #define new DEBUG_NEW
126 #endif
128 ///////////
129 // USING //
130 ///////////
131 using namespace NLMISC;
132 using namespace NLNET;
133 using namespace NL3D;
134 using namespace NLLIGO;
135 using namespace std;
137 // NVIDIA recommanded drivers
138 #define NVIDIA_RECOMMANDED_DRIVERS UINT64_CONSTANT(0x0006000e000a1820)
139 #define NVIDIA_RECOMMANDED_DRIVERS_STRING_TEST "nvidia"
140 #define NVIDIA_RECOMMANDED_DRIVERS_STRING_NTEST "go"
141 #define NVIDIA_RECOMMANDED_DRIVERS_VENDOR "NVIDIA"
142 #define NVIDIA_RECOMMANDED_DRIVERS_URL "http://www.nvidia.com/drivers"
144 // ATI recommanded drivers
145 #define ATI_RECOMMANDED_DRIVERS UINT64_CONSTANT(0x0006000e000a191e)
146 #define ATI_RECOMMANDED_DRIVERS_STRING_TEST "radeon"
147 #define ATI_RECOMMANDED_DRIVERS_VENDOR "ATI Technologies Inc."
148 #define ATI_RECOMMANDED_DRIVERS_URL "http://www.ati.com/support/driver.html"
150 // ProgressBar steps in init / connection phase
151 #define BAR_STEP_INIT_CONNECTION 17
153 /////////////
154 // GLOBALS //
155 /////////////
156 // Ligo primitive class
157 CLigoConfig LigoConfig;
159 CClientChatManager ChatMngr;
161 bool LastScreenSaverEnabled = false;
164 extern void registerInterfaceElements();
165 extern CContinentManager ContinentMngr;
167 extern NLMISC::CCmdArgs Args;
169 // Tips of the day count
170 #define RZ_NUM_TIPS 17
171 std::string TipsOfTheDay;
172 uint TipsOfTheDayIndex;
174 // includes for following register classes
175 #include "entities.h"
176 #include "character_cl.h"
177 #include "player_cl.h"
178 #include "user_entity.h"
179 #include "fx_cl.h"
180 #include "item_cl.h"
182 ///////////////
183 // FUNCTIONS //
184 ///////////////
186 // ***************************************************************************
189 // XML allocator functions
190 // Due to Bug #906, we disable the stl xml allocation
192 static volatile bool XmlAllocUsesSTL = true;
194 static std::allocator<uint8> xmlStlAlloc;
198 void XmlFree4NeL (void *ptr)
200 // if (XmlAllocUsesSTL)
202 int size = *(((int *) ptr) - 1);
203 xmlStlAlloc.deallocate((uint8 *) ptr - sizeof(int), size + sizeof(int));
205 // else
206 // {
207 // MemoryDeallocate (ptr);
208 // }
211 void *XmlMalloc4NeL (size_t size)
213 // if (XmlAllocUsesSTL)
215 int *newB = (int *) xmlStlAlloc.allocate(size + sizeof(int));
216 *newB = (int)size;
217 return (void *) (newB + 1);
219 // else
220 // {
221 // return MemoryAllocate(size);
222 // }
225 void *XmlRealloc4NeL (void *ptr, size_t size)
227 // if (XmlAllocUsesSTL)
229 if (ptr == NULL) return XmlMalloc4NeL(size);
230 int oldSize = *(((int *) ptr) - 1);
231 if (oldSize == (int) size) return ptr;
232 void *newB = XmlMalloc4NeL(size);
233 memcpy(newB, ptr, std::min(oldSize, (int) size));
234 XmlFree4NeL(ptr);
235 return newB;
237 // else
238 // {
239 // // Get the block size
240 // return MemoryReallocate (ptr, size);
241 // }
244 char *XmlStrdup4NeL (const char *str)
246 nlassert (str);
247 char *newStr;
248 // if (XmlAllocUsesSTL)
250 newStr = (char *) XmlMalloc4NeL(strlen (str)+1);
252 // else
253 // {
254 // newStr = (char*)MemoryAllocate(strlen (str)+1);
255 // }
256 strcpy (newStr, str);
257 return newStr;
262 #ifdef NL_OS_WINDOWS
265 static std::wstring CurrentErrorMessage;
267 static INT_PTR CALLBACK ExitClientErrorDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM /* lParam */)
269 switch(uMsg)
271 case WM_INITDIALOG:
273 if (CI18N::hasTranslation("TheSagaOfRyzom"))
275 if (!SetWindowTextW(hwndDlg, nlUtf8ToWide(CI18N::get("TheSagaOfRyzom").c_str())))
277 nlwarning("SetWindowText failed: %s", formatErrorMessage(getLastError()).c_str());
280 SetDlgItemTextW(hwndDlg, IDC_ERROR_MSG_TEXT, (WCHAR*)CurrentErrorMessage.c_str());
281 if (CI18N::hasTranslation("uiRyzomErrorMsgBoxExit"))
283 SetDlgItemTextW(hwndDlg, IDOK, nlUtf8ToWide(CI18N::get("uiRyzomErrorMsgBoxExit").c_str()));
285 if (CI18N::hasTranslation("uiRyzomErrorMsgBoxHelp"))
287 SetDlgItemTextW(hwndDlg, IDC_RYZOM_ERROR_HELP, nlUtf8ToWide(CI18N::get("uiRyzomErrorMsgBoxHelp").c_str()));
289 RECT rect;
290 RECT rectDesktop;
291 GetWindowRect (hwndDlg, &rect);
292 GetWindowRect (GetDesktopWindow (), &rectDesktop);
293 SetWindowPos (hwndDlg, HWND_TOPMOST, (rectDesktop.right-rectDesktop.left-rect.right+rect.left)/2, (rectDesktop.bottom-rectDesktop.top-rect.bottom+rect.top)/2, 0, 0, SWP_NOSIZE);
294 HICON exitClientDlgIcon = LoadIcon(HInstance, MAKEINTRESOURCE(IDI_MAIN_ICON));
295 ::SendMessageA(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) exitClientDlgIcon);
297 break;
298 case WM_COMMAND:
299 switch(LOWORD(wParam))
301 case IDOK:
302 EndDialog(hwndDlg, IDOK);
303 break;
304 case IDC_RYZOM_ERROR_HELP:
306 if (Driver)
308 HWND wnd = Driver->getDisplay();
309 ShowWindow(wnd, SW_MINIMIZE);
311 browseFAQ(ClientCfg.ConfigFile);
312 EndDialog(hwndDlg, IDOK);
314 break;
316 break;
317 case WM_CLOSE:
318 EndDialog(hwndDlg, IDOK);
319 break;
321 return FALSE;
324 #endif
328 // Use this function to return an error to the final user and exit the client
329 void ExitClientError (const char *format, ...)
331 char *str;
332 NLMISC_CONVERT_VARGS (str, format, 256/*NLMISC::MaxCStringSize*/);
334 // Driver ?
335 if (Driver)
337 Driver->release();
340 #ifdef NL_OS_WINDOWS
341 CurrentErrorMessage = NLMISC::utf8ToWide(str);
342 DialogBox(HInstance, MAKEINTRESOURCE(IDD_ERROR_HELP_MESSAGE_BOX), NULL, ExitClientErrorDialogProc);
344 MessageBoxW (NULL, nlUtf8ToWide(str.c_str()), nlUtf8ToWide(CI18N::get("TheSagaOfRyzom").c_str()), MB_OK|MB_ICONERROR);
346 #else
347 fprintf (stderr, "%s\n", str);
348 #endif
349 // Exit
350 extern void quitCrashReport ();
351 quitCrashReport ();
352 NLMISC::NL3D_BlockMemoryAssertOnPurge = false; // at this point some object may remain allocated
353 // so don't want to fire an assert here
354 exit (EXIT_FAILURE);
357 // Use this function to return an information to the final user
358 void ClientInfo (const std::string &message)
360 #ifdef NL_OS_WINDOWS
361 MessageBoxW(NULL, nlUtf8ToWide(message.c_str()), nlUtf8ToWide(CI18N::get("TheSagaOfRyzom").c_str()), MB_OK|MB_ICONINFORMATION);
362 #endif
365 // Use this function to ask a question to the final user
366 bool ClientQuestion (const std::string &message)
368 #ifdef NL_OS_WINDOWS
369 return MessageBoxW(NULL, nlUtf8ToWide(message.c_str()), nlUtf8ToWide(CI18N::get("TheSagaOfRyzom").c_str()), MB_YESNO|MB_ICONQUESTION) != IDNO;
370 #else
371 return false;
372 #endif
375 void selectTipsOfTheDay (uint /* tips */)
377 /* todo tips of the day uncomment
378 tips %= RZ_NUM_TIPS;
379 TipsOfTheDayIndex = tips;
380 string title = CI18N::get ("uiTipsTitle");
381 title += toString (tips+1);
382 title += " : ";
383 TipsOfTheDay = title+CI18N::get ("uiTips"+toString (tips));*/
384 // todo tips of the day remove
385 //trap TipsOfTheDay = CI18N::get ("uiMessageOfTheDay");
386 TipsOfTheDay.clear(); //trap
389 // ***************************************************************************
391 // For nel memory
392 void outOfMemory()
394 nlstopex (("OUT OF MEMORY"));
397 uint64 Debug_OldCPUMask = 0;
398 uint64 Debug_NewCPUMask = 0;
400 // For multi cpu, active only one CPU for the main thread
401 void setCPUMask(uint64 userCPUMask)
403 uint64 cpuMask = IProcess::getCurrentProcess()->getCPUMask();
404 Debug_OldCPUMask = cpuMask;
406 // if user CPU mask is valid
407 if (cpuMask & userCPUMask)
409 // use it
410 IProcess::getCurrentProcess ()->setCPUMask(cpuMask & userCPUMask);
412 else
414 // else get first available CPU
416 // get the processor to allow process
417 uint i = 0;
418 while ((i < 64) && ((cpuMask & (UINT64_CONSTANT(1) << i)) == 0))
419 i++;
421 // Set the CPU mask
422 if (i < 64)
424 IProcess::getCurrentProcess ()->setCPUMask(UINT64_CONSTANT(1) << i);
428 // check
429 cpuMask = IProcess::getCurrentProcess ()->getCPUMask();
430 Debug_NewCPUMask = cpuMask;
433 void displayCPUInfo()
435 nlinfo("CPUInfo: CPUMask before change: %x, after change: %x, CPUID: %x, hasHyperThreading: %s", (uint32)Debug_OldCPUMask, (uint32)Debug_NewCPUMask, CSystemInfo::getCPUID(), (CSystemInfo::hasHyperThreading()?"YES":"NO"));
438 string getVersionString (uint64 version)
440 return toString ("%u.%u.%u.%u", (unsigned int) (version >> 48), (unsigned int) ((version >> 32) & 0xffff), (unsigned int) ((version >> 16) & 0xffff), (unsigned int) (version & 0xffff));
444 string getSystemInformation()
446 string s;
447 s += "Memory: " + bytesToHumanReadable(CSystemInfo::availablePhysicalMemory()) + "/" + bytesToHumanReadable(CSystemInfo::totalPhysicalMemory()) + "\n";
448 s += "Process Virtual Memory: " + bytesToHumanReadable(CSystemInfo::virtualMemory()) + "\n";
449 s += "OS: " + CSystemInfo::getOS() + "\n";
450 s += "Processor: " + CSystemInfo::getProc() + "\n";
451 s += toString("CPUID: %x\n", CSystemInfo::getCPUID());
452 s += toString("HT: %s\n", CSystemInfo::hasHyperThreading()?"YES":"NO");
453 s += toString("CpuMask: %x\n", IProcess::getCurrentProcess ()->getCPUMask());
456 if(Driver)
457 s += "NeL3D: " + string(Driver->getVideocardInformation()) + "\n";
458 else
459 s += "NeL3D: No driver\n";
461 // More display info
462 string deviceName;
463 uint64 driverVersion;
464 if (CSystemInfo::getVideoInfo (deviceName, driverVersion))
466 s += "3DCard: ";
467 s += deviceName;
468 s += ", version ";
469 s += getVersionString (driverVersion) + "\n";
472 if (SoundMngr && SoundMngr->getMixer())
473 SoundMngr->getMixer()->writeProfile (s);
474 else
475 s += "No sound\n";
477 return s;
480 static string crashCallback()
482 string s = getDebugInformation();
483 s += getSystemInformation();
485 #ifdef NL_OS_WINDOWS
486 if (Driver)
488 NL3D::UDriver::CMode mode;
489 Driver->getCurrentScreenMode(mode);
490 if (!mode.Windowed)
492 HWND wnd = Driver->getDisplay();
493 ShowWindow(wnd, SW_MINIMIZE);
496 #endif
499 return s;
502 void checkDriverVersion()
504 string deviceName;
505 uint64 driverVersion;
506 if (CSystemInfo::getVideoInfo (deviceName, driverVersion))
508 static uint64 driversVersion[]=
510 NVIDIA_RECOMMANDED_DRIVERS,
511 ATI_RECOMMANDED_DRIVERS
513 static const char *driversTest[]=
515 NVIDIA_RECOMMANDED_DRIVERS_STRING_TEST,
516 ATI_RECOMMANDED_DRIVERS_STRING_TEST
518 static const char *driversNTest[]=
520 NVIDIA_RECOMMANDED_DRIVERS_STRING_NTEST,
521 NULL
523 static const char *driversURL[]=
525 NVIDIA_RECOMMANDED_DRIVERS_URL,
526 ATI_RECOMMANDED_DRIVERS_URL
528 static const char *driversVendor[]=
530 NVIDIA_RECOMMANDED_DRIVERS_VENDOR,
531 ATI_RECOMMANDED_DRIVERS_VENDOR,
534 uint i;
535 for (i=0; i< sizeofarray(driversVersion); i++)
537 string lwr = toLowerAscii(deviceName);
538 if ((lwr.find (driversTest[i])!=string::npos) && (driversNTest[i]==NULL || lwr.find (driversNTest[i])==string::npos))
540 if (driverVersion < driversVersion[i])
542 string message = CI18N::get ("uiUpdateDisplayDriversNotUpToDate") + "\n\n";
543 // message += CI18N::get ("uiUpdateDisplayDriversVendor") + driversVendor[i] + "\n";
544 message += CI18N::get ("uiUpdateDisplayDriversCard") + deviceName + "\n";
545 message += CI18N::get ("uiUpdateDisplayDriversCurrent") + getVersionString (driverVersion) + "\n";
546 message += CI18N::get ("uiUpdateDisplayDriversRecommanded") + getVersionString (driversVersion[i]) + "\n\n";
547 message += CI18N::get ("uiUpdateDisplayDrivers") + "\n";
548 if (ClientQuestion (message))
550 openURL(driversURL[i]);
551 extern void quitCrashReport ();
552 quitCrashReport ();
553 exit (EXIT_FAILURE);
556 break;
559 if (i==sizeof (driversVersion)/sizeof(uint))
560 nlwarning ("Unknown video card : %s", deviceName.c_str());
562 else
563 nlwarning ("Can't check video driver version");
566 void checkDriverDepth ()
568 // Check desktop is in 32 bit else no window mode allowed.
569 if (ClientCfg.Windowed)
571 nlassert (Driver);
572 UDriver::CMode mode;
573 Driver->getCurrentScreenMode(mode);
574 #ifdef NL_OS_WINDOWS
575 if (mode.Depth != 32)
576 #else
577 if (mode.Depth != 16 && mode.Depth != 24 && mode.Depth != 32)
578 #endif
579 ExitClientError (CI18N::get ("uiDesktopNotIn32").c_str ());
583 void listStereoDisplayDevices(std::vector<NL3D::CStereoDeviceInfo> &devices)
585 bool cache = VRDeviceCache.empty();
586 nldebug("VR [C]: List devices");
587 if (cache)
589 VRDeviceCache.push_back(std::pair<std::string, std::string>("Auto", "0"));
591 IStereoDisplay::listDevices(devices);
592 for (std::vector<NL3D::CStereoDeviceInfo>::iterator it(devices.begin()), end(devices.end()); it != end; ++it)
594 std::string name = toString("%s - %s - %s", IStereoDisplay::getLibraryName(it->Library), it->Manufacturer.c_str(), it->ProductName.c_str());
595 std::string fullname = toString("[%s] [%s]", name.c_str(), it->Serial.c_str());
596 nlinfo("VR [C]: Stereo Display: %s", name.c_str());
597 if (cache)
599 VRDeviceCache.push_back(std::pair<std::string, std::string>(name, it->Serial)); // VR_CONFIG
604 void cacheStereoDisplayDevices() // VR_CONFIG
606 if (VRDeviceCache.empty())
608 std::vector<NL3D::CStereoDeviceInfo> devices;
609 listStereoDisplayDevices(devices);
613 void initStereoDisplayDevice()
615 if (ClientCfg.VREnable)
617 // VR_CONFIG
618 nldebug("VR [C]: Enabled");
619 std::vector<NL3D::CStereoDeviceInfo> devices;
620 listStereoDisplayDevices(devices);
621 CStereoDeviceInfo *deviceInfo = NULL;
622 if (ClientCfg.VRDisplayDevice == std::string("Auto"))
624 for (std::vector<NL3D::CStereoDeviceInfo>::iterator it(devices.begin()), end(devices.end()); it != end; ++it)
626 if ((*it).AllowAuto)
628 deviceInfo = &(*it);
629 break;
633 else
635 for (std::vector<NL3D::CStereoDeviceInfo>::iterator it(devices.begin()), end(devices.end()); it != end; ++it)
637 std::string name = toString("%s - %s - %s", IStereoDisplay::getLibraryName(it->Library), it->Manufacturer.c_str(), it->ProductName.c_str());
638 if (name == ClientCfg.VRDisplayDevice)
639 deviceInfo = &(*it);
640 if (ClientCfg.VRDisplayDeviceId == it->Serial)
641 break;
644 if (deviceInfo)
646 nlinfo("VR [C]: Create VR stereo display device");
647 StereoDisplay = IStereoDisplay::createDevice(*deviceInfo);
648 if (StereoDisplay)
650 if (deviceInfo->Class == CStereoDeviceInfo::StereoHMD)
652 nlinfo("VR [C]: Stereo display device is a HMD");
653 StereoHMD = static_cast<IStereoHMD *>(StereoDisplay);
655 if (Driver) // VR_DRIVER
657 StereoDisplay->setDriver(Driver);
662 else
664 nldebug("VR [C]: NOT Enabled");
666 IStereoDisplay::releaseUnusedLibraries();
669 // we want to get executable directory
670 static void addPaths(IProgressCallback &progress, const std::vector<std::string> &paths, bool recurse)
672 // all prefixes for paths
673 std::vector<std::string> directoryPrefixes;
675 // current directory has priority everywhere
676 directoryPrefixes.push_back(CPath::standardizePath(CPath::getCurrentPath()));
678 // startup directory
679 directoryPrefixes.push_back(Args.getStartupPath());
681 #if defined(NL_OS_WINDOWS)
682 // check in same directory as executable
683 directoryPrefixes.push_back(Args.getProgramPath());
684 #elif defined(NL_OS_MAC)
685 // check in bundle (Installer)
686 directoryPrefixes.push_back(getAppBundlePath() + "/Contents/Resources/");
688 // check in same directory as bundle (Steam)
689 directoryPrefixes.push_back(CPath::makePathAbsolute(getAppBundlePath() + "/..", ".", true));
690 #elif defined(NL_OS_UNIX)
691 // check in same directory as executable
692 directoryPrefixes.push_back(Args.getProgramPath());
694 // check in installed directory
695 if (CFile::isDirectory(getRyzomSharePrefix())) directoryPrefixes.push_back(CPath::standardizePath(getRyzomSharePrefix()));
696 #endif
698 std::set<std::string> directoriesToProcessSet;
699 std::vector<std::string> directoriesToProcess;
701 // first pass, build a map with all existing directories to process in second pass
702 for (uint j = 0; j < directoryPrefixes.size(); j++)
704 std::string directoryPrefix = directoryPrefixes[j];
706 for (uint i = 0; i < paths.size(); i++)
708 std::string directory = NLMISC::expandEnvironmentVariables(paths[i]);
710 // only prepend prefix if path is relative
711 if (!directory.empty() && !directoryPrefix.empty() && !CPath::isAbsolutePath(directory))
712 directory = directoryPrefix + directory;
714 // only process existing directories
715 if (CFile::isExists(directory))
717 if (directoriesToProcessSet.find(directory) == directoriesToProcessSet.end())
719 directoriesToProcessSet.insert(directory);
720 directoriesToProcess.push_back(directory);
726 // second pass, add search paths
727 for (size_t i = 0; i < directoriesToProcess.size(); ++i)
729 progress.progress((float)i / (float)directoriesToProcess.size());
730 progress.pushCropedValues((float)i / (float)directoriesToProcess.size(), (float)(i + 1) / (float)directoriesToProcess.size());
732 CPath::addSearchPath(directoriesToProcess[i], recurse, false, &progress);
734 progress.popCropedValues();
738 void initStreamedPackageManager(NLMISC::IProgressCallback &progress)
740 CStreamedPackageManager &spm = CStreamedPackageManager::getInstance();
741 nlassert(!spm.Provider); // If this asserts, init was called twice without release
742 nlassert(!HttpPackageProvider); // Idem
743 NLWEB::CHttpPackageProvider *hpp = new NLWEB::CHttpPackageProvider();
744 hpp->Path = ClientCfg.StreamedPackagePath;
745 for (uint i = 0; i < ClientCfg.StreamedPackageHosts.size(); i++)
746 hpp->Hosts.push_back(ClientCfg.StreamedPackageHosts[i]);
747 spm.Provider = hpp;
748 HttpPackageProvider = hpp;
751 void addSearchPaths(IProgressCallback &progress)
753 // Add search path of UI addon. Allow only a subset of files.
754 // Must do it first because take precedence other standard files
755 InterfaceAddOnManager.addSearchFiles("uiaddon", "*.xml;*.lua;*.tga", "login_*.xml;out_v2_*.xml", &progress);
757 // Add Standard search paths
759 H_AUTO(InitRZAddSearchPath2)
761 addPaths(progress, ClientCfg.DataPath, true);
763 CPath::loadRemappedFiles("remap_files.csv");
766 addPaths(progress, ClientCfg.DataPathNoRecurse, false);
769 void addPreDataPaths(NLMISC::IProgressCallback &progress)
771 NLMISC::TTime initPaths = ryzomGetLocalTime ();
773 H_AUTO(InitRZAddSearchPaths);
775 addPaths(progress, ClientCfg.PreDataPath, true);
777 //nlinfo ("PROFILE: %d seconds for Add search paths Predata", (uint32)(ryzomGetLocalTime ()-initPaths)/1000);
780 static void addPackedSheetUpdatePaths(NLMISC::IProgressCallback &progress)
782 for(uint i = 0; i < ClientCfg.UpdatePackedSheetPath.size(); i++)
784 progress.progress((float)i/(float)ClientCfg.UpdatePackedSheetPath.size());
785 progress.pushCropedValues ((float)i/(float)ClientCfg.UpdatePackedSheetPath.size(), (float)(i+1)/(float)ClientCfg.UpdatePackedSheetPath.size());
786 CPath::addSearchPath(NLMISC::expandEnvironmentVariables(ClientCfg.UpdatePackedSheetPath[i]), true, false, &progress);
787 progress.popCropedValues();
791 #if defined(NL_OS_UNIX) && !defined(NL_OS_MAC)
792 static bool addRyzomIconBitmap(const std::string &directory, vector<CBitmap> &bitmaps)
794 if (CFile::isDirectory(directory))
796 // build filename from directory and default ryzom client icon name
797 std::string filename = NLMISC::toString("%s/%s.png", directory.c_str(), getRyzomClientIcon().c_str());
799 if (CFile::fileExists(filename))
801 CIFile file;
803 if (file.open(filename))
805 CBitmap bitmap;
807 if (bitmap.load(file))
809 bitmaps.push_back(bitmap);
810 return true;
816 return false;
818 #endif
820 //---------------------------------------------------
821 // initLog :
822 // Initialize the client.log file
823 //---------------------------------------------------
824 void initLog()
826 // Add a displayer for Debug Infos.
827 createDebug();
829 // Client.Log displayer
830 nlassert( !ErrorLog->getDisplayer("CLIENT.LOG") );
831 CFileDisplayer *ClientLogDisplayer = new CFileDisplayer(getLogDirectory() + "client.log", true, "CLIENT.LOG");
832 DebugLog->addDisplayer (ClientLogDisplayer);
833 InfoLog->addDisplayer (ClientLogDisplayer);
834 WarningLog->addDisplayer (ClientLogDisplayer);
835 ErrorLog->addDisplayer (ClientLogDisplayer);
836 AssertLog->addDisplayer (ClientLogDisplayer);
838 // Display the client version.
839 nlinfo("RYZOM VERSION: %s", getDebugVersion().c_str());
840 nlinfo("Memory: %s/%s", bytesToHumanReadable(CSystemInfo::availablePhysicalMemory()).c_str(), bytesToHumanReadable(CSystemInfo::totalPhysicalMemory()).c_str());
841 nlinfo("OS: %s", CSystemInfo::getOS().c_str());
842 nlinfo("Processor: %s", CSystemInfo::getProc().c_str());
844 #ifdef NL_OS_MAC
845 struct rlimit rlp, rlp2, rlp3;
847 getrlimit(RLIMIT_NOFILE, &rlp);
849 rlim_t value = 1024;
851 rlp2.rlim_cur = std::min(value, rlp.rlim_max);
852 rlp2.rlim_max = rlp.rlim_max;
854 if (setrlimit(RLIMIT_NOFILE, &rlp2))
856 if (errno == EINVAL)
858 nlwarning("Unable to set rlimit with error: the specified limit is invalid");
860 else if (errno == EPERM)
862 nlwarning("Unable to set rlimit with error: the limit specified would have raised the maximum limit value and the caller is not the super-user");
864 else
866 nlwarning("Unable to set rlimit with error: unknown error");
870 getrlimit(RLIMIT_NOFILE, &rlp3);
871 nlinfo("rlimit before %llu %llu", (uint64)rlp.rlim_cur, (uint64)rlp.rlim_max);
872 nlinfo("rlimit after %llu %llu", (uint64)rlp3.rlim_cur, (uint64)rlp3.rlim_max);
874 // add the bundle's plugins path as library search path (for nel drivers)
875 if (CFile::isExists(getAppBundlePath() + "/Contents/PlugIns/nel"))
877 CLibrary::addLibPath(getAppBundlePath() + "/Contents/PlugIns/nel/");
879 #endif
882 //---------------------------------------------------
883 // prelogInit :
884 // Initialize the application before login
885 // if the init fails, call nlerror
886 //---------------------------------------------------
887 void prelogInit()
891 H_AUTO ( RZ_Client_Init );
893 // Assert if no more memory
894 set_new_handler(outOfMemory);
896 NLMISC_REGISTER_CLASS(CStage);
897 NLMISC_REGISTER_CLASS(CStageSet);
898 NLMISC_REGISTER_CLASS(CEntityManager);
899 NLMISC_REGISTER_CLASS(CCharacterCL);
900 NLMISC_REGISTER_CLASS(CPlayerCL);
901 NLMISC_REGISTER_CLASS(CUserEntity);
902 NLMISC_REGISTER_CLASS(CFxCL);
903 NLMISC_REGISTER_CLASS(CItemCL);
904 NLMISC_REGISTER_CLASS(CNamedEntityPositionState);
905 NLMISC_REGISTER_CLASS(CAnimalPositionState);
907 // Progress bar for init() and connection()
908 ProgressBar.reset (BAR_STEP_INIT_CONNECTION);
910 // save screen saver state and disable it
911 LastScreenSaverEnabled = CSystemUtils::isScreensaverEnabled();
913 if (LastScreenSaverEnabled)
914 CSystemUtils::enableScreensaver(false);
916 // Random init
917 srand ((uint)CTime::getLocalTime());
919 // Set FPU exceptions
920 #ifdef NL_OS_WINDOWS
921 _control87 (_EM_INVALID|_EM_DENORMAL/*|_EM_ZERODIVIDE|_EM_OVERFLOW*/|_EM_UNDERFLOW|_EM_INEXACT, _MCW_EM);
922 #endif // NL_OS_WINDOWS
924 FPU_CHECKER_ONCE
926 NLMISC::TTime initStart = ryzomGetLocalTime ();
928 // _CrtSetDbgFlag( _CRTDBG_CHECK_CRT_DF );
930 // Init XML Lib allocator
931 // Due to Bug #906, we disable the stl xml allocation
932 // nlverify (xmlMemSetup (XmlFree4NeL, XmlMalloc4NeL, XmlRealloc4NeL, XmlStrdup4NeL) == 0);
934 // Init the debug memory
935 initDebugMemory();
937 // Load the application configuration.
938 string nmsg("Loading config file...");
939 ProgressBar.newMessage (nmsg);
941 ClientCfg.init(ConfigFileName);
942 CLoginProgressPostThread::getInstance().init(ClientCfg.ConfigFile);
944 sint cpuMask;
946 if (ClientCfg.CPUMask < 1)
948 CTime::CTimerInfo timerInfo;
949 NLMISC::CTime::probeTimerInfo(timerInfo);
951 cpuMask = timerInfo.RequiresSingleCore ? 1:0;
953 else
955 cpuMask = ClientCfg.CPUMask;
958 if (cpuMask) setCPUMask(cpuMask);
960 setCrashCallback(crashCallback);
962 // Display Some Info On CPU
963 displayCPUInfo();
965 FPU_CHECKER_ONCE
967 // create the save dir.
968 if (!CFile::isExists("save")) CFile::createDirectory("save");
970 // create the user dir.
971 if (!CFile::isExists("user")) CFile::createDirectory("user");
973 #if !FINAL_VERSION
974 // if we're not in final version then start the file access logger to keep track of the files that we read as we play
975 //ICommand::execute("iFileAccessLogStart",*NLMISC::InfoLog);
976 #endif
978 // check "BuildName" in ClientCfg
979 //nlassert(!ClientCfg.BuildName.empty()); // TMP comment by nico do not commit
981 // Start memory allocation log
982 // if (ClientCfg.LogMemoryAllocation)
983 // NLMEMORY::StartAllocationLog ("alloc.memlog", ClientCfg.LogMemoryAllocationSize);
985 // Remap tga files on dds files.
986 CPath::remapExtension ("dds", "tga", true);
987 CPath::remapExtension ("dds", "png", true);
988 CPath::remapExtension ("png", "tga", true);
989 FPU_CHECKER_ONCE
991 initStreamedPackageManager(ProgressBar);
992 addPreDataPaths(ProgressBar);
994 FPU_CHECKER_ONCE
996 H_AUTO(InitRZUIStr)
998 FPU_CHECKER_ONCE
999 // Set the data path for the localisation.
1000 const string nmsg("Loading I18N...");
1001 ProgressBar.newMessage ( nmsg );
1003 FPU_CHECKER_ONCE
1004 STRING_MANAGER::CLoadProxy loadProxy;
1005 CI18N::setLoadProxy(&loadProxy);
1006 CI18N::load(ClientCfg.LanguageCode);
1007 CI18N::setLoadProxy(NULL);
1008 FPU_CHECKER_ONCE
1010 // Yoyo: Append the skills and Bricks to the I18N
1011 STRING_MANAGER::CStringManagerClient::initI18NSpecialWords(ClientCfg.LanguageCode);
1012 FPU_CHECKER_ONCE
1015 FPU_CHECKER_ONCE
1017 // Check driver version
1018 checkDriverVersion();
1020 // Initialize the VR devices (even more important than the most important part of the client)
1021 nmsg = "Initializing VR devices...";
1022 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1023 initStereoDisplayDevice(); // VR_CONFIG
1025 // Create the driver (most important part of the client).
1026 nmsg = "Creating 3d driver...";
1027 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1029 UDriver::TDriver driver = UDriver::OpenGl;
1031 #ifdef NL_OS_WINDOWS
1032 uintptr_t icon = (uintptr_t)LoadIcon(HInstance, MAKEINTRESOURCE(IDI_MAIN_ICON));
1033 #else
1034 uintptr_t icon = 0;
1035 #endif // NL_OS_WINDOWS
1037 switch(ClientCfg.Driver3D)
1039 #ifdef NL_OS_WINDOWS
1040 case CClientConfig::Direct3D:
1041 driver = UDriver::Direct3d;
1042 break;
1043 #endif // NL_OS_WINDOWS
1044 case CClientConfig::DrvAuto:
1045 case CClientConfig::OpenGL:
1046 driver = UDriver::OpenGl;
1047 break;
1048 case CClientConfig::OpenGLES:
1049 driver = UDriver::OpenGlEs;
1050 break;
1051 default:
1052 break;
1055 Driver = UDriver::createDriver(icon, driver);
1057 if(Driver == NULL)
1059 ExitClientError (CI18N::get ("Can_t_load_the_display_driver").c_str ());
1060 // ExitClientError() call exit() so the code after is never called
1061 return;
1064 // used to determine screen default resolution
1065 if (ClientCfg.Width < 800 || ClientCfg.Height < 600)
1067 UDriver::CMode mode;
1069 CConfigFile::CVar *varPtr = NULL;
1071 if (!ClientCfg.Windowed && Driver->getCurrentScreenMode(mode))
1073 ClientCfg.Width = mode.Width;
1074 ClientCfg.Height = mode.Height;
1075 ClientCfg.Depth = mode.Depth;
1076 ClientCfg.Frequency = mode.Frequency;
1078 // update client.cfg with detected depth and frequency
1079 varPtr = ClientCfg.ConfigFile.getVarPtr("Depth");
1080 if(varPtr)
1081 varPtr->forceAsInt(ClientCfg.Depth);
1083 varPtr = ClientCfg.ConfigFile.getVarPtr("Frequency");
1084 if(varPtr)
1085 varPtr->forceAsInt(ClientCfg.Frequency);
1087 else
1089 ClientCfg.Width = 1024;
1090 ClientCfg.Height = 768;
1093 // update client.cfg with detected resolution
1094 varPtr = ClientCfg.ConfigFile.getVarPtr("Width");
1095 if(varPtr)
1096 varPtr->forceAsInt(ClientCfg.Width);
1098 varPtr = ClientCfg.ConfigFile.getVarPtr("Height");
1099 if(varPtr)
1100 varPtr->forceAsInt(ClientCfg.Height);
1103 CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_VideoModeSetup, "login_step_video_mode_setup"));
1105 FPU_CHECKER_ONCE
1107 // Check the driver is not is 16 bits
1108 checkDriverDepth ();
1110 UDriver::CMode mode;
1112 if (Driver->getCurrentScreenMode(mode))
1114 // use current mode if its smaller than 1024x768
1115 // mode should be windowed already, but incase its not, use the mode as is
1116 if (mode.Windowed && (mode.Width > 1024 && mode.Height > 768))
1118 mode.Width = 1024;
1119 mode.Height = 768;
1122 else
1124 mode.Width = 1024;
1125 mode.Height = 768;
1126 mode.Windowed = true;
1129 // Disable Hardware Vertex Program.
1130 if(ClientCfg.DisableVtxProgram)
1131 Driver->disableHardwareVertexProgram();
1132 // Disable Hardware Vertex AGP.
1133 if(ClientCfg.DisableVtxAGP)
1134 Driver->disableHardwareVertexArrayAGP();
1135 // Disable Hardware Texture Shader.
1136 if(ClientCfg.DisableTextureShdr)
1137 Driver->disableHardwareTextureShader();
1139 if (StereoDisplay) // VR_CONFIG // VR_DRIVER
1141 // override mode TODO
1144 // Set the mode of the window.
1145 if (!Driver->setDisplay (mode, false))
1147 string msg;
1148 if (mode.Windowed)
1150 msg = CI18N::get ("can_t_create_a_window_display");
1152 else
1154 msg = CI18N::get ("can_t_create_a_fullscreen_display");
1156 msg += " (%dx%d %d ";
1157 msg += CI18N::get ("bits");
1158 msg += ")";
1159 ExitClientError (msg.c_str (), mode.Width, mode.Height, mode.Depth);
1160 // ExitClientError() call exit() so the code after is never called
1161 return;
1164 // Enable or disable VSync
1165 if (ClientCfg.WaitVBL)
1166 Driver->setSwapVBLInterval(1);
1167 else
1168 Driver->setSwapVBLInterval(0);
1170 // initialize system utils class
1171 CSystemUtils::init();
1172 CSystemUtils::setWindow(Driver->getDisplay());
1174 CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_VideoModeSetupHighColor, "login_step_video_mode_setup_high_color"));
1176 #ifdef NL_OS_WINDOWS
1178 #ifdef RYZOM_BG_DOWNLOADER
1179 CBGDownloaderAccess::getInstance().init();
1180 #endif
1182 if (SlashScreen)
1183 DestroyWindow (SlashScreen);
1185 #endif // NL_OS_WINDOW
1187 // Set the title
1188 Driver->setWindowTitle(CI18N::get("TheSagaOfRyzom"));
1190 #if defined(NL_OS_UNIX) && !defined(NL_OS_MAC)
1191 // add all existing directory prefixes
1192 vector<string> directoryPrefixes;
1194 // user local directory prefix (~/.local)
1195 const char* homeDirectory = getenv("HOME");
1197 if (homeDirectory)
1198 directoryPrefixes.push_back(CPath::standardizePath(homeDirectory) + ".local");
1200 // system local directory prefix (/usr/local)
1201 directoryPrefixes.push_back("/usr/local");
1203 // system directory prefix (/usr)
1204 directoryPrefixes.push_back("/usr");
1206 // all supported icon sizes
1207 vector<uint> iconSizes;
1208 iconSizes.push_back(512);
1209 iconSizes.push_back(256);
1210 iconSizes.push_back(128);
1211 iconSizes.push_back(96);
1212 iconSizes.push_back(64);
1213 iconSizes.push_back(48);
1214 iconSizes.push_back(32);
1215 iconSizes.push_back(24);
1216 iconSizes.push_back(22);
1217 iconSizes.push_back(16);
1219 vector<CBitmap> bitmaps;
1221 // process all icon sizes
1222 for(size_t j = 0; j < iconSizes.size(); ++j)
1224 // process all directory prefixes
1225 for(size_t i = 0; i < directoryPrefixes.size(); ++i)
1227 uint size = iconSizes[j];
1229 // build directory where to look for icon
1230 std::string directory = toString("%s/share/icons/hicolor/%ux%u/apps", directoryPrefixes[i].c_str(), size, size);
1232 // if found, skip other directories for this icon size
1233 if (addRyzomIconBitmap(directory, bitmaps)) break;
1237 if (bitmaps.empty())
1239 // check if an icon is present in same directory as executable
1240 addRyzomIconBitmap(Args.getProgramPath(), bitmaps);
1243 if (bitmaps.empty())
1245 // check if an icon is present in current directory
1246 addRyzomIconBitmap(".", bitmaps);
1249 Driver->setWindowIcon(bitmaps);
1250 #endif
1252 sint32 posX = 0, posY = 0;
1254 if (ClientCfg.Windowed)
1256 // use position saved in config
1257 posX = ClientCfg.PositionX;
1258 posY = ClientCfg.PositionY;
1260 else
1262 // position is not saved in config so center the window
1263 if (Driver->getCurrentScreenMode(mode))
1265 posX = (mode.Width - Driver->getWindowWidth())/2;
1266 posY = (mode.Height - Driver->getWindowHeight())/2;
1270 // Set the window position
1271 Driver->setWindowPos(posX, posY);
1273 // Show the window
1274 Driver->showWindow();
1276 // for background downloader : store this window handle in shared memory for later access
1277 // (we use SendMessage to communicate with the background downloader)
1279 // Enough AGP for vertices ?
1280 if (Driver->getAvailableVertexAGPMemory () == 0)
1283 std::string deviceName;
1284 uint64 driverVersion;
1285 CSystemInfo::getVideoInfo(deviceName, driverVersion);
1286 deviceName = NLMISC::toLowerAscii(deviceName);
1287 // for radeon 7200, patch because agp crash with agp with OpenGL -> don't display the message
1288 if (!(Driver->getNbTextureStages() <= 3 && strstr(deviceName.c_str(), "radeon")))
1290 if (ClientQuestion (CI18N::get ("agp_trouble")))
1292 openDoc ("client_troubles.html");
1293 extern void quitCrashReport ();
1294 quitCrashReport ();
1295 exit (EXIT_FAILURE);
1300 FPU_CHECKER_ONCE
1302 // Set the monitor color properties
1303 CMonitorColorProperties monitorColor;
1304 for (uint i=0; i<3; i++)
1306 monitorColor.Contrast[i] = ClientCfg.Contrast;
1307 monitorColor.Luminosity[i] = ClientCfg.Luminosity;
1308 monitorColor.Gamma[i] = ClientCfg.Gamma;
1310 if (!Driver->setMonitorColorProperties (monitorColor))
1312 nlwarning("init : setMonitorColorProperties fails");
1315 // The client require at least 2 textures.
1316 if(Driver->getNbTextureStages() < 2)
1317 throw Exception("Application require at least 2 textures stages !!");
1319 Driver->enableUsedTextureMemorySum(true);
1321 // Initialize the font manager.
1322 Driver->setFontManagerMaxMemory(2000000);
1324 // Init the DXTCCompression.
1325 Driver->forceDXTCCompression(ClientCfg.ForceDXTC);
1327 // Set the anisotropic filter
1328 Driver->setAnisotropicFilter(ClientCfg.AnisotropicFilter);
1330 // Divide the texture size.
1331 if (ClientCfg.DivideTextureSizeBy2)
1332 Driver->forceTextureResize(2);
1333 else
1334 Driver->forceTextureResize(1);
1336 // Create a generic material.
1337 GenericMat = Driver->createMaterial();
1338 if(GenericMat.empty())
1339 nlerror("init: Cannot Create the generic material.");
1342 // Create a text context. We need to put the full path because we not already add search path
1343 // resetTextContext ("bremenb.ttf", false);
1344 resetTextContext ("ryzom.ttf", false);
1347 CInterfaceManager::getInstance();
1348 CViewRenderer::getInstance()->setInterfaceScale(1.0f, 1024, 768);
1349 CViewRenderer::getInstance()->setBilinearFiltering(ClientCfg.BilinearUI);
1351 CWidgetManager::getInstance()->setWindowSnapInvert(ClientCfg.WindowSnapInvert);
1352 CWidgetManager::getInstance()->setWindowSnapDistance(ClientCfg.WindowSnapDistance);
1354 // Yoyo: initialize NOW the InputHandler for Event filtering.
1355 CInputHandlerManager *InputHandlerManager = CInputHandlerManager::getInstance();
1356 InputHandlerManager->addToServer (&Driver->EventServer);
1358 std::string filename = CPath::lookup( ClientCfg.XMLInputFile, false );
1359 if( !filename.empty() )
1360 InputHandlerManager->readInputConfigFile( filename );
1362 ProgressBar.setFontFactor(0.85f);
1364 nmsg = "Loading background...";
1365 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1367 // Choose a tips of the day
1368 selectTipsOfTheDay (rand());
1370 // Create the loading texture. We can't do that before because we need to add pre search path first and driver
1371 //UseEscapeDuringLoading = USE_ESCAPE_DURING_LOADING;
1372 UseEscapeDuringLoading = false;
1373 beginLoading (StartBackground); //put here intro Gameforge if wanted
1375 FPU_CHECKER_ONCE
1377 // Define the root path that contains all data needed for the application.
1378 nmsg = "Adding search paths...";
1379 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1381 if(!ClientCfg.TestBrowser)
1383 NLMISC::TTime initPaths = ryzomGetLocalTime ();
1384 addSearchPaths(ProgressBar);
1385 if (ClientCfg.UpdatePackedSheet)
1387 addPackedSheetUpdatePaths(ProgressBar);
1389 //nlinfo ("PROFILE: %d seconds for Add search paths Data", (uint32)(ryzomGetLocalTime ()-initPaths)/1000);
1392 // Initialize HTTP cache
1393 CHttpCache::getInstance()->setCacheIndex("cache/cache.index");
1394 CHttpCache::getInstance()->init();
1396 CStrictTransportSecurity::getInstance()->init("save/hsts-list.save");
1398 // Register the reflected classes
1399 registerInterfaceElements();
1401 // set driver used by bloom (must be called before init)
1402 CBloomEffect::getInstance().setDriver(Driver);
1404 // init bloom effect
1405 CBloomEffect::getInstance().init();
1407 if (StereoDisplay) // VR_CONFIG
1409 // Init stereo display resources
1410 StereoDisplay->setDriver(Driver); // VR_DRIVER
1414 H_AUTO(InitRZSound)
1416 // Init the sound manager
1417 nmsg = "Initializing sound manager...";
1418 ProgressBar.newMessage(ClientCfg.buildLoadingString(nmsg));
1419 if (ClientCfg.SoundOn)
1421 nlassert(!SoundMngr);
1422 SoundMngr = new CSoundManager(&ProgressBar);
1425 SoundMngr->init(&ProgressBar);
1427 catch(const Exception &e)
1429 nlwarning("init : Error when creating 'SoundMngr' : %s", e.what());
1430 delete SoundMngr;
1431 SoundMngr = NULL;
1434 // Play Music just after the SoundMngr is inited
1435 if (SoundMngr)
1437 // init the SoundMngr with backuped volume
1438 SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume);
1439 SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume);
1441 // Play the login screen music
1442 SoundMngr->playMusic(ClientCfg.StartMusic, 0, true, true, true);
1446 CPath::memoryCompress(); // Because sound calls addSearchPath
1449 nlinfo ("PROFILE: %d seconds for prelogInit", (uint32)(ryzomGetLocalTime ()-initStart)/1000);
1451 FPU_CHECKER_ONCE
1453 catch (const Exception &e)
1455 ExitClientError (e.what());
1460 // ***************************************************************************
1461 void initBotObjectSelection()
1463 // Get the driver shape bank
1464 UShapeBank *shapeBank= Driver->getShapeBank();
1465 if(!shapeBank)
1466 return;
1468 // Parse all .creature
1469 const CSheetManager::TEntitySheetMap &sheets= SheetMngr.getSheets();
1470 CSheetManager::TEntitySheetMap::const_iterator it= sheets.begin();
1471 for(;it!=sheets.end();it++)
1473 CEntitySheet *entitySheet= it->second.EntitySheet;
1474 if(entitySheet->Type!=CEntitySheet::FAUNA)
1475 continue;
1476 const CCharacterSheet *sheet= dynamic_cast<const CCharacterSheet *>(entitySheet);
1477 if(sheet)
1479 // If the entity define no Skeleton, it is not skinned
1480 // thus we must force the shape to bkup the geometry in RAM, for fast selection
1481 if(sheet->IdSkelFilename==CStaticStringMapper::emptyId())
1483 // For all equipement (yoyo: Body is theorically the only one bound)
1484 std::vector<const CCharacterSheet::CEquipment*> equipList;
1485 sheet->getWholeEquipmentList(equipList);
1486 for(uint i=0;i<equipList.size();i++)
1488 string strShape= equipList[i]->getItem();
1489 // if some item bound
1490 if(!strShape.empty())
1492 // If this is a reference on an item
1493 string ext = CFile::getExtension(strShape);
1494 if((ext == "item") || (ext == "sitem"))
1496 // IS the item a valid one ?
1497 CSheetId itemId;
1498 if(itemId.buildSheetId(NLMISC::toLowerAscii(strShape)))
1500 // Get this item sheet ?
1501 CItemSheet *itemSheet= dynamic_cast<CItemSheet *>(SheetMngr.get(itemId));
1502 if(itemSheet)
1504 // and so get the actual shape name
1505 strShape= itemSheet->getShape();
1510 // If ok (after possible .sitem translation)
1511 if(!strShape.empty())
1513 shapeBank->buildSystemGeometryForshape(strShape);
1524 // ***************************************************************************
1525 //---------------------------------------------------
1526 // postlogInit :
1527 // Initialize the application after login
1528 // if the init fails, call nlerror
1529 //---------------------------------------------------
1530 void postlogInit()
1532 Driver->clearBuffers(CRGBA::Black);
1533 Driver->swapBuffers();
1534 CNiceInputAuto niceInputs;
1535 string nmsg;
1539 NLMISC::TTime initStart = ryzomGetLocalTime();
1540 NLMISC::TTime initLast = initStart;
1541 NLMISC::TTime initCurrent = initLast;
1543 H_AUTO(InitRZNetwk)
1544 // Initialize the Generic Message Header Manager.
1545 nmsg = "Initializing network...";
1546 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1548 std::string msgXMLPath = CPath::lookup("msg.xml");
1549 GenericMsgHeaderMngr.init(msgXMLPath);
1550 initializeNetwork();
1552 initLast = initCurrent;
1553 initCurrent = ryzomGetLocalTime();
1554 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing network", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1558 H_AUTO(InitRZChat)
1560 // init the chat manager
1561 nmsg = "Initializing chat manager...";
1562 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1564 ChatMngr.init( CPath::lookup("chat_static.cdb") );
1566 initLast = initCurrent;
1567 initCurrent = ryzomGetLocalTime();
1568 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing chat manager", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1572 H_AUTO(InitRZLigo)
1574 // Read the ligo primitive class file
1575 nmsg = "Initializing primitive classes...";
1576 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1578 if (!LigoConfig.readPrimitiveClass (ClientCfg.LigoPrimitiveClass.c_str(), false))
1580 nlwarning ("Can't load primitive class file %s", ClientCfg.LigoPrimitiveClass.c_str());
1583 initLast = initCurrent;
1584 initCurrent = ryzomGetLocalTime();
1585 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing primitive classes", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1588 // set the primitive context
1589 CPrimitiveContext::instance().CurrentLigoConfig = &LigoConfig;
1592 H_AUTO(InitRZShIdI)
1594 nmsg = "Initializing sheets...";
1595 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1597 // Initialize Sheet IDs.
1598 CSheetId::init (ClientCfg.UpdatePackedSheet);
1600 // load packed sheets
1601 nmsg = "Loading sheets...";
1602 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1604 SheetMngr.setOutputDataPath("../../client/data");
1605 SheetMngr.load (ProgressBar, ClientCfg.UpdatePackedSheet, ClientCfg.NeedComputeVS, ClientCfg.DumpVSIndex);
1607 initLast = initCurrent;
1608 initCurrent = ryzomGetLocalTime();
1609 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing sheets", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1613 nmsg = "Initializing bricks...";
1614 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1616 CSBrickManager::getInstance()->init(); // Must be done after sheet loading
1617 //STRING_MANAGER::CStringManagerClient::specialWordsMemoryCompress(); // Must be done after brick manager init
1619 initLast = initCurrent;
1620 initCurrent = ryzomGetLocalTime();
1621 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing bricks", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1624 if (!ClientCfg.Light)
1626 H_AUTO(InitRZCh)
1628 nmsg = "Initializing Color Slot...";
1629 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1631 // Initialize the color slot manager
1632 initColorSlotManager();
1634 nmsg = "Initializing Gabarit Set...";
1635 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1637 // Initialize the set of gabarit
1638 GabaritSet.loadGabarits (ProgressBar);
1640 nmsg = "Initializing Hair Set...";
1641 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1643 // Initialize the hair sets
1644 HairSet.init (ProgressBar);
1646 nmsg = "Initializing Starting Role Set...";
1647 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1649 // Init all BotObjects for fast selection
1650 nmsg = "Initializing Bot Objects...";
1651 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1652 initBotObjectSelection();
1654 initLast = initCurrent;
1655 initCurrent = ryzomGetLocalTime();
1656 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing Color Slot etc.", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1658 else
1660 // To have the same number of newMessage in client light
1661 nmsg.clear();
1662 ProgressBar.newMessage (nmsg);
1663 ProgressBar.newMessage (nmsg);
1664 ProgressBar.newMessage (nmsg);
1665 ProgressBar.newMessage (nmsg);
1666 ProgressBar.newMessage (nmsg);
1669 // Initialize MovieShooter
1671 nmsg = "Initializing Movie Shooter ...";
1672 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1673 if(ClientCfg.MovieShooterMemory>0)
1675 MovieShooter.init(ClientCfg.MovieShooterMemory);
1676 MovieShooter.setFrameSkip(ClientCfg.MovieShooterFrameSkip);
1679 initLast = initCurrent;
1680 initCurrent = ryzomGetLocalTime();
1681 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing Movie Shooter", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1685 nmsg = "Initializing primitives...";
1686 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1688 // Register the ligo primitives for .primitive sheets
1689 NLLIGO::Register ();
1691 // Load PACS primitive
1692 initPrimitiveBlocks();
1694 initLast = initCurrent;
1695 initCurrent = ryzomGetLocalTime();
1696 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing primitives", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1700 nmsg = "Executing cfg file start commands...";
1701 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1703 // Call the user commands from the config file if any
1704 CConfigFile::CVar *var;
1705 if ((var = ClientCfg.ConfigFile.getVarPtr ("StartCommands")) != NULL)
1707 for (uint i = 0; i < var->size(); i++)
1709 ICommand::execute (var->asString(i), *InfoLog);
1713 initLast = initCurrent;
1714 initCurrent = ryzomGetLocalTime();
1715 //nlinfo ("PROFILE: %d seconds (%d total) for Executing cfg file start commands", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1718 // Next step will be the connection with the server.
1719 nmsg = "Connecting...";
1720 ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
1722 nlinfo ("PROFILE: %d seconds for postlogInit", (uint32)(ryzomGetLocalTime ()-initStart)/1000);
1724 catch (const Exception &e)
1726 ExitClientError (e.what());
1728 }// init //