diff --git a/GUI Geo11.ahk b/GUI Geo11.ahk index 6787dc4..934805e 100644 --- a/GUI Geo11.ahk +++ b/GUI Geo11.ahk @@ -11,38 +11,8 @@ SetBatchLines -1 Logdir := A_AppDataCommon "\GameslistGeo11" FileCreateDir, %Logdir% LogGames := A_AppDataCommon "\GameslistGeo11\Gamename.txt" -NextInstall := A_AppDataCommon "\GameslistGeo11\NextInstall.txt" + GamesUpdate := A_AppDataCommon "\GameslistGeo11\GamesUpdate.txt" -Helix := A_AppDataCommon "\GameslistGeo11\HelixLocal.txt" -Loop, read, %GamesUpdate% -{ - if (A_LoopReadLine="") - continue - else - { - CurrentGame := % A_LoopReadLine - } -} -if FileExist(Helix) -{ - BinaryHelixFile := 1 - Loop, read, %Helix% - { - if (A_LoopReadLine="") - continue - else - { - HelixPath := % A_LoopReadLine - } - } -} -Else - BinaryHelixFile := 0 -If (HelixPath ="") -{ - BinaryHelixFile := 0 -} -SelectedGame := CurrentGame ColumnNr := [1] delimiter := "," Loop, read, %LogGames% @@ -61,31 +31,20 @@ Loop, read, %LogGames% global GameError := 0 Imagine := A_ScriptDir "\ico\bg.jpg" Gui, Add, Picture, x-8 y0 w610 h385 , % Imagine + Gui Font, s9, Segoe UI Gui Add, DropDownList, vVersion x288 y72 w84, x64 game||x32 game -Gui Add, Text, x180 y10 w189 h61, Select Game Location and version,`n'Generate' will push the Geo11 files and a Geo11 desktop shortcut. -Gui Add, Button, gGenerate x288 y144 w87 h23, Generate -Gui Add, DropDownList, vInstall x288 y108 w84, Yes||No -Gui Add, Button, gBrowse x184 y70 w90 h25, Browse -Gui Add, Button, gUninstall x288 y333 w84 h23, Uninstall -Gui Add, ListBox, vStoredforDisplay x176 y248 w102 h134, %Stored% -Gui Add, Button, gConfiger x288 y296 w84 h23, Config ini -Gui Add, Text, x288 y256 w101 h23, Current Installs -;If (SelectedGame="") -; SelectedGame := "Click Browse" -;Gui Add, Edit, vSelectedGameexe x184 y144 w90 h21, %SelectedGame% -Gui Add, Text, x179 y109 w100 h23, with Helix Vision? -If (BinaryHelixFile=1) -{ - Gui Add, CheckBox, vHelixChecked x176 y192 w225 h20 checked, Katanga/Helix Vision install is detected -} -else -{ - Gui Add, CheckBox, vHelixChecked x176 y192 w225 h20, Katanga/Helix Vision install is detected -} -Gui Add, Text, x8 y8 w154 h318, This app will take the Geo11 files such as dxd11.dll and move to a "geo" folder in the game's directory. `n`nIt creates a desktop shortcut, when clicked, it will move the game's original "dxd11.dll" files to "/originaldx" and load geo11 dxd11 files. Creating a VR specific launcher/shortcut.`n`nOn game close, the files will return to original locations.`n`nThis is a 3rd party mod loader, I am not affiliated with the Geo11 team. Just a fan. -GuiControl, text, SelectedGame, %CurrentGame% -Gui Show, w418 h394, Mod Manager for Geo11 +Gui Add, Text, x192 y16 w189 h61, Select Game Location and version,`n'Generate' will push the Geo11 files and a Geo11 desktop shortcut. +Gui Add, Button, gGenerate x288 y112 w84 h23, Generate +Gui Add, Button, gBrowse x184 y72 w85 h23, Browse +Gui Add, Button, gUninstall x288 y248 w84 h23, Uninstall +Gui Add, ListBox, vStoredforDisplay x176 y176 w102 h95, %Stored% +Gui Add, Button, gConfiger x288 y192 w84 h23, Config Game + +Gui Add, Text, x179 y143 w101 h23, Current Installs +Gui Add, Text, x8 y8 w154 h278, This app will take the Geo11 files such as dxd11.dll and move to a "geo" folder in the game's directory. `n`nIt creates a desktop shortcut, when clicked, it will move the game's original "dxd11.dll" files to "/originaldx" and load geo11 dxd11 files. Creating a VR specific launcher/shortcut.`n`nOn game close, the files will return to original locations. +;Gui Add, Edit, x184 y216 w85 h23, %SelectedGame% +Gui Show, w390 h295, Mod Manager for Geo11 Return Browse: @@ -95,7 +54,6 @@ Browse: MsgBox, You didn't select anything. else { - SplitPath, Selectgame, Gameexe, Gamepath, Gameextenstion, Gamenameonly if !FileExist(LogGames) @@ -119,25 +77,19 @@ Browse: break } Else - { - GameError := 0 - FileAppend, %Gameexe%, %GamesUpdate% - - } + GameError := 0 } ;Gui Add, ComboBox, vcbx w200 vVersChoice, x32||x64 } } - Nextup: ;Gui Add, ComboBox, vcbx w200 vVersChoice, x32||x64 - GuiControlGet,BinaryInstall,, Install - + Nextup: ;Gui Add, ComboBox, vcbx w200 vVersChoice, x32||x64 } return Generate: - { + { if (GameError=0) - { + { GuiControlGet,VersionRet,, Version Msgbox, %VersionRet% Dlls for %Gameexe% if (VersionRet="x64 game") @@ -151,8 +103,8 @@ Browse: DllLocal := A_ScriptDir 64or32 ChangeNames := DllLocal ;arraygeo := ["d3d11.geo", "d3dcompiler_47.geo", "d3dx.geo", "d3dxdm.geo", "nvapi64.geo"] - FileCreateDir, %Gamepath%\geo - FileCreateDir, %Gamepath%\originaldx + FileCreateDir, %Gamepath%\geo + ;arraygeo := ["d3d11.geo", "d3dcompiler_47.geo", "d3dx.geo", "d3dxdm.geo", "nvapi64.geo"] arraydll := ["d3d11.dll", "d3dcompiler_47.dll", "d3dx.ini", "d3dxdm.ini", "nvapi64.dll"] @@ -169,156 +121,125 @@ Browse: Logfile := Gamepath "\Gamename.txt" Random, rand, 1, 12 Localicon := A_ScriptDir "\ico\" rand ".ico" - TextforGamelog := Selectgame "," Gameexe "`n" - If (BinaryInstall="Yes") - { - if (HelixPath != "") - { - msgbox, 4,, Is this the right path to Helix Katanga? `n%HelixPath% - IfMsgBox No - Goto, KatangaGo - IfMsgBox Yes - Goto, KatangaYes - } - KatangaGo: - Msgbox, Select Path to Katanga - FileSelectFile, HelixPath, 32, , Select Kantagna Path, Application (*.exe) - if (Selectgame = "") - MsgBox, You didn't select anything. - } - KatangaYes: - FileDelete, %Logfile% ; - If (BinaryInstall="Yes") - { - FileAppend, - ( -%Selectgame% -%HelixPath% - ), %Logfile% - Filedelete, %Helix% - FileAppend, %HelixPath%, %Helix% - } - Else - FileAppend, %Selectgame%, %Logfile% - - FileAppend, %TextforGamelog%, %LogGames% - - ShortcutMaker := A_Desktop "\" Gamenameonly " VR.lnk" - AHKLocal := Gamepath "\leaveingamedir.exe" - FileCreateShortcut, %AHKLocal%, %ShortcutMaker%, %Gamepath%,,,%Localicon% - Msgbox, Geo11 Shortcut sent to desktop. - Reload - - } + TextforGamelog := Selectgame "," Gameexe "`n" + FileDelete, %Logfile% ; + FileAppend, %Selectgame%, %Logfile% + FileAppend, %TextforGamelog%, %LogGames% + msgbox, %TextforGamelog% + + ShortcutMaker := A_Desktop "\" Gamenameonly " VR.lnk" + AHKLocal := Gamepath "\leaveingamedir.exe" + FileCreateShortcut, %AHKLocal%, %ShortcutMaker%, %Gamepath%,,,%Localicon% + Msgbox, Geo11 Shortcut sent to desktop. + Reload + } + Else + Msgbox, Select a game without Geo11 files - Else - Msgbox, Select a game without Geo11 files - } - return + } + return - Configer: + Configer: + { + GuiControlGet, StoredGet,,StoredforDisplay + delimiter := "," + Loop, read, %LogGames%, %GamesUpdate% + { + Currentline := A_LoopReadLine + If InStr(Currentline, StoredGet) { - GuiControlGet, StoredGet,,StoredforDisplay - delimiter := "," - Loop, read, %LogGames%, %GamesUpdate% - { - Currentline := A_LoopReadLine - If InStr(Currentline, StoredGet) - { - LineRead := StrSplit(Currentline,delimiter) - GameLocation := LineRead[1] - SplitPath, GameLocation, OutFileName, OutDir, OutExtension, OutNameNoExt, OutDrive - Run, %OutDir%\geo\d3dxdm.ini - } - else - Continue - } + LineRead := StrSplit(Currentline,delimiter) + GameLocation := LineRead[1] + SplitPath, GameLocation, OutFileName, OutDir, OutExtension, OutNameNoExt, OutDrive + Run, %OutDir%\geo\d3dxdm.ini } - return + else + Continue + } + } + return - Uninstall: - { - GuiControlGet, StoredGet,,StoredforDisplay - Msgbox, 4,, Uninstall Geo11 for %StoredGet%? - IfMsgBox Yes + Uninstall: + { + GuiControlGet, StoredGet,,StoredforDisplay + Msgbox, 4,, Uninstall Geo11 for %StoredGet%? + IfMsgBox Yes + { + delimiter := "," + Loop, read, %LogGames%, %GamesUpdate% + { + Currentline := A_LoopReadLine + If InStr(Currentline, StoredGet) { - delimiter := "," - Loop, read, %LogGames%, %GamesUpdate% - { - Currentline := A_LoopReadLine - If InStr(Currentline, StoredGet) - { - LineRead := StrSplit(Currentline,delimiter) - GameLocation := LineRead[1] - SplitPath, GameLocation, OutFileName, OutDir, OutExtension, OutNameNoExt, OutDrive - Filedelete, %OutDir%\geo\*.dll - Filedelete, %OutDir%\geo\*.ini - Filedelete, %OutDir%\leaveingame*.exe - Filedelete, %OutDir%\VRLaun*.exe - ;FileAppend %A_LoopReadLine%`n - ;FileMove, %GamesUpdate%, %LogGames%, 1 - LineNumber := A_Index - EndLine := LineNumber + 1 - } - else - Continue - } - LogTF := "!"LogGames - TF_ReplaceLine(LogTF,LineNumber,EndLine,"") - Msgbox, Success - Reload - Goto, Beginning - } - - Else - Goto, Beginning - + LineRead := StrSplit(Currentline,delimiter) + GameLocation := LineRead[1] + SplitPath, GameLocation, OutFileName, OutDir, OutExtension, OutNameNoExt, OutDrive + Filedelete, %OutDir%\geo\*.dll + Filedelete, %OutDir%\geo\*.ini + Filedelete, %OutDir%\leaveingame*.exe + Filedelete, %OutDir%\VRLaun*.exe + ;FileAppend %A_LoopReadLine%`n + ;FileMove, %GamesUpdate%, %LogGames%, 1 + LineNumber := A_Index + EndLine := LineNumber + 1 + } + else + Continue } - Beginning: - return + LogTF := "!"LogGames + TF_ReplaceLine(LogTF,LineNumber,EndLine,"") + Msgbox, Success + Reload + Goto, Beginning + } - ;arraygeo := ["d3d11.geo", "d3dcompiler_47.geo", "d3dx.geo", "d3dxdm.geo", "nvapi64.geo"] - arraydll := ["d3d11.dll", "d3dcompiler_47.dll", "d3dx.ini", "d3dxdm.ini", "nvapi64.dll"] - FileCreateDir, %Gamepath%\geo - FileCreateDir, %Gamepath%\originaldx + Else + Goto, Beginning - For index, value in arraydll - { - ;val := % value - ;geo := % arraygeo[index] - ;FileCopy, %DllLocal%\%val%, %DllLocal%\geo\, 1 - ;sleep, 15 - ;FileMove, %DllLocal%\geo\%val%, %DllLocal%\geo\%geo%, 1 - ;sleep, 10 - dll := % arraydll[index] - FileCopy, %DllLocal%\%dll%, %Gamepath%\geo\, 1 - } - ;For index, value in arraygeo - ;{ - ; geo := % arraygeo[index] - ; FileCopy, %DllLocal%\geo\%geo%, %Gamepath%, 1 - ;} - ;FileCopy, %A_ScriptDir%\leaveingamedir.exe, %Gamepath%\leaveingamedir.exe, 1 - ;FileCopyDir, %DllLocal%\ShaderFixes, %Gamepath%\ShaderFixes, 1 + } + Beginning: + return - ;geo3d: - ; { - ; FileSelectFolder, OutputVar [, *StartingFolder, 2, Select where you will store], Selectgeo, 32, , Select D3Directory, File (*.dll); *.lnk - ; if (Selectgeo = "") - ; MsgBox, The user didn't select anything. - ; else - ; { - ; SplitPath, Selectgeo, Geoexe, Geopath, Geoextenstion, Geonameonly - ; } - ; } - ;return - ; - ;generate: - ;{ - ; loglocal := "\Logfile.txt" - ; Logfile := A_AppDataCommon loglocal - ; } - GuiEscape: - GuiClose: - FileDelete, %GamesUpdate% - ExitApp \ No newline at end of file + ;arraygeo := ["d3d11.geo", "d3dcompiler_47.geo", "d3dx.geo", "d3dxdm.geo", "nvapi64.geo"] + arraydll := ["d3d11.dll", "d3dcompiler_47.dll", "d3dx.ini", "d3dxdm.ini", "nvapi64.dll"] + FileCreateDir, %Gamepath%\geo + + For index, value in arraydll + { + ;val := % value + ;geo := % arraygeo[index] + ;FileCopy, %DllLocal%\%val%, %DllLocal%\geo\, 1 + ;sleep, 15 + ;FileMove, %DllLocal%\geo\%val%, %DllLocal%\geo\%geo%, 1 + ;sleep, 10 + dll := % arraydll[index] + FileCopy, %DllLocal%\%dll%, %Gamepath%\geo\, 1 + } + ;For index, value in arraygeo + ;{ + ; geo := % arraygeo[index] + ; FileCopy, %DllLocal%\geo\%geo%, %Gamepath%, 1 + ;} + ;FileCopy, %A_ScriptDir%\leaveingamedir.exe, %Gamepath%\leaveingamedir.exe, 1 + ;FileCopyDir, %DllLocal%\ShaderFixes, %Gamepath%\ShaderFixes, 1 + + ;geo3d: + ; { + ; FileSelectFolder, OutputVar [, *StartingFolder, 2, Select where you will store], Selectgeo, 32, , Select D3Directory, File (*.dll); *.lnk + ; if (Selectgeo = "") + ; MsgBox, The user didn't select anything. + ; else + ; { + ; SplitPath, Selectgeo, Geoexe, Geopath, Geoextenstion, Geonameonly + ; } + ; } + ;return + ; + ;generate: + ;{ + ; loglocal := "\Logfile.txt" + ; Logfile := A_AppDataCommon loglocal + ; } + GuiEscape: + GuiClose: + ExitApp \ No newline at end of file diff --git a/Geo11 Shortcut Maker.xml b/Geo11 Shortcut Maker.xml new file mode 100644 index 0000000..c66faeb --- /dev/null +++ b/Geo11 Shortcut Maker.xml @@ -0,0 +1,20 @@ + + + Geo11 Shortcut Maker + Geo11-Shortcut-Maker-v-1-1 + 1 + + + Geo11 Shortcut Maker.exe + + + + + + + + + + + + \ No newline at end of file diff --git a/Geo11FilesGoHere/x32/d3dxdm.ini b/Geo11FilesGoHere/x32/d3dxdm.ini index be4a9fc..6381fa5 100644 --- a/Geo11FilesGoHere/x32/d3dxdm.ini +++ b/Geo11FilesGoHere/x32/d3dxdm.ini @@ -22,7 +22,7 @@ ; ; tab - Top and Bottom ; sbs - Side by Side -direct_mode = sbs +direct_mode = katanga_vr matrix_analyzer = 1 auto_detect_depth_buffer = 1 diff --git a/Geo11FilesGoHere/x32/geo/ShaderFixes/3dvision2sbs.hlsl b/Geo11FilesGoHere/x32/geo/ShaderFixes/3dvision2sbs.hlsl new file mode 100644 index 0000000..2f07403 --- /dev/null +++ b/Geo11FilesGoHere/x32/geo/ShaderFixes/3dvision2sbs.hlsl @@ -0,0 +1,99 @@ +Texture2D StereoParams : register(t125); +Texture1D 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 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 */ diff --git a/Geo11FilesGoHere/x32/geo/ShaderFixes/3dvision2sbs.ini b/Geo11FilesGoHere/x32/geo/ShaderFixes/3dvision2sbs.ini new file mode 100644 index 0000000..802f9ff --- /dev/null +++ b/Geo11FilesGoHere/x32/geo/ShaderFixes/3dvision2sbs.ini @@ -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 diff --git a/Geo11FilesGoHere/x32/geo/ShaderFixes/3dvision2sbs_sli_downscale_pass1.hlsl b/Geo11FilesGoHere/x32/geo/ShaderFixes/3dvision2sbs_sli_downscale_pass1.hlsl new file mode 100644 index 0000000..1d84734 --- /dev/null +++ b/Geo11FilesGoHere/x32/geo/ShaderFixes/3dvision2sbs_sli_downscale_pass1.hlsl @@ -0,0 +1,24 @@ +Texture2D StereoParams : register(t125); +Texture1D IniParams : register(t120); +Texture2D 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; +} diff --git a/Geo11FilesGoHere/x32/geo/ShaderFixes/3dvision2sbs_sli_downscale_pass2.hlsl b/Geo11FilesGoHere/x32/geo/ShaderFixes/3dvision2sbs_sli_downscale_pass2.hlsl new file mode 100644 index 0000000..74b41be --- /dev/null +++ b/Geo11FilesGoHere/x32/geo/ShaderFixes/3dvision2sbs_sli_downscale_pass2.hlsl @@ -0,0 +1,50 @@ +Texture2D StereoParams : register(t125); +Texture1D IniParams : register(t120); +Texture2D t100 : register(t100); + +#define mode IniParams[0].x + +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 == 2 || mode == 3) { // Side by side + if (mode == 3) { // Swap eyes + x += width / 2 * (x >= width / 2 ? -1 : 1); + } + } else if (mode == 4 || mode == 5) { // Top and bottom + 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 + y /= 2; + if (mode == 6) { + if (side == 0) { // left side of the reverse blited image + } else { // right side of the reverse blited image + x = x + width / 2; + } + } + else if (mode == 7) { // swap eyes + if (side == 0) { // right side of the reverse blited image + x = x + width / 2; + } else { // left side of the reverse blited image + } + } + } + + result = t100.Load(float3(x, y, 0)); + result.w = 1; +} diff --git a/Geo11FilesGoHere/x32/geo/ShaderFixes/mouse.hlsl b/Geo11FilesGoHere/x32/geo/ShaderFixes/mouse.hlsl new file mode 100644 index 0000000..b869050 --- /dev/null +++ b/Geo11FilesGoHere/x32/geo/ShaderFixes/mouse.hlsl @@ -0,0 +1,219 @@ +#define cursor_window IniParams[0].xy +#define cursor_hotspot IniParams[0].zw +#define window_size IniParams[1].xy +#define cursor_showing IniParams[1].z +#define cursor_pass IniParams[1].w + +Texture2D StereoParams : register(t125); +Texture1D IniParams : register(t120); + +Texture2D cursor_mask : register(t100); +Texture2D cursor_color : register(t101); + +struct vs2ps { + float4 pos : SV_Position0; + float2 texcoord : TEXCOORD0; +}; + +#ifdef VERTEX_SHADER +void main(out vs2ps output, uint vertex : SV_VertexID) +{ + uint mask_width, mask_height; + uint color_width, color_height; + float2 cursor_size; + + // For easy bailing: + output.pos = 0; + output.texcoord = 0; + + if (!cursor_showing) + return; + + cursor_color.GetDimensions(color_width, color_height); + cursor_mask.GetDimensions(mask_width, mask_height); + + if (color_width) { + // Colour cursor, bail if we are in the black and white / inverted cursor pass: + if (cursor_pass == 2) + return; + cursor_size = float2(color_width, color_height); + } else { + // Black and white / inverted cursor, bail if we are in the colour cursor pass: + if (cursor_pass == 1) + return; + cursor_size = float2(mask_width, mask_height / 2); + } + + output.pos.xy = cursor_window - cursor_hotspot; + + // Not using vertex buffers so manufacture our own coordinates. + switch(vertex) { + case 0: + output.texcoord = float2(0, cursor_size.y); + break; + case 1: + output.texcoord = float2(0, 0); + output.pos.y += cursor_size.y; + break; + case 2: + output.texcoord = float2(cursor_size.x, cursor_size.y); + output.pos.x += cursor_size.x; + break; + case 3: + output.texcoord = float2(cursor_size.x, 0); + output.pos.xy += cursor_size; + break; + default: + output.pos.xy = 0; + break; + }; + + // Scale from pixels to clip space: + output.pos.xy = (output.pos.xy / window_size * 2 - 1) * float2(1, -1); + output.pos.zw = float2(0, 1); + + // Adjust stereo depth of pos here using whatever means you feel is + // suitable for this game, e.g. with a suitable crosshair.hlsl you + // could automatically adjust it from the depth buffer: + //float2 mouse_pos = (cursor_window / window_size * 2 - 1); + //output.pos.x += adjust_from_depth_buffer(mouse_pos.x, mouse_pos.y); +} +#endif /* VERTEX_SHADER */ + +#ifdef PIXEL_SHADER +// Draw a black and white, and possibly inverted cursor, +// e.g. use "Windows Standard", "Windows Inverted" or "Windows Black" to test +float4 draw_cursor_bw(float2 texcoord, float2 dimensions) +{ + float4 result; + + if (any(texcoord < 0 || texcoord >= dimensions)) + return float4(0, 0, 0, 1); + + // Black and white cursor - "the upper half is the icon AND bitmask and + // the lower half is the icon XOR bitmask". + uint xor = cursor_mask.Load(float3(texcoord, 0)).x; + uint and = cursor_mask.Load(float3(texcoord.x, texcoord.y + dimensions.y, 0)).x; + + result.xyz = xor; + result.w = and ^ xor; + + return result; +} + +// Draw a colour cursor, e.g. use "Windows Default" to test +float4 draw_cursor_color(float2 texcoord, float2 dimensions) +{ + float4 result; + float mask; + + if (any(texcoord < 0 || texcoord >= dimensions)) + return 0; + + result = cursor_color.Load(float3(texcoord, 0)); + mask = cursor_mask.Load(float3(texcoord, 0)).x; + + // We may or may not have an alpha channel in the color bitmap, but + // as far as I can tell Windows doesn't expose an API to check if the + // cursor has an alpha channel or not, so we have no good way to know + // (32bpp does not imply alpha). People on stackoverflow are scanning + // the entire alpha channel looking for non-zero values to fudge this. + // + // If the alpha is 0 it may either mean there is an alpha channel and + // this pixel should be fully transparent, or that there is no alpha + // channel and this pixel should only use the AND mask for alpha. Let's + // assume that alpha=0 means no alpha channel, which should work + // provided the mask blanks out those pixels as well. + // + // If later we find a way to detect this in 3DMigoto we can use + // Format=DXGI_FORMAT_B8G8R8X8_UNORM_SRGB to indicate there is no alpha + // channel, which will cause the read here to return 1 for opaque. + + if (!result.w) + result.w = 1; + + if (mask) + result.w = 0; + + return result; +} + +float4 smooth_cursor_bw(float2 texcoord) +{ + uint mask_width, mask_height; + float4 px1, px2, px3, px4, tmp1, tmp2; + float2 coord1, coord2; + + cursor_mask.GetDimensions(mask_width, mask_height); + float2 dimensions = float2(mask_width, mask_height / 2); + + // Subtracting 0.5 here to sample at the edge of each pixel instead of + // the center - when not scaling the cursor this will make it just as + // sharp as if we hadn't applied an interpolation filter at all, but + // still gives us a smooth result when we are scaling. Note that this + // can make some of the sample locations negative, which we handle in + // draw_cursor_bw: + texcoord -= 0.5; + + coord1 = floor(texcoord); + coord2 = min(ceil(texcoord), dimensions - 1); + + // Because of the special handling we have to do with the mask, we + // can't use a SamplerState to interpolate the cursor image, so + // implement a simple linear filter with loads instead: + px1 = draw_cursor_bw(coord1, dimensions); + px2 = draw_cursor_bw(float2(coord2.x, coord1.y), dimensions); + px3 = draw_cursor_bw(float2(coord1.x, coord2.y), dimensions); + px4 = draw_cursor_bw(coord2, dimensions); + + tmp1 = lerp(px1, px2, frac(texcoord.x)); + tmp2 = lerp(px3, px4, frac(texcoord.x)); + return lerp(tmp1, tmp2, frac(texcoord.y)); +} + +float4 smooth_cursor_color(float2 texcoord, float2 dimensions) +{ + float4 px1, px2, px3, px4, tmp1, tmp2; + float2 coord1, coord2; + + // Subtracting 0.5 here to sample at the edge of each pixel instead of + // the center - when not scaling the cursor this will make it just as + // sharp as if we hadn't applied an interpolation filter at all, but + // still gives us a smooth result when we are scaling. Note that this + // can make some of the sample locations negative, which we handle in + // draw_cursor_color: + texcoord -= 0.5; + + coord1 = floor(texcoord); + coord2 = min(ceil(texcoord), dimensions - 1); + + // Because of the special handling we have to do with the mask, we + // can't use a SamplerState to interpolate the cursor image, so + // implement a simple linear filter with loads instead: + px1 = draw_cursor_color(coord1, dimensions); + px2 = draw_cursor_color(float2(coord2.x, coord1.y), dimensions); + px3 = draw_cursor_color(float2(coord1.x, coord2.y), dimensions); + px4 = draw_cursor_color(coord2, dimensions); + + tmp1 = lerp(px1, px2, frac(texcoord.x)); + tmp2 = lerp(px3, px4, frac(texcoord.x)); + return lerp(tmp1, tmp2, frac(texcoord.y)); +} + +float4 draw_cursor(float2 texcoord) +{ + uint color_width, color_height; + + cursor_color.GetDimensions(color_width, color_height); + + if (color_width) + return smooth_cursor_color(texcoord, float2(color_width, color_height)); + else + return smooth_cursor_bw(texcoord); +} + +void main(vs2ps input, out float4 result : SV_Target0) +{ + result = draw_cursor(input.texcoord); +} +#endif /* PIXEL_SHADER */ diff --git a/Geo11FilesGoHere/x32/geo/ShaderFixes/mouse.ini b/Geo11FilesGoHere/x32/geo/ShaderFixes/mouse.ini new file mode 100644 index 0000000..b287404 --- /dev/null +++ b/Geo11FilesGoHere/x32/geo/ShaderFixes/mouse.ini @@ -0,0 +1,97 @@ +; This 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 include line in +; the main d3dx.ini. Edit the bottom of mouse.hlsl vertex shader to adjust the +; stereo depth of the cursor as desired. Note that this shader has a higher +; latency than the hardware cursor! + +[Present] +run = CustomShaderSoftwareMouse + +[Device] +hide_cursor = 1 + +[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 +; Back up IniParams we are about to use: +local $bak_x0 = x0 +local $bak_y0 = y0 +local $bak_z0 = z0 +local $bak_w0 = w0 +local $bak_x1 = x1 +local $bak_y1 = y1 +local $bak_z1 = z1 +local $bak_w1 = w1 +; Pass cursor position and visibility info to the shader: +x0 = cursor_window_x +y0 = cursor_window_y +z0 = cursor_hotspot_x +w0 = cursor_hotspot_y +z1 = cursor_showing +; Pass the size of the window to the shader: +x1 = window_width +y1 = 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 w1 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: +w1 = 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 w1: +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 +; Restore IniParams: +x0 = $bak_x0 +y0 = $bak_y0 +z0 = $bak_z0 +w0 = $bak_w0 +x1 = $bak_x1 +y1 = $bak_y1 +z1 = $bak_z1 +w1 = $bak_w1 +[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 w1 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: +w1 = 2 +draw = 4, 0 diff --git a/Geo11FilesGoHere/x32/geo/ShaderFixes/upscale.hlsl b/Geo11FilesGoHere/x32/geo/ShaderFixes/upscale.hlsl new file mode 100644 index 0000000..9898cfa --- /dev/null +++ b/Geo11FilesGoHere/x32/geo/ShaderFixes/upscale.hlsl @@ -0,0 +1,48 @@ +// Upscaling: This shader creates a quad and texture coordinates to be used by the +// pixel shader for full screen blits. + +#ifdef VERTEX_SHADER +void main( + out float4 pos : SV_Position0, out float2 texcoord : TEXCOORD0, + uint vertex : SV_VertexID) +{ + // Not using vertex buffers so manufacture our own coordinates. + switch(vertex) { + case 0: + pos.xy = float2(-1, -1); + texcoord = float2(0,1); + break; + case 1: + pos.xy = float2(-1, 1); + texcoord = float2(0,0); + break; + case 2: + pos.xy = float2(1, -1); + texcoord = float2(1,1); + break; + case 3: + pos.xy = float2(1, 1); + texcoord = float2(1,0); + break; + default: + pos.xy = 0; + texcoord = float2(0,0); + break; + }; + pos.zw = float2(0, 1); +} +#endif /* VERTEX_SHADER */ + +#ifdef PIXEL_SHADER +// This shader uses provided texture coordinates and sampler to blit +// the game screen with 3Dmigoto overlays to the actual swap chain + +Texture2D t101 : register(t101); +SamplerState SampleType; + +void main(float4 pos : SV_Position0, float2 texcoord : TEXCOORD0, out float4 result : SV_Target0) +{ + float2 tex = texcoord.xy; + result = t101.Sample(SampleType, tex); +} +#endif /* PIXEL_SHADER */ diff --git a/Geo11FilesGoHere/x32/geo/ShaderFixes/upscale.ini b/Geo11FilesGoHere/x32/geo/ShaderFixes/upscale.ini new file mode 100644 index 0000000..2cc531b --- /dev/null +++ b/Geo11FilesGoHere/x32/geo/ShaderFixes/upscale.ini @@ -0,0 +1,61 @@ +[Present] +; Enables a custom shader that allows the stereo output mode to be +; upscaled. NOTE: uncomment only if 'upscaling' and resolution are not zero. +run = CustomShaderUpscale + +;------------------------------------------------------------------------------------------------------ +; The following custom shader can be used to perform upscaling to arbitrary resolutions, +; specifically useful for 4K 3D TVs or for DSR. To enable, uncomment the +; ";run = CustomShaderUpscale" in the Present section, set the custom resolution and +; enable "upscaling=1" in the Device section. +; If you uncomment upscale shader without actually enabling the upscaling in [Device] +; you might have wrong screen resolution or the game will not be able to enter the fullscreen mode. +; Both Upscaling and SBS can be used at the same time. + +[Resource3DVisionUpscaleBackupTexture] +[CustomShaderUpscale] +; Load a custom vertex + pixel shader: +vs = upscale.hlsl +ps = upscale.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 +; enable sampler with the filter: anisotropic_filter, linear_filter, point_filter +sampler = anisotropic_filter +; 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 real 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 r_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: +Resource3DVisionUpscaleBackupTexture = reference ps-t101 +; Use faked bb to give the shader access to the back buffers of +; both eyes: +; f_bb is the faked swap chain that has the game resolution +ps-t101 = f_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: +; upscaling with msaa swap chain is currently only avialable if upscale_mode = 1 +; ps-t100 = resolve_msaa f_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 +; Restore the original texture from the ps-t100 slot: +post ps-t101 = reference Resource3DVisionUpscaleBackupTexture +; Tell 3DMigoto that upscaling has been performed. Before this "bb" referred +; to "f_bb" and afterwards will refer to "r_bb" until the next frame. Makes it +; easier to re-order upscaling and other shaders. If this command is not found +; anywhere in the d3dx.ini or upscaling is disabled, "bb" will refer to "r_bb" +special = upscaling_switch_bb diff --git a/Geo11FilesGoHere/x32/geo/Uninstall.bat b/Geo11FilesGoHere/x32/geo/Uninstall.bat new file mode 100644 index 0000000..2748a0f --- /dev/null +++ b/Geo11FilesGoHere/x32/geo/Uninstall.bat @@ -0,0 +1,130 @@ +REM Delete everything that could be in the target folder, including debug items. +REM If something is not there, the DEL skips without error. +REM Also deletes the ShaderCache, ShaderFixes, ShaderFromGame folders + +del d3d9.dll +del d3d9_log.txt +del d3d9.exp +del d3d9.pdb +del d3d9.ilk +del d3d9.lib + +del d3d10.dll +del d3d10_log.txt +del d3d10.exp +del d3d10.pdb +del d3d10.ilk +del d3d10.lib + +del d3d11.dll +del d3d11_log.txt +del d3d11_profile_log.txt +del d3d11.exp +del d3d11.pdb +del d3d11.ilk +del d3d11.lib + +del "3DMigoto Loader.exe" + +del D3DCompiler_39.dll +del D3DCompiler_39_org.dll +del D3DCompiler_39_log.txt +del D3DCompiler_39.exp +del D3DCompiler_39.pdb +del D3DCompiler_39.ilk +del D3DCompiler_39.lib + +del D3DCompiler_41.dll +del D3DCompiler_41_org.dll +del D3DCompiler_41_log.txt +del D3DCompiler_41.exp +del D3DCompiler_41.pdb +del D3DCompiler_41.ilk +del D3DCompiler_41.lib + +del D3DCompiler_42.dll +del D3DCompiler_42_org.dll +del D3DCompiler_42_log.txt +del D3DCompiler_42.exp +del D3DCompiler_42.pdb +del D3DCompiler_42.ilk +del D3DCompiler_42.lib + +del D3DCompiler_43.dll +del D3DCompiler_43_org.dll +del D3DCompiler_43_log.txt +del D3DCompiler_43.exp +del D3DCompiler_43.pdb +del D3DCompiler_43.ilk +del D3DCompiler_43.lib + +REM games seem to use this often, let's not delete this +REM file, as it's benign if not used. +REM del D3DCompiler_46.dll +del D3DCompiler_46_org.dll +del D3DCompiler_46_log.txt +del D3DCompiler_46.exp +del D3DCompiler_46.pdb +del D3DCompiler_46.ilk +del D3DCompiler_46.lib + +del dxgi.dll +del dxgi_log.txt +del dxgi.exp +del dxgi.pdb +del dxgi.ilk +del dxgi.lib + +del nvapi.dll +del nvapi_log.txt +del nvapi.exp +del nvapi.pdb +del nvapi.ilk +del nvapi.lib + +del nvapi64.dll +del nvapi_log.txt +del nvapi64.exp +del nvapi64.pdb +del nvapi64.ilk +del nvapi64.lib + + +del courierbold.spritefont +del XInput9_1_0.dll +del d3dx.ini +del d3dx_user.ini +del 3dmigoto9.ini + +del DirectXTK.lib +del DirectXTK.pdb +del DirectXTK.ilk + +del D3D_Shaders.exe +del D3D_Shaders.pdb +del D3D_Shaders.ilk +del D3D_Shaders.lib + +del BinaryDecompiler.lib + +del ShaderUsage.txt + + +rmdir /s /q ShaderFixes +rmdir /s /q ShaderCache +rmdir /s /q ShaderFromGame + + +REM Delete possible _disabled files from 3DFM/HelixVision +del nvwgf2umx_disabled.dll +del d3d11_disabled.dll + +REM Delete any new geo-11 DM files and folders +del d3dxdm.ini + +rmdir /s /q DMAutoPatchCache +rmdir /s /q DMAutoPatchFailures +rmdir /s /q ShaderCacheDM +rmdir /s /q ShaderFixesDM + +del uninstall.bat diff --git a/Geo11FilesGoHere/x32/geo/d3d11.dll b/Geo11FilesGoHere/x32/geo/d3d11.dll new file mode 100644 index 0000000..f97bf94 Binary files /dev/null and b/Geo11FilesGoHere/x32/geo/d3d11.dll differ diff --git a/Geo11FilesGoHere/x32/geo/d3dcompiler_47.dll b/Geo11FilesGoHere/x32/geo/d3dcompiler_47.dll new file mode 100644 index 0000000..b9b1506 Binary files /dev/null and b/Geo11FilesGoHere/x32/geo/d3dcompiler_47.dll differ diff --git a/Geo11FilesGoHere/x32/geo/d3dx.ini b/Geo11FilesGoHere/x32/geo/d3dx.ini new file mode 100644 index 0000000..ae01efd --- /dev/null +++ b/Geo11FilesGoHere/x32/geo/d3dx.ini @@ -0,0 +1,1163 @@ +; ------------------------------------------------------------------------------------------------------ +; Additional configuration files +; ------------------------------------------------------------------------------------------------------ +[Include] +; If you were using 3DMigoto as a full modding platform for a given game +; instead of just a single stand-alone mod (e.g. facilitating mesh/texture +; replacements or other graphics mods), you can include an entire directory +; where users can extract third party mods created by others and 3DMigoto will +; include every .ini file and any external files referred to by CustomShader / +; Resource sections (Replaced shaders in these mods should still go in +; ShaderFixes for now, unless the modders want to use CustomShaders or +; ShaderRegex to keep them standalone). +;include_recursive = Mods +exclude_recursive = DISABLED* + +; Uncomment to enable a custom shader that allows the stereo output mode to be +; upscaled. NOTE: uncomment only if 'upscaling' and resolution are not zero in +; the [Device] section. +;include = ShaderFixes\upscale.ini + +; Uncomment to 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. +; Note that this shader has a higher latency than the hardware cursor! +;include = ShaderFixes\mouse.ini + +; Uncomment to enable a custom shader that allows the stereo output mode to be +; changed to Side-by-Side or Top-and-Bottom via the F11 key. 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. You +; can set a default mode by altering $\ShaderFixes\3dvision2sbs.ini\mode in the +; [Constants] section: +;include = ShaderFixes\3dvision2sbs.ini + + +;------------------------------------------------------------------------------------------------------ +; Logging options. +; Comment line or set value to 0 for no logging. +;------------------------------------------------------------------------------------------------------ +[Logging] + +; Log all API usage +calls=1 + +; Log Input key actions +input=1 + +; Super verbose massive log +debug=0 + +; Unbuffered logging to avoid missing anything at file end +unbuffered=0 + +; Force the CPU affinity to use only a single CPU for debugging multi-threaded +force_cpu_affinity=0 + +; Log NVAPI convergence modifications +convergence=0 + +; Log NVAPI separation modifications +separation=0 + +; Enable 3DMigoto's deadlock detection algorithm. If you get hangs (not +; crashes) this might help find out why. +debug_locks=0 + +; Enable 3DMigoto's crash handler to flush the log and write out a minidump +; file in the event the game crashes. If the game hangs rather than crashes you +; can manually invoke the handler by holding down Ctrl+Alt+F11 until you hear +; the SOS tones: +crash=0 + +; ------------------------------------------------------------------------------------------------------ +; Command list to run on launch / after config reload. +; ------------------------------------------------------------------------------------------------------ +[Constants] +; Declare named global variables here to use them from other command lists, +; [Key] bindings and [Preset]s. Named variables are namespaced so that any +; included ini files can use their own without worrying about name clashes: +;global $my_named_variable = 0.0 + +; Mark a variable as persist[ent] to automatically save it to the +; d3dx_user.ini on exit or F10 (config_reload). Use Ctrl+Alt+F10 +; (wipe_user_config) to discard persistent values: +;global persist $some_persistent_variable = 1 + +; Set the initial value of "IniParams" variables, which are accessible from +; within shaders, but they are not namespaced and too many can become unwieldy: +;x = 0.8 +;y = 1.0 +;z = 1.2 +;w = 2.0 +;y1 = 3 + +;depthTargetIndicator +x111=0.0 + +; This is used by the 3DVision2SBS custom shader. To use, find the [Include] +; section above and uncomment the 'include = ShaderFixes\3dvision2sbs.ini' +; line. F11 will cycle between these modes while playing, and the current +; value will be automatically saved to the d3dx_user.ini on exit / F10: +; 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 +;$\ShaderFixes\3dvision2sbs.ini\mode = 0 + + +;------------------------------------------------------------------------------------------------------ +; Custom settings override for any of [convergence, separation, x, y, z, w] +; +; Four types are supported - by default the bindings will simply load the +; configured settings, but type=hold can be specified to have a preset +; active while the button is held, type=toggle can be used to make a simple +; on/off toggle, and type=cycle can be used to cycle forwards and/or backwards +; between several presets. +; +; Delays (type=hold only) and linear or cosine trasition periods (any key type) +; can be used to better synchonrise setting changes to the game's animations, +; or to smoothly adjust UI elements over a short period of time. +; +; Key bindings: For A-Z and 0-9 on the number row, just use that single +; character. For everything else (including mouse buttons), use the virtual key +; name (with or without the VK_ prefix) or hex code from this article: +; http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx +; +; Key combinations can be specified by separating key names with spaces, e.g. +; "Shift Q". It is also possible to indicate that a key must *not* be held for +; the binding to activate, e.g. "NO_ALT F1" would prevent the binding from +; activating when taking a 3D Screenshot with Alt F1. "NO_MODIFIERS" may be +; used as a shorthand for excluding all standard modifiers (Ctrl, Alt, Shift, +; Windows). +; +; Keys can also be from XBox controllers using: +; XB_LEFT_TRIGGER, XB_RIGHT_TRIGGER, +; XB_LEFT_SHOULDER, XB_RIGHT_SHOULDER, +; XB_LEFT_THUMB, XB_RIGHT_THUMB, +; XB_DPAD_UP, XB_DPAD_DOWN, XB_DPAD_LEFT, XB_DPAD_RIGHT, +; XB_A, XB_B, XB_X, XB_Y, XB_START, XB_BACK, XB_GUIDE +; By default all attached controllers are used - to associate a binding with a +; specific controller add the controller number 1-4 to the prefix, like +; XB2_LEFT_TRIGGER, though this may be more useful for hunting than playing. +; +; Multiple keys may be set in a single [Key] section to allow keyboard and xbox +; controller toggles and cycles to share the same state as each other. +;------------------------------------------------------------------------------------------------------ + +; Example for changing default settings +;[KeyBasicExample] +;Key = z +;separation = 100.0 +;convergence = 4.0 +;x = 0.98 +; Named variables declared in [Constants] can be set here: +;$my_named_variable = 2 + +; Example to support momentary hold type overrides, like aiming. Shows how to +; bind two separate buttons to the same action. +;[KeyMomentaryHoldExample] +;Key = RBUTTON +;Key = XB_LEFT_TRIGGER +;convergence = 0.1 +;type = hold + +; Example for a toggle override that remembers the previous value and restores +; it automatically when pressed a second time. +;[KeyToggleExample] +;Key = q +;separation = 0.1 +;type = toggle +;y = 0.0 + +; Example for using a smart cycle type instead of a toggle. Smart is now the +; default for cycles, and when activated it will quickly check if the current +; values match its current cycle preset and resynchronise if necessary. This is +; better than type=toggle if you always want to toggle between exactly two +; values specified here, while type=toggle is better if you want to remember +; some arbitrary current value and return to it: +;[KeySmartCycleExample] +;Key = w +;type = cycle +;smart = true +;$some_variable = 0, 1 + +; Example for a momentary hold, but with a delay followed by a smooth +; transition (ms) on hold and release to sync better with the game. Note that +; delay only works with type=hold (for now), while transitions will work with +; all types. +;[KeyDelayAndTransitionExample] +;Key = RBUTTON +;Key = XB_LEFT_TRIGGER +;type = hold +;y = 0.25 +;delay = 100 +;transition = 100 +;transition_type = linear +;release_delay = 0 +;release_transition = 500 +;release_transition_type = cosine + +; Example of a cycle transition that might be used to provide several presets +; that set both convergence and UI depth to suit different scenes in a game. +; Cosine transitions are used to smooth the changes over 1/10 of a second. +; Both keyboard and Xbox controller buttons are bound to this same cycle, so +; that they can be used interchangeably and remember the same position in the +; preset list. A second key is used to cycle backwards through the presets, and +; wrapping from one end of the list to the other is disabled. +;[KeyCycleExample] +;Key = E +;Key = XB_RIGHT_SHOULDER +;Back = Q +;Back = XB_LEFT_SHOULDER +;type = cycle +;wrap = false +;convergence = 1.45, 1.13, 0.98 +;z = 0.25, 0.5, 0.75 +;transition = 100 +;transition_type = cosine + +; Keys can only directly set variables to simple values. If you want to do +; something more advanced, you may need to call a command list from the key +; binding. type=hold/toggle keys will run the post phase of the command list on +; release. +;[KeyCommandListExample] +;key = f +;run = CommandListF +;[CommandListF] +;if $foo == 0 && cursor_showing +; $foo = $bar * 3.14 / rt_width +;else +; $foo = 0 +;endif + +; Example of a preset override that can be referenced by one or more [ShaderOverride*] +; sections which can be activated / deactivated automatically when one of the shader +; overrides is activated / deactivated. This is useful for setting automatic +; convergence for specific scene. +;[PresetExample] +;convergence = 0 +;$some_variable = 1 +;transition = 100 +;transition_type = linear + + +;------------------------------------------------------------------------------------------------------ +; Shader hunting options. +; Default setup is to use keyboard similar to Helix presets +;------------------------------------------------------------------------------------------------------ +[Hunting] + +; 0: Release mode is with shader hunting disabled, optimized for speed. +; 1: Hunting mode enabled +; 2: Hunting mode "soft disabled" - can be turned on via the toggle_hunting key +hunting=1 + +; Highlight mode of currently selected shader / rendertarget. +; "skip" = skip shader. don't render anything using the currently selected shader. +; "original" = fall back to original shader if the currently selected shader was patched. +; "pink" = make the output hot pink to make it standout. +; "mono" = disable stereo for the selected shader / rendertarget. +marking_mode=skip + +; Cycle through available marking modes. VK_DECIMAL VK_NUMPAD0 +; means hold the dot on the number pad while pressing numpad 0: +next_marking_mode = no_modifiers VK_DECIMAL VK_NUMPAD0 + +; What action(s) to take when marking a selected shader/buffer +; "hlsl" = decompile shader to HLSL and copy to ShaderFixes +; "asm" = disassemble shader and copy to ShaderFixes (if hlsl is disabled or failed) +; "regex" = output ShaderRegex patched shader if applicable (NOTE: Will lose associated command list) +; "clipboard" = copy shader/buffer hash to clipboard +; "mono_snapshot" = take mono screenshot (previously called mark_snapshot=1) +; "stereo_snapshot" = take stereo screenshot (previously called mark_snapshot=2) +; "snapshot_if_pink" = limit mono/stereo_snapshot to when marking_mode=pink +marking_actions = clipboard regex hlsl asm stereo_snapshot snapshot_if_pink + +; Key bindings: For A-Z and 0-9 on the number row, just use that single +; character. For everything else (including mouse buttons), use the virtual key +; name (with or without the VK_ prefix) or hex code from this article: +; http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx +; +; XBox controllers are supported using the same bindings as the [Key] sections +; (see above). If the game already uses the first controller you might try +; using the second controller for hunting with e.g. XB2_LEFT_SHOULDER + +; rotate through all VISIBLE pixel shaders at the current scene. +previous_pixelshader = no_modifiers NO_VK_DECIMAL VK_NUMPAD1 +next_pixelshader = no_modifiers NO_VK_DECIMAL VK_NUMPAD2 +mark_pixelshader = no_modifiers NO_VK_DECIMAL VK_NUMPAD3 + +; rotate through all VISIBLE vertex shaders at the current scene. +previous_vertexshader = no_modifiers NO_VK_DECIMAL VK_NUMPAD4 +next_vertexshader = no_modifiers NO_VK_DECIMAL VK_NUMPAD5 +mark_vertexshader = no_modifiers NO_VK_DECIMAL VK_NUMPAD6 + +; rotate through all USED index buffers at the current scene. +previous_indexbuffer = no_modifiers NO_VK_DECIMAL VK_NUMPAD7 +next_indexbuffer = no_modifiers NO_VK_DECIMAL VK_NUMPAD8 +mark_indexbuffer = no_modifiers NO_VK_DECIMAL VK_NUMPAD9 + +; rotate through all USED vertex buffers at the current scene. +previous_vertexbuffer = no_modifiers NO_VK_DECIMAL VK_DIVIDE +next_vertexbuffer = no_modifiers NO_VK_DECIMAL VK_MULTIPLY +mark_vertexbuffer = no_modifiers NO_VK_DECIMAL VK_SUBTRACT + +; rotate through all USED render targets at the current scene. +;previous_rendertarget = no_modifiers VK_INSERT +;next_rendertarget = no_modifiers VK_HOME +;mark_rendertarget = no_modifiers VK_PAGEUP + +; rotate through all USED compute shaders at the current scene. +previous_computeshader = no_modifiers VK_DECIMAL VK_NUMPAD1 +next_computeshader = no_modifiers VK_DECIMAL VK_NUMPAD2 +mark_computeshader = no_modifiers VK_DECIMAL VK_NUMPAD3 + +; rotate through all VISIBLE geometry shaders at the current scene. +previous_geometryshader = no_modifiers VK_DECIMAL VK_NUMPAD4 +next_geometryshader = no_modifiers VK_DECIMAL VK_NUMPAD5 +mark_geometryshader = no_modifiers VK_DECIMAL VK_NUMPAD6 + +; rotate through all VISIBLE domain shaders at the current scene. +previous_domainshader = no_modifiers VK_DECIMAL VK_NUMPAD7 +next_domainshader = no_modifiers VK_DECIMAL VK_NUMPAD8 +mark_domainshader = no_modifiers VK_DECIMAL VK_NUMPAD9 + +; rotate through all VISIBLE hull shaders at the current scene. +previous_hullshader = no_modifiers VK_DECIMAL VK_DIVIDE +next_hullshader = no_modifiers VK_DECIMAL VK_MULTIPLY +mark_hullshader = no_modifiers VK_DECIMAL VK_SUBTRACT + +; Re-enable shaders once done with hunting: +done_hunting = NO_MODIFIERS NO_VK_DECIMAL VK_ADD + +; Screenshot as pns +take_screenshot = no_modifiers VK_SNAPSHOT + +; reload all fixes from ShaderFixes folder +reload_fixes = no_modifiers VK_F10 + +; Key to turn hunting itself on/off. This will also show/hide overlay. +; Hunting must be set to either 1 or 2 to enable this toggle. +toggle_hunting = no_modifiers NO_VK_DECIMAL VK_NUMPAD0 + +; Key to reload the settings from the d3dx.ini without restarting. This can +; be the same key as reload_fixes for convenience, or a different key may be +; used to avoid resetting the ini parameters every time the shaders are +; reloaded. Note that not all settings can be reloaded, so if something doesn't +; work as expected you may still have to restart the game: +reload_config = no_modifiers VK_F10 + +; Deletes the d3dx_user.ini file and reloads settings to get a "clean slate" +wipe_user_config = ctrl alt no_shift VK_F10 + +; Hold this key to temporarily disable the fix - useful to quickly check what +; an effect looked like in the original game. +show_original = no_modifiers VK_F9 + +; Shows the CPU utilisation and performance impact of every active command list +monitor_performance = ctrl no_shift no_alt F9 + +; Freeze the current performance monitor display and log to the d3d11_log.txt +freeze_performance_monitor = no_ctrl shift no_alt F9 + +; Sets how often the performance monitor updates +monitor_performance_interval = 2.0 + +; Auto-repeat key rate in events per second. +repeat_rate=10 + +; Enabling this makes the overlay show the hashes of the currently selected +; shaders and index buffer during hunting. We don't actually recommend this, +; because writing down the hash from the screen is a bad habbit that tends to +; be very error prone - the recommended workflow is to dump the shaders to disk +; and check the most recently modified file in ShaderFixes, but advanced users +; can enable this if they want it: +verbose_overlay=1 + +; tunable parameter to use in modified shaders as variable (StereoParams.Load(int3(1,0,0)).xyzw) +; enabling tuning results in a small performance hit because the parameter texture +;tune_enable=1 +;tune_step=0.1 +;tune1_up=VK_INSERT +;tune1_down=VK_DELETE +;tune2_up=X +;tune2_down=Z + + +; Dumps out a flight log of DirectX state changes and the contents of each +; render target after every immediate draw call for the next frame. Takes up a +; large amount of space, so disabled by default. +;analyse_frame = no_modifiers VK_F8 + +; analyse_options specifies options for the frame analysis feature. Options can +; be combined by separating them with a space. +; +; Dumping selection (also refer to the "dump" command described below): +; dump_rt: Dumps render targets and UAVs +; dump_depth: Dumps depth/stencil targets +; dump_tex: Dumps shader resources (textures) +; dump_cb: Dumps constant buffers +; dump_vb: Dumps vertex buffers +; dump_ib: Dumps index buffers +; +; Texture2D format selection: +; jpg/jps: Dumps out 2D/stereo resources as .jps files. These are the easiest +; to work with and don't take up as much space as DDS files, but +; they are not dumped for every resource and are missing some data. +; dds: Dumps out 2D/stereo resources as .dds files. WARNING: This option +; may require hundreds of gigabytes and a long time! Only use it if +; you absolutely need more information than you can get otherwise. +; jps_dds: Dumps out .jps when possible, .dds otherwise (default). +; desc: Dumps out DirectX resource descriptions to .dsc files. +; +; Buffer format selection: +; buf: Dumps out buffers as binary .buf files +; txt: Decodes buffers as text, and includes some extra metadata not +; found in the .buf files. May not correctly decode all buffers. +; Default if dump_cb/vb/ib was specified. +; desc: Dumps out DirectX resource descriptions to .dsc files. +; +; Misc options: +; hold: Continue analysing subsequent frames while the key is held +; clear_rt: Clears each render target the first time they are used in the +; frame. Makes it easier to see what is being drawn if the game +; doesn't clear them, but might cause some effects not to render. +; filename_reg: Normally the draw number is the first part of the filename so +; that the files will be sorted in the order they were used in +; the game. Sometimes it is more desirable to examine how a +; specific output changed through the frame and this option will +; place the register number first in the filename to allow that. +; mono: Dump out mono textures instead of stereo. To dump both, specify +; 'mono stereo'. If neither are specified, defaults to stereo. +; dump_on_unmap: Dumps buffers/textures whenever the game maps them to the CPU +; with the Map() / Unmap() calls. Typically used to update +; constant buffers. +; dump_on_update: Dumps buffers/textures whenever the game updates them with +; the UpdateSubresource() call. Alternative method used to +; update constant buffers. +; share_dupes: Use a folder that is shared with subsequent frame analysis +; dumps for de-duplicating dumped resources. Makes future frame +; analysis dumps faster and use less disk space if there are a +; lot of identical textures, but less trivial to delete +; individual dump folders to reclaim disk space (i.e. all or +; nothing). Individual frame analysis folders are still +; de-duplicated regardless of this setting. +; symlink: Try to use symbolic links when de-duplicating files in a +; frame analysis dump. Requires developer mode to be enabled in +; Windows 10, and will fall back to hard links or shortcuts +; when not possible. Useful to see the relationship between +; deduplicated files, especially when working with cygwin, but +; some Windows applications may behave worse when using these. +; +; Experimental Deferred Context (multi-threaded rendering) Frame Analyis Support: +; deferred_ctx_immediate: Dumps resources from deferred contexts using the +; immediate context. Not suitable for dump_rt or other +; resources altered during the frame (by the GPU or CPU). May +; be ok for static unchanging resources, such as collecting HUD +; textures for filtering. Not thread safe - potential to crash. +; Recommended (not enforced) to use in conjunction with 'mono'. +; deferred_ctx_accurate: Delays dumping resources from deferred contexts +; until after the GPU has updated them. Copies of *all* +; resources being dumped are held in memory, so it may run out +; - try to restrict using this option to specific resources +; where it is needed - preferably via the "dump" command rather +; than the global analyse_options. Works with 'stereo'. +; +; analyse_options can also be specified in [ShaderOverride*] sections (or other +; command lists) to set up triggers to change the options mid-way through a +; frame analysis, either for a single draw call (default), or permanently (by +; adding the 'persist' keyword). +; +; Alternatively, "dump" can be specified in a [ShaderOverride*] section (or +; any other command list) to dump specific resources with per-resource options +; (e.g. "dump = dump_tex dds share_dupes mono ps-t0"), dump resources at a +; specific point in time (e.g. "pre dump = o0") or dump a custom resource that +; frame analysis cannot otherwise see (e.g. "dump = ResourceDepthBuffer"). Use +; additional "dump" commands to dump multiple resources. +; +;analyse_options = dump_rt jps clear_rt + + + +;------------------------------------------------------------------------------------------------------ +; Chain load other wrapper DLLs instead of system DLLs. +;------------------------------------------------------------------------------------------------------ +[System] + +;proxy_d3d9=d3d9_helix.dll +;proxy_d3d11=d3d11_helix.dll + +; We force all LoadLibrary calls back to the game folder, because games +; and nvidia both break the loading chain by going directly to System32. +; load_library_redirect=0 for off, allowing all through unchanged. +; load_library_redirect=1 for nvapi.dll override only, forced to game folder. +; load_library_redirect=2 for both d3d11.dll and nvapi.dll forced to game folder. +load_library_redirect=2 + +; Only enable key input processing when the game is in the foreground: +check_foreground_window=1 + +; Options to use hooking instead of wrapping. Used in MGSV. Possible objects to hook include: +; deferred_contexts +; immediate_context +; device +; all - all of the above +; recommended - settings currently recommended by the 3DMigoto developers +;hook=recommended + +; Options to allow ID3D11Device to be created and wrapped. We have typically had good +; luck with returning an error for all non-dx11 requests, but some games error out +; with these checks in place. +; The allow_create_device allows D3D10 Device creation and is needed for some games. +; It has two options, allow_create_device=1, which will allow anything to go through +; without returning an error, and allow_create_device=2, which will force all requests +; to become D3D11 Devices, no matter what was passed in. +; The allow_platform_update option allows the D3D11Device1 and D3D11Context1 +; interfaces introduced in Windows 8 and the platform update of Windows 7. +; +; Start with allow_check_interfaces, if that doesn't work +; then try allow_create_device=2, lastly try allow_create_device=1 +; +allow_check_interface=1 +allow_create_device=1 +allow_platform_update=1 + +;------------------------------------------------------------------------------------------------------ +; Settings used by the external 3DMigoto Loader +;------------------------------------------------------------------------------------------------------ +[Loader] +; Target process to load into. You can optionally include part of the directory +; structure in case the game's executable name is generic. +;target = \Dead or Alive 6\DOA6.exe + +; This tells the loader where to find 3DMigoto. This DLL must be located +; in the same directory as 3DMigoto Loader.exe and will be loaded in the target +; process under the same name. If d3d11.dll doesn't work try 3dmigoto.dll +;module = d3d11.dll + +; Uncomment to always elevate the loader to support games that run as admin. +; This will display a UAC prompt so only enable it if you actually need it. +;require_admin = true + +; Automatically launch the game from the loader. If you put the executable name +; here than the loader will need to be located in the game directory. You can +; use the full path, but that is not recommended to ship any fixes with since +; it will vary on a user's system. If the game is on Steam you can use the +; steam browser protocol to launch it, optionally passing it any command line +; arguments you need (unfortunately Steam pops a dialog to confirm command line +; parameters, which tends to end up behind other windows): +;launch = DOA6.exe +;launch = steam://run/838380/ +;launch = steam://run/237850//-window-mode exclusive/ + +; Delay this many extra seconds after confirming that 3DMigoto was loaded in +; the target process. For games that respawn themselves or have multiple +; executables of the same name when the first process we see may not be the +; actual one we need. Set to -1 to disable automatic shut down. +;delay = 20 + +;------------------------------------------------------------------------------------------------------ +; Settings to force display device to a specific mode. +; Uncomment a value to force the specific setting. +;------------------------------------------------------------------------------------------------------ +[Device] + +; (0) - disable upscaling +; (1) - enable upscaling and allows the game to disable and enable fullscreen mode +; (2) - enable upscaling and don't allow the game to switch fullscreen mode +; (always force fullscreen). Try this if you get issues with the mouse cursor. +; Note if you enable upscaling please do not forget to: +; 1) Uncomment "run = CustomShaderUpscale" in the [Present] section, +; otherwise you will see only a black window (with game sound). +; 2) Set a custom resolution here for width and height that the game will see. +; 3) Uncomment upscale_mode here. + +; Will now auto-upscale to desktop display resolution, unless overriden by the +; width/height below. +upscaling = 0 + +; Force override the screen resolution. +; If upscaling is on, the resizing functionality is disabled. +; If upscaling is on, then you MUST specify the resolution the game will be upscaled to. +; To achieve the best visual result use the native resolution of your tv or monitor. +;width = 3840 +;height = 2160 + +; upscale_mode = 0: 3Dmigoto creates a texture and pushes it as the back buffer for the game. +; Seems to work with only few games but everything seems to run a bit smoother. +; upscale_mode = 1: 3Dmigoto creates a second swap chain and pushes the game to use it. +; Seems to work with most games. dont forget to activate upscaling shader in [present] section +;upscale_mode = 1 + + +; overrides refresh rate set by game. +;refresh_rate=60 + +; filters available video modes to those providing given refresh rates. +; some games don't explicitely set the refresh rate, but use the video mode. +; use this if setting refresh_rate doesn't work. +;filter_refresh_rate=24,59,60 + +; full_screen=1 forces creation of full screen devices and swap chains. +; use this for 3dtvplay if game won't active stereo mode. +; full_screen=2 will also disable SetWindowPos which might help in some games. +full_screen=0 + +; This attempts to force exclusive full screen when this key is pressed, and +; may be useful in games where full_screen doesn't work or has undesirable side +; effects: +;force_full_screen_on_key = no_modifiers VK_F7 + +; This toggles forcing the full screen mode on and off. It will not take effect +; immediately, but will change what happens the next time the game tries to +; change the fullscreen mode. This is a specific hack to workaround a bug in +; Unity games, which crash when alt+tabbing out from exclusive mode fullscreen. +; +; To switch out of a Unity game without it crashing: +; Enable this option, Press F7, Alt+Enter, Alt+Tab +;toggle_full_screen = no_modifiers VK_F7 + +; some games explicitely disable stereo, prohibiting any stereo attempts. +; Setting this to 1 ignores all stereo disabling calls and also calls +; NvAPI_Stereo_Enable to force stereo on. +; Setting this to 2 sets 3Dmigoto to use 3D Vision Direct Mode +force_stereo = 2 + +; almost all DX11 games deactivate window message handling. +; setting this to 1 reenables print screen handling, alt-tab key handling etc. +allow_windowcommands=1 + +; Indicates where the resolution is obtained for texture hashes. Comment this +; out to never special case hashes that match the resolution or a multiple. +; Possible values are swap_chain and depth_stencil. Recommended to test which +; works for a given game (e.g. CryEngine always creates a swap chain that +; matches the native resolution so has to use depth_stencil). +get_resolution_from = large_2d_depth_stencil_if_swap_chain_native +;depth_stencil_if_swap_chain_native +;get_resolution_from = swap_chain + +; This will hide the hardware mouse cursor, and will be automatically enabled +; if the software mouse configuration file is included at the top of this file. +; The hardware mouse cursor cannot be moved to depth and cannot be used in +; conjunction with the side-by-side or top-and-bottom output modes, so using a +; software mouse cursor is recommended in those cases. +; NOTE: IT IS RECOMMENDED TO RESTART THE GAME AFTER CHANGING THIS SETTING! +hide_cursor = 0 + +fps_monitor_interval = 1 +show_fps_monitor = true +fps_show_hide = no_modifiers VK_F5 + +;------------------------------------------------------------------------------------------------------ +; Settings for NVidia stereo driver. +;------------------------------------------------------------------------------------------------------ +[Stereo] + +; games which have their own stereo renderer disable the NVidia automatic +; stereo mode and render themselves into stereo buffers (Crysis 3 for example). +; Setting this to 1 disables the game stereo renderer and enables NVidia auto stereo mechanism. +; This also forces 'false' as a return for any request for NvAPI_Stereo_IsEnabled. +automatic_mode=0 + +; Some games (CryEngine games, for example) lock the separation & convergence +; to a specific value, which can be undesirable. Set this to 1 to ignore these +; requests from the game to unlock the separation: +unlock_separation=0 +unlock_convergence=0 + +; games without predefined profiles can't save stereo settings. +; enabling this options automatically creates a profile for unknown games. +; Note that there is now a more flexible means to alter the game's profile - +; refer to the [Profile] section. +create_profile=0 + +; sets the global surface creation heuristic for NVidia stero driver. +; 0 = NVAPI_STEREO_SURFACECREATEMODE_AUTO - use driver registry profile settings for surface creation mode. +; 1 = NVAPI_STEREO_SURFACECREATEMODE_FORCESTEREO - Always create stereo surfaces. +; 2 = NVAPI_STEREO_SURFACECREATEMODE_FORCEMONO - Always create mono surfaces. +surface_createmode=0 + +; overrides surface creation mode for square surfaces. +;surface_square_createmode=1 + +; Force the NvAPI_Initialize to return an error so that games think stereo and NVidia is unavailable. +force_no_nvapi=0 + + +;------------------------------------------------------------------------------------------------------ +; Settings for GPU manipulations. +; Render settings override +;------------------------------------------------------------------------------------------------------ +[Rendering] + +; GPU program manipulations. + +; Type of shader hashes in use: +; 3dmigoto = Traditional hash used by 3DMigoto (unseeded software FNV-1) +; embedded = Use the first half of the MD5-like hash embedded within the +; shaders to skip the hash calculation altogether. +; bytecode = Only hash bytecode and signatures with hardware accelerated +; CRC32C. Used to minimise duplicate shaders in certain games, but +; potentially carries a higher risk of hash collisions between +; unrelated shaders in some games (e.g. that only differ in +; variable names). May occasionally avoid hash changes on game +; updates due to changes in the game developer's build environment +; (shader compiler version, build path embedded in debug info, +; constants renamed, etc). Will not avoid hash changes if the +; shader code, constant values, etc are changed. +shader_hash = 3dmigoto + +; Switch to newer texture hashes that are less susceptible to corruption and +; don't have collisions if part of the image matches. May have a slight +; performance penalty since more of the image is hashes. Do not enable if +; upgrading an existing fix! +texture_hash=0 + +; Shaders in game will be replaced by these custom shaders. +override_directory=ShaderFixes + +; Automatically patched shaders will be written here if caching is enabled. +cache_directory=ShaderCache + +; Shaders that are directly compiled by the game, instead of binary, go here. +storage_directory=ShaderFromGame + +; cache all compiled .txt shaders into .bin. this removes loading stalls. +cache_shaders=1 + +; Indicates whether scissor clipping should be disabled by default. A restart +; is required for this to take effect. If you need to do this on a per shader +; basis, you can use "run = BuiltInCustomShaderEnableScissorClipping" or "run = +; BuiltInCustomShaderDisableScissorClipping" from a [ShaderOverride], or define +; your own [CustomShader] section to change whatever render state you need and +; use "handling = skip" and "draw = from_caller" to transfer the draw call to +; them. +rasterizer_disable_scissor=0 + +; Tracks copies and updates to textures which may cause their hash to become +; out of sync with their contents - enable if texture hashes seem unreliable. +; You can also set this to 2 to disable hash contamination detection for better +; performance in hunting mode, but only do that if you are certain you won't +; be needing this in the game in question. +track_texture_updates=0 + +; Registers where the StereoParams and IniParams textures will be assigned - +; change if the game already uses these registers. Newly decompiled shaders +; will use the new registers, but existing shaders will not be updated - best +; workflow is to remove ShaderCache after changing these and run a search and +; replace on all shaders in ShaderFixes. Set to -1 to disable if not required. +stereo_params = 125 +ini_params = 120 + +; Set to 1 to assemble the Input / Output / Patch Constant signature comments +; in shader assembly to allow them to be changed for passing new values between +; pipeline stages. Be careful with these comments if this is enabled - treat +; them like code! If set to 0 the assembler will use the old behaviour and +; re-use the sections from the unmodified shaders. +assemble_signature_comments = 1 + +; Include raw "undecipherable custom data" when disassembling shaders for +; ShaderRegex - leaving this out is for backwards compatibility with patterns +; that may not expect to see it since we didn't used to include it. Shaders +; dumped via export or hunting always include any undecipherable data. +disassemble_undecipherable_custom_data=0 + +; Replace constant buffer offsets with indices & components in the comment +; blocks when disassembling shaders so they match up with how they are accessed +; in the code, making things easier to follow and simplifying ShaderRegex. +patch_assembly_cb_offsets=0 + +; Enables more sensible behaviour when including HLSL files from subdirectories +; that themselves include other files. Also disables backwards compatibility +; where files could be specified relative to the game's working directory (i.e. +; use #include "hud.hlsl" instead of #include "ShaderFixes/hud.hlsl"). Requires +; two config reloads and a cache invalidation for changes to take effect +recursive_include = 1 + +;------------------------------------------------------------------------------------------------------ +; Analyzation options. +; +; save all autofixed shaders as HLSL +export_fixed=0 + +; save all shaders sent to DX11 as ASM, or as HLSL text files if compiled by game. +export_shaders=0 + +; save all shaders seen as HLSL code, autofixed or not. 1= HLSL only, 2=HLSL+OriginalASM, 3=HLSL+OriginalASM+RecompiledASM +export_hlsl=0 + +; stores a ShaderUsage.txt file on any marking button press. +dump_usage=0 + +;------------------------------------------------------------------------------------------------------ +; Automatic shader fixes. Those settings here apply only on newly read shaders. +; All existing *_replace.txt or *_replace.bin files are not tampered with. +; If you change settings here, the best workflow is to delete all shaders in +; the shader cache directory and let them be fixed again. + +; Stereoize all shader parameters with position semantic. +fix_sv_position=0 + +; Pixel depth evaluation. +;fix_ZRepair_DepthTexture1=SceneDepthTexture.x +;fix_ZRepair_Dependencies1=MinZ_MaxZRatio +;fix_ZRepair_ZPosCalc1=zTex * MinZ_MaxZRatio.z - MinZ_MaxZRatio.w +;fix_ZRepair_DepthTexture2=SceneDepthTexture.x +;fix_ZRepair_Dependencies2= +;fix_ZRepair_ZPosCalc2=zTex +;fix_ZRepair_PositionTexture=PositionTexture +;fix_ZRepair_PositionCalc=1024 * %s + +; Inject depth texture if other depth sources are unavailable. +;fix_ZRepair_DepthTextureHash=8a19f087b004598f + +; Correct inverse transformations in pixel shaders using evaluated depth. +;fix_InvTransform=ScreenToLight,InverseTranslatedViewProjectionMatrix + +; Back projection coordinate fix. +; +; Available variables in expressions: +; stereoParams.x = Separation value in range [0..1] or [-0..-1] dependent on active eye +; stereoParams.y = Convergence value in w coordinates (1/z) +; stereoParams.z = -1/1 for left/right eye +; stereoParams.w = Separation value without eye separation +; stereoTune.x = tune value 1 (default is 1) +; stereoTune.y = tune value 2 (default is 1) +; stereoTune.z = tune value 3 (default is 1) +; stereoTune.w = tune value 4 (default is 1) +; stereoScreenRes.x = Primary swap chain backbuffer horizontal resolution +; stereoScreenRes.y = Primary swap chain backbuffer vertical resolution +; zpos = current pixel z position in pixel shader +; wpos = current pixel w position in pixel shader + +; Send inverse transformations from vertex shaders to pixel shaders. +;fix_BackProjectionTransform1=ScreenToTranslatedWorldMatrix._m00,ScreenToTranslatedWorldMatrix._m02,ScreenToTranslatedWorldMatrix._m01 +;fix_BackProjectionTransform2=ScreenToWorld._m00,ScreenToWorld._m02,ScreenToWorld._m01 + +; Position variables to correct in pixel shaders. +;fix_ObjectPosition1=PointPositionAndInverseRadius +;fix_ObjectPosition1Multiplier=1, (stereoScreenRes.x/stereoScreenRes.y)*0.5, -0.5 +;fix_ObjectPosition2=SpotPositionAndInverseRadius +;fix_ObjectPosition2Multiplier=1, (stereoScreenRes.x/stereoScreenRes.y)*0.5, -0.5 + +; Matrix multiplications to correct in pixel shaders. +;fix_MatrixOperand1=TranslatedWorldToShadowMatrix +;fix_MatrixOperand1Multiplier=1, (stereoScreenRes.x/stereoScreenRes.y)*0.5 - viewDirection.z*0.05 + (0.02791946-stereoParams.x/stereoParams.w), 0 + +; autofix shader option: recompiles all vertex shaders. fixes minor differences in deferred rendering. +;recompile_all_vs=0 + +;------------------------------------------------------------------------------------------------------ +; Shader manipulations without patches + shader filtering. +;------------------------------------------------------------------------------------------------------ +;[ShaderOverride1] +;Hash=69732c4f23cb6c48 +; Custom stereo separation value while rendering objects using this shader. +;Separation=0 +; Custom stereo convergence value while rendering objects using this +; shader (e.g. convergence=0 will move an object to infinity). +;Convergence=0 +; don't draw anything using this shader. +;Handling=skip +; Use replaced shader only when there is/is not an active depth buffer (for UI filtering) +; Deprecated: use 'x = oD' instead, and test for negative zero in the shader with +; if (asint(IniParams[0].x) == asint(-0.0)) { /* depth inactive */ } else { /* depth active */ } +;depth_filter = depth_inactive +;depth_filter = depth_active +; Override a value from [Constants] when this shader is used: +;x=2.0 +; Pass the dimensions of the active render target and resolution (obtained with +; get_resolution_from) into the shader: +;x1=rt_width +;y1=rt_height +;z1=res_width +;w1=res_height +; Use t0 from active pixel shader for texture filtering. Will be 0 if no +; [TextureOverride*] section exists for the texture or 1 if one does. For +; advanced filtering, set a value for filter_index in the [TextureOverride] +; section. This also works with other slot types (like o0, oD, ib, etc). Will +; be -0.0 (needs a special test) if no resource bound in this slot: +;x2 = ps-t0 +; Match the partner shader (any of vs/hs/ds/gs/ps/cs). Works in much the same +; way as texture filtering - set a filter_index in the [ShaderOverride] or +; [ShaderRegex] for the partner shader you want to match and it will be set in +; this variable, or 1 = ShaderOverride/Regex matched with no filter_index, 0 = +; No ShaderOverride/Regex matched, -0.0 = No shader bound. The filter_index +; from a ShaderOverride always takes priority over any matching ShaderRegex. +;local $partner = vs +; Override the shader model to allow using newer features like Texture2DMS: +;model=vs_5_0 +; Activate a preset section when this shader override is in use. +;preset = PresetExample +; Enable/disable scissor clipping for this specific shader. This is an alias +; for "run = BuiltInCustomShaderDisableScissorClipping" +; or "run = BuiltInCustomShaderEnableScissorClipping" +;disable_scissor = 1 +; There's also support for copying textures, constant buffers, depth buffers, +; etc. from one shader to another. This is a complex topic - see this page: +; https://github.com/bo3b/3Dmigoto/wiki/Resource-Copying + + +;------------------------------------------------------------------------------------------------------ +; On the fly regular expression shader patching engine +;------------------------------------------------------------------------------------------------------ +; +; These sections define regular expressions to match against shaders and apply +; certain classes of fixes on the fly. Only assembly shaders are supported by +; this method for reliability and performance reasons. +; +; Every pattern must have a main section prefixed with ShaderRegex: +; +;[ShaderRegex1] +; shader_model is required and must be set to the types of shaders that this +; pattern will be applied against. Multiple shader models can be specified to +; match the pattern against multiple types. There are some differences in +; instructions between shader model 4 and 5 (such as in resource load +; instructions), so in some cases you may need separate patterns for each. +;shader_model = ps_4_0 ps_5_0 +; +; temps is used to give names to temporary registers that you will use in the +; pattern. 3DMigoto will identify free register numbers and automatically +; adjust dcl_temps as required. +;temps = stereo tmp1 +; +; This main section also acts as a command list so that you can define actions +; that will be applied on every matching shader, just as you would on any other +; command list enabled section, such as ShaderOverride, Present, etc. +; +; +; The next section of interest is the regular expression pattern. If this +; section is omitted than every shader of with matching shader_model will be +; matched (and have the command lists and InsertDeclarations processed). The +; first part of the section name must match the main ShaderRegex section you +; defined above, and it ends with ".Pattern". The regular expression grammar +; that we support is PCRE2, which is largely compatible with the powerful Perl +; and Python grammars. You can find the syntax reference here, but generally +; speaking any regular expression tutorial will give you a good primer: +; +; http://www.pcre.org/current/doc/html/pcre2syntax.html +; +; Note that since this is parsed in an ini file that blank lines and ini +; comments are ignored, and preceding and trailing whitespace from each line +; will be stripped, so if you need to match an indented line you will need to +; explicitly match the whitespace at the start of the line with \s* +; You should also use \n to match the newline character at the end of each +; line. This should not be confused with extended mode activated by the (?x) +; switch, which will ignore *all* whitespace to allow complex patterns to be +; broken up for clarity. +; +; Multiline matching is enabled by default, as is case insensitivity (due to +; differences in the capitalisation produced by different versions of the +; disassembler), but PCRE2 provides switches for most of these options if you +; need something else. +; +; This is an example of how you might match a matrix multiply in a shader, and +; uses Python style named capture groups to pull out the registers and swizzles +; of the X and Z coordinates, and another named capture group to verify that +; the register used in the div instruction matches the one used in the multiply: +; +;[ShaderRegex1.Pattern] +;mul r\d+\.xyzw, r\d+\.yyyy, cb0\[28\]\.xyzw\n +;mad r\d+\.xyzw, (?Pr\d+)\.(?P[xyzw])[xyzw]{3}, cb0\[27\]\.xyzw, r\d+\.xyzw\n +;mad r\d+\.xyzw, (?Pr\d+)\.(?P[xyzw])[xyzw]{3}, cb0\[29\]\.xyzw, r\d+\.xyzw\n +;add (?Pr\d+)\.xyzw, r\d+\.xyzw, cb0\[30\]\.xyzw\n +;div r\d+\.[xyzw]{2}, (?P=result)\.[xyzw]{4}, r\d+\.wwww\n +; +; +; The next section specifies how to modify the matched pattern. Again the name +; must begin with the same name as the main section, and end in +; ".Pattern.Replace" (there is a reason the replacement is associated with the +; pattern, but that's coming soon). You can (and I highly encourage that you +; do) use named capture groups in the above pattern and substitute them in +; here. Temporary registers that you defined in the main ShaderRegex section +; are also available here with the same syntax as named capture groups. Use +; ${0} to indicate where the matched pattern goes, allowing you to insert code +; before and/or after it, or use additonal capture groups to insert code in the +; middle. Extended substitution is enabled in PCRE2, which among other things +; makes \n insert a newline. +; +;[ShaderRegex1.Pattern.Replace] +;\n +;// UE4 shadow correction:\n +;ld_indexable(texture2d)(float,float,float,float) ${stereo}.xyzw, l(0, 0, 0, 0), t125.xyzw\n +;add ${tmp1}.x, ${pos_z}.${swizzle_z}, -${stereo}.y\n +;mad ${pos_x}.${swizzle_x}, -${tmp1}.x, ${stereo}.x, ${pos_x}.${swizzle_x}\n +;\n +;${0} +; +; +; The final section allows you to insert new declarations into the shader, and +; 3DMigoto will check that this declaration has not already been inserted +; first. Typically this is used to get access to StereoParams in t125: +; +;[ShaderRegex1.InsertDeclarations] +;dcl_resource_texture2d (float,float,float,float) t125 + + +;------------------------------------------------------------------------------------------------------ +; texture / render target manipulations +;------------------------------------------------------------------------------------------------------ +; +; NOTE: If you are trying to match a texture the same size as the resolution (or +; a /2, x2, x4 or x8 multiple), you should confirm that the same hash is used +; on different resolutions, and adjust get_resolution_from if necessary. +; +; NOTE: If you find a texture hash seems to change inconsistently, try enabling +; track_texture_updates in the [Rendering] section. +; +;[TextureOverride1] +;Hash=c3e55ebd +; NVidia stores surface creation mode heuristics in the game profile. setting +; this option overrides the creation mode for a given texture / buffer. +; 0 = NVAPI_STEREO_SURFACECREATEMODE_AUTO - use driver registry profile settings. +; 1 = NVAPI_STEREO_SURFACECREATEMODE_FORCESTEREO - create stereo surface. +; 2 = NVAPI_STEREO_SURFACECREATEMODE_FORCEMONO - create mono surface. +;StereoMode=2 + +;[TextureOverride2] +;Hash = e27b9d07 +; Prevent the game reading from this texture - will give the game a blank +; buffer instead. Used to prevent CryEngine games falsely culling objects. Use +; the frame analysis log and look for MapType:1 to identify possible hashes. +;deny_cpu_read=1 +; Expand the region copied to this texture with CopySubresourceRegion (similar +; issue to rasterizer_disable_scissor). Used to solve issues with transparent +; refraction effects (like glass) in CryEngine games. +;expand_region_copy=1 + +;[TextureOverrideUAVNotRT] +; Example of fuzzy matching based on attributes instead of hash. Provides an +; alternative to driver heuristics that we have more precise control over. +;match_type = Texture2D +;match_width = height * 16 / 9 +;match_height = !res_height +;match_msaa = >1 +;match_bind_flags = +unordered_access -render_target +;match_priority = -1 +;StereoMode = 2 + +;------------------------------------------------------------------------------------------------------ +; Example of settings override by mouse button configuration +; Mapping of from game provided hard coded convergence values to custom values +; Those are values for L.A. Noir +; Example of settings override by mouse button configuration +;------------------------------------------------------------------------------------------------------ +;[ConvergenceMap] + +;Map1=from 3e99999a to 0.3 +;Map2=from 3f800000 to 1.0 +;Map3=from 3f666666 to 0.9 + + +;------------------------------------------------------------------------------------------------------ +; Updates the game's driver profile on launch. +; +; Any changes here will require the user to OK a UAC prompt the first time they +; run the game, but the DLL tries to only do that if it is actually required. +;------------------------------------------------------------------------------------------------------ +[Profile] +; This setting should always be added to a profile - it is required for a +; number of other settings to work, as well as allowing the convergence to be +; saved. If you are customising a profile you should **always uncomment this**: +StereoProfile = 1 +; +; This setting enables stereo compute shaders (0x00004000), which is required +; to fix a lot of "one eye" type rendering issues in many DX11 games, and +; allows stereo2mono and the side-by-side / top-and-bottom output modes to work +; in SLI (0x00000008): +;StereoFlagsDX10 = 0x00004008 +; +; This sets the default convergence in the profile. Note that 3DMigoto will +; happily override the default value from the driver, but will only override +; the user's custom convergence if it has another reason to update the profile, +; such as a change to another setting (adding a version tag to the Comments +; setting would be one way to force an update): +;StereoConvergence = 0.5 +; +; This changes the green text that the driver displays, and is a good place to +; put any reminders to display to the user or just take some credit: +;Comments = "Such and such 3D fix by an awesome modder. Disable motion blur!" +; +; Change the rating: "0": 3D Vision Ready, "1": Excellent, "2": Good, +; "3": Fair, "4": Not Recommended +;Compat = "0" +; +; If you have added some comments, you probably want to force the green text to +; show up when the game is next run. Note that like convergence, 3DMigoto will +; only override a user setting here if something else has also been updated +; (such as Comments), so this will usually only show up the first time a user +; runs the game after installing the fix (be sure to enable StereoProfile). +;StereoMemoEnabled = 1 +; +; Disable compatibility mode to make sure users are seeing the real deal. Like +; convergence, 3DMigoto will respect the users custom settings here: +;Disable2DD = 1 +; +; Put a reminder in the green text of compatibility mode that they are not +; seeing the real deal: +;2DD_Notes = "Compatibility mode is enabled. To use the fix, please disable it with Ctrl+Alt+F11" +; +; These two options change which constant buffers the driver uses to pass the +; separation and convergence to any Vertex and Domain shaders it has modified. +; The default value is 12, and you may need to change it if the game already +; uses that constant buffer for any purpose, which should be apparent as you +; will see 2D geometry on any shader that uses this. You should avoid using +; these constant buffers yourself unless you understand the nuances involved. +;DX10VSCBNumber = 12 +;DX10DSCBNumber = 12 +; +; Workaround crashes and hangs in games that violate DirectX threading +; constraints (e.g. Resident Evil 2/7, Devil May Cry 5). Set to 1 to always +; enable workaround or 2 to only enable workaround with 3D Vision: +APP_COMPAT_SHIM = 1 +; +; If a setting doesn't have a name or you don't know what it is (check the +; d3d11_log.txt for the names of all settings in this profile, or use the name +; from Nvidia Profile Inspector), you can use the hex ID (in fact, you can even +; paste a complete profile from Geforce Profile Manager - just be sure to +; delete any corrupt string settings if you do): +;0x1033cec2 = 0x00000002 +; +; There are many more options, and we have tried to document them here - +; *please* edit this page if you figure out anything new: +; http://wiki.bo3b.net/index.php?title=Driver_Profile_Settings + + +;------------------------------------------------------------------------------------------------------ +; This section defines a shortcut for unbinding all render and depth targets, +; which is commonly needed in [CustomShader] sections since all bound render +; and depth targets *must* be the same size, and leaving something else bound +; is a sure way for things to go weirdly wrong. Call it from any section that +; supports a command list with 'run = CommandListUnbindAllRenderTargets' after +; you have copied any state you need from these and before binding your own. +;------------------------------------------------------------------------------------------------------ +[CommandListUnbindAllRenderTargets] +run = BuiltInCommandListUnbindAllRenderTargets + +;------------------------------------------------------------------------------------------------------ +; Commands to run from the Present call at the start/end of each frame +; +; Useful to clear custom resources or ini params at the start of each frame, or +; to run a custom shader to do whatever you can dream up. The post keyword will +; make an action run at the start of a frame instead of the end - as general +; guideline you want overlays drawn at the end of a frame and resources cleared +; at the start of a new frame. +;------------------------------------------------------------------------------------------------------ +[Present] +; Example: Clear an ini param at the start of each frame: +;post x = 0 +; Example: Undefine a custom resource until something is copied into it: +;post ResourceDepthBuffer = null +; Example: Clear a custom resource with black/zero at the start of each frame +; (beware that driver bugs may mean only one eye is cleared in some cases): +;post clear = ResourceFoo + +; If you are looking for CustomShader3DVision2SBS, CustomShaderSoftwareMouse or +; CustomShaderUpscale, these are now enabled in the [Include] section at the +; top of this file instead. The other options related to these are still in +; the same place. diff --git a/Geo11FilesGoHere/x32/geo/d3dxdm.ini b/Geo11FilesGoHere/x32/geo/d3dxdm.ini new file mode 100644 index 0000000..6381fa5 --- /dev/null +++ b/Geo11FilesGoHere/x32/geo/d3dxdm.ini @@ -0,0 +1,155 @@ +; ------------------------------------------------------------------------------------------------------ +; Additional configuration files +; ------------------------------------------------------------------------------------------------------ +[Include] + +;------------------------------------------------------------------------------------------------------ +[Constants] + + +;------------------------------------------------------------------------------------------------------ +[Device] + +; direct_mode: choose stereo output option based on hardware +; tab_reversed - not yet implemented +; sbs_reversed - not yet implemented +; interlaced - not implemented +; interlaced_reversed - not implemented +; +; katanga_vr - vr output to HelixVision. +; nvidia_dx9 - works on latest drivers. Requires 3D Vision Driver. Requires game in exclusive fullscreen. +; nvidia_dx11 - works up to driver 452.06. Requires 3D Vision Driver. Requires game in windowed mode. +; +; tab - Top and Bottom +; sbs - Side by Side +direct_mode = katanga_vr + +matrix_analyzer = 1 +auto_detect_depth_buffer = 1 +resolve_msaa_depth_buffers = 1 +preserve_depth_buffers = 1 +dm_deferred_context_queue_per_eye = 0 +repeat_command_list_depth_buffer_stats = 0 + +fps_monitor_interval = 1 +show_fps_monitor = false +; fps_show_hide = no_modifiers VK_F5 + +;------------------------------------------------------------------------------------------------------ +[Stereo] +dm_stereo_enabled = 1 +dm_convergence = 3.0 +dm_separation = 80 +dm_hud_detection = 0 +;dm_hud_depth_override = -1.0 +dm_auto_convergence = 0 +dm_auto_convergence_uav_buffer_updates = 1 +dm_hud_depth_max_offset_in = 0.002 + +dm_min_convergence = 0.1 +dm_max_convergence_soft = 6.0 +dm_max_convergence_hard = 8.0 +dm_popout_bias = 0.02 +dm_slow_convergence_rate = 5.0 +dm_slow_convergence_threshold_near = 0.0 +dm_slow_convergence_threshold_far = 0.0 +dm_instant_convergence_threshold = 4.0 +dm_anti_judder_threshold = 0.5 +dm_auto_convergence_hud_enabled = 1 +dm_auto_convergence_hud_timeout = 2.0 +dm_warn_no_z_buffer = 1 +dm_patching_mode = 0 +dm_auto_scissor_rect = 0 +dm_auto_convergence_post_present = 1 + +;------------------------------------------------------------------------------------------------------ +; Settings for GPU manipulations. +; Render settings override +;------------------------------------------------------------------------------------------------------ +[Rendering] +override_directory_dm=ShaderFixesDM +dm_auto_patch_failure_path = DMAutoPatchFailures +dm_auto_patch_cache_path = DMAutoPatchCache +dm_auto_patch_cache_auto_scissor_path = AutoScissor +dm_auto_patch_cache_hud_path = Hud + +; Automatically patched shaders will be written here if caching is enabled. +cache_directory_dm=ShaderCacheDM + +[Constants] +global $increaseconvergence = 0 +global $decreaseconvergence = 0 +global $increaseseparation = 0 +global $decreaseseparation = 0 +global $showoverlaystereoparams = 0 +global $hideoverlaystereoparamstime = 0 + +[PresetIncreaseConvergence] +condition = ($increaseconvergence == 1 && autoconvergence_enabled == 0) +convergence = convergence * 1.05 +transition = 100 +transition_type = cosine + +[PresetDecreaseConvergence] +condition = ($decreaseconvergence == 1 && autoconvergence_enabled == 0 && convergence > 0.25) +convergence = convergence * 0.95 +transition = 100 +transition_type = cosine + +[PresetIncreaseSeparation] +condition = ($increaseSeparation == 1) +separation = separation + 1 +transition = 50 +transition_type = cosine + +[PresetDecreaseSeparation] +condition = ($decreaseseparation == 1) +separation = separation - 1 +transition = 50 +transition_type = cosine + +[Present] +preset = PresetIncreaseConvergence +preset = PresetDecreaseConvergence +preset = PresetIncreaseSeparation +preset = PresetDecreaseSeparation +if $showoverlaystereoparams + show_stereo_params = 1 + $hideoverlaystereoparamstime = -1 +else + if $increaseSeparation || $decreaseseparation || (($increaseconvergence || $decreaseconvergence) && !autoconvergence_enabled) + show_stereo_params = 1 + $hideoverlaystereoparamstime = time + else if $hideoverlaystereoparamstime == -1 + show_stereo_params = 0 + else if $hideoverlaystereoparamstime + 2.0 < time + show_stereo_params = 0 + $hideoverlaystereoparamstime = -1 + endif +endif + +[KeyToggleOverlayStereoParams] +Key = shift F6 +type = toggle +$showoverlaystereoparams = 1 + +[KeyIncreaseConvergence] +Key = ctrl F6 +type = hold +$increaseconvergence = 1 + +[KeyDecreaseConvergence] +Key = ctrl F5 +type = hold +$decreaseconvergence = 1 + +[KeyIncreaseSeparation] +Key = ctrl F4 +type = hold +$increaseSeparation = 1 + +[KeyDecreaseSeparation] +Key = ctrl F3 +type = hold +$decreaseseparation = 1 + diff --git a/Geo11FilesGoHere/x32/geo/nvapi.dll b/Geo11FilesGoHere/x32/geo/nvapi.dll new file mode 100644 index 0000000..f6186f9 Binary files /dev/null and b/Geo11FilesGoHere/x32/geo/nvapi.dll differ diff --git a/Geo11FilesGoHere/x64/d3dxdm.ini b/Geo11FilesGoHere/x64/d3dxdm.ini index be4a9fc..6381fa5 100644 --- a/Geo11FilesGoHere/x64/d3dxdm.ini +++ b/Geo11FilesGoHere/x64/d3dxdm.ini @@ -22,7 +22,7 @@ ; ; tab - Top and Bottom ; sbs - Side by Side -direct_mode = sbs +direct_mode = katanga_vr matrix_analyzer = 1 auto_detect_depth_buffer = 1 diff --git a/Geo11FilesGoHere/x64/geo/ShaderFixes/3dvision2sbs.hlsl b/Geo11FilesGoHere/x64/geo/ShaderFixes/3dvision2sbs.hlsl new file mode 100644 index 0000000..2f07403 --- /dev/null +++ b/Geo11FilesGoHere/x64/geo/ShaderFixes/3dvision2sbs.hlsl @@ -0,0 +1,99 @@ +Texture2D StereoParams : register(t125); +Texture1D 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 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 */ diff --git a/Geo11FilesGoHere/x64/geo/ShaderFixes/3dvision2sbs.ini b/Geo11FilesGoHere/x64/geo/ShaderFixes/3dvision2sbs.ini new file mode 100644 index 0000000..802f9ff --- /dev/null +++ b/Geo11FilesGoHere/x64/geo/ShaderFixes/3dvision2sbs.ini @@ -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 diff --git a/Geo11FilesGoHere/x64/geo/ShaderFixes/3dvision2sbs_sli_downscale_pass1.hlsl b/Geo11FilesGoHere/x64/geo/ShaderFixes/3dvision2sbs_sli_downscale_pass1.hlsl new file mode 100644 index 0000000..1d84734 --- /dev/null +++ b/Geo11FilesGoHere/x64/geo/ShaderFixes/3dvision2sbs_sli_downscale_pass1.hlsl @@ -0,0 +1,24 @@ +Texture2D StereoParams : register(t125); +Texture1D IniParams : register(t120); +Texture2D 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; +} diff --git a/Geo11FilesGoHere/x64/geo/ShaderFixes/3dvision2sbs_sli_downscale_pass2.hlsl b/Geo11FilesGoHere/x64/geo/ShaderFixes/3dvision2sbs_sli_downscale_pass2.hlsl new file mode 100644 index 0000000..74b41be --- /dev/null +++ b/Geo11FilesGoHere/x64/geo/ShaderFixes/3dvision2sbs_sli_downscale_pass2.hlsl @@ -0,0 +1,50 @@ +Texture2D StereoParams : register(t125); +Texture1D IniParams : register(t120); +Texture2D t100 : register(t100); + +#define mode IniParams[0].x + +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 == 2 || mode == 3) { // Side by side + if (mode == 3) { // Swap eyes + x += width / 2 * (x >= width / 2 ? -1 : 1); + } + } else if (mode == 4 || mode == 5) { // Top and bottom + 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 + y /= 2; + if (mode == 6) { + if (side == 0) { // left side of the reverse blited image + } else { // right side of the reverse blited image + x = x + width / 2; + } + } + else if (mode == 7) { // swap eyes + if (side == 0) { // right side of the reverse blited image + x = x + width / 2; + } else { // left side of the reverse blited image + } + } + } + + result = t100.Load(float3(x, y, 0)); + result.w = 1; +} diff --git a/Geo11FilesGoHere/x64/geo/ShaderFixes/mouse.hlsl b/Geo11FilesGoHere/x64/geo/ShaderFixes/mouse.hlsl new file mode 100644 index 0000000..b869050 --- /dev/null +++ b/Geo11FilesGoHere/x64/geo/ShaderFixes/mouse.hlsl @@ -0,0 +1,219 @@ +#define cursor_window IniParams[0].xy +#define cursor_hotspot IniParams[0].zw +#define window_size IniParams[1].xy +#define cursor_showing IniParams[1].z +#define cursor_pass IniParams[1].w + +Texture2D StereoParams : register(t125); +Texture1D IniParams : register(t120); + +Texture2D cursor_mask : register(t100); +Texture2D cursor_color : register(t101); + +struct vs2ps { + float4 pos : SV_Position0; + float2 texcoord : TEXCOORD0; +}; + +#ifdef VERTEX_SHADER +void main(out vs2ps output, uint vertex : SV_VertexID) +{ + uint mask_width, mask_height; + uint color_width, color_height; + float2 cursor_size; + + // For easy bailing: + output.pos = 0; + output.texcoord = 0; + + if (!cursor_showing) + return; + + cursor_color.GetDimensions(color_width, color_height); + cursor_mask.GetDimensions(mask_width, mask_height); + + if (color_width) { + // Colour cursor, bail if we are in the black and white / inverted cursor pass: + if (cursor_pass == 2) + return; + cursor_size = float2(color_width, color_height); + } else { + // Black and white / inverted cursor, bail if we are in the colour cursor pass: + if (cursor_pass == 1) + return; + cursor_size = float2(mask_width, mask_height / 2); + } + + output.pos.xy = cursor_window - cursor_hotspot; + + // Not using vertex buffers so manufacture our own coordinates. + switch(vertex) { + case 0: + output.texcoord = float2(0, cursor_size.y); + break; + case 1: + output.texcoord = float2(0, 0); + output.pos.y += cursor_size.y; + break; + case 2: + output.texcoord = float2(cursor_size.x, cursor_size.y); + output.pos.x += cursor_size.x; + break; + case 3: + output.texcoord = float2(cursor_size.x, 0); + output.pos.xy += cursor_size; + break; + default: + output.pos.xy = 0; + break; + }; + + // Scale from pixels to clip space: + output.pos.xy = (output.pos.xy / window_size * 2 - 1) * float2(1, -1); + output.pos.zw = float2(0, 1); + + // Adjust stereo depth of pos here using whatever means you feel is + // suitable for this game, e.g. with a suitable crosshair.hlsl you + // could automatically adjust it from the depth buffer: + //float2 mouse_pos = (cursor_window / window_size * 2 - 1); + //output.pos.x += adjust_from_depth_buffer(mouse_pos.x, mouse_pos.y); +} +#endif /* VERTEX_SHADER */ + +#ifdef PIXEL_SHADER +// Draw a black and white, and possibly inverted cursor, +// e.g. use "Windows Standard", "Windows Inverted" or "Windows Black" to test +float4 draw_cursor_bw(float2 texcoord, float2 dimensions) +{ + float4 result; + + if (any(texcoord < 0 || texcoord >= dimensions)) + return float4(0, 0, 0, 1); + + // Black and white cursor - "the upper half is the icon AND bitmask and + // the lower half is the icon XOR bitmask". + uint xor = cursor_mask.Load(float3(texcoord, 0)).x; + uint and = cursor_mask.Load(float3(texcoord.x, texcoord.y + dimensions.y, 0)).x; + + result.xyz = xor; + result.w = and ^ xor; + + return result; +} + +// Draw a colour cursor, e.g. use "Windows Default" to test +float4 draw_cursor_color(float2 texcoord, float2 dimensions) +{ + float4 result; + float mask; + + if (any(texcoord < 0 || texcoord >= dimensions)) + return 0; + + result = cursor_color.Load(float3(texcoord, 0)); + mask = cursor_mask.Load(float3(texcoord, 0)).x; + + // We may or may not have an alpha channel in the color bitmap, but + // as far as I can tell Windows doesn't expose an API to check if the + // cursor has an alpha channel or not, so we have no good way to know + // (32bpp does not imply alpha). People on stackoverflow are scanning + // the entire alpha channel looking for non-zero values to fudge this. + // + // If the alpha is 0 it may either mean there is an alpha channel and + // this pixel should be fully transparent, or that there is no alpha + // channel and this pixel should only use the AND mask for alpha. Let's + // assume that alpha=0 means no alpha channel, which should work + // provided the mask blanks out those pixels as well. + // + // If later we find a way to detect this in 3DMigoto we can use + // Format=DXGI_FORMAT_B8G8R8X8_UNORM_SRGB to indicate there is no alpha + // channel, which will cause the read here to return 1 for opaque. + + if (!result.w) + result.w = 1; + + if (mask) + result.w = 0; + + return result; +} + +float4 smooth_cursor_bw(float2 texcoord) +{ + uint mask_width, mask_height; + float4 px1, px2, px3, px4, tmp1, tmp2; + float2 coord1, coord2; + + cursor_mask.GetDimensions(mask_width, mask_height); + float2 dimensions = float2(mask_width, mask_height / 2); + + // Subtracting 0.5 here to sample at the edge of each pixel instead of + // the center - when not scaling the cursor this will make it just as + // sharp as if we hadn't applied an interpolation filter at all, but + // still gives us a smooth result when we are scaling. Note that this + // can make some of the sample locations negative, which we handle in + // draw_cursor_bw: + texcoord -= 0.5; + + coord1 = floor(texcoord); + coord2 = min(ceil(texcoord), dimensions - 1); + + // Because of the special handling we have to do with the mask, we + // can't use a SamplerState to interpolate the cursor image, so + // implement a simple linear filter with loads instead: + px1 = draw_cursor_bw(coord1, dimensions); + px2 = draw_cursor_bw(float2(coord2.x, coord1.y), dimensions); + px3 = draw_cursor_bw(float2(coord1.x, coord2.y), dimensions); + px4 = draw_cursor_bw(coord2, dimensions); + + tmp1 = lerp(px1, px2, frac(texcoord.x)); + tmp2 = lerp(px3, px4, frac(texcoord.x)); + return lerp(tmp1, tmp2, frac(texcoord.y)); +} + +float4 smooth_cursor_color(float2 texcoord, float2 dimensions) +{ + float4 px1, px2, px3, px4, tmp1, tmp2; + float2 coord1, coord2; + + // Subtracting 0.5 here to sample at the edge of each pixel instead of + // the center - when not scaling the cursor this will make it just as + // sharp as if we hadn't applied an interpolation filter at all, but + // still gives us a smooth result when we are scaling. Note that this + // can make some of the sample locations negative, which we handle in + // draw_cursor_color: + texcoord -= 0.5; + + coord1 = floor(texcoord); + coord2 = min(ceil(texcoord), dimensions - 1); + + // Because of the special handling we have to do with the mask, we + // can't use a SamplerState to interpolate the cursor image, so + // implement a simple linear filter with loads instead: + px1 = draw_cursor_color(coord1, dimensions); + px2 = draw_cursor_color(float2(coord2.x, coord1.y), dimensions); + px3 = draw_cursor_color(float2(coord1.x, coord2.y), dimensions); + px4 = draw_cursor_color(coord2, dimensions); + + tmp1 = lerp(px1, px2, frac(texcoord.x)); + tmp2 = lerp(px3, px4, frac(texcoord.x)); + return lerp(tmp1, tmp2, frac(texcoord.y)); +} + +float4 draw_cursor(float2 texcoord) +{ + uint color_width, color_height; + + cursor_color.GetDimensions(color_width, color_height); + + if (color_width) + return smooth_cursor_color(texcoord, float2(color_width, color_height)); + else + return smooth_cursor_bw(texcoord); +} + +void main(vs2ps input, out float4 result : SV_Target0) +{ + result = draw_cursor(input.texcoord); +} +#endif /* PIXEL_SHADER */ diff --git a/Geo11FilesGoHere/x64/geo/ShaderFixes/mouse.ini b/Geo11FilesGoHere/x64/geo/ShaderFixes/mouse.ini new file mode 100644 index 0000000..b287404 --- /dev/null +++ b/Geo11FilesGoHere/x64/geo/ShaderFixes/mouse.ini @@ -0,0 +1,97 @@ +; This 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 include line in +; the main d3dx.ini. Edit the bottom of mouse.hlsl vertex shader to adjust the +; stereo depth of the cursor as desired. Note that this shader has a higher +; latency than the hardware cursor! + +[Present] +run = CustomShaderSoftwareMouse + +[Device] +hide_cursor = 1 + +[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 +; Back up IniParams we are about to use: +local $bak_x0 = x0 +local $bak_y0 = y0 +local $bak_z0 = z0 +local $bak_w0 = w0 +local $bak_x1 = x1 +local $bak_y1 = y1 +local $bak_z1 = z1 +local $bak_w1 = w1 +; Pass cursor position and visibility info to the shader: +x0 = cursor_window_x +y0 = cursor_window_y +z0 = cursor_hotspot_x +w0 = cursor_hotspot_y +z1 = cursor_showing +; Pass the size of the window to the shader: +x1 = window_width +y1 = 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 w1 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: +w1 = 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 w1: +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 +; Restore IniParams: +x0 = $bak_x0 +y0 = $bak_y0 +z0 = $bak_z0 +w0 = $bak_w0 +x1 = $bak_x1 +y1 = $bak_y1 +z1 = $bak_z1 +w1 = $bak_w1 +[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 w1 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: +w1 = 2 +draw = 4, 0 diff --git a/Geo11FilesGoHere/x64/geo/ShaderFixes/upscale.hlsl b/Geo11FilesGoHere/x64/geo/ShaderFixes/upscale.hlsl new file mode 100644 index 0000000..9898cfa --- /dev/null +++ b/Geo11FilesGoHere/x64/geo/ShaderFixes/upscale.hlsl @@ -0,0 +1,48 @@ +// Upscaling: This shader creates a quad and texture coordinates to be used by the +// pixel shader for full screen blits. + +#ifdef VERTEX_SHADER +void main( + out float4 pos : SV_Position0, out float2 texcoord : TEXCOORD0, + uint vertex : SV_VertexID) +{ + // Not using vertex buffers so manufacture our own coordinates. + switch(vertex) { + case 0: + pos.xy = float2(-1, -1); + texcoord = float2(0,1); + break; + case 1: + pos.xy = float2(-1, 1); + texcoord = float2(0,0); + break; + case 2: + pos.xy = float2(1, -1); + texcoord = float2(1,1); + break; + case 3: + pos.xy = float2(1, 1); + texcoord = float2(1,0); + break; + default: + pos.xy = 0; + texcoord = float2(0,0); + break; + }; + pos.zw = float2(0, 1); +} +#endif /* VERTEX_SHADER */ + +#ifdef PIXEL_SHADER +// This shader uses provided texture coordinates and sampler to blit +// the game screen with 3Dmigoto overlays to the actual swap chain + +Texture2D t101 : register(t101); +SamplerState SampleType; + +void main(float4 pos : SV_Position0, float2 texcoord : TEXCOORD0, out float4 result : SV_Target0) +{ + float2 tex = texcoord.xy; + result = t101.Sample(SampleType, tex); +} +#endif /* PIXEL_SHADER */ diff --git a/Geo11FilesGoHere/x64/geo/ShaderFixes/upscale.ini b/Geo11FilesGoHere/x64/geo/ShaderFixes/upscale.ini new file mode 100644 index 0000000..2cc531b --- /dev/null +++ b/Geo11FilesGoHere/x64/geo/ShaderFixes/upscale.ini @@ -0,0 +1,61 @@ +[Present] +; Enables a custom shader that allows the stereo output mode to be +; upscaled. NOTE: uncomment only if 'upscaling' and resolution are not zero. +run = CustomShaderUpscale + +;------------------------------------------------------------------------------------------------------ +; The following custom shader can be used to perform upscaling to arbitrary resolutions, +; specifically useful for 4K 3D TVs or for DSR. To enable, uncomment the +; ";run = CustomShaderUpscale" in the Present section, set the custom resolution and +; enable "upscaling=1" in the Device section. +; If you uncomment upscale shader without actually enabling the upscaling in [Device] +; you might have wrong screen resolution or the game will not be able to enter the fullscreen mode. +; Both Upscaling and SBS can be used at the same time. + +[Resource3DVisionUpscaleBackupTexture] +[CustomShaderUpscale] +; Load a custom vertex + pixel shader: +vs = upscale.hlsl +ps = upscale.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 +; enable sampler with the filter: anisotropic_filter, linear_filter, point_filter +sampler = anisotropic_filter +; 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 real 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 r_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: +Resource3DVisionUpscaleBackupTexture = reference ps-t101 +; Use faked bb to give the shader access to the back buffers of +; both eyes: +; f_bb is the faked swap chain that has the game resolution +ps-t101 = f_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: +; upscaling with msaa swap chain is currently only avialable if upscale_mode = 1 +; ps-t100 = resolve_msaa f_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 +; Restore the original texture from the ps-t100 slot: +post ps-t101 = reference Resource3DVisionUpscaleBackupTexture +; Tell 3DMigoto that upscaling has been performed. Before this "bb" referred +; to "f_bb" and afterwards will refer to "r_bb" until the next frame. Makes it +; easier to re-order upscaling and other shaders. If this command is not found +; anywhere in the d3dx.ini or upscaling is disabled, "bb" will refer to "r_bb" +special = upscaling_switch_bb diff --git a/Geo11FilesGoHere/x64/geo/Uninstall.bat b/Geo11FilesGoHere/x64/geo/Uninstall.bat new file mode 100644 index 0000000..2748a0f --- /dev/null +++ b/Geo11FilesGoHere/x64/geo/Uninstall.bat @@ -0,0 +1,130 @@ +REM Delete everything that could be in the target folder, including debug items. +REM If something is not there, the DEL skips without error. +REM Also deletes the ShaderCache, ShaderFixes, ShaderFromGame folders + +del d3d9.dll +del d3d9_log.txt +del d3d9.exp +del d3d9.pdb +del d3d9.ilk +del d3d9.lib + +del d3d10.dll +del d3d10_log.txt +del d3d10.exp +del d3d10.pdb +del d3d10.ilk +del d3d10.lib + +del d3d11.dll +del d3d11_log.txt +del d3d11_profile_log.txt +del d3d11.exp +del d3d11.pdb +del d3d11.ilk +del d3d11.lib + +del "3DMigoto Loader.exe" + +del D3DCompiler_39.dll +del D3DCompiler_39_org.dll +del D3DCompiler_39_log.txt +del D3DCompiler_39.exp +del D3DCompiler_39.pdb +del D3DCompiler_39.ilk +del D3DCompiler_39.lib + +del D3DCompiler_41.dll +del D3DCompiler_41_org.dll +del D3DCompiler_41_log.txt +del D3DCompiler_41.exp +del D3DCompiler_41.pdb +del D3DCompiler_41.ilk +del D3DCompiler_41.lib + +del D3DCompiler_42.dll +del D3DCompiler_42_org.dll +del D3DCompiler_42_log.txt +del D3DCompiler_42.exp +del D3DCompiler_42.pdb +del D3DCompiler_42.ilk +del D3DCompiler_42.lib + +del D3DCompiler_43.dll +del D3DCompiler_43_org.dll +del D3DCompiler_43_log.txt +del D3DCompiler_43.exp +del D3DCompiler_43.pdb +del D3DCompiler_43.ilk +del D3DCompiler_43.lib + +REM games seem to use this often, let's not delete this +REM file, as it's benign if not used. +REM del D3DCompiler_46.dll +del D3DCompiler_46_org.dll +del D3DCompiler_46_log.txt +del D3DCompiler_46.exp +del D3DCompiler_46.pdb +del D3DCompiler_46.ilk +del D3DCompiler_46.lib + +del dxgi.dll +del dxgi_log.txt +del dxgi.exp +del dxgi.pdb +del dxgi.ilk +del dxgi.lib + +del nvapi.dll +del nvapi_log.txt +del nvapi.exp +del nvapi.pdb +del nvapi.ilk +del nvapi.lib + +del nvapi64.dll +del nvapi_log.txt +del nvapi64.exp +del nvapi64.pdb +del nvapi64.ilk +del nvapi64.lib + + +del courierbold.spritefont +del XInput9_1_0.dll +del d3dx.ini +del d3dx_user.ini +del 3dmigoto9.ini + +del DirectXTK.lib +del DirectXTK.pdb +del DirectXTK.ilk + +del D3D_Shaders.exe +del D3D_Shaders.pdb +del D3D_Shaders.ilk +del D3D_Shaders.lib + +del BinaryDecompiler.lib + +del ShaderUsage.txt + + +rmdir /s /q ShaderFixes +rmdir /s /q ShaderCache +rmdir /s /q ShaderFromGame + + +REM Delete possible _disabled files from 3DFM/HelixVision +del nvwgf2umx_disabled.dll +del d3d11_disabled.dll + +REM Delete any new geo-11 DM files and folders +del d3dxdm.ini + +rmdir /s /q DMAutoPatchCache +rmdir /s /q DMAutoPatchFailures +rmdir /s /q ShaderCacheDM +rmdir /s /q ShaderFixesDM + +del uninstall.bat diff --git a/Geo11FilesGoHere/x64/geo/d3d11.dll b/Geo11FilesGoHere/x64/geo/d3d11.dll index 16411ca..78226c9 100644 Binary files a/Geo11FilesGoHere/x64/geo/d3d11.dll and b/Geo11FilesGoHere/x64/geo/d3d11.dll differ diff --git a/Geo11FilesGoHere/x64/geo/d3dcompiler_47.dll b/Geo11FilesGoHere/x64/geo/d3dcompiler_47.dll index cbe0765..e21b65b 100644 Binary files a/Geo11FilesGoHere/x64/geo/d3dcompiler_47.dll and b/Geo11FilesGoHere/x64/geo/d3dcompiler_47.dll differ diff --git a/Geo11FilesGoHere/x64/geo/d3dxdm.ini b/Geo11FilesGoHere/x64/geo/d3dxdm.ini index 40d5379..6381fa5 100644 --- a/Geo11FilesGoHere/x64/geo/d3dxdm.ini +++ b/Geo11FilesGoHere/x64/geo/d3dxdm.ini @@ -11,15 +11,18 @@ [Device] ; direct_mode: choose stereo output option based on hardware -; nvidia_dx9 -; nvidia_dx11 -; tab -; tab_reversed -; sbs -; sbs_reversed -; interlaced -; interlaced_reversed -direct_mode = nvidia_dx11 +; tab_reversed - not yet implemented +; sbs_reversed - not yet implemented +; interlaced - not implemented +; interlaced_reversed - not implemented +; +; katanga_vr - vr output to HelixVision. +; nvidia_dx9 - works on latest drivers. Requires 3D Vision Driver. Requires game in exclusive fullscreen. +; nvidia_dx11 - works up to driver 452.06. Requires 3D Vision Driver. Requires game in windowed mode. +; +; tab - Top and Bottom +; sbs - Side by Side +direct_mode = katanga_vr matrix_analyzer = 1 auto_detect_depth_buffer = 1 @@ -29,7 +32,7 @@ dm_deferred_context_queue_per_eye = 0 repeat_command_list_depth_buffer_stats = 0 fps_monitor_interval = 1 -show_fps_monitor = true +show_fps_monitor = false ; fps_show_hide = no_modifiers VK_F5 ;------------------------------------------------------------------------------------------------------ diff --git a/Geo11FilesGoHere/x64/geo/nvapi64.dll b/Geo11FilesGoHere/x64/geo/nvapi64.dll index 4d46100..5c99e07 100644 Binary files a/Geo11FilesGoHere/x64/geo/nvapi64.dll and b/Geo11FilesGoHere/x64/geo/nvapi64.dll differ diff --git a/Geo11_Shortcut_Maker.exe b/Geo11_ModManager.exe similarity index 99% rename from Geo11_Shortcut_Maker.exe rename to Geo11_ModManager.exe index d9c2065..c95b228 100644 Binary files a/Geo11_Shortcut_Maker.exe and b/Geo11_ModManager.exe differ diff --git a/Geo11_Mod_Manager.zip b/Geo11_Mod_Manager.zip new file mode 100644 index 0000000..d646b53 Binary files /dev/null and b/Geo11_Mod_Manager.zip differ diff --git a/Simple.ahk b/Simple.ahk index b5c0a8c..111e346 100644 --- a/Simple.ahk +++ b/Simple.ahk @@ -20,10 +20,10 @@ delimiter = "," LogGames := A_AppDataCommon "\GameslistGeo11\Gamename.txt" NextInstall := A_AppDataCommon "\GameslistGeo11\NextInstall.txt" GamesUpdate := A_AppDataCommon "\GameslistGeo11\GamesUpdate.txt" - +HelixLauncherBat := "\vrapplauncher.bat" Logdir := A_AppDataCommon "\GameslistGeo11" HelixLocal := A_AppDataCommon "\GameslistGeo11\HelixLocal.txt" -FileCreateDir, %Logdir% +FileCreateDir, %Logdir% /* Loop, read, %GamesUpdate% { @@ -61,9 +61,10 @@ delimiter := "," neutron := new NeutronWindow() neutron.Load("Simple.html") -FileInstall, lib\bootstrap.min.css, \lib\bootstrap.min.css -FileInstall, lib\bootstrap.min.js, \lib\bootstrap.min.js -FileInstall, lib\jquery.min.js, \lib\jquery.min.js +FileInstall, lib\bootstrap.min.css, lib\bootstrap.min.css +FileInstall, lib\bootstrap.min.js, lib\bootstrap.min.js +FileInstall, lib\jquery.min.js, lib\jquery.min.js +FileInstall, Untitled-1.png, Untitled-1.png neutron.Gui("+LabelNeutron") ; Use the Gui method to set a custom label prefix for GUI events. This code is @@ -368,8 +369,7 @@ Ex4_Submit3(neutron, event) ) } } - */ - + */ /* Loop, Read, %HTMLFile% @@ -382,8 +382,8 @@ Ex4_Submit3(neutron, event) ) } */ - neutron.qs("#myH2data").innerHTML:="" - neutron.qs("#myH2data").innerHTML:=html + neutron.qs("#myH2data").innerHTML:="" + neutron.qs("#myH2data").innerHTML:=html /* Model:=CSV_ReadCell("data", 2,2) @@ -458,7 +458,7 @@ BrowseButton(neutron, event) HTMLFile := A_AppDataCommon "\GameslistGeo11\HTMLfile.txt" ; event.target will contain the HTML Element that fired the event. ; Show a message box with its inner text. - */ + */ FileSelectFile, Selectgame, 32, , Select a game, Application (*.exe) if (Selectgame = "") MsgBox, You didn't select anything. @@ -469,11 +469,11 @@ BrowseButton(neutron, event) if !FileExist(LogGames) { Games= -( + ( -%Selectgame%, %Gameexe% + %Selectgame%, %Gameexe% -) + ) FileAppend,%Games%,%LogGames% GameError := 0 } @@ -486,7 +486,7 @@ BrowseButton(neutron, event) Gamename := LineRead[2] If InStr(Gamename, Gamenameonly) { - + Msgbox, Error. %Gameexe% already has Geo11. GameError := 1 break @@ -530,43 +530,39 @@ BrowseButton(neutron, event) GameError:=0 } } - - If (GameError=0) +*/ + If (GameError="0") { - msgbox, 2 - FileDelete, %GamesUpdate% - FileAppend, %Gameexe%, %GamesUpdate% HTMLPretext= ( - %Selectgame%,%Gameexe%,%Gamepath% +%Selectgame%,%Gameexe%,%Gamepath% ) + FileDelete, %GamesUpdate% + FileAppend, %HTMLPretext%, %GamesUpdate% GameError := 0 FileDelete, %HTMLFile% FileAppend, %HTMLPretext%, %HTMLFile% - } - else - msgbox, placement9 - } - */ + } + } } ;Gui Add, ComboBox, vcbx w200 vVersChoice, x32||x64 ;Gui Add, ComboBox, vcbx w200 vVersChoice, x32||x64 ;html := Gameexe - + } Warning(neutron, event) { -Msgbox, For now, browse for your game first and then select your VR app location. For configure, that feature will be enabled later this weekend. -} + Msgbox, For now, browse for your game first and then select your VR app location. For configure, that feature will be enabled later this weekend. + } + SubmitGen(neutron, event) { Global event.preventDefault() ; Some events have a default action that needs to be prevented. A form will ; redirect the page by default, but we want to handle the form data ourself. - GetAddresses() ; Use Neutron's GetFormData method to process the form data into a form that ; is easily accessed. Fields that have a 'name' attribute will be keyed by @@ -576,6 +572,22 @@ SubmitGen(neutron, event) msgbox, Select a game else { + SplitPath, Selectgame, Gameexe, Gamepath + + Loop, read, %GamesUpdate% + { + Currentline := A_LoopReadLine + + if (Currentline="") + continue + else + break + } + + + LineRead := StrSplit(Currentline,delimiter) + Gameexe := LineRead[2] + Selectgame := LineRead[1] ; You can access all of the form fields by iterating over the FormData ; object. It will go through them in the order they appear in the HTML. @@ -584,26 +596,27 @@ SubmitGen(neutron, event) vrapp := formData.vrapp gamevers := formData.gamevers - if FileExist(HelixLocal) + if FileExist(HelixLocal) { BinaryHelixFile := 1 Loop, read, %HelixLocal% { - if (A_LoopReadLine="") + CurrLine:=A_LoopReadLine + if (CurrLine="") continue else { - HelixPath := % A_LoopReadLine + HelixPath := CurrLine } } + } Else - BinaryHelixFile := 0 - If (HelixPath ="") + BinaryHelixFile := "0" + If (HelixPath="") { - BinaryHelixFile := 0 - } - + BinaryHelixFile := "0" + } ; Show the output if (gamevers="64x") @@ -619,7 +632,8 @@ SubmitGen(neutron, event) ;arraygeo := ["d3d11.geo", "d3dcompiler_47.geo", "d3dx.geo", "d3dxdm.geo", "nvapi64.geo"] FileCreateDir, %Gamepath%\geo FileCreateDir, %Gamepath%\originaldx - ;arraygeo := ["d3d11.geo", "d3dcompiler_47.geo", "d3dx.geo", "d3dxdm.geo", "nvapi64.geo"] + ;arraygeo := ["d3d11.geo", "d3dcompiler_47.geo", "d3dx.geo", "d3dxdm.geo", "nvapi64.geo"] + array := ["d3d11.dll", "d3dcompiler_47.dll", "d3dx.ini", "d3dxdm.ini", "nvapi64.dll"] For index, value in array @@ -627,7 +641,10 @@ SubmitGen(neutron, event) geo := % array[index] FileCopy, %DllLocal%\%geo%, %Gamepath%\geo\%geo%, 1 } - FileCopy, %A_ScriptDir%\leaveingamedir.exe, %Gamepath%\leaveingamedir.exe, 1 + FileDelete, %Gamepath%\leaveingamedir.exe + FileDelete, %Gamepath%\pregame_move.bat + FileDelete, %Gamepath%\postgame_move.bat + FileCopy, %A_ScriptDir%\leaveingamedir.exe, %Gamepath%\leaveingamedir.exe, 1 FileCopy, %A_ScriptDir%\pregame_move.bat, %Gamepath%\pregame_move.bat, 1 FileCopy, %A_ScriptDir%\postgame_move.bat, %Gamepath%\postgame_move.bat, 1 FileCopyDir, %DllLocal%\ShaderFixes, %Gamepath%\ShaderFixes, 1 @@ -636,153 +653,207 @@ SubmitGen(neutron, event) Random, rand, 1, 12 Localicon := A_ScriptDir "\ico\" rand ".ico" TextforGamelog= -( - + ( + %Selectgame%,%Gameexe% - -) - If (vrapp="Helix Vision" or vrapp="Virtual Desktop" or vrapp="Other") - { - if (BinaryHelixFile != 0) - { - msgbox, 4,, Is this the right path to %vrapp%? `n%HelixPath% - IfMsgBox No - Goto, KatangaGo1 - IfMsgBox Yes - Goto, KatangaYes1 - } - KatangaGo1: - msgboxstored= -( + + ) + HV:="0" + VRL:="0" + If (vrapp = "Helix Vision") + { + HV:="1" + VRL:="1" + } + if (vrapp= "Virtual Desktop" or vrapp="Other") + { + HV:="0" + VRL:="1" + msgbox, This was designed to integrate with HelixVision, other VR apps won't have full resolution. + } + if (HV="0" and VRL="0") + { + HV:="0" + VRL:="0" + msgbox, This was designed to integrate with HelixVision, other VR apps won't have full resolution. + } + if (HV="0" and VRL="0") + { + Goto, NoDesktopApp + msgbox, This was designed to integrate with HelixVision, other VR apps won't have full resolution. + } + + if (BinaryHelixFile=1) + { + msgbox, 4,, Is this the right path to %vrapp%? `n%HelixPath% + IfMsgBox No + Goto, KatangaGo1 + IfMsgBox Yes + Goto, KatangaYes1 + } + KatangaGo1: + if (HL=1) + { + msgboxstored= + ( Usually stored in C:\Program Files (x86)\Steam\steamapps\common\HelixVision\Tools\Katanga\katanga.exe -) - Msgbox, Select Path to %vrapp%. %msgboxstored% - FileSelectFile, HelixPath, 32, , Select Kantagna Path, Application (*.exe) - if (Selectgame = "") - MsgBox, You didn't select anything. - - KatangaYes1: - FileDelete, %Logfile% ; - tester1= -( + ) + } + Msgbox, Select Path to %vrapp%. %msgboxstored% + FileSelectFile, HelixPath, 32, , Select Kantagna Path, Application (*.exe) + if (Selectgame = "") + MsgBox, You didn't select anything. + KatangaYes1: + FileDelete, %Logfile% ; + tester1= + ( %Selectgame% %HelixPath% -) - FileAppend, %tester1%, %Logfile% - Filedelete, %HelixLocal% - FileAppend, %HelixPath%, %HelixLocal% - } - Else - FileAppend, %Selectgame%, %Logfile% + ) + FileAppend, %tester1%, %Logfile% + /* - FileAppend, %TextforGamelog%, %LogGames% - html:=LoadInstalled(html) - - empty:="" - neutron.qs("#myH2data").innerHTML:=empty - sleep, 50 - neutron.qs("#myH2data").innerHTML:=html - - ShortcutMaker := A_Desktop "\" Gamenameonly " VR.lnk" - AHKLocal := Gamepath "\leaveingamedir.exe" - FileCreateShortcut, %AHKLocal%, %ShortcutMaker%, %Gamepath%,,,%Localicon% - Msgbox, Geo11 Shortcut sent to desktop. - Selectgame:="" - FileDelete, %GamesUpdate% - FileAppend, + helix launcher batch for katanga + + */ + + If (HV=1) + { + filedelete, %A_ScriptDir%\%HelixLauncherBat% + Fileappend, ( -%Gamepath%\%Gameexe%,%Gameexe%,%Gamenameonly% - ), %GamesUpdate% +@echo off +start "" "%HelixPath%" --game-path "%Selectgame%" --launch-type DX11Exe +rem +rem +rem +echo: +echo: +echo: +echo: Loading Katanga and Moving Mountains +echo: +rem +rem +rem +timeout /t 20 +rem +rem +rem +), %A_ScriptDir%\%HelixLauncherBat% + Filedelete, %HelixLocal% + FileAppend, %HelixPath%, %HelixLocal% + } + } + + FileCopy, %A_ScriptDir%\%HelixLauncherBat%, %Gamepath%\%HelixLauncherBat%, 1 + NoDesktopApp: + FileAppend, %TextforGamelog%, %LogGames% + html:=LoadInstalled(html) + + empty:="" + neutron.qs("#myH2data").innerHTML:=empty + sleep, 50 + neutron.qs("#myH2data").innerHTML:=html + + ShortcutMaker := A_Desktop "\" Gamenameonly " VR.lnk" + AHKLocal := Gamepath "\leaveingamedir.exe" + FileCreateShortcut, %AHKLocal%, %ShortcutMaker%, %Gamepath%,,,%Localicon% + Msgbox, Geo11 Shortcut sent to desktop. + Selectgame:="" + FileDelete, %GamesUpdate% + FileAppend, + ( + %Gamepath%\%Gameexe%,%Gameexe%,%Gamenameonly% + ), %GamesUpdate% /* html:=LoadInstalled(html) neutron.doc.getElementById("myH2").insertAdjacentHTML("beforebegin",html) - */ - } - } + */ + Selectgame:="" + } - Storing(Stringer,Event) - { - Loop, read, %LogGames% - if (A_LoopReadLine="") - continue - else +Storing(Stringer,Event) +{ + Loop, read, %LogGames% + if (A_LoopReadLine="") + continue + else + { + Cell := StrSplit(A_LoopReadLine,delimiter) + If (Stored="") { - Cell := StrSplit(A_LoopReadLine,delimiter) - If (Stored="") - { - Stored := Cell[2] - Stringer= - ( - - ) - } - else - Stored := Cell[2] + Stored := Cell[2] Stringer= ( - %Stringer% - - ) - return, %Stringer% + + ) } - } + else + Stored := Cell[2] + Stringer= + ( + %Stringer% + + ) + return, %Stringer% + } +} - Uninstaller(neutron, event) - { +Uninstaller(neutron, event) +{ - Global - event.preventDefault() - ; Some events have a default action that needs to be prevented. A form will - ; redirect the page by default, but we want to handle the form data ourself. - - GetAddresses() - ; Use Neutron's GetFormData method to process the form data into a form that - ; is easily accessed. Fields that have a 'name' attribute will be keyed by - ; that, or if they don't they'll be keyed by their 'id' attribute. - formData := neutron.GetFormData(event.target) - for name, value in formData - StoredGet:=value - ; You can access all of the form fields by iterating over the FormData - ; object. It will go through them in the order they appear in the HTML. - ; You can also get field values by name directly. Use object dot notation - ; with the field name/id. + Global + event.preventDefault() + ; Some events have a default action that needs to be prevented. A form will + ; redirect the page by default, but we want to handle the form data ourself. + + GetAddresses() + ; Use Neutron's GetFormData method to process the form data into a form that + ; is easily accessed. Fields that have a 'name' attribute will be keyed by + ; that, or if they don't they'll be keyed by their 'id' attribute. + formData := neutron.GetFormData(event.target) + for name, value in formData + StoredGet:=value + ; You can access all of the form fields by iterating over the FormData + ; object. It will go through them in the order they appear in the HTML. + ; You can also get field values by name directly. Use object dot notation + ; with the field name/id. /* html= ( ) - */ - Msgbox, 4,, Uninstall Geo11 for %StoredGet%? - IfMsgBox Yes - { - FSRemove(StoredGet) - html:="" - delimiter := "," - Loop, read, %LogGames% - { - if (A_LoopReadLine="") - continue - else - { - Cell := StrSplit(A_LoopReadLine,delimiter) - curgame := Cell[2] - html= -( - + */ + Msgbox, 4,, Uninstall Geo11 for %StoredGet%? + IfMsgBox Yes + { + FSRemove(StoredGet) + html:="" + delimiter := "," + Loop, read, %LogGames% + { + if (A_LoopReadLine="") + continue + else + { + Cell := StrSplit(A_LoopReadLine,delimiter) + curgame := Cell[2] + html= + ( + -%html% -) - } - } - - /* - Loop, read, %LogGames% + %html% + ) + } + } + + Loop, read, %GamesUpdate% { Currentline := A_LoopReadLine If InStr(Currentline, StoredGet) { LineRead := StrSplit(Currentline,delimiter) - GameLocation := LineRead[2] + GameLocation := LineRead[1] SplitPath, GameLocation, OutFileName, OutDir, OutExtension, OutNameNoExt, OutDrive Filedelete, %OutDir%\geo\*.dll Filedelete, %OutDir%\geo\*.ini @@ -790,6 +861,7 @@ Usually stored in C:\Program Files (x86)\Steam\steamapps\common\HelixVision\Tool Filedelete, %OutDir%\pregame*.bat Filedelete, %OutDir%\postgame*.bat Filedelete, %OutDir%\VRLaun*.exe + Filedelete, %OutDir%\vrapplauncher.bat ;FileAppend %A_LoopReadLine%`n ;FileMove, %GamesUpdate%, %LogGames%, 1 LineNumber := A_Index - 1 @@ -798,14 +870,14 @@ Usually stored in C:\Program Files (x86)\Steam\steamapps\common\HelixVision\Tool else Continue } - */ - Msgbox, Success `nThe UI will update when you restart. - Goto, Beginning - } - Else - Goto, Nevermind + */ + Msgbox, Success `nThe UI will update when you restart. + Goto, Beginning + } + Else + Goto, Nevermind - Beginning: + Beginning: /* html:="" LoadInstalled() @@ -818,20 +890,20 @@ Usually stored in C:\Program Files (x86)\Steam\steamapps\common\HelixVision\Tool neutron.doc.getElementById("myH2data").insertAdjacentHTML("afterbegin",html) ;neutron.doc.getElementById("myH2data").insertAdjacentHTML("afterbegin",html) */ - Nevermind: - } + Nevermind: + } - SetLocations() - { - ColumnNr := [1] - delimiter := "," + SetLocations() + { + ColumnNr := [1] + delimiter := "," - LogGames := A_AppDataCommon "\GameslistGeo11\Gamename.txt" - NextInstall := A_AppDataCommon "\GameslistGeo11\NextInstall.txt" - GamesUpdate := A_AppDataCommon "\GameslistGeo11\GamesUpdate.txt" + LogGames := A_AppDataCommon "\GameslistGeo11\Gamename.txt" + NextInstall := A_AppDataCommon "\GameslistGeo11\NextInstall.txt" + GamesUpdate := A_AppDataCommon "\GameslistGeo11\GamesUpdate.txt" - Logdir := A_AppDataCommon "\GameslistGeo11" - HelixLocal := A_AppDataCommon "\GameslistGeo11\HelixLocal.txt" - HTMLFile := A_AppDataCommon "\GameslistGeo11\HTMLfile.txt" - } + Logdir := A_AppDataCommon "\GameslistGeo11" + HelixLocal := A_AppDataCommon "\GameslistGeo11\HelixLocal.txt" + HTMLFile := A_AppDataCommon "\GameslistGeo11\HTMLfile.txt" + } diff --git a/Simple.html b/Simple.html index 705d0d0..190f61f 100644 --- a/Simple.html +++ b/Simple.html @@ -274,10 +274,9 @@
-

