Ejemplo n.º 1
0
//////////////////////////////////////////////////////////
//
// ValidateGTAPath
//
// Check GTA path looks good
//
//////////////////////////////////////////////////////////
void ValidateGTAPath( void )
{
    // Get path to GTA
    ePathResult iResult = DiscoverGTAPath( true );
    if ( iResult == GAME_PATH_MISSING ) {
        DisplayErrorMessageBox ( _("Registry entries are missing. Please reinstall Multi Theft Auto: San Andreas."), _E("CL12"), "reg-entries-missing" );
        return ExitProcess( EXIT_ERROR );
    }
    else if ( iResult == GAME_PATH_UNICODE_CHARS ) {
        DisplayErrorMessageBox ( _("The path to your installation of GTA: San Andreas contains unsupported (unicode) characters. Please move your Grand Theft Auto: San Andreas installation to a compatible path that contains only standard ASCII characters and reinstall Multi Theft Auto: San Andreas."), _E("CL13") );
        return ExitProcess( EXIT_ERROR );
    }
    else if ( iResult == GAME_PATH_STEAM ) {
        DisplayErrorMessageBox ( _("It appears you have a Steam version of GTA:SA, which is currently incompatible with MTASA.  You are now being redirected to a page where you can find information to resolve this issue."), _E("CL14") );
        BrowseToSolution ( "downgrade-steam" );
        return ExitProcess( EXIT_ERROR );
    }

    SString strGTAPath = GetGTAPath();

    // We can now set this
    SetCurrentDirectory ( strGTAPath );

    const SString strMTASAPath = GetMTASAPath ();
    if ( strGTAPath.Contains ( ";" ) || strMTASAPath.Contains ( ";" ) )
    {
        DisplayErrorMessageBox (_( "The path to your installation of 'MTA:SA' or 'GTA: San Andreas'\n"
                                   "contains a ';' (semicolon).\n\n"
                                   " If you experience problems when running MTA:SA,\n"
                                   " move your installation(s) to a path that does not contain a semicolon." ), _E("CL15"), "path-semicolon" );
    }
}
Ejemplo n.º 2
0
//////////////////////////////////////////////////////////
//
// HandleTrouble
//
//
//
//////////////////////////////////////////////////////////
void HandleTrouble ( void )
{
    if ( CheckAndShowFileOpenFailureMessage () )
        return;

    int iResponse = MessageBoxUTF8 ( NULL, _("Are you having problems running MTA:SA?.\n\nDo you want to revert to an earlier version?"), "MTA: San Andreas"+_E("CL07"), MB_YESNO | MB_ICONQUESTION | MB_TOPMOST );
    if ( iResponse == IDYES )
    {
        BrowseToSolution ( "crashing-before-gtagame", TERMINATE_PROCESS );
    }
}
Ejemplo n.º 3
0
////////////////////////////////////////////////
//
// CSettingsSA::FindVideoMode
//
// Find best matching video mode
//
////////////////////////////////////////////////
uint CSettingsSA::FindVideoMode( int iResX, int iResY, int iColorBits )
{
    int iBestMode, iBestScore = -1;

    uint numVidModes = GetNumVideoModes();
    for ( uint vidMode = 0; vidMode < numVidModes; vidMode++ )
    {
        VideoMode vidModeInfo;
        GetVideoModeInfo( &vidModeInfo, vidMode );

        // Remove resolutions that will make the gui unusable
        if ( vidModeInfo.width < 640 || vidModeInfo.height < 480 )
            continue;

        if ( vidModeInfo.flags & rwVIDEOMODEEXCLUSIVE )
        {
            // Rate my res
            int iScore = abs( iResX - vidModeInfo.width ) + abs( iResY - vidModeInfo.height );

            // Penalize matches with wrong bit depth
            if ( vidModeInfo.depth != iColorBits )
            {
                iScore += 100000;
            }

            // Penalize matches with higher than requested resolution
            if ( vidModeInfo.width > iResX || vidModeInfo.height > iResY )
            {
                iScore += 200000;
            }

            if ( iScore < iBestScore || iBestScore == -1 )
            {
                // Found a better match
                iBestScore = iScore;
                iBestMode = vidMode;
            }
        }
    }

    if ( iBestScore != -1 )
        return iBestMode;

    BrowseToSolution ( "no-find-res", EXIT_GAME_FIRST | ASK_GO_ONLINE, _( "Can't find valid screen resolution." ) );
    return 1;
}
Ejemplo n.º 4
0
//////////////////////////////////////////////////////////
//
// HandleResetSettings
//
//
//
//////////////////////////////////////////////////////////
void HandleResetSettings ( void )
{
    if ( CheckAndShowFileOpenFailureMessage () )
        return;

    CheckAndShowMissingFileMessage();

    SString strSaveFilePath = PathJoin ( GetSystemPersonalPath(), "GTA San Andreas User Files" );
    SString strSettingsFilename = PathJoin ( strSaveFilePath, "gta_sa.set" );
    SString strSettingsFilenameBak = PathJoin ( strSaveFilePath, "gta_sa_old.set" );

    if ( FileExists ( strSettingsFilename ) )
    {
        int iResponse = MessageBoxUTF8 ( NULL, _("There seems to be a problem launching MTA:SA.\nResetting GTA settings can sometimes fix this problem.\n\nDo you want to reset GTA settings now?"), "MTA: San Andreas"+_E("CL08"), MB_YESNO | MB_ICONQUESTION | MB_TOPMOST );
        if ( iResponse == IDYES )
        {
            FileDelete ( strSettingsFilenameBak );
            FileRename ( strSettingsFilename, strSettingsFilenameBak );
            FileDelete ( strSettingsFilename );
            if ( !FileExists ( strSettingsFilename ) )
            {
                AddReportLog ( 4053, "Deleted gta_sa.set" );
                MessageBoxUTF8 ( NULL, _("GTA settings have been reset.\n\nPress OK to continue."), "MTA: San Andreas", MB_OK | MB_ICONINFORMATION | MB_TOPMOST );
            }
            else
            {
                AddReportLog ( 5054, SString ( "Delete gta_sa.set failed with '%s'", *strSettingsFilename ) );
                MessageBoxUTF8 ( NULL, SString ( _("File could not be deleted: '%s'"), *strSettingsFilename ), "Error"+_E("CL09"), MB_OK | MB_ICONWARNING | MB_TOPMOST );
            }
        }
    }
    else
    {
        // No settings to delete, or can't find them
        int iResponse = MessageBoxUTF8 ( NULL, _("Are you having problems running MTA:SA?.\n\nDo you want to see some online help?"), "MTA: San Andreas", MB_YESNO | MB_ICONQUESTION | MB_TOPMOST );
        if ( iResponse == IDYES )
        {
            BrowseToSolution ( "crashing-before-gtalaunch", TERMINATE_PROCESS );
        }
    }
}
Ejemplo n.º 5
0
///////////////////////////////////////////////////////////////
//
// WinMain
//
//
//
///////////////////////////////////////////////////////////////
int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    // Load the loader.dll and continue the load
#ifdef MTA_DEBUG
    SString strLoaderDllFilename = "loader_d.dll";
