diff --git a/CxbxKrnl.dsp b/CxbxKrnl.dsp index fc75ba264..c69fed532 100644 --- a/CxbxKrnl.dsp +++ b/CxbxKrnl.dsp @@ -226,6 +226,10 @@ SOURCE=.\Include\Win32\CxbxKrnl\EmuD3D8.h # End Source File # Begin Source File +SOURCE=.\Include\Win32\CxbxKrnl\EmuD3D8Conv.h +# End Source File +# Begin Source File + SOURCE=.\Include\Win32\CxbxKrnl\EmuDInput.h # End Source File # Begin Source File diff --git a/Include/Cxbx.h b/Include/Cxbx.h index 7396854f9..4e963add6 100644 --- a/Include/Cxbx.h +++ b/Include/Cxbx.h @@ -62,9 +62,9 @@ typedef signed long sint32; // version information #ifndef _DEBUG_TRACE -#define _CXBX_VERSION "0.7.9-Pre2" +#define _CXBX_VERSION "0.7.9-Pre3" #else -#define _CXBX_VERSION "0.7.9-Pre2-Trace" +#define _CXBX_VERSION "0.7.9-Pre3-Trace" #endif // round dwValue to the nearest multiple of dwMult diff --git a/Include/Win32/CxbxKrnl/Emu.h b/Include/Win32/CxbxKrnl/Emu.h index 7d6f6f0b5..8285bffd6 100644 --- a/Include/Win32/CxbxKrnl/Emu.h +++ b/Include/Win32/CxbxKrnl/Emu.h @@ -67,6 +67,9 @@ extern "C" CXBXKRNL_API void NTAPI EmuPanic(); // exception handler extern int EmuException(LPEXCEPTION_POINTERS e); +// check the allocation size of a given virtual address +extern int EmuCheckAllocationSize(LPVOID pBase, bool largeBound); + // global exception patching address extern uint32 g_HaloHack[4]; diff --git a/Source/Win32/CxbxKrnl/Emu.cpp b/Source/Win32/CxbxKrnl/Emu.cpp index ed63565fb..3a0aa0506 100644 --- a/Source/Win32/CxbxKrnl/Emu.cpp +++ b/Source/Win32/CxbxKrnl/Emu.cpp @@ -492,7 +492,7 @@ extern "C" CXBXKRNL_API void NTAPI EmuInit // _USE_XGMATH Disabled in mesh :[ // halo : dword_0_2E2D18 // halo : 1744F0 (bink) - // _asm int 3 + _asm int 3 Entry(); @@ -610,7 +610,8 @@ extern int EmuException(LPEXCEPTION_POINTERS e) { if(e->ExceptionRecord->ExceptionCode == 0xC0000005) { - if(e->ContextRecord->Eip == 0x3394C) + // Halo Access Adjust 1 + if(e->ContextRecord->Eip == 0x0003394C) { if(e->ContextRecord->Ecx == 0x803BD800) { @@ -622,9 +623,157 @@ extern int EmuException(LPEXCEPTION_POINTERS e) ((XTL::X_D3DResource*)fix)->Data = g_HaloHack[1] + (((XTL::X_D3DResource*)fix)->Data - 0x803A6000); + // go through and fix any other pointers in the ESI allocation chunk + { + DWORD dwESI = e->ContextRecord->Esi; + DWORD dwSize = EmuCheckAllocationSize((PVOID)dwESI, false); + + // dword aligned + dwSize -= 4 - dwSize%4; + + for(DWORD v=0;v= 0x803A6000 && dwCur < 0x819A6000) + *(DWORD*)(dwESI+v) = g_HaloHack[1] + (dwCur - 0x803A6000); + } + } + + // fix this global pointer + { + DWORD dwValue = *(DWORD*)0x39CE24; + + *(DWORD*)0x39CE24 = g_HaloHack[1] + (dwValue - 0x803A6000); + } + + #ifdef _DEBUG_TRACE + printf("EmuMain (0x%X): Halo Access Adjust 1 was applied!\n", GetCurrentThreadId()); + #endif + return EXCEPTION_CONTINUE_EXECUTION; } } + // Halo Access Adjust 2 + else if(e->ContextRecord->Eip == 0x00058D8C) + { + if(e->ContextRecord->Eax == 0x819A5818) + { + uint32 fix = g_HaloHack[1] + (e->ContextRecord->Eax - 0x803A6000); + + *(DWORD*)0x0039BE58 = e->ContextRecord->Eax = fix; + + // go through and fix any other pointers in the 0x2DF1C8 allocation chunk + { + DWORD dwPtr = *(DWORD*)0x2DF1C8; + DWORD dwSize = EmuCheckAllocationSize((PVOID)dwPtr, false); + + // dword aligned + dwSize -= 4 - dwSize%4; + + for(DWORD v=0;v= 0x803A6000 && dwCur < 0x819A6000) + *(DWORD*)(dwPtr+v) = g_HaloHack[1] + (dwCur - 0x803A6000); + } + } + + #ifdef _DEBUG_TRACE + printf("EmuMain (0x%X): Halo Access Adjust 2 was applied!\n", GetCurrentThreadId()); + #endif + + return EXCEPTION_CONTINUE_EXECUTION; + } + } + + /* obsolete + // Halo Access Adjust 1 + if(e->ContextRecord->Eip == 0x0003394C) + { + if(e->ContextRecord->Ecx == 0x803BD800) + { + uint32 fix = g_HaloHack[1] + (e->ContextRecord->Eax - 0x803A6000); + + e->ContextRecord->Eax = e->ContextRecord->Ecx = fix; + + *(uint32*)e->ContextRecord->Esp = fix; + + ((XTL::X_D3DResource*)fix)->Data = g_HaloHack[1] + (((XTL::X_D3DResource*)fix)->Data - 0x803A6000); + + #ifdef _DEBUG_TRACE + printf("EmuMain (0x%X): Halo Access Adjust 1 was applied!\n", GetCurrentThreadId()); + #endif + + return EXCEPTION_CONTINUE_EXECUTION; + } + } + // Halo Access Adjust 2 + else if(e->ContextRecord->Eip == 0x00033977) + { + if(e->ContextRecord->Eax == 0x803DA660) + { + uint32 fix = g_HaloHack[1] + (e->ContextRecord->Eax - 0x803A6000); + + e->ContextRecord->Eax = fix; + + #ifdef _DEBUG_TRACE + printf("EmuMain (0x%X): Halo Access Adjust 2 was applied!\n", GetCurrentThreadId()); + #endif + + return EXCEPTION_CONTINUE_EXECUTION; + } + } + // Halo Access Adjust 3 + else if(e->ContextRecord->Eip == 0x00058DF1) + { + if(e->ContextRecord->Ecx == 0x803A6024) + { + uint32 fix = g_HaloHack[1] + (e->ContextRecord->Ecx - 0x803A6000); + + e->ContextRecord->Ecx = fix; + + #ifdef _DEBUG_TRACE + printf("EmuMain (0x%X): Halo Access Adjust 3 was applied!\n", GetCurrentThreadId()); + #endif + + return EXCEPTION_CONTINUE_EXECUTION; + } + } + // Halo Access Adjust 4 + else if(e->ContextRecord->Eip == 0x00058DF5) + { + if(e->ContextRecord->Eax == 0x803DDA20) + { + uint32 fix = g_HaloHack[1] + (e->ContextRecord->Eax - 0x803A6000); + + e->ContextRecord->Eax = fix; + + #ifdef _DEBUG_TRACE + printf("EmuMain (0x%X): Halo Access Adjust 4 was applied!\n", GetCurrentThreadId()); + #endif + + return EXCEPTION_CONTINUE_EXECUTION; + } + } + // Halo Access Adjust 5 + else if(e->ContextRecord->Eip == 0x0003523E) + { + if(e->ContextRecord->Ecx == 0x803A6024) + { + uint32 fix = g_HaloHack[1] + (e->ContextRecord->Eax - 0x803A6000); + + e->ContextRecord->Eax = fix; + + #ifdef _DEBUG_TRACE + printf("EmuMain (0x%X): Halo Access Adjust 5 was applied!\n", GetCurrentThreadId()); + #endif + + return EXCEPTION_CONTINUE_EXECUTION; + } + } + //*/ } } @@ -698,6 +847,26 @@ extern int EmuException(LPEXCEPTION_POINTERS e) return EXCEPTION_CONTINUE_SEARCH; } +// check how many bytes were allocated for a structure +extern int EmuCheckAllocationSize(LPVOID pBase, bool largeBound) +{ + MEMORY_BASIC_INFORMATION MemoryBasicInfo; + + DWORD dwRet = VirtualQuery(pBase, &MemoryBasicInfo, sizeof(MemoryBasicInfo)); + + if(dwRet == 0) + return 0; + + if(MemoryBasicInfo.State != MEM_COMMIT) + return 0; + + // this is a hack in order to determine when pointers come from a large write-combined database + if(largeBound && MemoryBasicInfo.RegionSize > 5*1024*1024) + return -1; + + return MemoryBasicInfo.RegionSize - ((DWORD)pBase - (DWORD)MemoryBasicInfo.BaseAddress); +} + // install function interception wrapper static inline void EmuInstallWrapper(void *FunctionAddr, void *WrapperAddr) { diff --git a/Source/Win32/CxbxKrnl/EmuD3D8.cpp b/Source/Win32/CxbxKrnl/EmuD3D8.cpp index 82b7b121d..3f64d25e6 100644 --- a/Source/Win32/CxbxKrnl/EmuD3D8.cpp +++ b/Source/Win32/CxbxKrnl/EmuD3D8.cpp @@ -65,7 +65,6 @@ static DWORD WINAPI EmuRenderWindow(LPVOID); static DWORD WINAPI EmuCreateDeviceProxy(LPVOID); static LRESULT WINAPI EmuMsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); static DWORD WINAPI EmuUpdateTickCount(LPVOID); -static DWORD EmuCheckAllocationSize(LPVOID); static inline void EmuVerifyResourceIsRegistered(XTL::X_D3DResource *pResource); static void EmuAdjustPower2(UINT *dwWidth, UINT *dwHeight); @@ -693,26 +692,6 @@ static DWORD WINAPI EmuCreateDeviceProxy(LPVOID) } } -// check how many bytes were allocated for a structure -static DWORD EmuCheckAllocationSize(PVOID pBase) -{ - MEMORY_BASIC_INFORMATION MemoryBasicInfo; - - DWORD dwRet = VirtualQuery(pBase, &MemoryBasicInfo, sizeof(MemoryBasicInfo)); - - if(dwRet == 0) - return 0; - - if(MemoryBasicInfo.State != MEM_COMMIT) - return 0; - - // this is a hack in order to determine when pointers come from a large write-combined database - if(MemoryBasicInfo.RegionSize > 5*1024*1024) - return -1; - - return MemoryBasicInfo.RegionSize - ((DWORD)pBase - (DWORD)MemoryBasicInfo.BaseAddress); -} - // check if a resource has been registered yet (if not, register it) static void EmuVerifyResourceIsRegistered(XTL::X_D3DResource *pResource) { @@ -1654,12 +1633,15 @@ HRESULT WINAPI XTL::EmuIDirect3DDevice8_SetVertexShaderConstant } #endif + HRESULT hRet = D3D_OK; + /* HRESULT hRet = g_pD3DDevice8->SetVertexShaderConstant ( Register, pConstantData, ConstantCount ); + */ if(FAILED(hRet)) { @@ -2629,10 +2611,14 @@ HRESULT WINAPI XTL::EmuIDirect3DResource8_Register // create vertex buffer { - DWORD dwSize = EmuCheckAllocationSize(pBase); + DWORD dwSize = EmuCheckAllocationSize(pBase, true); if(dwSize == -1) - EmuCleanup("Detected dangerous allocation techniques. This will be fixed soon!"); + { + // TODO: once this is known to be working, remove the warning + EmuWarning("Vertex buffer allocation size unknown"); + dwSize = 0x20; // temporarily assign a small buffer, which will be increased later + } hRet = g_pD3DDevice8->CreateVertexBuffer ( @@ -2670,7 +2656,7 @@ HRESULT WINAPI XTL::EmuIDirect3DResource8_Register // create index buffer { - DWORD dwSize = EmuCheckAllocationSize(pBase); + DWORD dwSize = EmuCheckAllocationSize(pBase, true); if(dwSize == -1) EmuCleanup("Detected dangerous allocation techniques. This will be fixed soon!"); diff --git a/Source/Win32/CxbxKrnl/EmuKrnl.cpp b/Source/Win32/CxbxKrnl/EmuKrnl.cpp index 8b5764fd5..d6a3c3cf2 100644 --- a/Source/Win32/CxbxKrnl/EmuKrnl.cpp +++ b/Source/Win32/CxbxKrnl/EmuKrnl.cpp @@ -568,6 +568,58 @@ XBSYSAPI EXPORTNUM(113) VOID NTAPI xboxkrnl::KeInitializeTimerEx return; } +// ****************************************************************** +// * KeQueryPerformanceCounter +// ****************************************************************** +XBSYSAPI EXPORTNUM(126) VOID __cdecl xboxkrnl::KeQueryPerformanceCounter() +{ + EmuSwapFS(); // Win2k/XP FS + + // debug trace + #ifdef _DEBUG_TRACE + { + printf("EmuKrnl (0x%X): KeQueryPerformanceCounter();\n", GetCurrentThreadId()); + } + #endif + + ::LARGE_INTEGER Counter; + + QueryPerformanceFrequency(&Counter); + + EmuSwapFS(); // Xbox FS + + __asm mov eax, Counter.u.LowPart + __asm mov edx, Counter.u.HighPart + + return; +} + +// ****************************************************************** +// * KeQueryPerformanceFrequency +// ****************************************************************** +XBSYSAPI EXPORTNUM(127) VOID __cdecl xboxkrnl::KeQueryPerformanceFrequency() +{ + EmuSwapFS(); // Win2k/XP FS + + // debug trace + #ifdef _DEBUG_TRACE + { + printf("EmuKrnl (0x%X): KeQueryPerformanceFrequency();\n", GetCurrentThreadId()); + } + #endif + + ::LARGE_INTEGER Frequency; + + QueryPerformanceFrequency(&Frequency); + + EmuSwapFS(); // Xbox FS + + __asm mov eax, Frequency.u.LowPart + __asm mov edx, Frequency.u.HighPart + + return; +} + // ****************************************************************** // * 0x0080 - KeQuerySystemTime // ****************************************************************** @@ -854,6 +906,47 @@ XBSYSAPI EXPORTNUM(178) VOID NTAPI xboxkrnl::MmPersistContiguousMemory EmuSwapFS(); // Xbox FS } +// ****************************************************************** +// * 0x00B5 - MmQueryStatistics +// ****************************************************************** +XBSYSAPI EXPORTNUM(181) NTSTATUS NTAPI xboxkrnl::MmQueryStatistics +( + OUT PMM_STATISTICS MemoryStatistics +) +{ + EmuSwapFS(); // Win2k/XP FS + + // debug trace + #ifdef _DEBUG_TRACE + { + printf("EmuKrnl (0x%X): MmQueryStatistics\n" + "(\n" + " MemoryStatistics : 0x%.08X\n" + ");\n", + GetCurrentThreadId(), MemoryStatistics); + } + #endif + + MEMORYSTATUS MemoryStatus; + + GlobalMemoryStatus(&MemoryStatus); + + ZeroMemory(MemoryStatistics, sizeof(MM_STATISTICS)); + + MemoryStatistics->Length = sizeof(MM_STATISTICS); + MemoryStatistics->TotalPhysicalPages = MemoryStatus.dwTotalVirtual / 4096; + MemoryStatistics->AvailablePages = MemoryStatus.dwAvailVirtual / 4096; + + // HACK (does this matter?) + MemoryStatistics->VirtualMemoryBytesReserved = MemoryStatus.dwTotalPhys - MemoryStatus.dwAvailPhys; + + // the rest arent really used from what i've seen + + EmuSwapFS(); // Xbox FS + + return STATUS_SUCCESS; +} + // ****************************************************************** // * 0x00B6 - MmSetAddressProtect // ****************************************************************** diff --git a/Source/Win32/CxbxKrnl/KernelThunk.cpp b/Source/Win32/CxbxKrnl/KernelThunk.cpp index 68b526607..cdafa16c4 100644 --- a/Source/Win32/CxbxKrnl/KernelThunk.cpp +++ b/Source/Win32/CxbxKrnl/KernelThunk.cpp @@ -183,8 +183,8 @@ extern "C" CXBXKRNL_API uint32 KernelThunkTable[367] = (uint32)PANIC(0x007B), // 0x007B (123) (uint32)PANIC(0x007C), // 0x007C (124) (uint32)PANIC(0x007D), // 0x007D (125) - (uint32)PANIC(0x007E), // 0x007E (126) - (uint32)PANIC(0x007F), // 0x007F (127) + (uint32)&xboxkrnl::KeQueryPerformanceCounter, // 0x007E (126) + (uint32)&xboxkrnl::KeQueryPerformanceFrequency, // 0x007F (127) (uint32)&xboxkrnl::KeQuerySystemTime, // 0x0080 (128) (uint32)PANIC(0x0081), // 0x0081 (129) (uint32)PANIC(0x0082), // 0x0082 (130) @@ -238,7 +238,7 @@ extern "C" CXBXKRNL_API uint32 KernelThunkTable[367] = (uint32)&xboxkrnl::MmPersistContiguousMemory, // 0x00B2 (178) (uint32)PANIC(0x00B3), // 0x00B3 (179) (uint32)PANIC(0x00B4), // 0x00B4 (180) - (uint32)PANIC(0x00B5), // 0x00B5 (181) + (uint32)&xboxkrnl::MmQueryStatistics, // 0x00B5 (181) (uint32)&xboxkrnl::MmSetAddressProtect, // 0x00B6 (182) (uint32)PANIC(0x00B7), // 0x00B7 (183) (uint32)&xboxkrnl::NtAllocateVirtualMemory, // 0x00B8 (184)