Skip to content

Commit 39f31f1

Browse files
committed
Add gyro support for motion shrines
Rebased on the main branch
1 parent 4545f11 commit 39f31f1

8 files changed

Lines changed: 373 additions & 107 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ target_sources(BetterVR_Layer PUBLIC
8181
${CMAKE_CURRENT_SOURCE_DIR}/src/hooking/rumble.cpp
8282
${CMAKE_CURRENT_SOURCE_DIR}/src/hooking/rumble.h
8383
${CMAKE_CURRENT_SOURCE_DIR}/src/hooking/skeleton.cpp
84+
${CMAKE_CURRENT_SOURCE_DIR}/src/hooking/openxr_motion_bridge.h
8485
${CMAKE_CURRENT_SOURCE_DIR}/src/rendering/d3d12.cpp
8586
${CMAKE_CURRENT_SOURCE_DIR}/src/rendering/d3d12.h
8687
${CMAKE_CURRENT_SOURCE_DIR}/src/rendering/renderer.cpp

include/cemu.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,81 @@ struct PPCInterpreter_t {
4040
} sprNew;
4141
};
4242

43+
enum VPADButtons : uint32_t {
44+
VPAD_BUTTON_A = 0x8000,
45+
VPAD_BUTTON_B = 0x4000,
46+
VPAD_BUTTON_X = 0x2000,
47+
VPAD_BUTTON_Y = 0x1000,
48+
VPAD_BUTTON_LEFT = 0x0800,
49+
VPAD_BUTTON_RIGHT = 0x0400,
50+
VPAD_BUTTON_UP = 0x0200,
51+
VPAD_BUTTON_DOWN = 0x0100,
52+
VPAD_BUTTON_ZL = 0x0080,
53+
VPAD_BUTTON_ZR = 0x0040,
54+
VPAD_BUTTON_L = 0x0020,
55+
VPAD_BUTTON_R = 0x0010,
56+
VPAD_BUTTON_PLUS = 0x0008,
57+
VPAD_BUTTON_MINUS = 0x0004,
58+
VPAD_BUTTON_HOME = 0x0002,
59+
VPAD_BUTTON_SYNC = 0x0001,
60+
VPAD_BUTTON_STICK_R = 0x00020000,
61+
VPAD_BUTTON_STICK_L = 0x00040000,
62+
VPAD_BUTTON_TV = 0x00010000,
63+
VPAD_STICK_R_EMULATION_LEFT = 0x04000000,
64+
VPAD_STICK_R_EMULATION_RIGHT = 0x02000000,
65+
VPAD_STICK_R_EMULATION_UP = 0x01000000,
66+
VPAD_STICK_R_EMULATION_DOWN = 0x00800000,
67+
VPAD_STICK_L_EMULATION_LEFT = 0x40000000,
68+
VPAD_STICK_L_EMULATION_RIGHT = 0x20000000,
69+
VPAD_STICK_L_EMULATION_UP = 0x10000000,
70+
VPAD_STICK_L_EMULATION_DOWN = 0x08000000,
71+
};
72+
73+
struct BEDir {
74+
BEVec3 x;
75+
BEVec3 y;
76+
BEVec3 z;
77+
78+
BEDir() = default;
79+
};
80+
81+
struct BETouchData {
82+
BEType<uint16_t> x;
83+
BEType<uint16_t> y;
84+
BEType<uint16_t> touch;
85+
BEType<uint16_t> validity;
86+
};
87+
88+
struct VPADStatus {
89+
BEType<uint32_t> hold;
90+
BEType<uint32_t> trig;
91+
BEType<uint32_t> release;
92+
BEVec2 leftStick;
93+
BEVec2 rightStick;
94+
BEVec3 acc;
95+
BEType<float> accMagnitude;
96+
BEType<float> accAcceleration;
97+
BEVec2 accXY;
98+
BEVec3 gyroChange;
99+
BEVec3 gyroOrientation;
100+
int8_t vpadErr;
101+
uint8_t padding1[1];
102+
BETouchData tpData;
103+
BETouchData tpProcessed1;
104+
BETouchData tpProcessed2;
105+
uint8_t padding2[2];
106+
BEDir dir;
107+
uint8_t headphoneStatus;
108+
uint8_t padding3[3];
109+
BEVec3 magnet;
110+
uint8_t slideVolume;
111+
uint8_t batteryLevel;
112+
uint8_t micStatus;
113+
uint8_t slideVolume2;
114+
uint8_t padding4[8];
115+
};
116+
static_assert(sizeof(VPADStatus) == 0xAC);
117+
43118
typedef void (*osLib_registerHLEFunctionPtr_t)(const char* libraryName, const char* functionName, void (*osFunction)(PPCInterpreter_t* hCPU));
44119
typedef void* (*memory_getBasePtr_t)();
45120
typedef uint64_t (*gameMeta_getTitleIdPtr_t)();

