[Present]
; Enable a custom shader that implements a software mouse cursor.
; Use in games that use a hardware cursor if you want to be able to adjust the
; stereo depth of the mouse, or to work with the below 3DVision2SBS shader.
; You should also set 'hide_cursor = 1' under [Device] to suppress the hardware
; mouse cursor. Note that this shader will use w5, x6, y6, z6, w6, y7, z7 and
; w7, and has a higher latency than the hardware cursor!
run = CustomShaderSoftwareMouse

[Device]
hide_cursor = 1

;------------------------------------------------------------------------------------------------------
; The following custom shader renders the mouse cursor in software, which can
; allow it's stereo depth to be adjusted and can work with the side-by-side /
; top-and-bottom output modes - to enable this uncomment the 'run =
; CustomShaderSoftwareMouse' in the [Present] section, and set 'hide_cursor =
; 1' in the [Device] section. Edit the bottom of mousevs.hlsl to adjust the
; stereo depth of the cursor as desired. Note that this shader uses w5, x6, y6,
; z6, w6, y7, z7 and w7, and has a higher latency than the hardware cursor!

[ResourceSoftwareMouseBackupTexture1]
[ResourceSoftwareMouseBackupTexture2]
[ResourceSoftwareMouseBackupTexture3]
[ResourceSoftwareMouseBackupTexture4]
[CustomShaderSoftwareMouse]
; Load software mouse shaders and explicitly unbind other shaders for safety:
vs = mouse.hlsl
ps = mouse.hlsl
hs = null
ds = null
gs = null
; 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
; Pass cursor position and visibility info to the shader:
x6 = cursor_window_x
y6 = cursor_window_y
z6 = cursor_hotspot_x
w6 = cursor_hotspot_y
y7 = cursor_showing
; Pass the size of the window to the shader:
z7 = window_width
w7 = window_height
; Back up textures we are about to replace:
ResourceSoftwareMouseBackupTexture1 = reference vs-t100
ResourceSoftwareMouseBackupTexture2 = reference vs-t101
ResourceSoftwareMouseBackupTexture3 = reference ps-t100
ResourceSoftwareMouseBackupTexture4 = reference ps-t101
; Bind cursor mask and colour textures to both vertex and pixel shaders:
vs-t100 = cursor_mask
vs-t101 = cursor_color
ps-t100 = cursor_mask
ps-t101 = cursor_color
; Enable alpha blending for a colour cursor:
blend = ADD SRC_ALPHA INV_SRC_ALPHA
; Set w5 to 1 to indicate that this pass is drawing a colour cursor - the
; vertex shader will bail if the cursor is black and white / inverted:
w5 = 1
draw = 4, 0
; If the cursor is black and white it needs a different blend mode to support
; inverted colours, but most of the rest of the state is the same. Fire off a
; second custom shader from here, which will inherit the state we have already
; set up but allow the blend mode to be changed (alternatively you could copy
; the back buffer and blend in the shader, or just ignore inverted cursors).
; The vertex shader will bail on one of these two passes depending on the
; cursor and current value of w5:
run = CustomShaderSoftwareMouseBW
; Restore backed up textures:
post vs-t100 = reference ResourceSoftwareMouseBackupTexture1
post vs-t101 = reference ResourceSoftwareMouseBackupTexture2
post ps-t100 = reference ResourceSoftwareMouseBackupTexture3
post ps-t101 = reference ResourceSoftwareMouseBackupTexture4
[CustomShaderSoftwareMouseBW]
; Set a blend mode that supports inverting the destination to suit black and
; white or inverted cursors:
blend = ADD INV_DEST_COLOR SRC_ALPHA
; Set w5 to 2 to indicate that this pass is drawing a black and white /
; inverted cursor - the vertex shader will bail if the cursor is colour:
w5 = 2
draw = 4, 0
