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)); } } }
// gta_sa.exe SString SharedUtil::GetLaunchFilename( void ) { return ExtractFilename( GetLaunchPathFilename() ); }