resources/BreathOfTheWild_BetterVR/patch_Misc.asm

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,22 @@ moduleMatches = 0x6267BFD0
33

44
.origin = codecave
55

6-
; the game normally draws most of the UI on top of the 3D color buffer
7-
; the VR mod uses the alpha channel of the 2D UI as a mask to present a transparent version of the HUD on top of the 3D framebuffer
8-
; this patch basically fixes a few elements not using the right blending options
9-
; for example, the minimap, dialogue boxes and various other things to overwrite the alpha of previously rendered 2D elements
10-
; which cause gaps inside the image that's shown in VR
11-
hook_FixUIBlending:
12-
stwu r1, -0x10(r1)
13-
mflr r0
14-
stw r0, 0x14(r1)
15-
stw r3, 0xC(r1)
16-
stw r4, 0x8(r1)
17-
18-
bl import.coreinit.hook_FixUIBlending
19-
20-
bl import.gx2.GX2SetBlendControl
21-
22-
lwz r4, 0x8(r1)
23-
lwz r3, 0xC(r1)
24-
lwz r0, 0x14(r1)
25-
addi r1, r1, 0x10
26-
mtlr r0
27-
blr
28-
29-
0x03C58BF8 = bla hook_FixUIBlending
30-
0x03C58CC0 = bla hook_FixUIBlending
31-
0x03C58D68 = bla hook_FixUIBlending
6+
; disable AutoExposure
7+
; 0x039D99A4 = li r3, 0
8+
9+
; hook Player::isRiding()
10+
0x02D32E98 = ba import.coreinit.hook_PlayerIsRiding
11+
12+
; disable gyro controls
13+
0x02E1905C = li r3, 0 ; always return 0 to signal disabled
14+
0x02E19060 = blr
15+
0x02E19064 = li r5, 0 ; always set 0
16+
17+
; disable inversed button controls
18+
0x02E199AC = li r3, 0 ; return 0 to signal disabled
19+
0x02E199B0 = blr
20+
0x02E199B4 = li r5, 0 ; always set 0
21+
3222

3323
; forces the player to always be guarding when the shield is drawn
3424
; uses player rotation to determine the guard direction, not shield direction

