Detegr / openRBRVR

Open source VR implementation for Richard Burns Rally
Mozilla Public License 2.0
29 stars 6 forks source link

Feature request: Pause the game, if it is in the Driving mode, and the VR view loses focus #17

Open dlipovetsky opened 2 months ago

dlipovetsky commented 2 months ago

Today, when the game is in Driving mode, and the VR view loses focus, the game is not paused.

There are different reasons that the VR view can lose focus. One reason might be that the player removes an HMD with a proximity sensor from their head. Another reason might be that the HMD displays an overlay that covers the game view.

Some personal motivation for this feature: I use OpenRBRVR with the OpenXR runtime and a Meta Quest 3 HMD. There is a known issue, where the HMD suddenly and unpredictably displays a dialog that covers the game view, and requires the user to acknowledge the dialog. If I am driving and I receive this dialog, I nearly always crash, because I am not able to pause the game in time. That can be frustrating, especially when it happens in the middle of a long stage. It could also cause a DNF in an online race.

dlipovetsky commented 2 months ago

I think this feature is possible with the OpenXR runtime. I don't know if this feature is possible with the OpenVR runtime. The following is a sketch of how I think it might work. I'm a software engineer, but I have no experience with VR runtimes.

Here's some pseudocode:

state := vr.current_session_state()
if state != focused:
  if rbr.gameMode == Driving:
    rbr.pause_game()
render_desktop_view()
# Do not render the VR view
return

From what I can tell, this belongs in the Present function.

I will experiment with this idea in my fork, and if I make progress, I'll open a PR.

From the OpenXR docs, it looks like there is exactly one state in which the game is visible to the user, and can receive XR input: XR_SESSION_STATE_FOCUSED.

Detegr commented 2 months ago

This sounds like a good idea to me. The correct place to handle this would be in init_or_update_game_data function. I am not sure if the game can be paused by just writing at the memory location containing the game mode. From previous experiences I would guess that's not the case but it's worth a shot.

dlipovetsky commented 2 months ago

Thanks for the feedback!

I am not sure if the game can be paused by just writing at the memory location containing the game mode.

That makes sense. I definitely hallucinated the rbr.pause_game() function. 😂

I learned a little bit from the original (?) reverse engineering report on RBR.

I'll try to set a conditional breakpoint that triggers when the "game mode" address is set to the pause value. If I can do that, maybe I can find out how to call the function that pauses the game.

I was also thinking about a completely different approach: sending an input event that is bound to the pause command.