1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2011 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 // 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");
1081 varPtr
->forceAsInt(ClientCfg
.Depth
);
1083 varPtr
= ClientCfg
.ConfigFile
.getVarPtr("Frequency");
1085 varPtr
->forceAsInt(ClientCfg
.Frequency
);
1089 ClientCfg
.Width
= 1024;
1090 ClientCfg
.Height
= 768;
1093 // update client.cfg with detected resolution
1094 varPtr
= ClientCfg
.ConfigFile
.getVarPtr("Width");
1096 varPtr
->forceAsInt(ClientCfg
.Width
);
1098 varPtr
= ClientCfg
.ConfigFile
.getVarPtr("Height");
1100 varPtr
->forceAsInt(ClientCfg
.Height
);
1103 CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_VideoModeSetup
, "login_step_video_mode_setup"));
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))
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))
1150 msg
= CI18N::get ("can_t_create_a_window_display");
1154 msg
= CI18N::get ("can_t_create_a_fullscreen_display");
1156 msg
+= " (%dx%d %d ";
1157 msg
+= CI18N::get ("bits");
1159 ExitClientError (msg
.c_str (), mode
.Width
, mode
.Height
, mode
.Depth
);
1160 // ExitClientError() call exit() so the code after is never called
1164 // Enable or disable VSync
1165 if (ClientCfg
.WaitVBL
)
1166 Driver
->setSwapVBLInterval(1);
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();
1183 DestroyWindow (SlashScreen
);
1185 #endif // NL_OS_WINDOW
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");
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
);
1252 sint32 posX
= 0, posY
= 0;
1254 if (ClientCfg
.Windowed
)
1256 // use position saved in config
1257 posX
= ClientCfg
.PositionX
;
1258 posY
= ClientCfg
.PositionY
;
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
);
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 ();
1295 exit (EXIT_FAILURE
);
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);
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
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
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());
1434 // Play Music just after the SoundMngr is inited
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);
1453 catch (const Exception
&e
)
1455 ExitClientError (e
.what());
1460 // ***************************************************************************
1461 void initBotObjectSelection()
1463 // Get the driver shape bank
1464 UShapeBank
*shapeBank
= Driver
->getShapeBank();
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
)
1476 const CCharacterSheet
*sheet
= dynamic_cast<const CCharacterSheet
*>(entitySheet
);
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 ?
1498 if(itemId
.buildSheetId(NLMISC::toLowerAscii(strShape
)))
1500 // Get this item sheet ?
1501 CItemSheet
*itemSheet
= dynamic_cast<CItemSheet
*>(SheetMngr
.get(itemId
));
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 //---------------------------------------------------
1527 // Initialize the application after login
1528 // if the init fails, call nlerror
1529 //---------------------------------------------------
1532 Driver
->clearBuffers(CRGBA::Black
);
1533 Driver
->swapBuffers();
1534 CNiceInputAuto niceInputs
;
1539 NLMISC::TTime initStart
= ryzomGetLocalTime();
1540 NLMISC::TTime initLast
= initStart
;
1541 NLMISC::TTime initCurrent
= initLast
;
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);
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);
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
;
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
)
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);
1660 // To have the same number of newMessage in client light
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());