Exemple #1
0
int WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, PVOID pvNothing)
{
    CFilePathTranslator     FileTranslator;
    std::string             WorkingDirectory;

    if ( dwReason == DLL_PROCESS_ATTACH )
    {
        WriteDebugEvent( SString( "DLL_PROCESS_ATTACH %08x", pvNothing ) );
        if ( IsGTAProcess() )
        {
            WriteDebugEvent( SString( "ModuleFileName: %s", *GetLaunchPathFilename() ) );

            AddUtf8FileHooks();

            // Set low frag heap for XP
            ULONG heapInfo = 2 ;
            HeapSetInformation( GetProcessHeap(), HeapCompatibilityInformation, &heapInfo, sizeof( heapInfo ) );

            FileTranslator.GetGTARootDirectory ( WorkingDirectory );
            SetCurrentDirectory ( WorkingDirectory.c_str ( ) );

            // For dll searches, this call replaces the current directory entry and turns off 'SafeDllSearchMode'
            // Meaning it will search the supplied path before the system and windows directory.
            // http://msdn.microsoft.com/en-us/library/ms682586%28VS.85%29.aspx
            SetDllDirectory( CalcMTASAPath ( "MTA" ) );

            g_pCore = new CCore;

            FileTranslator.GetGTARootDirectory ( WorkingDirectory );
            SetCurrentDirectory ( WorkingDirectory.c_str ( ) );
        }
    } 
    else if (dwReason == DLL_PROCESS_DETACH)
    {
        WriteDebugEvent( SString( "DLL_PROCESS_DETACH %08x", pvNothing ) );
        if ( IsGTAProcess () )
        {
            RemoveUtf8FileHooks();

            AddReportLog( 7102, "Core - PROCESS_DETACH" );
            // For now, TerminateProcess if any destruction is attempted (or we'll crash)
            TerminateProcess ( GetCurrentProcess (), 0 );

            if ( g_pCore )
            {
                delete g_pCore;
                g_pCore = NULL;
            }
        }
    }

    return TRUE;
}
////////////////////////////////////////////////
//
// AddCapsReport
//
// Check caps seem correct
//
////////////////////////////////////////////////
void AddCapsReport(UINT Adapter, IDirect3D9* pDirect3D, IDirect3DDevice9* pD3DDevice9, bool bFixGTACaps)
{
    HRESULT hr;

    WriteDebugEvent(SString("ModuleFileName - %s ", *GetLaunchPathFilename()));

    // Get caps that GTA got
    D3DCAPS9* pGTACaps9 = (D3DCAPS9*)0x00C9BF00;
    WriteDebugEvent(SString("CapsReport GTACaps9 - %s ", *ToString(*pGTACaps9)));

    if (!pD3DDevice9)
        return;

    // Check device returns same D3D interface
    IDirect3D9* pDirect3DOther = NULL;
    pD3DDevice9->GetDirect3D(&pDirect3DOther);
    if (pDirect3DOther != pDirect3D)
    {
        WriteDebugEvent(SString("IDirect3D9 differs: %x %x", pDirect3D, pDirect3DOther));

        if (pDirect3DOther)
        {
            // Log graphic card name
            D3DADAPTER_IDENTIFIER9 AdapterIdent1;
            pDirect3D->GetAdapterIdentifier(Adapter, 0, &AdapterIdent1);
            WriteDebugEvent("pDirect3D:");
            WriteDebugEvent(ToString(AdapterIdent1));

            // Log graphic card name
            D3DADAPTER_IDENTIFIER9 AdapterIdent2;
            pDirect3DOther->GetAdapterIdentifier(Adapter, 0, &AdapterIdent2);
            WriteDebugEvent("pDirect3DOther:");
            WriteDebugEvent(ToString(AdapterIdent2));

            // Get caps from pDirect3DOther
            D3DCAPS9 D3DCaps9;
            hr = pDirect3DOther->GetDeviceCaps(Adapter, D3DDEVTYPE_HAL, &D3DCaps9);
            WriteDebugEvent(SString("pDirect3DOther CapsReport Caps9 - %s ", *ToString(D3DCaps9)));
        }
    }

    SAFE_RELEASE(pDirect3DOther);

    // Get caps from D3D
    D3DCAPS9 D3DCaps9;
    hr = pDirect3D->GetDeviceCaps(Adapter, D3DDEVTYPE_HAL, &D3DCaps9);
    WriteDebugEvent(SString("IDirect3D9 CapsReport Caps9 - %s ", *ToString(D3DCaps9)));

    // Get caps from Device
    D3DCAPS9 DeviceCaps9;
    hr = pD3DDevice9->GetDeviceCaps(&DeviceCaps9);
    WriteDebugEvent(SString("IDirect3DDevice9 CapsReport Caps9 - %s ", *ToString(DeviceCaps9)));

    // Test caps
    struct
    {
        DWORD CapsType;
        BYTE  VertexType;
    } DeclTypesList[] = {
        {D3DDTCAPS_UBYTE4, D3DDECLTYPE_UBYTE4},       {D3DDTCAPS_UBYTE4N, D3DDECLTYPE_UBYTE4N},   {D3DDTCAPS_SHORT2N, D3DDECLTYPE_SHORT2N},
        {D3DDTCAPS_SHORT4N, D3DDECLTYPE_SHORT4N},     {D3DDTCAPS_USHORT2N, D3DDECLTYPE_USHORT2N}, {D3DDTCAPS_USHORT4N, D3DDECLTYPE_USHORT4N},
        {D3DDTCAPS_UDEC3, D3DDECLTYPE_UDEC3},         {D3DDTCAPS_DEC3N, D3DDECLTYPE_DEC3N},       {D3DDTCAPS_FLOAT16_2, D3DDECLTYPE_FLOAT16_2},
        {D3DDTCAPS_FLOAT16_4, D3DDECLTYPE_FLOAT16_4},
    };

    // Try each vertex declaration type to see if it matches with what was advertised
    uint uiNumItems = NUMELMS(DeclTypesList);
    uint uiNumMatchesCaps = 0;
    for (uint i = 0; i < uiNumItems; i++)
    {
        // Try create
        D3DVERTEXELEMENT9 VertexElements[] = {{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()};
        VertexElements[0].Type = DeclTypesList[i].VertexType;
        IDirect3DVertexDeclaration9* pD3DVertexDecl;
        hr = pD3DDevice9->CreateVertexDeclaration(VertexElements, &pD3DVertexDecl);
        SAFE_RELEASE(pD3DVertexDecl);

        // Check against device caps
        bool bCapsSaysOk = (DeviceCaps9.DeclTypes & DeclTypesList[i].CapsType) ? true : false;
        bool bMatchesCaps = (hr == D3D_OK) == (bCapsSaysOk == true);
        if (bMatchesCaps)
            uiNumMatchesCaps++;
        else
            WriteDebugEvent(SString("CapsReport - CreateVertexDeclaration %d/%d [MISMATCH] (VertexType:%d) result: %x (Matches caps:%d)", i, uiNumItems,
                                    DeclTypesList[i].VertexType, hr, bMatchesCaps));
    }
    WriteDebugEvent(SString("CapsReport - CreateVertexDeclarations MatchesCaps:%d/%d", uiNumMatchesCaps, uiNumItems));

    DWORD MaxActiveLights = std::min(DeviceCaps9.MaxActiveLights, pGTACaps9->MaxActiveLights);
    pGTACaps9->MaxActiveLights = MaxActiveLights;
    D3DCaps9.MaxActiveLights = MaxActiveLights;
    DeviceCaps9.MaxActiveLights = MaxActiveLights;

    DWORD MaxVertexBlendMatrixIndex = std::min(DeviceCaps9.MaxVertexBlendMatrixIndex, pGTACaps9->MaxVertexBlendMatrixIndex);
    pGTACaps9->MaxVertexBlendMatrixIndex = MaxVertexBlendMatrixIndex;
    D3DCaps9.MaxVertexBlendMatrixIndex = MaxVertexBlendMatrixIndex;
    DeviceCaps9.MaxVertexBlendMatrixIndex = MaxVertexBlendMatrixIndex;

    DWORD VertexProcessingCaps = DeviceCaps9.VertexProcessingCaps & pGTACaps9->VertexProcessingCaps;
    pGTACaps9->VertexProcessingCaps = VertexProcessingCaps;
    D3DCaps9.VertexProcessingCaps = VertexProcessingCaps;
    DeviceCaps9.VertexProcessingCaps = VertexProcessingCaps;

    bool DeviceCapsSameAsGTACaps = memcmp(&DeviceCaps9, pGTACaps9, sizeof(D3DCAPS9)) == 0;
    bool DeviceCapsSameAsD3DCaps9 = memcmp(&DeviceCaps9, &D3DCaps9, sizeof(D3DCAPS9)) == 0;

    WriteDebugEvent(SString("DeviceCaps==GTACaps:%d  DeviceCaps==D3DCaps9:%d", DeviceCapsSameAsGTACaps, DeviceCapsSameAsD3DCaps9));

    SString strDiffDesc1 = GetByteDiffDesc(&DeviceCaps9, pGTACaps9, sizeof(D3DCAPS9));
    if (!strDiffDesc1.empty())
        WriteDebugEvent(SString("DeviceCaps==GTACaps diff:%s", *strDiffDesc1.Left(500)));

    SString strDiffDesc2 = GetByteDiffDesc(&DeviceCaps9, &D3DCaps9, sizeof(D3DCAPS9));
    if (!strDiffDesc2.empty())
        WriteDebugEvent(SString("DeviceCaps==D3DCaps9 diff:%s", *strDiffDesc2.Left(500)));

    if (bFixGTACaps && !DeviceCapsSameAsGTACaps)
    {
        if (DeviceCaps9.DeclTypes > pGTACaps9->DeclTypes)
        {
            WriteDebugEvent("Not Fixing GTA caps as DeviceCaps is better");
        }
        else
        {
            WriteDebugEvent("Fixing GTA caps");
            memcpy(pGTACaps9, &DeviceCaps9, sizeof(D3DCAPS9));
        }
    }
}
Exemple #3
0
// gta_sa.exe
SString SharedUtil::GetLaunchFilename( void )
{
    return ExtractFilename( GetLaunchPathFilename() );
}