From 05fd0fea48cfa1f7842d0e37c1ebac9389b90303 Mon Sep 17 00:00:00 2001 From: Silent <16026653+s-ilent@users.noreply.github.com> Date: Sat, 30 Nov 2024 15:02:47 +1030 Subject: [PATCH 01/21] Change default UI overlay width Fixes overlay crosshair being squished. Also looks a bit more natural than a square HUD, but that may just be my opinion. --- HaloCEVR/Game.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HaloCEVR/Game.cpp b/HaloCEVR/Game.cpp index eeb796b..ccabedd 100644 --- a/HaloCEVR/Game.cpp +++ b/HaloCEVR/Game.cpp @@ -761,7 +761,7 @@ void Game::SetupConfigs() c_UIOverlayDistance = config.RegisterFloat("UIOverlayDistance", "Distance in metres in front of the HMD to display the UI", 15.0f); c_UIOverlayScale = config.RegisterFloat("UIOverlayScale", "Width of the UI overlay in metres", 10.0f); c_UIOverlayCurvature = config.RegisterFloat("UIOverlayCurvature", "Curvature of the UI Overlay, on a scale of 0 to 1", 0.1f); - c_UIOverlayWidth = config.RegisterInt("UIOverlayWidth", "Width of the UI overlay in pixels", 600); + c_UIOverlayWidth = config.RegisterInt("UIOverlayWidth", "Width of the UI overlay in pixels", 800); c_UIOverlayHeight = config.RegisterInt("UIOverlayHeight", "Height of the UI overlay in pixels", 600); // Control settings c_LeftHanded = config.RegisterBool("LeftHanded", "Make the left hand the dominant hand. Does not affect bindings, change these in the SteamVR overlay", false); From 5338254ac5604cdbe9f1f59637a1752372d47458 Mon Sep 17 00:00:00 2001 From: Cody Herzog Date: Mon, 2 Dec 2024 20:07:44 -0800 Subject: [PATCH 02/21] Scale width and height by same amount to avoid warp on head tilt. I don't know if this has any bad side effects. --- HaloCEVR/VR/OpenVR.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/HaloCEVR/VR/OpenVR.cpp b/HaloCEVR/VR/OpenVR.cpp index 40d3135..58ee4b7 100644 --- a/HaloCEVR/VR/OpenVR.cpp +++ b/HaloCEVR/VR/OpenVR.cpp @@ -150,8 +150,13 @@ void OpenVR::Init() realWidth = recommendedWidth; realHeight = recommendedHeight; - recommendedWidth = static_cast(recommendedWidth / (std::max)(textureBounds[0].uMax - textureBounds[0].uMin, textureBounds[1].uMax - textureBounds[1].uMin)); - recommendedHeight = static_cast(recommendedHeight / (std::max)(textureBounds[0].vMax - textureBounds[0].vMin, textureBounds[1].vMax - textureBounds[1].vMin)); + const float widthDiv = (std::max)(textureBounds[0].uMax - textureBounds[0].uMin, textureBounds[1].uMax - textureBounds[1].uMin); + const float heightDiv = (std::max)(textureBounds[0].vMax - textureBounds[0].vMin, textureBounds[1].vMax - textureBounds[1].vMin); + const float minDiv = (std::min)(widthDiv, heightDiv); + + // Scale width and height by same amount, or we may see warping on head tilt. + recommendedWidth = static_cast(recommendedWidth / minDiv); + recommendedHeight = static_cast(recommendedHeight / minDiv); Logger::log << "[OpenVR] Stretched Width/Height from " << realWidth << "x" << realHeight << " to " << recommendedWidth << "x" << recommendedHeight << std::endl; Logger::log << "[OpenVR] Desired fov = " << (fov * (180.0f / 3.141593f)) << " Desired aspect ratio = " << aspect << std::endl; From 10c759f7a75b4cf0cd2ba7a9243140ee1c81d6a5 Mon Sep 17 00:00:00 2001 From: Cody Herzog Date: Tue, 3 Dec 2024 14:32:44 -0800 Subject: [PATCH 03/21] Disabled scaling hack that helped in my configuration and added more detailed logging. --- HaloCEVR/VR/OpenVR.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/HaloCEVR/VR/OpenVR.cpp b/HaloCEVR/VR/OpenVR.cpp index 58ee4b7..51f447b 100644 --- a/HaloCEVR/VR/OpenVR.cpp +++ b/HaloCEVR/VR/OpenVR.cpp @@ -14,6 +14,8 @@ #pragma comment(lib, "openvr_api.lib") #pragma comment(lib, "d3d11.lib") +#define SCALING_HACK 0 + void OpenVR::Init() { Logger::log << "[OpenVR] Initialising OpenVR" << std::endl; @@ -125,24 +127,29 @@ void OpenVR::Init() float l_left = 0.0f, l_right = 0.0f, l_top = 0.0f, l_bottom = 0.0f; vrSystem->GetProjectionRaw(vr::EVREye::Eye_Left, &l_left, &l_right, &l_top, &l_bottom); + Logger::log << "[OpenVR] Left eye raw projection[l, r, t, b] = [" << l_left << ", " << l_right << ", " << l_top << ", " << l_bottom << "]" << std::endl; float r_left = 0.0f, r_right = 0.0f, r_top = 0.0f, r_bottom = 0.0f; vrSystem->GetProjectionRaw(vr::EVREye::Eye_Right, &r_left, &r_right, &r_top, &r_bottom); + Logger::log << "[OpenVR] Right eye raw projection[l, r, t, b] = [" << r_left << ", " << r_right << ", " << r_top << ", " << r_bottom << "]" << std::endl; float tanHalfFov[2]; tanHalfFov[0] = (std::max)({ -l_left, l_right, -r_left, r_right }); tanHalfFov[1] = (std::max)({ -l_top, l_bottom, -r_top, r_bottom }); + Logger::log << "[OpenVR] tanHalfFov[horiz, vert] = [" << tanHalfFov[0] << ", " << tanHalfFov[1] << "]" << std::endl; textureBounds[0].uMin = 0.5f + 0.5f * l_left / tanHalfFov[0]; textureBounds[0].uMax = 0.5f + 0.5f * l_right / tanHalfFov[0]; textureBounds[0].vMin = 0.5f - 0.5f * l_bottom / tanHalfFov[1]; textureBounds[0].vMax = 0.5f - 0.5f * l_top / tanHalfFov[1]; + Logger::log << "[OpenVR] Left eye textureBounds[uMin, uMax, vMin, vMax] = [" << textureBounds[0].uMin << ", " << textureBounds[0].uMax << ", " << textureBounds[0].vMin << ", " << textureBounds[0].vMax << "]" << std::endl; textureBounds[1].uMin = 0.5f + 0.5f * r_left / tanHalfFov[0]; textureBounds[1].uMax = 0.5f + 0.5f * r_right / tanHalfFov[0]; textureBounds[1].vMin = 0.5f - 0.5f * r_bottom / tanHalfFov[1]; textureBounds[1].vMax = 0.5f - 0.5f * r_top / tanHalfFov[1]; + Logger::log << "[OpenVR] Right eye textureBounds[uMin, uMax, vMin, vMax] = [" << textureBounds[1].uMin << ", " << textureBounds[1].uMax << ", " << textureBounds[1].vMin << ", " << textureBounds[1].vMax << "]" << std::endl; aspect = tanHalfFov[0] / tanHalfFov[1]; fov = 2.0f * atan(tanHalfFov[1]); @@ -152,11 +159,18 @@ void OpenVR::Init() const float widthDiv = (std::max)(textureBounds[0].uMax - textureBounds[0].uMin, textureBounds[1].uMax - textureBounds[1].uMin); const float heightDiv = (std::max)(textureBounds[0].vMax - textureBounds[0].vMin, textureBounds[1].vMax - textureBounds[1].vMin); - const float minDiv = (std::min)(widthDiv, heightDiv); + Logger::log << "[OpenVR] Stretch factor[width, height] = [" << 1.0f / widthDiv << ", " << 1.0f / heightDiv << "]" << std::endl; +#if SCALING_HACK + const float minDiv = (std::min)(widthDiv, heightDiv); // Scale width and height by same amount, or we may see warping on head tilt. + // This seems to help on Quest 3 using Virutal Desktop, but makes some other configurations worse. recommendedWidth = static_cast(recommendedWidth / minDiv); recommendedHeight = static_cast(recommendedHeight / minDiv); +#else + recommendedWidth = static_cast(recommendedWidth / widthDiv); + recommendedHeight = static_cast(recommendedHeight / heightDiv); +#endif Logger::log << "[OpenVR] Stretched Width/Height from " << realWidth << "x" << realHeight << " to " << recommendedWidth << "x" << recommendedHeight << std::endl; Logger::log << "[OpenVR] Desired fov = " << (fov * (180.0f / 3.141593f)) << " Desired aspect ratio = " << aspect << std::endl; From f08200f1bd732f656eec690dd01856e3f4ddb854 Mon Sep 17 00:00:00 2001 From: Cody Herzog Date: Sat, 7 Dec 2024 14:56:32 -0800 Subject: [PATCH 04/21] Removing scaling hack now that viewport config options exist. --- HaloCEVR/VR/OpenVR.cpp | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/HaloCEVR/VR/OpenVR.cpp b/HaloCEVR/VR/OpenVR.cpp index b990f08..5514a4f 100644 --- a/HaloCEVR/VR/OpenVR.cpp +++ b/HaloCEVR/VR/OpenVR.cpp @@ -15,8 +15,6 @@ #pragma comment(lib, "openvr_api.lib") #pragma comment(lib, "d3d11.lib") -#define SCALING_HACK 0 - void OpenVR::Init() { Logger::log << "[OpenVR] Initialising OpenVR" << std::endl; @@ -158,20 +156,8 @@ void OpenVR::Init() realWidth = recommendedWidth; realHeight = recommendedHeight; - const float widthDiv = (std::max)(textureBounds[0].uMax - textureBounds[0].uMin, textureBounds[1].uMax - textureBounds[1].uMin); - const float heightDiv = (std::max)(textureBounds[0].vMax - textureBounds[0].vMin, textureBounds[1].vMax - textureBounds[1].vMin); - Logger::log << "[OpenVR] Stretch factor[width, height] = [" << 1.0f / widthDiv << ", " << 1.0f / heightDiv << "]" << std::endl; - -#if SCALING_HACK - const float minDiv = (std::min)(widthDiv, heightDiv); - // Scale width and height by same amount, or we may see warping on head tilt. - // This seems to help on Quest 3 using Virutal Desktop, but makes some other configurations worse. - recommendedWidth = static_cast(recommendedWidth / minDiv); - recommendedHeight = static_cast(recommendedHeight / minDiv); -#else - recommendedWidth = static_cast(recommendedWidth / widthDiv); - recommendedHeight = static_cast(recommendedHeight / heightDiv); -#endif + recommendedWidth = static_cast(recommendedWidth / (std::max)(textureBounds[0].uMax - textureBounds[0].uMin, textureBounds[1].uMax - textureBounds[1].uMin)); + recommendedHeight = static_cast(recommendedHeight / (std::max)(textureBounds[0].vMax - textureBounds[0].vMin, textureBounds[1].vMax - textureBounds[1].vMin)); Logger::log << "[OpenVR] Stretched Width/Height from " << realWidth << "x" << realHeight << " to " << recommendedWidth << "x" << recommendedHeight << std::endl; Logger::log << "[OpenVR] Desired fov = " << (fov * (180.0f / 3.141593f)) << " Desired aspect ratio = " << aspect << std::endl; From ab495bf4c1ded9db34c072efb3300432e865f1d7 Mon Sep 17 00:00:00 2001 From: LivingFray Date: Sun, 8 Dec 2024 01:03:17 +0000 Subject: [PATCH 05/21] Changed a lot of magic numbers, try to guess why ;P --- HaloCEVR/Hooking/SigScanner.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/HaloCEVR/Hooking/SigScanner.h b/HaloCEVR/Hooking/SigScanner.h index 6d4f8dc..d831149 100644 --- a/HaloCEVR/Hooking/SigScanner.h +++ b/HaloCEVR/Hooking/SigScanner.h @@ -23,8 +23,8 @@ struct Offset class Offsets { public: - INDIRECT(AssetsArray, 0x042455, 0x4B, "74 31 57 0f bf f8 69 ff 0c 08 00 00 81 c7 ?? ?? ?? ?? e8 44"); - INDIRECT(Controls, 0x08b4b0, 0xCD, "83 ec 08 56 57 8d 44 24 08 50 ff 15 ?? ?? ?? ?? 8b 4c 24 0c"); + INDIRECT(AssetsArray, 0x042455, 0x4B, "74 31 57 0f bf f8 69 ff 0c 08 00 00 81 c7 ?? ?? ?? ?? e8"); + INDIRECT(Controls, 0x08cca0, 0x12, "a1 ?? ?? ?? ?? 83 ec ?? 53 55 56 57 b9 ?? ?? ?? ?? be"); INDIRECT(DirectX9, 0x1169c0, 0xE4, "83 ec 60 8b 15 ?? ?? ?? ?? 8b 0d ?? ?? ?? ?? 53 33 db"); INDIRECT(DirectX9Device, 0x1169c0, 0x4B, "83 ec 60 8b 15 ?? ?? ?? ?? 8b 0d ?? ?? ?? ?? 53 33 db"); INDIRECT(HideMouse, 0x045640, 0x23, "8a 0d ?? ?? ?? ?? 8b 44 24 04 8b 15 ?? ?? ?? ?? 81 ec 90 00 00 00"); @@ -33,14 +33,14 @@ class Offsets INDIRECT(LocalPlayer, 0x047880, 0x0F, "8b 44 24 04 8b 0d ?? ?? ?? ?? 83 ec 24 56 a3 ?? ?? ?? ?? 8b 71 04"); INDIRECT(WindowRect, 0x0ca1a0, 0x3E, "66 a1 ?? ?? ?? ?? 81 ec 18 03 00 00 66 3d 01 00 53 55 56 57"); INDIRECT(RenderTargets, 0x12ccc0, 0x1E, "83 ec 38 56 57 66 8b f0 33 ff 66 83 fe 09 ?? ?? 66 85 f6"); - INDIRECT(CameraMatrices, 0x10bfb0, 0x5A, "81 ec a0 02 00 00 53 55 8b ac 24 ac 02 00 00 56"); + INDIRECT(CameraMatrices, 0x10bfb0, 0x5A, "81 ec a0 02 00 00 53 55 8b ac 24 ac 02 00 00 56 8b 35"); INDIRECT(InputData, 0x0735b0, 0xAD, "51 53 56 6a 10 68 ?? ?? ?? ?? bb 00 02 00 00 e8 ?? ?? ?? ?? 6a 10"); INDIRECT(CurrentRect, 0x12ccc0, 0x51, "83 ec 38 56 57 66 8b f0 33 ff 66 83 fe 09 ?? ?? 66 85 f6"); INDIRECT(LoadingState, 0x097410, 0x01, "a1 ?? ?? ?? ?? 81 ec 18 04 00 00 57 33 ff 3b c7 0f 84 ?? ?? ?? ?? a1 ?? ?? ?? ?? 56 83 ce ff"); INDIRECT(CmdLineArgs, 0x140ee0, 0x5F, "53 57 6a 01 33 db ff 15 ?? ?? ?? ?? 68 ?? ?? ?? ?? ff 15 ?? ?? ?? ?? 33 c0 b9 41 00 00 00"); INDIRECT(IsWindowed, 0x1169c0, 0x0B, "83 ec 60 8b 15 ?? ?? ?? ?? 8b 0d ?? ?? ?? ?? 53 33 db"); - INDIRECT(CutsceneData, 0x07f8b0, 0x32, "0f bf 44 24 04 8b 04 85 ?? ?? ?? ?? 8b 4c 24 0c 56 8b 74 24 0c 51 8d 50 1c 0f bf 40 1a 52 50 56"); - INDIRECT(CampaignLoading, 0x0c7886, 0x02, "38 1d ?? ?? ?? ?? 74 ?? e8 ?? ?? ?? ?? 38 1d ?? ?? ?? ?? 74 ?? e8 ?? ?? ?? ?? bf 1e 00 00 00 89 3d"); + INDIRECT(CutsceneData, 0x07f8d5, 0x0D, "83 c4 10 85 c0 74 25 8a 00 84 c0"); + INDIRECT(CampaignLoading, 0x0c7886, 0x02, "38 1d ?? ?? ?? ?? 74 ?? e8 ?? ?? ?? ?? 38 1d ?? ?? ?? ?? 74 ?? e8"); OFFSET(TabOutVideo, 0x0c7b74, "38 1D ?? ?? ?? ?? 74 0E 83 FD 01 74 09 83 FD 02 0F 85"); OFFSET(TabOutVideo2, 0x0c801c, "75 11 38 1D ?? ?? ?? ?? 75 04 3A C3 74 05 C6 44 24 17 01"); @@ -48,7 +48,7 @@ class Offsets OFFSET(CutsceneFPSCap, 0x0c9fb5, "b3 01 eb ?? 32 db 8b 2d ?? ?? ?? ?? 8d 4c"); OFFSET(CreateMouseDevice, 0x0919c0, "6a 17 ff 15 ?? ?? ?? ?? 85 c0 74 ?? 66 c7 05 ?? ?? ?? ?? 02 00"); OFFSET(SetViewModelVisible, 0x092430, "51 8b 0d ?? ?? ?? ?? 66 83 f9 ff 74 ?? 8b 15 ?? ?? ?? ?? 56 0f bf f1"); - OFFSET(TextureAlphaWrite, 0x11c9a0, "81 ec 4c 01 00 00 56 8b f0 a0 ?? ?? ?? ?? 84 c0 c6 44 24 07 01"); + OFFSET(TextureAlphaWrite, 0x11c9a0, "81 ec ?? ?? 00 00 56 8b f0 a0 ?? ?? ?? ?? 84 c0"); OFFSET(TextAlphaWrite, 0x131b80, "a0 ?? ?? ?? ?? 84 c0 0f 84 ?? ?? ?? ?? 66 83 ?? ?? ?? ?? 00 01 0f 85 ?? ?? ?? ?? 53 55 56"); OFFSET(CrouchHeight, 0x168ff0, "d9 86 0c 05 00 00 f6 86 cc 04 00 00 01 75 ?? d8 15"); OFFSET(CinematicBarDrawCall, 0x049b25, "e8 ?? ?? ?? ?? 0f bf 15 ?? ?? ?? ?? 89 54 24 18 db 44 24 18 d9 5c 24 18 d9 44 24 18"); @@ -60,12 +60,12 @@ class Offsets OFFSET(DrawLoadingScreen, 0x10bdc0, "55 8b ec 83 e4 f8 81 ec 5c 02 00 00 53 56 8b 75 08"); OFFSET(DrawFrameMPLoading, 0x10c590, "8b 15 ?? ?? ?? ?? 81 ec 70 02 00 00 53 56 42 57"); OFFSET(DrawCrosshair, 0x0acad0, "83 ec 28 84 db 55 8b 6c 24 38 56 8b 74 24 38 57 8b f8"); - OFFSET(DrawImage, 0x11c9a0, "81 ec 4c 01 00 00 56 8b f0 a0 ?? ?? ?? ?? 84 c0 c6 44 24 07 01"); + OFFSET(DrawImage, 0x11c9a0, "81 ec ?? ?? 00 00 56 8b f0 a0 ?? ?? ?? ?? 84 c0"); OFFSET(DrawLoadingScreen2, 0x097410, "a1 ?? ?? ?? ?? 81 ec 18 04 00 00 57 33 ff 3b c7 0f 84 ?? ?? ?? ?? a1 ?? ?? ?? ?? 56 83 ce ff"); OFFSET(DrawCinematicBars, 0x0499c0, "8b 15 ?? ?? ?? ?? 8a 4a 08 83 ec 34 84 c9 53 55 56 57"); OFFSET(DrawViewModel, 0x0924b0, "66 8b 0d ?? ?? ?? ?? 81 ec 3c 0d 00 00 66 83 f9 ff 53 55 56 57"); - OFFSET(SetViewModelPosition, 0x0d6880, "81 ec f0 00 00 00 53 55 25 ff ff 00 00 56 8b f1 8b 0d 14"); + OFFSET(SetViewModelPosition, 0x0d6880, "81 ec f0 00 00 00 53 55 25 ff ff 00 00 56 8b f1 8b 0d"); OFFSET(HandleInputs, 0x08b4b0, "83 ec 08 56 57 8d 44 24 08 50 ff 15 ?? ?? ?? ?? 8b 4c 24 0c"); OFFSET(UpdatePitchYaw, 0x072160, "81 ec a4 00 00 00 8b 15 ?? ?? ?? ?? 53 0f bf c8"); OFFSET(SetMousePosition, 0x097250, "56 8b 35 ?? ?? ?? ?? 33 d2 3b f0 75 ?? 39 0d"); From 3063953689de12ad29f7b9f56dea4d303bf37c43 Mon Sep 17 00:00:00 2001 From: LivingFray Date: Sun, 15 Dec 2024 17:34:36 +0000 Subject: [PATCH 06/21] Added hooks for reload start/end events. (To enable uncomment the lines in Hooks.cpp that enable the hook) --- HaloCEVR/Game.cpp | 19 +++++++++++++++ HaloCEVR/Game.h | 2 ++ HaloCEVR/Helpers/Objects.h | 18 ++++++++++++++ HaloCEVR/Hooking/FunctionTypedefs.h | 4 +++- HaloCEVR/Hooking/Hooks.cpp | 37 +++++++++++++++++++++++++++++ HaloCEVR/Hooking/Hooks.h | 2 ++ HaloCEVR/Hooking/SigScanner.h | 2 ++ 7 files changed, 83 insertions(+), 1 deletion(-) diff --git a/HaloCEVR/Game.cpp b/HaloCEVR/Game.cpp index 7404520..21d39d3 100644 --- a/HaloCEVR/Game.cpp +++ b/HaloCEVR/Game.cpp @@ -674,6 +674,25 @@ bool Game::GetCalculatedHandPositions(Matrix4& controllerTransform, Vector3& dom return inputHandler.GetCalculatedHandPositions(controllerTransform, dominantHandPos, offHand); } +void Game::ReloadStart(HaloID param1, short param2, bool param3) +{ + // TODO: Check if this reload was from the player (can probably be done by checking the weapon's parent ID matches the player) + WeaponDynamicObject* weaponObject = static_cast((Helpers::GetDynamicObject(param1))); + + Weapon& weapon = weaponObject->weaponData[param2]; + + // Reload function gets called whenever the player tries to reload, if reloadstate is 1 then a reload was actually triggered + if (weapon.reloadState == 1) + { + Logger::log << "Reload Start (" << param1 << ", " << param2 << ", " << param3 << ")" << std::endl; + } +} + +void Game::ReloadEnd(short param1, HaloID param2) +{ + Logger::log << "Reload End" << std::endl; +} + Vector3 Game::GetSmoothedInput() { return inputHandler.smoothedPosition; diff --git a/HaloCEVR/Game.h b/HaloCEVR/Game.h index 3b16519..c2e5576 100644 --- a/HaloCEVR/Game.h +++ b/HaloCEVR/Game.h @@ -55,6 +55,8 @@ class Game void PreThrowGrenade(HaloID& playerID); void PostThrowGrenade(HaloID& playerID); bool GetCalculatedHandPositions(Matrix4& controllerTransform, Vector3& dominantHandPos, Vector3& offHand); + void ReloadStart(HaloID param1, short param2, bool param3); + void ReloadEnd(short param1, HaloID param2); void UpdateInputs(); void CalculateSmoothedInput(); diff --git a/HaloCEVR/Helpers/Objects.h b/HaloCEVR/Helpers/Objects.h index 851169c..f97c2f5 100644 --- a/HaloCEVR/Helpers/Objects.h +++ b/HaloCEVR/Helpers/Objects.h @@ -212,6 +212,24 @@ struct PlayerDatum char pad_0038[216]; //0x0038 }; +struct Weapon +{ +public: + uint16_t reloadState; + uint16_t reloadRemaining; + uint16_t reloadTime; + uint16_t reserveAmmo; + uint16_t ammo; + uint16_t unk; +}; + +struct WeaponDynamicObject : public BaseDynamicObject +{ +public: + char pad_01F4[188]; //0x01F4 + Weapon weaponData[4]; //0x02B0 +}; //Size: 0x0340 + namespace Helpers { ObjectTable& GetObjectTable(); diff --git a/HaloCEVR/Hooking/FunctionTypedefs.h b/HaloCEVR/Hooking/FunctionTypedefs.h index 5acc2f1..f6fb84b 100644 --- a/HaloCEVR/Hooking/FunctionTypedefs.h +++ b/HaloCEVR/Hooking/FunctionTypedefs.h @@ -23,4 +23,6 @@ typedef void(*Func_SetCameraMatrices)(); typedef int(__cdecl* Func_MaybeNightVision)(float* param1); typedef void(__fastcall* Func_DrawLoadingScreen2)(void* parma1); typedef void(*Func_DrawCinematicBars)(); -typedef void(*Func_DrawViewModel)(); \ No newline at end of file +typedef void(*Func_DrawViewModel)(); +typedef void(__cdecl* Func_ReloadStart)(HaloID, short, bool); +typedef void(*Func_ReloadEnd)(); \ No newline at end of file diff --git a/HaloCEVR/Hooking/Hooks.cpp b/HaloCEVR/Hooking/Hooks.cpp index 6e1fbf1..5696006 100644 --- a/HaloCEVR/Hooking/Hooks.cpp +++ b/HaloCEVR/Hooking/Hooks.cpp @@ -52,6 +52,8 @@ void Hooks::InitHooks() CREATEHOOK(DrawLoadingScreen2); CREATEHOOK(DrawCinematicBars); CREATEHOOK(DrawViewModel); + CREATEHOOK(ReloadStart); + CREATEHOOK(ReloadEnd); // These are handled with a direct patch, so manually scan them SigScanner::UpdateOffset(o.CutsceneFPSCap); @@ -99,6 +101,8 @@ void Hooks::EnableAllHooks() DrawLoadingScreen2.EnableHook(); DrawCinematicBars.EnableHook(); DrawViewModel.EnableHook(); + //ReloadStart.EnableHook(); + //ReloadEnd.EnableHook(); Freeze(); @@ -845,6 +849,39 @@ void Hooks::H_DrawViewModel() } } +void Hooks::H_ReloadStart(HaloID param1, short param2, bool param3) +{ + ReloadStart.Original(param1, param2, param3); + + Game::instance.ReloadStart(param1, param2, param3); +} + +void __declspec(naked) Hooks::H_ReloadEnd() +{ + static short param1; + static HaloID param2; + + _asm + { + mov param1, cx + push eax + mov eax, [esp + 0x8] + mov param2, eax + pop eax + push param2 + } + + ReloadEnd.Original(); + + Game::instance.ReloadEnd(param1, param2); + + _asm + { + add esp, 0x4 + ret; + } +} + //================================//Patches//================================// void Hooks::P_FixTabOut() diff --git a/HaloCEVR/Hooking/Hooks.h b/HaloCEVR/Hooking/Hooks.h index 591f67d..e1a63d0 100644 --- a/HaloCEVR/Hooking/Hooks.h +++ b/HaloCEVR/Hooking/Hooks.h @@ -41,6 +41,8 @@ class Hooks DEFINE_HOOK_FULL(DrawLoadingScreen2, void __fastcall, void* param1); DEFINE_HOOK(DrawCinematicBars); DEFINE_HOOK(DrawViewModel); + DEFINE_HOOK_FULL(ReloadStart, void __cdecl, HaloID param1, short param2, bool param3); + DEFINE_HOOK(ReloadEnd); // All direct patches go here: static void P_FixTabOut(); diff --git a/HaloCEVR/Hooking/SigScanner.h b/HaloCEVR/Hooking/SigScanner.h index d831149..7fbcbd7 100644 --- a/HaloCEVR/Hooking/SigScanner.h +++ b/HaloCEVR/Hooking/SigScanner.h @@ -72,6 +72,8 @@ class Offsets OFFSET(UpdateMouseInfo, 0x091bc0, "8b 01 53 55 8b 6c 24 0c 89 45 00 8b 51 04 f7 da 56"); OFFSET(FireWeapon, 0x0c3f10, "81 ec 94 00 00 00 8b 84 24 98 00 00 00 8b 0d ?? ?? ?? ?? 8b 51 34 53"); OFFSET(ThrowGrenade, 0x16e440, "8b 44 24 04 8b 0d ?? ?? ?? ?? 8b 51 34 8b 0d ?? ?? ?? ?? 83 ec 3c"); + OFFSET(ReloadStart, 0x0c35b0, "83 ec 0c 8b 54 24 10 53 55 0f bf 6c 24 1c 56 8b 35"); + OFFSET(ReloadEnd, 0x0c3900, "8b 44 24 04 8b 15 ?? ?? ?? ?? 8b 52 34 53 8b 1d ?? ?? ?? ?? 25 ff ff 00 00 55 56"); OFFSET(SetViewportSize, 0x0c8da0, "83 ec 10 53 55 56 57 8b f8 33 c0 83 ff 01 0f 9e c0"); OFFSET(SetViewportScale, 0x10ca90, "51 0f bf 50 2e 56 0f bf 70 30 57 0f bf 78 2c 2b f7"); From b498241b270772bc0ab22fa1bfe43473462b06b9 Mon Sep 17 00:00:00 2001 From: slipperfish Date: Mon, 16 Dec 2024 04:59:15 -0600 Subject: [PATCH 07/21] Update README.md Added Halo Refined info. Dsoal, chimera, and halo refined share a section with improvements --- README.md | 105 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 67 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 82a39b7..2511be1 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,73 @@ A full VR conversion mod for the original 2003 PC edition of _Halo: Combat Evolv 1. Go play the MCC version instead 2. Delete/rename the d3d9.dll you placed in the same directory as the halo executable (this contains all of the mod code and is only pretending to be d3d9 to trick halo into loading it). For example, you could rename it to d3d9-backup.dll. +## Graphical and Audio Enhancements, Restoration +### dsoal + +Dsoal allows you to turn on hardware acceleration and EAX in Halo without said hardware to enjoy environmental sound effects like reverb and HRTF(head-related transfer function), providing realistic, locatable 3D sound with high accuracy for virtual reality. Highly recommended even for low fidelity audio such as on Quest. (Notice: Doesn't currently work on first-person sounds) + +1) Download and extract https://github.com/ThreeDeeJay/dsoal/releases/download/0.9.6/DSOAL+HRTF.zip +2) Open the \Win32\ folder +3) Copy & paste all files (alsoft.ini, dsoal-aldrv.dll, dsound.dll) in your \Halo\halo.exe folder. +4) Edit and paste these settings into alsoft.ini: +``` + [general] +channels=stereo +frequency=48000 +stereo-mode=headphones +cf_level=0 +sources=512 +sample-type=float32 +hrtf=true +period_size=960 +hrtf-mode = full + +[reverb] +boost=-6 +``` +### chimera + +Chimera passively increases animation framerate, corrects some fog, boosts polygon limit, object limit, and draw distance. Highly recommended for comfort and bug fixes alone. + +See installation instructions above. If you installed chimera, you can execute commands to reduce pop-in and low detail models (lods), turn on anisotrophic filtering for sharper textures on world geometry, and turn on reverberation for first person sounds (requires dsoal). These are not turned on by default. There are several ways to do this. Please read about all 3 methods before proceeding. + +To launch the game in flat mode and use the console with the tilde ~ key, you can temporarily rename d3d9.dll to d3d9aa.dll. However executed console commands are saved and read from/to a text file, which you can navigate to and edit directly instead. + +Go to (Your User Folder)\Documents\My Games\Halo\chimera\preferences.txt, and add these commands. +``` +chimera_model_detail 8 +chimera_af 1 +chimera_fp_reverb 1 +``` +If you want these preferences to be portable and travel with your Halo installation: + +1) Create a new text file named chimera_preferences.txt in the \Halo\ folder along side chimera.ini +2) edit \Halo\chimera.ini +3) Do not paste the commands into chimera.ini, some of them will not work +5) chimera.ini comments(disables) lines with a semi-colon ```;```. Find ```exec=``` and remove any semi-colon on that line, such as ```;exec=``` +6) set the value to ```exec=./chimera_preferences.txt``` +7) paste the commands listed above into chimera_preferences.txt + +### Halo Refined + +When Halo was ported to PC in 2003, many graphical effects present in the original Xbox version were broken and outdated assets were accidentally used. Halo Refined is a community project that fixes many issues such as invisible bumpmapping, missing specular, broken transparency effects, etc and provides some faithful high resolution assets by replacing Halo's map files. + +Halo Refined is poorly tested with HaloCEVR but seems to work, recommended for experimental use. Please keep back ups of your original .map files before installing. If you are having any issues with HaloCEVR while using Refined's maps, restore the original files and retest before reporting your issue. + +Recent versions require chimera. Refined is designed with dgVoodoo2 and CEnshine in mind to fix even more effects, but these are tools and modifications can't be used with HaloCEVR. CEnshine is for Custom Edition only which HaloCEVR does not currently support. + +1) Download and extract the latest distribution for Retail, not Custom Edition +2) Backup all files in \Halo\maps\ +3) Replace files in \Halo\maps\ +4) (Optional) Read \Halo\maps\info.txt + +Download, updated as of the time of writing: +https://www.proxeninc.net/Halo/Refined/ + +Mirror, outdated as of the time of writing: +http://vaporeon.io/hosted/halo/refined/ + + ## FAQ ### Why the gearbox port and not MCC? Short answer: skill issue. @@ -116,44 +183,6 @@ Stand up straight (or sit up if playing seated) and hold down the menu button fo By default you crouch in real life. If you do not prefer that, change the option in the config.txt file in the VR folder, specifically set CrouchHeight = -1.0 and bind a button to crouch in the SteamVR Input menu. ### I wish (insert action) was bound to a different key Use SteamVR input settings to change your bindings to whatever you want. You can also search for other peoples' bindings for your controller in the bindings menu. You can learn how to use SteamVR input by watching this video by HoriZon, who also has bindings available for Quest controllers: https://www.youtube.com/watch?v=rdlCu7IjbGI. It's useful in a bunch of games! -### Textures seem to pop in too much. Any fix? -Try using chimera (highly recommended anyway) and create a file called chimera_preferences.txt in your Halo directory. In that text file, insert the following lines: -``` -chimera_model_detail 8 -chimera_lod 1 -``` -Then in your chimera.ini file, find the line that starts with ;exec= and change it to: -``` -exec=path\to\your\chimera_preferences.txt -``` -Example: -``` -exec=C:\HaloVRMod\Halo\chimera_preferences.txt -``` -Note that deleting the semicolon is what makes this line active. It's telling chimera to load the text commands you wrote that control the level of detail. If others share chimera commands in the future you can place them here. -You can test that the commands are being executed by changing the name of the VR mod dll file, d3d9.dll, to something else temporarily and booting the game up in flat screen. The commands will flash on the screen if this step worked. -#### How can I make sounds even more immersive? -Check out DSOAL for 3D sound ingame: https://github.com/ThreeDeeJay/dsoal/releases/tag/0.9.6, specific download zip link: https://github.com/ThreeDeeJay/dsoal/releases/download/0.9.6/DSOAL+HRTF.zip --Extract to a location on your computer. Inside the zip, find the Win32 folder, open it, and copy and paste all Win32 files into your Halo folder --One of the files will be called alsoft.ini which is a configuration file for DSOAL. - -Path: Halo>alsoft.ini - -Copy and Paste into alsoft.ini: -``` - [general] -channels=stereo -frequency=48000 -stereo-mode=headphones -cf_level=0 -sources=512 -sample-type=float32 -hrtf=true -period_size=960 - -[reverb] -boost=-6 -``` ### I know C++ coding or will learn to help develop the mod. How do I help? Thank you! See compiling source directions below and submit a Pull Request on Github explaining the changes you have made and impact on other files. Be sure to thoroughly test any changes before submitting them. After others and I test the changes, they may be incorporated into the mod release. From b7fe4e136bb8b3865b61a8dab8026af0e1cae09d Mon Sep 17 00:00:00 2001 From: slipperfish Date: Mon, 16 Dec 2024 05:01:48 -0600 Subject: [PATCH 08/21] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2511be1..20ee2f8 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ Chimera passively increases animation framerate, corrects some fog, boosts polyg See installation instructions above. If you installed chimera, you can execute commands to reduce pop-in and low detail models (lods), turn on anisotrophic filtering for sharper textures on world geometry, and turn on reverberation for first person sounds (requires dsoal). These are not turned on by default. There are several ways to do this. Please read about all 3 methods before proceeding. -To launch the game in flat mode and use the console with the tilde ~ key, you can temporarily rename d3d9.dll to d3d9aa.dll. However executed console commands are saved and read from/to a text file, which you can navigate to and edit directly instead. +To launch the game in flat mode and use the console with the tilde ~ key, you can disable the VR mod by temporarily renaming d3d9.dll to something like d3d9aa.dll. However executed console commands are saved and read from/to a text file, which you can navigate to and edit directly instead. Go to (Your User Folder)\Documents\My Games\Halo\chimera\preferences.txt, and add these commands. ``` From 1e69059edbd24ae42978dcaefbd3b150bfde3a2a Mon Sep 17 00:00:00 2001 From: slipperfish Date: Mon, 16 Dec 2024 05:12:48 -0600 Subject: [PATCH 09/21] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 20ee2f8..43e46a6 100644 --- a/README.md +++ b/README.md @@ -58,9 +58,9 @@ A full VR conversion mod for the original 2003 PC edition of _Halo: Combat Evolv Dsoal allows you to turn on hardware acceleration and EAX in Halo without said hardware to enjoy environmental sound effects like reverb and HRTF(head-related transfer function), providing realistic, locatable 3D sound with high accuracy for virtual reality. Highly recommended even for low fidelity audio such as on Quest. (Notice: Doesn't currently work on first-person sounds) 1) Download and extract https://github.com/ThreeDeeJay/dsoal/releases/download/0.9.6/DSOAL+HRTF.zip -2) Open the \Win32\ folder -3) Copy & paste all files (alsoft.ini, dsoal-aldrv.dll, dsound.dll) in your \Halo\halo.exe folder. -4) Edit and paste these settings into alsoft.ini: +2) Open the \DSOAL+HRTF\Win32\ folder +3) Copy & paste all files from \Win32\ (alsoft.ini, dsoal-aldrv.dll, dsound.dll) into your \Halo\ install folder where halo.exe is located. +4) Edit alsoft.ini and copy & paste these settings: ``` [general] channels=stereo @@ -84,7 +84,7 @@ See installation instructions above. If you installed chimera, you can execute c To launch the game in flat mode and use the console with the tilde ~ key, you can disable the VR mod by temporarily renaming d3d9.dll to something like d3d9aa.dll. However executed console commands are saved and read from/to a text file, which you can navigate to and edit directly instead. -Go to (Your User Folder)\Documents\My Games\Halo\chimera\preferences.txt, and add these commands. +Go to (Your User Folder)\Documents\My Games\Halo\chimera\preferences.txt, and add these commands: ``` chimera_model_detail 8 chimera_af 1 From 1feaf75c6d510b692ac56b8b5bf7d72556a43866 Mon Sep 17 00:00:00 2001 From: slipperfish Date: Mon, 16 Dec 2024 17:38:30 -0600 Subject: [PATCH 10/21] Update README.md --- README.md | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 43e46a6..533bd66 100644 --- a/README.md +++ b/README.md @@ -55,14 +55,16 @@ A full VR conversion mod for the original 2003 PC edition of _Halo: Combat Evolv ## Graphical and Audio Enhancements, Restoration ### dsoal -Dsoal allows you to turn on hardware acceleration and EAX in Halo without said hardware to enjoy environmental sound effects like reverb and HRTF(head-related transfer function), providing realistic, locatable 3D sound with high accuracy for virtual reality. Highly recommended even for low fidelity audio such as on Quest. (Notice: Doesn't currently work on first-person sounds) +Dsoal allows you to turn on hardware acceleration and EAX in Halo without requisite hardware to enjoy environmental sound effects like reverb and HRTF, providing realistic, locatable 3D sound with high accuracy for virtual reality. Highly recommended for even low fidelity headphones such as on Quest. -1) Download and extract https://github.com/ThreeDeeJay/dsoal/releases/download/0.9.6/DSOAL+HRTF.zip -2) Open the \DSOAL+HRTF\Win32\ folder -3) Copy & paste all files from \Win32\ (alsoft.ini, dsoal-aldrv.dll, dsound.dll) into your \Halo\ install folder where halo.exe is located. +Note: Chimera is required for reverb on first person sounds. HRTF does not work on first person sounds. + +1) Download and extract from https://github.com/ThreeDeeJay/dsoal/releases/download/0.9.6/DSOAL+HRTF.zip +2) Open the DSOAL+HRTF\Win32\ folder. +3) Copy & paste all files from Win32\ (alsoft.ini, dsoal-aldrv.dll, dsound.dll) into your Halo\ install folder where halo.exe is located. 4) Edit alsoft.ini and copy & paste these settings: ``` - [general] +[general] channels=stereo frequency=48000 stereo-mode=headphones @@ -78,39 +80,39 @@ boost=-6 ``` ### chimera -Chimera passively increases animation framerate, corrects some fog, boosts polygon limit, object limit, and draw distance. Highly recommended for comfort and bug fixes alone. +Chimera passively increases animation framerate, corrects some fog, boosts polygon limit, object limit, and draw distance, but is highly recommended for bug fixes and QOL changes alone. -See installation instructions above. If you installed chimera, you can execute commands to reduce pop-in and low detail models (lods), turn on anisotrophic filtering for sharper textures on world geometry, and turn on reverberation for first person sounds (requires dsoal). These are not turned on by default. There are several ways to do this. Please read about all 3 methods before proceeding. +See installation instructions above. If you installed chimera, you can execute console commands to reduce pop-in and low detail models (lods), turn on anisotrophic filtering for sharper textures on world geometry, and turn on reverberation for first person sounds (requires dsoal). These are not turned on by default. There are several ways to do this. Please read about all 3 methods before proceeding. -To launch the game in flat mode and use the console with the tilde ~ key, you can disable the VR mod by temporarily renaming d3d9.dll to something like d3d9aa.dll. However executed console commands are saved and read from/to a text file, which you can navigate to and edit directly instead. +* To launch the game in flat mode and use the console with the tilde ~ key, you can disable the VR mod by temporarily renaming d3d9.dll to something like d3d9aa.dll. -Go to (Your User Folder)\Documents\My Games\Halo\chimera\preferences.txt, and add these commands: +* However, executed console commands are saved and read from a text file, it might be easier to edit this file directly instead. After running Halo once with chimera installed, close Halo and go to (Your User Folder)\Documents\My Games\Halo\chimera\preferences.txt, and add these commands: ``` chimera_model_detail 8 chimera_af 1 chimera_fp_reverb 1 ``` -If you want these preferences to be portable and travel with your Halo installation: +* If you want these preferences to be portable and travel with your Halo installation: -1) Create a new text file named chimera_preferences.txt in the \Halo\ folder along side chimera.ini -2) edit \Halo\chimera.ini -3) Do not paste the commands into chimera.ini, some of them will not work +1) Create a new text file named chimera_preferences.txt in the Halo\ folder alongside chimera.ini +2) edit Halo\chimera.ini +3) Do not paste the commands into chimera.ini, some of them will not work. 5) chimera.ini comments(disables) lines with a semi-colon ```;```. Find ```exec=``` and remove any semi-colon on that line, such as ```;exec=``` 6) set the value to ```exec=./chimera_preferences.txt``` 7) paste the commands listed above into chimera_preferences.txt ### Halo Refined -When Halo was ported to PC in 2003, many graphical effects present in the original Xbox version were broken and outdated assets were accidentally used. Halo Refined is a community project that fixes many issues such as invisible bumpmapping, missing specular, broken transparency effects, etc and provides some faithful high resolution assets by replacing Halo's map files. +A Community project that restores many graphical effects present in the original Xbox version by replacing Halo's map files. Fixes issues such as invisible bumpmapping, missing specular, broken transparency effects, etc. Also provides some high res asset replacements, most notably an HD HUD. Halo Refined is poorly tested with HaloCEVR but seems to work, recommended for experimental use. Please keep back ups of your original .map files before installing. If you are having any issues with HaloCEVR while using Refined's maps, restore the original files and retest before reporting your issue. -Recent versions require chimera. Refined is designed with dgVoodoo2 and CEnshine in mind to fix even more effects, but these are tools and modifications can't be used with HaloCEVR. CEnshine is for Custom Edition only which HaloCEVR does not currently support. +Recent versions require chimera. Refined is designed with dgVoodoo2 and CEnshine in mind to fix even more effects, but these are tools and modifications can't be used with HaloCEVR. 1) Download and extract the latest distribution for Retail, not Custom Edition -2) Backup all files in \Halo\maps\ -3) Replace files in \Halo\maps\ -4) (Optional) Read \Halo\maps\info.txt +2) Backup all files in Halo\maps\ by copying them to a different location +3) Replace files in Halo\maps\ +4) (Optional) Read Halo\maps\info.txt Download, updated as of the time of writing: https://www.proxeninc.net/Halo/Refined/ From 935481506ca3b203471dae33966f0b3deb9661c8 Mon Sep 17 00:00:00 2001 From: slipperfish Date: Mon, 16 Dec 2024 17:46:48 -0600 Subject: [PATCH 11/21] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 533bd66..2ac449a 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,8 @@ Note: Chimera is required for reverb on first person sounds. HRTF does not work 1) Download and extract from https://github.com/ThreeDeeJay/dsoal/releases/download/0.9.6/DSOAL+HRTF.zip 2) Open the DSOAL+HRTF\Win32\ folder. 3) Copy & paste all files from Win32\ (alsoft.ini, dsoal-aldrv.dll, dsound.dll) into your Halo\ install folder where halo.exe is located. -4) Edit alsoft.ini and copy & paste these settings: +5) Edit alsoft.ini and copy & paste the settings shown below: +6) Launch Halo and go to Settings >> Audio Setup. Make sure Hardware Acceleration is set to Yes and Environmental Sound to EAX. ``` [general] channels=stereo From e1bbe01c878402bf102d836a559ae332ae02d227 Mon Sep 17 00:00:00 2001 From: slipperfish Date: Mon, 16 Dec 2024 19:46:06 -0600 Subject: [PATCH 12/21] Update README.md --- README.md | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 2ac449a..473663f 100644 --- a/README.md +++ b/README.md @@ -55,9 +55,9 @@ A full VR conversion mod for the original 2003 PC edition of _Halo: Combat Evolv ## Graphical and Audio Enhancements, Restoration ### dsoal -Dsoal allows you to turn on hardware acceleration and EAX in Halo without requisite hardware to enjoy environmental sound effects like reverb and HRTF, providing realistic, locatable 3D sound with high accuracy for virtual reality. Highly recommended for even low fidelity headphones such as on Quest. +Dsoal allows you to turn on hardware acceleration and EAX in Halo without requisite hardware to use environmental sound effects like reverb and HRTF, providing realistic, locatable 3D sound with high accuracy for virtual reality. Highly recommended, you do not need high-fidelity headphones to enjoy this. -Note: Chimera is required for reverb on first person sounds. HRTF does not work on first person sounds. +Note: Chimera is required for reverb on first person sounds. First person sounds have no stereo/HRTF/location effects. 1) Download and extract from https://github.com/ThreeDeeJay/dsoal/releases/download/0.9.6/DSOAL+HRTF.zip 2) Open the DSOAL+HRTF\Win32\ folder. @@ -81,39 +81,38 @@ boost=-6 ``` ### chimera -Chimera passively increases animation framerate, corrects some fog, boosts polygon limit, object limit, and draw distance, but is highly recommended for bug fixes and QOL changes alone. +Chimera increases animation framerate, corrects fog, enables anisotropic filtering, enables reverb for first person sounds (requires dsoal), and boosts polygon count, object limit, and draw distance. But is highly recommended for bug fixes and QOL changes alone. -See installation instructions above. If you installed chimera, you can execute console commands to reduce pop-in and low detail models (lods), turn on anisotrophic filtering for sharper textures on world geometry, and turn on reverberation for first person sounds (requires dsoal). These are not turned on by default. There are several ways to do this. Please read about all 3 methods before proceeding. +See installation instructions above. If you installed chimera, there is an enhancement not enabled by default. You can execute a console command ```chimera_model_detail 8``` to reduce pop-in and low detail models (lods). There are several ways to do this. -* To launch the game in flat mode and use the console with the tilde ~ key, you can disable the VR mod by temporarily renaming d3d9.dll to something like d3d9aa.dll. +* You can bring up the in-game console with tilde ~ key, but it helps to disable the VR mod by temporarily by renaming d3d9.dll to something like d3d9aa.dll so you can see the console. -* However, executed console commands are saved and read from a text file, it might be easier to edit this file directly instead. After running Halo once with chimera installed, close Halo and go to (Your User Folder)\Documents\My Games\Halo\chimera\preferences.txt, and add these commands: -``` -chimera_model_detail 8 -chimera_af 1 -chimera_fp_reverb 1 -``` -* If you want these preferences to be portable and travel with your Halo installation: +* Executed console commands are saved and read from a text file. You can create this file yourself: +1) Navigate to (Your User Folder)\Documents\My Games\Halo\chimera\ and create a text file named preferences.txt +2) Edit your preferences.txt and add ```chimera_model_detail 8``` + +* If you want this command and other preferences to be portable and travel with your Halo installation: 1) Create a new text file named chimera_preferences.txt in the Halo\ folder alongside chimera.ini -2) edit Halo\chimera.ini -3) Do not paste the commands into chimera.ini, some of them will not work. -5) chimera.ini comments(disables) lines with a semi-colon ```;```. Find ```exec=``` and remove any semi-colon on that line, such as ```;exec=``` -6) set the value to ```exec=./chimera_preferences.txt``` -7) paste the commands listed above into chimera_preferences.txt +2) Edit Halo\chimera.ini +3) Adding ```chimera_model_detail 8``` into chimera.ini will not work. +4) chimera.ini disables lines with a semi-colon ```;``` +5) Find ```exec=``` and remove any semi-colon on that line, such as ```;exec=```. +6) Set the value to ```exec=./chimera_preferences.txt``` +7) Add ```chimera_model_detail 8``` into chimera_preferences.txt ### Halo Refined A Community project that restores many graphical effects present in the original Xbox version by replacing Halo's map files. Fixes issues such as invisible bumpmapping, missing specular, broken transparency effects, etc. Also provides some high res asset replacements, most notably an HD HUD. -Halo Refined is poorly tested with HaloCEVR but seems to work, recommended for experimental use. Please keep back ups of your original .map files before installing. If you are having any issues with HaloCEVR while using Refined's maps, restore the original files and retest before reporting your issue. +Halo Refined is poorly tested with HaloCEVR but seems to work, recommended for experimental use. Please keep backups of your original .map files before installing. If you are having any issues with HaloCEVR while using Refined's maps, restore the original files and retest before reporting your issue. Recent versions require chimera. Refined is designed with dgVoodoo2 and CEnshine in mind to fix even more effects, but these are tools and modifications can't be used with HaloCEVR. 1) Download and extract the latest distribution for Retail, not Custom Edition 2) Backup all files in Halo\maps\ by copying them to a different location 3) Replace files in Halo\maps\ -4) (Optional) Read Halo\maps\info.txt +4) (Optional) Read Halo\maps\info.txt for project information Download, updated as of the time of writing: https://www.proxeninc.net/Halo/Refined/ From 99c273fce99db4fe8b1a2f669f9e31224a7597dc Mon Sep 17 00:00:00 2001 From: slipperfish Date: Mon, 16 Dec 2024 19:48:48 -0600 Subject: [PATCH 13/21] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 473663f..2cb45c8 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ A full VR conversion mod for the original 2003 PC edition of _Halo: Combat Evolv 1. Go play the MCC version instead 2. Delete/rename the d3d9.dll you placed in the same directory as the halo executable (this contains all of the mod code and is only pretending to be d3d9 to trick halo into loading it). For example, you could rename it to d3d9-backup.dll. -## Graphical and Audio Enhancements, Restoration +## Installing Graphical and Audio Enhancements ### dsoal Dsoal allows you to turn on hardware acceleration and EAX in Halo without requisite hardware to use environmental sound effects like reverb and HRTF, providing realistic, locatable 3D sound with high accuracy for virtual reality. Highly recommended, you do not need high-fidelity headphones to enjoy this. From d7e1e7a3ffb1dc9a66b6fbe419cf9935c8e44373 Mon Sep 17 00:00:00 2001 From: slipperfish Date: Mon, 16 Dec 2024 19:49:44 -0600 Subject: [PATCH 14/21] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2cb45c8..c9c366a 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ A full VR conversion mod for the original 2003 PC edition of _Halo: Combat Evolv ## Installing Graphical and Audio Enhancements ### dsoal -Dsoal allows you to turn on hardware acceleration and EAX in Halo without requisite hardware to use environmental sound effects like reverb and HRTF, providing realistic, locatable 3D sound with high accuracy for virtual reality. Highly recommended, you do not need high-fidelity headphones to enjoy this. +Dsoal allows you to turn on hardware acceleration and EAX in Halo without requisite hardware to use environmental sound effects like reverb and HRTF, providing realistic, locatable 3D sound with high accuracy for virtual reality. Highly recommended, and you do not need high-fidelity headphones to enjoy this. Note: Chimera is required for reverb on first person sounds. First person sounds have no stereo/HRTF/location effects. From cf25990e2d14197c3874d523d7811baef3d0f713 Mon Sep 17 00:00:00 2001 From: slipperfish Date: Mon, 16 Dec 2024 19:52:53 -0600 Subject: [PATCH 15/21] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c9c366a..2946986 100644 --- a/README.md +++ b/README.md @@ -87,11 +87,11 @@ See installation instructions above. If you installed chimera, there is an enhan * You can bring up the in-game console with tilde ~ key, but it helps to disable the VR mod by temporarily by renaming d3d9.dll to something like d3d9aa.dll so you can see the console. -* Executed console commands are saved and read from a text file. You can create this file yourself: +* Or, executed console commands are saved and read from a text file. You can create this file yourself: 1) Navigate to (Your User Folder)\Documents\My Games\Halo\chimera\ and create a text file named preferences.txt 2) Edit your preferences.txt and add ```chimera_model_detail 8``` -* If you want this command and other preferences to be portable and travel with your Halo installation: +* Or, If you want this command and other preferences to be portable and travel with your Halo installation: 1) Create a new text file named chimera_preferences.txt in the Halo\ folder alongside chimera.ini 2) Edit Halo\chimera.ini From cb1df1a1396b87212ddd6f3c38412ab9c670b8dc Mon Sep 17 00:00:00 2001 From: slipperfish Date: Mon, 16 Dec 2024 20:11:28 -0600 Subject: [PATCH 16/21] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2946986..552ab32 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,9 @@ Note: Chimera is required for reverb on first person sounds. First person sounds 2) Open the DSOAL+HRTF\Win32\ folder. 3) Copy & paste all files from Win32\ (alsoft.ini, dsoal-aldrv.dll, dsound.dll) into your Halo\ install folder where halo.exe is located. 5) Edit alsoft.ini and copy & paste the settings shown below: -6) Launch Halo and go to Settings >> Audio Setup. Make sure Hardware Acceleration is set to Yes and Environmental Sound to EAX. +6) ```hrtf-mode = full``` may or may not be CPU intensive, remove if you experience new performance issues. +7) Launch Halo and go to Settings >> Audio Setup. Make sure Hardware Acceleration is set to Yes and Environmental Sound to EAX. + ``` [general] channels=stereo From e4db3d0d3856135a444c16b21d97f16e6f9c9f60 Mon Sep 17 00:00:00 2001 From: LivingFray <5647734+LivingFray@users.noreply.github.com> Date: Tue, 17 Dec 2024 15:06:54 +0000 Subject: [PATCH 17/21] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 552ab32..610ff01 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ A full VR conversion mod for the original 2003 PC edition of _Halo: Combat Evolv ## Known issues * Game sometimes isn't the focused window on launch and inputs/sounds may break when the game is unfocused -* First stage of the tutorial ("look around") doesn't detect headset movement, wiggle the mouse and you should get passed it +* First stage of the tutorial ("look around") doesn't detect headset movement, wiggle the mouse (physically or via steamvr's desktop view) and you should get past it * Camera behaves weirdly briefly when entering/exiting vehicles * Reloading a checkpoint made while in a vehicle can mess with the camera position, get out and in again to fix it * Melee and interact use head aiming rather than controller aiming @@ -39,9 +39,9 @@ A full VR conversion mod for the original 2003 PC edition of _Halo: Combat Evolv * Some people report a minor distortion or warping effect when tilting their head side to side. ## Installation -0. Install _Halo: Combat Evolved for PC_ (not Custom Edition) using an original installation CD + product key. IMPORTANT: Install in a directory OTHER THAN Program Files (example: C:\HaloVRMod\Halo). Installing in Program Files potentailly causes numerous permissions-related issues. -1. Install the 1.10 patch for PC (not Custom Edition) -2. (Optional) Install [chimera](https://github.com/SnowyMouse/chimera) (fixes a few bugs/issues such as entities moving at 30fps). Grab the RELEASE files from [releases](https://github.com/SnowyMouse/chimera/releases/download/1.0.0r1021/chimera-1.0.0r1021.10144368.7z). Copy chimera.ini, strings.dll, and the fonts folder from the chimera zip after unzipping and place into your halo game folder in the same location as halo.exe. +0. Install _Halo: Combat Evolved for PC_ (not Custom Edition) using an original installation CD + product key. **IMPORTANT: Install in a directory OTHER THAN Program Files (example: C:\HaloVRMod\Halo). Installing in Program Files potentailly causes numerous permissions-related issues**. +1. Install the 1.0.10 patch for PC (not Custom Edition) +2. (Optional) Install [chimera](https://github.com/SnowyMouse/chimera) (fixes a few bugs/issues such as entities moving at 30fps). Grab the RELEASE files from [releases](https://github.com/SnowyMouse/chimera/releases). Copy chimera.ini, strings.dll, and the fonts folder from the chimera zip after unzipping and place into your halo game folder in the same location as halo.exe. 3. If using chimera: open chimera.ini, locate the "Font Override Settings" section, and change enabled=1 to enabled=0 (failing to do this will break many UI elements in VR) 4. Download the latest version of this mod from the [releases page](../../releases) 5. Extract HaloCEVR.zip and place the files in the same directory as the halo executable (You should see a VR folder, openvr_api.dll and d3d9.dll if done correctly - if you do not see these files your antivirus may be interfering) @@ -81,7 +81,7 @@ hrtf-mode = full [reverb] boost=-6 ``` -### chimera +### Chimera Chimera increases animation framerate, corrects fog, enables anisotropic filtering, enables reverb for first person sounds (requires dsoal), and boosts polygon count, object limit, and draw distance. But is highly recommended for bug fixes and QOL changes alone. @@ -134,13 +134,13 @@ As you may guess, this is hard. By focusing on an older title I have a simpler p ### Where do I even get a CD copy in \? Can I use a cracked version? No. -This mod is intended to only be used with legitimate copies of Halo: Combat Evolved with the official 1.10 patch. Fortunately the product keys aren't single use, so if you can find a second hand copy (or a friend willing to lend the copy they happened to archive 20 years ago) you can use that without worrying about the key being invalid. +This mod is intended to only be used with legitimate copies of Halo: Combat Evolved with the official 1.10 patch. Fortunately the product keys aren't single use, so if you can find a second hand copy (or a friend/person on the _internet_ willing to lend the copy they happened to _archive_ 20 years ago) you can use that without worrying about the key being invalid. ### Does multiplayer work? This mod was designed for singleplayer, it is untested in multiplayer and as such some features, such as weapon aiming, may not function or only work for the host. Also it does not work in Co-op because this version of the game does not have that mode. ### Does this work with Custom Edition? -No. +Not currently. ### Does this work with MCC Edition? No. ### Does this work with SPV3? From 8ee7c3c9f4f89d5b1995aa3d13acea1c3f5b3ca3 Mon Sep 17 00:00:00 2001 From: LivingFray Date: Tue, 17 Dec 2024 16:37:25 +0000 Subject: [PATCH 18/21] Changed more magic numbers for compatibility with something --- HaloCEVR/Hooking/Hooks.cpp | 2 +- HaloCEVR/Hooking/SigScanner.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/HaloCEVR/Hooking/Hooks.cpp b/HaloCEVR/Hooking/Hooks.cpp index 5696006..05c500f 100644 --- a/HaloCEVR/Hooking/Hooks.cpp +++ b/HaloCEVR/Hooking/Hooks.cpp @@ -916,7 +916,7 @@ void Hooks::P_EnableUIAlphaWrite() { // By default the UI doesn't write to the alpha channel (since its being drawn last + straight onto the main image) // We need the alpha value in order to have transparency in floating UI elements - SetByte(o.TextureAlphaWrite.Address + 0x4a, 0xf); + SetByte(o.TextureAlphaWrite.Address + 0x19, 0xf); SetByte(o.TextAlphaWrite.Address + 0x72, 0xf); } diff --git a/HaloCEVR/Hooking/SigScanner.h b/HaloCEVR/Hooking/SigScanner.h index 7fbcbd7..3cfe126 100644 --- a/HaloCEVR/Hooking/SigScanner.h +++ b/HaloCEVR/Hooking/SigScanner.h @@ -48,7 +48,7 @@ class Offsets OFFSET(CutsceneFPSCap, 0x0c9fb5, "b3 01 eb ?? 32 db 8b 2d ?? ?? ?? ?? 8d 4c"); OFFSET(CreateMouseDevice, 0x0919c0, "6a 17 ff 15 ?? ?? ?? ?? 85 c0 74 ?? 66 c7 05 ?? ?? ?? ?? 02 00"); OFFSET(SetViewModelVisible, 0x092430, "51 8b 0d ?? ?? ?? ?? 66 83 f9 ff 74 ?? 8b 15 ?? ?? ?? ?? 56 0f bf f1"); - OFFSET(TextureAlphaWrite, 0x11c9a0, "81 ec ?? ?? 00 00 56 8b f0 a0 ?? ?? ?? ?? 84 c0"); + OFFSET(TextureAlphaWrite, 0x11c9d1, "6a 01 6a 16 33 ?? 50 89 ?? ?? ?? ff 91 e4 00 00 00 a1 ?? ?? ?? ?? 8b 10 6a 07 68 a8 00 00 00 50 ff 92 e4 00 00 00 a1 ?? ?? ?? ?? 8b 08 6a 01 6a 1b 50"); OFFSET(TextAlphaWrite, 0x131b80, "a0 ?? ?? ?? ?? 84 c0 0f 84 ?? ?? ?? ?? 66 83 ?? ?? ?? ?? 00 01 0f 85 ?? ?? ?? ?? 53 55 56"); OFFSET(CrouchHeight, 0x168ff0, "d9 86 0c 05 00 00 f6 86 cc 04 00 00 01 75 ?? d8 15"); OFFSET(CinematicBarDrawCall, 0x049b25, "e8 ?? ?? ?? ?? 0f bf 15 ?? ?? ?? ?? 89 54 24 18 db 44 24 18 d9 5c 24 18 d9 44 24 18"); From 8ccd2197038dc75a5644e7c9808142abe80a7c42 Mon Sep 17 00:00:00 2001 From: LivingFray Date: Wed, 18 Dec 2024 01:14:23 +0000 Subject: [PATCH 19/21] Added rudimentary profiler for use in dev builds/testing --- HaloCEVR/Game.cpp | 196 +++++++++++++++++++++++++++++- HaloCEVR/Game.h | 10 +- HaloCEVR/HaloCEVR.vcxproj | 2 + HaloCEVR/HaloCEVR.vcxproj.filters | 6 + HaloCEVR/Hooking/Hooks.cpp | 39 +++++- HaloCEVR/Profiler.cpp | 79 ++++++++++++ HaloCEVR/Profiler.h | 75 ++++++++++++ HaloCEVR/VR/OpenVR.cpp | 39 +++++- 8 files changed, 435 insertions(+), 11 deletions(-) create mode 100644 HaloCEVR/Profiler.cpp create mode 100644 HaloCEVR/Profiler.h diff --git a/HaloCEVR/Game.cpp b/HaloCEVR/Game.cpp index 21d39d3..10b682d 100644 --- a/HaloCEVR/Game.cpp +++ b/HaloCEVR/Game.cpp @@ -16,11 +16,19 @@ #include "VR/OpenVR.h" #endif +#if USE_PROFILER +#include +#endif + void Game::Init() { Logger::log << "[Game] HaloCEVR initialising..." << std::endl; +#if USE_PROFILER + profiler.Init(); +#endif + SetupConfigs(); CreateConsole(); @@ -57,6 +65,10 @@ void Game::Shutdown() vr->Shutdown(); +#if USE_PROFILER + profiler.Shutdown(); +#endif + MH_STATUS hookStatus = MH_DisableHook(MH_ALL_HOOKS); if (hookStatus != MH_OK) @@ -110,6 +122,8 @@ void Game::OnInitDirectX() void Game::PreDrawFrame(struct Renderer* renderer, float deltaTime) { + VR_PROFILE_SCOPE(Game_PreDrawFrame); + lastDeltaTime = deltaTime; renderState = ERenderState::UNKNOWN; @@ -137,6 +151,7 @@ void Game::PreDrawFrame(struct Renderer* renderer, float deltaTime) window->right = vr->GetViewWidth(); window->bottom = vr->GetViewHeight(); + VR_PROFILE_START(Game_PreDrawFrame_ClearSurfaces); // Clear UI surfaces IDirect3DSurface9* currentSurface = nullptr; Helpers::GetDirect3DDevice9()->GetRenderTarget(0, ¤tSurface); @@ -148,6 +163,7 @@ void Game::PreDrawFrame(struct Renderer* renderer, float deltaTime) Helpers::GetDirect3DDevice9()->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 0, 0, 0), 1.0f, 0); Helpers::GetDirect3DDevice9()->SetRenderTarget(0, currentSurface); currentSurface->Release(); + VR_PROFILE_STOP(Game_PreDrawFrame_ClearSurfaces); frustum1 = renderer->frustum; frustum2 = renderer->frustum2; @@ -176,6 +192,8 @@ void Game::PreDrawFrame(struct Renderer* renderer, float deltaTime) if (c_ShowRoomCentre->Value()) { + VR_PROFILE_SCOPE(Game_PreDrawFrame_DrawRoomCentre); + Vector3 position = Helpers::GetCamera().position; position.z -= 0.62f; Vector3 upVector(0.0f, 0.0f, 1.0f); @@ -226,6 +244,8 @@ void Game::PreDrawFrame(struct Renderer* renderer, float deltaTime) void Game::PreDrawEye(Renderer* renderer, float deltaTime, int eye) { + VR_PROFILE_SCOPE(Game_PreDrawEye); + renderState = eye == 0 ? ERenderState::LEFT_EYE : ERenderState::RIGHT_EYE; renderer->frustum = frustum1; @@ -247,6 +267,8 @@ void Game::PreDrawEye(Renderer* renderer, float deltaTime, int eye) void Game::PostDrawEye(struct Renderer* renderer, float deltaTime, int eye) { + VR_PROFILE_SCOPE(Game_PostDrawEye); + if (Helpers::IsLoading() || Helpers::IsCampaignLoading()) { Helpers::GetDirect3DDevice9()->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0); @@ -257,6 +279,8 @@ void Game::PostDrawEye(struct Renderer* renderer, float deltaTime, int eye) bool Game::PreDrawScope(Renderer* renderer, float deltaTime) { + VR_PROFILE_SCOPE(Game_PreDrawScope); + UnitDynamicObject* player = static_cast(Helpers::GetLocalPlayer()); if (!player || player->zoom == -1) @@ -325,6 +349,8 @@ bool Game::PreDrawScope(Renderer* renderer, float deltaTime) void Game::PostDrawScope(Renderer* renderer, float deltaTime) { + VR_PROFILE_SCOPE(Game_PostDrawScope); + RestoreRenderTargets(); Vector2 innerSize = Vector2(0.0f, 0.0f); @@ -354,6 +380,8 @@ void Game::PostDrawScope(Renderer* renderer, float deltaTime) void Game::PreDrawMirror(struct Renderer* renderer, float deltaTime) { + VR_PROFILE_SCOPE(Game_PreDrawMirror); + renderState = ERenderState::GAME; renderer->frustum = frustum1; @@ -372,6 +400,8 @@ void Game::PreDrawMirror(struct Renderer* renderer, float deltaTime) void Game::PostDrawMirror(struct Renderer* renderer, float deltaTime) { + VR_PROFILE_SCOPE(Game_PostDrawMirror); + // Do something here to copy the image into the backbuffer correctly inGameRenderer.ClearRenderTargets(); @@ -380,6 +410,8 @@ void Game::PostDrawMirror(struct Renderer* renderer, float deltaTime) void Game::PostDrawFrame(struct Renderer* renderer, float deltaTime) { + VR_PROFILE_START(Game_PostDrawFrame); + RestoreRenderTargets(); vr->PostDrawFrame(renderer, deltaTime); inGameRenderer.PostRender(); @@ -392,6 +424,8 @@ void Game::PostDrawFrame(struct Renderer* renderer, float deltaTime) if (c_DrawMirror->Value() && mirrorSource != ERenderState::GAME) { + VR_PROFILE_SCOPE(Game_PostDrawFrame_Mirror); + int sWidth = vr->GetViewWidth(); int sHeight = vr->GetViewHeight(); @@ -443,10 +477,18 @@ void Game::PostDrawFrame(struct Renderer* renderer, float deltaTime) currentSurface->Release(); Helpers::GetDirect3DDevice9()->StretchRect(vr->GetRenderSurface(eye), nullptr, Helpers::GetRenderTargets()[0].renderSurface, &destRect, D3DTEXF_LINEAR); } + + VR_PROFILE_STOP(Game_PostDrawFrame); + +#if USE_PROFILER + profiler.NewFrame(); +#endif } bool Game::PreDrawHUD() { + VR_PROFILE_SCOPE(Game_PreDrawHUD); + // Only render UI once per frame if (GetRenderState() != ERenderState::LEFT_EYE) { @@ -488,6 +530,8 @@ bool Game::PreDrawHUD() void Game::PostDrawHUD() { + VR_PROFILE_SCOPE(Game_PostDrawHUD); + // Only render UI once per frame if (GetRenderState() != ERenderState::LEFT_EYE) { @@ -517,6 +561,8 @@ void Game::PostDrawHUD() bool Game::PreDrawMenu() { + VR_PROFILE_SCOPE(Game_PreDrawMenu); + // Only render UI once per frame if (GetRenderState() != ERenderState::LEFT_EYE) { @@ -534,6 +580,8 @@ bool Game::PreDrawMenu() void Game::PostDrawMenu() { + VR_PROFILE_SCOPE(Game_PostDrawMenu); + // Only render UI once per frame if (GetRenderState() != ERenderState::LEFT_EYE) { @@ -547,6 +595,8 @@ void Game::PostDrawMenu() D3DVIEWPORT9 currentViewport; bool Game::PreDrawLoading(int param1, struct Renderer* renderer) { + VR_PROFILE_SCOPE(Game_PreDrawLoading); + // Only render UI once per frame if (GetRenderState() != ERenderState::LEFT_EYE) { @@ -562,6 +612,8 @@ bool Game::PreDrawLoading(int param1, struct Renderer* renderer) void Game::PostDrawLoading(int param1, struct Renderer* renderer) { + VR_PROFILE_SCOPE(Game_PostDrawLoading); + // Only render UI once per frame if (GetRenderState() != ERenderState::LEFT_EYE) { @@ -573,6 +625,8 @@ void Game::PostDrawLoading(int param1, struct Renderer* renderer) bool Game::PreDrawCrosshair(short* anchorLocation) { + VR_PROFILE_SCOPE(Game_PreDrawCrosshair); + // Draw things normally for the scope if (GetRenderState() == ERenderState::SCOPE) { @@ -595,6 +649,8 @@ bool Game::PreDrawCrosshair(short* anchorLocation) void Game::PostDrawCrosshair() { + VR_PROFILE_SCOPE(Game_PostDrawCrosshair); + // Draw things normally for the scope if (GetRenderState() == ERenderState::SCOPE) { @@ -607,6 +663,8 @@ void Game::PostDrawCrosshair() void Game::PreDrawImage(void* param1, void* param2) { + VR_PROFILE_SCOPE(Game_PreDrawImage); + Helpers::GetDirect3DDevice9()->GetRenderState(D3DRS_ALPHAFUNC, &realAlphaFunc); Helpers::GetDirect3DDevice9()->GetRenderState(D3DRS_SRCBLENDALPHA, &realAlphaSrc); Helpers::GetDirect3DDevice9()->GetRenderState(D3DRS_DESTBLENDALPHA, &realAlphaDest); @@ -621,6 +679,8 @@ void Game::PreDrawImage(void* param1, void* param2) void Game::PostDrawImage(void* param1, void* param2) { + VR_PROFILE_SCOPE(Game_PostDrawImage); + DWORD tmp1, tmp2, tmp3; Helpers::GetDirect3DDevice9()->GetRenderState(D3DRS_ALPHAFUNC, &tmp1); @@ -636,46 +696,68 @@ void Game::PostDrawImage(void* param1, void* param2) void Game::UpdateViewModel(HaloID& id, Vector3* pos, Vector3* facing, Vector3* up, TransformQuat* BoneTransforms, Transform* OutBoneTransforms) { + VR_PROFILE_SCOPE(Game_UpdateViewModel); weaponHandler.UpdateViewModel(id, pos, facing, up, BoneTransforms, OutBoneTransforms); } void Game::PreFireWeapon(HaloID& weaponID, short param2) { + VR_PROFILE_SCOPE(Game_PreFireWeapon); weaponHandler.PreFireWeapon(weaponID, param2); } void Game::PostFireWeapon(HaloID& weaponID, short param2) { + VR_PROFILE_SCOPE(Game_PostFireWeapon); weaponHandler.PostFireWeapon(weaponID, param2); } void Game::PreThrowGrenade(HaloID& playerID) { + VR_PROFILE_SCOPE(Game_PreThrowGrenade); weaponHandler.PreThrowGrenade(playerID); } void Game::PostThrowGrenade(HaloID& playerID) { + VR_PROFILE_SCOPE(Game_PostThrowGrenade); weaponHandler.PostThrowGrenade(playerID); } void Game::UpdateInputs() { + VR_PROFILE_SCOPE(Game_UpdateInputs); inputHandler.UpdateInputs(bInVehicle); + +#if USE_PROFILER + static bool bWasPressed = false; + + bool bPressed = GetAsyncKeyState(VK_F5) & 0x8000; + + if (bPressed && !bWasPressed) + { + DumpProfilerData(); + } + + bWasPressed = bPressed; +#endif } void Game::CalculateSmoothedInput() { - inputHandler.CalculateSmoothedInput(); + VR_PROFILE_SCOPE(Game_CalculateSmoothedInput); + inputHandler.CalculateSmoothedInput(); } bool Game::GetCalculatedHandPositions(Matrix4& controllerTransform, Vector3& dominantHandPos, Vector3& offHand) { + VR_PROFILE_SCOPE(Game_GetCalculatedHandPositions); return inputHandler.GetCalculatedHandPositions(controllerTransform, dominantHandPos, offHand); } void Game::ReloadStart(HaloID param1, short param2, bool param3) { + VR_PROFILE_SCOPE(Game_ReloadStart); // TODO: Check if this reload was from the player (can probably be done by checking the weapon's parent ID matches the player) WeaponDynamicObject* weaponObject = static_cast((Helpers::GetDynamicObject(param1))); @@ -690,16 +772,18 @@ void Game::ReloadStart(HaloID param1, short param2, bool param3) void Game::ReloadEnd(short param1, HaloID param2) { + VR_PROFILE_SCOPE(Game_ReloadEnd); Logger::log << "Reload End" << std::endl; } -Vector3 Game::GetSmoothedInput() +Vector3 Game::GetSmoothedInput() const { return inputHandler.smoothedPosition; } void Game::UpdateCamera(float& yaw, float& pitch) { + VR_PROFILE_SCOPE(Game_UpdateCamera); // Don't bother simulating inputs if we aren't actually in vr #if EMULATE_VR return; @@ -717,6 +801,7 @@ void Game::UpdateCamera(float& yaw, float& pitch) void Game::SetMousePosition(int& x, int& y) { + VR_PROFILE_SCOPE(Game_SetMousePosition); // Don't bother simulating inputs if we aren't actually in vr #if EMULATE_VR return; @@ -726,6 +811,7 @@ void Game::SetMousePosition(int& x, int& y) void Game::UpdateMouseInfo(MouseInfo* mouseInfo) { + VR_PROFILE_SCOPE(Game_UpdateMouseInfo); // Don't bother simulating inputs if we aren't actually in vr #if EMULATE_VR return; @@ -735,6 +821,7 @@ void Game::UpdateMouseInfo(MouseInfo* mouseInfo) void Game::SetViewportScale(Viewport* viewport) { + VR_PROFILE_SCOPE(Game_SetViewportScale); // This appears to be broken, the code this is overriding does something very weird with the scaling /* viewport->left = -1.0f; @@ -772,6 +859,7 @@ void Game::CreateConsole() void Game::PatchGame() { + VR_PROFILE_SCOPE(Game_PatchGame); MH_STATUS hookStatus; if ((hookStatus = MH_Initialize()) != MH_OK) @@ -789,6 +877,8 @@ void Game::PatchGame() void Game::SetupConfigs() { + VR_PROFILE_SCOPE(Game_SetupConfigs); + Config config; // Window settings @@ -849,7 +939,7 @@ void Game::SetupConfigs() const bool bLoadedConfig = config.LoadFromFile("VR/config.txt"); const bool bSavedConfig = config.SaveToFile("VR/config.txt"); - + if (!bLoadedConfig) { Logger::log << "[Config] First time startup, generating default config file" << std::endl; @@ -859,7 +949,7 @@ void Game::SetupConfigs() { Logger::log << "[Config] Couldn't save config file, halo is likely running as non-administrator from a protected directory" << std::endl; } - + // First run, but couldn't create config file if (!bLoadedConfig && !bSavedConfig) { @@ -905,14 +995,100 @@ void Game::CalcFPS(float deltaTime) } } +#if USE_PROFILER +void Game::DumpProfilerData() +{ + VR_PROFILE_SCOPE(Game_DumpProfilerData); + + // TODO: Create a better system for viewing this data (e.g. real time display/proper dedicated profile files) + std::vector frameTimings; + Game::instance.profiler.GetTimings(frameTimings); + + Logger::log << "[Profiler] Dumping last 30 seconds of profiler data..." << std::endl; + + float minFrame = FLT_MAX; + float maxFrame = -FLT_MAX; + float totalFrame = 0.0f; + int numFrames = 0; + + Profiler::time_point now = std::chrono::high_resolution_clock::now(); + + std::unordered_map totalTimes; + + for (auto it = frameTimings.rbegin(); it != frameTimings.rend(); ++it) + { + float ago = std::chrono::duration(now - (*it)->frameEnd).count(); + if (ago > 30.0f * 1000.0f) + { + break; + } + + float duration = std::chrono::duration((*it)->frameEnd - (*it)->frameStart).count(); + + minFrame = (std::min)(minFrame, duration); + maxFrame = (std::max)(maxFrame, duration); + totalFrame += duration; + numFrames++; + + for (auto& kv : (*it)->timings) + { + const std::string& eventName = kv.first; + const Profiler::Timings* timings = kv.second; + /* + Logger::log << "[Profiler] " + << eventName + << ": calls " << timings->numHits + << " min. " << timings->minTime + << " avg. " << timings->totalTime / timings->numHits + << " max. " << timings->maxTime + << std::endl; + */ + + totalTimes[eventName].minTime = (std::min)(totalTimes[eventName].minTime, timings->minTime); + totalTimes[eventName].maxTime = (std::max)(totalTimes[eventName].maxTime, timings->maxTime); + totalTimes[eventName].numHits += timings->numHits; + totalTimes[eventName].totalTime += timings->totalTime; + } + } + + Logger::log << "[Profiler] Frame times: min. " << minFrame << " avg. " << (totalFrame / numFrames) << " max. " << maxFrame << std::endl; + Logger::log << "[Profiler] Total Event times: " << std::endl; + + std::vector> topTimings; + for (auto& kv : totalTimes) + { + topTimings.push_back(kv); + } + + std::sort(topTimings.begin(), topTimings.end(), [](const auto& a, const auto& b) + { + return a.second.totalTime > b.second.totalTime; + } + ); + + for (auto& kv : topTimings) + { + Logger::log << "[Profiler] " + << kv.first + << ": calls " << kv.second.numHits + << " min. " << kv.second.minTime + << " avg. " << kv.second.totalTime / kv.second.numHits + << " max. " << kv.second.maxTime + << std::endl; + } +} +#endif + void Game::UpdateCrosshairAndScope() { + VR_PROFILE_SCOPE(Game_UpdateCrosshairAndScope); + auto fixupRotation = [](Matrix4& m, Vector3& pos) { m.translate(-pos); m.rotate(90.0f, m.getUpAxis()); m.rotate(-90.0f, m.getLeftAxis()); m.translate(pos); - }; + }; Vector3 aimPos, aimDir; @@ -939,7 +1115,7 @@ void Game::UpdateCrosshairAndScope() overlayTransform.translate(targetPos); overlayTransform.lookAt(hmdPos, Vector3(0.0f, 0.0f, 1.0f)); - + fixupRotation(overlayTransform, targetPos); if (c_ShowCrosshair->Value()) @@ -970,6 +1146,8 @@ void Game::UpdateCrosshairAndScope() void Game::SetScopeTransform(Matrix4& newTransform, bool bIsVisible) { + VR_PROFILE_SCOPE(Game_SetScopeTransform); + if (!bIsVisible) { return; @@ -1006,6 +1184,8 @@ void Game::SetScopeTransform(Matrix4& newTransform, bool bIsVisible) void Game::StoreRenderTargets() { + VR_PROFILE_SCOPE(Game_StoreRenderTargets); + for (int i = 0; i < 8; i++) { gameRenderTargets[i].width = Helpers::GetRenderTargets()[i].width; @@ -1018,6 +1198,8 @@ void Game::StoreRenderTargets() void Game::RestoreRenderTargets() { + VR_PROFILE_SCOPE(Game_RestoreRenderTargets); + for (int i = 0; i < 8; i++) { Helpers::GetRenderTargets()[i].width = gameRenderTargets[i].width; @@ -1030,6 +1212,8 @@ void Game::RestoreRenderTargets() void Game::CreateTextureAndSurface(UINT Width, UINT Height, DWORD Usage, D3DFORMAT Format, IDirect3DSurface9** OutSurface, IDirect3DTexture9** OutTexture) { + VR_PROFILE_SCOPE(Game_CreateTextureAndSurface); + HRESULT result = Helpers::GetDirect3DDevice9()->CreateTexture(Width, Height, 1, Usage, Format, D3DPOOL_DEFAULT, OutTexture, nullptr); if (FAILED(result)) { diff --git a/HaloCEVR/Game.h b/HaloCEVR/Game.h index c2e5576..6d15c9b 100644 --- a/HaloCEVR/Game.h +++ b/HaloCEVR/Game.h @@ -12,6 +12,7 @@ #include "WeaponHandler.h" #include "InputHandler.h" #include "InGameRenderer.h" +#include "Profiler.h" enum class ERenderState { UNKNOWN, LEFT_EYE, RIGHT_EYE, GAME, SCOPE}; @@ -32,7 +33,7 @@ class Game void PreDrawMirror(struct Renderer* renderer, float deltaTime); void PostDrawMirror(struct Renderer* renderer, float deltaTime); void PostDrawFrame(struct Renderer* renderer, float deltaTime); - Vector3 GetSmoothedInput(); + Vector3 GetSmoothedInput() const; bool PreDrawHUD(); void PostDrawHUD(); @@ -93,6 +94,10 @@ class Game bool bDetectedChimera = false; Vector3 LastLookDir; + +#if USE_PROFILER + Profiler profiler; +#endif protected: void CreateConsole(); @@ -102,6 +107,9 @@ class Game void SetupConfigs(); void CalcFPS(float deltaTime); +#if USE_PROFILER + void DumpProfilerData(); +#endif void UpdateCrosshairAndScope(); void SetScopeTransform(Matrix4& newTransform, bool bIsVisible); diff --git a/HaloCEVR/HaloCEVR.vcxproj b/HaloCEVR/HaloCEVR.vcxproj index 62787ad..b4bf929 100644 --- a/HaloCEVR/HaloCEVR.vcxproj +++ b/HaloCEVR/HaloCEVR.vcxproj @@ -184,6 +184,7 @@ + @@ -213,6 +214,7 @@ + diff --git a/HaloCEVR/HaloCEVR.vcxproj.filters b/HaloCEVR/HaloCEVR.vcxproj.filters index 925fbce..ef7da09 100644 --- a/HaloCEVR/HaloCEVR.vcxproj.filters +++ b/HaloCEVR/HaloCEVR.vcxproj.filters @@ -87,6 +87,9 @@ Source Files + + Source Files + @@ -176,6 +179,9 @@ Header Files + + Header Files + diff --git a/HaloCEVR/Hooking/Hooks.cpp b/HaloCEVR/Hooking/Hooks.cpp index 05c500f..58158bc 100644 --- a/HaloCEVR/Hooking/Hooks.cpp +++ b/HaloCEVR/Hooking/Hooks.cpp @@ -10,11 +10,15 @@ #include "../DirectXWrappers/IDirect3DDevice9ExWrapper.h" #include "../Helpers/CmdLineArgs.h" +#include "../Profiler.h" + #define CREATEHOOK(Func) Func##.CreateHook(#Func, o.##Func##, &H_##Func##) #define RESOLVEINDIRECT(Name) ResolveIndirect(o.I_##Name, o.##Name) void Hooks::InitHooks() { + VR_PROFILE_SCOPE(Hooks_InitHooks); + RESOLVEINDIRECT(AssetsArray); RESOLVEINDIRECT(Controls); RESOLVEINDIRECT(DirectX9); @@ -83,6 +87,8 @@ void Hooks::InitHooks() void Hooks::EnableAllHooks() { + VR_PROFILE_SCOPE(Hooks_EnableAllHooks); + InitDirectX.EnableHook(); DrawFrame.EnableHook(); DrawHUD.EnableHook(); @@ -307,6 +313,8 @@ void Hooks::ResolveIndirect(Offset& offset, long long& Address) bool Hooks::H_InitDirectX() { + VR_PROFILE_SCOPE(Hooks_InitDirectX); + bool bSuccess = InitDirectX.Original(); Game::instance.OnInitDirectX(); @@ -316,6 +324,7 @@ bool Hooks::H_InitDirectX() void Hooks::H_DrawFrame(Renderer* param1, short param2, short* param3, float tickProgress, float deltaTime) { + VR_PROFILE_SCOPE(Hooks_DrawFrame); /* In order to get each perspective (left eye, right eye, PiP scope, mirror [todo: just blit an eye for the mirror]) we need to call the draw function multiple times, but should take care to avoid creating multiple d3d scenes as @@ -344,7 +353,9 @@ void Hooks::H_DrawFrame(Renderer* param1, short param2, short* param3, float tic // Draw scope if necessary if (Game::instance.PreDrawScope(param1, deltaTime)) { + VR_PROFILE_START(Hooks_DrawFrame_DrawScope); DrawFrame.Original(param1, param2, param3, tickProgress, deltaTime); + VR_PROFILE_STOP(Hooks_DrawFrame_DrawScope); Game::instance.PostDrawScope(param1, deltaTime); reinterpret_cast(Helpers::GetDirect3DDevice9())->bIgnoreNextStart = true; @@ -353,7 +364,9 @@ void Hooks::H_DrawFrame(Renderer* param1, short param2, short* param3, float tic // Draw left eye Game::instance.PreDrawEye(param1, deltaTime, 0); + VR_PROFILE_START(Hooks_DrawFrame_DrawLeftEye); DrawFrame.Original(param1, param2, param3, tickProgress, deltaTime); + VR_PROFILE_STOP(Hooks_DrawFrame_DrawLeftEye); Game::instance.PostDrawEye(param1, deltaTime, 0); reinterpret_cast(Helpers::GetDirect3DDevice9())->bIgnoreNextStart = true; @@ -361,7 +374,9 @@ void Hooks::H_DrawFrame(Renderer* param1, short param2, short* param3, float tic // Draw right eye Game::instance.PreDrawEye(param1, deltaTime, 1); + VR_PROFILE_START(Hooks_DrawFrame_DrawRightEye); DrawFrame.Original(param1, param2, param3, tickProgress, deltaTime); + VR_PROFILE_STOP(Hooks_DrawFrame_DrawRightEye); Game::instance.PostDrawEye(param1, deltaTime, 1); // Draw Mirror view, but only if the secret mirror mode is set in settings due to performance cost @@ -370,7 +385,9 @@ void Hooks::H_DrawFrame(Renderer* param1, short param2, short* param3, float tic reinterpret_cast(Helpers::GetDirect3DDevice9())->bIgnoreNextStart = true; Game::instance.PreDrawMirror(param1, deltaTime); + VR_PROFILE_START(Hooks_DrawFrame_DrawMirror); DrawFrame.Original(param1, param2, param3, tickProgress, deltaTime); + VR_PROFILE_STOP(Hooks_DrawFrame_DrawMirror); Game::instance.PostDrawMirror(param1, deltaTime); } Game::instance.PostDrawFrame(param1, deltaTime); @@ -383,6 +400,7 @@ void Hooks::H_DrawFrame(Renderer* param1, short param2, short* param3, float tic void Hooks::H_DrawHUD() { + VR_PROFILE_SCOPE(Hooks_DrawHUD); if (Game::instance.PreDrawHUD()) { DrawHUD.Original(); @@ -398,10 +416,16 @@ void __declspec(naked) Hooks::H_DrawMenu() pushad } - if (Game::instance.PreDrawMenu()) { - DrawMenu.Original(); - Game::instance.PostDrawMenu(); + VR_PROFILE_START(Hooks_DrawMenu); + + if (Game::instance.PreDrawMenu()) + { + DrawMenu.Original(); + Game::instance.PostDrawMenu(); + } + + VR_PROFILE_STOP(Hooks_DrawMenu); } _asm @@ -769,6 +793,8 @@ void __declspec(naked) Hooks::H_UpdateMouseInfo() void Hooks::H_FireWeapon(HaloID param1, short param2) { + VR_PROFILE_SCOPE(Hooks_FireWeapon); + Game::instance.PreFireWeapon(param1, param2); FireWeapon.Original(param1, param2); @@ -780,6 +806,8 @@ void Hooks::H_FireWeapon(HaloID param1, short param2) void Hooks::H_ThrowGrenade(HaloID param1, bool param2) { + VR_PROFILE_SCOPE(Hooks_ThrowGrenade); + Game::instance.PreThrowGrenade(param1); ThrowGrenade.Original(param1, param2); @@ -831,6 +859,8 @@ void Hooks::H_DrawCinematicBars() void Hooks::H_DrawViewModel() { + VR_PROFILE_SCOPE(Hooks_DrawViewModel); + if (Game::instance.c_LeftHanded->Value()) { Helpers::GetDirect3DDevice9()->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); @@ -851,6 +881,8 @@ void Hooks::H_DrawViewModel() void Hooks::H_ReloadStart(HaloID param1, short param2, bool param3) { + VR_PROFILE_SCOPE(Hooks_ReloadStart); + ReloadStart.Original(param1, param2, param3); Game::instance.ReloadStart(param1, param2, param3); @@ -908,6 +940,7 @@ void Hooks::P_RemoveCutsceneFPSCap() void Hooks::P_KeepViewModelVisible(bool bAlwaysShow) { + VR_PROFILE_SCOPE(Hooks_P_KeepViewModelVisible); // Wouldn't normally profile patches, but this one gets dynamically applied at run time // Replace "bShowViewModel = false" with "bShowViewModel = true" SetByte(o.SetViewModelVisible.Address + 0x55, bAlwaysShow ? 0x0 : 0x1); } diff --git a/HaloCEVR/Profiler.cpp b/HaloCEVR/Profiler.cpp new file mode 100644 index 0000000..0db3eb7 --- /dev/null +++ b/HaloCEVR/Profiler.cpp @@ -0,0 +1,79 @@ +#include "Profiler.h" + +void Profiler::Init() +{ + NewFrame(); +} + +void Profiler::Shutdown() +{ + delete currentFrame; + for (FrameTimings* frame : timings) + { + for (auto kv : frame->timings) + { + delete kv.second; + } + delete frame; + } + timings.clear(); +} + +void Profiler::NewFrame() +{ + time_point now = std::chrono::high_resolution_clock::now(); + if (currentFrame) + { + currentFrame->frameEnd = now; + timings.push_back(currentFrame); + } + + currentFrame = new FrameTimings(); + currentFrame->frameStart = std::chrono::high_resolution_clock::now(); +} + +int Profiler::StartEvent(const char* id) +{ + ActiveEvent& newEvent = activeEvents.emplace_back(); + newEvent.id = id; + newEvent.startTime = std::chrono::high_resolution_clock::now(); + + return activeEvents.size() - 1; +} + +void Profiler::StopEvent(int eventId) +{ + time_point now = std::chrono::high_resolution_clock::now(); + + ActiveEvent& e = activeEvents[eventId]; + + float duration = std::chrono::duration(now - e.startTime).count(); + + Timings*& timings = currentFrame->timings[e.id]; + + if (!timings) + { + timings = new Timings(); + } + + timings->numHits++; + timings->totalTime += duration; + timings->minTime = (std::min)(timings->minTime, duration); + timings->maxTime = (std::max)(timings->maxTime, duration); +} + +void Profiler::GetTimings(std::vector& outTimings) const +{ + outTimings = timings; +} + +ProfilerScopeGuard::ProfilerScopeGuard(Profiler* profiler, const char* id) +{ + this->id = profiler->StartEvent(id); + this->profiler = profiler; +} + +ProfilerScopeGuard::~ProfilerScopeGuard() +{ + profiler->StopEvent(id); +} diff --git a/HaloCEVR/Profiler.h b/HaloCEVR/Profiler.h new file mode 100644 index 0000000..50bd9a5 --- /dev/null +++ b/HaloCEVR/Profiler.h @@ -0,0 +1,75 @@ +#pragma once +#include +#include +#include +#include + +#define USE_PROFILER 0 + +#if USE_PROFILER +#define VR_PROFILE_SCOPE(x) ProfilerScopeGuard profiler_##x(&Game::instance.profiler, #x); +#define VR_PROFILE_START(x) int profiler_##x = Game::instance.profiler.StartEvent(#x); +#define VR_PROFILE_STOP(x) Game::instance.profiler.StopEvent(profiler_##x); +#else +#define VR_PROFILE_SCOPE(x) +#define VR_PROFILE_START(x) +#define VR_PROFILE_STOP(x) +#endif + +class ProfilerScopeGuard +{ +public: + ProfilerScopeGuard() = delete; + ProfilerScopeGuard(class Profiler* profiler, const char* id); + ~ProfilerScopeGuard(); + +protected: + int id; + class Profiler* profiler; +}; + +class Profiler +{ +public: + typedef std::chrono::time_point time_point; + + struct Timings + { + int numHits = 0; + float minTime = FLT_MAX; + float maxTime = -FLT_MAX; + float totalTime = 0.0f; + }; + + struct FrameTimings + { + time_point frameStart; + time_point frameEnd; + std::unordered_map timings; + }; + + + void Init(); + void Shutdown(); + + void NewFrame(); + + int StartEvent(const char* id); + void StopEvent(int eventId); + + void GetTimings(std::vector& outTimings) const; + +protected: + + std::vector timings; + FrameTimings* currentFrame = nullptr; + + struct ActiveEvent + { + time_point startTime; + std::string id; + }; + + std::vector activeEvents; +}; + diff --git a/HaloCEVR/VR/OpenVR.cpp b/HaloCEVR/VR/OpenVR.cpp index b414af6..005dd4a 100644 --- a/HaloCEVR/VR/OpenVR.cpp +++ b/HaloCEVR/VR/OpenVR.cpp @@ -5,18 +5,20 @@ #include "OpenVR.h" #include "../Logger.h" #include "../Game.h" +#include "../Profiler.h" #include "../Helpers/DX9.h" #include "../Helpers/Renderer.h" #include "../Helpers/RenderTarget.h" #include "../Helpers/Camera.h" #include "../Helpers/Cutscene.h" -#include "../Helpers/Menus.h" #pragma comment(lib, "openvr_api.lib") #pragma comment(lib, "d3d11.lib") void OpenVR::Init() { + VR_PROFILE_SCOPE(OpenVR_Init); + Logger::log << "[OpenVR] Initialising OpenVR" << std::endl; vr::EVRInitError initError = vr::VRInitError_None; @@ -162,6 +164,8 @@ void OpenVR::Init() void OpenVR::OnGameFinishInit() { + VR_PROFILE_SCOPE(OpenVR_OnGameFinishInit); + HRESULT result = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, NULL, D3D11_SDK_VERSION, &d3dDevice, NULL, NULL); if (FAILED(result)) @@ -222,6 +226,8 @@ void OpenVR::Shutdown() void OpenVR::CreateTexAndSurface(int index, UINT Width, UINT Height, DWORD Usage, D3DFORMAT Format) { + VR_PROFILE_SCOPE(OpenVR_CreateTexAndSurface); + HANDLE sharedHandle = nullptr; // Create texture on game @@ -267,12 +273,16 @@ void OpenVR::CreateTexAndSurface(int index, UINT Width, UINT Height, DWORD Usage void OpenVR::UpdatePoses() { + VR_PROFILE_SCOPE(OpenVR_UpdatePoses); + if (!vrCompositor) { return; } + VR_PROFILE_START(OpenVR_WaitGetPoses); vrCompositor->WaitGetPoses(renderPoses, vr::k_unMaxTrackedDeviceCount, gamePoses, vr::k_unMaxTrackedDeviceCount); + VR_PROFILE_STOP(OpenVR_WaitGetPoses); UpdateSkeleton(ControllerRole::Left); UpdateSkeleton(ControllerRole::Right); @@ -307,6 +317,8 @@ void OpenVR::UpdatePoses() void OpenVR::UpdateSkeleton(ControllerRole hand) { + VR_PROFILE_SCOPE(OpenVR_UpdateSkeleton); + if (!vrInput) { return; @@ -352,6 +364,8 @@ void OpenVR::UpdateSkeleton(ControllerRole hand) void OpenVR::UpdatePose(ControllerRole hand) { + VR_PROFILE_SCOPE(OpenVR_UpdatePose); + if (!vrInput || !bHasValidTipPoses) { return; @@ -377,6 +391,8 @@ void OpenVR::PreDrawFrame(Renderer* renderer, float deltaTime) void OpenVR::PositionOverlay() { + VR_PROFILE_SCOPE(OpenVR_PositionOverlay); + // Get the HMD's position and rotation vr::HmdMatrix34_t mat = renderPoses[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking; vr::HmdVector3_t position; @@ -407,12 +423,15 @@ void OpenVR::PositionOverlay() void OpenVR::PostDrawFrame(Renderer* renderer, float deltaTime) { + VR_PROFILE_SCOPE(OpenVR_PostDrawFrame); + if (!vrCompositor) { return; } // Wait for frame to finish rendering + VR_PROFILE_START(OpenVR_QueryD3D); IDirect3DQuery9* pEventQuery = nullptr; Helpers::GetDirect3DDevice9()->CreateQuery(D3DQUERYTYPE_EVENT, &pEventQuery); if (pEventQuery != nullptr) @@ -421,7 +440,9 @@ void OpenVR::PostDrawFrame(Renderer* renderer, float deltaTime) while (pEventQuery->GetData(nullptr, 0, D3DGETDATA_FLUSH) != S_OK); pEventQuery->Release(); } + VR_PROFILE_STOP(OpenVR_QueryD3D); + VR_PROFILE_START(OpenVR_SubmitEyes); vr::Texture_t leftEye { (void*)vrRenderTexture[0], vr::TextureType_DirectX, vr::ColorSpace_Auto}; vr::EVRCompositorError error = vrCompositor->Submit(vr::Eye_Left, &leftEye, &textureBounds[0], vr::Submit_Default); @@ -437,6 +458,7 @@ void OpenVR::PostDrawFrame(Renderer* renderer, float deltaTime) { Logger::log << "[OpenVR] Could not submit right eye texture: " << error << std::endl; } + VR_PROFILE_STOP(OpenVR_SubmitEyes); PositionOverlay(); @@ -448,11 +470,14 @@ void OpenVR::PostDrawFrame(Renderer* renderer, float deltaTime) Logger::log << "[OpenVR] Could not submit ui texture: " << oError << std::endl; } + VR_PROFILE_START(OpenVR_PostPresentHandoff); vrCompositor->PostPresentHandoff(); + VR_PROFILE_STOP(OpenVR_PostPresentHandoff); } void OpenVR::UpdateCameraFrustum(CameraFrustum* frustum, int eye) { + VR_PROFILE_SCOPE(OpenVR_UpdateCameraFrustum); frustum->fov = fov; Matrix4 eyeMatrix = GetHMDMatrixPoseEye((vr::Hmd_Eye) eye); @@ -546,6 +571,7 @@ float OpenVR::GetYawOffset() Matrix4 OpenVR::GetHMDTransform(bool bRenderPose) { + VR_PROFILE_SCOPE(OpenVR_GetHMDTransform); if (bRenderPose) { return ConvertSteamVRMatrixToMatrix4(renderPoses[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking).translate(-positionOffset).rotateZ(-yawOffset); @@ -558,6 +584,7 @@ Matrix4 OpenVR::GetHMDTransform(bool bRenderPose) Matrix4 OpenVR::GetRawControllerTransform(ControllerRole role, bool bRenderPose) { + VR_PROFILE_SCOPE(OpenVR_GetRawControllerTransform); vr::TrackedDeviceIndex_t controllerIndex = vrSystem->GetTrackedDeviceIndexForControllerRole(role == ControllerRole::Left ? vr::TrackedControllerRole_LeftHand : vr::TrackedControllerRole_RightHand); Matrix4 outMatrix; @@ -574,6 +601,7 @@ Matrix4 OpenVR::GetRawControllerTransform(ControllerRole role, bool bRenderPose) Matrix4 OpenVR::GetControllerTransformInternal(ControllerRole role, int bone, bool bRenderPose) { + VR_PROFILE_SCOPE(OpenVR_GetControllerTransformInternal); if (!vrSystem) { return Matrix4(); @@ -634,6 +662,7 @@ Matrix4 OpenVR::GetControllerBoneTransform(ControllerRole role, int bone, bool b Vector3 OpenVR::GetControllerVelocity(ControllerRole role, bool bRenderPose) { + VR_PROFILE_SCOPE(OpenVR_GetControllerVelocity); if (!vrSystem) { return Vector3(); @@ -660,6 +689,8 @@ Vector3 OpenVR::GetControllerVelocity(ControllerRole role, bool bRenderPose) bool OpenVR::TryGetControllerFacing(ControllerRole role, Vector3& outDirection) { + VR_PROFILE_SCOPE(OpenVR_TryGetControllerFacing); + // todo: only get once, cache offset, use that if (bHasValidTipPoses) { @@ -708,6 +739,8 @@ IDirect3DTexture9* OpenVR::GetScopeTexture() void OpenVR::SetMouseVisibility(bool bIsVisible) { + VR_PROFILE_SCOPE(OpenVR_SetMouseVisibility); + if (!vrOverlay) { return; @@ -731,6 +764,8 @@ void OpenVR::SetMouseVisibility(bool bIsVisible) void OpenVR::SetCrosshairTransform(Matrix4& newTransform) { + VR_PROFILE_SCOPE(OpenVR_SetCrosshairTransform); + // This should be moved into game code really Vector3 pos = (newTransform * Vector3(0.0f, 0.0f, 0.0f)) * Game::instance.MetresToWorld(1.0f) + Helpers::GetCamera().position; @@ -753,6 +788,8 @@ void OpenVR::SetCrosshairTransform(Matrix4& newTransform) void OpenVR::UpdateInputs() { + VR_PROFILE_SCOPE(OpenVR_UpdateInputs); + vr::EVRInputError error = vrInput->UpdateActionState(actionSets, sizeof(vr::VRActiveActionSet_t), 1); if (error != vr::VRInputError_None) From f33ddacc1e4596a7e5c43d31e1d902ce3ffe338b Mon Sep 17 00:00:00 2001 From: slipperfish Date: Fri, 20 Dec 2024 01:49:43 -0600 Subject: [PATCH 20/21] Seems to make the UI 4:3 so it's aspect corrected Seems to make the UI 4:3 from 1:1 to correct the aspect ratio. If 1 sets the height to 100% of the width, 0.75 could be 75% of the width. I was just messing with numbers trying to change something else, and I knew this was a requested fix. I have no idea what I'm doing. --- HaloCEVR/VR/OpenVR.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HaloCEVR/VR/OpenVR.cpp b/HaloCEVR/VR/OpenVR.cpp index 005dd4a..d96751d 100644 --- a/HaloCEVR/VR/OpenVR.cpp +++ b/HaloCEVR/VR/OpenVR.cpp @@ -413,7 +413,7 @@ void OpenVR::PositionOverlay() float yaw = atan2(-mat.m[2][0], mat.m[2][2]); vr::HmdMatrix34_t transform = { cos(yaw), 0, sin(yaw), position.v[0], - 0, 1, 0, position.v[1], + 0, 0.75, 0, position.v[1], -sin(yaw), 0, cos(yaw), position.v[2] }; From 576ae3ef1f363f0a8577ffdfca342f50204f462e Mon Sep 17 00:00:00 2001 From: slipperfish Date: Fri, 20 Dec 2024 19:54:02 -0600 Subject: [PATCH 21/21] Now its a float --- HaloCEVR/VR/OpenVR.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HaloCEVR/VR/OpenVR.cpp b/HaloCEVR/VR/OpenVR.cpp index d96751d..b7266e3 100644 --- a/HaloCEVR/VR/OpenVR.cpp +++ b/HaloCEVR/VR/OpenVR.cpp @@ -413,7 +413,7 @@ void OpenVR::PositionOverlay() float yaw = atan2(-mat.m[2][0], mat.m[2][2]); vr::HmdMatrix34_t transform = { cos(yaw), 0, sin(yaw), position.v[0], - 0, 0.75, 0, position.v[1], + 0, 0.75f, 0, position.v[1], -sin(yaw), 0, cos(yaw), position.v[2] };