+

- This app will take the Geo11 files such as dxd11.dll and move to a "geo" folder in the game's directory. - Ensuring the game's original files stay intact.

+ This app will load Geo11 files, and Katanga from HelixVision, without harming the game's files.

It creates a desktop shortcut, when clicked, it will move the game's original "dxd11.dll" files to "/originaldx" and load geo11 dxd11 files. Creating a VR specific launcher/shortcut. On game close, the files @@ -285,32 +284,35 @@

This is a 3rd party mod loader, I am not affiliated with the Geo11 team. Just a fan.

-

Browse for New Game or Manage Existing Games

+

Browse for Game or Manage Existing Games

Select Game Location and version. 'Generate' will push the Geo11 files to a folder in the game's directory and a - Geo11 desktop shortcut.

-

+ Geo11 desktop shortcut.

+ + + +
- +
- +
@@ -321,7 +323,7 @@

Browse for New Game or Manage Existing Games<

- +

@@ -332,8 +334,8 @@

Browse for New Game or Manage Existing Games< - - @@ -346,15 +348,19 @@

Browse for New Game or Manage Existing Games<

+ +

+

+










-

Update feature coming soon. Credit to Geo11 Helix team.

+

Update feature coming soon. Credit to Geo11 Helix team.

diff --git a/browse.ahk b/browse.ahk new file mode 100644 index 0000000..7a9010c --- /dev/null +++ b/browse.ahk @@ -0,0 +1,358 @@ +GetAddresses() +{ + global + LogGames := A_AppDataCommon "\GameslistGeo11\Gamename.txt" + NextInstall := A_AppDataCommon "\GameslistGeo11\NextInstall.txt" + GamesUpdate := A_AppDataCommon "\GameslistGeo11\GamesUpdate.csv" + HelixLauncherBat := "\GameslistGeo11\vrapplauncher.bat" + HTMLFile := A_AppDataCommon "\GameslistGeo11\HTMLfile.txt" + HTMLFile1 := A_AppDataCommon "\GameslistGeo11\HTMLfile1.txt" + HelixLocal := A_AppDataCommon "\GameslistGeo11\HelixLocal.txt" + ColumnNr := [1] + TF("!" . LogGames, CreateGlobalVar="T") + TF("!" . HTMLFile, CreateGlobalVar="H") + delimiter := "," + return +} + +FSRemove(StoredGet) +{ + Global + LogGames := A_AppDataCommon "\GameslistGeo11\Gamename.txt" + loopstore:="" + Loop, Read, %LogGames% + { + word_array := StrSplit(A_LoopReadLine, delimiter) + string:=word_array[2] + if instr(string,StoredGet) + continue + if (string="") + continue + else + { + loopstore= + ( +%A_LoopReadLine% + +%loopstore% + + ) + } + } + Filedelete, loggame.txt + Fileappend, %loopstore%, loggame.txt + Filemove, loggame.txt, %LogGames%, 1 + Filedelete, %GamesUpdate% + Fileappend, %loopstore%, %GamesUpdate% +} + +Readfile() +{ + GamesUpdate := A_AppDataCommon "\GameslistGeo11\GamesUpdate.csv" + CSV_Load(GamesUpdate,"csv", ",") + Cols:=CSV_TotalCols("csv") + Loop, % Cols + { + reader := CSV_ReadCell("csv",1,A_Index) + totaller.= CSV_ReadCell("csv",1,A_Index) + } +} +LoadInstalled(html) +{ + global + delimiter:="," + html:="" + Logger:=[] + Loop, read, %LogGames% + { + word_array := StrSplit(A_LoopReadLine, delimiter) + string:=word_array[2] + if (string!="") + { + html= + ( + + +%html% + ) + Gamesarray:=Logger[A_Index] + } + } + + Filedelete, loggame.txt + FileAppend, %html%, loggame.txt + FileMove, loggame.txt, %HTMLFile%, 1 + return html +} + +LooperHtml(looper) +{ + global + line:="" + Loop, Read, %HTMLFile% ; read file line by line + if !instr(A_LoopReadLine,Gameexe) + { + line .= A_LoopReadLine + } + FileAppend, %line%, %HTMLFile1% + FileMove, %HTMLFile1%, %HTMLFile%, 1 + +} + +LoopGameFile() +{ + Global + CSV_Load(LogGames, "data") + Rows:=CSV_TotalRows("data") + Loop, % Rows + { + Row:=A_Index + Rowdata:=CSV_ReadRow("data",Row) + If Instr(Rowdata,StoredGet) + CSV_DeleteRow("data", Row) + } +} +/* +BROWSE_One() +{ + + GetAddresses() + global LogGames + global NextInstall + global GamesUpdate + global HTMLFile + global ColumnNr + global delimiter + FileSelectFile, Selectgame, 32, , Select a game, Application (*.exe) + if (Selectgame = "") + MsgBox, You didn't select anything. + else + { + SplitPath, Selectgame, Gameexe, Gamepath, Gameextenstion, Gamenameonly + if !FileExist(LogGames) + { + FileAppend,%Selectgame%,%LogGames% + FileDelete, %GamesUpdate% + CurrentGameString= +( +%Selectgame%,%Gameexe%,%Gamepath% +) + FileAppend,%CurrentGameString%,%LogGames% + GameError := 0 + Goto, Nextup + } + Else + { + Loop, read, %LogGames% + { + Currentline := A_LoopReadLine + If InStr(Currentline, Gameexe) + { + LineRead := StrSplit(Currentline,delimiter) + Gamename := LineRead[2] + Msgbox, Error. %Gamename% already has Geo11. + GameError := 1 + break + } + Else + { + HTMLPretext= + ( + %Selectgame%,%Gameexe%,Gamepath + ) + GameError := 0 + FileAppend, %Gameexe%, %GamesUpdate% + FileAppend, %HTMLPretext%, %HTMLFile% + Stringer= + ( +`n + ) + } + } + ;Gui Add, ComboBox, vcbx w200 vVersChoice, x32||x64 + } + } + Nextup: ;Gui Add, ComboBox, vcbx w200 vVersChoice, x32||x64 + GuiControlGet,BinaryInstall,, Install ; pass on a file, replace the word "key" with "lock" in file_copy.txt + + Return Stringer +} + +LoadGames() +{ + + GetAddresses() + global LogGames + global NextInstall + global GamesUpdate + global HTMLFile + global ColumnNr + global delimiter + msgbox, 1 + Stored := "" + Loop, Read, %LogGames% + { + if (A_LoopReadLine="") + continue + else + { + Cell := StrSplit(A_LoopReadLine,delimiter) + If (Stored="") + { + Stored := Cell[2] + Stringer= + ( + `n + ) + } + else + { + Stored := Cell[2] + Stringer= + ( + %Stringer% + + ) + msgbox, %Stringer% + } + } + } + FileAppend, %Stringer%, %HTMLFile% + return Stringer +} + +Generater() +{ + + GetAddresses() + global LogGames + global NextInstall + global GamesUpdate + global HTMLFile + global ColumnNr + global delimiter + if (GameError=0) + { + GuiControlGet,VersionRet,, Version + Msgbox, %VersionRet% Dlls for %Gameexe% + if (VersionRet="x64 game") + { + 64or32 := "\Geo11FilesGoHere\x64\" + } + Else + { + 64or32 := "\Geo11FilesGoHere\x32\" + } + DllLocal := A_ScriptDir 64or32 + ChangeNames := DllLocal + ;arraygeo := ["d3d11.geo", "d3dcompiler_47.geo", "d3dx.geo", "d3dxdm.geo", "nvapi64.geo"] + FileCreateDir, %Gamepath%\geo + FileCreateDir, %Gamepath%\originaldx + ;arraygeo := ["d3d11.geo", "d3dcompiler_47.geo", "d3dx.geo", "d3dxdm.geo", "nvapi64.geo"] + arraydll := ["d3d11.dll", "d3dcompiler_47.dll", "d3dx.ini", "d3dxdm.ini", "nvapi64.dll"] + + For index, value in arraydll + { + geo := % arraydll[index] + FileCopy, %DllLocal%\%geo%, %Gamepath%\geo\%geo%, 1 + } + FileCopy, %A_ScriptDir%\leaveingamedir.exe, %Gamepath%\leaveingamedir.exe, 1 + FileCopy, %A_ScriptDir%\pregame_move.bat, %Gamepath%\pregame_move.bat, 1 + FileCopy, %A_ScriptDir%\postgame_move.bat, %Gamepath%\postgame_move.bat, 1 + FileCopyDir, %DllLocal%\ShaderFixes, %Gamepath%\ShaderFixes, 1 + + Logfile := Gamepath "\Gamename.txt" + Random, rand, 1, 12 + Localicon := A_ScriptDir "\ico\" rand ".ico" + TextforGamelog := Selectgame "," Gameexe "`n" + If (BinaryInstall="Yes") + { + if (HelixPath != "") + { + msgbox, 4,, Is this the right path to Helix Katanga? `n%HelixPath% + IfMsgBox No + Goto, KatangaGo + IfMsgBox Yes + Goto, KatangaYes + } + KatangaGo: + Msgbox, Select Path to Katanga + FileSelectFile, HelixPath, 32, , Select Kantagna Path, Application (*.exe) + if (Selectgame = "") + MsgBox, You didn't select anything. + } + KatangaYes: + FileDelete, %Logfile% ; + If (BinaryInstall="Yes") + { + FileAppend, + ( + %Selectgame% + %HelixPath% + ), %Logfile% + Filedelete, %Helix% + FileAppend, %HelixPath%, %Helix% + } + Else + FileAppend, %Selectgame%, %Logfile% + + FileAppend, %TextforGamelog%, %LogGames% + + ShortcutMaker := A_Desktop "\" Gamenameonly " VR.lnk" + AHKLocal := Gamepath "\leaveingamedir.exe" + FileCreateShortcut, %AHKLocal%, %ShortcutMaker%, %Gamepath%,,,%Localicon% + Msgbox, Geo11 Shortcut sent to desktop. + + } + Else + Msgbox, Select a game without Geo11 files + } + + HelixFunc() + { + GetAddresses() + global LogGames + global NextInstall + global GamesUpdate + global HTMLFile + global ColumnNr + global delimiter + FileSelectFile, SelectHelix, 32, , Select a Helix, Application (*.exe) + if (SelectHelix = "") + MsgBox, You didn't select anything. + else + { + + SplitPath, SelectHelix, Helixexe, Helixpath, Helixextenstion, Helixnameonly + + if !FileExist(Helix) + { + FileAppend,%Selecthelix%,%LogGames% + helixError := 0 + Goto, Letsgo + } + Else + { + Loop, read, %LogGames% + { + Currentline := A_LoopReadLine + If InStr(Currentline, Helixexe) + { + LineRead := StrSplit(Currentline,delimiter) + Helixname := LineRead[2] + Msgbox, Error. %Helixname% already has Geo11. + HelixError := 1 + break + } + Else + { + HelixError := 0 + FileAppend, %Helixexe%, %HelixUpdate% + } + } + ;Gui Add, ComboBox, vcbx w200 vVersChoice, x32||x64 + } + } + Letsgo: ;Gui Add, ComboBox, vcbx w200 vVersChoice, x32||x64 + GuiControlGet,BinaryInstall,, Install + } \ No newline at end of file diff --git a/leaveingamedir.ahk b/leaveingamedir.ahk index a86a74c..1a70b65 100644 --- a/leaveingamedir.ahk +++ b/leaveingamedir.ahk @@ -12,14 +12,30 @@ SplitPath, OutputVar, Gameexe, Gamepath, Gameextenstion, Gamenameonly arraygeo := ["d3d11.geo", "d3dcompiler_47.geo", "d3dx.geo", "d3dxdm.geo", "nvapi64.geo"] arrayorig := ["d3d11.orig", "d3dcompiler_47.orig", "d3dx.orig", "d3dxdm.orig", "nvapi64.orig"] arraydll := ["d3d11.dll", "d3dcompiler_47.dll", "d3dx.ini", "d3dxdm.ini", "nvapi64.dll"] -BeforeLaunch(arraygeo, arrayorig, arraydll) -sleep, 1000 -If (Helix != "") +BeforeLaunch(arraygeo, arrayorig, arraydll) +sleep, 1000 + +HelixLauncherBat := Gamepath "\" "vrapplauncher.bat" + +sleep, 1000 +Run %Gameexe%, A_ScriptDir +sleep, 15000 +if WinExist("ahk_exe" Gameexe) { -Run %Helix%,%Helixpath% -Sleep, 1000 + Run %HelixLauncherBat%, A_ScriptDir } -Run %Gameexe%, A_ScriptDir +else +{ + Sleep, 5000 + Run %HelixLauncherBat%, A_ScriptDir +} + +sleep, 4000 +WinActivate, ahk_exe %Gameexe% +sleep, 4000 +WinActivate, ahk_exe %Gameexe% +sleep, 4000 +WinActivate, ahk_exe %Gameexe% Loop, 10 { ; CHECK FOR GAME LAUNCH CORRECTLY 1 @@ -35,7 +51,7 @@ Loop, 10 } } if (Exister="1") -{ +{ Loop { if !WinExist("ahk_exe" Gameexe) @@ -49,14 +65,14 @@ if (Exister="1") Sleep, 1000 } } -else +else { OnMessage(0x44, "OnMsgBox") MsgBox 0x84, %Gameexe% never launched, Should the VR launcher continue to wait for %Gameexe%? (App can be closed in system tray) OnMessage(0x44, "") IfMsgBox Yes, { - Sleep, 20000 + Sleep, 100000 WinWaitClose, ahk_exe Gameexe AfterLaunch(arraygeo, arrayorig, arraydll) exitapp diff --git a/leaveingamedir.exe b/leaveingamedir.exe index dc6344c..834b9cc 100644 Binary files a/leaveingamedir.exe and b/leaveingamedir.exe differ diff --git a/skins/tf.ahk b/skins/tf.ahk new file mode 100644 index 0000000..c3df7f3 --- /dev/null +++ b/skins/tf.ahk @@ -0,0 +1,1537 @@ +/* +Name : TF: Textfile & String Library for AutoHotkey +Version : 3.8 +Documentation : https://github.com/hi5/TF +AutoHotkey.com: https://www.autohotkey.com/boards/viewtopic.php?f=6&t=576 +AutoHotkey.com: http://www.autohotkey.com/forum/topic46195.html (Also for examples) +License : see license.txt (GPL 2.0) + +Credits & History: See documentation at GH above. + +Structure of most functions: + +TF_...(Text, other parameters) + { + ; get the basic data we need for further processing and returning the output: + TF_GetData(OW, Text, FileName) + ; OW = 0 Copy inputfile + ; OW = 1 Overwrite inputfile + ; OW = 2 Return variable + ; Text : either contents of file or the var that was passed on + ; FileName : Used in case OW is 0 or 1 (=file), not used for OW=2 (variable) + + ; Creates a matchlist for use in Loop below + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; A_ThisFunc useful for debugging your scripts + + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + { + ... + } + Else + { + ... + } + } + ; either copy or overwrite file or return variable + Return TF_ReturnOutPut(OW, OutPut, FileName, TrimTrailing, CreateNewFile) + ; OW 0 or 1 = file + ; Output = new content of file to save or variable to return + ; FileName + ; TrimTrailing: because of the loops used most functions will add trailing newline, this will remove it by default + ; CreateNewFile: To create a file that doesn't exist this parameter is needed, only used in few functions + } + +*/ + +TF_CountLines(Text) +{ + TF_GetData(OW, Text, FileName) + StringReplace, Text, Text, `n, `n, UseErrorLevel + Return ErrorLevel + 1 +} + +TF_ReadLines(Text, StartLine = 1, EndLine = 0, Trailing = 0) +{ + TF_GetData(OW, Text, FileName) + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + OutPut .= A_LoopField "`n" + Else if (A_Index => EndLine) + Break + } + OW = 2 ; make sure we return variable not process file + Return TF_ReturnOutPut(OW, OutPut, FileName, Trailing) +} + +TF_ReplaceInLines(Text, StartLine = 1, EndLine = 0, SearchText = "", ReplaceText = "") +{ + TF_GetData(OW, Text, FileName) + IfNotInString, Text, %SearchText% + Return Text ; SearchText not in TextFile so return and do nothing, we have to return Text in case of a variable otherwise it would empty the variable contents bug fix 3.3 + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + { + StringReplace, LoopField, A_LoopField, %SearchText%, %ReplaceText%, All + OutPut .= LoopField "`n" + } + Else + OutPut .= A_LoopField "`n" + } + Return TF_ReturnOutPut(OW, OutPut, FileName) +} + +TF_Replace(Text, SearchText, ReplaceText="") +{ + TF_GetData(OW, Text, FileName) + IfNotInString, Text, %SearchText% + Return Text ; SearchText not in TextFile so return and do nothing, we have to return Text in case of a variable otherwise it would empty the variable contents bug fix 3.3 + Loop + { + StringReplace, Text, Text, %SearchText%, %ReplaceText%, All + if (ErrorLevel = 0) ; No more replacements needed. + break + } + Return TF_ReturnOutPut(OW, Text, FileName, 0) +} + +TF_RegExReplaceInLines(Text, StartLine = 1, EndLine = 0, NeedleRegEx = "", Replacement = "") +{ + options:="^[imsxADJUXPS]+\)" ; Hat tip to sinkfaze http://www.autohotkey.com/forum/viewtopic.php?t=60062 + If RegExMatch(searchText,options,o) + searchText := RegExReplace(searchText,options,(!InStr(o,"m") ? "m$0" : "$0")) + Else searchText := "m)" . searchText + TF_GetData(OW, Text, FileName) + If (RegExMatch(Text, SearchText) < 1) + Return Text ; SearchText not in TextFile so return and do nothing, we have to return Text in case of a variable otherwise it would empty the variable contents bug fix 3.3 + + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + { + LoopField := RegExReplace(A_LoopField, NeedleRegEx, Replacement) + OutPut .= LoopField "`n" + } + Else + OutPut .= A_LoopField "`n" + } + Return TF_ReturnOutPut(OW, OutPut, FileName) +} + +TF_RegExReplace(Text, NeedleRegEx = "", Replacement = "") +{ + options:="^[imsxADJUXPS]+\)" ; Hat tip to sinkfaze http://www.autohotkey.com/forum/viewtopic.php?t=60062 + if RegExMatch(searchText,options,o) + searchText := RegExReplace(searchText,options,(!InStr(o,"m") ? "m$0" : "$0")) + else searchText := "m)" . searchText + TF_GetData(OW, Text, FileName) + If (RegExMatch(Text, SearchText) < 1) + Return Text ; SearchText not in TextFile so return and do nothing, we have to return Text in case of a variable otherwise it would empty the variable contents bug fix 3.3 + Text := RegExReplace(Text, NeedleRegEx, Replacement) + Return TF_ReturnOutPut(OW, Text, FileName, 0) +} + +TF_RemoveLines(Text, StartLine = 1, EndLine = 0) +{ + TF_GetData(OW, Text, FileName) + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + Continue + Else + OutPut .= A_LoopField "`n" + } + Return TF_ReturnOutPut(OW, OutPut, FileName) +} + +TF_RemoveBlankLines(Text, StartLine = 1, EndLine = 0) +{ + TF_GetData(OW, Text, FileName) + If (RegExMatch(Text, "[\S]+?\r?\n?") < 1) + Return Text ; No empty lines so return and do nothing, we have to return Text in case of a variable otherwise it would empty the variable contents bug fix 3.3 + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + OutPut .= (RegExMatch(A_LoopField,"[\S]+?\r?\n?")) ? A_LoopField "`n" : + Else + OutPut .= A_LoopField "`n" + } + Return TF_ReturnOutPut(OW, OutPut, FileName) + } + + TF_RemoveDuplicateLines(Text, StartLine = 1, Endline = 0, Consecutive = 0, CaseSensitive = false) + { + TF_GetData(OW, Text, FileName) + If (StartLine = "") + StartLine = 1 + If (Endline = 0 OR Endline = "") + EndLine := TF_Count(Text, "`n") + 1 + Loop, Parse, Text, `n, `r + { + If (A_Index < StartLine) + Section1 .= A_LoopField "`n" + If A_Index between %StartLine% and %Endline% + { + If (Consecutive = 1) + { + If (A_LoopField <> PreviousLine) ; method one for consecutive duplicate lines + Section2 .= A_LoopField "`n" + PreviousLine:=A_LoopField + } + Else + { + If !(InStr(SearchForSection2,"__bol__" . A_LoopField . "__eol__",CaseSensitive)) ; not found + { + SearchForSection2 .= "__bol__" A_LoopField "__eol__" ; this makes it unique otherwise it could be a partial match + Section2 .= A_LoopField "`n" + } + } + } + If (A_Index > EndLine) + Section3 .= A_LoopField "`n" + } + Output .= Section1 Section2 Section3 + Return TF_ReturnOutPut(OW, OutPut, FileName) + } + + TF_InsertLine(Text, StartLine = 1, Endline = 0, InsertText = "") + { + TF_GetData(OW, Text, FileName) + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + Output .= InsertText "`n" A_LoopField "`n" + Else + Output .= A_LoopField "`n" + } + Return TF_ReturnOutPut(OW, OutPut, FileName) + } + + TF_ReplaceLine(Text, StartLine = 1, Endline = 0, ReplaceText = "") + { + TF_GetData(OW, Text, FileName) + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + Output .= ReplaceText "`n" + Else + Output .= A_LoopField "`n" + } + Return TF_ReturnOutPut(OW, OutPut, FileName) + } + + TF_InsertPrefix(Text, StartLine = 1, EndLine = 0, InsertText = "") + { + TF_GetData(OW, Text, FileName) + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + OutPut .= InsertText A_LoopField "`n" + Else + OutPut .= A_LoopField "`n" + } + Return TF_ReturnOutPut(OW, OutPut, FileName) + } + + TF_InsertSuffix(Text, StartLine = 1, EndLine = 0 , InsertText = "") + { + TF_GetData(OW, Text, FileName) + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + OutPut .= A_LoopField InsertText "`n" + Else + OutPut .= A_LoopField "`n" + } + Return TF_ReturnOutPut(OW, OutPut, FileName) + } + + TF_TrimLeft(Text, StartLine = 1, EndLine = 0, Count = 1) + { + TF_GetData(OW, Text, FileName) + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + { + StringTrimLeft, StrOutPut, A_LoopField, %Count% + OutPut .= StrOutPut "`n" + } + Else + OutPut .= A_LoopField "`n" + } + Return TF_ReturnOutPut(OW, OutPut, FileName) + } + + TF_TrimRight(Text, StartLine = 1, EndLine = 0, Count = 1) + { + TF_GetData(OW, Text, FileName) + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + { + StringTrimRight, StrOutPut, A_LoopField, %Count% + OutPut .= StrOutPut "`n" + } + Else + OutPut .= A_LoopField "`n" + } + Return TF_ReturnOutPut(OW, OutPut, FileName) + } + + TF_AlignLeft(Text, StartLine = 1, EndLine = 0, Columns = 80, Padding = 0) + { + Trim:=A_AutoTrim ; store trim settings + AutoTrim, On ; make sure AutoTrim is on + TF_GetData(OW, Text, FileName) + If (Endline = 0 OR Endline = "") + EndLine := TF_Count(Text, "`n") + 1 + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + { + LoopField = %A_LoopField% ; Make use of AutoTrim, should be faster then a RegExReplace. Trims leading and trailing spaces! + SpaceNum := Columns-StrLen(LoopField)-1 + If (SpaceNum > 0) and (Padding = 1) ; requires padding + keep padding + { + Left:=TF_SetWidth(LoopField,Columns, 0) ; align left + OutPut .= Left "`n" + } + Else + OutPut .= LoopField "`n" + } + Else + OutPut .= A_LoopField "`n" + } + AutoTrim, %Trim% ; restore original Trim + Return TF_ReturnOutPut(OW, OutPut, FileName) + } + + TF_AlignCenter(Text, StartLine = 1, EndLine = 0, Columns = 80, Padding = 0) + { + Trim:=A_AutoTrim ; store trim settings + AutoTrim, On ; make sure AutoTrim is on + TF_GetData(OW, Text, FileName) + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + { + LoopField = %A_LoopField% ; Make use of AutoTrim, should be faster then a RegExReplace + SpaceNum := (Columns-StrLen(LoopField)-1)/2 + If (Padding = 1) and (LoopField = "") ; skip empty lines, do not fill with spaces + { + OutPut .= "`n" + Continue + } + If (StrLen(LoopField) >= Columns) + { + OutPut .= LoopField "`n" ; add as is + Continue + } + Centered:=TF_SetWidth(LoopField,Columns, 1) ; align center using set width + OutPut .= Centered "`n" + } + Else + OutPut .= A_LoopField "`n" + } + AutoTrim, %Trim% ; restore original Trim + Return TF_ReturnOutPut(OW, OutPut, FileName) + } + + TF_AlignRight(Text, StartLine = 1, EndLine = 0, Columns = 80, Skip = 0) + { + Trim:=A_AutoTrim ; store trim settings + AutoTrim, On ; make sure AutoTrim is on + TF_GetData(OW, Text, FileName) + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + { + LoopField = %A_LoopField% ; Make use of AutoTrim, should be faster then a RegExReplace + If (Skip = 1) and (LoopField = "") ; skip empty lines, do not fill with spaces + { + OutPut .= "`n" + Continue + } + If (StrLen(LoopField) >= Columns) + { + OutPut .= LoopField "`n" ; add as is + Continue + } + Right:=TF_SetWidth(LoopField,Columns, 2) ; align right using set width + OutPut .= Right "`n" + } + Else + OutPut .= A_LoopField "`n" + } + AutoTrim, %Trim% ; restore original Trim + Return TF_ReturnOutPut(OW, OutPut, FileName) + } + + ; Based on: CONCATenate text files, ftp://garbo.uwasa.fi/pc/ts/tsfltc22.zip + TF_ConCat(FirstTextFile, SecondTextFile, OutputFile = "", Blanks = 0, FirstPadMargin = 0, SecondPadMargin = 0) + { + If (Blanks > 0) + Loop, %Blanks% + InsertBlanks .= A_Space + If (FirstPadMargin > 0) + Loop, %FirstPadMargin% + PaddingFile1 .= A_Space + If (SecondPadMargin > 0) + Loop, %SecondPadMargin% + PaddingFile2 .= A_Space + Text:=FirstTextFile + TF_GetData(OW, Text, FileName) + StringSplit, Str1Lines, Text, `n, `r + Text:=SecondTextFile + TF_GetData(OW, Text, FileName) + StringSplit, Str2Lines, Text, `n, `r + Text= ; clear mem + + ; first we need to determine the file with the most lines for our loop + If (Str1Lines0 > Str2Lines0) + MaxLoop:=Str1Lines0 + Else + MaxLoop:=Str2Lines0 + Loop, %MaxLoop% + { + Section1:=Str1Lines%A_Index% + Section2:=Str2Lines%A_Index% + OutPut .= Section1 PaddingFile1 InsertBlanks Section2 PaddingFile2 "`n" + Section1= ; otherwise it will remember the last line from the shortest file or var + Section2= + } + OW=1 ; it is probably 0 so in that case it would create _copy, so set it to 1 + If (OutPutFile = "") ; if OutPutFile is empty return as variable + OW=2 + Return TF_ReturnOutPut(OW, OutPut, OutputFile, 1, 1) + } + + TF_LineNumber(Text, Leading = 0, Restart = 0, Char = 0) ; HT ribbet.1 + { + global t + TF_GetData(OW, Text, FileName) + Lines:=TF_Count(Text, "`n") + 1 + Padding:=StrLen(Lines) + If (Leading = 0) and (Char = 0) + Char := A_Space + Loop, %Padding% + PadLines .= Char + Loop, Parse, Text, `n, `r + { + If Restart = 0 + MaxNo = %A_Index% + Else + { + MaxNo++ + If MaxNo > %Restart% + MaxNo = 1 + } + LineNumber:= MaxNo + If (Leading = 1) + { + LineNumber := Padlines LineNumber ; add padding + StringRight, LineNumber, LineNumber, StrLen(Lines) ; remove excess padding + } + If (Leading = 0) + { + LineNumber := LineNumber Padlines ; add padding + StringLeft, LineNumber, LineNumber, StrLen(Lines) ; remove excess padding + } + OutPut .= LineNumber A_Space A_LoopField "`n" + } + Return TF_ReturnOutPut(OW, OutPut, FileName) + } + + ; skip = 1, skip shorter lines (e.g. lines shorter startcolumn position) + ; modified in TF 3.4, fixed in 3.5 + TF_ColGet(Text, StartLine = 1, EndLine = 0, StartColumn = 1, EndColumn = 1, Skip = 0) + { + TF_GetData(OW, Text, FileName) + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + If (StartColumn < 0) + { + StartColumn++ + Loop, Parse, Text, `n, `r ; parsing file/var + { + If A_Index in %TF_MatchList% + { + output .= SubStr(A_LoopField,StartColumn) "`n" + } + else + output .= A_LoopField "`n" + } + Return TF_ReturnOutPut(OW, OutPut, FileName) + } + if RegExMatch(StartColumn, ",|\+|-") + { + StartColumn:=_MakeMatchList(Text, StartColumn, 1, 1) + Loop, Parse, Text, `n, `r ; parsing file/var + { + If A_Index in %TF_MatchList% + { + loop, parse, A_LoopField ; parsing LINE char by char + { + If A_Index in %StartColumn% ; if col in index get char + output .= A_LoopField + } + output .= "`n" + } + else + output .= A_LoopField "`n" + } + output .= A_LoopField "`n" + } + else + { + EndColumn:=(EndColumn+1)-StartColumn + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + { + StringMid, Section, A_LoopField, StartColumn, EndColumn + If (Skip = 1) and (StrLen(A_LoopField) < StartColumn) + Continue + OutPut .= Section "`n" + } + } + } + Return TF_ReturnOutPut(OW, OutPut, FileName) +} + +; Based on: COLPUT.EXE & CUT.EXE, ftp://garbo.uwasa.fi/pc/ts/tsfltc22.zip +; modified in TF 3.4 +TF_ColPut(Text, Startline = 1, EndLine = 0, StartColumn = 1, InsertText = "", Skip = 0) +{ + TF_GetData(OW, Text, FileName) + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + If RegExMatch(StartColumn, ",|\+") + { + StartColumn:=_MakeMatchList(Text, StartColumn, 0, 1) + Loop, Parse, Text, `n, `r ; parsing file/var + { + If A_Index in %TF_MatchList% + { + loop, parse, A_LoopField ; parsing LINE char by char + { + If A_Index in %StartColumn% ; if col in index insert text + output .= InsertText A_LoopField + Else + output .= A_LoopField + } + output .= "`n" + } + else + output .= A_LoopField "`n" + } + output .= A_LoopField "`n" + } + else + { + StartColumn-- + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + { + If (StartColumn > 0) + { + StringLeft, Section1, A_LoopField, StartColumn + StringMid, Section2, A_LoopField, StartColumn+1 + If (Skip = 1) and (StrLen(A_LoopField) < StartColumn) + OutPut .= Section1 Section2 "`n" + } + Else + { + Section1:=SubStr(A_LoopField, 1, StrLen(A_LoopField) + StartColumn + 1) + Section2:=SubStr(A_LoopField, StrLen(A_LoopField) + StartColumn + 2) + If (Skip = 1) and (A_LoopField = "") + OutPut .= Section1 Section2 "`n" + } + OutPut .= Section1 InsertText Section2 "`n" + } + Else + OutPut .= A_LoopField "`n" + } + } + Return TF_ReturnOutPut(OW, OutPut, FileName) +} + +; modified TF 3.4 +TF_ColCut(Text, StartLine = 1, EndLine = 0, StartColumn = 1, EndColumn = 1) +{ + TF_GetData(OW, Text, FileName) + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + If RegExMatch(StartColumn, ",|\+|-") + { + StartColumn:=_MakeMatchList(Text, StartColumn, EndColumn, 1) + Loop, Parse, Text, `n, `r ; parsing file/var + { + If A_Index in %TF_MatchList% + { + loop, parse, A_LoopField ; parsing LINE char by char + { + If A_Index not in %StartColumn% ; if col not in index get char + output .= A_LoopField + } + output .= "`n" + } + else + output .= A_LoopField "`n" + } + output .= A_LoopField "`n" + } + else + { + StartColumn-- + EndColumn++ + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + { + StringLeft, Section1, A_LoopField, StartColumn + StringMid, Section2, A_LoopField, EndColumn + OutPut .= Section1 Section2 "`n" + } + Else + OutPut .= A_LoopField "`n" + } + } + Return TF_ReturnOutPut(OW, OutPut, FileName) +} + +TF_ReverseLines(Text, StartLine = 1, EndLine = 0) +{ + TF_GetData(OW, Text, FileName) + StringSplit, Line, Text, `n, `r ; line0 is number of lines + If (EndLine = 0 OR EndLine = "") + EndLine:=Line0 + If (EndLine > Line0) + EndLine:=Line0 + CountDown:=EndLine+1 + Loop, Parse, Text, `n, `r + { + If (A_Index < StartLine) + Output1 .= A_LoopField "`n" ; section1 + If A_Index between %StartLine% and %Endline% + { + CountDown-- + Output2 .= Line%CountDown% "`n" section2 + } + If (A_Index > EndLine) + Output3 .= A_LoopField "`n" + } + OutPut.= Output1 Output2 Output3 + Return TF_ReturnOutPut(OW, OutPut, FileName) +} + +;TF_SplitFileByLines +;example: +;TF_SplitFileByLines("TestFile.txt", "4", "sfile_", "txt", "1") ; split file every 3 lines +; InFile = 0 skip line e.g. do not include the actual line in any of the output files +; InFile = 1 include line IN current file +; InFile = 2 include line IN next file +TF_SplitFileByLines(Text, SplitAt, Prefix = "file", Extension = "txt", InFile = 1) +{ + LineCounter=1 + FileCounter=1 + Where:=SplitAt + Method=1 + ; 1 = default, splitat every X lines, + ; 2 = splitat: - rotating if applicable + ; 3 = splitat: specific lines comma separated + TF_GetData(OW, Text, FileName) + + IfInString, SplitAt, `- ; method 2 + { + StringSplit, Split, SplitAt, `- + Part=1 + Where:=Split%Part% + Method=2 + } + IfInString, SplitAt, `, ; method 3 + { + StringSplit, Split, SplitAt, `, + Part=1 + Where:=Split%Part% + Method=3 + } + Loop, Parse, Text, `n, `r + { + OutPut .= A_LoopField "`n" + If (LineCounter = Where) + { + If (InFile = 0) + { + StringReplace, CheckOutput, PreviousOutput, `n, , All + StringReplace, CheckOutput, CheckOutput, `r, , All + If (CheckOutput <> "") and (OW <> 2) ; skip empty files + TF_ReturnOutPut(1, PreviousOutput, Prefix FileCounter "." Extension, 0, 1) + If (CheckOutput <> "") and (OW = 2) ; skip empty files + TF_SetGlobal(Prefix FileCounter,PreviousOutput) + Output:= + } + If (InFile = 1) + { + StringReplace, CheckOutput, Output, `n, , All + StringReplace, CheckOutput, CheckOutput, `r, , All + If (CheckOutput <> "") and (OW <> 2) ; skip empty files + TF_ReturnOutPut(1, Output, Prefix FileCounter "." Extension, 0, 1) + If (CheckOutput <> "") and (OW = 2) ; skip empty files + TF_SetGlobal(Prefix FileCounter,Output) + Output:= + } + If (InFile = 2) + { + OutPut := PreviousOutput + StringReplace, CheckOutput, Output, `n, , All + StringReplace, CheckOutput, CheckOutput, `r, , All + If (CheckOutput <> "") and (OW <> 2) ; skip empty files + TF_ReturnOutPut(1, Output, Prefix FileCounter "." Extension, 0, 1) + If (CheckOutput <> "") and (OW = 2) ; output to array + TF_SetGlobal(Prefix FileCounter,Output) + OutPut := A_LoopField "`n" + } + If (Method <> 3) + LineCounter=0 ; reset + FileCounter++ ; next file + Part++ + If (Method = 2) ; 2 = splitat: - rotating if applicable + { + If (Part > Split0) + { + Part=1 + } + Where:=Split%Part% + } + If (Method = 3) ; 3 = splitat: specific lines comma separated + { + If (Part > Split0) + Where:=Split%Split0% + Else + Where:=Split%Part% + } + } + LineCounter++ + PreviousOutput:=Output + PreviousLine:=A_LoopField + } + StringReplace, CheckOutput, Output, `n, , All + StringReplace, CheckOutput, CheckOutput, `r, , All + If (CheckOutPut <> "") and (OW <> 2) ; skip empty files + TF_ReturnOutPut(1, Output, Prefix FileCounter "." Extension, 0, 1) + If (CheckOutput <> "") and (OW = 2) ; output to array + { + TF_SetGlobal(Prefix FileCounter,Output) + TF_SetGlobal(Prefix . "0" , FileCounter) + } +} + +; TF_SplitFileByText("TestFile.txt", "button", "sfile_", "txt") ; split file at every line with button in it, can be regexp +; InFile = 0 skip line e.g. do not include the actual line in any of the output files +; InFile = 1 include line IN current file +; InFile = 2 include line IN next file +TF_SplitFileByText(Text, SplitAt, Prefix = "file", Extension = "txt", InFile = 1) +{ + LineCounter=1 + FileCounter=1 + TF_GetData(OW, Text, FileName) + SplitPath, TextFile,, Dir + Loop, Parse, Text, `n, `r + { + OutPut .= A_LoopField "`n" + FoundPos:=RegExMatch(A_LoopField, SplitAt) + If (FoundPos > 0) + { + If (InFile = 0) + { + StringReplace, CheckOutput, PreviousOutput, `n, , All + StringReplace, CheckOutput, CheckOutput, `r, , All + If (CheckOutput <> "") and (OW <> 2) ; skip empty files + TF_ReturnOutPut(1, PreviousOutput, Prefix FileCounter "." Extension, 0, 1) + If (CheckOutput <> "") and (OW = 2) ; output to array + TF_SetGlobal(Prefix FileCounter,PreviousOutput) + Output:= + } + If (InFile = 1) + { + StringReplace, CheckOutput, Output, `n, , All + StringReplace, CheckOutput, CheckOutput, `r, , All + If (CheckOutput <> "") and (OW <> 2) ; skip empty files + TF_ReturnOutPut(1, Output, Prefix FileCounter "." Extension, 0, 1) + If (CheckOutput <> "") and (OW = 2) ; output to array + TF_SetGlobal(Prefix FileCounter,Output) + Output:= + } + If (InFile = 2) + { + OutPut := PreviousOutput + StringReplace, CheckOutput, Output, `n, , All + StringReplace, CheckOutput, CheckOutput, `r, , All + If (CheckOutput <> "") and (OW <> 2) ; skip empty files + TF_ReturnOutPut(1, Output, Prefix FileCounter "." Extension, 0, 1) + If (CheckOutput <> "") and (OW = 2) ; output to array + TF_SetGlobal(Prefix FileCounter,Output) + OutPut := A_LoopField "`n" + } + LineCounter=0 ; reset + FileCounter++ ; next file + } + LineCounter++ + PreviousOutput:=Output + PreviousLine:=A_LoopField + } + StringReplace, CheckOutput, Output, `n, , All + StringReplace, CheckOutput, CheckOutput, `r, , All + If (CheckOutPut <> "") and (OW <> 2) ; skip empty files + TF_ReturnOutPut(1, Output, Prefix FileCounter "." Extension, 0, 1) + If (CheckOutput <> "") and (OW = 2) ; output to array + { + TF_SetGlobal(Prefix FileCounter,Output) + TF_SetGlobal(Prefix . "0" , FileCounter) + } +} + +TF_Find(Text, StartLine = 1, EndLine = 0, SearchText = "", ReturnFirst = 1, ReturnText = 0) +{ + options:="^[imsxADJUXPS]+\)" + if RegExMatch(searchText,options,o) + searchText:=RegExReplace(searchText,options,(!InStr(o,"m") ? "m$0(*ANYCRLF)" : "$0")) + else searchText:="m)(*ANYCRLF)" searchText + options:="^[imsxADJUXPS]+\)" ; Hat tip to sinkfaze, see http://www.autohotkey.com/forum/viewtopic.php?t=60062 + if RegExMatch(searchText,options,o) + searchText := RegExReplace(searchText,options,(!InStr(o,"m") ? "m$0" : "$0")) + else searchText := "m)" . searchText + + TF_GetData(OW, Text, FileName) + If (RegExMatch(Text, SearchText) < 1) + Return "0" ; SearchText not in file or error, so do nothing + + TF_GetData(OW, Text, FileName) + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + { + If (RegExMatch(A_LoopField, SearchText) > 0) + { + If (ReturnText = 0) + Lines .= A_Index "," ; line number + Else If (ReturnText = 1) + Lines .= A_LoopField "`n" ; text of line + Else If (ReturnText = 2) + Lines .= A_Index ": " A_LoopField "`n" ; add line number + If (ReturnFirst = 1) ; only return first occurrence + Break + } + } + } + If (Lines <> "") + StringTrimRight, Lines, Lines, 1 ; trim trailing , or `n + Else + Lines = 0 ; make sure we return 0 + Return Lines +} + +TF_Prepend(File1, File2) +{ + FileList= + ( + %File1% + %File2% + ) + TF_Merge(FileList,"`n", "!" . File2) + Return +} + +TF_Append(File1, File2) +{ + FileList= + ( + %File2% + %File1% + ) + TF_Merge(FileList,"`n", "!" . File2) + Return +} + +; For TF_Merge You will need to create a Filelist variable, one file per line, +; to pass on to the function: +; FileList= +; ( +; c:\file1.txt +; c:\file2.txt +; ) +; use Loop (files & folders) to create one quickly if you want to merge all TXT files for example +; +; Loop, c:\*.txt +; FileList .= A_LoopFileFullPath "`n" +; +; By default, a new line is used as a separator between two text files +; !merged.txt deletes target file before starting to merge files +TF_Merge(FileList, Separator = "`n", FileName = "merged.txt") +{ + OW=0 + Loop, Parse, FileList, `n, `r + { + Append2File= ; Just make sure it is empty + IfExist, %A_LoopField% + { + FileRead, Append2File, %A_LoopField% + If not ErrorLevel ; Successfully loaded + Output .= Append2File Separator + } + } + + If (SubStr(FileName,1,1)="!") ; check if we want to delete the target file before we start + { + FileName:=SubStr(FileName,2) + OW=1 + } + Return TF_ReturnOutPut(OW, OutPut, FileName, 0, 1) +} + +TF_Wrap(Text, Columns = 80, AllowBreak = 0, StartLine = 1, EndLine = 0) +{ + TF_GetData(OW, Text, FileName) + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + If (AllowBreak = 1) + Break= + Else + Break=[ \r?\n] + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + { + If (StrLen(A_LoopField) > Columns) + { + LoopField := A_LoopField " " ; just seems to work better by adding a space + OutPut .= RegExReplace(LoopField, "(.{1," . Columns . "})" . Break , "$1`n") + } + Else + OutPut .= A_LoopField "`n" + } + Else + OutPut .= A_LoopField "`n" + } + Return TF_ReturnOutPut(OW, OutPut, FileName) +} + +TF_WhiteSpace(Text, RemoveLeading = 1, RemoveTrailing = 1, StartLine = 1, EndLine = 0) { + TF_GetData(OW, Text, FileName) + TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) ; create MatchList + Trim:=A_AutoTrim ; store trim settings + AutoTrim, On ; make sure AutoTrim is on + Loop, Parse, Text, `n, `r + { + If A_Index in %TF_MatchList% + { + If (RemoveLeading = 1) AND (RemoveTrailing = 1) + { + LoopField = %A_LoopField% + Output .= LoopField "`n" + Continue + } + If (RemoveLeading = 1) AND (RemoveTrailing = 0) + { + LoopField := A_LoopField . "." + LoopField = %LoopField% + StringTrimRight, LoopField, LoopField, 1 + Output .= LoopField "`n" + Continue + } + If (RemoveLeading = 0) AND (RemoveTrailing = 1) + { + LoopField := "." A_LoopField + LoopField = %LoopField% + StringTrimLeft, LoopField, LoopField, 1 + Output .= LoopField "`n" + Continue + } + If (RemoveLeading = 0) AND (RemoveTrailing = 0) + { + Output .= A_LoopField "`n" + Continue + } + } + Else + Output .= A_LoopField "`n" + } + AutoTrim, %Trim% ; restore original Trim + Return TF_ReturnOutPut(OW, OutPut, FileName) +} + +; Delete lines from file1 in file2 (using StringReplace) +; Partialmatch = 2 added in 3.4 +TF_Substract(File1, File2, PartialMatch = 0) { + Text:=File1 + TF_GetData(OW, Text, FileName) + Str1:=Text + Text:=File2 + TF_GetData(OW, Text, FileName) + OutPut:=Text + If (OW = 2) + File1= ; free mem in case of var/text + OutPut .= "`n" ; just to make sure the StringReplace will work + + If (PartialMatch = 2) + { + Loop, Parse, Str1, `n, `r + { + IfInString, Output, %A_LoopField% + { + Output:= RegExReplace(Output, "im)^.*" . A_LoopField . ".*\r?\n?", replace) + } + } + } + Else If (PartialMatch = 1) ; allow paRTIal match + { + Loop, Parse, Str1, `n, `r + StringReplace, Output, Output, %A_LoopField%, , All ; remove lines from file1 in file2 + } + Else If (PartialMatch = 0) + { + search:="m)^(.*)$" + replace=__bol__$1__eol__ + Output:=RegExReplace(Output, search, replace) + StringReplace, Output, Output, `n__eol__,__eol__ , All ; strange fix but seems to be needed. + Loop, Parse, Str1, `n, `r + StringReplace, Output, Output, __bol__%A_LoopField%__eol__, , All ; remove lines from file1 in file2 + } + If (PartialMatch = 0) + { + StringReplace, Output, Output, __bol__, , All + StringReplace, Output, Output, __eol__, , All + } + + ; Remove all blank lines from the text in a variable: + Loop + { + StringReplace, Output, Output, `r`n`r`n, `r`n, UseErrorLevel + if (ErrorLevel = 0) or (ErrorLevel = 1) ; No more replacements needed. + break + } + Return TF_ReturnOutPut(OW, OutPut, FileName, 0) +} + +; Similar to "BK Replace EM" RangeReplace +TF_RangeReplace(Text, SearchTextBegin, SearchTextEnd, ReplaceText = "", CaseSensitive = "False", KeepBegin = 0, KeepEnd = 0) +{ + TF_GetData(OW, Text, FileName) + IfNotInString, Text, %SearchText% + Return Text ; SearchTextBegin not in TextFile so return and do nothing, we have to return Text in case of a variable otherwise it would empty the variable contents bug fix 3.3 + Start = 0 + End = 0 + If (KeepBegin = 1) + KeepBegin:=SearchTextBegin + Else + KeepBegin= + If (KeepEnd = 1) + KeepEnd:= SearchTextEnd + Else + KeepEnd= + If (SearchTextBegin = "") + Start=1 + If (SearchTextEnd = "") + End=2 + + Loop, Parse, Text, `n, `r + { + If (End = 1) ; end has been found already, replacement made simply continue to add all lines + { + Output .= A_LoopField "`n" + Continue + } + If (Start = 0) ; start hasn't been found + { + If (InStr(A_LoopField,SearchTextBegin,CaseSensitive)) ; start has been found + { + Start = 1 + KeepSection := SubStr(A_LoopField, 1, InStr(A_LoopField, SearchTextBegin)-1) + EndSection := SubStr(A_LoopField, InStr(A_LoopField, SearchTextBegin)-1) + ; check if SearchEndText is in second part of line + If (InStr(EndSection,SearchTextEnd,CaseSensitive)) ; end found + { + EndSection := ReplaceText KeepEnd SubStr(EndSection, InStr(EndSection, SearchTextEnd) + StrLen(SearchTextEnd) ) "`n" + If (End <> 2) + End=1 + If (End = 2) + EndSection= + } + Else + EndSection= + Output .= KeepSection KeepBegin EndSection + Continue + } + Else + Output .= A_LoopField "`n" ; if not found yet simply add + } + If (Start = 1) and (End <> 2) ; start has been found, now look for end if end isn't an empty string + { + If (InStr(A_LoopField,SearchTextEnd,CaseSensitive)) ; end found + { + End = 1 + Output .= ReplaceText KeepEnd SubStr(A_LoopField, InStr(A_LoopField, SearchTextEnd) + StrLen(SearchTextEnd) ) "`n" + } + } + } + If (End = 2) + Output .= ReplaceText + Return TF_ReturnOutPut(OW, OutPut, FileName) +} + +; Create file of X lines and Y columns, fill with space or other character(s) +TF_MakeFile(Text, Lines = 1, Columns = 1, Fill = " ") +{ + OW=1 + If (Text = "") ; if OutPutFile is empty return as variable + OW=2 + Loop, % Columns + Cols .= Fill + Loop, % Lines + Output .= Cols "`n" + Return TF_ReturnOutPut(OW, OutPut, Text, 1, 1) +} + +; Convert tabs to spaces, shorthand for TF_ReplaceInLines +TF_Tab2Spaces(Text, TabStop = 4, StartLine = 1, EndLine =0) +{ + Loop, % TabStop + Replace .= A_Space + Return TF_ReplaceInLines(Text, StartLine, EndLine, A_Tab, Replace) +} + +; Convert spaces to tabs, shorthand for TF_ReplaceInLines +TF_Spaces2Tab(Text, TabStop = 4, StartLine = 1, EndLine =0) +{ + Loop, % TabStop + Replace .= A_Space + Return TF_ReplaceInLines(Text, StartLine, EndLine, Replace, A_Tab) +} + +; Sort (section of) a text file +TF_Sort(Text, SortOptions = "", StartLine = 1, EndLine = 0) ; use the SORT options http://www.autohotkey.com/docs/commands/Sort.htm +{ + TF_GetData(OW, Text, FileName) + If StartLine contains -,+,`, ; no sections, incremental or multiple line input + Return + If (StartLine = 1) and (Endline = 0) ; process entire file + { + Output:=Text + Sort, Output, %SortOptions% + } + Else + { + Output := TF_ReadLines(Text, 1, StartLine-1) ; get first section + ToSort := TF_ReadLines(Text, StartLine, EndLine) ; get section to sort + Sort, ToSort, %SortOptions% + OutPut .= ToSort + OutPut .= TF_ReadLines(Text, EndLine+1) ; append last section + } + Return TF_ReturnOutPut(OW, OutPut, FileName, 0) ; https://github.com/hi5/TF/issues/11 +} + +TF_Tail(Text, Lines = 1, RemoveTrailing = 0, ReturnEmpty = 1) +{ + TF_GetData(OW, Text, FileName) + Neg = 0 + If (Lines < 0) + { + Neg=1 + Lines:= Lines * -1 + } + If (ReturnEmpty = 0) ; remove blank lines first so we can't return any blank lines anyway + { + Loop, Parse, Text, `n, `r + OutPut .= (RegExMatch(A_LoopField,"[\S]+?\r?\n?")) ? A_LoopField "`n" : + StringTrimRight, OutPut, OutPut, 1 ; remove trailing `n added by loop above + Text:=OutPut + OutPut= + } + If (Neg = 1) ; get only one line! + { + Lines++ + Output:=Text + StringGetPos, Pos, Output, `n, R%Lines% ; These next two Lines by Tuncay see + StringTrimLeft, Output, Output, % ++Pos ; http://www.autoHotkey.com/forum/viewtopic.php?p=262375#262375 + StringGetPos, Pos, Output, `n + StringLeft, Output, Output, % Pos + Output .= "`n" + } + Else + { + Output:=Text + StringGetPos, Pos, Output, `n, R%Lines% ; These next two Lines by Tuncay see + StringTrimLeft, Output, Output, % ++Pos ; http://www.autoHotkey.com/forum/viewtopic.php?p=262375#262375 + Output .= "`n" + } + OW = 2 ; make sure we return variable not process file + Return TF_ReturnOutPut(OW, OutPut, FileName, RemoveTrailing) +} + +TF_Count(String, Char) +{ + StringReplace, String, String, %Char%,, UseErrorLevel + Return ErrorLevel +} + +TF_Save(Text, FileName, OverWrite = 1) { ; HugoV write file + Return TF_ReturnOutPut(OverWrite, Text, FileName, 0, 1) +} + +TF(TextFile, CreateGlobalVar = "T") { ; read contents of file in output and %output% as global var ... http://www.autohotkey.com/forum/viewtopic.php?p=313120#313120 + global + FileRead, %CreateGlobalVar%, %TextFile% + Return, (%CreateGlobalVar%) +} + +; TF_Join +; SmartJoin: Detect if CHAR(s) is/are already present at the end of the line before joining the next, this to prevent unnecessary double spaces for example. +; Char: character(s) to use between new lines, defaults to a space. To use nothing use "" +TF_Join(Text, StartLine = 1, EndLine = 0, SmartJoin = 0, Char = 0) +{ + If ( (InStr(StartLine,",") > 0) AND (InStr(StartLine,"-") = 0) ) OR (InStr(StartLine,"+") > 0) + Return Text ; can't do multiplelines, only multiple sections of lines e.g. "1,5" bad "1-5,15-10" good, "2+2" also bad +TF_GetData(OW, Text, FileName) +If (InStr(Text,"`n") = 0) + Return Text ; there are no lines to join so just return Text +If (InStr(StartLine,"-") > 0) ; OK, we need some counter-intuitive string mashing to substract ONE from the "endline" parameter +{ + Loop, Parse, StartLine, CSV + { + StringSplit, part, A_LoopField, - + NewStartLine .= part1 "-" (part2-1) "," + } + StringTrimRight, StartLine, NewStartLine, 1 +} +If (Endline > 0) + Endline-- +TF_MatchList:=_MakeMatchList(Text, StartLine, EndLine, 0, A_ThisFunc) +If (Char = 0) + Char:=A_Space +Char_Org:=Char +GetRightLen:=StrLen(Char)-1 +Loop, Parse, Text, `n, `r +{ + If A_Index in %TF_MatchList% + { + If (SmartJoin = 1) + { + GetRightText:=SubStr(A_LoopField,0) + If (GetRightText = Char) + Char= + } + Output .= A_LoopField Char + Char:=Char_Org + } + Else + Output .= A_LoopField "`n" +} +Return TF_ReturnOutPut(OW, OutPut, FileName) +} + +;----- Helper functions ---------------- + +TF_SetGlobal(var, content = "") ; helper function for TF_Split* to return array and not files, credits Tuncay :-) +{ + global + %var% := content +} + +; Helper function to determine if VAR/TEXT or FILE is passed to TF +; Update 11 January 2010 (skip filecheck if `n in Text -> can't be file) +TF_GetData(byref OW, byref Text, byref FileName) +{ + If (text = 0 "") ; v3.6 -> v3.7 https://github.com/hi5/TF/issues/4 and https://autohotkey.com/boards/viewtopic.php?p=142166#p142166 in case user passes on zero/zeros ("0000") as text - will error out when passing on one 0 and there is no file with that name + { + IfNotExist, %Text% ; additional check to see if a file 0 exists + { + MsgBox, 48, TF Lib Error, % "Read Error - possible reasons (see documentation):`n- Perhaps you used !""file.txt"" vs ""!file.txt""`n- A single zero (0) was passed on to a TF function as text" + ExitApp + } + } + OW=0 ; default setting: asume it is a file and create file_copy + IfNotInString, Text, `n ; it can be a file as the Text doesn't contact a newline character + { + If (SubStr(Text,1,1)="!") ; first we check for "overwrite" + { + Text:=SubStr(Text,2) + OW=1 ; overwrite file (if it is a file) + } + IfNotExist, %Text% ; now we can check if the file exists, it doesn't so it is a var + { + If (OW=1) ; the variable started with a ! so we need to put it back because it is variable/text not a file + Text:= "!" . Text + OW=2 ; no file, so it is a var or Text passed on directly to TF + } + } + Else ; there is a newline character in Text so it has to be a variable + { + OW=2 + } + If (OW = 0) or (OW = 1) ; it is a file, so we have to read into var Text + { + Text := (SubStr(Text,1,1)="!") ? (SubStr(Text,2)) : Text + FileName=%Text% ; Store FileName + FileRead, Text, %Text% ; Read file and return as var Text + If (ErrorLevel > 0) + { + MsgBox, 48, TF Lib Error, % "Can not read " FileName + ExitApp + } + } + Return +} + +; Skan - http://www.autohotkey.com/forum/viewtopic.php?p=45880#45880 +; SetWidth() : SetWidth increases a String's length by adding spaces to it and aligns it Left/Center/Right. ( Requires Space() ) +TF_SetWidth(Text,Width,AlignText) +{ + If (AlignText!=0 and AlignText!=1 and AlignText!=2) + AlignText=0 + If AlignText=0 + { + RetStr= % (Text)TF_Space(Width) + StringLeft, RetText, RetText, %Width% + } + If AlignText=1 + { + Spaces:=(Width-(StrLen(Text))) + RetStr= % TF_Space(Round(Spaces/2))(Text)TF_Space(Spaces-(Round(Spaces/2))) + } + If AlignText=2 + { + RetStr= % TF_Space(Width)(Text) + StringRight, RetStr, RetStr, %Width% + } + Return RetStr +} + +; Skan - http://www.autohotkey.com/forum/viewtopic.php?p=45880#45880 +TF_Space(Width) +{ + Loop,%Width% + Space=% Space Chr(32) + Return Space +} + +; Write to file or return variable depending on input +TF_ReturnOutPut(OW, Text, FileName, TrimTrailing = 1, CreateNewFile = 0) { + If (OW = 0) ; input was file, file_copy will be created, if it already exist file_copy will be overwritten + { + IfNotExist, % FileName ; check if file Exist, if not return otherwise it would create an empty file. Thanks for the idea Murp|e + { + If (CreateNewFile = 1) ; CreateNewFile used for TF_SplitFileBy* and others + { + OW = 1 + Goto CreateNewFile + } + Else + Return + } + If (TrimTrailing = 1) + StringTrimRight, Text, Text, 1 ; remove trailing `n + SplitPath, FileName,, Dir, Ext, Name + If (Dir = "") ; if Dir is empty Text & script are in same directory + Dir := A_WorkingDir + IfExist, % Dir "\backup" ; if there is a backup dir, copy original file there + FileCopy, % Dir "\" Name "_copy." Ext, % Dir "\backup\" Name "_copy.bak", 1 + FileDelete, % Dir "\" Name "_copy." Ext + FileAppend, %Text%, % Dir "\" Name "_copy." Ext + Return Errorlevel ? False : True +} +CreateNewFile: + If (OW = 1) ; input was file, will be overwritten by output + { + IfNotExist, % FileName ; check if file Exist, if not return otherwise it would create an empty file. Thanks for the idea Murp|e + { + If (CreateNewFile = 0) ; CreateNewFile used for TF_SplitFileBy* and others + Return + } + If (TrimTrailing = 1) + StringTrimRight, Text, Text, 1 ; remove trailing `n + SplitPath, FileName,, Dir, Ext, Name + If (Dir = "") ; if Dir is empty Text & script are in same directory + Dir := A_WorkingDir + IfExist, % Dir "\backup" ; if there is a backup dir, copy original file there + FileCopy, % Dir "\" Name "." Ext, % Dir "\backup\" Name ".bak", 1 + FileDelete, % Dir "\" Name "." Ext + FileAppend, %Text%, % Dir "\" Name "." Ext + Return Errorlevel ? False : True + } + If (OW = 2) ; input was var, return variable + { + If (TrimTrailing = 1) + StringTrimRight, Text, Text, 1 ; remove trailing `n + Return Text + } +} + +; _MakeMatchList() +; Purpose: +; Make a MatchList which is used in various functions +; Using a MatchList gives greater flexibility so you can process multiple +; sections of lines in one go avoiding repetitive fileread/append actions +; For TF 3.4 added COL = 0/1 option (for TF_Col* functions) and CallFunc for +; all TF_* functions to facilitate bug tracking +_MakeMatchList(Text, Start = 1, End = 0, Col = 0, CallFunc = "Not available") +{ + ErrorList= + (join| + Error 01: Invalid StartLine parameter (non numerical character)`nFunction used: %CallFunc% + Error 02: Invalid EndLine parameter (non numerical character)`nFunction used: %CallFunc% + Error 03: Invalid StartLine parameter (only one + allowed)`nFunction used: %CallFunc% + ) + StringSplit, ErrorMessage, ErrorList, | + Error = 0 + + If (Col = 1) + { + LongestLine:=TF_Stat(Text) + If (End > LongestLine) or (End = 1) ; FIXITHERE BUG + End:=LongestLine + } + + TF_MatchList= ; just to be sure + If (Start = 0 or Start = "") + Start = 1 + + ; some basic error checking + + ; error: only digits - and + allowed + If (RegExReplace(Start, "[ 0-9+\-\,]", "") <> "") + Error = 1 + + If (RegExReplace(End, "[0-9 ]", "") <> "") + Error = 2 + + ; error: only one + allowed + If (TF_Count(Start,"+") > 1) + Error = 3 + + If (Error > 0 ) + { + MsgBox, 48, TF Lib Error, % ErrorMessage%Error% + ExitApp + } + + ; Option #0 [ added 30-Oct-2010 ] + ; Startline has negative value so process X last lines of file + ; endline parameter ignored + + If (Start < 0) ; remove last X lines from file, endline parameter ignored + { + Start:=TF_CountLines(Text) + Start + 1 + End=0 ; now continue + } + + ; Option #1 + ; StartLine has + character indicating startline + incremental processing. + ; EndLine will be used + ; Make TF_MatchList + + IfInString, Start, `+ + { + If (End = 0 or End = "") ; determine number of lines + End:= TF_Count(Text, "`n") + 1 + StringSplit, Section, Start, `, ; we need to create a new "TF_MatchList" so we split by , + Loop, %Section0% + { + StringSplit, SectionLines, Section%A_Index%, `+ + LoopSection:=End + 1 - SectionLines1 + Counter=0 + TF_MatchList .= SectionLines1 "," + Loop, %LoopSection% + { + If (A_Index >= End) ; + Break + If (Counter = (SectionLines2-1)) ; counter is smaller than the incremental value so skip + { + TF_MatchList .= (SectionLines1 + A_Index) "," + Counter=0 + } + Else + Counter++ + } + } + StringTrimRight, TF_MatchList, TF_MatchList, 1 ; remove trailing , + Return TF_MatchList + } + + ; Option #2 + ; StartLine has - character indicating from-to, COULD be multiple sections. + ; EndLine will be ignored + ; Make TF_MatchList + + IfInString, Start, `- + { + StringSplit, Section, Start, `, ; we need to create a new "TF_MatchList" so we split by , + Loop, %Section0% + { + StringSplit, SectionLines, Section%A_Index%, `- + LoopSection:=SectionLines2 + 1 - SectionLines1 + Loop, %LoopSection% + { + TF_MatchList .= (SectionLines1 - 1 + A_Index) "," + } + } + StringTrimRight, TF_MatchList, TF_MatchList, 1 ; remove trailing , + Return TF_MatchList + } + + ; Option #3 + ; StartLine has comma indicating multiple lines. + ; EndLine will be ignored + + IfInString, Start, `, + { + TF_MatchList:=Start + Return TF_MatchList + } + + ; Option #4 + ; parameters passed on as StartLine, EndLine. + ; Make TF_MatchList from StartLine to EndLine + + If (End = 0 or End = "") ; determine number of lines + End:= TF_Count(Text, "`n") + 1 + LoopTimes:=End-Start + Loop, %LoopTimes% + { + TF_MatchList .= (Start - 1 + A_Index) "," + } + TF_MatchList .= End "," + StringTrimRight, TF_MatchList, TF_MatchList, 1 ; remove trailing , +Return TF_MatchList +} + +; added for TF 3.4 col functions - currently only gets longest line may change in future +TF_Stat(Text) +{ + TF_GetData(OW, Text, FileName) + Sort, Text, f _AscendingLinesL + Pos:=InStr(Text,"`n")-1 +Return pos +} + +_AscendingLinesL(a1, a2) ; used by TF_Stat +{ +Return StrLen(a2) - StrLen(a1) +} + +/* -------------- */ diff --git a/vrapplauncher.bat b/vrapplauncher.bat new file mode 100644 index 0000000..18c5be6 --- /dev/null +++ b/vrapplauncher.bat @@ -0,0 +1,17 @@ +@echo off +start "" "C:\Program Files (x86)\Steam\steamapps\common\HelixVision\Tools\Katanga\katanga.exe" --game-path "T:\SteamLibrary\steamapps\common\BeamNG.drive\Bin64\BeamNG.drive.x64.exe" --launch-type DX11Exe +rem +rem +rem +echo: +echo: +echo: +echo: Loading Katanga and Moving Mountains +echo: +rem +rem +rem +timeout /t 20 +rem +rem +rem \ No newline at end of file