#else
    SString strLoaderDllFilename = "loader.dll";
#endif

    SString strMTASAPath = PathJoin ( GetLaunchPath (), "mta" );
    SString strLoaderDllPathFilename = PathJoin ( strMTASAPath, strLoaderDllFilename );

    // Load loader dll
    HMODULE hModule = LoadLibrary ( strLoaderDllPathFilename );

    int iReturnCode = 0;
    if ( hModule )
    {
        // Find and call DoWinMain
        typedef int (*PFNDOWINMAIN) ( HINSTANCE, HINSTANCE, LPSTR, int );
        PFNDOWINMAIN pfnDoWinMain = static_cast < PFNDOWINMAIN > ( static_cast < PVOID > ( GetProcAddress ( hModule, "DoWinMain" ) ) );
        if ( pfnDoWinMain )
            iReturnCode = pfnDoWinMain ( hInstance, hPrevInstance, lpCmdLine, nCmdShow );

        FreeLibrary ( hModule );
    }
    else
    {
        SString strError = GetSystemErrorMessage ( GetLastError () );
        SString strMessage ( "Failed to load: '%s'\n\n%s", *strLoaderDllPathFilename, *strError );
        AddReportLog ( 5711, strMessage );
        BrowseToSolution ( "loader-dll-missing", true, false, false, strMessage );
        iReturnCode = 1;
    }

    return iReturnCode;
}
Ejemplo n.º 6
0
////////////////////////////////////////////////
//
// 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(&parameters);

        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;
}
Ejemplo n.º 7
0
////////////////////////////////////////////////
//
// 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(&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"));
        }
    }

    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;
}