Fixing the Opcode Replay Buffer

I’ve been working every night on the opcode replay buffer for about a week now.  It’s really starting to come along, and I’ve fixed a lot of issues with it.  I’d overlooked the fact that the CPU could decide to change a bunch of things in memory midframe.  Some of these things include the:

  • Index Buffer
  • Vertex Buffer
  • Vertex Shader Constants
  • Geometery Shader Constants
  • Pixel Shader Constants (?)

I didn’t know too much about the Direct3D 11 rendering pipeline before this week, so it was a good way to ramp up on Direct3D at the same time.  So far I’ve implemented fixes for the Vertex Buffer and Vertex Shader Constants.  This fixes a bunch of games that had terrible flashing and corruption making them unplayable with the Opcode Replay Buffer enabled.  Things aren’t perfect.  My fix has only been implemented for Direct3D, so I still have to figure out how to do the same thing in OpenGL.  I also need to add options to correct the rest of the bullet points.  Will the other bullet points help at all?  I’m not sure, but there’s only one way to find out!

The discovery of a CPU->GPU synchronization option hidden in the “Enable Idle Skipping” section of the code was also a big win.  This helps fix issues on a bunch of games.  Generally now, it is always recommended to run with “Enable Idle Skipping” on.  I’ve found that this fixes judder issues, synchronous timewarp issues, as well opcode replay errors, crashes and warnings.  The only game I’ve found that has issues with it being enabled is Zelda: Wind Waker.  I’ve forced off the synchronization in the .ini though, so end users don’t have to worry about figuring out the correct settings!  Eventually I hope to fix this so the game works either way, but it’s a solid workaround for now.

Some synchronization issues persist (Super Mario Sunshine objects bouncing, start of game lockup), and I still haven’t implemented it when the XFB is enabled, or in deterministic dual core mode.  So much to do still, but I’m glad I’m making progress on it again!

Advertisements

New skybox features

Here’s an old post from a year ago that I never got around to publishing…

Until now, several games have had issues with the sky appearing too close when viewed in 3D. Examples include Wind Waker, Metroid Prime 1 and 3, The Hobbit, the Lord of the Rings: The Two Towers, and Blood Omen 2.

Because the sky always has to be behind everything else in the scene, games just draw it at any depth, then clear the depth buffer before drawing anything else. That works in 2D because everything else will still be drawn in front of the sky, but it doesn’t work in 3D when you can see how far away everything is.

Because the sky is infinitely far away, it’s apparent position should not be affected by moving the game camera. To achieve that, games often draw the sky as a box (called a skybox) or a sphere centred at 0, 0, 0 relative to the game camera.

So I added a game-specific option to Dolphin VR for recognising any 3D object drawn at 0, 0, 0 as a skybox. When enabled, and a skybox is detected, Dolphin VR now draws it infinitely far away, and it is not affected by freelook or position tracking.

It isn’t working in most games. For example, it doesn’t detect the stars in Wind Waker which are too close, and it doesn’t detect the correctly working skybox in Return of the King. In Wind Waker that’s because the stars are drawn in groups as several different independent objects, rather than as a single sphere centered at the origin. So for Wind Waker, I added a set of Remove Object Codes for removing the skybox instead.

Unfortunately, in some games there are still some effects that get falsely detected as a skybox. Depending on the game, this might be a problem.

But for some games it works.

Detecting the skybox also allowed me to add two more motion sickness prevention options. The first is simply always hiding the skybox, making the background a solid colour such as black. When you turn using the gamepad, there will only be half as much optic flow without the skybox, so you will feel less motion sick.

The second option is always locking the skybox. This is the feature discussed at Oculus Connect, called “player-locked skybox”. The skybox will be locked to the real world, so when you turn using the gamepad, the skybox stays still. That makes it feel like you are stationary but the ground is turning. As far as I know, Dolphin VR is now the first Rift application to implement this feature.

Skip to 37:23

These motion sickness options are in addition to the existing ones in Dolphin VR:

  • camera rotation stabilisation – This prevents the game from rotating the camera. To turn, you have to turn in real life.
  • Reducing the FOV when moving or turning with the gamepad.
  • Blacking the screen when moving or turning with the gamepad.
  • PLCB mode.

60FPS Hacks

Edit: Many of the hacks I’ve made can be found here: https://forums.dolphin-emu.org/Thread-game-modification-60-fps-hacks-and-patches?page=10

