////////////////////////////////////////////////////////// // // PostRunWatchDogs // // // ////////////////////////////////////////////////////////// void PostRunWatchDogs ( int iReturnCode ) { if ( iReturnCode == 0 ) { WatchDogClearCounter ( "CR1" ); WatchDogCompletedSection ( "L0" ); } }
//////////////////////////////////////////////// // // Hook CCore::OnPostCreateDevice // // Wrap device or log failure // //////////////////////////////////////////////// HRESULT CCore::OnPostCreateDevice(HRESULT hResult, IDirect3D9* pDirect3D, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface) { if (!UsingAltD3DSetup()) return D3D_OK; // // - Allow create device with no changes // - Check caps and report diff with GTA caps // - Release device // WriteDebugEvent("CCore::OnPostCreateDevice - Alt startup used"); if (hResult != D3D_OK) WriteDebugEvent(SString("Initial CreateDevice failed: %08x", hResult)); else WriteDebugEvent("Initial CreateDevice succeeded"); AddCapsReport(Adapter, pDirect3D, *ppReturnedDeviceInterface, false); SAFE_RELEASE(*ppReturnedDeviceInterface); // // - Create device with required changes // - Check caps and report diff with GTA caps // - Fix GTA caps if needed // // Save original values for later BehaviorFlagsOrig = BehaviorFlags; presentationParametersOrig = *pPresentationParameters; WriteDebugEvent(" Original paramters:"); WriteDebugEvent(ToString(Adapter, DeviceType, hFocusWindow, BehaviorFlags, *pPresentationParameters)); // Make sure DirectX Get...() calls will work BehaviorFlags &= ~D3DCREATE_PUREDEVICE; // Enable the auto depth stencil parameter pPresentationParameters->EnableAutoDepthStencil = true; GetVideoModeManager()->PreCreateDevice(pPresentationParameters); WriteDebugEvent(" Modified paramters:"); WriteDebugEvent(ToString(Adapter, DeviceType, hFocusWindow, BehaviorFlags, *pPresentationParameters)); hResult = CreateDeviceInsist(2, 1000, pDirect3D, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); if (hResult != D3D_OK) WriteDebugEvent(SString("MTA CreateDevice failed: %08x", hResult)); else WriteDebugEvent("MTA CreateDevice succeeded"); AddCapsReport(Adapter, pDirect3D, *ppReturnedDeviceInterface, true); // Change the window title to MTA: San Andreas #ifdef MTA_DEBUG SetWindowTextW(hFocusWindow, MbUTF8ToUTF16("MTA: San Andreas [DEBUG]").c_str()); #else SetWindowTextW(hFocusWindow, MbUTF8ToUTF16("MTA: San Andreas").c_str()); #endif // Log graphic card name D3DADAPTER_IDENTIFIER9 AdapterIdent; pDirect3D->GetAdapterIdentifier(Adapter, 0, &AdapterIdent); WriteDebugEvent(ToString(AdapterIdent)); // Store the rendering window in the direct 3d data CDirect3DData::GetSingleton().StoreDeviceWindow(pPresentationParameters->hDeviceWindow); // Apply input hook CMessageLoopHook::GetSingleton().ApplyHook(hFocusWindow); // Make sure the object was created successfully. if (hResult == D3D_OK) { WriteDebugEvent("CreateDevice succeeded"); GetVideoModeManager()->PostCreateDevice(*ppReturnedDeviceInterface, pPresentationParameters); // We must first store the presentation values. CDirect3DData::GetSingleton().StoreViewport(0, 0, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight); // Calc and store readable depth format for shader use ERenderFormat ReadableDepthFormat = CDirect3DEvents9::DiscoverReadableDepthFormat(*ppReturnedDeviceInterface, pPresentationParameters->MultiSampleType, pPresentationParameters->Windowed != 0); CGraphics::GetSingleton().GetRenderItemManager()->SetDepthBufferFormat(ReadableDepthFormat); // Now create the proxy device. *ppReturnedDeviceInterface = new CProxyDirect3DDevice9(*ppReturnedDeviceInterface); // Debug output D3DDEVICE_CREATION_PARAMETERS parameters; (*ppReturnedDeviceInterface)->GetCreationParameters(¶meters); WriteDebugEvent(" Used creation parameters:"); WriteDebugEvent(SString(" Adapter:%d DeviceType:%d BehaviorFlags:0x%x ReadableDepth:%s", parameters.AdapterOrdinal, parameters.DeviceType, parameters.BehaviorFlags, ReadableDepthFormat ? std::string((char*)&ReadableDepthFormat, 4).c_str() : "None")); } bool bDetectOptimus = (GetModuleHandle("nvd3d9wrap.dll") != NULL); // Calc log level to use uint uiDiagnosticLogLevel = 0; if (GetApplicationSettingInt("nvhacks", "optimus") || bDetectOptimus) uiDiagnosticLogLevel = 1; // Log and continue if (hResult != D3D_OK) uiDiagnosticLogLevel = 2; // Log and wait - If fail status // Do diagnostic log now if needed if (uiDiagnosticLogLevel) { // Prevent statup warning in loader WatchDogCompletedSection("L3"); // Run diagnostic CCore::GetSingleton().GetNetwork()->ResetStub('dia3', *ms_strExtraLogBuffer, uiDiagnosticLogLevel); } ms_strExtraLogBuffer.clear(); // Handle fatal error if (hResult != D3D_OK) { // Inform user SString strMessage; strMessage += "There was a problem starting MTA:SA\n\n"; strMessage += SString("Direct3D CreateDevice error: %08x", hResult); BrowseToSolution("d3dcreatedevice-fail", EXIT_GAME_FIRST | ASK_GO_ONLINE, strMessage); } return hResult; }
//////////////////////////////////////////////// // // HandleCreateDeviceResult // // Log result and possibly fix everything // //////////////////////////////////////////////// HRESULT HandleCreateDeviceResult(HRESULT hResult, IDirect3D9* pDirect3D, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface) { // Log graphic card name D3DADAPTER_IDENTIFIER9 AdapterIdent; pDirect3D->GetAdapterIdentifier(Adapter, 0, &AdapterIdent); WriteDebugEvent(ToString(AdapterIdent)); uint uiCurrentStatus = 0; // 0-unknown 1-fail 2-success after retry 3-success if (hResult == D3D_OK) { // Log success and creation parameters WriteDebugEvent("CreateDevice success"); uiCurrentStatus = CREATE_DEVICE_SUCCESS; WriteDebugEvent(ToString(Adapter, DeviceType, hFocusWindow, BehaviorFlags, *pPresentationParameters)); } if (hResult != D3D_OK) { // Handle failure of initial create device call WriteDebugEvent(SString("CreateDevice failed #0: %08x", hResult)); // Try create device again hResult = DoCreateDevice(pDirect3D, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); // Handle retry result if (hResult != D3D_OK) { WriteDebugEvent("--CreateDevice failed after retry"); uiCurrentStatus = CREATE_DEVICE_FAIL; } else { WriteDebugEvent("++CreateDevice succeeded after retry"); uiCurrentStatus = CREATE_DEVICE_RETRY_SUCCESS; // Apply input hook CMessageLoopHook::GetSingleton().ApplyHook(hFocusWindow); GetVideoModeManager()->PostCreateDevice(*ppReturnedDeviceInterface, pPresentationParameters); // We must first store the presentation values. CDirect3DData::GetSingleton().StoreViewport(0, 0, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight); // Calc and store readable depth format for shader use ERenderFormat ReadableDepthFormat = CDirect3DEvents9::DiscoverReadableDepthFormat( *ppReturnedDeviceInterface, pPresentationParameters->MultiSampleType, pPresentationParameters->Windowed != 0); CGraphics::GetSingleton().GetRenderItemManager()->SetDepthBufferFormat(ReadableDepthFormat); // Now create the proxy device. *ppReturnedDeviceInterface = new CProxyDirect3DDevice9(*ppReturnedDeviceInterface); // Debug output D3DDEVICE_CREATION_PARAMETERS parameters; (*ppReturnedDeviceInterface)->GetCreationParameters(¶meters); WriteDebugEvent(SString(" Adapter:%d DeviceType:%d BehaviorFlags:0x%x ReadableDepth:%s", parameters.AdapterOrdinal, parameters.DeviceType, parameters.BehaviorFlags, ReadableDepthFormat ? std::string((char*)&ReadableDepthFormat, 4).c_str() : "None")); } } uint uiLastStatus = GetApplicationSettingInt("diagnostics", "createdevice-last-status"); SetApplicationSettingInt("diagnostics", "createdevice-last-status", uiCurrentStatus); // Calc log level to use uint uiDiagnosticLogLevel = 0; if (uiLastStatus == CREATE_DEVICE_FAIL && uiCurrentStatus != CREATE_DEVICE_FAIL) uiDiagnosticLogLevel = 1; // Log and continue - If changing from fail status if (uiCurrentStatus == CREATE_DEVICE_FAIL) uiDiagnosticLogLevel = 2; // Log and wait - If fail status bool bDetectOptimus = (GetModuleHandle("nvd3d9wrap.dll") != NULL); bool bFixCaps = false; if (GetApplicationSettingInt("nvhacks", "optimus") || bDetectOptimus) { bFixCaps = true; if (uiDiagnosticLogLevel == 0) uiDiagnosticLogLevel = 1; } AddCapsReport(Adapter, pDirect3D, *ppReturnedDeviceInterface, bFixCaps); if (uiDiagnosticLogLevel) { // Prevent statup warning in loader WatchDogCompletedSection("L3"); CCore::GetSingleton().GetNetwork()->ResetStub('dia3', *ms_strExtraLogBuffer, uiDiagnosticLogLevel); } ms_strExtraLogBuffer.clear(); if (hResult != D3D_OK) { // Handle fatal error SString strMessage; strMessage += "There was a problem starting MTA:SA\n\n"; strMessage += SString("Direct3D CreateDevice error: %08x", hResult); BrowseToSolution("d3dcreatedevice-fail", EXIT_GAME_FIRST | ASK_GO_ONLINE, strMessage); } return hResult; }
////////////////////////////////////////////////////////// // // PreLaunchWatchDogs // // // ////////////////////////////////////////////////////////// void PreLaunchWatchDogs ( void ) { assert ( !CreateSingleInstanceMutex () ); // // "L0" is opened before the launch sequence and is closed if MTA shutsdown with no error // "L1" is opened before the launch sequence and is closed if GTA is succesfully started // "CR1" is a counter which is incremented if GTA was not started and MTA shutsdown with an error // // "L2" is opened before the launch sequence and is closed if the GTA loading screen is shown // "CR2" is a counter which is incremented at startup, if the previous run didn't make it to the loading screen // // "L3" is opened before the launch sequence and is closed if the GTA loading screen is shown, or a startup problem is handled elsewhere // // Check for unclean stop on previous run #ifndef MTA_DEBUG if ( WatchDogIsSectionOpen ( "L0" ) ) WatchDogSetUncleanStop ( true ); // Flag to maybe do things differently if MTA exit code on last run was not 0 else #endif WatchDogSetUncleanStop ( false ); SString strCrashFlagFilename = CalcMTASAPath( "mta\\core.log.flag" ); if ( FileExists( strCrashFlagFilename ) ) { FileDelete( strCrashFlagFilename ); WatchDogSetLastRunCrash( true ); // Flag to maybe do things differently if MTA crashed last run } else WatchDogSetLastRunCrash( false ); // Reset counter if gta game was run last time if ( !WatchDogIsSectionOpen ( "L1" ) ) WatchDogClearCounter ( "CR1" ); // If crashed 3 times in a row before starting the game, do something if ( WatchDogGetCounter ( "CR1" ) >= 3 ) { WatchDogReset (); HandleTrouble (); } // Check for possible gta_sa.set problems if ( WatchDogIsSectionOpen ( "L2" ) ) { WatchDogIncCounter ( "CR2" ); // Did not reach loading screen last time WatchDogCompletedSection ( "L2" ); } else WatchDogClearCounter ( "CR2" ); // If didn't reach loading screen 5 times in a row, do something if ( WatchDogGetCounter ( "CR2" ) >= 5 ) { WatchDogClearCounter ( "CR2" ); HandleResetSettings (); } // Clear down freeze on quit detection WatchDogCompletedSection( "Q0" ); WatchDogBeginSection ( "L0" ); // Gets closed if MTA exits with a return code of 0 WatchDogBeginSection ( "L1" ); // Gets closed when online game has started SetApplicationSetting ( "diagnostics", "gta-fopen-fail", "" ); SetApplicationSetting ( "diagnostics", "last-crash-reason", "" ); SetApplicationSetting ( "diagnostics", "gta-fopen-last", "" ); }
/////////////////////////////////////////////////////////////// // // CModelCacheManagerImpl::PreLoad // // Cache all weapons and upgrades // // Peds KB: 64,832 KB 7-312 306 296 valid, 10 not so valid 219 KB/model 4.45/MB // Weapons KB: 470 321-372 52 39 valid, 3 invalid(329,332,340) 470 KB all weapons // Upgrades KB: 2,716 1000-1193 194 all valid 2,716 KB all upgrades // Vehicles(400-499) KB: 14,622 140 KB/model 7/MB // Vehicles(500-599) KB: 14,888 // /////////////////////////////////////////////////////////////// void CModelCacheManagerImpl::PreLoad ( void ) { if ( m_bDonePreLoad ) return; m_bDonePreLoad = true; CTickCount startTicks = CTickCount::Now (); #if 0 for ( uint i = 321 ; i <= 372 ; i++ ) { if ( CClientPedManager::IsValidWeaponModel ( i ) ) AddModelRefCount ( i ); } #endif m_pGame->GetStreaming()->LoadAllRequestedModels ( false ); // Get current limits int bSlowMethod = GetApplicationSettingInt( DIAG_PRELOAD_UPGRADES_SLOW ); int iLowestUnsafeUpgrade = GetApplicationSettingInt( DIAG_PRELOAD_UPGRADES_LOWEST_UNSAFE ); SetApplicationSetting( DIAG_CRASH_EXTRA_MSG, "** AUTO FIXING CRASH (Step 1/2) **\n\n** Please continue and connect to a server **" ); // Crashed during previous PreLoad? if ( WatchDogIsSectionOpen( WD_SECTION_PRELOAD_UPGRADES ) ) { AddReportLog( 8545, SString( "PreLoad Upgrades - Crash detect - bSlowMethod:%d iLowestUnsafeUpgrade:%d", bSlowMethod, iLowestUnsafeUpgrade ) ); iLowestUnsafeUpgrade = GetApplicationSettingInt( DIAG_PRELOAD_UPGRADE_ATTEMPT_ID ); bSlowMethod = 1; SetApplicationSettingInt( DIAG_PRELOAD_UPGRADES_LOWEST_UNSAFE, iLowestUnsafeUpgrade ); SetApplicationSettingInt( DIAG_PRELOAD_UPGRADES_SLOW, bSlowMethod ); SetApplicationSetting( DIAG_CRASH_EXTRA_MSG, "** AUTO FIXING CRASH (Step 2/2) **\n\n** Please continue and connect to a server **" ); } if ( iLowestUnsafeUpgrade == 0 ) iLowestUnsafeUpgrade = 1194; // PreLoad upgrades WatchDogBeginSection( WD_SECTION_PRELOAD_UPGRADES ); { for ( int i = 1000 ; i < iLowestUnsafeUpgrade ; i++ ) { if ( bSlowMethod ) SetApplicationSettingInt( DIAG_PRELOAD_UPGRADE_ATTEMPT_ID, i ); AddModelRefCount ( i ); if ( bSlowMethod ) m_pGame->GetStreaming()->LoadAllRequestedModels ( false ); } m_pGame->GetStreaming()->LoadAllRequestedModels ( false ); } WatchDogCompletedSection( WD_SECTION_PRELOAD_UPGRADES ); SetApplicationSetting( DIAG_CRASH_EXTRA_MSG, "" ); // Report if LowestUnsafeUpgrade has fallen int iPrevHiScore = GetApplicationSettingInt( DIAG_PRELOAD_UPGRADES_HISCORE ); SetApplicationSettingInt( DIAG_PRELOAD_UPGRADES_HISCORE, iLowestUnsafeUpgrade ); if ( iPrevHiScore > iLowestUnsafeUpgrade ) AddReportLog( 8544, SString( "PreLoad Upgrades - LowestUnsafeUpgrade fallen from %d to %d", iPrevHiScore, iLowestUnsafeUpgrade ) ); CTickCount deltaTicks = CTickCount::Now () - startTicks; OutputDebugLine ( SString ( "CModelCacheManagerImpl::PreLoad completed in %d ms", deltaTicks.ToInt () ) ); }