1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2020 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 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>
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/>.
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"
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"
52 #include "nel/net/email.h"
54 #include "nel/ligo/ligo_config.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"
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"
83 //#include "starting_roles.h"
85 #include "init_main_loop.h"
89 #include "time_client.h"
90 #include "pacs_client.h"
91 #include "interface_v3/music_player.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"
106 #include <libxml/xmlmemory.h>
110 extern HINSTANCE HInstance
;
111 extern HWND SlashScreen
;
112 #endif // NL_OS_WINDOWS
116 #include <sys/resource.h>
117 #include "nel/misc/dynloadlib.h"
120 #include "app_bundle_utils.h"
125 #define new DEBUG_NEW
131 using namespace NLMISC
;
132 using namespace NLNET
;
133 using namespace NL3D
;
134 using namespace NLLIGO
;
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
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"
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));
207 // MemoryDeallocate (ptr);
211 void *XmlMalloc4NeL (size_t size)
213 // if (XmlAllocUsesSTL)
215 int *newB = (int *) xmlStlAlloc.allocate(size + sizeof(int));
217 return (void *) (newB + 1);
221 // return MemoryAllocate(size);
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));
239 // // Get the block size
240 // return MemoryReallocate (ptr, size);
244 char *XmlStrdup4NeL (const char *str)
248 // if (XmlAllocUsesSTL)
250 newStr = (char *) XmlMalloc4NeL(strlen (str)+1);
254 // newStr = (char*)MemoryAllocate(strlen (str)+1);
256 strcpy (newStr, str);
265 static std::wstring CurrentErrorMessage
;
267 static INT_PTR CALLBACK
ExitClientErrorDialogProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM
/* lParam */)
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()));
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
);
299 switch(LOWORD(wParam
))
302 EndDialog(hwndDlg
, IDOK
);
304 case IDC_RYZOM_ERROR_HELP
:
308 HWND wnd
= Driver
->getDisplay();
309 ShowWindow(wnd
, SW_MINIMIZE
);
311 browseFAQ(ClientCfg
.ConfigFile
);
312 EndDialog(hwndDlg
, IDOK
);
318 EndDialog(hwndDlg
, IDOK
);
328 // Use this function to return an error to the final user and exit the client
329 void ExitClientError (const char *format
, ...)
332 NLMISC_CONVERT_VARGS (str
, format
, 256/*NLMISC::MaxCStringSize*/);
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);
347 fprintf (stderr
, "%s\n", str
);
350 extern void quitCrashReport ();
352 NLMISC::NL3D_BlockMemoryAssertOnPurge
= false; // at this point some object may remain allocated
353 // so don't want to fire an assert here
357 // Use this function to return an information to the final user
358 void ClientInfo (const std::string
&message
)
361 MessageBoxW(NULL
, nlUtf8ToWide(message
.c_str()), nlUtf8ToWide(CI18N::get("TheSagaOfRyzom").c_str()), MB_OK
|MB_ICONINFORMATION
);
365 // Use this function to ask a question to the final user
366 bool ClientQuestion (const std::string
&message
)
369 return MessageBoxW(NULL
, nlUtf8ToWide(message
.c_str()), nlUtf8ToWide(CI18N::get("TheSagaOfRyzom").c_str()), MB_YESNO
|MB_ICONQUESTION
) != IDNO
;
375 void selectTipsOfTheDay (uint
/* tips */)
377 /* todo tips of the day uncomment
379 TipsOfTheDayIndex = tips;
380 string title = CI18N::get ("uiTipsTitle");
381 title += toString (tips+1);
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 // ***************************************************************************
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
)
410 IProcess::getCurrentProcess ()->setCPUMask(cpuMask
& userCPUMask
);
414 // else get first available CPU
416 // get the processor to allow process
418 while ((i
< 64) && ((cpuMask
& (UINT64_CONSTANT(1) << i
)) == 0))
424 IProcess::getCurrentProcess ()->setCPUMask(UINT64_CONSTANT(1) << i
);
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()
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());
457 s
+= "NeL3D: " + string(Driver
->getVideocardInformation()) + "\n";
459 s
+= "NeL3D: No driver\n";
463 uint64 driverVersion
;
464 if (CSystemInfo::getVideoInfo (deviceName
, driverVersion
))
469 s
+= getVersionString (driverVersion
) + "\n";
472 if (SoundMngr
&& SoundMngr
->getMixer())
473 SoundMngr
->getMixer()->writeProfile (s
);
480 static string
crashCallback()
482 string s
= getDebugInformation();
483 s
+= getSystemInformation();
488 NL3D::UDriver::CMode mode
;
489 Driver
->getCurrentScreenMode(mode
);
492 HWND wnd
= Driver
->getDisplay();
493 ShowWindow(wnd
, SW_MINIMIZE
);
502 void checkDriverVersion()
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
,
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
,
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 ();
559 if (i
==sizeof (driversVersion
)/sizeof(uint
))
560 nlwarning ("Unknown video card : %s", deviceName
.c_str());
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
)
573 Driver
->getCurrentScreenMode(mode
);
575 if (mode
.Depth
!= 32)
577 if (mode
.Depth
!= 16 && mode
.Depth
!= 24 && mode
.Depth
!= 32)
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");
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());
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
)
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
)
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
)
640 if (ClientCfg
.VRDisplayDeviceId
== it
->Serial
)
646 nlinfo("VR [C]: Create VR stereo display device");
647 StereoDisplay
= IStereoDisplay::createDevice(*deviceInfo
);
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
);
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()));
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()));
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
]);
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
))
803 if (file
.open(filename
))
807 if (bitmap
.load(file
))
809 bitmaps
.push_back(bitmap
);
820 //---------------------------------------------------
822 // Initialize the client.log file
823 //---------------------------------------------------
826 // Add a displayer for Debug Infos.
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());
845 struct rlimit rlp
, rlp2
, rlp3
;
847 getrlimit(RLIMIT_NOFILE
, &rlp
);
851 rlp2
.rlim_cur
= std::min(value
, rlp
.rlim_max
);
852 rlp2
.rlim_max
= rlp
.rlim_max
;
854 if (setrlimit(RLIMIT_NOFILE
, &rlp2
))
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");
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/");
882 //---------------------------------------------------
884 // Initialize the application before login
885 // if the init fails, call nlerror
886 //---------------------------------------------------
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);
917 srand ((uint
)CTime::getLocalTime());
919 // Set FPU exceptions
921 _control87 (_EM_INVALID
|_EM_DENORMAL
/*|_EM_ZERODIVIDE|_EM_OVERFLOW*/|_EM_UNDERFLOW
|_EM_INEXACT
, _MCW_EM
);
922 #endif // NL_OS_WINDOWS
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
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
);
946 if (ClientCfg
.CPUMask
< 1)
948 CTime::CTimerInfo timerInfo
;
949 NLMISC::CTime::probeTimerInfo(timerInfo
);
951 cpuMask
= timerInfo
.RequiresSingleCore
? 1:0;
955 cpuMask
= ClientCfg
.CPUMask
;
958 if (cpuMask
) setCPUMask(cpuMask
);
960 setCrashCallback(crashCallback
);
962 // Display Some Info On CPU
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");
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);
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);
991 initStreamedPackageManager(ProgressBar
);
992 addPreDataPaths(ProgressBar
);
999 // Set the data path for the localisation.
1000 const string
nmsg("Loading I18N...");
1001 ProgressBar
.newMessage ( nmsg
);
1004 STRING_MANAGER::CLoadProxy loadProxy
;
1005 CI18N::setLoadProxy(&loadProxy
);
1006 CI18N::load(ClientCfg
.LanguageCode
);
1007 CI18N::setLoadProxy(NULL
);
1010 // Yoyo: Append the skills and Bricks to the I18N
1011 STRING_MANAGER::CStringManagerClient::initI18NSpecialWords(ClientCfg
.LanguageCode
);
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
));
1035 #endif // NL_OS_WINDOWS
1037 switch(ClientCfg
.Driver3D
)
1039 #ifdef NL_OS_WINDOWS
1040 case CClientConfig::Direct3D
:
1041 driver
= UDriver::Direct3d
;
1043 #endif // NL_OS_WINDOWS
1044 case CClientConfig::DrvAuto
:
1045 case CClientConfig::OpenGL
:
1046 driver
= UDriver::OpenGl
;
1048 case CClientConfig::OpenGLES
:
1049 driver
= UDriver::OpenGlEs
;
1055 Driver
= UDriver::createDriver(icon
, driver
);
1059 ExitClientError (CI18N::get ("Can_t_load_the_display_driver").c_str ());
1060 // ExitClientError() call exit() so the code after is never called
1064 UDriver::CMode mode
;
1065 // first run (no client.cfg)
1066 if (ClientCfg
.Width
== 0 || ClientCfg
.Height
== 0)
1068 if (Driver
->getCurrentScreenMode(mode
))
1070 // fullscreen, using monitor resolution
1071 mode
.Windowed
= false;
1073 ClientCfg
.Windowed
= mode
.Windowed
;
1074 ClientCfg
.Width
= mode
.Width
;
1075 ClientCfg
.Height
= mode
.Height
;
1076 ClientCfg
.Depth
= mode
.Depth
;
1077 ClientCfg
.Frequency
= mode
.Frequency
;
1082 ClientCfg
.Windowed
= true;
1083 ClientCfg
.Width
= 1024;
1084 ClientCfg
.Height
= 768;
1087 // update client.cfg with detected resolution
1088 ClientCfg
.writeBool("FullScreen", !ClientCfg
.Windowed
, true);
1089 ClientCfg
.writeInt("Width", ClientCfg
.Width
, true);
1090 ClientCfg
.writeInt("Height", ClientCfg
.Height
, true);
1091 ClientCfg
.writeInt("Depth", ClientCfg
.Depth
, true);
1092 ClientCfg
.writeInt("Frequency", ClientCfg
.Frequency
, true);
1094 ClientCfg
.ConfigFile
.save();
1098 mode
.Windowed
= ClientCfg
.Windowed
;
1099 mode
.Width
= ClientCfg
.Width
;
1100 mode
.Height
= ClientCfg
.Height
;
1101 mode
.Depth
= ClientCfg
.Depth
;
1102 mode
.Frequency
= ClientCfg
.Frequency
;
1105 CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_VideoModeSetup
, "login_step_video_mode_setup"));
1109 // Check the driver is not is 16 bits
1110 checkDriverDepth ();
1112 // Disable Hardware Vertex Program.
1113 if(ClientCfg
.DisableVtxProgram
)
1114 Driver
->disableHardwareVertexProgram();
1115 // Disable Hardware Vertex AGP.
1116 if(ClientCfg
.DisableVtxAGP
)
1117 Driver
->disableHardwareVertexArrayAGP();
1118 // Disable Hardware Texture Shader.
1119 if(ClientCfg
.DisableTextureShdr
)
1120 Driver
->disableHardwareTextureShader();
1122 if (StereoDisplay
) // VR_CONFIG // VR_DRIVER
1124 // override mode TODO
1127 // Set the mode of the window.
1128 if (!Driver
->setDisplay (mode
, false))
1133 msg
= CI18N::get ("can_t_create_a_window_display");
1137 msg
= CI18N::get ("can_t_create_a_fullscreen_display");
1139 msg
+= " (%dx%d %d ";
1140 msg
+= CI18N::get ("bits");
1142 ExitClientError (msg
.c_str (), mode
.Width
, mode
.Height
, mode
.Depth
);
1143 // ExitClientError() call exit() so the code after is never called
1147 // Enable or disable VSync
1148 if (ClientCfg
.WaitVBL
)
1149 Driver
->setSwapVBLInterval(1);
1151 Driver
->setSwapVBLInterval(0);
1153 // initialize system utils class
1154 CSystemUtils::init();
1155 CSystemUtils::setWindow(Driver
->getDisplay());
1157 CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_VideoModeSetupHighColor
, "login_step_video_mode_setup_high_color"));
1159 #ifdef NL_OS_WINDOWS
1161 #ifdef RYZOM_BG_DOWNLOADER
1162 CBGDownloaderAccess::getInstance().init();
1166 DestroyWindow (SlashScreen
);
1168 #endif // NL_OS_WINDOW
1171 Driver
->setWindowTitle(CI18N::get("TheSagaOfRyzom"));
1173 #if defined(NL_OS_UNIX) && !defined(NL_OS_MAC)
1174 // add all existing directory prefixes
1175 vector
<string
> directoryPrefixes
;
1177 // user local directory prefix (~/.local)
1178 const char* homeDirectory
= getenv("HOME");
1181 directoryPrefixes
.push_back(CPath::standardizePath(homeDirectory
) + ".local");
1183 // system local directory prefix (/usr/local)
1184 directoryPrefixes
.push_back("/usr/local");
1186 // system directory prefix (/usr)
1187 directoryPrefixes
.push_back("/usr");
1189 // all supported icon sizes
1190 vector
<uint
> iconSizes
;
1191 iconSizes
.push_back(512);
1192 iconSizes
.push_back(256);
1193 iconSizes
.push_back(128);
1194 iconSizes
.push_back(96);
1195 iconSizes
.push_back(64);
1196 iconSizes
.push_back(48);
1197 iconSizes
.push_back(32);
1198 iconSizes
.push_back(24);
1199 iconSizes
.push_back(22);
1200 iconSizes
.push_back(16);
1202 vector
<CBitmap
> bitmaps
;
1204 // process all icon sizes
1205 for(size_t j
= 0; j
< iconSizes
.size(); ++j
)
1207 // process all directory prefixes
1208 for(size_t i
= 0; i
< directoryPrefixes
.size(); ++i
)
1210 uint size
= iconSizes
[j
];
1212 // build directory where to look for icon
1213 std::string directory
= toString("%s/share/icons/hicolor/%ux%u/apps", directoryPrefixes
[i
].c_str(), size
, size
);
1215 // if found, skip other directories for this icon size
1216 if (addRyzomIconBitmap(directory
, bitmaps
)) break;
1220 if (bitmaps
.empty())
1222 // check if an icon is present in same directory as executable
1223 addRyzomIconBitmap(Args
.getProgramPath(), bitmaps
);
1226 if (bitmaps
.empty())
1228 // check if an icon is present in current directory
1229 addRyzomIconBitmap(".", bitmaps
);
1232 Driver
->setWindowIcon(bitmaps
);
1235 sint32 posX
= 0, posY
= 0;
1237 if (ClientCfg
.Windowed
)
1239 // use position saved in config
1240 posX
= ClientCfg
.PositionX
;
1241 posY
= ClientCfg
.PositionY
;
1245 // position is not saved in config so center the window
1247 if (Driver
->getCurrentScreenMode(tmp
))
1249 posX
= (tmp
.Width
- Driver
->getWindowWidth())/2;
1250 posY
= (tmp
.Height
- Driver
->getWindowHeight())/2;
1254 // Set the window position
1255 Driver
->setWindowPos(posX
, posY
);
1258 Driver
->showWindow();
1260 // for background downloader : store this window handle in shared memory for later access
1261 // (we use SendMessage to communicate with the background downloader)
1263 // Enough AGP for vertices ?
1264 if (Driver
->getAvailableVertexAGPMemory () == 0)
1267 std::string deviceName;
1268 uint64 driverVersion;
1269 CSystemInfo::getVideoInfo(deviceName, driverVersion);
1270 deviceName = NLMISC::toLowerAscii(deviceName);
1271 // for radeon 7200, patch because agp crash with agp with OpenGL -> don't display the message
1272 if (!(Driver->getNbTextureStages() <= 3 && strstr(deviceName.c_str(), "radeon")))
1274 if (ClientQuestion (CI18N::get ("agp_trouble")))
1276 openDoc ("client_troubles.html");
1277 extern void quitCrashReport ();
1279 exit (EXIT_FAILURE
);
1286 // Set the monitor color properties
1287 CMonitorColorProperties monitorColor
;
1288 for (uint i
=0; i
<3; i
++)
1290 monitorColor
.Contrast
[i
] = ClientCfg
.Contrast
;
1291 monitorColor
.Luminosity
[i
] = ClientCfg
.Luminosity
;
1292 monitorColor
.Gamma
[i
] = ClientCfg
.Gamma
;
1294 if (!Driver
->setMonitorColorProperties (monitorColor
))
1296 nlwarning("init : setMonitorColorProperties fails");
1299 // The client require at least 2 textures.
1300 if(Driver
->getNbTextureStages() < 2)
1301 throw Exception("Application require at least 2 textures stages !!");
1303 Driver
->enableUsedTextureMemorySum(true);
1305 // Initialize the font manager.
1306 Driver
->setFontManagerMaxMemory(2000000);
1308 // Init the DXTCCompression.
1309 Driver
->forceDXTCCompression(ClientCfg
.ForceDXTC
);
1311 // Set the anisotropic filter
1312 Driver
->setAnisotropicFilter(ClientCfg
.AnisotropicFilter
);
1314 // Divide the texture size.
1315 if (ClientCfg
.DivideTextureSizeBy2
)
1316 Driver
->forceTextureResize(2);
1318 Driver
->forceTextureResize(1);
1320 // Create a generic material.
1321 GenericMat
= Driver
->createMaterial();
1322 if(GenericMat
.empty())
1323 nlerror("init: Cannot Create the generic material.");
1326 // Create a text context. We need to put the full path because we not already add search path
1327 // resetTextContext ("bremenb.ttf", false);
1328 resetTextContext ("ryzom.ttf", false);
1331 CInterfaceManager::getInstance();
1332 CViewRenderer::getInstance()->setInterfaceScale(1.0f
, 1024, 768);
1333 CViewRenderer::getInstance()->setBilinearFiltering(ClientCfg
.BilinearUI
);
1335 CWidgetManager::getInstance()->setWindowSnapInvert(ClientCfg
.WindowSnapInvert
);
1336 CWidgetManager::getInstance()->setWindowSnapDistance(ClientCfg
.WindowSnapDistance
);
1338 // Yoyo: initialize NOW the InputHandler for Event filtering.
1339 CInputHandlerManager
*InputHandlerManager
= CInputHandlerManager::getInstance();
1340 InputHandlerManager
->addToServer (&Driver
->EventServer
);
1342 std::string filename
= CPath::lookup( ClientCfg
.XMLInputFile
, false );
1343 if( !filename
.empty() )
1344 InputHandlerManager
->readInputConfigFile( filename
);
1346 ProgressBar
.setFontFactor(0.85f
);
1348 nmsg
= "Loading background...";
1349 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1351 // Choose a tips of the day
1352 selectTipsOfTheDay (rand());
1354 // Create the loading texture. We can't do that before because we need to add pre search path first and driver
1355 //UseEscapeDuringLoading = USE_ESCAPE_DURING_LOADING;
1356 UseEscapeDuringLoading
= false;
1357 beginLoading (StartBackground
); //put here intro Gameforge if wanted
1361 // Define the root path that contains all data needed for the application.
1362 nmsg
= "Adding search paths...";
1363 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1365 if(!ClientCfg
.TestBrowser
)
1367 NLMISC::TTime initPaths
= ryzomGetLocalTime ();
1368 addSearchPaths(ProgressBar
);
1369 if (ClientCfg
.UpdatePackedSheet
)
1371 addPackedSheetUpdatePaths(ProgressBar
);
1373 //nlinfo ("PROFILE: %d seconds for Add search paths Data", (uint32)(ryzomGetLocalTime ()-initPaths)/1000);
1376 // Initialize HTTP cache
1377 CHttpCache::getInstance()->setCacheIndex("cache/cache.index");
1378 CHttpCache::getInstance()->init();
1380 CStrictTransportSecurity::getInstance()->init("save/hsts-list.save");
1382 // Register the reflected classes
1383 registerInterfaceElements();
1385 // set driver used by bloom (must be called before init)
1386 CBloomEffect::getInstance().setDriver(Driver
);
1388 // init bloom effect
1389 CBloomEffect::getInstance().init();
1391 if (StereoDisplay
) // VR_CONFIG
1393 // Init stereo display resources
1394 StereoDisplay
->setDriver(Driver
); // VR_DRIVER
1400 // Init the sound manager
1401 nmsg
= "Initializing sound manager...";
1402 ProgressBar
.newMessage(ClientCfg
.buildLoadingString(nmsg
));
1403 if (ClientCfg
.SoundOn
)
1405 nlassert(!SoundMngr
);
1406 SoundMngr
= new CSoundManager(&ProgressBar
);
1409 SoundMngr
->init(&ProgressBar
);
1411 catch(const Exception
&e
)
1413 nlwarning("init : Error when creating 'SoundMngr' : %s", e
.what());
1418 // Play Music just after the SoundMngr is inited
1421 // init the SoundMngr with backuped volume
1422 SoundMngr
->setSFXVolume(ClientCfg
.SoundSFXVolume
);
1423 SoundMngr
->setGameMusicVolume(ClientCfg
.SoundGameMusicVolume
);
1425 // Play the login screen music
1426 SoundMngr
->playMusic(ClientCfg
.StartMusic
, 0, true, true, true);
1430 CPath::memoryCompress(); // Because sound calls addSearchPath
1433 nlinfo ("PROFILE: %d seconds for prelogInit", (uint32
)(ryzomGetLocalTime ()-initStart
)/1000);
1437 catch (const Exception
&e
)
1439 ExitClientError (e
.what());
1443 void stopSoundMngr()
1453 // ***************************************************************************
1454 void initBotObjectSelection()
1456 // Get the driver shape bank
1457 UShapeBank
*shapeBank
= Driver
->getShapeBank();
1461 // Parse all .creature
1462 const CSheetManager::TEntitySheetMap
&sheets
= SheetMngr
.getSheets();
1463 CSheetManager::TEntitySheetMap::const_iterator it
= sheets
.begin();
1464 for(;it
!=sheets
.end();it
++)
1466 CEntitySheet
*entitySheet
= it
->second
.EntitySheet
;
1467 if(entitySheet
->Type
!=CEntitySheet::FAUNA
)
1469 const CCharacterSheet
*sheet
= dynamic_cast<const CCharacterSheet
*>(entitySheet
);
1472 // If the entity define no Skeleton, it is not skinned
1473 // thus we must force the shape to bkup the geometry in RAM, for fast selection
1474 if(sheet
->IdSkelFilename
==CStaticStringMapper::emptyId())
1476 // For all equipement (yoyo: Body is theorically the only one bound)
1477 std::vector
<const CCharacterSheet::CEquipment
*> equipList
;
1478 sheet
->getWholeEquipmentList(equipList
);
1479 for(uint i
=0;i
<equipList
.size();i
++)
1481 string strShape
= equipList
[i
]->getItem();
1482 // if some item bound
1483 if(!strShape
.empty())
1485 // If this is a reference on an item
1486 string ext
= CFile::getExtension(strShape
);
1487 if((ext
== "item") || (ext
== "sitem"))
1489 // IS the item a valid one ?
1491 if(itemId
.buildSheetId(NLMISC::toLowerAscii(strShape
)))
1493 // Get this item sheet ?
1494 CItemSheet
*itemSheet
= dynamic_cast<CItemSheet
*>(SheetMngr
.get(itemId
));
1497 // and so get the actual shape name
1498 strShape
= itemSheet
->getShape();
1503 // If ok (after possible .sitem translation)
1504 if(!strShape
.empty())
1506 shapeBank
->buildSystemGeometryForshape(strShape
);
1517 // ***************************************************************************
1518 //---------------------------------------------------
1520 // Initialize the application after login
1521 // if the init fails, call nlerror
1522 //---------------------------------------------------
1525 Driver
->clearBuffers(CRGBA::Black
);
1526 Driver
->swapBuffers();
1527 CNiceInputAuto niceInputs
;
1532 NLMISC::TTime initStart
= ryzomGetLocalTime();
1533 NLMISC::TTime initLast
= initStart
;
1534 NLMISC::TTime initCurrent
= initLast
;
1537 // Initialize the Generic Message Header Manager.
1538 nmsg
= "Initializing network...";
1539 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1541 std::string msgXMLPath
= CPath::lookup("msg.xml");
1542 GenericMsgHeaderMngr
.init(msgXMLPath
);
1543 initializeNetwork();
1545 initLast
= initCurrent
;
1546 initCurrent
= ryzomGetLocalTime();
1547 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing network", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1553 // init the chat manager
1554 nmsg
= "Initializing chat manager...";
1555 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1557 ChatMngr
.init( CPath::lookup("chat_static.cdb") );
1559 initLast
= initCurrent
;
1560 initCurrent
= ryzomGetLocalTime();
1561 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing chat manager", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1567 // Read the ligo primitive class file
1568 nmsg
= "Initializing primitive classes...";
1569 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1571 if (!LigoConfig
.readPrimitiveClass (ClientCfg
.LigoPrimitiveClass
.c_str(), false))
1573 nlwarning ("Can't load primitive class file %s", ClientCfg
.LigoPrimitiveClass
.c_str());
1576 initLast
= initCurrent
;
1577 initCurrent
= ryzomGetLocalTime();
1578 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing primitive classes", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1581 // set the primitive context
1582 CPrimitiveContext::instance().CurrentLigoConfig
= &LigoConfig
;
1589 // Init the sound manager
1590 nmsg
= "Initializing sound manager...";
1591 ProgressBar
.newMessage(ClientCfg
.buildLoadingString(nmsg
));
1592 if (ClientCfg
.SoundOn
)
1594 SoundMngr
= new CSoundManager(&ProgressBar
);
1597 SoundMngr
->init(&ProgressBar
);
1599 catch (const Exception
&e
)
1601 nlwarning("init : Error when creating 'SoundMngr' : %s", e
.what());
1608 // init the SoundMngr with backuped volume
1609 SoundMngr
->setSFXVolume(ClientCfg
.SoundSFXVolume
);
1610 SoundMngr
->setGameMusicVolume(ClientCfg
.SoundGameMusicVolume
);
1614 CPath::memoryCompress(); // Because sound calls addSearchPath
1621 nmsg
= "Initializing sheets...";
1622 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1624 // Initialize Sheet IDs.
1625 CSheetId::init (ClientCfg
.UpdatePackedSheet
);
1627 // load packed sheets
1628 nmsg
= "Loading sheets...";
1629 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1631 SheetMngr
.setOutputDataPath("../../client/data");
1632 SheetMngr
.load (ProgressBar
, ClientCfg
.UpdatePackedSheet
, ClientCfg
.NeedComputeVS
, ClientCfg
.DumpVSIndex
);
1634 initLast
= initCurrent
;
1635 initCurrent
= ryzomGetLocalTime();
1636 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing sheets", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1640 nmsg
= "Initializing bricks...";
1641 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1643 CSBrickManager::getInstance()->init(); // Must be done after sheet loading
1644 //STRING_MANAGER::CStringManagerClient::specialWordsMemoryCompress(); // Must be done after brick manager init
1646 initLast
= initCurrent
;
1647 initCurrent
= ryzomGetLocalTime();
1648 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing bricks", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1651 if (!ClientCfg
.Light
)
1655 nmsg
= "Initializing Color Slot...";
1656 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1658 // Initialize the color slot manager
1659 initColorSlotManager();
1661 nmsg
= "Initializing Gabarit Set...";
1662 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1664 // Initialize the set of gabarit
1665 GabaritSet
.loadGabarits (ProgressBar
);
1667 nmsg
= "Initializing Hair Set...";
1668 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1670 // Initialize the hair sets
1671 HairSet
.init (ProgressBar
);
1673 nmsg
= "Initializing Starting Role Set...";
1674 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1676 // Init all BotObjects for fast selection
1677 nmsg
= "Initializing Bot Objects...";
1678 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1679 initBotObjectSelection();
1681 initLast
= initCurrent
;
1682 initCurrent
= ryzomGetLocalTime();
1683 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing Color Slot etc.", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1687 // To have the same number of newMessage in client light
1689 ProgressBar
.newMessage (nmsg
);
1690 ProgressBar
.newMessage (nmsg
);
1691 ProgressBar
.newMessage (nmsg
);
1692 ProgressBar
.newMessage (nmsg
);
1693 ProgressBar
.newMessage (nmsg
);
1696 // Initialize MovieShooter
1698 nmsg
= "Initializing Movie Shooter ...";
1699 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1700 if(ClientCfg
.MovieShooterMemory
>0)
1702 MovieShooter
.init(ClientCfg
.MovieShooterMemory
);
1703 MovieShooter
.setFrameSkip(ClientCfg
.MovieShooterFrameSkip
);
1706 initLast
= initCurrent
;
1707 initCurrent
= ryzomGetLocalTime();
1708 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing Movie Shooter", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1712 nmsg
= "Initializing primitives...";
1713 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1715 // Register the ligo primitives for .primitive sheets
1716 NLLIGO::Register ();
1718 // Load PACS primitive
1719 initPrimitiveBlocks();
1721 initLast
= initCurrent
;
1722 initCurrent
= ryzomGetLocalTime();
1723 //nlinfo ("PROFILE: %d seconds (%d total) for Initializing primitives", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1727 nmsg
= "Executing cfg file start commands...";
1728 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1730 // Call the user commands from the config file if any
1731 CConfigFile::CVar
*var
;
1732 if ((var
= ClientCfg
.ConfigFile
.getVarPtr ("StartCommands")) != NULL
)
1734 for (uint i
= 0; i
< var
->size(); i
++)
1736 ICommand::execute (var
->asString(i
), *InfoLog
);
1740 initLast
= initCurrent
;
1741 initCurrent
= ryzomGetLocalTime();
1742 //nlinfo ("PROFILE: %d seconds (%d total) for Executing cfg file start commands", (uint32)(initCurrent-initLast)/1000, (uint32)(initCurrent-initStart)/1000);
1745 // Next step will be the connection with the server.
1746 nmsg
= "Connecting...";
1747 ProgressBar
.newMessage ( ClientCfg
.buildLoadingString(nmsg
) );
1749 nlinfo ("PROFILE: %d seconds for postlogInit", (uint32
)(ryzomGetLocalTime ()-initStart
)/1000);
1751 catch (const Exception
&e
)
1753 ExitClientError (e
.what());