I’ve been working on figuring out how to hack 30fps games to run at 60fps or faster the past two days with some success.  In some games it is very easy to find these codes, because they have a variable frame rate. Most games that run below 60fps first poll the NTSC frame rate (60fps) then divide it by 2 or 3 to get the desired final frame rate.  Good examples of this are Pikmin 1 and Pikmin 2, ExciteBots for Wii and both N64 Legend of Zelda games.  Finding the codes is as simple as searching for “2” in the Dolphin cheat manager when the game runs at 30fps, then “1” when the game is running at 60fps.  Doing this enough will give you the memory positions of a couple of places where the code could go.  Then you can write an Action Replay code to force the memory value to 1 for a solid frame rate of 60fps.

There are other games that use a similar principle, but instead use floating point values.  Final Fantasy Fables: Chocobo’s Dungeon uses this scheme.  Searching for the floating point “0x3f800000” (1.00) during the 60fps menus and “0x40000000” during the 30fps games can net you the addresses needed.  Forcing the value to 1.00 or 0.80 gives you a frame rate of 60fps and 75fps respectively.  This website can calculate the floating point values for you by they way: http://www.h-schmidt.net/FloatConverter/IEEE754.html, if you’d like to find some on your own.

It’s not all this easy though.  Some games have side effects due to lazy programming, and have issues when the frame rate is changed.  It requires a lot of extra work to fix that!  Also, games without a variable frame rate can’t be found this way!  One idea I had was to force the easier to find NTSC frame rate in Super Mario Sunshine to a higher value, but that caused crash on initialization, so that was a failure.

Anyway, someday I think it would be worth it to figure out a way to bruteforce these codes.  A bruteforcer like this would be somewhat tricky.  How do you detect when the frame rate has changed?  You could check the frame rate indicator, but some games slow down instead (requiring the frame limit to be doubled), so that wouldn’t work for everything.  Also, do you attempt to force the memory locations, searching for 60, 30, 2 and floating point versions of these numbers?  Is it better to go through the actual functions are try and force values there?

I think we’ll have to find some more 60fps codes before this is clear!  More research is needed…

New Camera Stabilization Options!

2eyeguy recently added Roll/Pitch/Yaw correction!  I spent some time working on fixing some of the odd glitches and then added “Keyhole” and “Keyhole Snap” as additional options.  I think these improvements are a big useability jump for Dolphin VR!  Here’s a run down of what the new features do:

Roll/Pitch correction: As long as there are no bugs in the particular game, this seems to improve basically everything. Cutscenes no longer have weird roll/yaw, 3rd person games don’t change the camera level, and 1st person games don’t tilt your head up when you aim upwards (huge improvement). Morphball still yaw’s weirdly, but is better than without it.

Roll/Pitch + Yaw correction: This on it’s own is interesting, but has some issues. It makes no sense in 3rd person games and will just mess with the camera, so it should be turned off for them. 1st person, it only makes sense if you’re a player who stands, because then you can turn yourself while you aim, to always keep your view inline with your body. It’s a bit confusing. Cutscenes often are facing the wrong way, which is annoying. It’s easy to lose the object you’re supposed to focusing on with this enabled. On the upside, your view will never be rotated, so it should be very low motion sickness.

Roll/Pitch + Yaw + Keyhole: This fixes a lot of the problems with just pure Yaw correction. Now cutscenes are always facing the right way, and are a bit better, because they can rotate a bit without moving your view. Your body stays mostly attached to your view, which is great. This still has view dragging, so it’s more likely to cause motion sickness than full yaw correction, but better than none. Morphball is smooth and stays in view. Better than the previous options in my opinion.

Roll/Pitch + Yaw + Keyhole + Snap: This is just like keyhole, except it should have very little motion sickness. Now your view snaps 10-45 degrees to the side when you turn out of your view. It takes a bit of getting used to, but there is no horizontal view dragging, which is known to cause sickness. Also, cutscenes that have rotation no longer rotate! They keep the same yaw until the object of interest gets out of your view, then it snaps back to the object of interest. I personally find cutscenes to be very nauseating, but with this option I find that problem mostly fixed. The morphball stays in view and your view snaps to it when it starts getting out of view. This is my favorite mode right now, as someone who suffers from simulator sickness in 1st person games.

Once again, all of this is optional and configurable in the GUI, you everyone can choose their own control scheme :).

Bonus Video of Keyhole in action:

One big thing left to do is have the ability to have positional correction, keyhole, and snap. This would be the most extreme form of motion sickness prevention. In 3rd person games, the view would occasionally jump forward/backwards/sideways when the character gets too far away. I imagine it would eliminate motion sickness in most 3rd person games. I think it would work okay in 1st person games as well, but it would lower the immersion/presence quite a bit. It would still be a great option for those people who get motion sick easily. Note: I don’t know how to do this yet, and I’m kind of hoping that 2eyeguy has a good idea for correction against position. It’s certainly much harder to correct for than roll/pitch/yaw, so I’m not guaranteeing this will become a reality.