Skip to content

Commit

Permalink
VR finished
Browse files Browse the repository at this point in the history
  • Loading branch information
Niko committed Sep 23, 2022
1 parent e2ddd34 commit e104d0d
Show file tree
Hide file tree
Showing 17 changed files with 2,365 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
Step 1/9:
Apply ctr-u_60fps_VR.xdelta to CTR USA rom (in .bin format)
Recommended to use the following patcher:
https://hack64.net/tools/patcher.php

Step 2/9:
Drag all files from geo-11 folder into DuckStation directory,
so the files are next to the DuckStation exe file

Step 3/9:
Open DuckStation, and boot the modified CTR rom (in .bin format)
If you see black screens after "Sony Presents", dont worry, it's normal.
Also the top/bottom dispaly on your monitor is normal.

Step 4/9:
Turn on Oculus Quest, go into Oculus Link mode,
then take headset off

Step 5/9:
Start OculusTest.exe, and enter DuckStation PID
You can get PID from windows task manager.
After entering PID, dont close the window, you can minimize though

Step 6/9:
Start vr-screen-cap-CTR.exe

Step 7/9:
Put on the headset, center your head, and press
PS1 Select button on your controller

Step 8/9:
Put on some headphones, cause there's no audio support in headset yet

Step 9/9:
Play the game!
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Geo-11
Only modified config files
https://helixmod.blogspot.com/2022/06/announcing-new-geo-11-3d-driver.html

VrScreenCap
Modified "update_matrices" to remove "self.rotation"
https://github.com/artumino/VRScreenCap

CTR 60fps XDELTA
Part of CTR-Tools\CTR-ModSDK github repository
This gets applied to the CTR rom

OculusTest.exe
Part of CTR-Tools\CTR-ModSDK github repository
This injects Oculus Quest data into the emulator

Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
Texture2D<float4> StereoParams : register(t125);
Texture1D<float4> IniParams : register(t120);

#define mode IniParams[0].x

#ifdef VERTEX_SHADER
void main(
out float4 pos : SV_Position0,
uint vertex : SV_VertexID)
{
float4 stereo = StereoParams.Load(0);

// Not using vertex buffers so manufacture our own coordinates.
switch(vertex) {
case 0:
pos.xy = float2(-1, -1);
break;
case 1:
pos.xy = float2(-1, 1);
break;
case 2:
pos.xy = float2(1, -1);
break;
case 3:
pos.xy = float2(1, 1);
break;
default:
pos.xy = 0;
break;
};
pos.zw = float2(0, 1);
}
#endif /* VERTEX_SHADER */

#ifdef PIXEL_SHADER
Texture2D<float4> t100 : register(t100);

void main(float4 pos : SV_Position0, out float4 result : SV_Target0)
{
float4 stereo = StereoParams.Load(0);

float x = pos.x;
float y = pos.y;
float width, height;
float x1 = 0, y1 = 0;

t100.GetDimensions(width, height);

if (mode == 0) { // Regular 3D Vision
if (stereo.z == 1)
x += width / 2;
} else if (mode == 1) { // Regular 3D Vision with eyes swapped
if (stereo.z == -1)
x += width / 2;
} else if (mode == 2 || mode == 3) { // Side by side
x = int(x);
x *= 2;
x1 = 1;
if (mode == 3) { // Swap eyes
x += width / 2 * (x >= width / 2 ? -1 : 1);
}
} else if (mode == 4 || mode == 5) { // Top and bottom
y = int(y);
y *= 2;
y1 = 1;
if (y >= height) {
y -= height;
if (mode == 4) {
x += width / 2;
}
} else if (mode == 5) {
x += width / 2;
}
} else if (mode == 6 || mode == 7) {
int side = y - (int)floor(y /2.0) * (int)2; // chooses the side for sampling if y is even side is always 0, else it is always 1
if (mode == 6) {
if (side == 0) { // left side of the reverse blited image
y1 = 1;
} else { // right side of the reverse blited image
y1 = -1;
x = x + width / 2;
}
}
else if (mode == 7) { // swap eyes
if (side == 0) { // right side of the reverse blited image
y1 = 1;
x = x + width / 2;
} else { // left side of the reverse blited image
y1 = -1;
}
}
}

result = t100.Load(float3(x, y, 0));
if (x1 || y1)
result = (result + t100.Load(float3(x + x1, y + y1, 0))) / 2;
result.w = 1;
}
#endif /* PIXEL_SHADER */
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
[Constants]
; 0 = Regular 3D Vision
; 1 = Reversed 3D Vision
; 2 = Side by Side
; 3 = Reversed Side by Side
; 4 = Top and Bottom
; 5 = Reversed Top and Bottom
; 6 = Line interlacing
; 7 = Reversed Line interlacing
global persist $mode = 0

