00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "viewer.h"
00035
00036 #include "llparcel.h"
00037 #include "llviewerparcelmgr.h"
00038 #include "llviewerjoystick.h"
00039
00040
00041 #include <errno.h>
00042 #include <stdexcept>
00043 #if LL_WINDOWS
00044 # include <share.h>
00045 #else
00046 # include <sys/file.h>
00047 # include <signal.h>
00048 #endif
00049 #include <sys/stat.h>
00050 #include <memory>
00051 #include <boost/tokenizer.hpp>
00052
00053 #if LL_WINDOWS
00054 #include <fcntl.h>
00055 #include <io.h>
00056 #include <errorrep.h>
00057 #include <process.h>
00058 #include <tchar.h>
00059
00060 #if LL_WINDOWS && _MSC_VER < 1400
00061
00062 #else
00063 #define LL_USE_SMARTHEAP 0
00064 #endif
00065
00066 #if LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP
00067 #include "smrtheap/smrtheap.h"
00068 #endif // LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP
00069
00070 #elif LL_DARWIN || LL_LINUX || LL_SOLARIS
00071
00072 # include <sys/socket.h>
00073
00074 # include <netinet/in.h>
00075 # include <arpa/inet.h>
00076
00077 #if LL_LINUX
00078 # include <dlfcn.h>
00079 # include <execinfo.h>
00080 # ifndef LL_ELFBIN
00081 #define LL_ELFBIN 1
00082 # endif // LL_ELFBIN
00083 # if LL_ELFBIN
00084 # include <cxxabi.h>
00085 # include "ELFIO.h"
00086 # endif // LL_ELFBIN
00087 #elif LL_SOLARIS
00088 # include <sys/types.h>
00089 # include <unistd.h>
00090 # include <fcntl.h>
00091 # include <ucontext.h>
00092 #endif
00093
00094 #if LL_DARWIN
00095 #include <Carbon/Carbon.h>
00096
00097 #ifdef check
00098 #undef check
00099 #endif
00100 #ifdef verify
00101 #undef verify
00102 #endif // verify
00103 #ifdef require
00104 #undef require
00105 #endif
00106 #endif
00107 #endif // !LL_WINDOWS
00108
00109
00110 #define LL_SEND_CRASH_REPORTS 1
00111
00112
00113
00114
00115
00116
00117 #include "audioengine.h"
00118 #include "llcommon.h"
00119 #include "llapr.h"
00120 #include "llcachename.h"
00121 #include "llcurl.h"
00122 #include "llcriticaldamp.h"
00123 #include "lldir.h"
00124 #include "lleconomy.h"
00125 #include "llerrorcontrol.h"
00126 #include "llhttpnode.h"
00127 #include "llflexibleobject.h"
00128 #include "llfasttimer.h"
00129 #include "llfocusmgr.h"
00130 #include "llgroupmgr.h"
00131 #include "llimage.h"
00132 #include "llimageworker.h"
00133 #include "lllfsthread.h"
00134 #include "llmemtype.h"
00135 #include "llmd5.h"
00136 #include "llsecondlifeurls.h"
00137 #include "llversionviewer.h"
00138 #include "llvfile.h"
00139 #include "llvfs.h"
00140 #include "llwindow.h"
00141 #include "llworkerthread.h"
00142 #include "llvfsthread.h"
00143 #include "llxfermanager.h"
00144 #include "message.h"
00145 #include "llvoavatar.h"
00146 #include "llglslshader.h"
00147
00148
00149
00150
00151
00152 #include "llagent.h"
00153 #include "llagentpilot.h"
00154 #include "llbutton.h"
00155 #include "llcallbacklist.h"
00156 #include "llchatbar.h"
00157
00158 #include "llconsole.h"
00159 #include "llcontainerview.h"
00160 #include "lldebugview.h"
00161 #include "lldrawpoolbump.h"
00162 #include "lldrawpoolterrain.h"
00163 #include "lleventnotifier.h"
00164 #include "llfasttimerview.h"
00165 #include "llfeaturemanager.h"
00166 #include "llfirstuse.h"
00167 #include "llfloateravatarlist.h"
00168 #include "llfloateractivespeakers.h"
00169 #include "llfloatertools.h"
00170 #include "llfloaterworldmap.h"
00171 #include "llfloaterhtmlhelp.h"
00172 #include "llfloatersaveavatar.h"
00173 #include "llfloatersnapshot.h"
00174 #include "llfloatereventlog.h"
00175 #include "llfolderview.h"
00176 #include "llframestats.h"
00177 #include "llgesturemgr.h"
00178 #include "llhoverview.h"
00179 #include "llhudeffecttrail.h"
00180 #include "llhudmanager.h"
00181 #include "llhttpclient.h"
00182 #include "llimview.h"
00183 #include "llimpanel.h"
00184 #include "llinventorymodel.h"
00185 #include "llinventoryview.h"
00186 #include "llkeyboard.h"
00187 #include "llkeyframemotion.h"
00188 #include "llpanellogin.h"
00189 #include "llmutelist.h"
00190 #include "llmenugl.h"
00191 #include "llnamelistctrl.h"
00192 #include "llnamebox.h"
00193 #include "llnameeditor.h"
00194 #include "llpumpio.h"
00195 #include "llnotify.h"
00196 #include "llregionnamecache.h"
00197 #include "llselectmgr.h"
00198 #include "llsky.h"
00199 #include "llsrv.h"
00200 #include "llstartup.h"
00201 #include "llstatusbar.h"
00202 #include "llsurface.h"
00203 #include "lltexlayer.h"
00204 #include "lltexturecache.h"
00205 #include "lltexturefetch.h"
00206 #include "lltoolbar.h"
00207 #include "lltoolmgr.h"
00208 #include "lltracker.h"
00209 #include "lltrustnet.h"
00210 #include "llurldispatcher.h"
00211 #include "llurlsimstring.h"
00212 #include "llurlwhitelist.h"
00213 #include "llv4math.h"
00214 #include "llviewerbuild.h"
00215 #include "llviewercamera.h"
00216 #include "llviewercontrol.h"
00217 #include "llviewerjointmesh.h"
00218 #include "llviewerimagelist.h"
00219 #include "llviewerkeyboard.h"
00220 #include "llviewermenu.h"
00221 #include "llviewermessage.h"
00222 #include "llviewernetwork.h"
00223 #include "llviewerobjectlist.h"
00224 #include "llviewerparcelmgr.h"
00225 #include "llviewerregion.h"
00226 #include "llviewerstats.h"
00227 #include "llviewerthrottle.h"
00228 #include "llvieweruictrlfactory.h"
00229 #include "llviewerwindow.h"
00230 #include "llvlmanager.h"
00231 #include "llvoavatar.h"
00232 #include "llvograss.h"
00233 #include "llvotree.h"
00234 #include "llvovolume.h"
00235 #include "llvowater.h"
00236 #include "llvolume.h"
00237 #include "llvolumemgr.h"
00238 #include "llvolumemessage.h"
00239 #include "llweb.h"
00240 #include "llworld.h"
00241 #include "llworldmap.h"
00242 #include "llworldmapview.h"
00243 #include "pipeline.h"
00244 #include "llface.h"
00245 #include "audiosettings.h"
00246 #include "res/resource.h"
00247 #include "llvoiceclient.h"
00248
00249 #if LL_WINDOWS
00250 #include "llwindebug.h"
00251 #include "lldxhardware.h"
00252 #include "llwindowwin32.h"
00253
00254
00255 #ifndef LL_LOGITECH_LCD_H
00256 #include "lllogitechlcd.h"
00257 #endif
00258 extern void CreateLCDDebugWindows();
00259
00260 #endif // LL_WINDOWS
00261
00262 #if LL_QUICKTIME_ENABLED
00263 #if LL_DARWIN
00264 #include <QuickTime/QuickTime.h>
00265 #else
00266
00267 #include "MacTypes.h"
00268 #include "QTML.h"
00269 #include "Movies.h"
00270 #include "FixMath.h"
00271 #endif
00272 #endif
00273
00274 #if LL_GSTREAMER_ENABLED
00275
00276
00277 void UnloadGStreamer();
00278 #endif // LL_GSTREAMER_ENABLED
00279
00280 #include "llmediaengine.h"
00281
00282 #if LL_LIBXUL_ENABLED
00283 #include "llmozlib.h"
00284 #endif // LL_LIBXUL_ENABLED
00285
00287
00289
00290 void errorCallback(const std::string &error_string);
00291 S32 gCrashBehavior = CRASH_BEHAVIOR_ASK;
00292 void (*gCrashCallback)(void) = NULL;
00293 BOOL gReportedCrash = FALSE;
00294
00295 bool gVerifySSLCert = true;
00296
00297 BOOL gHandleKeysAsync = FALSE;
00298
00299
00300 BOOL gProbeHardware = TRUE;
00301 std::string gSerialNumber;
00302
00304
00306
00307 BOOL gAgentMovementCompleted = FALSE;
00308 BOOL gHaveSavedSnapshot = FALSE;
00309
00310 S32 gYieldMS = 0;
00311 BOOL gYieldTime = FALSE;
00312
00313 const U32 COLLISION_LIST_DEPTH = 300;
00314 const S32 MAX_CONSOLE_LINES = 500;
00315 const S32 NUM_SESSIONS_BEFORE_SHOW_PROFILE = 5;
00316 const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f;
00317
00318 const char *VFS_DATA_FILE_BASE = "data.db2.x.";
00319 const char *VFS_INDEX_FILE_BASE = "index.db2.x.";
00320
00321 F32 gSimLastTime;
00322 F32 gSimFrames;
00323
00324
00325
00327
00329
00330
00331
00332
00333 #if LL_WINDOWS
00334 llLCD *gLcdScreen = NULL;
00335 #endif
00336
00337 LLString gSecondLife;
00338 LLString gWindowTitle;
00339 static char sWindowClass[] = "Dale's Unofficial Viewer";
00340 LLString gDisabledMessage;
00341 BOOL gHideLinks = FALSE;
00342
00343
00344 BOOL gInProductionGrid = FALSE;
00345
00346
00347 #if LL_RELEASE_FOR_DOWNLOAD
00348
00349 #ifndef APPLE_PREVIEW
00350 static EUserServerDomain UserServerDefaultChoice = USERSERVER_AGNI;
00351 #else
00352 static EUserServerDomain UserServerDefaultChoice = USERSERVER_ADITI;
00353 #endif
00354 #else
00355
00356 static EUserServerDomain UserServerDefaultChoice = USERSERVER_DMZ;
00357 #endif
00358
00359 #ifdef TOGGLE_HACKED_GODLIKE_VIEWER
00360 BOOL gHackGodmode = FALSE;
00361 #endif
00362
00363 std::vector<std::string> gLoginURIs;
00364 static std::string gHelperURI;
00365
00366 LLAgent gAgent;
00367 LLPipeline gPipeline;
00368
00369
00370
00371 BOOL gDoDisconnect = FALSE;
00372 BOOL gDisconnected = FALSE;
00373
00374
00375 BOOL gPurgeOnExit = FALSE;
00376 BOOL gPurgeCache = FALSE;
00377
00378
00379 #if LL_RELEASE_FOR_DOWNLOAD
00380 BOOL gMultipleViewersOK = FALSE;
00381 #else
00382 BOOL gMultipleViewersOK = TRUE;
00383 #endif
00384 BOOL gSecondInstance = FALSE;
00385 BOOL gDisableVoice = FALSE;
00386
00387 LLString gArgs;
00388
00389
00390 BOOL gQuit = FALSE;
00391
00392 BOOL gQuitRequested = FALSE;
00393 LLString gLaunchFileOnQuit;
00394 BOOL gDoneLogout = FALSE;
00395
00396 BOOL gInitializationComplete = FALSE;
00397 BOOL gAutoLogin = FALSE;
00398 LLString gOldSettingsFileName;
00399 BOOL gPrintMessagesThisFrame = FALSE;
00400 const char* DEFAULT_SETTINGS_FILE = "settings_dale.xml";
00401 const char* LEGACY_DEFAULT_SETTINGS_FILE = "settings_dale.ini";
00402 BOOL gUseWireframe = FALSE;
00403 LLUUID gViewerDigest;
00404 LLPumpIO* gServicePump = NULL;
00405 S32 gNumSessions = 0;
00406
00407 BOOL gAllowIdleAFK = TRUE;
00408 F32 gAFKTimeout = DEFAULT_AFK_TIMEOUT;
00409 F32 gMouseSensitivity = 3.f;
00410 BOOL gInvertMouse = FALSE;
00411 BOOL gLogoutRequestSent = FALSE;
00412 LLTimer gLogoutTimer;
00413 BOOL gShowObjectUpdates = FALSE;
00414
00415 const F32 LOGOUT_REQUEST_TIME = 6.f;
00416 F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME;
00417
00418
00419 F32 gMapScale = 128.f;
00420 F32 gMiniMapScale = 128.f;
00421
00422
00423 LLSky gSky;
00424
00425
00426 BOOL gDisplayWindInfo = FALSE;
00427 BOOL gDisplayCameraPos = FALSE;
00428 BOOL gDisplayNearestWater = FALSE;
00429 BOOL gDoNearestWaterSearch = FALSE;
00430 BOOL gDisplayFOV = FALSE;
00431
00432
00433 LLFrameTimer gRestoreGLTimer;
00434 BOOL gRestoreGL = FALSE;
00435
00436
00437
00438 LLVFS* gStaticVFS = NULL;
00439
00440
00441 LLTextureCache* gTextureCache = NULL;
00442 LLWorkerThread* gImageDecodeThread = NULL;
00443 LLTextureFetch* gTextureFetch = NULL;
00444
00445
00446 FILE *gDebugFile = NULL;
00447 BOOL gRandomizeFramerate = FALSE;
00448 BOOL gPeriodicSlowFrame = FALSE;
00449 std::map<S32,LLFrameTimer> gDebugTimers;
00450
00451
00452
00453
00454
00455
00456
00457 U64 gFrameTime = 0;
00458 F32 gFrameTimeSeconds = 0.f;
00459 F32 gFrameIntervalSeconds = 0.f;
00460 U32 gFrameCount = 0;
00461 U32 gForegroundFrameCount = 0;
00462 U64 gStartTime = 0;
00463 U64 gSpaceTime = 0;
00464
00465
00466 LLTimer gRenderStartTime;
00467 LLFrameTimer gForegroundTime;
00468 F32 gQuitAfterSeconds = 0.f;
00469 BOOL gRotateRight = FALSE;
00470
00471
00472
00473 BOOL gPacificDaylightTime = FALSE;
00474
00475
00476
00477
00478 U32 gSecondsPerDay = 0;
00479 U32 gSecondsPerYear = 0;
00480
00481 LLString gLastVersionChannel;
00482
00483
00484
00485
00486
00487
00488 LLVector3 gWindVec(3.0, 3.0, 0.0);
00489 LLVector3 gRelativeWindVec(0.0, 0.0, 0.0);
00490
00491
00492
00493
00494
00495 BOOL gVelocityInterpolate = TRUE;
00496 BOOL gPingInterpolate = TRUE;
00497
00498
00499
00500
00501
00502 LLMemoryInfo gSysMemory;
00503 LLOSInfo gSysOS;
00504
00505
00506 static const char USAGE[] = "\n"
00507 "usage:\tviewer [options]\n"
00508 "options:\n"
00509 " -login <first> <last> <password> log in as a user\n"
00510 " -autologin log in as last saved user\n"
00511 " -loginuri <URI> login server and CGI script to use\n"
00512 " -helperuri <URI> helper web CGI prefix to use\n"
00513 " -settings <filename> specify the filename of a\n"
00514 " configuration file\n"
00515 " default is settings.xml\n"
00516 " -setdefault <variable> <value> specify the value of a particular\n"
00517 " configuration variable which can be\n"
00518 " overridden by settings.xml\n"
00519 " -set <variable> <value> specify the value of a particular\n"
00520 " configuration variable that\n"
00521 " overrides all other settings\n"
00522 " -user <user_server_ip> specify userserver in dotted quad\n"
00523 #if !LL_RELEASE_FOR_DOWNLOAD
00524 " -sim <simulator_ip> specify the simulator ip address\n"
00525 #endif
00526 " -god log in as god if you have god access\n"
00527 " -purge delete files in cache\n"
00528 " -safe reset preferences, run in safe mode\n"
00529 " -noutc logs in local time, not UTC\n"
00530 " -nothread run vfs in single thread\n"
00531 " -noinvlib Do not request inventory library\n"
00532 " -multiple allow multiple viewers\n"
00533 " -nomultiple block multiple viewers\n"
00534 " -novoice disable voice\n"
00535 " -ignorepixeldepth ignore pixel depth settings\n"
00536 " -cooperative [ms] yield some idle time to local host\n"
00537 " -skin ui/branding skin folder to use\n"
00538 #if LL_WINDOWS
00539 " -noprobe disable hardware probe\n"
00540 #endif
00541 " -noquicktime disable QuickTime movies, speeds startup\n"
00542 " -nopreload don't preload UI images or sounds, speeds startup\n"
00543
00544
00545
00546 "\n";
00547
00548
00549
00550 BOOL gGodConnect = FALSE;
00551 BOOL gUseConsole = TRUE;
00552 BOOL gUseAudio = TRUE;
00553 BOOL gUseFMOD = TRUE;
00554 BOOL gLogMessages = FALSE;
00555 BOOL gRequestInventoryLibrary = TRUE;
00556 BOOL gAcceptTOS = FALSE;
00557 BOOL gAcceptCriticalMessage = FALSE;
00558
00559 std::string gChannelName = LL_CHANNEL;
00560
00561 LLUUID gInventoryLibraryOwner;
00562 LLUUID gInventoryLibraryRoot;
00563 bool gPreloadImages = true;
00564 bool gPreloadSounds = true;
00565
00566 LLString gCmdLineFirstName;
00567 LLString gCmdLineLastName;
00568 LLString gCmdLinePassword;
00569 std::map<std::string, std::string> gCommandLineSettings;
00570 std::map<std::string, std::string> gCommandLineForcedSettings;
00571 BOOL gLastExecFroze = FALSE;
00572 BOOL gIgnorePixelDepth = FALSE;
00573
00574
00575 LLPointer<LLImageGL> gDisconnectedImagep = NULL;
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00593
00594
00595
00596
00597
00598
00599
00600 void init_marker_file();
00601 void init_crash_handler();
00602 void init_logging();
00603 void create_console();
00604 void write_system_info();
00605 int parse_args(int argc, char **argv);
00606 void saved_settings_to_globals();
00607 BOOL init_cache();
00608 void purge_cache();
00609 void cleanup_app();
00610 void disconnect_viewer(void *);
00611
00612
00613
00614
00615 void write_debug(const char *str);
00616 void write_debug(const std::string& str);
00617 void close_debug();
00618 void catch_signals();
00619 void viewer_crash_callback();
00620 void remove_marker_file();
00621 #if !LL_WINDOWS
00622 void release_signals();
00623 #endif
00624
00625 void bad_network_handler();
00626
00627 #if LL_WINDOWS
00628 void disable_win_error_reporting();
00629 #endif
00630 std::string get_serial_number();
00631 bool send_url_to_other_instance(const std::string& url);
00632 BOOL another_instance_running();
00633 void main_loop();
00634
00635
00636
00637
00638
00639
00640 void uuid_table_request_file_callback(void **user_data, S32 result, LLExtStat ext_status);
00641 void send_stats();
00642
00643
00644
00645
00646 #if LL_DARWIN
00647 void init_apple_menu(const char* product);
00648 OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn);
00649 OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn);
00650 OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata);
00651 OSStatus DisplayReleaseNotes(void);
00652 #endif // LL_DARWIN
00653
00654 void ui_audio_callback(const LLUUID& uuid)
00655 {
00656 if (gAudiop)
00657 {
00658 F32 volume = gSavedSettings.getF32("AudioLevelUI");
00659 gAudiop->triggerSound(uuid, gAgent.getID(), volume);
00660 }
00661 }
00662
00663 #if LL_WINDOWS
00664 BOOL CALLBACK login_dialog_func(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lparam)
00665 {
00666 char buffer[MAX_STRING];
00667 switch(msg)
00668 {
00669 case WM_INITDIALOG:
00670 {
00671 LLString first_name = gCmdLineFirstName;
00672 LLString last_name = gCmdLineLastName;
00673 LLString password = gCmdLinePassword;
00674
00675 if (!first_name.empty())
00676 {
00677 SetDlgItemTextA( hwnd, IDC_EDIT_FIRSTNAME, first_name.c_str());
00678 }
00679 if (!last_name.empty())
00680 {
00681 SetDlgItemTextA( hwnd, IDC_EDIT_LASTNAME, last_name.c_str());
00682 }
00683 if (!password.empty())
00684 {
00685 SetDlgItemTextA( hwnd, IDC_EDIT_PASSWORD, password.c_str());
00686 }
00687
00688 first_name = gSavedSettings.getString("FirstName");
00689 last_name = gSavedSettings.getString("LastName");
00690 password = load_password_from_disk();
00691
00692 if (!first_name.empty())
00693 {
00694 SetDlgItemTextA( hwnd, IDC_EDIT_FIRSTNAME, first_name.c_str());
00695 }
00696 if (!last_name.empty())
00697 {
00698 SetDlgItemTextA( hwnd, IDC_EDIT_LASTNAME, last_name.c_str());
00699 }
00700 if (!password.empty())
00701 {
00702 SetDlgItemTextA( hwnd, IDC_EDIT_PASSWORD, password.c_str());
00703 }
00704
00705
00706 if (first_name.empty())
00707 {
00708 SetFocus(GetDlgItem(hwnd, IDC_EDIT_FIRSTNAME));
00709 }
00710 else if (last_name.empty())
00711 {
00712 SetFocus(GetDlgItem(hwnd, IDC_EDIT_LASTNAME));
00713 }
00714 else if (password.empty())
00715 {
00716 SetFocus(GetDlgItem(hwnd, IDC_EDIT_PASSWORD));
00717 }
00718 else
00719 {
00720 SetFocus(GetDlgItem(hwnd, IDC_EDIT_FIRSTNAME));
00721 }
00722
00723 BOOL remember_password = gSavedSettings.getBOOL("RememberPassword");
00724 if (remember_password)
00725 {
00726 CheckDlgButton(hwnd, IDC_REMEMBER_PASSWORD, BST_CHECKED);
00727 }
00728 else
00729 {
00730 CheckDlgButton(hwnd, IDC_REMEMBER_PASSWORD, BST_UNCHECKED);
00731 }
00732 return TRUE;
00733 }
00734
00735 case WM_COMMAND:
00736 switch(LOWORD(wParam))
00737 {
00738 case IDOK:
00739 {
00740
00741 if (GetDlgItemTextA(hwnd, IDC_EDIT_FIRSTNAME, buffer, MAX_STRING))
00742 {
00743 gCmdLineFirstName = buffer;
00744 }
00745 if (GetDlgItemTextA(hwnd, IDC_EDIT_LASTNAME, buffer, MAX_STRING))
00746 {
00747 gCmdLineLastName = buffer;
00748 }
00749 if (GetDlgItemTextA(hwnd, IDC_EDIT_PASSWORD, buffer, MAX_STRING))
00750 {
00751 gCmdLinePassword = buffer;
00752 }
00753 BOOL remember_password = (IsDlgButtonChecked(hwnd, IDC_REMEMBER_PASSWORD) == BST_CHECKED);
00754 gSavedSettings.setBOOL("RememberPassword", remember_password);
00755 EndDialog(hwnd, 0);
00756 return TRUE;
00757 }
00758 }
00759
00760 return FALSE;
00761
00762 case WM_CLOSE:
00763 case WM_DESTROY:
00764 EndDialog(hwnd, 666);
00765 return TRUE;
00766
00767 default:
00768 return FALSE;
00769 }
00770 }
00771 #endif
00772
00773 #if LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP
00774
00775 MEM_BOOL MEM_CALLBACK second_mem_error_handler(MEM_ERROR_INFO *errorInfo);
00776
00777 MEM_BOOL MEM_CALLBACK first_mem_error_handler(MEM_ERROR_INFO *errorInfo)
00778 {
00779 MemSetErrorHandler(second_mem_error_handler);
00780
00781
00782
00783
00784
00785 llerrs << "Memory allocation failed; aborting." << llendl;
00786
00787
00788
00789
00790
00791 return 0;
00792 }
00793
00794 MEM_BOOL MEM_CALLBACK second_mem_error_handler(MEM_ERROR_INFO *errorInfo)
00795 {
00796
00797 LLError::crashAndLoop("");
00798
00799 return 0;
00800 }
00801
00802 #endif // LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP
00803
00804
00805 #if LL_WINDOWS
00806 int APIENTRY WinMain(HINSTANCE hInstance,
00807 HINSTANCE hPrevInstance,
00808 LPSTR lpCmdLine,
00809 int nCmdShow)
00810 #else
00811 int main( int argc, char **argv )
00812 #endif
00813 {
00814 LLMemType mt1(LLMemType::MTYPE_STARTUP);
00815
00816 #if LL_SOLARIS && defined(__sparc)
00817 asm ("ta\t6");
00818 #endif
00819
00820 #if LL_DARWIN
00821
00822 (void) chdir(gDirUtilp->getAppRODataDir().c_str());
00823 #endif
00824
00825 #if 1
00826
00827 LLCommon::initClass();
00828
00829 # if MEM_TRACK_MEM
00830 static const bool enable_threads = false;
00831 # else
00832 static const bool enable_threads = true;
00833 # endif
00834 LLVFSThread::initClass(enable_threads && true);
00835 LLLFSThread::initClass(enable_threads && true);
00836
00837 gImageDecodeThread = new LLWorkerThread("ImageDecode", enable_threads && true);
00838 gTextureCache = new LLTextureCache(enable_threads && true);
00839 gTextureFetch = new LLTextureFetch(gTextureCache, enable_threads && false);
00840 LLImageWorker::initClass(gImageDecodeThread);
00841 LLImageJ2C::openDSO();
00842 #endif
00843
00844 #if LL_WINDOWS
00845
00846
00847
00848
00849
00850
00851 LPSTR cmd_line_including_exe_name = GetCommandLineA();
00852
00853 gIconResource = MAKEINTRESOURCE(IDI_LL_ICON);
00854
00855 const S32 MAX_ARGS = 100;
00856 int argc = 0;
00857 char* argv[MAX_ARGS];
00858
00859 char *token = NULL;
00860 if( cmd_line_including_exe_name[0] == '\"' )
00861 {
00862
00863 token = strtok( cmd_line_including_exe_name, "\"" );
00864 argv[argc++] = token;
00865 token = strtok( NULL, " \t," );
00866 }
00867 else
00868 {
00869
00870 token = strtok( cmd_line_including_exe_name, " \t," );
00871 }
00872
00873 while( (token != NULL) && (argc < MAX_ARGS) )
00874 {
00875 argv[argc++] = token;
00876
00877 if (*(token + strlen(token) + 1) == '\"')
00878 {
00879 token = strtok( NULL, "\"");
00880 }
00881 else
00882 {
00883 token = strtok( NULL, " \t," );
00884 }
00885 }
00886 #endif
00887
00888
00889
00890
00891
00892
00893
00894
00895 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[UserServerDefaultChoice].mName);
00896 S32 j;
00897 for (j = 1; j < argc; j++)
00898 {
00899 if (!strcmp(argv[j], "--aditi"))
00900 {
00901 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[USERSERVER_ADITI].mName);
00902 }
00903 else if (!strcmp(argv[j], "--agni"))
00904 {
00905 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[USERSERVER_AGNI].mName);
00906 }
00907 else if (!strcmp(argv[j], "--dmz"))
00908 {
00909 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[USERSERVER_DMZ].mName);
00910 }
00911 else if (!strcmp(argv[j], "--siva"))
00912 {
00913 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[USERSERVER_SIVA].mName);
00914 }
00915 else if (!strcmp(argv[j], "--shakti"))
00916 {
00917 sprintf(gUserServerName,"%s", gUserServerDomainName[USERSERVER_SHAKTI].mName);
00918 }
00919 else if (!strcmp(argv[j], "--durga"))
00920 {
00921 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[USERSERVER_DURGA].mName);
00922 }
00923 else if (!strcmp(argv[j], "--soma"))
00924 {
00925 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[USERSERVER_SOMA].mName);
00926 }
00927 else if (!strcmp(argv[j], "--ganga"))
00928 {
00929 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[USERSERVER_GANGA].mName);
00930 }
00931 else if (!strcmp(argv[j], "--vaak"))
00932 {
00933 sprintf(gUserServerName,"%s", gUserServerDomainName[USERSERVER_VAAK].mName);
00934 }
00935 else if (!strcmp(argv[j], "--uma"))
00936 {
00937 sprintf(gUserServerName,"%s", gUserServerDomainName[USERSERVER_UMA].mName);
00938 }
00939 else if (!strcmp(argv[j], "-user") && (++j < argc))
00940 {
00941 if (!strcmp(argv[j], "-"))
00942 {
00943 snprintf(gUserServerName, MAX_STRING, "%s", LOOPBACK_ADDRESS_STRING);
00944 }
00945 else
00946 {
00947 snprintf(gUserServerName, MAX_STRING, "%s", argv[j]);
00948 }
00949 }
00950 else if (!strcmp(argv[j], "-multiple"))
00951 {
00952
00953 gMultipleViewersOK = TRUE;
00954 }
00955 else if (!strcmp(argv[j], "-novoice"))
00956 {
00957
00958 gDisableVoice = TRUE;
00959 }
00960 }
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972 gDirUtilp->initAppDirs("SecondLife");
00973
00974
00975
00976
00977 LLError::initForApplication(
00978 gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
00979 LLError::setFatalFunction(errorCallback);
00980
00981
00982 #if LL_RELEASE_FOR_DOWNLOAD && LL_SEND_CRASH_REPORTS
00983
00984
00985
00986
00987 init_crash_handler();
00988 #endif
00989
00990 init_logging();
00991
00992
00993
00994
00995
00996
00997 gSettingsFileName = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, DEFAULT_SETTINGS_FILE);
00998 gOldSettingsFileName = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, LEGACY_DEFAULT_SETTINGS_FILE);
00999
01001
01002
01003
01004 S32 args_result = 0;
01005
01006 #if LL_DARWIN
01007 {
01008
01009 std::string args;
01010 if(_read_file_into_string(args, "arguments.txt"))
01011 {
01012
01013
01014
01015 std::vector<std::string> arglist;
01016
01017 arglist.push_back("newview");
01018
01019 llinfos << "Reading additional command line arguments from arguments.txt..." << llendl;
01020
01021 typedef boost::tokenizer<boost::escaped_list_separator<char> > tokenizer;
01022 boost::escaped_list_separator<char> sep("\\", "\r\n ", "\"'");
01023 tokenizer tokens(args, sep);
01024 tokenizer::iterator token_iter;
01025
01026 for(token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter)
01027 {
01028 llinfos << "argument: '" << (token_iter->c_str()) << "'" << llendl;
01029
01030 arglist.push_back(*token_iter);
01031 }
01032
01033 char **fakeargv = new char*[arglist.size()];
01034 int i;
01035 for(i=0; i < arglist.size(); i++)
01036 fakeargv[i] = const_cast<char*>(arglist[i].c_str());
01037
01038 args_result = parse_args(arglist.size(), fakeargv);
01039 delete[] fakeargv;
01040 }
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050 CFURLRef url = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("language"), CFSTR("txt"), NULL);
01051 char path[MAX_PATH];
01052 if(CFURLGetFileSystemRepresentation(url, false, (UInt8 *)path, sizeof(path)))
01053 {
01054 std::string lang;
01055 if(_read_file_into_string(lang, path))
01056 {
01057 gCommandLineForcedSettings["SystemLanguage"] = lang;
01058 }
01059 }
01060 CFRelease(url);
01061 }
01062 #endif
01063
01064
01065
01066
01067 args_result |= parse_args(argc, argv);
01068 if (args_result)
01069 {
01070 remove_marker_file();
01071 return args_result;
01072 }
01073
01074 if (!strcmp(gUserServerName, gUserServerDomainName[USERSERVER_AGNI].mName))
01075 {
01076 gInProductionGrid = TRUE;
01077 }
01078
01079
01080 gSecondLife = "Second Life (Dale's Unofficial Viewer)";
01081
01082
01083 if (! gDirUtilp->getSkinDir().empty() )
01084 {
01085 std::string skin_def_file = gDirUtilp->getExpandedFilename(LL_PATH_TOP_SKIN, "skin.xml");
01086 LLXmlTree skin_def_tree;
01087
01088 if (!skin_def_tree.parseFile(skin_def_file))
01089 {
01090 llerrs << "Failed to parse skin definition." << llendl;
01091 }
01092
01093 LLXmlTreeNode* rootp = skin_def_tree.getRoot();
01094 LLXmlTreeNode* disabled_message_node = rootp->getChildByName("disabled_message");
01095 if (disabled_message_node)
01096 {
01097 gDisabledMessage = disabled_message_node->getContents();
01098 }
01099
01100 static LLStdStringHandle hide_links_string = LLXmlTree::addAttributeString("hide_links");
01101 rootp->getFastAttributeBOOL(hide_links_string, gHideLinks);
01102
01103
01104
01105 static LLStdStringHandle silent_string = LLXmlTree::addAttributeString("silent_update");
01106 BOOL silent_update;
01107 rootp->getFastAttributeBOOL(silent_string, silent_update);
01108 gHideLinks = (gHideLinks || silent_update);
01109 }
01110
01111 #if LL_DARWIN
01112
01113 init_apple_menu(gSecondLife.c_str());
01114
01115 #if __ppc__
01116
01117
01118 if(!gSysCPU.hasAltivec())
01119 {
01120 std::ostringstream msg;
01121 msg << gSecondLife << " requires a processor with AltiVec (G4 or later).";
01122 OSMessageBox(
01123 msg.str().c_str(),
01124 NULL,
01125 OSMB_OK);
01126 remove_marker_file();
01127 return 1;
01128 }
01129 #endif
01130
01131 #endif // LL_DARWIN
01132
01133
01134
01135 std::ostringstream splash_msg;
01136
01137 splash_msg << "Loading " << gSecondLife << "...";
01138 LLSplashScreen::show();
01139 LLSplashScreen::update(splash_msg.str().c_str());
01140
01141 LLVolumeMgr::initClass();
01142
01143
01144
01145
01146 gFeatureManagerp = new LLFeatureManager;
01147
01148 gStartTime = totalTime();
01149
01150
01152
01153
01154
01155
01156
01157 declare_settings();
01158
01159 #if !LL_RELEASE_FOR_DOWNLOAD
01160
01161 gSavedSettings.saveToFile(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"settings_default.xml").c_str(), FALSE);
01162 #endif
01163
01164
01165
01166
01167 #if LL_RELEASE_FOR_DOWNLOAD
01168 gWindowTitle = gSecondLife;
01169 #elif LL_DEBUG
01170 gWindowTitle = gSecondLife + LLString(" [DEBUG] ") + gArgs;
01171 #else
01172 gWindowTitle = gSecondLife + LLString(" ") + gArgs;
01173 #endif
01174 LLString::truncate(gWindowTitle, 255);
01175
01176 if (!gMultipleViewersOK)
01177 {
01178
01179
01180
01181
01182
01183
01184
01185
01186 std::string slurl;
01187 if (!LLStartUp::sSLURLCommand.empty())
01188 {
01189 slurl = LLStartUp::sSLURLCommand;
01190 }
01191 else if (LLURLSimString::parse())
01192 {
01193 slurl = LLURLSimString::getURL();
01194 }
01195 if (!slurl.empty())
01196 {
01197 if (send_url_to_other_instance(slurl))
01198 {
01199
01200 return 1;
01201 }
01202 }
01203
01204 gSecondInstance = another_instance_running();
01205
01206 if (gSecondInstance)
01207 {
01208 std::ostringstream msg;
01209 msg <<
01210 gSecondLife << " is already running.\n"
01211 "\n"
01212 "Check your task bar for a minimized copy of the program.\n"
01213 "If this message persists, restart your computer.",
01214 OSMessageBox(
01215 msg.str().c_str(),
01216 NULL,
01217 OSMB_OK);
01218 return 1;
01219 }
01220
01221 init_marker_file();
01222
01223 #if LL_SEND_CRASH_REPORTS
01224 if (gLastExecFroze)
01225 {
01226 llinfos << "Last execution froze, requesting to send crash report." << llendl;
01227
01228
01229
01230 std::ostringstream msg;
01231 msg << gSecondLife
01232 << " appears to have frozen or crashed on the previous run.\n"
01233 << "Would you like to send a crash report?";
01234 std::string alert;
01235 alert = gSecondLife;
01236 alert += " Alert";
01237 S32 choice = OSMessageBox(msg.str().c_str(),
01238 alert.c_str(),
01239 OSMB_YESNO);
01240 if (OSBTN_YES == choice)
01241 {
01242 llinfos << "Sending crash report." << llendl;
01243
01244 remove_marker_file();
01245 #if LL_WINDOWS
01246 std::string exe_path = gDirUtilp->getAppRODataDir();
01247 exe_path += gDirUtilp->getDirDelimiter();
01248 exe_path += "win_crash_logger.exe";
01249
01250 std::string arg_string = "-previous -user ";
01251 arg_string += gUserServerName;
01252 arg_string += " -name \"";
01253 arg_string += gSecondLife;
01254 arg_string += "\"";
01255
01256
01257 _spawnl(_P_WAIT, exe_path.c_str(), exe_path.c_str(), arg_string.c_str(), NULL);
01258 #elif LL_DARWIN
01259 std::string command_str;
01260 command_str = "crashreporter.app/Contents/MacOS/crashreporter ";
01261 command_str += "-previous -user ";
01262 command_str += gUserServerName;
01263
01264
01265 system(command_str.c_str());
01266 #elif LL_LINUX || LL_SOLARIS
01267 std::string cmd =gDirUtilp->getAppRODataDir();
01268 cmd += gDirUtilp->getDirDelimiter();
01269 #if LL_LINUX
01270 cmd += "linux-crash-logger.bin";
01271 #else // LL_SOLARIS
01272 cmd += "bin/solaris-crash-logger";
01273 #endif
01274 char* const cmdargv[] =
01275 {(char*)cmd.c_str(),
01276 (char*)"-previous",
01277 (char*)"-user",
01278 (char*)gUserServerName,
01279 (char*)"-name",
01280 (char*)gSecondLife.c_str(),
01281 NULL};
01282 fflush(NULL);
01283 pid_t pid = fork();
01284 if (pid == 0)
01285 {
01286 execv(cmd.c_str(), cmdargv);
01287 llwarns << "execv failure when trying to start " << cmd << llendl;
01288 _exit(1);
01289 } else {
01290 if (pid > 0)
01291 {
01292
01293 int childExitStatus;
01294 waitpid(pid, &childExitStatus, 0);
01295 } else {
01296 llwarns << "fork failure." << llendl;
01297 }
01298 }
01299 #endif
01300 }
01301 else
01302 {
01303 llinfos << "Not sending crash report." << llendl;
01304 }
01305 }
01306 #endif // #if LL_SEND_CRASH_REPORTS
01307 }
01308 else
01309 {
01310 gSecondInstance = another_instance_running();
01311
01312 if (gSecondInstance)
01313 {
01314 gDisableVoice = TRUE;
01315 }
01316
01317 init_marker_file();
01318 }
01319
01320
01321
01322
01323 write_system_info();
01324
01325 #if LL_WINDOWS
01326
01327
01328
01329
01330
01331 llinfos << "Turning off Windows error reporting." << llendl;
01332 disable_win_error_reporting();
01333 #endif // LL_WINDOWS
01334
01335
01336 gCurrentVersion = llformat("%s %d.%d.%d.%d.%d", gChannelName.c_str(), LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH, LL_VERSION_BUILD, LL_VERSION_REVISION );
01337
01338
01339
01340
01341 llinfos << "J2C Engine is: " << LLImageJ2C::getEngineInfo() << llendl;
01342
01343
01344
01345
01346 llinfos << "Loading feature tables." << llendl;
01347
01348 gFeatureManagerp->loadFeatureTables();
01349 gFeatureManagerp->initCPUFeatureMasks();
01350
01351
01352 gSavedSettings.applyOverrides(gCommandLineSettings);
01353
01354
01355 gUICtrlFactory = new LLViewerUICtrlFactory();
01356
01357
01358
01359 LLAlertDialog::parseAlerts("alerts.xml", &gSavedSettings, TRUE);
01360
01361
01362 llinfos << "Loading configuration file " << gSettingsFileName << llendl;
01363 if (0 == gSavedSettings.loadFromFile(gSettingsFileName))
01364 {
01365 llinfos << "Failed to load settings from " << gSettingsFileName << llendl;
01366 llinfos << "Loading legacy settings from " << gOldSettingsFileName << llendl;
01367 gSavedSettings.loadFromFileLegacy(gOldSettingsFileName);
01368 }
01369
01370
01371 LLString nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" );
01372 if ( nextLoginLocation.length() )
01373 {
01374 LLURLSimString::setString( nextLoginLocation.c_str() );
01375 };
01376
01377
01378 gSavedSettings.applyOverrides(gCommandLineForcedSettings);
01379
01380 gLastRunVersion = gSavedSettings.getString("LastRunVersion");
01381
01382 fixup_settings();
01383
01384
01385 std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
01386 gCrashSettings.loadFromFile(crash_settings_filename.c_str());
01387
01389
01391 #if LL_WINDOWS
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409 #endif
01410
01411
01412 gNumSessions = gSavedSettings.getS32("NumSessions");
01413 gNumSessions++;
01414 gSavedSettings.setS32("NumSessions", gNumSessions);
01415
01416 gSavedSettings.setString("HelpLastVisitedURL",gSavedSettings.getString("HelpHomeURL"));
01417
01418 if (gSavedSettings.getBOOL("VerboseLogs"))
01419 {
01420 LLError::setPrintLocation(true);
01421 }
01422
01423 #if !LL_RELEASE_FOR_DOWNLOAD
01424 if (gUserServerChoice == USERSERVER_NONE)
01425 {
01426
01427
01428 S32 server = gSavedSettings.getS32("ServerChoice");
01429 if (server != 0)
01430 gUserServerChoice = (EUserServerDomain)llclamp(server, 0, (S32)USERSERVER_COUNT - 1);
01431 if (server == USERSERVER_OTHER)
01432 {
01433 LLString custom_server = gSavedSettings.getString("CustomServer");
01434 if (custom_server.empty())
01435 {
01436 snprintf(gUserServerName, MAX_STRING, "none");
01437 }
01438 else
01439 {
01440 snprintf(gUserServerName, MAX_STRING, "%s", custom_server.c_str());
01441 }
01442 }
01443 }
01444 #endif
01445
01446 if (gUserServerChoice == USERSERVER_NONE)
01447 {
01448 gUserServerChoice = UserServerDefaultChoice;
01449 }
01450
01451
01452 LLString viewer_art_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"viewerart.xml");
01453 llinfos << "Loading art table from " << viewer_art_filename << llendl;
01454 gViewerArt.loadFromFile(viewer_art_filename.c_str(), FALSE);
01455 LLString textures_filename = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "textures", "textures.xml");
01456 llinfos << "Loading art table from " << textures_filename << llendl;
01457 gViewerArt.loadFromFile(textures_filename.c_str(), FALSE);
01458
01459 LLString colors_base_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "colors_base.xml");
01460 llinfos << "Loading base colors from " << colors_base_filename << llendl;
01461 gColors.loadFromFile(colors_base_filename.c_str(), FALSE, TYPE_COL4U);
01462
01463
01464 LLString user_colors_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "colors.xml");
01465 llinfos << "Loading user colors from " << user_colors_filename << llendl;
01466 if (gColors.loadFromFile(user_colors_filename.c_str(), FALSE, TYPE_COL4U) == 0)
01467 {
01468 llinfos << "Failed to load user colors from " << user_colors_filename << llendl;
01469 LLString user_legacy_colors_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "colors.ini");
01470 llinfos << "Loading legacy colors from " << user_legacy_colors_filename << llendl;
01471 gColors.loadFromFileLegacy(user_legacy_colors_filename.c_str(), FALSE, TYPE_COL4U);
01472 }
01473
01474
01475 LLUI::initClass(&gSavedSettings,
01476 &gColors,
01477 &gViewerArt,
01478 &gImageList,
01479 ui_audio_callback,
01480 &LLUI::sGLScaleFactor);
01481
01482 gUICtrlFactory->setupPaths();
01483
01485
01486
01487
01488
01489 LLGroupMgr::parseRoleActions("role_actions.xml");
01490
01491 LLAgent::parseTeleportMessages("teleport_strings.xml");
01492
01493
01494 saved_settings_to_globals();
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529 gSerialNumber = get_serial_number();
01530
01531 #if LL_WINDOWS
01532
01533
01534
01535
01536 if (gProbeHardware)
01537 {
01538 BOOL vram_only = !gSavedSettings.getBOOL("ProbeHardwareOnStartup");
01539
01540 LLSplashScreen::update("Detecting hardware...");
01541
01542 llinfos << "Attempting to poll DirectX for hardware info" << llendl;
01543 gDXHardware.setWriteDebugFunc(write_debug);
01544 BOOL probe_ok = gDXHardware.getInfo(vram_only);
01545
01546 if (!probe_ok
01547 && gSavedSettings.getWarning("AboutDirectX9"))
01548 {
01549 llinfos << "DirectX probe failed, alerting user." << llendl;
01550
01551
01552
01553 std::ostringstream msg;
01554 msg <<
01555 gSecondLife << " is unable to detect DirectX 9.0b or greater.\n"
01556 "\n" <<
01557 gSecondLife << " uses DirectX to detect hardware and/or\n"
01558 "outdated drivers that can cause stability problems,\n"
01559 "poor performance and crashes. While you can run\n" <<
01560 gSecondLife << " without it, we highly recommend running\n"
01561 "with DirectX 9.0b\n"
01562 "\n"
01563 "Do you wish to continue?\n";
01564 S32 button = OSMessageBox(
01565 msg.str().c_str(),
01566 "Warning",
01567 OSMB_YESNO);
01568 if (OSBTN_NO== button)
01569 {
01570 llinfos << "User quitting after failed DirectX 9 detection" << llendl;
01571 LLWeb::loadURLExternal(DIRECTX_9_URL);
01572 return 0;
01573 }
01574 gSavedSettings.setWarning("AboutDirectX9", FALSE);
01575 }
01576 llinfos << "Done polling DirectX for hardware info" << llendl;
01577
01578
01579 gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE);
01580
01581
01582 LLSplashScreen::update(splash_msg.str().c_str());
01583 }
01584
01585 if (!LLWinDebug::setupExceptionHandler())
01586 {
01587 llwarns << " Someone took over my exception handler (post hardware probe)!" << llendl;
01588 }
01589
01590 gGLManager.mVRAM = gDXHardware.getVRAM();
01591 llinfos << "Detected VRAM: " << gGLManager.mVRAM << llendl;
01592 #endif
01593
01594
01595
01596 LLUUID::getNodeID(gMACAddress);
01597
01598
01599
01600 #if LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP
01601 MemSetErrorHandler(first_mem_error_handler);
01602 #endif // LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP
01603
01604 gViewerStats = new LLViewerStats();
01605
01606
01607
01608
01609
01610 if (!init_cache())
01611 {
01612 std::ostringstream msg;
01613 msg <<
01614 gSecondLife << " is unable to access a file that it needs.\n"
01615 "\n"
01616 "This can be because you somehow have multiple copies running, "
01617 "or your system incorrectly thinks a file is open. "
01618 "If this message persists, restart your computer and try again. "
01619 "If it continues to persist, you may need to completely uninstall " <<
01620 gSecondLife << " and reinstall it.";
01621 OSMessageBox(
01622 msg.str().c_str(),
01623 NULL,
01624 OSMB_OK);
01625 return 1;
01626 }
01627
01628 #if LL_DARWIN
01629
01630 if(!gHideLinks && gCurrentVersion != gLastRunVersion)
01631 {
01632
01633 DisplayReleaseNotes();
01634 }
01635 #endif
01636
01637
01638
01639
01640
01641
01642 #if LL_WINDOWS
01643 if (gUseConsole && gSavedSettings.getBOOL("ShowConsoleWindow"))
01644 {
01645 create_console();
01646 }
01647 #endif
01648
01649 llinfos << "Initializing window..." << llendl;
01650
01651
01652 gNoRender = gSavedSettings.getBOOL("DisableRendering");
01653
01654
01655 LLSplashScreen::hide();
01656
01657
01658 char window_title_str[256];
01659 strncpy(window_title_str, gWindowTitle.c_str(), sizeof(window_title_str) - 1);
01660 window_title_str[sizeof(window_title_str) - 1] = '\0';
01661
01662
01663 gViewerWindow = new LLViewerWindow(window_title_str, sWindowClass,
01664 gSavedSettings.getS32("WindowX"), gSavedSettings.getS32("WindowY"),
01665 gSavedSettings.getS32("WindowWidth"), gSavedSettings.getS32("WindowHeight"),
01666 FALSE, gIgnorePixelDepth, gSavedSettings.getS32("StereoMode"));
01667
01668 if (gSavedSettings.getBOOL("FullScreen"))
01669 {
01670 gViewerWindow->toggleFullscreen(FALSE);
01671
01672 }
01673
01674
01675 gSavedSettings.setS32("StereoMode", gViewerWindow->getWindow()->getStereoMode());
01676
01677 if (gSavedSettings.getBOOL("WindowMaximized"))
01678 {
01679 gViewerWindow->mWindow->maximize();
01680 gViewerWindow->getWindow()->setNativeAspectRatio(gSavedSettings.getF32("FullScreenAspectRatio"));
01681 }
01682
01683 LLUI::sWindow = gViewerWindow->getWindow();
01684
01685 LLAlertDialog::parseAlerts("alerts.xml");
01686 LLNotifyBox::parseNotify("notify.xml");
01687
01688 LLMediaEngine::initClass();
01689
01690
01691
01692
01693
01694 gFeatureManagerp->cleanupFeatureTables();
01695
01696
01697 gViewerWindow->setCursor(UI_CURSOR_WAIT);
01698
01699
01700 #if LL_WINDOWS && LL_LCD_COMPILE
01701
01702 gLcdScreen = new llLCD(hInstance);
01703 CreateLCDDebugWindows();
01704 #endif
01705
01706
01707 gViewerWindow->initBase();
01708
01709
01710 gViewerWindow->mWindow->show();
01711
01712 write_debug(gGLManager.getGLInfoString());
01713 llinfos << gGLManager.getGLInfoString() << llendl;
01714
01715
01716 bind_keyboard_functions();
01717
01718
01719 if (!gViewerKeyboard.loadBindings(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"keys.ini").c_str()))
01720 {
01721 llerrs << "Unable to open keys.ini" << llendl;
01722 }
01723
01724 gViewerKeyboard.loadBindings(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"custom_keys.ini").c_str());
01725
01726
01727 FILE* app_file = LLFile::fopen( gDirUtilp->getExecutablePathAndName().c_str(), "rb" );
01728 if( app_file )
01729 {
01730 LLMD5 app_md5;
01731 app_md5.update( app_file );
01732 app_md5.finalize();
01733 app_md5.raw_digest( gViewerDigest.mData );
01734 }
01735 llinfos << "Viewer Digest: " << gViewerDigest << llendl;
01736
01737
01738
01739 if (!gGLManager.mHasMultitexture && !gNoRender)
01740 {
01741 std::ostringstream msg;
01742 msg <<
01743 "You do not appear to have the proper hardware requirements "
01744 "for " << gSecondLife << ". " << gSecondLife << " requires an OpenGL graphics "
01745 "card that has multitexture support. If this is the case, "
01746 "you may want to make sure that you have the latest drivers for "
01747 "your graphics card, and service packs and patches for your "
01748 "operating system.\n"
01749 "If you continue to have problems, please go to: "
01750 "www.secondlife.com/support ";
01751 OSMessageBox(
01752 msg.str().c_str(),
01753 NULL,
01754 OSMB_OK);
01755 return 0;
01756 }
01757
01758
01759 gSavedSettings.setString("LastRunVersion", gCurrentVersion);
01760
01761 gSimLastTime = gRenderStartTime.getElapsedTimeF32();
01762 gSimFrames = (F32)gFrameCount;
01763
01764
01765
01766
01767 main_loop();
01768
01769 cleanup_app();
01770
01771
01772
01773 if (!gLaunchFileOnQuit.empty())
01774 {
01775 #if LL_WINDOWS
01776
01777 SetCursor(LoadCursor(NULL, IDC_WAIT));
01778 #endif
01779
01780
01781 ms_sleep(1000);
01782
01783 LLWeb::loadURLExternal( gLaunchFileOnQuit );
01784 }
01785
01786 llinfos << "Goodbye" << llendflush;
01787 return 0;
01788 }
01789
01790 bool send_url_to_other_instance(const std::string& url)
01791 {
01792 #if LL_WINDOWS
01793 wchar_t window_class[256];
01794 mbstowcs(window_class, sWindowClass, 255);
01795 window_class[255] = 0;
01796
01797 HWND other_window = FindWindow(window_class, NULL);
01798 if (other_window != NULL)
01799 {
01800 lldebugs << "Found other window with the name '" << gWindowTitle << "'" << llendl;
01801 COPYDATASTRUCT cds;
01802 const S32 SLURL_MESSAGE_TYPE = 0;
01803 cds.dwData = SLURL_MESSAGE_TYPE;
01804 cds.cbData = url.length() + 1;
01805 cds.lpData = (void*)url.c_str();
01806
01807 LRESULT msg_result = SendMessage(other_window, WM_COPYDATA, NULL, (LPARAM)&cds);
01808 lldebugs << "SendMessage(WM_COPYDATA) to other window '"
01809 << gWindowTitle << "' returned " << msg_result << llendl;
01810 return true;
01811 }
01812 #endif
01813 return false;
01814 }
01815
01816 BOOL another_instance_running()
01817 {
01818
01819
01820
01821 std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.exec_marker");
01822 llinfos << "Checking marker file for lock..." << llendl;
01823
01824
01825
01826 FILE* fMarker = LLFile::fopen(marker_file.c_str(), "rb");
01827 if (fMarker != NULL)
01828 {
01829
01830 fclose(fMarker);
01831 fMarker = LLFile::fopen(marker_file.c_str(), "wb");
01832 if (fMarker == NULL)
01833 {
01834 llinfos << "Marker file is locked." << llendl;
01835 return TRUE;
01836 }
01837 #if LL_DARWIN
01838
01839 if (flock(fileno(fMarker), LOCK_EX | LOCK_NB) == -1)
01840 {
01841
01842 fclose(fMarker);
01843 llinfos << "Marker file is locked." << llendl;
01844 return TRUE;
01845 }
01846 #endif
01847 fclose(fMarker);
01848 }
01849 llinfos << "Marker file isn't locked." << llendl;
01850 return FALSE;
01851 }
01852
01853
01854 void check_for_events()
01855 {
01856 LLFastTimer t2(LLFastTimer::FTM_MESSAGES);
01857 #if LL_WINDOWS
01858 if (!LLWinDebug::setupExceptionHandler())
01859 {
01860 llwarns << " Someone took over my exception handler (post messagehandling)!" << llendl;
01861 }
01862 #endif
01863
01864 gViewerWindow->mWindow->gatherInput();
01865 }
01866
01867 #include "moviemaker.h"
01868 extern BOOL gbCapturing;
01869
01870 #if !LL_SOLARIS
01871 extern MovieMaker gMovieMaker;
01872 #endif
01873
01874 void main_loop()
01875 {
01876
01877 gServicePump = new LLPumpIO(gAPRPoolp);
01878 LLHTTPClient::setPump(*gServicePump);
01879 LLHTTPClient::setCABundle(gDirUtilp->getCAFile());
01880
01881
01882 gLocalSpeakerMgr = new LLLocalSpeakerMgr();
01883 gActiveChannelSpeakerMgr = new LLActiveSpeakerMgr();
01884
01885 LLVoiceChannel::initClass();
01886 LLVoiceClient::init(gServicePump);
01887
01888 LLMemType mt1(LLMemType::MTYPE_MAIN);
01889 LLTimer frameTimer,idleTimer;
01890 LLTimer debugTime;
01891
01892
01893 while (!gQuit)
01894 {
01895 LLFastTimer::reset();
01896 {
01897 LLFastTimer t(LLFastTimer::FTM_FRAME);
01898
01899 check_for_events();
01900
01901 #if 1 && !RELEASE_FOR_DOWNLOAD
01902
01903 if (debugTime.getElapsedTimeF32() > 1.f)
01904 {
01905 debugTime.reset();
01906 }
01907 #endif
01908 if (!gQuit)
01909 {
01910
01911
01912
01913 if (gViewerWindow->mWindow->getVisible()
01914 && gViewerWindow->getActive()
01915 && !gViewerWindow->mWindow->getMinimized()
01916 && LLStartUp::getStartupState() == STATE_STARTED
01917 && !gViewerWindow->getShowProgress()
01918 && !gFocusMgr.focusLocked())
01919 {
01920 gKeyboard->scanKeyboard();
01921 LLViewerJoystick::scanJoystick();
01922 }
01923
01924
01925 {
01926 LLFastTimer t3(LLFastTimer::FTM_IDLE);
01927 idle();
01928 LLCurl::process();
01929
01930 gServicePump->pump();
01931 gServicePump->callback();
01932 }
01933
01934 if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED))
01935 {
01936 save_final_snapshot(NULL);
01937 disconnect_viewer(NULL);
01938 }
01939
01940
01941 if (!gQuit)
01942 {
01943 display();
01944
01945 LLFloaterSnapshot::update();
01946
01947 #if !LL_SOLARIS
01948 if (gbCapturing)
01949 {
01950 gMovieMaker.Snap();
01951 }
01952 #endif
01953 #if LL_WINDOWS && LL_LCD_COMPILE
01954
01955 gLcdScreen->UpdateDisplay();
01956 #endif
01957 }
01958 }
01959
01960
01961 {
01962 LLFastTimer t2(LLFastTimer::FTM_SLEEP);
01963 bool run_multiple_threads = gSavedSettings.getBOOL("RunMultipleThreads");
01964
01965
01966 if(gYieldTime)
01967 {
01968 ms_sleep(gYieldMS);
01969 }
01970
01971
01972 if ( gNoRender
01973 || !gViewerWindow->mWindow->getVisible()
01974 || !gFocusMgr.getAppHasFocus())
01975 {
01976
01977 S32 milliseconds_to_sleep = llclamp(gSavedSettings.getS32("BackgroundYieldTime"), 0, 1000);
01978
01979
01980 if (milliseconds_to_sleep > 0)
01981 {
01982 ms_sleep(milliseconds_to_sleep);
01983
01984 gTextureCache->pause();
01985 gImageDecodeThread->pause();
01986 }
01987 }
01988
01989 if (gRandomizeFramerate)
01990 {
01991 ms_sleep(rand() % 200);
01992 }
01993
01994 if (gPeriodicSlowFrame
01995 && (gFrameCount % 10 == 0))
01996 {
01997 llinfos << "Periodic slow frame - sleeping 500 ms" << llendl;
01998 ms_sleep(500);
01999 }
02000
02001
02002 const F64 min_frame_time = 0.0;
02003 const F64 min_idle_time = 0.0;
02004 const F64 max_idle_time = run_multiple_threads ? min_idle_time : .005;
02005 idleTimer.reset();
02006 while(1)
02007 {
02008 S32 work_pending = 0;
02009 S32 io_pending = 0;
02010 work_pending += gTextureCache->update(1);
02011 work_pending += gImageDecodeThread->update(1);
02012 work_pending += gTextureFetch->update(1);
02013 io_pending += LLVFSThread::updateClass(1);
02014 io_pending += LLLFSThread::updateClass(1);
02015 if (io_pending > 1000)
02016 {
02017 ms_sleep(llmin(io_pending/100,100));
02018 }
02019
02020 F64 frame_time = frameTimer.getElapsedTimeF64();
02021 F64 idle_time = idleTimer.getElapsedTimeF64();
02022 if (frame_time >= min_frame_time &&
02023 idle_time >= min_idle_time &&
02024 (!work_pending || idle_time >= max_idle_time))
02025 {
02026 break;
02027 }
02028 }
02029 frameTimer.reset();
02030
02031
02032
02033 if (run_multiple_threads == FALSE)
02034 {
02035 gTextureCache->pause();
02036 gImageDecodeThread->pause();
02037
02038 }
02039
02040
02041 }
02042
02043 }
02044 }
02045
02046
02047 if (STATE_STARTED == LLStartUp::getStartupState())
02048 {
02049 save_final_snapshot(NULL);
02050 }
02051
02052 delete gServicePump;
02053
02054 llinfos << "Exiting main_loop" << llendflush;
02055 }
02056
02057
02058 void process_keystrokes_async()
02059 {
02060 #if LL_WINDOWS
02061 MSG msg;
02062
02063 while( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE | PM_NOYIELD))
02064 {
02065
02066 if (msg.message >= WM_MOUSEFIRST &&
02067 msg.message <= WM_MOUSELAST ||
02068 msg.message == WM_QUIT)
02069 {
02070 break;
02071 }
02072
02073
02074 PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE | PM_NOYIELD);
02075
02076
02077
02078
02079 TranslateMessage(&msg);
02080 DispatchMessage(&msg);
02081 }
02082
02083
02084
02085
02086 if (gViewerWindow->mWindow->getVisible()
02087 && gViewerWindow->getActive()
02088 && !gViewerWindow->mWindow->getMinimized()
02089 && LLStartUp::getStartupState() == STATE_STARTED
02090 && !gViewerWindow->getShowProgress()
02091 && !gFocusMgr.focusLocked())
02092 {
02093 gKeyboard->scanKeyboard();
02094 }
02095 #endif
02096 }
02097
02099
02100
02101
02102
02103 FILE *gMarkerFile = NULL;
02104
02105 void remove_marker_file()
02106 {
02107 llinfos << "remove_marker_file()" << llendl;
02108 if (gMarkerFile != NULL)
02109 {
02110 fclose(gMarkerFile);
02111 gMarkerFile = NULL;
02112 }
02113 if( gDirUtilp )
02114 {
02115 LLString marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.exec_marker");
02116 ll_apr_file_remove( marker_file );
02117 }
02118 }
02119
02120 void init_marker_file()
02121 {
02122 #if LL_SOLARIS
02123 struct flock fl;
02124 fl.l_whence = SEEK_SET;
02125 fl.l_start = 0;
02126 fl.l_len = 1;
02127 #endif
02128
02129
02130
02131
02132 std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.exec_marker");
02133 llinfos << "Checking marker file for lock..." << llendl;
02134
02135 FILE* fMarker = LLFile::fopen(marker_file.c_str(), "rb");
02136 if (fMarker != NULL)
02137 {
02138
02139 fclose(fMarker);
02140 fMarker = LLFile::fopen(marker_file.c_str(), "wb");
02141 if (fMarker == NULL)
02142 {
02143
02144 llinfos << "Marker file is locked." << llendl;
02145 return;
02146 }
02147 #if LL_DARWIN
02148
02149 if (flock(fileno(fMarker), LOCK_EX | LOCK_NB) == -1)
02150 {
02151
02152 fclose(fMarker);
02153 llinfos << "Marker file is locked." << llendl;
02154 return;
02155 }
02156 #endif
02157
02158
02159 fclose(fMarker);
02160 gLastExecFroze = TRUE;
02161 llinfos << "Exec marker found: program froze on previous execution" << llendl;
02162 }
02163
02164
02165
02166 #if LL_WINDOWS
02167 gMarkerFile = LLFile::_fsopen(marker_file.c_str(), "w", _SH_DENYWR);
02168 #else
02169 gMarkerFile = LLFile::fopen(marker_file.c_str(), "w");
02170 if (gMarkerFile)
02171 {
02172 int fd = fileno(gMarkerFile);
02173
02174 #if LL_SOLARIS
02175 fl.l_type = F_WRLCK;
02176 if (fcntl(fd, F_SETLK, &fl) == -1)
02177 #else
02178 if (flock(fd, LOCK_EX | LOCK_NB) == -1)
02179 #endif
02180 {
02181 llinfos << "Failed to lock file." << llendl;
02182 }
02183 }
02184 #endif
02185 if (gMarkerFile)
02186 {
02187 llinfos << "Marker file created." << llendl;
02188 }
02189 else
02190 {
02191 llinfos << "Failed to create marker file." << llendl;
02192 }
02193
02194 #if LL_WINDOWS
02195
02196 llinfos << "Removing SecondLife.dmp" << llendl;
02197 std::string dmp_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.dmp");
02198 LLFile::remove(dmp_filename.c_str());
02199 #endif
02200
02201
02202
02203 llinfos << "Removing message.log" << llendl;
02204 std::string message_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "message.log");
02205 LLFile::remove(message_filename.c_str());
02206
02207 llinfos << "Exiting init_marker_file()." << llendl;
02208 }
02209
02210 void init_crash_handler()
02211 {
02213
02214
02215
02216
02217
02218 catch_signals();
02219
02220
02221 gCrashCallback = viewer_crash_callback;
02222 }
02223
02224 void init_logging()
02225 {
02226
02227 std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
02228 "SecondLife.old");
02229 LLFile::remove(old_log_file.c_str());
02230
02231 #if LL_LINUX || LL_SOLARIS
02232
02233 std::string old_stack_file =
02234 gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");
02235 LLFile::remove(old_stack_file.c_str());
02236 #endif // LL_LINUX || LL_SOLARIS
02237
02238
02239 std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
02240 "SecondLife.log");
02241 LLFile::rename(log_file.c_str(), old_log_file.c_str());
02242
02243
02244
02245 LLError::logToFile(log_file);
02246 }
02247
02248 void write_system_info()
02249 {
02250 write_debug("SL Log: ");
02251 write_debug(LLError::logFileName());
02252 write_debug("\n");
02253
02254 std::string tmp_str = gSecondLife
02255 + llformat(" version %d.%d.%d build %d",
02256 LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH, LL_VIEWER_BUILD);
02257 write_debug(tmp_str.c_str());
02258 write_debug("\n");
02259 write_debug(gSysCPU.getCPUString());
02260 write_debug("\n");
02261
02262 tmp_str = llformat("RAM: %u KB\n", gSysMemory.getPhysicalMemoryKB());
02263 write_debug(tmp_str.c_str());
02264 write_debug("OS: ");
02265 write_debug(gSysOS.getOSString().c_str());
02266 write_debug("\n");
02267
02268
02269 llinfos << gSecondLife << " version "
02270 << LL_VERSION_MAJOR << "."
02271 << LL_VERSION_MINOR << "."
02272 << LL_VERSION_PATCH
02273 << llendl;
02274
02275
02276 time_t now;
02277 time(&now);
02278 char tbuffer[256];
02279 strftime(tbuffer, 256, "%Y-%m-%dT%H:%M:%S %Z", localtime(&now));
02280 llinfos << "Local time: " << tbuffer << llendl;
02281
02282
02283 llinfos << "CPU info:\n" << gSysCPU << llendl;
02284 llinfos << "Memory info:\n" << gSysMemory << llendl;
02285 llinfos << "OS info: " << gSysOS << llendl;
02286 }
02287
02288 #if LL_WINDOWS
02289 void disable_win_error_reporting()
02290 {
02291 const char win_xp_string[] = "Microsoft Windows XP";
02292 BOOL is_win_xp = ( gSysOS.getOSString().substr(0, strlen(win_xp_string) ) == win_xp_string );
02293 if( is_win_xp )
02294 {
02295
02296
02297 HINSTANCE fault_rep_dll_handle = LoadLibrary(L"faultrep.dll");
02298 if( fault_rep_dll_handle )
02299 {
02300 pfn_ADDEREXCLUDEDAPPLICATIONA pAddERExcludedApplicationA = (pfn_ADDEREXCLUDEDAPPLICATIONA) GetProcAddress(fault_rep_dll_handle, "AddERExcludedApplicationA");
02301 if( pAddERExcludedApplicationA )
02302 {
02303
02304
02305 const char* executable_name = gDirUtilp->getExecutableFilename().c_str();
02306
02307 if( 0 == pAddERExcludedApplicationA( executable_name ) )
02308 {
02309 U32 error_code = GetLastError();
02310 llinfos << "AddERExcludedApplication() failed with error code " << error_code << llendl;
02311 }
02312 else
02313 {
02314 llinfos << "AddERExcludedApplication() success for " << executable_name << llendl;
02315 }
02316 }
02317 FreeLibrary( fault_rep_dll_handle );
02318 }
02319 }
02320 }
02321 #endif // LL_WINDOWS
02322
02323
02324
02325 std::string get_serial_number()
02326 {
02327 char serial_md5[MD5HEX_STR_SIZE];
02328 serial_md5[0] = 0;
02329
02330 #if LL_WINDOWS
02331 DWORD serial = 0;
02332 DWORD flags = 0;
02333 BOOL success = GetVolumeInformation(
02334 L"C:\\",
02335 NULL,
02336 0,
02337 &serial,
02338 NULL,
02339 &flags,
02340 NULL,
02341 0);
02342 if (success)
02343 {
02344 LLMD5 md5;
02345 md5.update( (unsigned char*)&serial, sizeof(DWORD));
02346 md5.finalize();
02347 md5.hex_digest(serial_md5);
02348 }
02349 else
02350 {
02351 llwarns << "GetVolumeInformation failed" << llendl;
02352 }
02353 return serial_md5;
02354
02355 #elif LL_DARWIN
02356
02357 CFStringRef serialNumber = NULL;
02358 io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault,
02359 IOServiceMatching("IOPlatformExpertDevice"));
02360 if (platformExpert) {
02361 serialNumber = (CFStringRef) IORegistryEntryCreateCFProperty(platformExpert,
02362 CFSTR(kIOPlatformSerialNumberKey),
02363 kCFAllocatorDefault, 0);
02364 IOObjectRelease(platformExpert);
02365 }
02366
02367 if (serialNumber)
02368 {
02369 char buffer[MAX_STRING];
02370 if (CFStringGetCString(serialNumber, buffer, MAX_STRING, kCFStringEncodingASCII))
02371 {
02372 LLMD5 md5( (unsigned char*)buffer );
02373 md5.hex_digest(serial_md5);
02374 }
02375 CFRelease(serialNumber);
02376 }
02377
02378 return serial_md5;
02379
02380 #elif LL_LINUX || LL_SOLARIS
02381
02382 return serial_md5;
02383
02384 #endif
02385 }
02386
02387 #if LL_LINUX
02388 #define MAX_STACK_TRACE_DEPTH 40
02389
02390
02391 static inline BOOL do_basic_glibc_backtrace()
02392 {
02393 void *array[MAX_STACK_TRACE_DEPTH];
02394 size_t size;
02395 char **strings;
02396 size_t i;
02397 BOOL success = FALSE;
02398
02399 size = backtrace(array, MAX_STACK_TRACE_DEPTH);
02400 strings = backtrace_symbols(array, size);
02401
02402 std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");
02403 llinfos << "Opening stack trace file " << strace_filename << llendl;
02404 FILE* StraceFile = LLFile::fopen(strace_filename.c_str(), "w");
02405 if (!StraceFile)
02406 {
02407 llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl;
02408 StraceFile = stderr;
02409 }
02410
02411 if (size)
02412 {
02413 for (i = 0; i < size; i++)
02414 fputs((std::string(strings[i])+"\n").c_str(),
02415 StraceFile);
02416
02417 success = TRUE;
02418 }
02419
02420 if (StraceFile != stderr)
02421 fclose(StraceFile);
02422
02423 free (strings);
02424 return success;
02425 }
02426
02427 #if LL_ELFBIN
02428
02429
02430
02431 static inline BOOL do_elfio_glibc_backtrace()
02432 {
02433 void *array[MAX_STACK_TRACE_DEPTH];
02434 size_t btsize;
02435 char **strings;
02436 BOOL success = FALSE;
02437
02438 std::string appfilename = gDirUtilp->getExecutablePathAndName();
02439
02440 std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");
02441 llinfos << "Opening stack trace file " << strace_filename << llendl;
02442 FILE* StraceFile = LLFile::fopen(strace_filename.c_str(), "w");
02443 if (!StraceFile)
02444 {
02445 llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl;
02446 StraceFile = stderr;
02447 }
02448
02449
02450 btsize = backtrace(array, MAX_STACK_TRACE_DEPTH);
02451 strings = backtrace_symbols(array, btsize);
02452
02453
02454 IELFI* pReader;
02455 const IELFISection* pSec = NULL;
02456 IELFISymbolTable* pSymTbl = 0;
02457 if (ERR_ELFIO_NO_ERROR != ELFIO::GetInstance()->CreateELFI(&pReader) ||
02458 ERR_ELFIO_NO_ERROR != pReader->Load(appfilename.c_str()) ||
02459
02460 NULL == (pSec = pReader->GetSection( ".symtab" )) ||
02461 ERR_ELFIO_NO_ERROR != pReader->CreateSectionReader(IELFI::ELFI_SYMBOL, pSec, (void**)&pSymTbl) )
02462 {
02463
02464 llinfos << "Could not initialize ELF symbol reading - doing basic backtrace." << llendl;
02465 if (StraceFile != stderr)
02466 fclose(StraceFile);
02467
02468
02469
02470
02471 return do_basic_glibc_backtrace();
02472 }
02473
02474
02475 std::string name;
02476 Elf32_Addr value;
02477 Elf32_Word ssize;
02478 unsigned char bind;
02479 unsigned char type;
02480 Elf32_Half section;
02481 int nSymNo = pSymTbl->GetSymbolNum();
02482 size_t btpos;
02483 for (btpos = 0; btpos < btsize; ++btpos)
02484 {
02485 fprintf(StraceFile, "%d:\t", btpos);
02486 int symidx;
02487 for (symidx = 0; symidx < nSymNo; ++symidx)
02488 {
02489 if (ERR_ELFIO_NO_ERROR ==
02490 pSymTbl->GetSymbol(symidx, name, value, ssize,
02491 bind, type, section))
02492 {
02493
02494 if (uintptr_t(array[btpos]) >= value &&
02495 uintptr_t(array[btpos]) < value+ssize)
02496 {
02497 char *demangled_str = NULL;
02498 int demangle_result = 1;
02499 demangled_str =
02500 abi::__cxa_demangle
02501 (name.c_str(), NULL, NULL,
02502 &demangle_result);
02503 if (0 == demangle_result &&
02504 NULL != demangled_str) {
02505 fprintf(StraceFile,
02506 "ELF(%s", demangled_str);
02507 free(demangled_str);
02508 }
02509 else
02510 {
02511 fprintf(StraceFile,
02512 "ELF(%s", name.c_str());
02513 }
02514
02515 fprintf(StraceFile,
02516 "+0x%lx) [%p]\n",
02517 uintptr_t(array[btpos]) -
02518 value,
02519 array[btpos]);
02520 goto got_sym;
02521 }
02522 }
02523 }
02524
02525
02526
02527 fprintf(StraceFile, "%s\n", strings[btpos]);
02528 got_sym:;
02529 }
02530
02531 if (StraceFile != stderr)
02532 fclose(StraceFile);
02533
02534 pSymTbl->Release();
02535 pSec->Release();
02536 pReader->Release();
02537
02538 free(strings);
02539
02540 llinfos << "Finished generating stack trace." << llendl;
02541
02542 success = TRUE;
02543 return success;
02544 }
02545 #endif // LL_ELFBIN
02546 #endif // LL_LINUX
02547
02548
02549 static inline bool being_debugged()
02550 {
02551 static enum {unknown, no, yes} debugged = unknown;
02552
02553 if (debugged == unknown)
02554 {
02555 #if LL_LINUX
02556 pid_t ppid = getppid();
02557 char *name;
02558 int ret;
02559
02560 ret = asprintf(&name, "/proc/%d/exe", ppid);
02561 if (ret != -1)
02562 {
02563 char buf[1024];
02564 ssize_t n;
02565
02566 n = readlink(name, buf, sizeof(buf) - 1);
02567 if (n != -1)
02568 {
02569 char *base = strrchr(buf, '/');
02570 buf[n + 1] = '\0';
02571 if (base == NULL)
02572 {
02573 base = buf;
02574 } else {
02575 base += 1;
02576 }
02577
02578 if (strcmp(base, "gdb") == 0)
02579 {
02580 debugged = yes;
02581 }
02582 }
02583 free(name);
02584 }
02585 #endif // LL_LINUX
02586 }
02587
02588 return debugged == yes;
02589 }
02590
02591 #ifdef LL_SOLARIS
02592 static inline BOOL do_basic_glibc_backtrace()
02593 {
02594 BOOL success = FALSE;
02595
02596 std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");
02597 llinfos << "Opening stack trace file " << strace_filename << llendl;
02598 FILE* StraceFile = LLFile::fopen(strace_filename.c_str(), "w");
02599 if (!StraceFile)
02600 {
02601 llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl;
02602 StraceFile = stderr;
02603 }
02604
02605 printstack(fileno(StraceFile));
02606
02607 if (StraceFile != stderr)
02608 fclose(StraceFile);
02609
02610 return success;
02611 }
02612 #endif // LL_SOLARIS
02613
02614 void viewer_crash_callback()
02615 {
02616
02617 if (being_debugged())
02618 {
02619 abort();
02620 }
02621
02622
02623
02624 if (gReportedCrash)
02625 {
02626 return;
02627 }
02628 gReportedCrash = TRUE;
02629
02630 BOOL do_crash_report = FALSE;
02631
02632 do_crash_report = TRUE;
02633
02634 write_debug("Viewer exe: ");
02635 write_debug(gDirUtilp->getExecutablePathAndName().c_str());
02636 write_debug("\n");
02637 write_debug("Cur path: ");
02638 write_debug(gDirUtilp->getCurPath().c_str());
02639 write_debug("\n\n");
02640
02641 if (gMessageSystem && gDirUtilp)
02642 {
02643 std::string filename;
02644 filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "stats.log");
02645 llofstream file(filename.c_str(), llofstream::binary);
02646 if(file.good())
02647 {
02648 gMessageSystem->summarizeLogs(file);
02649 }
02650 }
02651
02652 if (gMessageSystem)
02653 {
02654 write_debug(gMessageSystem->getCircuitInfoString());
02655 gMessageSystem->stopLogging();
02656 }
02657 write_debug("\n");
02658 if (gWorldp)
02659 {
02660 write_debug(gWorldp->getInfoString());
02661 }
02662
02663
02664 close_debug();
02665 LLError::logToFile("");
02666
02667
02668
02669 remove_marker_file();
02670
02671 #if LL_WINDOWS
02672
02673 std::string exe_path = gDirUtilp->getAppRODataDir();
02674 exe_path += gDirUtilp->getDirDelimiter();
02675 exe_path += "win_crash_logger.exe";
02676
02677 std::string arg_string = "-user ";
02678 arg_string += gUserServerName;
02679
02680 switch(gCrashBehavior)
02681 {
02682 case CRASH_BEHAVIOR_ASK:
02683 default:
02684 arg_string += " -dialog ";
02685 _spawnl(_P_NOWAIT, exe_path.c_str(), exe_path.c_str(), arg_string.c_str(), NULL);
02686 break;
02687
02688 case CRASH_BEHAVIOR_ALWAYS_SEND:
02689 _spawnl(_P_NOWAIT, exe_path.c_str(), exe_path.c_str(), arg_string.c_str(), NULL);
02690 break;
02691
02692 case CRASH_BEHAVIOR_NEVER_SEND:
02693 break;
02694 }
02695
02696 #elif LL_DARWIN
02697
02698 LLString command_str;
02699 command_str = "crashreporter.app/Contents/MacOS/crashreporter ";
02700 command_str += "-user ";
02701 command_str += gUserServerName;
02702 command_str += " &";
02703 system(command_str.c_str());
02704
02705
02706
02707 exit(1);
02708 #elif LL_LINUX || LL_SOLARIS
02709
02710
02711 if (CRASH_BEHAVIOR_NEVER_SEND != gCrashBehavior)
02712 {
02713
02714 # if LL_ELFBIN
02715 do_elfio_glibc_backtrace();
02716 # else
02717 do_basic_glibc_backtrace();
02718 # endif // LL_ELFBIN
02719
02720 char* ask_dialog = "-dialog";
02721 if (CRASH_BEHAVIOR_ASK != gCrashBehavior)
02722 ask_dialog = "";
02723 std::string cmd =gDirUtilp->getAppRODataDir();
02724 cmd += gDirUtilp->getDirDelimiter();
02725 cmd += "linux-crash-logger.bin";
02726 char* const cmdargv[] =
02727 {(char*)cmd.c_str(),
02728 ask_dialog,
02729 (char*)"-user",
02730 (char*)gUserServerName,
02731 (char*)"-name",
02732 (char*)gSecondLife.c_str(),
02733 NULL};
02734 fflush(NULL);
02735 pid_t pid = fork();
02736 if (pid == 0)
02737 {
02738 execv(cmd.c_str(), cmdargv);
02739 llwarns << "execv failure when trying to start " << cmd << llendl;
02740 _exit(1);
02741 } else {
02742 if (pid > 0)
02743 {
02744
02745
02746
02749 } else {
02750 llwarns << "fork failure." << llendl;
02751 }
02752 }
02753 }
02754
02755
02756 exit(1);
02757 #else
02758 #error do something with your platform.
02759 #endif // LL_DARWIN
02760
02761 return;
02762 }
02763
02764
02765
02766 BOOL init_cache()
02767 {
02768 gPurgeCache = FALSE;
02769
02770 if (gSavedSettings.getBOOL("PurgeCacheOnStartup") ||
02771 gSavedSettings.getBOOL("PurgeCacheOnNextStartup"))
02772 {
02773 gSavedSettings.setBOOL("PurgeCacheOnNextStartup", FALSE);
02774 gPurgeCache = TRUE;
02775 }
02776
02777 else
02778 {
02779 static const S32 cache_version = 5;
02780 if (gSavedSettings.getS32("LocalCacheVersion") != cache_version)
02781 {
02782 gPurgeCache = TRUE;
02783 gSavedSettings.setS32("LocalCacheVersion", cache_version);
02784 }
02785 }
02786
02787
02788 LLString cache_location = gSavedSettings.getString("CacheLocation");
02789 LLString new_cache_location = gSavedSettings.getString("NewCacheLocation");
02790 if (new_cache_location != cache_location)
02791 {
02792 gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation"));
02793 purge_cache();
02794 gSavedSettings.setString("CacheLocation", new_cache_location);
02795 }
02796
02797 if (!gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation")))
02798 {
02799 llwarns << "Unable to set cache location" << llendl;
02800 gSavedSettings.setString("CacheLocation", "");
02801 }
02802
02803 if (gPurgeCache)
02804 {
02805 LLSplashScreen::update("Clearing cache...");
02806 purge_cache();
02807 }
02808
02809 LLSplashScreen::update("Initializing Texture Cache...");
02810
02811
02812
02813 BOOL read_only = gSecondInstance ? TRUE : FALSE;
02814 const S32 MB = 1024*1024;
02815 S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB;
02816 const S64 MAX_CACHE_SIZE = 1024*MB;
02817 cache_size = llmin(cache_size, MAX_CACHE_SIZE);
02818 S64 texture_cache_size = ((cache_size * 8)/10);
02819 S64 extra = gTextureCache->initCache(LL_PATH_CACHE, texture_cache_size, read_only);
02820 texture_cache_size -= extra;
02821
02822 LLSplashScreen::update("Initializing VFS...");
02823
02824
02825 S64 vfs_size = cache_size - texture_cache_size;
02826 const S64 MAX_VFS_SIZE = 1024 * MB;
02827 vfs_size = llmin(vfs_size, MAX_VFS_SIZE);
02828 vfs_size = (vfs_size / MB) * MB;
02829 U32 vfs_size_u32 = (U32)vfs_size;
02830 U32 old_vfs_size = gSavedSettings.getU32("VFSOldSize") * MB;
02831 bool resize_vfs = (vfs_size_u32 != old_vfs_size);
02832 if (resize_vfs)
02833 {
02834 gSavedSettings.setU32("VFSOldSize", vfs_size_u32/MB);
02835 }
02836 llinfos << "VFS CACHE SIZE: " << vfs_size/(1024*1024) << " MB" << llendl;
02837
02838
02839
02840 srand(time(NULL));
02841 U32 old_salt = gSavedSettings.getU32("VFSSalt");
02842 U32 new_salt;
02843 char old_vfs_data_file[LL_MAX_PATH];
02844 char old_vfs_index_file[LL_MAX_PATH];
02845 char new_vfs_data_file[LL_MAX_PATH];
02846 char new_vfs_index_file[LL_MAX_PATH];
02847 char static_vfs_index_file[LL_MAX_PATH];
02848 char static_vfs_data_file[LL_MAX_PATH];
02849
02850 if (gMultipleViewersOK)
02851 {
02852
02853 new_salt = old_salt;
02854 }
02855 else
02856 {
02857 do
02858 {
02859 new_salt = rand();
02860 } while( new_salt == old_salt );
02861 }
02862
02863 snprintf(old_vfs_data_file, LL_MAX_PATH, "%s%u",
02864 gDirUtilp->getExpandedFilename(LL_PATH_CACHE,VFS_DATA_FILE_BASE).c_str(),
02865 old_salt);
02866
02867
02868 llstat s;
02869 S32 stat_result = LLFile::stat(old_vfs_data_file, &s);
02870 if (stat_result)
02871 {
02872
02873 std::string mask;
02874 mask = gDirUtilp->getDirDelimiter();
02875 mask += VFS_DATA_FILE_BASE;
02876 mask += "*";
02877
02878 std::string dir;
02879 dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"");
02880
02881 std::string found_file;
02882 if (gDirUtilp->getNextFileInDir(dir, mask, found_file, FALSE))
02883 {
02884 snprintf(old_vfs_data_file, LL_MAX_PATH, "%s%s%s", dir.c_str(), gDirUtilp->getDirDelimiter().c_str(), found_file.c_str());
02885
02886 S32 start_pos;
02887 S32 length = strlen(found_file.c_str());
02888 for (start_pos = length - 1; start_pos >= 0; start_pos--)
02889 {
02890 if (found_file[start_pos] == '.')
02891 {
02892 start_pos++;
02893 break;
02894 }
02895 }
02896 if (start_pos > 0)
02897 {
02898 sscanf(found_file.c_str() + start_pos, "%d", &old_salt);
02899 }
02900 llinfos << "Default vfs data file not present, found " << old_vfs_data_file << llendl;
02901 llinfos << "Old salt: " << old_salt << llendl;
02902 }
02903 }
02904
02905 snprintf(old_vfs_index_file, LL_MAX_PATH, "%s%u",
02906 gDirUtilp->getExpandedFilename(LL_PATH_CACHE,VFS_INDEX_FILE_BASE).c_str(),
02907 old_salt);
02908
02909 stat_result = LLFile::stat(old_vfs_index_file, &s);
02910 if (stat_result)
02911 {
02912
02913 llwarns << "Bad or missing vfx index file " << old_vfs_index_file << llendl;
02914 llwarns << "Removing old vfs data file " << old_vfs_data_file << llendl;
02915 LLFile::remove(old_vfs_data_file);
02916 LLFile::remove(old_vfs_index_file);
02917
02918
02919 std::string dir;
02920 dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"");
02921
02922 std::string mask;
02923 mask = gDirUtilp->getDirDelimiter();
02924 mask += VFS_DATA_FILE_BASE;
02925 mask += "*";
02926
02927 gDirUtilp->deleteFilesInDir(dir, mask);
02928
02929 mask = gDirUtilp->getDirDelimiter();
02930 mask += VFS_INDEX_FILE_BASE;
02931 mask += "*";
02932
02933 gDirUtilp->deleteFilesInDir(dir, mask);
02934 }
02935
02936 snprintf(new_vfs_data_file, LL_MAX_PATH, "%s%u",
02937 gDirUtilp->getExpandedFilename(LL_PATH_CACHE,VFS_DATA_FILE_BASE).c_str(),
02938 new_salt);
02939
02940 snprintf(new_vfs_index_file, LL_MAX_PATH, "%s%u", gDirUtilp->getExpandedFilename(LL_PATH_CACHE, VFS_INDEX_FILE_BASE).c_str(),
02941 new_salt);
02942
02943
02944 strncpy(static_vfs_data_file, gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"static_data.db2").c_str(), LL_MAX_PATH -1);
02945 static_vfs_data_file[LL_MAX_PATH -1] = '\0';
02946 strncpy(static_vfs_index_file, gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"static_index.db2").c_str(), LL_MAX_PATH -1);
02947 static_vfs_index_file[LL_MAX_PATH -1] = '\0';
02948
02949 if (resize_vfs)
02950 {
02951 llinfos << "Removing old vfs and re-sizing" << llendl;
02952
02953 LLFile::remove(old_vfs_data_file);
02954 LLFile::remove(old_vfs_index_file);
02955 }
02956 else if (old_salt != new_salt)
02957 {
02958
02959 llinfos << "Renaming " << old_vfs_data_file << " to " << new_vfs_data_file << llendl;
02960 llinfos << "Renaming " << old_vfs_index_file << " to " << new_vfs_index_file << llendl;
02961 LLFile::rename(old_vfs_data_file, new_vfs_data_file);
02962 LLFile::rename(old_vfs_index_file, new_vfs_index_file);
02963 }
02964
02965
02966 gSavedSettings.setU32("VFSSalt", new_salt);
02967
02968
02969 gVFS = new LLVFS(new_vfs_index_file, new_vfs_data_file, FALSE, vfs_size_u32, FALSE);
02970 if( VFSVALID_BAD_CORRUPT == gVFS->getValidState() )
02971 {
02972
02973
02974 llwarns << "VFS corrupt, deleted. Making new VFS." << llendl;
02975 delete gVFS;
02976 gVFS = new LLVFS(new_vfs_index_file, new_vfs_data_file, FALSE, vfs_size_u32, FALSE);
02977 }
02978
02979 gStaticVFS = new LLVFS(static_vfs_index_file, static_vfs_data_file, TRUE, 0, FALSE);
02980
02981 BOOL success = gVFS->isValid() && gStaticVFS->isValid();
02982 if( !success )
02983 {
02984 return FALSE;
02985 }
02986 else
02987 {
02988 LLVFile::initClass();
02989 return TRUE;
02990 }
02991 }
02992
02993 #if LL_DARWIN
02994
02995 OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
02996 {
02997 OSErr result = noErr;
02998 DescType actualType;
02999 char buffer[1024];
03000 Size size;
03001
03002 result = AEGetParamPtr (
03003 messagein,
03004 keyDirectObject,
03005 typeCString,
03006 &actualType,
03007 (Ptr)buffer,
03008 sizeof(buffer),
03009 &size);
03010
03011 if(result == noErr)
03012 {
03013 std::string url = buffer;
03014 LLURLDispatcher::dispatch(url);
03015 }
03016
03017 return(result);
03018 }
03019
03020 OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
03021 {
03022 OSErr result = noErr;
03023
03024 app_user_quit();
03025
03026 return(result);
03027 }
03028
03029 OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata)
03030 {
03031 OSStatus result = eventNotHandledErr;
03032 OSStatus err;
03033 UInt32 evtClass = GetEventClass(event);
03034 UInt32 evtKind = GetEventKind(event);
03035 WindowRef window = (WindowRef)userdata;
03036
03037 if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess))
03038 {
03039 HICommand cmd;
03040 err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd);
03041
03042 if(err == noErr)
03043 {
03044 switch(cmd.commandID)
03045 {
03046 case kHICommandOK:
03047 QuitAppModalLoopForWindow(window);
03048 result = noErr;
03049 break;
03050
03051 case kHICommandCancel:
03052 QuitAppModalLoopForWindow(window);
03053 result = userCanceledErr;
03054 break;
03055 }
03056 }
03057 }
03058
03059 return(result);
03060 }
03061
03062 OSStatus DisplayReleaseNotes(void)
03063 {
03064 OSStatus err;
03065 IBNibRef nib = NULL;
03066 WindowRef window = NULL;
03067
03068 err = CreateNibReference(CFSTR("SecondLife"), &nib);
03069
03070 if(err == noErr)
03071 {
03072 CreateWindowFromNib(nib, CFSTR("Release Notes"), &window);
03073 }
03074
03075 if(err == noErr)
03076 {
03077
03078 HIViewRef textView;
03079 ControlID id;
03080
03081 id.signature = 'text';
03082 id.id = 0;
03083
03084 std::string releaseNotesText;
03085 _read_file_into_string(releaseNotesText, "releasenotes.txt");
03086
03087 err = HIViewFindByID(HIViewGetRoot(window), id, &textView);
03088
03089 if(err == noErr)
03090 {
03091
03092 CFStringRef str = CFStringCreateWithBytes(
03093 NULL,
03094 (const UInt8*)releaseNotesText.c_str(),
03095 releaseNotesText.size(),
03096 kCFStringEncodingWindowsLatin1,
03097 FALSE);
03098
03099 if(str != NULL)
03100 {
03101 int size = CFStringGetLength(str);
03102
03103 if(size > 0)
03104 {
03105 UniChar *chars = new UniChar[size + 1];
03106 CFStringGetCharacters(str, CFRangeMake(0, size), chars);
03107
03108 err = TXNSetData(HITextViewGetTXNObject(textView), kTXNUnicodeTextData, chars, size * sizeof(UniChar), kTXNStartOffset, kTXNStartOffset);
03109
03110 delete[] chars;
03111 }
03112
03113 CFRelease(str);
03114 }
03115 else
03116 {
03117
03118 err = TXNSetData(HITextViewGetTXNObject(textView), kTXNTextData, releaseNotesText.c_str(), releaseNotesText.size(), kTXNStartOffset, kTXNStartOffset);
03119 }
03120 }
03121
03122
03123 if(err == noErr)
03124 {
03125 err = TXNSetSelection(HITextViewGetTXNObject(textView), kTXNStartOffset, kTXNStartOffset);
03126 }
03127
03128 if(err == noErr)
03129 {
03130
03131 TXNShowSelection(HITextViewGetTXNObject(textView), false);
03132 }
03133 }
03134
03135 if(err == noErr)
03136 {
03137 ShowWindow(window);
03138 }
03139
03140 if(err == noErr)
03141 {
03142
03143 EventHandlerRef handler = NULL;
03144 EventTypeSpec handlerEvents[] =
03145 {
03146 { kEventClassCommand, kEventCommandProcess }
03147 };
03148
03149 InstallWindowEventHandler(
03150 window,
03151 NewEventHandlerUPP(simpleDialogHandler),
03152 GetEventTypeCount (handlerEvents),
03153 handlerEvents,
03154 (void*)window,
03155 &handler);
03156 }
03157
03158 if(err == noErr)
03159 {
03160 RunAppModalLoopForWindow(window);
03161 }
03162
03163 if(window != NULL)
03164 {
03165 DisposeWindow(window);
03166 }
03167
03168 if(nib != NULL)
03169 {
03170 DisposeNibReference(nib);
03171 }
03172
03173 return(err);
03174 }
03175
03176 void init_apple_menu(const char* product)
03177 {
03178
03179 {
03180 OSStatus err;
03181 IBNibRef nib = NULL;
03182
03183 err = CreateNibReference(CFSTR("SecondLife"), &nib);
03184
03185 if(err == noErr)
03186 {
03187
03188 SetMenuBarFromNib(nib, CFSTR("MenuBar"));
03189 }
03190
03191 if(nib != NULL)
03192 {
03193 DisposeNibReference(nib);
03194 }
03195 }
03196
03197
03198
03199 if(AEInstallEventHandler('GURL', 'GURL', NewAEEventHandlerUPP(AEGURLHandler),0, false) != noErr)
03200 {
03201
03202 llinfos << "Couldn't install 'GURL' AppleEvent handler. Continuing..." << llendl;
03203 }
03204
03205
03206 if(AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(AEQuitHandler),0, false) != noErr)
03207 {
03208
03209 llinfos << "Couldn't install Quit AppleEvent handler. Continuing..." << llendl;
03210 }
03211 }
03212 #endif
03213
03214 void user_logout()
03215 {
03216 if (!gDoneLogout)
03217 {
03218 LLMessageSystem* msg = gMessageSystem;
03219 if (msg)
03220 {
03221 gSavedSettings.setBOOL("LoggedIn", FALSE);
03222 }
03223 gDoneLogout = TRUE;
03224 }
03225 }
03226
03227
03228
03229
03230
03231 void save_final_snapshot(void*)
03232 {
03233 if (!gHaveSavedSnapshot && !gNoRender)
03234 {
03235 gSavedSettings.setVector3d("FocusPosOnLogout", gAgent.calcFocusPositionTargetGlobal());
03236 gSavedSettings.setVector3d("CameraPosOnLogout", gAgent.calcCameraPositionTargetGlobal());
03237 gViewerWindow->setCursor(UI_CURSOR_WAIT);
03238 gAgent.changeCameraToThirdPerson( FALSE );
03239 gSavedSettings.setBOOL("ShowParcelOwners", FALSE);
03240 idle();
03241
03242 LLString snap_filename = gDirUtilp->getLindenUserDir();
03243 snap_filename += gDirUtilp->getDirDelimiter();
03244 snap_filename += SCREEN_LAST_FILENAME;
03245 gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidth(), gViewerWindow->getWindowHeight(), FALSE, TRUE);
03246 gHaveSavedSnapshot = TRUE;
03247 }
03248 }
03249
03250
03251
03252 void app_force_quit(const char* launch_file_on_quit)
03253 {
03254
03255
03256
03257 if (launch_file_on_quit)
03258 {
03259 gLaunchFileOnQuit.assign( (const char*)launch_file_on_quit );
03260 }
03261
03262 gQuit = TRUE;
03263 }
03264
03265 static void finish_quit(S32 option, void *userdata)
03266 {
03267 if (option == 0)
03268 {
03269 app_request_quit();
03270 }
03271 }
03272
03273 void app_user_quit()
03274 {
03275 gViewerWindow->alertXml("ConfirmQuit", finish_quit, NULL);
03276 }
03277
03278
03279
03280
03281 void app_request_quit()
03282 {
03283 llinfos << "app_request_quit" << llendl;
03284
03285 LLViewerRegion* region = gAgent.getRegion();
03286
03287 if( (LLStartUp::getStartupState() < STATE_STARTED) || !region )
03288 {
03289
03290 app_force_quit(NULL);
03291 return;
03292 }
03293
03294 if (gHUDManager)
03295 {
03296 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
03297 effectp->setPositionGlobal(gAgent.getPositionGlobal());
03298 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
03299 gHUDManager->sendEffects();
03300 }
03301
03302
03303
03304 if (gFloaterView)
03305 {
03306
03307 gFloaterView->closeAllChildren(true);
03308 }
03309
03310 send_stats();
03311
03312 gLogoutTimer.reset();
03313 gQuitRequested = TRUE;
03314 }
03315
03316
03317
03318
03319 void app_abort_quit()
03320 {
03321 llinfos << "app_abort_quit()" << llendl;
03322 gQuitRequested = FALSE;
03323 }
03324
03325 void idle_shutdown()
03326 {
03327
03328 if (LLModalDialog::activeCount() > 0)
03329 {
03330 return;
03331 }
03332
03333
03334 if(gIMMgr)
03335 {
03336 gIMMgr->disconnectAllSessions();
03337 }
03338
03339
03340 if (gFloaterView
03341 && !gFloaterView->allChildrenClosed())
03342 {
03343 return;
03344 }
03345
03346 static bool saved_snapshot = false;
03347 if (!saved_snapshot)
03348 {
03349 saved_snapshot = true;
03350 save_final_snapshot(NULL);
03351 return;
03352 }
03353
03354 const F32 SHUTDOWN_UPLOAD_SAVE_TIME = 5.f;
03355
03356 S32 pending_uploads = gAssetStorage->getNumPendingUploads();
03357 if (pending_uploads > 0
03358 && gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME
03359 && !gLogoutRequestSent)
03360 {
03361 static S32 total_uploads = 0;
03362
03363 total_uploads = llmax(total_uploads, pending_uploads);
03364 gViewerWindow->setShowProgress(TRUE);
03365 S32 finished_uploads = total_uploads - pending_uploads;
03366 F32 percent = 100.f * finished_uploads / total_uploads;
03367 gViewerWindow->setProgressPercent(percent);
03368 char buffer[MAX_STRING];
03369 snprintf(buffer, MAX_STRING, "Saving final data...");
03370 gViewerWindow->setProgressString(buffer);
03371 return;
03372 }
03373
03374
03375 if( !gLogoutRequestSent )
03376 {
03377 send_logout_request();
03378
03379
03380 gViewerWindow->setShowProgress(TRUE);
03381 gViewerWindow->setProgressPercent(100.f);
03382 gViewerWindow->setProgressString("Logging out...");
03383 return;
03384 }
03385
03386
03387 if( gLogoutRequestSent
03388 && gLogoutTimer.getElapsedTimeF32() > gLogoutMaxTime )
03389 {
03390 app_force_quit(NULL);
03391 return;
03392 }
03393 }
03394
03395
03396 U32 gTotalLandIn = 0, gTotalLandOut = 0;
03397 U32 gTotalWaterIn = 0, gTotalWaterOut = 0;
03398
03399 F32 gAveLandCompression = 0.f, gAveWaterCompression = 0.f;
03400 F32 gBestLandCompression = 1.f, gBestWaterCompression = 1.f;
03401 F32 gWorstLandCompression = 0.f, gWorstWaterCompression = 0.f;
03402
03403 F32 gFPSClamped = 10.f;
03404 F32 gFrameDTClamped = 0.f;
03405 F32 gFrameDT = 0.f;
03406
03407
03408 U32 gPacketsIn = 0;
03409
03410 U32 gTotalWorldBytes = 0, gTotalObjectBytes = 0, gTotalTextureBytes = 0, gSimPingCount = 0;
03411 U32 gObjectBits = 0;
03412 F32 gAvgSimPing = 0.f;
03413
03414
03415 extern U32 gVisCompared;
03416 extern U32 gVisTested;
03417
03418
03419 void update_statistics(U32 frame_count)
03420 {
03421 gTotalWorldBytes += gVLManager.getTotalBytes();
03422 gTotalObjectBytes += gObjectBits / 8;
03423 gTotalTextureBytes += LLViewerImageList::sTextureBits / 8;
03424
03425
03426 if (gFrameIntervalSeconds > 0.f)
03427 {
03428 if (gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK)
03429 {
03430 gViewerStats->incStat(LLViewerStats::ST_MOUSELOOK_SECONDS, gFrameIntervalSeconds);
03431 }
03432 else if (gAgent.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR)
03433 {
03434 gViewerStats->incStat(LLViewerStats::ST_AVATAR_EDIT_SECONDS, gFrameIntervalSeconds);
03435 }
03436 else if (gFloaterTools && gFloaterTools->getVisible())
03437 {
03438 gViewerStats->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds);
03439 }
03440 }
03441 gViewerStats->setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable"));
03442 gViewerStats->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gSavedSettings.getS32("RenderLightingDetail"));
03443 gViewerStats->setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip"));
03444 gViewerStats->setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles"));
03445 #if 0 // 1.9.2
03446 gViewerStats->setStat(LLViewerStats::ST_SHADER_OBJECTS, (F64)gSavedSettings.getS32("VertexShaderLevelObject"));
03447 gViewerStats->setStat(LLViewerStats::ST_SHADER_AVATAR, (F64)gSavedSettings.getBOOL("VertexShaderLevelAvatar"));
03448 gViewerStats->setStat(LLViewerStats::ST_SHADER_ENVIRONMENT, (F64)gSavedSettings.getBOOL("VertexShaderLevelEnvironment"));
03449 #endif
03450 gViewerStats->setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_FRAME));
03451 F64 idle_secs = gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_IDLE);
03452 F64 network_secs = gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_NETWORK);
03453 gViewerStats->setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs);
03454 gViewerStats->setStat(LLViewerStats::ST_NETWORK_SECS, network_secs);
03455 gViewerStats->setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_IMAGE_UPDATE));
03456 gViewerStats->setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_REBUILD));
03457 gViewerStats->setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_RENDER_GEOMETRY));
03458
03459 LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
03460 if (cdp)
03461 {
03462 gViewerStats->mSimPingStat.addValue(cdp->getPingDelay());
03463 gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1);
03464 gSimPingCount++;
03465 }
03466 else
03467 {
03468 gViewerStats->mSimPingStat.addValue(10000);
03469 }
03470
03471 if (gFocusMgr.getAppHasFocus())
03472 {
03473 gViewerStats->mFPSStat.addValue(1);
03474 }
03475 F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits());
03476 gViewerStats->mLayersKBitStat.addValue(layer_bits/1024.f);
03477 gViewerStats->mObjectKBitStat.addValue(gObjectBits/1024.f);
03478 gViewerStats->mTextureKBitStat.addValue(LLViewerImageList::sTextureBits/1024.f);
03479 gViewerStats->mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending());
03480 gViewerStats->mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f);
03481 gTransferManager.resetTransferBitsIn(LLTCT_ASSET);
03482
03483 static S32 tex_bits_idle_count = 0;
03484 if (LLViewerImageList::sTextureBits == 0)
03485 {
03486 if (++tex_bits_idle_count >= 30)
03487 gDebugTimers[0].pause();
03488 }
03489 else
03490 {
03491 tex_bits_idle_count = 0;
03492 gDebugTimers[0].unpause();
03493 }
03494
03495 gViewerStats->mTexturePacketsStat.addValue(LLViewerImageList::sTexturePackets);
03496
03497 gViewerStats->mUserserverPingStat.addValue(0);
03498
03499
03500 #if LL_LIBXUL_ENABLED
03501 {
03502 BOOL result = gViewerHtmlHelp.getFloaterOpened();
03503 gViewerStats->setStat(LLViewerStats::ST_LIBXUL_WIDGET_USED, (F64)result);
03504 }
03505 #endif
03506
03507 {
03508 static F32 visible_avatar_frames = 0.f;
03509 static F32 avg_visible_avatars = 0;
03510 F32 visible_avatars = (F32)LLVOAvatar::sNumVisibleAvatars;
03511 if (visible_avatars > 0.f)
03512 {
03513 visible_avatar_frames = 1.f;
03514 avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames;
03515 }
03516 gViewerStats->setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars);
03517 }
03518 gWorldp->updateNetStats();
03519 gWorldp->requestCacheMisses();
03520
03521
03522 gVLManager.resetBitCounts();
03523 gObjectBits = 0;
03524
03525
03526 LLViewerImageList::sTextureBits = 0;
03527 LLViewerImageList::sTexturePackets = 0;
03528
03529 #if LL_WINDOWS && LL_LCD_COMPILE
03530 bool LCDenabled = gLcdScreen->Enabled();
03531 gViewerStats->setStat(LLViewerStats::ST_LOGITECH_LCD, LCDenabled);
03532 #else
03533 gViewerStats->setStat(LLViewerStats::ST_LOGITECH_LCD, false);
03534 #endif
03535
03536 }
03537
03538
03539
03540
03541
03542 #define TIME_THROTTLE_MESSAGES
03543
03544 #ifdef TIME_THROTTLE_MESSAGES
03545 #define CHECK_MESSAGES_DEFAULT_MAX_TIME .020f // 50 ms = 50 fps (just for messages!)
03546 static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
03547 #endif
03548
03549 void idle_network()
03550 {
03551 gObjectList.mNumNewObjects = 0;
03552 S32 total_decoded = 0;
03553
03554 if (!gSavedSettings.getBOOL("SpeedTest"))
03555 {
03556 LLFastTimer t(LLFastTimer::FTM_IDLE_NETWORK);
03557
03558
03559 gCacheName->processPending();
03560
03561 LLTimer check_message_timer;
03562
03563 stop_glerror();
03564 const S64 frame_count = gFrameCount;
03565 F32 total_time = 0.0f;
03566 while (gMessageSystem->checkAllMessages(frame_count, gServicePump))
03567 {
03568 if (gDoDisconnect)
03569 {
03570
03571
03572
03573 break;
03574 }
03575 stop_glerror();
03576
03577 total_decoded++;
03578 gPacketsIn++;
03579
03580 if (total_decoded > MESSAGE_MAX_PER_FRAME)
03581 {
03582 break;
03583 }
03584
03585 #ifdef TIME_THROTTLE_MESSAGES
03586
03587
03588
03589
03590 total_time = check_message_timer.getElapsedTimeF32();
03591 if (total_time >= CheckMessagesMaxTime)
03592 break;
03593 #endif
03594 }
03595
03596 gMessageSystem->processAcks();
03597
03598 #ifdef TIME_THROTTLE_MESSAGES
03599 if (total_time >= CheckMessagesMaxTime)
03600 {
03601
03602 CheckMessagesMaxTime *= 1.035f;
03603 }
03604 else
03605 {
03606
03607 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
03608 }
03609 #endif
03610
03611
03612
03613
03614 gAgent.resetControlFlags();
03615 stop_glerror();
03616
03617
03618
03619 S32 remaining_possible_decodes = MESSAGE_MAX_PER_FRAME - total_decoded;
03620
03621 if( remaining_possible_decodes <= 0 )
03622 {
03623 llinfos << "Maxed out number of messages per frame at " << MESSAGE_MAX_PER_FRAME << llendl;
03624 }
03625
03626 if (gPrintMessagesThisFrame)
03627 {
03628 llinfos << "Decoded " << total_decoded << " msgs this frame!" << llendl;
03629 gPrintMessagesThisFrame = FALSE;
03630 }
03631 }
03632
03633 gObjectList.mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects);
03634
03635
03636 gXferManager->retransmitUnackedPackets();
03637 gAssetStorage->checkForTimeouts();
03638
03639 gViewerThrottle.updateDynamicThrottle();
03640 }
03641
03642 void idle_afk_check()
03643 {
03644
03645 if (gAllowIdleAFK && (gAwayTriggerTimer.getElapsedTimeF32() > gAFKTimeout))
03646 {
03647 gAgent.setAFK();
03648 }
03649 }
03650 void request_initial_instant_messages()
03651 {
03652 static BOOL requested = FALSE;
03653 if (!requested
03654 && gMuteListp
03655 && gMuteListp->isLoaded()
03656 && gAgent.getAvatarObject())
03657 {
03658
03659
03660
03661 LLMessageSystem* msg = gMessageSystem;
03662 msg->newMessageFast(_PREHASH_RetrieveInstantMessages);
03663 msg->nextBlockFast(_PREHASH_AgentData);
03664 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
03665 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03666 gAgent.sendReliableMessage();
03667 requested = TRUE;
03668 }
03669 }
03670
03672
03673
03674
03675
03677
03678 void idle()
03679 {
03680
03681 static LLTimer idle_timer;
03682
03683 LLControlBase::updateAllListeners();
03684
03685 LLFrameTimer::updateFrameTime();
03686 LLEventTimer::updateClass();
03687 LLCriticalDamp::updateInterpolants();
03688 LLMortician::updateClass();
03689 F32 dt_raw = idle_timer.getElapsedTimeAndResetF32();
03690
03691
03692
03693
03694 const F32 MIN_FRAME_RATE = 1.f;
03695 const F32 MAX_FRAME_RATE = 200.f;
03696
03697 F32 frame_rate_clamped = 1.f / dt_raw;
03698 frame_rate_clamped = llclamp(frame_rate_clamped, MIN_FRAME_RATE, MAX_FRAME_RATE);
03699 gFrameDTClamped = 1.f / frame_rate_clamped;
03700
03701
03702
03703 gFPSClamped = (frame_rate_clamped + (4.f * gFPSClamped)) / 5.f;
03704
03705 if (gQuitAfterSeconds > 0.f)
03706 {
03707 if (gRenderStartTime.getElapsedTimeF32() > gQuitAfterSeconds)
03708 {
03709 app_force_quit(NULL);
03710 }
03711 }
03712
03713
03714
03715 request_initial_instant_messages();
03716
03718
03719
03720
03721
03722 if (LLStartUp::getStartupState() < STATE_STARTED)
03723 {
03724
03725 if (!idle_startup())
03726 {
03727 return;
03728 }
03729 }
03730
03731
03732 F32 yaw = 0.f;
03733
03734 if (!gDisconnected)
03735 {
03736 LLFastTimer t(LLFastTimer::FTM_NETWORK);
03737
03738
03739 gWorldp->setSpaceTimeUSec(gWorldp->getSpaceTimeUSec() + (U32)(dt_raw * SEC_TO_MICROSEC));
03740
03741
03743
03744
03745
03746
03747 if (gRotateRight)
03748 {
03749 gAgent.moveYaw(-1.f);
03750 }
03751
03752
03753 gAgentPilot.updateTarget();
03754 gAgent.autoPilot(&yaw);
03755
03756 static LLFrameTimer agent_update_timer;
03757 static U32 last_control_flags;
03758
03759
03760 F32 agent_update_time = agent_update_timer.getElapsedTimeF32();
03761 BOOL flags_changed = gAgent.controlFlagsDirty() || (last_control_flags != gAgent.getControlFlags());
03762
03763 if (flags_changed || (agent_update_time > (1.0f / (F32) AGENT_UPDATES_PER_SECOND)))
03764 {
03765
03766 last_control_flags = gAgent.getControlFlags();
03767 send_agent_update(TRUE);
03768 agent_update_timer.reset();
03769 }
03770 }
03771
03773
03774
03775
03776
03777
03778 {
03779 static LLFrameTimer viewer_stats_timer;
03780 reset_statistics();
03781
03782
03783
03784
03785 if (viewer_stats_timer.getElapsedTimeF32() >= 300.f && !gDisconnected)
03786 {
03787 llinfos << "Transmitting sessions stats" << llendl;
03788 send_stats();
03789 viewer_stats_timer.reset();
03790 }
03791
03792
03793 static LLFrameTimer object_debug_timer;
03794 if (object_debug_timer.getElapsedTimeF32() > 5.f)
03795 {
03796 object_debug_timer.reset();
03797 if (gObjectList.mNumDeadObjectUpdates)
03798 {
03799 llinfos << "Dead object updates: " << gObjectList.mNumDeadObjectUpdates << llendl;
03800 gObjectList.mNumDeadObjectUpdates = 0;
03801 }
03802 if (gObjectList.mNumUnknownKills)
03803 {
03804 llinfos << "Kills on unknown objects: " << gObjectList.mNumUnknownKills << llendl;
03805 gObjectList.mNumUnknownKills = 0;
03806 }
03807 if (gObjectList.mNumUnknownUpdates)
03808 {
03809 llinfos << "Unknown object updates: " << gObjectList.mNumUnknownUpdates << llendl;
03810 gObjectList.mNumUnknownUpdates = 0;
03811 }
03812 }
03813 gFrameStats.addFrameData();
03814 }
03815
03816
03817 gFloaterAvatarList->updateAvatarList();
03818
03819 gFloaterEventLog->updateWindow();
03820
03821 if (!gDisconnected)
03822 {
03823 LLFastTimer t(LLFastTimer::FTM_NETWORK);
03824
03826
03827
03828
03829
03830
03831
03832
03833 gFrameStats.start(LLFrameStats::IDLE_NETWORK);
03834 idle_network();
03835 stop_glerror();
03836
03837 gFrameStats.start(LLFrameStats::AGENT_MISC);
03838
03839
03840 idle_afk_check();
03841
03842
03843 update_statistics(gFrameCount);
03844
03845 gViewerWindow->updateDebugText();
03846 }
03847
03849
03850
03851
03852
03853
03854 {
03855
03856
03857
03858 gEventNotifier.update();
03859
03860 gIdleCallbacks.callFunctions();
03861 }
03862
03863 if (gDisconnected)
03864 {
03865 return;
03866 }
03867
03868 gViewerWindow->handlePerFrameHover();
03869
03871
03872
03873 LLCoordGL current_mouse = gViewerWindow->getCurrentMouse();
03874
03875
03876
03877 {
03878
03879
03880
03881
03882 gSelectMgr->deselectAllIfTooFar();
03883 gSelectMgr->update();
03884 }
03885
03886 {
03887 LLFastTimer t(LLFastTimer::FTM_RESET_DRAWORDER);
03888
03890
03891
03892
03893
03894
03895
03896
03897 gPipeline.resetDrawOrders();
03898 }
03899 {
03900
03901 gGestureManager.update();
03902
03903 gAgent.updateAgentPosition(gFrameDTClamped, yaw, current_mouse.mX, current_mouse.mY);
03904 }
03905
03906 {
03907 LLFastTimer t(LLFastTimer::FTM_OBJECTLIST_UPDATE);
03908 gFrameStats.start(LLFrameStats::OBJECT_UPDATE);
03909
03910 if (!(gLogoutRequestSent && gHaveSavedSnapshot))
03911 {
03912 gObjectList.update(gAgent, *gWorldp);
03913 }
03914 }
03915
03916 {
03917 LLFastTimer t(LLFastTimer::FTM_UPDATE_SKY);
03918 gSky.updateSky();
03919 }
03920
03922
03923
03924
03925
03926
03927 {
03928 LLFastTimer t(LLFastTimer::FTM_CLEANUP);
03929 gFrameStats.start(LLFrameStats::CLEAN_DEAD);
03930 gObjectList.cleanDeadObjects();
03931 LLDrawable::cleanupDeadDrawables();
03932 }
03933
03934
03935
03936
03937
03938
03940
03941
03942
03943
03944
03945
03946
03947 {
03948
03949
03950 gFrameStats.start(LLFrameStats::UPDATE_EFFECTS);
03951 gSelectMgr->updateEffects();
03952 gHUDManager->cleanupEffects();
03953 gHUDManager->sendEffects();
03954 }
03955
03956 stop_glerror();
03957
03959
03960
03961
03962
03963 {
03964 LLFastTimer t(LLFastTimer::FTM_NETWORK);
03965 gVLManager.unpackData();
03966 }
03967
03969
03970
03971
03972
03973 gWorldp->updateVisibilities();
03974 {
03975 const F32 max_region_update_time = .001f;
03976 LLFastTimer t(LLFastTimer::FTM_REGION_UPDATE);
03977 gWorldp->updateRegions(max_region_update_time);
03978 }
03979
03981
03982
03983
03984
03985 if (!gNoRender)
03986 {
03987 gWorldp->updateClouds(gFrameDTClamped);
03988 gSky.propagateHeavenlyBodies(gFrameDTClamped);
03989
03990
03991 LLVector3 wind_position_region;
03992 static LLVector3 average_wind;
03993
03994 LLViewerRegion *regionp;
03995 regionp = gWorldp->resolveRegionGlobal(wind_position_region, gAgent.getPositionGlobal());
03996 if (regionp)
03997 {
03998 gWindVec = regionp->mWind.getVelocity(wind_position_region);
03999
04000
04001
04002 average_wind = regionp->mWind.getAverage();
04003 F32 cloud_density = regionp->mCloudLayer.getDensityRegion(wind_position_region);
04004
04005 gSky.setCloudDensityAtAgent(cloud_density);
04006 gSky.setWind(average_wind);
04007
04008 }
04009 else
04010 {
04011 gWindVec.setVec(0.0f, 0.0f, 0.0f);
04012 }
04013 }
04014 stop_glerror();
04015
04017
04018
04019
04020
04021
04022 gFrameStats.start(LLFrameStats::IMAGE_UPDATE);
04023
04024 LLFastTimer t(LLFastTimer::FTM_IMAGE_UPDATE);
04025
04026 LLViewerImage::updateClass(gCamera->getVelocityStat()->getMean(),
04027 gCamera->getAngularVelocityStat()->getMean());
04028
04029 gBumpImageList.updateImages();
04030
04031 const F32 max_image_decode_time = 0.005f;
04032 gImageList.updateImages(max_image_decode_time);
04033 stop_glerror();
04034
04036
04037
04038
04039
04040
04041 if (!gNoRender)
04042 {
04043 gFrameStats.start(LLFrameStats::UPDATE_MOVE);
04044 gPipeline.updateMove();
04045
04046 gFrameStats.start(LLFrameStats::UPDATE_PARTICLES);
04047 gWorldp->updateParticles();
04048 }
04049 stop_glerror();
04050
04051 if (!LLViewerJoystick::sOverrideCamera)
04052 {
04053 gAgent.updateCamera();
04054 }
04055 else
04056 {
04057 LLViewerJoystick::updateCamera();
04058 }
04059
04060
04061 {
04062 LLFastTimer t(LLFastTimer::FTM_LOD_UPDATE);
04063 gObjectList.updateApparentAngles(gAgent);
04064 }
04065
04066 {
04067 gFrameStats.start(LLFrameStats::AUDIO);
04068 LLFastTimer t(LLFastTimer::FTM_AUDIO_UPDATE);
04069
04070 if (gAudiop)
04071 {
04072 audio_update_volume(false);
04073 audio_update_listener();
04074 audio_update_wind(false);
04075
04076
04077 const F32 max_audio_decode_time = 0.002f;
04078 gAudiop->idle(max_audio_decode_time);
04079 }
04080 }
04081
04082 if ( gTrustNet )
04083 {
04084 gTrustNet->processRequests();
04085 }
04086
04087
04088
04089
04090 if (gQuitRequested)
04091 {
04092 idle_shutdown();
04093 }
04094
04095 stop_glerror();
04096 }
04097
04098
04099 F32 mouse_x_from_center(S32 x)
04100 {
04101 return ((F32) x / (F32) gViewerWindow->getWindowWidth() ) - 0.5f;
04102 }
04103
04104
04105 F32 mouse_y_from_center(S32 y)
04106 {
04107 return ((F32) y / (F32) gViewerWindow->getWindowHeight() ) - 0.5f;
04108 }
04109
04110
04112
04113 void init_audio()
04114 {
04115 if (!gAudiop)
04116 {
04117 llwarns << "Failed to create an appropriate Audio Engine" << llendl;
04118 return;
04119 }
04120 LLVector3d lpos_global = gAgent.getCameraPositionGlobal();
04121 LLVector3 lpos_global_f;
04122
04123 lpos_global_f.setVec(lpos_global);
04124
04125 gAudiop->setListener(lpos_global_f,
04126 LLVector3::zero,
04127 gCamera->getUpAxis(),
04128 gCamera->getAtAxis());
04129
04130
04131
04132 BOOL mute_audio = gSavedSettings.getBOOL("MuteAudio");
04133
04134 if (!mute_audio && gPreloadSounds)
04135 {
04136 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndAlert")));
04137 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndBadKeystroke")));
04138
04139 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndClick")));
04140 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndClickRelease")));
04141 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndHealthReductionF")));
04142 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndHealthReductionM")));
04143
04144
04145
04146 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndInvalidOp")));
04147
04148 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndMoneyChangeDown")));
04149 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndMoneyChangeUp")));
04150
04151 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectCreate")));
04152 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectDelete")));
04153 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectRezIn")));
04154 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectRezOut")));
04155 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuAppear")));
04156 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuHide")));
04157 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight0")));
04158 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight1")));
04159 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight2")));
04160 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight3")));
04161 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight4")));
04162 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight5")));
04163 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight6")));
04164 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight7")));
04165 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndSnapshot")));
04166
04167
04168 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStartIM")));
04169
04170 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTeleportOut")));
04171
04172
04173 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTyping")));
04174 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowClose")));
04175 gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowOpen")));
04176 }
04177
04178 audio_update_volume(true);
04179 }
04180
04181 void audio_update_volume(bool force_update)
04182 {
04183 F32 master_volume = gSavedSettings.getF32("AudioLevelMaster");
04184 BOOL mute_audio = gSavedSettings.getBOOL("MuteAudio");
04185 if (!gViewerWindow->getActive() && (gSavedSettings.getBOOL("MuteWhenMinimized")))
04186 {
04187 mute_audio = TRUE;
04188 }
04189 F32 mute_volume = mute_audio ? 0.0f : 1.0f;
04190
04191
04192 if (gAudiop)
04193 {
04194 gAudiop->setMasterGain ( master_volume );
04195
04196 gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler"));
04197 gAudiop->setDistanceFactor(gSavedSettings.getF32("AudioLevelDistance"));
04198 gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
04199 #ifdef kAUDIO_ENABLE_WIND
04200 gAudiop->enableWind(!mute_audio);
04201 #endif
04202
04203 gAudiop->setMuted(mute_audio);
04204
04205 if (force_update)
04206 {
04207 audio_update_wind(true);
04208 }
04209 }
04210
04211
04212 if (gAudiop)
04213 {
04214 F32 music_volume = gSavedSettings.getF32("AudioLevelMusic");
04215 music_volume = mute_volume * master_volume * (music_volume*music_volume);
04216 gAudiop->setInternetStreamGain ( music_volume );
04217 }
04218
04219
04220 if(LLMediaEngine::getInstance())
04221 {
04222 F32 media_volume = gSavedSettings.getF32("AudioLevelMedia");
04223 media_volume = mute_volume * master_volume * (media_volume*media_volume);
04224 LLMediaEngine::getInstance()->setVolume(media_volume);
04225 }
04226
04227
04228 if (gVoiceClient)
04229 {
04230 F32 voice_volume = gSavedSettings.getF32("AudioLevelVoice");
04231 voice_volume = mute_volume * master_volume * voice_volume;
04232 gVoiceClient->setVoiceVolume(voice_volume);
04233 gVoiceClient->setMicGain(gSavedSettings.getF32("AudioLevelMic"));
04234
04235 if (!gViewerWindow->getActive() && (gSavedSettings.getBOOL("MuteWhenMinimized")))
04236 {
04237 gVoiceClient->setMuteMic(true);
04238 }
04239 else
04240 {
04241 gVoiceClient->setMuteMic(false);
04242 }
04243 }
04244 }
04245
04246 void audio_update_listener()
04247 {
04248 if (gAudiop)
04249 {
04250
04251 LLVector3d lpos_global = gAgent.getCameraPositionGlobal();
04252 LLVector3 lpos_global_f;
04253 lpos_global_f.setVec(lpos_global);
04254
04255 gAudiop->setListener(lpos_global_f,
04256
04257
04258 gAgent.getVelocity(),
04259 gCamera->getUpAxis(),
04260 gCamera->getAtAxis());
04261 }
04262 }
04263
04264 void audio_update_wind(bool force_update)
04265 {
04266 #ifdef kAUDIO_ENABLE_WIND
04267
04268
04269
04270 LLViewerRegion* region = gAgent.getRegion();
04271 if (region)
04272 {
04273 static F32 last_camera_water_height = -1000.f;
04274 LLVector3 camera_pos = gAgent.getCameraPositionAgent();
04275 F32 camera_water_height = camera_pos.mV[VZ] - region->getWaterHeight();
04276
04277
04278
04279
04280 if (force_update || (last_camera_water_height * camera_water_height) < 0.f)
04281 {
04282 if (camera_water_height < 0.f)
04283 {
04284 gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff") * LL_ROLLOFF_MULTIPLIER_UNDER_WATER);
04285 }
04286 else
04287 {
04288 gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff"));
04289 }
04290 }
04291
04292
04293
04294 gRelativeWindVec = gAgent.getFrameAgent().rotateToLocal(gWindVec - gAgent.getVelocity());
04295
04296
04297
04298
04299 gAudiop->mMaxWindGain = gSavedSettings.getF32("AudioLevelAmbient");
04300
04301 last_camera_water_height = camera_water_height;
04302 gAudiop->updateWind(gRelativeWindVec, camera_water_height);
04303 }
04304 #endif
04305 }
04306
04307
04309
04310 BOOL raycast_for_new_obj_pos( S32 x, S32 y, LLViewerObject** hit_obj, S32* hit_face,
04311 BOOL* b_hit_land, LLVector3* ray_start_region, LLVector3* ray_end_region, LLViewerRegion** region )
04312 {
04313 F32 max_dist_from_camera = gSavedSettings.getF32( "MaxSelectDistance" ) - 1.f;
04314
04315
04316
04317 gViewerWindow->hitObjectOrLandGlobalImmediate(x, y, NULL, FALSE);
04318
04319
04320
04321 *hit_obj = gObjectList.findObject( gLastHitNonFloraObjectID );
04322 *hit_face = gLastHitNonFloraObjectFace;
04323 *b_hit_land = !(*hit_obj) && !gLastHitNonFloraPosGlobal.isExactlyZero();
04324 LLVector3d land_pos_global = gLastHitNonFloraPosGlobal;
04325
04326
04327 BOOL bypass_sim_raycast = FALSE;
04328 LLVector3d surface_pos_global;
04329 if (*b_hit_land)
04330 {
04331 surface_pos_global = land_pos_global;
04332 bypass_sim_raycast = TRUE;
04333 }
04334 else
04335 if (*hit_obj)
04336 {
04337 surface_pos_global = (*hit_obj)->getPositionGlobal();
04338 }
04339 else
04340 {
04341 return FALSE;
04342 }
04343
04344
04345 LLVector3d ray_start_global = gAgent.getCameraPositionGlobal();
04346 F32 dist_to_surface_sq = (F32)((surface_pos_global - ray_start_global).magVecSquared());
04347 if( dist_to_surface_sq > (max_dist_from_camera * max_dist_from_camera) )
04348 {
04349 return FALSE;
04350 }
04351
04352
04353 LLViewerRegion *regionp = gWorldp->getRegionFromPosGlobal(surface_pos_global);
04354 if (!regionp)
04355 {
04356 llwarns << "Trying to add object outside of all known regions!" << llendl;
04357 return FALSE;
04358 }
04359
04360
04361 LLVector3d mouse_direction;
04362 mouse_direction.setVec( gViewerWindow->mouseDirectionGlobal( x, y ) );
04363
04364 *region = regionp;
04365 *ray_start_region = regionp->getPosRegionFromGlobal( ray_start_global );
04366 F32 near_clip = gCamera->getNear() + 0.01f;
04367 *ray_start_region += gCamera->getAtAxis() * near_clip;
04368
04369 if( bypass_sim_raycast )
04370 {
04371
04372 *ray_end_region = regionp->getPosRegionFromGlobal( surface_pos_global );
04373 }
04374 else
04375 {
04376 LLVector3d ray_end_global = ray_start_global + (1.f + max_dist_from_camera) * mouse_direction;
04377 *ray_end_region = regionp->getPosRegionFromGlobal( ray_end_global );
04378 }
04379
04380 return TRUE;
04381 }
04382
04383 const LLVector3 DEFAULT_OBJECT_SCALE(0.5f, 0.5f, 0.5f);
04384
04385 BOOL add_object( LLPCode pcode, S32 x, S32 y, U8 use_physics )
04386 {
04387 LLVector3 ray_start_region;
04388 LLVector3 ray_end_region;
04389 LLViewerRegion* regionp = NULL;
04390 BOOL b_hit_land = FALSE;
04391 S32 hit_face = -1;
04392 LLViewerObject* hit_obj = NULL;
04393 U8 state = 0;
04394 BOOL success = raycast_for_new_obj_pos( x, y, &hit_obj, &hit_face, &b_hit_land, &ray_start_region, &ray_end_region, ®ionp );
04395 if( !success )
04396 {
04397 return FALSE;
04398 }
04399
04400 if( hit_obj && (hit_obj->isAvatar() || hit_obj->isAttachment()) )
04401 {
04402
04403 return FALSE;
04404 }
04405
04406 if (NULL == regionp)
04407 {
04408 llwarns << "regionp was NULL; aborting function." << llendl;
04409 return FALSE;
04410 }
04411
04412 if (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX)
04413 {
04414 LLFirstUse::useSandbox();
04415 }
04416
04417
04418 LLQuaternion rotation;
04419 LLVector3 scale = DEFAULT_OBJECT_SCALE;
04420 U8 material = LL_MCODE_WOOD;
04421 BOOL create_selected = FALSE;
04422 LLVolumeParams volume_params;
04423
04424 switch (pcode)
04425 {
04426 case LL_PCODE_LEGACY_GRASS:
04427
04428 scale.setVec(10.f + ll_frand(20.f), 10.f + ll_frand(20.f), 1.f + ll_frand(2.f));
04429 state = rand() % LLVOGrass::sMaxGrassSpecies;
04430 break;
04431
04432
04433 case LL_PCODE_LEGACY_TREE:
04434 case LL_PCODE_TREE_NEW:
04435 state = rand() % LLVOTree::sMaxTreeSpecies;
04436 break;
04437
04438 case LL_PCODE_SPHERE:
04439 case LL_PCODE_CONE:
04440 case LL_PCODE_CUBE:
04441 case LL_PCODE_CYLINDER:
04442 case LL_PCODE_TORUS:
04443 case LLViewerObject::LL_VO_SQUARE_TORUS:
04444 case LLViewerObject::LL_VO_TRIANGLE_TORUS:
04445 default:
04446 create_selected = TRUE;
04447 break;
04448 }
04449
04450
04451 if (gAudiop)
04452 {
04453 F32 volume = gSavedSettings.getF32("AudioLevelUI");
04454 gAudiop->triggerSound( LLUUID(gSavedSettings.getString("UISndObjectCreate")), gAgent.getID(), volume);
04455 }
04456
04457 gMessageSystem->newMessageFast(_PREHASH_ObjectAdd);
04458 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
04459 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
04460 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
04461 gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
04462 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
04463 gMessageSystem->addU8Fast(_PREHASH_Material, material);
04464
04465 U32 flags = 0;
04466 if (use_physics)
04467 {
04468 flags |= FLAGS_USE_PHYSICS;
04469 }
04470 if (create_selected)
04471 {
04472 flags |= FLAGS_CREATE_SELECTED;
04473 }
04474 gMessageSystem->addU32Fast(_PREHASH_AddFlags, flags );
04475
04476 LLPCode volume_pcode;
04477 switch (pcode)
04478 {
04479 case LL_PCODE_SPHERE:
04480 rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis);
04481
04482 volume_params.setType( LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE );
04483 volume_params.setBeginAndEndS( 0.f, 1.f );
04484 volume_params.setBeginAndEndT( 0.f, 1.f );
04485 volume_params.setRatio ( 1, 1 );
04486 volume_params.setShear ( 0, 0 );
04487 LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
04488 volume_pcode = LL_PCODE_VOLUME;
04489 break;
04490
04491 case LL_PCODE_TORUS:
04492 rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis);
04493
04494 volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_CIRCLE );
04495 volume_params.setBeginAndEndS( 0.f, 1.f );
04496 volume_params.setBeginAndEndT( 0.f, 1.f );
04497 volume_params.setRatio ( 1.f, 0.25f );
04498 volume_params.setShear ( 0, 0 );
04499 LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
04500 volume_pcode = LL_PCODE_VOLUME;
04501 break;
04502
04503 case LLViewerObject::LL_VO_SQUARE_TORUS:
04504 rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis);
04505
04506 volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_CIRCLE );
04507 volume_params.setBeginAndEndS( 0.f, 1.f );
04508 volume_params.setBeginAndEndT( 0.f, 1.f );
04509 volume_params.setRatio ( 1.f, 0.25f );
04510 volume_params.setShear ( 0, 0 );
04511 LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
04512 volume_pcode = LL_PCODE_VOLUME;
04513 break;
04514
04515 case LLViewerObject::LL_VO_TRIANGLE_TORUS:
04516 rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis);
04517
04518 volume_params.setType( LL_PCODE_PROFILE_EQUALTRI, LL_PCODE_PATH_CIRCLE );
04519 volume_params.setBeginAndEndS( 0.f, 1.f );
04520 volume_params.setBeginAndEndT( 0.f, 1.f );
04521 volume_params.setRatio ( 1.f, 0.25f );
04522 volume_params.setShear ( 0, 0 );
04523 LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
04524 volume_pcode = LL_PCODE_VOLUME;
04525 break;
04526
04527 case LL_PCODE_SPHERE_HEMI:
04528 volume_params.setType( LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE );
04529
04530 volume_params.setBeginAndEndT( 0.f, 0.5f );
04531 volume_params.setRatio ( 1, 1 );
04532 volume_params.setShear ( 0, 0 );
04533 LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
04534 volume_pcode = LL_PCODE_VOLUME;
04535 break;
04536
04537 case LL_PCODE_CUBE:
04538 volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE );
04539 volume_params.setBeginAndEndS( 0.f, 1.f );
04540 volume_params.setBeginAndEndT( 0.f, 1.f );
04541 volume_params.setRatio ( 1, 1 );
04542 volume_params.setShear ( 0, 0 );
04543 LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
04544 volume_pcode = LL_PCODE_VOLUME;
04545 break;
04546
04547 case LL_PCODE_PRISM:
04548 volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE );
04549 volume_params.setBeginAndEndS( 0.f, 1.f );
04550 volume_params.setBeginAndEndT( 0.f, 1.f );
04551 volume_params.setRatio ( 0, 1 );
04552 volume_params.setShear ( -0.5f, 0 );
04553 LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
04554 volume_pcode = LL_PCODE_VOLUME;
04555 break;
04556
04557 case LL_PCODE_PYRAMID:
04558 volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE );
04559 volume_params.setBeginAndEndS( 0.f, 1.f );
04560 volume_params.setBeginAndEndT( 0.f, 1.f );
04561 volume_params.setRatio ( 0, 0 );
04562 volume_params.setShear ( 0, 0 );
04563 LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
04564 volume_pcode = LL_PCODE_VOLUME;
04565 break;
04566
04567 case LL_PCODE_TETRAHEDRON:
04568 volume_params.setType( LL_PCODE_PROFILE_EQUALTRI, LL_PCODE_PATH_LINE );
04569 volume_params.setBeginAndEndS( 0.f, 1.f );
04570 volume_params.setBeginAndEndT( 0.f, 1.f );
04571 volume_params.setRatio ( 0, 0 );
04572 volume_params.setShear ( 0, 0 );
04573 LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
04574 volume_pcode = LL_PCODE_VOLUME;
04575 break;
04576
04577 case LL_PCODE_CYLINDER:
04578 volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE );
04579 volume_params.setBeginAndEndS( 0.f, 1.f );
04580 volume_params.setBeginAndEndT( 0.f, 1.f );
04581 volume_params.setRatio ( 1, 1 );
04582 volume_params.setShear ( 0, 0 );
04583 LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
04584 volume_pcode = LL_PCODE_VOLUME;
04585 break;
04586
04587 case LL_PCODE_CYLINDER_HEMI:
04588 volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE );
04589 volume_params.setBeginAndEndS( 0.25f, 0.75f );
04590 volume_params.setBeginAndEndT( 0.f, 1.f );
04591 volume_params.setRatio ( 1, 1 );
04592 volume_params.setShear ( 0, 0 );
04593 LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
04594 volume_pcode = LL_PCODE_VOLUME;
04595 break;
04596
04597 case LL_PCODE_CONE:
04598 volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE );
04599 volume_params.setBeginAndEndS( 0.f, 1.f );
04600 volume_params.setBeginAndEndT( 0.f, 1.f );
04601 volume_params.setRatio ( 0, 0 );
04602 volume_params.setShear ( 0, 0 );
04603 LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
04604 volume_pcode = LL_PCODE_VOLUME;
04605 break;
04606
04607 case LL_PCODE_CONE_HEMI:
04608 volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE );
04609 volume_params.setBeginAndEndS( 0.25f, 0.75f );
04610 volume_params.setBeginAndEndT( 0.f, 1.f );
04611 volume_params.setRatio ( 0, 0 );
04612 volume_params.setShear ( 0, 0 );
04613 LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem);
04614 volume_pcode = LL_PCODE_VOLUME;
04615 break;
04616
04617 default:
04618 LLVolumeMessage::packVolumeParams(0, gMessageSystem);
04619 volume_pcode = pcode;
04620 break;
04621 }
04622 gMessageSystem->addU8Fast(_PREHASH_PCode, volume_pcode);
04623
04624 gMessageSystem->addVector3Fast(_PREHASH_Scale, scale );
04625 gMessageSystem->addQuatFast(_PREHASH_Rotation, rotation );
04626 gMessageSystem->addVector3Fast(_PREHASH_RayStart, ray_start_region );
04627 gMessageSystem->addVector3Fast(_PREHASH_RayEnd, ray_end_region );
04628 gMessageSystem->addU8Fast(_PREHASH_BypassRaycast, (U8)b_hit_land );
04629 gMessageSystem->addU8Fast(_PREHASH_RayEndIsIntersection, (U8)FALSE );
04630 gMessageSystem->addU8Fast(_PREHASH_State, state);
04631
04632
04633
04634
04635 LLUUID ray_target_id;
04636 if( hit_obj )
04637 {
04638 ray_target_id = hit_obj->getID();
04639 }
04640 else
04641 {
04642 ray_target_id.setNull();
04643 }
04644 gMessageSystem->addUUIDFast(_PREHASH_RayTargetID, ray_target_id );
04645
04646
04647 gMessageSystem->sendReliable(regionp->getHost());
04648
04649
04650 if (create_selected)
04651 {
04652 gSelectMgr->deselectAll();
04653 gViewerWindow->getWindow()->incBusyCount();
04654 }
04655
04656
04657 LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
04658 effectp->setSourceObject(gAgent.getAvatarObject());
04659 effectp->setPositionGlobal(regionp->getPosGlobalFromRegion(ray_end_region));
04660 effectp->setDuration(LL_HUD_DUR_SHORT);
04661 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
04662
04663 gViewerStats->incStat(LLViewerStats::ST_CREATE_COUNT);
04664
04665 return TRUE;
04666 }
04667
04668
04669
04670 #if LL_WINDOWS
04671 void create_console()
04672 {
04673 int h_con_handle;
04674 long l_std_handle;
04675
04676 CONSOLE_SCREEN_BUFFER_INFO coninfo;
04677 FILE *fp;
04678
04679
04680 AllocConsole();
04681
04682
04683 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
04684 coninfo.dwSize.Y = MAX_CONSOLE_LINES;
04685 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
04686
04687
04688 l_std_handle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
04689 h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT);
04690 fp = _fdopen( h_con_handle, "w" );
04691 *stdout = *fp;
04692 setvbuf( stdout, NULL, _IONBF, 0 );
04693
04694
04695 l_std_handle = (long)GetStdHandle(STD_INPUT_HANDLE);
04696 h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT);
04697 fp = _fdopen( h_con_handle, "r" );
04698 *stdin = *fp;
04699 setvbuf( stdin, NULL, _IONBF, 0 );
04700
04701
04702 l_std_handle = (long)GetStdHandle(STD_ERROR_HANDLE);
04703 h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT);
04704 fp = _fdopen( h_con_handle, "w" );
04705 *stderr = *fp;
04706 setvbuf( stderr, NULL, _IONBF, 0 );
04707 }
04708 #endif
04709
04710
04711
04712
04713
04714
04715
04716
04717
04718
04719
04720 BOOL gVectorizePerfTest = TRUE;
04721 BOOL gVectorizeEnable = FALSE;
04722 U32 gVectorizeProcessor = 0;
04723 BOOL gVectorizeSkin = FALSE;
04724
04725 void update_vector_performances(void)
04726 {
04727 char *vp;
04728
04729 switch(gVectorizeProcessor)
04730 {
04731 case 2: vp = "SSE2"; break;
04732 case 1: vp = "SSE"; break;
04733 default: vp = "COMPILER DEFAULT"; break;
04734 }
04735 llinfos << "Vectorization : " << ( gVectorizeEnable ? "ENABLED" : "DISABLED" ) << llendl ;
04736 llinfos << "Vector Processor : " << vp << llendl ;
04737 llinfos << "Vectorized Skinning : " << ( gVectorizeSkin ? "ENABLED" : "DISABLED" ) << llendl ;
04738
04739 if(gVectorizeEnable && gVectorizeSkin)
04740 {
04741 switch(gVectorizeProcessor)
04742 {
04743 case 2:
04744 LLViewerJointMesh::sUpdateGeometryFunc = &LLViewerJointMesh::updateGeometrySSE2;
04745 break;
04746 case 1:
04747 LLViewerJointMesh::sUpdateGeometryFunc = &LLViewerJointMesh::updateGeometrySSE;
04748 break;
04749 default:
04750 LLViewerJointMesh::sUpdateGeometryFunc = &LLViewerJointMesh::updateGeometryVectorized;
04751 break;
04752 }
04753 }
04754 else
04755 {
04756 LLViewerJointMesh::sUpdateGeometryFunc = &LLViewerJointMesh::updateGeometryOriginal;
04757 }
04758 }
04759
04760
04761 class LLVectorizationEnableListener: public LLSimpleListener
04762 {
04763 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04764 {
04765 gVectorizeEnable = event->getValue().asBoolean();
04766 update_vector_performances();
04767 return true;
04768 }
04769 };
04770 static LLVectorizationEnableListener vectorization_enable_listener;
04771
04772 class LLVectorizeSkinListener: public LLSimpleListener
04773 {
04774 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04775 {
04776 gVectorizeSkin = event->getValue().asBoolean();
04777 update_vector_performances();
04778 return true;
04779 }
04780 };
04781 static LLVectorizeSkinListener vectorize_skin_listener;
04782
04783 class LLVectorProcessorListener: public LLSimpleListener
04784 {
04785 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04786 {
04787 gVectorizeProcessor = event->getValue().asInteger();
04788 update_vector_performances();
04789 return true;
04790 }
04791 };
04792 static LLVectorProcessorListener vector_processor_listener;
04793
04794
04795
04796 void saved_settings_to_globals()
04797 {
04798 LLBUTTON_H_PAD = gSavedSettings.getS32("ButtonHPad");
04799 LLBUTTON_V_PAD = gSavedSettings.getS32("ButtonVPad");
04800 BTN_HEIGHT_SMALL = gSavedSettings.getS32("ButtonHeightSmall");
04801 BTN_HEIGHT = gSavedSettings.getS32("ButtonHeight");
04802
04803 MENU_BAR_HEIGHT = gSavedSettings.getS32("MenuBarHeight");
04804 MENU_BAR_WIDTH = gSavedSettings.getS32("MenuBarWidth");
04805 STATUS_BAR_HEIGHT = gSavedSettings.getS32("StatusBarHeight");
04806
04807 LLCOMBOBOX_HEIGHT = BTN_HEIGHT - 2;
04808 LLCOMBOBOX_WIDTH = 128;
04809
04810 LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize"));
04811
04812 LLVOSky::sNighttimeBrightness = gSavedSettings.getF32("RenderNightBrightness");
04813
04814 LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic");
04815 LLVOVolume::sLODFactor = gSavedSettings.getF32("RenderVolumeLODFactor");
04816 LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
04817 LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
04818 LLVOTree::sTreeFactor = gSavedSettings.getF32("RenderTreeLODFactor");
04819 LLVOAvatar::sLODFactor = gSavedSettings.getF32("RenderAvatarLODFactor");
04820 LLVOAvatar::sMaxVisible = gSavedSettings.getS32("RenderAvatarMaxVisible");
04821 LLVOAvatar::sVisibleInFirstPerson = gSavedSettings.getBOOL("FirstPersonAvatarVisible");
04822
04823 LLFolderView::sAutoOpenTime = llmax(0.25f, gSavedSettings.getF32("FolderAutoOpenDelay"));
04824 LLToolBar::sInventoryAutoOpenTime = gSavedSettings.getF32("InventoryAutoOpenDelay");
04825 LLSelectMgr::sRectSelectInclusive = gSavedSettings.getBOOL("RectangleSelectInclusive");
04826 LLSelectMgr::sRenderHiddenSelections = gSavedSettings.getBOOL("RenderHiddenSelections");
04827 LLSelectMgr::sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius");
04828
04829 gFrameStats.setTrackStats(gSavedSettings.getBOOL("StatsSessionTrackFrameStats"));
04830 gAgentPilot.mNumRuns = gSavedSettings.getS32("StatsNumRuns");
04831 gAgentPilot.mQuitAfterRuns = gSavedSettings.getBOOL("StatsQuitAfterRuns");
04832 gAgent.mHideGroupTitle = gSavedSettings.getBOOL("RenderHideGroupTitle");
04833
04834 gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");
04835 gAllowIdleAFK = gSavedSettings.getBOOL("AllowIdleAFK");
04836 gAFKTimeout = gSavedSettings.getF32("AFKTimeout");
04837 gMouseSensitivity = gSavedSettings.getF32("MouseSensitivity");
04838 gInvertMouse = gSavedSettings.getBOOL("InvertMouse");
04839 gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");
04840 gMapScale = gSavedSettings.getF32("MapScale");
04841 gMiniMapScale = gSavedSettings.getF32("MiniMapScale");
04842 gHandleKeysAsync = gSavedSettings.getBOOL("AsyncKeyboard");
04843 LLHoverView::sShowHoverTips = gSavedSettings.getBOOL("ShowHoverTips");
04844
04845 #if LL_VECTORIZE
04846 if (gSysCPU.hasAltivec())
04847 {
04848 gSavedSettings.setBOOL("VectorizeEnable", TRUE );
04849 gSavedSettings.setU32("VectorizeProcessor", 0 );
04850 }
04851 else
04852 if (gSysCPU.hasSSE2())
04853 {
04854 gSavedSettings.setBOOL("VectorizeEnable", TRUE );
04855 gSavedSettings.setU32("VectorizeProcessor", 2 );
04856 }
04857 else
04858 if (gSysCPU.hasSSE())
04859 {
04860 gSavedSettings.setBOOL("VectorizeEnable", TRUE );
04861 gSavedSettings.setU32("VectorizeProcessor", 1 );
04862 }
04863 else
04864 {
04865
04866 gSavedSettings.setBOOL("VectorizePerfTest", FALSE );
04867 gSavedSettings.setBOOL("VectorizeEnable", FALSE );
04868 gSavedSettings.setU32("VectorizeProcessor", 0 );
04869 gSavedSettings.setBOOL("VectorizeSkin", FALSE);
04870 }
04871 #else
04872
04873 gSavedSettings.setBOOL("VectorizePerfTest", FALSE );
04874 gSavedSettings.setBOOL("VectorizeEnable", FALSE );
04875 gSavedSettings.setU32("VectorizeProcessor", 0 );
04876 gSavedSettings.setBOOL("VectorizeSkin", FALSE);
04877 #endif
04878
04879 gVectorizePerfTest = gSavedSettings.getBOOL("VectorizePerfTest");
04880 gVectorizeEnable = gSavedSettings.getBOOL("VectorizeEnable");
04881 gVectorizeProcessor = gSavedSettings.getU32("VectorizeProcessor");
04882 gVectorizeSkin = gSavedSettings.getBOOL("VectorizeSkin");
04883 update_vector_performances();
04884
04885
04886 gCrashBehavior = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING);
04887
04888
04889 gSavedSettings.setBOOL("PTTCurrentlyEnabled", gSavedSettings.getBOOL("EnablePushToTalk"));
04890
04891 settings_setup_listeners();
04892
04893
04894 gSavedSettings.getControl("VectorizeEnable")->addListener(&vectorization_enable_listener);
04895 gSavedSettings.getControl("VectorizeProcessor")->addListener(&vector_processor_listener);
04896 gSavedSettings.getControl("VectorizeSkin")->addListener(&vectorize_skin_listener);
04897
04898
04899 }
04900
04901 void cleanup_saved_settings()
04902 {
04903 gSavedSettings.setBOOL("MouseSun", FALSE);
04904
04905 gSavedSettings.setBOOL("FlyBtnState", FALSE);
04906
04907 gSavedSettings.setBOOL("FirstPersonBtnState", FALSE);
04908 gSavedSettings.setBOOL("ThirdPersonBtnState", TRUE);
04909 gSavedSettings.setBOOL("BuildBtnState", FALSE);
04910
04911 gSavedSettings.setBOOL("UseEnergy", TRUE);
04912
04913 gSavedSettings.setBOOL("DebugWindowProc", gDebugWindowProc);
04914
04915 gSavedSettings.setBOOL("AllowIdleAFK", gAllowIdleAFK);
04916 gSavedSettings.setBOOL("ShowObjectUpdates", gShowObjectUpdates);
04917
04918 if (!gNoRender)
04919 {
04920 if (gDebugView)
04921 {
04922 gSavedSettings.setBOOL("ShowDebugConsole", gDebugView->mDebugConsolep->getVisible());
04923 gSavedSettings.setBOOL("ShowDebugStats", gDebugView->mStatViewp->getVisible());
04924 }
04925 }
04926
04927
04928
04929 BOOL fullscreen = gViewerWindow->mWindow->getFullscreen();
04930 BOOL maximized = gViewerWindow->mWindow->getMaximized();
04931 if (!fullscreen && !maximized)
04932 {
04933 LLCoordScreen window_pos;
04934
04935 if (gViewerWindow->mWindow->getPosition(&window_pos))
04936 {
04937 gSavedSettings.setS32("WindowX", window_pos.mX);
04938 gSavedSettings.setS32("WindowY", window_pos.mY);
04939 }
04940 }
04941
04942 gSavedSettings.setF32("MapScale", gMapScale );
04943 gSavedSettings.setF32("MiniMapScale", gMiniMapScale );
04944 gSavedSettings.setBOOL("AsyncKeyboard", gHandleKeysAsync);
04945 gSavedSettings.setBOOL("ShowHoverTips", LLHoverView::sShowHoverTips);
04946
04947
04948 if (gAgent.mInitialized)
04949 {
04950 gSavedSettings.setF32("RenderFarClip", gAgent.mDrawDistance);
04951 }
04952
04953 gCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, gCrashBehavior);
04954 }
04955
04956
04957 void callback_cache_name(const LLUUID& id, const char* firstname, const char* lastname, BOOL is_group, void* data)
04958 {
04959 LLNameListCtrl::refreshAll(id, firstname, lastname, is_group);
04960 LLNameBox::refreshAll(id, firstname, lastname, is_group);
04961 LLNameEditor::refreshAll(id, firstname, lastname, is_group);
04962
04963
04964
04965 dialog_refresh_all();
04966 }
04967
04968
04969 void write_debug(const std::string& str)
04970 {
04971 write_debug(str.c_str());
04972 }
04973
04974 void write_debug(const char *str)
04975 {
04976 if (!gDebugFile)
04977 {
04978 std::string debug_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"debug_info.log");
04979 llinfos << "Opening debug file " << debug_filename << llendl;
04980 gDebugFile = LLFile::fopen(debug_filename.c_str(), "w");
04981 if (!gDebugFile)
04982 {
04983 llinfos << "Opening debug file " << debug_filename << " failed. Using stderr." << llendl;
04984 gDebugFile = stderr;
04985 }
04986 }
04987 fputs(str, gDebugFile);
04988 fflush(gDebugFile);
04989 }
04990
04991 void close_debug()
04992 {
04993 if (gDebugFile)
04994 {
04995 fclose(gDebugFile);
04996 }
04997 gDebugFile = NULL;
04998 }
04999
05000 void print_agent_nvpairs(void*)
05001 {
05002 LLViewerObject *objectp;
05003
05004 llinfos << "Agent Name Value Pairs" << llendl;
05005
05006 objectp = gObjectList.findObject(gAgentID);
05007 if (objectp)
05008 {
05009 objectp->printNameValuePairs();
05010 }
05011 else
05012 {
05013 llinfos << "Can't find agent object" << llendl;
05014 }
05015
05016 llinfos << "Camera at " << gAgent.getCameraPositionGlobal() << llendl;
05017 }
05018
05019
05020 void reset_statistics()
05021 {
05022 gPipeline.resetFrameStats();
05023 if (LLSurface::sTextureUpdateTime)
05024 {
05025 LLSurface::sTexelsUpdatedPerSecStat.addValue(0.001f*(LLSurface::sTexelsUpdated / LLSurface::sTextureUpdateTime));
05026 LLSurface::sTexelsUpdated = 0;
05027 LLSurface::sTextureUpdateTime = 0.f;
05028 }
05029 }
05030
05031
05032 void output_statistics(void*)
05033 {
05034 llinfos << "Number of orphans: " << gObjectList.getOrphanCount() << llendl;
05035 llinfos << "Number of dead objects: " << gObjectList.mNumDeadObjects << llendl;
05036 llinfos << "Num images: " << gImageList.getNumImages() << llendl;
05037 llinfos << "Texture usage: " << LLImageGL::sGlobalTextureMemory << llendl;
05038 llinfos << "Texture working set: " << LLImageGL::sBoundTextureMemory << llendl;
05039 llinfos << "Raw usage: " << LLImageRaw::sGlobalRawMemory << llendl;
05040 llinfos << "Formatted usage: " << LLImageFormatted::sGlobalFormattedMemory << llendl;
05041 llinfos << "Zombie Viewer Objects: " << LLViewerObject::getNumZombieObjects() << llendl;
05042 llinfos << "Number of lights: " << gPipeline.getLightCount() << llendl;
05043
05044 llinfos << "Memory Usage:" << llendl;
05045 llinfos << "--------------------------------" << llendl;
05046 llinfos << "Pipeline:" << llendl;
05047 llinfos << llendl;
05048
05049 #if LL_SMARTHEAP
05050 llinfos << "--------------------------------" << llendl;
05051 {
05052 llinfos << "sizeof(LLVOVolume) = " << sizeof(LLVOVolume) << llendl;
05053
05054 U32 total_pool_size = 0;
05055 U32 total_used_size = 0;
05056 MEM_POOL_INFO pool_info;
05057 MEM_POOL_STATUS pool_status;
05058 U32 pool_num = 0;
05059 for(pool_status = MemPoolFirst( &pool_info, 1 );
05060 pool_status != MEM_POOL_END;
05061 pool_status = MemPoolNext( &pool_info, 1 ) )
05062 {
05063 llinfos << "Pool #" << pool_num << llendl;
05064 if( MEM_POOL_OK != pool_status )
05065 {
05066 llwarns << "Pool not ok" << llendl;
05067 continue;
05068 }
05069
05070 llinfos << "Pool blockSizeFS " << pool_info.blockSizeFS
05071 << " pageSize " << pool_info.pageSize
05072 << llendl;
05073
05074 U32 pool_count = MemPoolCount(pool_info.pool);
05075 llinfos << "Blocks " << pool_count << llendl;
05076
05077 U32 pool_size = MemPoolSize( pool_info.pool );
05078 if( pool_size == MEM_ERROR_RET )
05079 {
05080 llinfos << "MemPoolSize() failed (" << pool_num << ")" << llendl;
05081 }
05082 else
05083 {
05084 llinfos << "MemPool Size " << pool_size / 1024 << "K" << llendl;
05085 }
05086
05087 total_pool_size += pool_size;
05088
05089 if( !MemPoolLock( pool_info.pool ) )
05090 {
05091 llinfos << "MemPoolLock failed (" << pool_num << ") " << llendl;
05092 continue;
05093 }
05094
05095 U32 used_size = 0;
05096 MEM_POOL_ENTRY entry;
05097 entry.entry = NULL;
05098 while( MemPoolWalk( pool_info.pool, &entry ) == MEM_POOL_OK )
05099 {
05100 if( entry.isInUse )
05101 {
05102 used_size += entry.size;
05103 }
05104 }
05105
05106 MemPoolUnlock( pool_info.pool );
05107
05108 llinfos << "MemPool Used " << used_size/1024 << "K" << llendl;
05109 total_used_size += used_size;
05110 pool_num++;
05111 }
05112
05113 llinfos << "Total Pool Size " << total_pool_size/1024 << "K" << llendl;
05114 llinfos << "Total Used Size " << total_used_size/1024 << "K" << llendl;
05115
05116 }
05117 #endif
05118
05119 llinfos << "--------------------------------" << llendl;
05120 llinfos << "Avatar Memory (partly overlaps with above stats):" << llendl;
05121 gTexStaticImageList.dumpByteCount();
05122 LLVOAvatar::dumpScratchTextureByteCount();
05123 LLTexLayerSetBuffer::dumpTotalByteCount();
05124 LLVOAvatar::dumpTotalLocalTextureByteCount();
05125 LLTexLayerParamAlpha::dumpCacheByteCount();
05126 LLVOAvatar::dumpBakedStatus();
05127
05128 llinfos << llendl;
05129
05130 llinfos << "Object counts:" << llendl;
05131 S32 i;
05132 S32 obj_counts[256];
05133
05134 for (i = 0; i < 256; i++)
05135 {
05136 obj_counts[i] = 0;
05137 }
05138 for (i = 0; i < gObjectList.getNumObjects(); i++)
05139 {
05140 LLViewerObject *objectp = gObjectList.getObject(i);
05141 if (objectp)
05142 {
05143 obj_counts[objectp->getPCode()]++;
05144 }
05145 }
05146 for (i = 0; i < 256; i++)
05147 {
05148 if (obj_counts[i])
05149 {
05150 llinfos << LLPrimitive::pCodeToString(i) << ":" << obj_counts[i] << llendl;
05151 }
05152 }
05153
05154
05155
05156
05157
05158
05159
05160
05161
05162
05163
05164
05165
05166
05167
05168
05169
05170
05171
05172
05173
05174
05175
05176
05177
05178
05179
05180
05181
05182
05183
05184
05185
05186
05187
05188
05189
05190
05191
05192
05193
05194
05195
05196
05197
05198
05199
05200
05201
05202
05203
05204
05205
05206
05207
05208
05209
05210
05211
05212
05213
05214
05215
05216
05217
05218
05219
05220
05221
05222 }
05223
05224 class ViewerStatsResponder : public LLHTTPClient::Responder
05225 {
05226 public:
05227 ViewerStatsResponder() { }
05228
05229 void error(U32 statusNum, const std::string& reason)
05230 {
05231 llinfos << "ViewerStatsResponder::error " << statusNum << " "
05232 << reason << llendl;
05233 }
05234
05235 void result(const LLSD& content)
05236 {
05237 llinfos << "ViewerStatsResponder::result" << llendl;
05238 }
05239 };
05240
05241
05242
05243
05244
05245
05246
05247
05248
05249
05250 void send_stats()
05251 {
05252
05253
05254
05255
05256
05257
05258 if (!gAgent.getRegion() || gNoRender)
05259 {
05260 return;
05261 }
05262
05263 LLSD body;
05264 std::string url = gAgent.getRegion()->getCapability("ViewerStats");
05265
05266 if (url.empty()) {
05267 llwarns << "Could not get ViewerStats capability" << llendl;
05268 return;
05269 }
05270
05271 body["session_id"] = gAgentSessionID;
05272
05273 LLSD &agent = body["agent"];
05274
05275 time_t ltime;
05276 time(<ime);
05277 F32 run_time = F32(LLFrameTimer::getElapsedSeconds());
05278
05279 agent["start_time"] = ltime - run_time;
05280 agent["run_time"] = run_time;
05281
05282 agent["fps"] = (F32)gForegroundFrameCount / gForegroundTime.getElapsedTimeF32();
05283 agent["version"] = gCurrentVersion;
05284 agent["language"] = gSavedSettings.getString("Language");
05285
05286 agent["sim_fps"] = ((F32) gFrameCount - gSimFrames) /
05287 (F32) (gRenderStartTime.getElapsedTimeF32() - gSimLastTime);
05288
05289 gSimLastTime = gRenderStartTime.getElapsedTimeF32();
05290 gSimFrames = (F32) gFrameCount;
05291
05292 agent["agents_in_view"] = LLVOAvatar::sNumVisibleAvatars;
05293 agent["ping"] = gAvgSimPing;
05294 agent["meters_traveled"] = gAgent.getDistanceTraveled();
05295 agent["regions_visited"] = gAgent.getRegionsVisited();
05296 agent["mem_use"] = getCurrentRSS() / 1024.0;
05297
05298 LLSD &system = body["system"];
05299
05300 system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB();
05301 system["os"] = gSysOS.getOSString();
05302 system["cpu"] = gSysCPU.getCPUString();
05303
05304 std::string gpu_desc = llformat(
05305 "%-6s Class %d ",
05306 gGLManager.mGLVendorShort.substr(0,6).c_str(),
05307 gFeatureManagerp->getGPUClass())
05308 + gFeatureManagerp->getGPUString();
05309
05310 system["gpu"] = gpu_desc;
05311 system["gpu_class"] = gFeatureManagerp->getGPUClass();
05312 system["gpu_vendor"] = gGLManager.mGLVendorShort;
05313 system["gpu_version"] = gGLManager.mDriverVersionVendorString;
05314
05315 LLSD &download = body["downloads"];
05316
05317 download["world_kbytes"] = gTotalWorldBytes / 1024.0;
05318 download["object_kbytes"] = gTotalObjectBytes / 1024.0;
05319 download["texture_kbytes"] = gTotalTextureBytes / 1024.0;
05320
05321 LLSD &in = body["stats"]["net"]["in"];
05322
05323 in["kbytes"] = gMessageSystem->mTotalBytesIn / 1024.0;
05324 in["packets"] = (S32) gMessageSystem->mPacketsIn;
05325 in["compressed_packets"] = (S32) gMessageSystem->mCompressedPacketsIn;
05326 in["savings"] = (gMessageSystem->mUncompressedBytesIn -
05327 gMessageSystem->mCompressedBytesIn) / 1024.0;
05328
05329 LLSD &out = body["stats"]["net"]["out"];
05330
05331 out["kbytes"] = gMessageSystem->mTotalBytesOut / 1024.0;
05332 out["packets"] = (S32) gMessageSystem->mPacketsOut;
05333 out["compressed_packets"] = (S32) gMessageSystem->mCompressedPacketsOut;
05334 out["savings"] = (gMessageSystem->mUncompressedBytesOut -
05335 gMessageSystem->mCompressedBytesOut) / 1024.0;
05336
05337 LLSD &fail = body["stats"]["failures"];
05338
05339 fail["send_packet"] = (S32) gMessageSystem->mSendPacketFailureCount;
05340 fail["dropped"] = (S32) gMessageSystem->mDroppedPackets;
05341 fail["resent"] = (S32) gMessageSystem->mResentPackets;
05342 fail["failed_resends"] = (S32) gMessageSystem->mFailedResendPackets;
05343 fail["off_circuit"] = (S32) gMessageSystem->mOffCircuitPackets;
05344 fail["invalid"] = (S32) gMessageSystem->mInvalidOnCircuitPackets;
05345
05346 gViewerStats->addToMessage(body);
05347
05348 LLHTTPClient::post(url, body, new ViewerStatsResponder());
05349 }
05350
05351 #if !LL_WINDOWS
05352
05353 void signal_handlers(S32 s)
05354 {
05355 release_signals();
05356
05357
05358 if(SIGTERM == s)
05359 {
05360
05361 app_force_quit(NULL);
05362 return;
05363 }
05364
05365 # if LL_LINUX || LL_SOLARIS
05366
05367
05368 llwarns << "*** Caught signal " << s << llendl;
05369 # endif
05370
05371 if (gCrashCallback)
05372 {
05373 gCrashCallback();
05374 }
05375 }
05376 #endif
05377
05378
05379 void catch_signals()
05380 {
05381 #if LL_WINDOWS
05382
05383 LLWinDebug::setupExceptionHandler();
05384 return;
05385 #else
05386
05387
05388
05389
05390 signal(SIGILL, signal_handlers);
05391 signal(SIGTRAP, signal_handlers);
05392 if (being_debugged())
05393 {
05394
05395
05396 signal(SIGABRT, SIG_DFL);
05397 } else {
05398 signal(SIGABRT, signal_handlers);
05399 }
05400 signal(SIGFPE, signal_handlers);
05401 signal(SIGBUS, signal_handlers);
05402 signal(SIGSEGV, signal_handlers);
05403 signal(SIGSYS, signal_handlers);
05404
05405
05406 #if !LL_LINUX && !LL_SOLARIS
05407 signal(SIGEMT, signal_handlers);
05408 #endif
05409
05410
05411 signal(SIGTERM, signal_handlers);
05412
05413 #endif // LL_WINDOWS
05414 }
05415
05416 #if !LL_WINDOWS
05417 void release_signals()
05418 {
05419 signal(SIGTERM, SIG_DFL);
05420 signal(SIGABRT, SIG_DFL);
05421 signal(SIGILL, SIG_DFL);
05422 signal(SIGFPE, SIG_DFL);
05423 signal(SIGSEGV, SIG_DFL);
05424
05425 #ifdef SIGBUS
05426 signal(SIGBUS, SIG_DFL);
05427 #endif
05428
05429 #ifdef SIGSYS
05430 signal(SIGSYS, SIG_DFL);
05431 #endif
05432 }
05433 #endif // !LL_WINDOWS
05434
05435 void purge_cache()
05436 {
05437 llinfos << "Purging Texture Cache..." << llendl;
05438 gTextureCache->purgeCache(LL_PATH_CACHE);
05439 llinfos << "Purging Cache..." << llendl;
05440 std::string mask = gDirUtilp->getDirDelimiter() + "*.*";
05441 gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"").c_str(),mask);
05442 }
05443
05444 int parse_args(int argc, char **argv)
05445 {
05446
05447
05448 LLString ip_string;
05449 S32 j;
05450
05451 for (j = 1; j < argc; j++)
05452 {
05453 gArgs += argv[j];
05454 gArgs += " ";
05455
05456 if ((!strcmp(argv[j], "-port")) && (++j < argc))
05457 {
05458 sscanf(argv[j], "%u", &(gAgent.mViewerPort));
05459 }
05460 else if ((!strcmp(argv[j], "-drop")) && (++j < argc))
05461 {
05462 sscanf(argv[j], "%f", &gPacketDropPercentage);
05463 }
05464 else if ((!strcmp(argv[j], "-inbw")) && (++j < argc))
05465 {
05466 sscanf(argv[j], "%f", &gInBandwidth);
05467 }
05468 else if ((!strcmp(argv[j], "-outbw")) && (++j < argc))
05469 {
05470 sscanf(argv[j], "%f", &gOutBandwidth);
05471 }
05472 else if (!strcmp(argv[j], "--aditi"))
05473 {
05474 gUserServerChoice = USERSERVER_ADITI;
05475 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[gUserServerChoice].mName);
05476 }
05477 else if (!strcmp(argv[j], "--agni"))
05478 {
05479 gUserServerChoice = USERSERVER_AGNI;
05480 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[gUserServerChoice].mName);
05481 }
05482 else if (!strcmp(argv[j], "--dmz"))
05483 {
05484 gUserServerChoice = USERSERVER_DMZ;
05485 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[gUserServerChoice].mName);
05486 }
05487 else if (!strcmp(argv[j], "--siva"))
05488 {
05489 gUserServerChoice = USERSERVER_SIVA;
05490 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[gUserServerChoice].mName);
05491 }
05492 else if (!strcmp(argv[j], "--shakti"))
05493 {
05494 gUserServerChoice = USERSERVER_SHAKTI;
05495 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[gUserServerChoice].mName);
05496 }
05497 else if (!strcmp(argv[j], "--durga"))
05498 {
05499 gUserServerChoice = USERSERVER_DURGA;
05500 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[gUserServerChoice].mName);
05501 }
05502 else if (!strcmp(argv[j], "--soma"))
05503 {
05504 gUserServerChoice = USERSERVER_SOMA;
05505 snprintf(gUserServerName, MAX_STRING, "%s", gUserServerDomainName[gUserServerChoice].mName);
05506 }
05507 else if (!strcmp(argv[j], "--ganga"))
05508 {
05509 gUserServerChoice = USERSERVER_GANGA;
05510 sprintf(gUserServerName,"%s", gUserServerDomainName[gUserServerChoice].mName);
05511 }
05512 else if (!strcmp(argv[j], "--vaak"))
05513 {
05514 gUserServerChoice = USERSERVER_VAAK;
05515 sprintf(gUserServerName,"%s", gUserServerDomainName[gUserServerChoice].mName);
05516 }
05517 else if (!strcmp(argv[j], "--uma"))
05518 {
05519 gUserServerChoice = USERSERVER_UMA;
05520 sprintf(gUserServerName,"%s", gUserServerDomainName[gUserServerChoice].mName);
05521 }
05522 else if (!strcmp(argv[j], "-user") && (++j < argc))
05523 {
05524 if (!strcmp(argv[j], "-"))
05525 {
05526 gUserServerChoice = USERSERVER_LOCAL;
05527 snprintf(gUserServerName, MAX_STRING, "%s", LOOPBACK_ADDRESS_STRING);
05528 }
05529 else
05530 {
05531 gUserServerChoice = USERSERVER_OTHER;
05532 ip_string.assign( argv[j] );
05533 LLString::trim(ip_string);
05534 snprintf(gUserServerName, MAX_STRING, "%s", ip_string.c_str());
05535 }
05536 }
05537 else if (!strcmp(argv[j], "-loginuri") && (++j < argc))
05538 {
05539 gLoginURIs.push_back(utf8str_trim(argv[j]));
05540 }
05541 else if (!strcmp(argv[j], "-helperuri") && (++j < argc))
05542 {
05543 gHelperURI = argv[j];
05544 gHelperURI = utf8str_trim(gHelperURI);
05545 }
05546 else if (!strcmp(argv[j], "-debugviews"))
05547 {
05548 LLView::sDebugRects = TRUE;
05549 }
05550 else if (!strcmp(argv[j], "-skin") && (++j < argc))
05551 {
05552 std::string folder(argv[j]);
05553 gDirUtilp->setSkinFolder(folder);
05554 }
05555 else if (!strcmp(argv[j], "-autologin") || !strcmp(argv[j], "--autologin"))
05556 {
05557 gAutoLogin = TRUE;
05558 }
05559 else if (!strcmp(argv[j], "-quitafter") && (++j < argc))
05560 {
05561 gQuitAfterSeconds = (F32)atof(argv[j]);
05562 }
05563 else if (!strcmp(argv[j], "-rotate"))
05564 {
05565 gRotateRight = TRUE;
05566 }
05567
05568
05569
05570
05571
05572 else if (!strcmp(argv[j], "-noaudio"))
05573 {
05574 gUseAudio = FALSE;
05575 }
05576 else if (!strcmp(argv[j], "-nosound"))
05577 {
05578 gUseAudio = FALSE;
05579 }
05580 else if (!strcmp(argv[j], "-nofmod"))
05581 {
05582 gUseFMOD = FALSE;
05583 }
05584 else if (!strcmp(argv[j], "-noprobe"))
05585 {
05586 gProbeHardware = FALSE;
05587 }
05588 else if (!strcmp(argv[j], "-noquicktime"))
05589 {
05590
05591
05592 gUseQuickTime = false;
05593 }
05594 else if (!strcmp(argv[j], "-nopreload"))
05595 {
05596
05597
05598 gPreloadSounds = false;
05599 gPreloadImages = false;
05600 }
05601 else if (!strcmp(argv[j], "-purge"))
05602 {
05603 purge_cache();
05604 }
05605 else if(!strcmp(argv[j], "-noinvlib"))
05606 {
05607 gRequestInventoryLibrary = FALSE;
05608 }
05609 else if (!strcmp(argv[j], "-log"))
05610 {
05611 gLogMessages = TRUE;
05612 continue;
05613 }
05614 else if (!strcmp(argv[j], "-logfile") && (++j < argc))
05615 {
05616
05617 char logfile[256];
05618 sscanf(argv[j], "%255s", logfile);
05619 llinfos << "Setting log file to " << logfile << llendl;
05620 LLFile::remove(logfile);
05621 LLError::logToFile(logfile);
05622 }
05623 else if (!strcmp(argv[j], "-settings") && (++j < argc))
05624 {
05625 gSettingsFileName = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, argv[j]);
05626 }
05627 else if (!strcmp(argv[j], "-setdefault") && (j + 2 < argc))
05628 {
05629 std::string control_name;
05630 std::string control_value;
05631
05632 j++;
05633 if (argv[j]) control_name = std::string(argv[j]);
05634
05635 j++;
05636 if (argv[j]) control_value = std::string(argv[j]);
05637
05638
05639 if (!control_name.empty())
05640 {
05641 gCommandLineSettings[control_name] = control_value;
05642 }
05643 }
05644 else if (!strcmp(argv[j], "-set") && (j + 2 < argc))
05645 {
05646 std::string control_name;
05647 std::string control_value;
05648
05649 j++;
05650 if (argv[j]) control_name = std::string(argv[j]);
05651
05652 j++;
05653 if (argv[j]) control_value = std::string(argv[j]);
05654
05655
05656 if (!control_name.empty())
05657 {
05658 gCommandLineForcedSettings[control_name] = control_value;
05659 }
05660 }
05661 else if (!strcmp(argv[j], "-login"))
05662 {
05663 if (j + 3 < argc)
05664 {
05665 j++;
05666 gCmdLineFirstName = argv[j];
05667 j++;
05668 gCmdLineLastName = argv[j];
05669 j++;
05670 gCmdLinePassword = argv[j];
05671 }
05672 else
05673 {
05674
05675 llerrs << "Not enough parameters to -login. Did you mean -loginuri?" << llendl;
05676 }
05677 }
05678 else if (!strcmp(argv[j], "-god"))
05679 {
05680 gGodConnect = TRUE;
05681 }
05682 else if (!strcmp(argv[j], "-noconsole"))
05683 {
05684 gUseConsole = FALSE;
05685 }
05686 else if (!strcmp(argv[j], "-safe"))
05687 {
05688 llinfos << "Setting viewer feature table to run in safe mode, resetting prefs" << llendl;
05689 gFeatureManagerp->setSafe(TRUE);
05690 }
05691 else if (!strcmp(argv[j], "-multiple"))
05692 {
05693 gMultipleViewersOK = TRUE;
05694 }
05695 else if (!strcmp(argv[j], "-nomultiple"))
05696 {
05697 gMultipleViewersOK = FALSE;
05698 }
05699 else if (!strcmp(argv[j], "-novoice"))
05700 {
05701 gDisableVoice = TRUE;
05702 }
05703 else if (!strcmp(argv[j], "-nothread"))
05704 {
05705 LLVFile::ALLOW_ASYNC = FALSE;
05706 llinfos << "Running VFS in nothread mode" << llendl;
05707 }
05708
05709
05710 else if (LLURLDispatcher::isSLURL(argv[j])
05711 || !strcmp(argv[j], "-url") && (++j < argc))
05712 {
05713 std::string slurl = argv[j];
05714 if (LLURLDispatcher::isSLURLCommand(slurl))
05715 {
05716 LLStartUp::sSLURLCommand = slurl;
05717 }
05718 else
05719 {
05720 LLURLSimString::setString(slurl);
05721 }
05722
05723
05724
05725
05726 gArgs += argv[j];
05727 return 0;
05728 }
05729 else if (!strcmp(argv[j], "-ignorepixeldepth"))
05730 {
05731 gIgnorePixelDepth = TRUE;
05732 }
05733 else if (!strcmp(argv[j], "-cooperative"))
05734 {
05735 S32 ms_to_yield = 0;
05736 if(++j < argc)
05737 {
05738 S32 rv = sscanf(argv[j], "%d", &ms_to_yield);
05739 if(0 == rv)
05740 {
05741 --j;
05742 }
05743 }
05744 else
05745 {
05746 --j;
05747 }
05748 gYieldMS = ms_to_yield;
05749 gYieldTime = TRUE;
05750 }
05751 else if (!strncmp(argv[j], "-lang", 5))
05752 {
05753 j++;
05754 if (argv[j])
05755 gSavedSettings.setString("Language", std::string(argv[j]));
05756 }
05757 else if (!strcmp(argv[j], "-no-verify-ssl-cert"))
05758 {
05759 gVerifySSLCert = false;
05760 }
05761 else if ( (!strcmp(argv[j], "--channel") || !strcmp(argv[j], "-channel")) && (++j < argc))
05762 {
05763 gChannelName = argv[j];
05764 }
05765 #if LL_DARWIN
05766 else if (!strncmp(argv[j], "-psn_", 5))
05767 {
05768
05769
05770 }
05771 #endif
05772 else
05773 {
05774
05775
05776
05777 llwarns << "Possible unknown keyword " << argv[j] << llendl;
05778
05779
05780 llinfos << USAGE << llendl;
05781
05782 }
05783 }
05784 return 0;
05785 }
05786
05787
05788
05789 void load_name_cache()
05790 {
05791 if (!gCacheName) return;
05792
05793 std::string name_cache;
05794 name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache");
05795 FILE* name_cache_fp = LLFile::fopen(name_cache.c_str(), "r");
05796 if (name_cache_fp)
05797 {
05798 gCacheName->importFile(name_cache_fp);
05799 fclose(name_cache_fp);
05800 }
05801 }
05802
05803 void save_name_cache()
05804 {
05805 if (!gCacheName) return;
05806
05807 std::string name_cache;
05808 name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache");
05809 FILE* name_cache_fp = LLFile::fopen(name_cache.c_str(), "w");
05810 if (name_cache_fp)
05811 {
05812 gCacheName->exportFile(name_cache_fp);
05813 fclose(name_cache_fp);
05814 }
05815 }
05816
05817 void load_region_name_cache()
05818 {
05819 if (!gCacheName) return;
05820
05821
05822 gRegionNameCache->importFile(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "region_names.xml"), true);
05823 gRegionNameCache->importFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "region_names.xml"), false);
05824 }
05825
05826 void save_region_name_cache()
05827 {
05828 if (!gCacheName) return;
05829
05830 std::string name_cache;
05831 name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "region_names.xml");
05832 gRegionNameCache->exportFile(name_cache);
05833 }
05834
05835
05836 void login_alert_done(S32 option, void* user_data)
05837 {
05838 LLPanelLogin::giveFocus();
05839 }
05840
05841 void disconnect_viewer(void *)
05842 {
05843 if (gDisconnected)
05844 {
05845 return;
05846 }
05847
05848
05849
05850
05851
05852 llinfos << "Disconnecting viewer!" << llendl;
05853
05854
05855 gFrameStats.dump();
05856
05857
05858
05859 #if !LL_WINDOWS
05860 release_signals();
05861 #endif
05862
05863
05864 gSavedSettings.setBOOL("FlyingAtExit", gAgent.getFlying() );
05865
05866
05867 if (!gNoRender)
05868 {
05869 if (gFloaterView)
05870 {
05871 gFloaterView->restoreAll();
05872 }
05873 }
05874
05875 if (gSelectMgr)
05876 {
05877 gSelectMgr->deselectAll();
05878 }
05879
05880 if (!gNoRender)
05881 {
05882
05883 gInventory.cache(gAgent.getInventoryRootID(), gAgent.getID());
05884 if(gInventoryLibraryRoot.notNull() && gInventoryLibraryOwner.notNull())
05885 {
05886 gInventory.cache(gInventoryLibraryRoot, gInventoryLibraryOwner);
05887 }
05888 }
05889
05890 save_name_cache();
05891 save_region_name_cache();
05892
05893
05894 LLInventoryView::cleanup();
05895
05896
05897 user_logout();
05898
05899
05900
05901
05902 gAgent.cleanup();
05903
05904 gObjectList.destroy();
05905 delete gWorldp;
05906 gWorldp = NULL;
05907
05908 cleanup_xfer_manager();
05909 gDisconnected = TRUE;
05910 }
05911
05912
05913 void remove_cache_files(const char* file_mask)
05914 {
05915 char mask[LL_MAX_PATH];
05916 snprintf(mask, LL_MAX_PATH, "%s%s", gDirUtilp->getDirDelimiter().c_str(), file_mask);
05917 gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "").c_str(), mask);
05918 }
05919
05920
05921
05922
05923 void finish_early_exit(S32 option, void* userdata)
05924 {
05925 app_force_quit(NULL);
05926 }
05927
05928 void app_early_exit(const LLString& mesg)
05929 {
05930 llwarns << "app_early_exit: " << mesg << llendl;
05931 gDoDisconnect = TRUE;
05932
05933
05934
05935 LLAlertDialog::showCritical(mesg, finish_early_exit, NULL);
05936 }
05937
05938
05939 void app_force_exit(S32 arg)
05940 {
05941 remove_marker_file();
05942 exit(arg);
05943 }
05944
05945
05946 void finish_disconnect(S32 option, void* userdata)
05947 {
05948 if (1 == option)
05949 {
05950 app_force_quit(NULL);
05951 }
05952 }
05953
05954
05955 void finish_forced_disconnect(S32 , void* )
05956 {
05957 app_force_quit(NULL);
05958 }
05959
05960 void send_logout_request()
05961 {
05962 if(!gLogoutRequestSent)
05963 {
05964 LLMessageSystem* msg = gMessageSystem;
05965 msg->newMessageFast(_PREHASH_LogoutRequest);
05966 msg->nextBlockFast(_PREHASH_AgentData);
05967 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
05968 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
05969 gAgent.sendReliableMessage();
05970
05971 gLogoutTimer.reset();
05972 gLogoutMaxTime = LOGOUT_REQUEST_TIME;
05973 gLogoutRequestSent = TRUE;
05974
05975 gVoiceClient->leaveChannel();
05976 }
05977 }
05978
05979 void do_disconnect(const LLString& mesg)
05980 {
05981 if (gDoDisconnect)
05982 {
05983
05984
05985 return;
05986 }
05987
05988
05989 LLString big_reason = LLAgent::sTeleportErrorMessages[mesg];
05990 if ( big_reason.size() == 0 )
05991 {
05992 big_reason = mesg;
05993 }
05994
05995 LLStringBase<char>::format_map_t args;
05996 gDoDisconnect = TRUE;
05997
05998 if (LLStartUp::getStartupState() < STATE_STARTED)
05999 {
06000
06001 args["[ERROR_MESSAGE]"] = big_reason;
06002 gViewerWindow->alertXml("ErrorMessage", args, finish_forced_disconnect);
06003 }
06004 else
06005 {
06006 args["[MESSAGE]"] = big_reason;
06007 gViewerWindow->alertXml("YouHaveBeenLoggedOut", args, finish_disconnect );
06008 }
06009 }
06010
06011 const LLUUID& agent_get_id()
06012 {
06013 return gAgent.getID();
06014 }
06015
06016 const LLUUID& agent_get_session_id()
06017 {
06018 return gAgent.getSessionID();
06019 }
06020
06021 void agent_send_reliable_message()
06022 {
06023 gAgent.sendReliableMessage();
06024 }
06025
06026 void bad_network_handler()
06027 {
06028
06029 gMessageSystem->dumpPacketToLog();
06030
06031
06032
06033
06034 gPurgeOnExit = TRUE;
06035
06036 #if LL_WINDOWS
06037 LLWinDebug::handleException(NULL);
06038 #else
06039
06040 if (gCrashCallback)
06041 {
06042 gCrashCallback();
06043 }
06044 #endif
06045
06046 std::ostringstream message;
06047 message <<
06048 "The viewer has detected mangled network data indicative\n"
06049 "of a bad upstream network connection or an incomplete\n"
06050 "local installation of " << gSecondLife << ". \n"
06051 " \n"
06052 "Try uninstalling and reinstalling to see if this resolves \n"
06053 "the issue. \n"
06054 " \n"
06055 "If the problem continues, see the Tech Support FAQ at: \n"
06056 "www.secondlife.com/support";
06057 do_disconnect(message.str());
06058 }
06059
06060
06061
06062 void save_avatar(void*)
06063 {
06064 LLFloaterSaveAvatar::show();
06065 }
06066
06067 void cleanup_app()
06068 {
06069
06070
06071 LLMortician::setZealous(TRUE);
06072
06073 LLVoiceClient::terminate();
06074
06075 disconnect_viewer(NULL);
06076
06077 llinfos << "Viewer disconnected" << llendflush;
06078
06079 gDisconnectedImagep = NULL;
06080 release_start_screen();
06081
06082 LLError::logToFixedBuffer(NULL);
06083
06084 llinfos << "Cleaning Up" << llendflush;
06085
06086 LLKeyframeDataCache::clear();
06087
06088
06089 LLHUDObject::cleanupHUDObjects();
06090 llinfos << "HUD Objects cleaned up" << llendflush;
06091
06092
06093 #if 0 // this seems to get us stuck in an infinite loop...
06094 gTransferManager.cleanup();
06095 #endif
06096
06097
06098 delete gWorldMap;
06099 gWorldMap = NULL;
06100
06101 delete gHUDManager;
06102 gHUDManager = NULL;
06103
06104 delete gToolMgr;
06105 gToolMgr = NULL;
06106
06107 delete gAssetStorage;
06108 gAssetStorage = NULL;
06109
06110 LLPolyMesh::freeAllMeshes();
06111
06112 delete gCacheName;
06113 gCacheName = NULL;
06114
06115 delete gGlobalEconomy;
06116 gGlobalEconomy = NULL;
06117
06118 delete gLocalSpeakerMgr;
06119 gLocalSpeakerMgr = NULL;
06120
06121 LLNotifyBox::cleanup();
06122
06123 llinfos << "Global stuff deleted" << llendflush;
06124
06125 #if !LL_RELEASE_FOR_DOWNLOAD
06126 if (gAudiop)
06127 {
06128 gAudiop->shutdown();
06129 }
06130 #else
06131
06132
06133 llwarns << "Hack, skipping audio engine cleanup" << llendflush;
06134 #endif
06135
06136
06137
06138
06139
06140 LLMediaEngine::cleanupClass();
06141
06142 #if LL_QUICKTIME_ENABLED
06143 if (gQuickTimeInitialized)
06144 {
06145
06146 llinfos << "Cleaning up QuickTime" << llendl;
06147 ExitMovies ();
06148 #if LL_WINDOWS
06149
06150 TerminateQTML ();
06151 #endif
06152 }
06153 llinfos << "Quicktime cleaned up" << llendflush;
06154 #endif
06155
06156 #if LL_GSTREAMER_ENABLED
06157 llinfos << "Cleaning up GStreamer" << llendl;
06158 UnloadGStreamer();
06159 llinfos << "GStreamer cleaned up" << llendflush;
06160 #endif
06161
06162 llinfos << "Cleaning up feature manager" << llendflush;
06163 delete gFeatureManagerp;
06164 gFeatureManagerp = NULL;
06165
06166
06167
06168
06169
06170 cleanup_saved_settings();
06171 llinfos << "Settings patched up" << llendflush;
06172
06173 delete gAudiop;
06174 gAudiop = NULL;
06175
06176
06177 remove_cache_files("*.wav");
06178 remove_cache_files("*.tmp");
06179 remove_cache_files("*.lso");
06180 remove_cache_files("*.out");
06181 remove_cache_files("*.dsf");
06182 remove_cache_files("*.bodypart");
06183 remove_cache_files("*.clothing");
06184
06185 llinfos << "Cache files removed" << llendflush;
06186
06187
06188 cleanup_menus();
06189
06190
06191 while (1)
06192 {
06193 S32 pending = LLVFSThread::updateClass(0);
06194 pending += LLLFSThread::updateClass(0);
06195 if (!pending)
06196 {
06197 break;
06198 }
06199 llinfos << "Waiting for pending IO to finish: " << pending << llendflush;
06200 ms_sleep(100);
06201 }
06202 llinfos << "Shutting down." << llendflush;
06203
06204
06205
06206
06207 delete gViewerWindow;
06208 gViewerWindow = NULL;
06209 llinfos << "ViewerWindow deleted" << llendflush;
06210
06211
06212 delete gKeyboard;
06213 gKeyboard = NULL;
06214
06215
06216
06217 LLSelectMgr::cleanupGlobals();
06218
06219 LLViewerObject::cleanupVOClasses();
06220
06221 LLTracker::cleanupInstance();
06222
06223 #if LL_LIBXUL_ENABLED
06224
06225
06226 LLMozLib::getInstance()->reset();
06227 #endif
06228
06229 #if LL_WINDOWS
06230 gDXHardware.cleanup();
06231 #endif // LL_WINDOWS
06232
06233 #if LL_WINDOWS && LL_LCD_COMPILE
06234
06235 delete gLcdScreen;
06236 #endif
06237
06238 if (!gVolumeMgr->cleanup())
06239 {
06240 llwarns << "Remaining references in the volume manager!" << llendflush;
06241 }
06242
06243 LLViewerParcelMgr::cleanupGlobals();
06244
06245 delete gViewerStats;
06246 gViewerStats = NULL;
06247
06248 end_messaging_system();
06249
06250 LLFollowCamMgr::cleanupClass();
06251 LLVolumeMgr::cleanupClass();
06252 LLWorldMapView::cleanupClass();
06253 LLUI::cleanupClass();
06254
06255
06256
06257
06258
06259
06260 LLVFile::cleanupClass();
06261 llinfos << "VFS cleaned up" << llendflush;
06262
06263
06264 gSavedPerAccountSettings.setU32("LastLogoff", time_corrected());
06265
06266
06267
06268 gSavedSettings.saveToFile(gSettingsFileName, TRUE);
06269 if (!gPerAccountSettingsFileName.empty())
06270 {
06271 gSavedPerAccountSettings.saveToFile(gPerAccountSettingsFileName, TRUE);
06272 }
06273 llinfos << "Saved settings" << llendflush;
06274
06275 std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE);
06276
06277 gCrashSettings.saveToFile(crash_settings_filename.c_str(), FALSE);
06278
06279 delete gUICtrlFactory;
06280 gUICtrlFactory = NULL;
06281
06282 gSavedSettings.cleanup();
06283 gViewerArt.cleanup();
06284 gColors.cleanup();
06285 gCrashSettings.cleanup();
06286
06287 if (gMuteListp)
06288 {
06289
06290 gMuteListp->cache(gAgent.getID());
06291
06292 delete gMuteListp;
06293 gMuteListp = NULL;
06294 }
06295
06296 if (gPurgeOnExit)
06297 {
06298 llinfos << "Purging all cache files on exit" << llendflush;
06299 char mask[LL_MAX_PATH];
06300 snprintf(mask, LL_MAX_PATH, "%s*.*", gDirUtilp->getDirDelimiter().c_str());
06301 gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"").c_str(),mask);
06302 }
06303
06304 remove_marker_file();
06305
06306 close_debug();
06307
06308
06309 LLTimer idleTimer;
06310 idleTimer.reset();
06311 const F64 max_idle_time = 5.f;
06312 while(1)
06313 {
06314 S32 pending = 0;
06315 pending += gTextureCache->update(1);
06316 pending += gImageDecodeThread->update(1);
06317 pending += gTextureFetch->update(1);
06318 pending += LLVFSThread::updateClass(0);
06319 pending += LLLFSThread::updateClass(0);
06320 F64 idle_time = idleTimer.getElapsedTimeF64();
06321 if (!pending || idle_time >= max_idle_time)
06322 {
06323 llwarns << "Quitting with pending background tasks." << llendl;
06324 break;
06325 }
06326 }
06327
06328
06329
06330 gTextureCache->shutdown();
06331 gTextureFetch->shutdown();
06332 gImageDecodeThread->shutdown();
06333 delete gTextureCache;
06334 delete gTextureFetch;
06335 delete gImageDecodeThread;
06336
06337 gImageList.shutdown();
06338
06339
06340 LLImageJ2C::closeDSO();
06341 LLImageFormatted::cleanupClass();
06342 LLVFSThread::cleanupClass();
06343 LLLFSThread::cleanupClass();
06344
06345 llinfos << "VFS Thread finished" << llendflush;
06346
06347 #ifndef LL_RELEASE_FOR_DOWNLOAD
06348 llinfos << "Auditing VFS" << llendl;
06349 gVFS->audit();
06350 #endif
06351
06352
06353
06354 delete gStaticVFS;
06355 gStaticVFS = NULL;
06356 delete gVFS;
06357 gVFS = NULL;
06358
06359 LLCurl::cleanup();
06360
06361
06362 LLCommon::cleanupClass();
06363
06364 end_messaging_system();
06365 }
06366
06367
06368 void resetURIs()
06369 {
06370 gLoginURIs.clear();
06371 gHelperURI.clear();
06372 }
06373
06374 const std::vector<std::string>& getLoginURIs()
06375 {
06376 if (gLoginURIs.empty())
06377 {
06378
06379 gLoginURIs = LLSRV::rewriteURI(gUserServerDomainName[gUserServerChoice].mLoginURI);
06380 }
06381 return gLoginURIs;
06382 }
06383
06384 const std::string& getHelperURI()
06385 {
06386 if (gHelperURI.empty())
06387 {
06388
06389 gHelperURI = gUserServerDomainName[gUserServerChoice].mHelperURI;
06390 }
06391 return gHelperURI;
06392 }
06393
06394 void errorCallback(const std::string &error_string)
06395 {
06396 #ifndef LL_RELEASE_FOR_DOWNLOAD
06397 OSMessageBox(error_string.c_str(), "Fatal Error", OSMB_OK);
06398 #endif
06399 LLError::crashAndLoop(error_string);
06400 }
06401
06402