src/hooking/cemu_hooks.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ class CemuHooks {
6666
osLib_registerHLEFunction("coreinit", "hook_ModifyHandModelAccessSearch", &hook_ModifyHandModelAccessSearch);
6767
osLib_registerHLEFunction("coreinit", "hook_CreateNewScreen", &hook_CreateNewScreen);
6868
osLib_registerHLEFunction("coreinit", "hook_FixUIBlending", &hook_FixUIBlending);
69-
osLib_registerHLEFunction("coreinit", "hook_RouteActorJob", &hook_RouteActorJob);
7069
};
7170
~CemuHooks() {
7271
FreeLibrary(m_cemuHandle);
@@ -239,7 +238,6 @@ class CemuHooks {
239238
static void hook_ModifyHandModelAccessSearch(PPCInterpreter_t* hCPU);
240239
static void hook_CreateNewScreen(PPCInterpreter_t* hCPU);
241240
static void hook_FixUIBlending(PPCInterpreter_t* hCPU);
242-
static void hook_RouteActorJob(PPCInterpreter_t* hCPU);
243241

244242
public:
245243
template <typename T>

src/hooking/controls.cpp

Lines changed: 2 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,6 @@
11
#include "cemu_hooks.h"
22
#include "../instance.h"
3-
4-
enum VPADButtons : uint32_t {
5-
VPAD_BUTTON_A = 0x8000,
6-
VPAD_BUTTON_B = 0x4000,
7-
VPAD_BUTTON_X = 0x2000,
8-
VPAD_BUTTON_Y = 0x1000,
9-
VPAD_BUTTON_LEFT = 0x0800,
10-
VPAD_BUTTON_RIGHT = 0x0400,
11-
VPAD_BUTTON_UP = 0x0200,
12-
VPAD_BUTTON_DOWN = 0x0100,
13-
VPAD_BUTTON_ZL = 0x0080,
14-
VPAD_BUTTON_ZR = 0x0040,
15-
VPAD_BUTTON_L = 0x0020,
16-
VPAD_BUTTON_R = 0x0010,
17-
VPAD_BUTTON_PLUS = 0x0008,
18-
VPAD_BUTTON_MINUS = 0x0004,
19-
VPAD_BUTTON_HOME = 0x0002,
20-
VPAD_BUTTON_SYNC = 0x0001,
21-
VPAD_BUTTON_STICK_R = 0x00020000,
22-
VPAD_BUTTON_STICK_L = 0x00040000,
23-
VPAD_BUTTON_TV = 0x00010000,
24-
VPAD_STICK_R_EMULATION_LEFT = 0x04000000,
25-
VPAD_STICK_R_EMULATION_RIGHT = 0x02000000,
26-
VPAD_STICK_R_EMULATION_UP = 0x01000000,
27-
VPAD_STICK_R_EMULATION_DOWN = 0x00800000,
28-
VPAD_STICK_L_EMULATION_LEFT = 0x40000000,
29-
VPAD_STICK_L_EMULATION_RIGHT = 0x20000000,
30-
VPAD_STICK_L_EMULATION_UP = 0x10000000,
31-
VPAD_STICK_L_EMULATION_DOWN = 0x08000000,
32-
};
33-
34-
struct BEDir {
35-
BEVec3 x;
36-
BEVec3 y;
37-
BEVec3 z;
38-
39-
BEDir() = default;
40-
};
41-
42-
struct BETouchData {
43-
BEType<uint16_t> x;
44-
BEType<uint16_t> y;
45-
BEType<uint16_t> touch;
46-
BEType<uint16_t> validity;
47-
};
48-
49-
struct VPADStatus {
50-
BEType<uint32_t> hold;
51-
BEType<uint32_t> trig;
52-
BEType<uint32_t> release;
53-
BEVec2 leftStick;
54-
BEVec2 rightStick;
55-
BEVec3 acc;
56-
BEType<float> accMagnitude;
57-
BEType<float> accAcceleration;
58-
BEVec2 accXY;
59-
BEVec3 gyroChange;
60-
BEVec3 gyroOrientation;
61-
int8_t vpadErr;
62-
uint8_t padding1[1];
63-
BETouchData tpData;
64-
BETouchData tpProcessed1;
65-
BETouchData tpProcessed2;
66-
uint8_t padding2[2];
67-
BEDir dir;
68-
uint8_t headphoneStatus;
69-
uint8_t padding3[3];
70-
BEVec3 magnet;
71-
uint8_t slideVolume;
72-
uint8_t batteryLevel;
73-
uint8_t micStatus;
74-
uint8_t slideVolume2;
75-
uint8_t padding4[8];
76-
};
77-
static_assert(sizeof(VPADStatus) == 0xAC);
3+
#include "openxr_motion_bridge.h"
784

795
enum JoyDir {
806
Up,
@@ -395,10 +321,7 @@ void CemuHooks::hook_InjectXRInput(PPCInterpreter_t* hCPU) {
395321
vpadStatus.tpData.validity = 3;
396322

397323
// motion
398-
vpadStatus.dir.x = glm::fvec3{1, 0, 0};
399-
vpadStatus.dir.y = glm::fvec3{0, 1, 0};
400-
vpadStatus.dir.z = glm::fvec3{0, 0, 1};
401-
vpadStatus.accXY = {1.0f, 0.0f};
324+
OpenXRMotionBridge::UpdateVPADStatus(inputs, vpadStatus);
402325

403326
// write the input back to VPADStatus
404327
writeMemory(vpadStatusOffset, &vpadStatus);

0 commit comments

Comments
 (0)