[Present]
; Enables a custom shader that allows the stereo output mode to be
; changed to Side-by-Side or Top-and-Bottom. If you are using SLI and this
; isn't working properly (partially blank or stuck image) you may need to also
; set StereoFlagsDX10 = 0x00000008 in the [Profile] section:

if stereo_active && $mode
; Set IniParams only when actually running this shader and restore the
; original value afterwards so that no one else needs to care which
; variable we used, but at the cost of two IniParams updates per frame.
local $bak = x
x = $mode
special = draw_3dmigoto_overlay
if sli && $mode >= 2
run = CustomShader3DVision2SBSDownscalePass1
run = CustomShader3DVision2SBSDownscalePass2
else
run = CustomShader3DVision2SBS
endif
x = $bak
endif

;------------------------------------------------------------------------------------------------------
; The following custom shader can convert 3D Vision to Side-by-Side and
; Top-and-Bottom for use with 3D TVs & projectors - to enable this uncomment
; the 'include = ShaderFixes\3dvision2sbs.ini' in the [Include] section, set 3D
; Vision to output "checkerboard" in the control panel (which will remove the
; 720p limitation) and enable this either via the F11 key, or by setting a
; default for $\ShaderFixes\3dvision2sbs.ini\mode in the [Constants] section.
; If you are using SLI and this isn't working properly (partially blank or
; stuck image) you may need to also set StereoFlagsDX10 = 0x00000008 in the
; [Profile] section.

[Resource3DVision2SBSBackupTexture]
[CustomShader3DVision2SBS]
; Load a custom vertex + pixel shader:
vs = 3dvision2sbs.hlsl
ps = 3dvision2sbs.hlsl
; Explicitly unbind other shader types for safety:
hs = null
ds = null
gs = null
; Disable the OM blend stage that could interfere with the shader:
blend = disable
; Disable front/back face culling so the vertices can be in any rotation:
cull = none
; Use a triangle strip topology so we only have to output four vertices:
topology = triangle_strip
; Clear all render + depth targets to avoid compatibility issues:
run = BuiltInCommandListUnbindAllRenderTargets
; Bind the back buffer as a render target. set_viewport ensures that the view
; port is the size of the buffer so the draw call will work:
o0 = set_viewport bb
; Back up any textures that were in the ps-t100 slot. The CustomResource
; section will already back up a lot of state, including shaders, render
; targets, depth targets, UAVs, viewports, blend state, rasterizer state,
; primitive topology, etc. but it does not back up textures:
Resource3DVision2SBSBackupTexture = reference ps-t100
; Use the reverse stereo blit to give the shader access to the back buffers of
; both eyes:
ps-t100 = stereo2mono bb
; Some rare games (e.g. Onechanbara Z2) use MSAA back buffers, which cannot be
; directly used with the reverse stereo blit and must be resolved to non MSAA
; versions first. The symptoms will be a black screen after enabling this
; shader with F11. In that case, replace the above line with these two:
; ps-t100 = resolve_msaa bb
; ps-t100 = stereo2mono ps-t100
; Draw four vertices. The vertex shader will construct coordinates to cover the
; full screen using the SV_VertexID semantic so we don't need vertex buffers:
draw = 4, 0
; Restore the original texture from the ps-t100 slot:
post ps-t100 = reference Resource3DVision2SBSBackupTexture

[Resource3DVision2SBSHalfHeight]
height_multiply = 0.5
[Resource3DVision2SBSHalfWidth]
width_multiply = 0.5

[CustomShader3DVision2SBSDownscalePass1]
; Load a custom vertex + pixel shader:
vs = 3dvision2sbs.hlsl
ps = 3dvision2sbs_sli_downscale_pass1.hlsl
; Explicitly unbind other shader types for safety:
hs = null
ds = null
gs = null
; Disable the OM blend stage that could interfere with the shader:
blend = disable
; Disable front/back face culling so the vertices can be in any rotation:
cull = none
; Use a triangle strip topology so we only have to output four vertices:
topology = triangle_strip
; Clear all render + depth targets to avoid compatibility issues:
run = BuiltInCommandListUnbindAllRenderTargets

if $mode >= 4
; Make our Resource3DVision2SBSHalfHeight compatible with the back buffer's
; description, but with the height overridden in the above resource section:
Resource3DVision2SBSHalfHeight = copy_desc bb
; Then bind it as the render target. set_viewport ensures that the view port is
; the size of the buffer so the draw call will work:
o0 = set_viewport Resource3DVision2SBSHalfHeight
else
Resource3DVision2SBSHalfWidth = copy_desc bb
o0 = set_viewport Resource3DVision2SBSHalfWidth
endif

; Back up any textures that were in the ps-t100 slot. The CustomResource
; section will already back up a lot of state, including shaders, render
; targets, depth targets, UAVs, viewports, blend state, rasterizer state,
; primitive topology, etc. but it does not back up textures:
Resource3DVision2SBSBackupTexture = reference ps-t100
; Bind the back buffer as a texture:
ps-t100 = bb
; Draw four vertices. The vertex shader will construct coordinates to cover the
; full screen using the SV_VertexID semantic so we don't need vertex buffers:
draw = 4, 0
[CustomShader3DVision2SBSDownscalePass2]
; Load a custom vertex + pixel shader:
vs = 3dvision2sbs.hlsl
ps = 3dvision2sbs_sli_downscale_pass2.hlsl
; Explicitly unbind other shader types for safety:
hs = null
ds = null
gs = null
; Disable the OM blend stage that could interfere with the shader:
blend = disable
; Disable front/back face culling so the vertices can be in any rotation:
cull = none
; Use a triangle strip topology so we only have to output four vertices:
topology = triangle_strip
; Clear all render + depth targets to avoid compatibility issues:
run = BuiltInCommandListUnbindAllRenderTargets
; Bind the back buffer as a render target. set_viewport ensures that the view
; port is the size of the buffer so the draw call will work:
o0 = set_viewport bb
; Use the reverse stereo blit to give the shader access to the downscaled back
; buffers of both eyes:
if $mode >= 4
ps-t100 = stereo2mono Resource3DVision2SBSHalfHeight
else
ps-t100 = stereo2mono Resource3DVision2SBSHalfWidth
endif
; Some rare games (e.g. Onechanbara Z2) use MSAA back buffers, which cannot be
; directly used with the reverse stereo blit and must be resolved to non MSAA
; versions first. The symptoms will be a black screen after enabling this
; shader with F11. In that case, replace the above line with these two:
; ps-t100 = resolve_msaa bb
; ps-t100 = stereo2mono ps-t100
; Draw four vertices. The vertex shader will construct coordinates to cover the
; full screen using the SV_VertexID semantic so we don't need vertex buffers:
draw = 4, 0
; Restore the original texture from the ps-t100 slot:
post ps-t100 = reference Resource3DVision2SBSBackupTexture

[KeyChange3DVision2SBSOutputMode]
key = no_modifiers F11
; 0 = Regular 3D Vision
; 1 = Reversed 3D Vision
; 2 = Side by Side
; 3 = Reversed Side by Side
; 4 = Top and Bottom
; 5 = Reversed Top and Bottom
; 6 = Line interlacing
; 7 = Line interlacing reverse
$mode = 1, 2, 3, 4, 5, 6 , 7, 0
type = cycle
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Texture2D<float4> StereoParams : register(t125);
Texture1D<float4> IniParams : register(t120);
Texture2D<float4> t100 : register(t100);

#define mode IniParams[0].x

void main(float4 pos : SV_Position0, out float4 result : SV_Target0)
{
int x = pos.x;
int y = pos.y;

if (mode >= 4) {
// TAB or Line Interlaced
y *= 2;
result = (t100.Load(int3(x, y , 0)) +
t100.Load(int3(x, y + 1, 0))) / 2;
} else {
// SBS
x *= 2;
result = (t100.Load(int3(x , y, 0)) +
t100.Load(int3(x + 1, y, 0))) / 2;
}
result.w = 1;
}
Loading

0 comments on commit e104d0d

Please sign in to comment.