mirror of
https://github.com/uberhalit/SekiroFpsUnlockAndMore.git
synced 2026-06-13 09:57:55 +00:00
updated guide
cleanup
This commit is contained in:
parent
9df5b8832b
commit
35dd34c9c5
6 changed files with 107 additions and 84 deletions
77
README.md
77
README.md
|
|
@ -5,7 +5,7 @@ Patches games memory while running, does not modify any game files. works with e
|
||||||
|
|
||||||
## Download
|
## Download
|
||||||
|
|
||||||
[Get the latest release here](https://github.com/uberhalit/SekiroFpsUnlockAndMore/releases)
|
**[Get the latest release here](https://github.com/uberhalit/SekiroFpsUnlockAndMore/releases)**
|
||||||
|
|
||||||
### See it in action:
|
### See it in action:
|
||||||
[](https://giant.gfycat.com/DevotedArtisticKingsnake.webm)
|
[](https://giant.gfycat.com/DevotedArtisticKingsnake.webm)
|
||||||
|
|
@ -16,13 +16,9 @@ Patches games memory while running, does not modify any game files. works with e
|
||||||
* works with legit, unmodified steam version as well as with unpacked, not-so-legit versions
|
* works with legit, unmodified steam version as well as with unpacked, not-so-legit versions
|
||||||
* GSYNC and FreeSync support even in borderless window mode
|
* GSYNC and FreeSync support even in borderless window mode
|
||||||
* unlock frame rate (remove FPS limit) by setting a new custom limit or setting lock to unlimited
|
* unlock frame rate (remove FPS limit) by setting a new custom limit or setting lock to unlimited
|
||||||
* 60 Hz monitors: disable VSYNC via driver (use 'Enhanced Sync' on AMD) and use fullscreen
|
|
||||||
* high refresh rate monitors: use borderless or force monitor to always use highest available refresh rate and then use fullscreen
|
|
||||||
* add a custom resolution, 21/9 widescreen supported (will overwrite the default 1920x1080 resolution, HUD limited to 16/9)
|
* add a custom resolution, 21/9 widescreen supported (will overwrite the default 1920x1080 resolution, HUD limited to 16/9)
|
||||||
* increase field of view (FOV) (credits to jackfuste)
|
* increase field of view (FOV) (credits to jackfuste)
|
||||||
* you have to be ingame with a loaded save game, FOV will reset after every time a save game loads
|
|
||||||
* set the game to borderless window mode
|
* set the game to borderless window mode
|
||||||
* requires "Windowed" in ingame settings first
|
|
||||||
* automatically patch game on startup
|
* automatically patch game on startup
|
||||||
* seamlessly switch between windowed, borderless and borderless fullscreen
|
* seamlessly switch between windowed, borderless and borderless fullscreen
|
||||||
* hotkey for patching while in (borderless) window mode
|
* hotkey for patching while in (borderless) window mode
|
||||||
|
|
@ -30,34 +26,61 @@ Patches games memory while running, does not modify any game files. works with e
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
The game enforces VSYNC and forces 60 Hz in fullscreen even on 144 Hz monitors so we have to override these.
|
The game enforces VSYNC and forces 60 Hz in fullscreen even on 144 Hz monitors so we have to override these.
|
||||||
|
#### 60 Hz monitors: disable VSYNC via driver (use 'Enhanced Sync' on AMD) and use fullscreen, see guide below
|
||||||
|
#### high refresh rate monitors: use borderless or force monitor to always use highest available refresh rate and then use fullscreen, see guide below
|
||||||
|
|
||||||
### Follow these steps (Nvidia):
|
### Follow these steps on Nvidia:
|
||||||
1. Open Nvidia Control Panel
|
1. Open Nvidia Control Panel
|
||||||
2. Navigate to `Configurate 3D Settings -> Program settings`
|
2. Navigate to `Display -> Change resolution`
|
||||||
3. Select Sekiro from the dropdown or add it manually if it's missing: `Add -> Select Sekiro`
|
3. **Make sure your monitor is set to the highest Refresh rate possible:**
|
||||||
4. **Set `Vertical sync` to `Off`**
|
4. [](#)
|
||||||
5. **Set `Preferred refresh rate` to `Highest available`**
|
5. Navigate to `3D Settings -> Manage 3D settings -> Program Settings`
|
||||||
6. Start `Sekiro FPS Unlocker and more` and set FPS lock to your desired framerate
|
6. Select Sekiro from the dropdown or add it manually if it's missing: `Add -> Select Sekiro -> Add Selected Program`
|
||||||
7. Start the game and use fullscreen or borderless window mode
|
7. **Set `Vertical sync` to `Off`**
|
||||||
8. These steps will force disable vsync so it won't limit your fps to monitor refresh rate and also force the monitor to ignore the games request to run at 60 Hz if in fullscreen
|
8. **Set `Preferred refresh rate` to `Highest available`**
|
||||||
|
9. [](#)
|
||||||
|
10. Hit apply and close Nvidia Control Panel
|
||||||
|
11. Start `Sekiro FPS Unlocker and more` and set FPS lock to your desired framerate
|
||||||
|
12. Start the game and use fullscreen or borderless window mode
|
||||||
|
13. These steps will force disable vsync so it won't limit your fps to monitor refresh rate and also force the monitor to ignore the games request to run at 60 Hz if in fullscreen
|
||||||
|
#### If you do not have 'Preferred refresh rate' or 'Vertical sync' follow these steps (Nvidia):
|
||||||
|
1. Download and extract the [Nvidia Inspector](https://www.techpowerup.com/download/nvidia-inspector/)
|
||||||
|
2. Start the Nvidia Profile Inspector
|
||||||
|
3. Under `2 - Sync and Refresh` set `Prefered Refreshrate` to `Highest available` and `Vertical Sync` to `Force off`
|
||||||
|
4. [](#)
|
||||||
|
5. Hit `Apply changes` and you are good to go
|
||||||
|
|
||||||
### Or these (AMD):
|
### Follow these steps on AMD:
|
||||||
1. Open Radeon Settings
|
1. Right click on Desktop -> `Display settings`
|
||||||
2. Navigate to `Gaming -> Sekiro` or add it manually if it's missing: `Add -> Browse -> Sekiro`
|
2. Scroll down an click `Advanced Display Settings -> Display Adapter Properties`
|
||||||
3. **Set `Wait for Vertical Refresh` to `Enhanced Sync`**
|
3. **Switch to `Monitor` tab and make sure your monitor is set to the highest Refresh rate possible:**
|
||||||
4. Start `Sekiro FPS Unlocker and more` and set FPS lock to your desired frame rate
|
4. [](#)
|
||||||
5. **Launch the game in windowed mode, then switch to fullscreen once in game**
|
5. Open Radeon Settings
|
||||||
6. The last step is important as AMD somehow does not correctly disable VSYNC otherwise
|
6. Navigate to `Gaming -> Sekiro` or add it manually if it's missing: `Add -> Browse -> Sekiro`
|
||||||
|
7. **Set `Wait for Vertical Refresh` to `Enhanced Sync`**:
|
||||||
|
8. [](#)
|
||||||
|
9. Apply and close Radeon Settings
|
||||||
|
10. Start `Sekiro FPS Unlocker and more` and set FPS lock to your desired frame rate
|
||||||
|
11. **Launch the game in windowed mode, then switch to fullscreen once in game**
|
||||||
|
12. The last step is important as AMD somehow does not correctly disable VSYNC otherwise
|
||||||
|
#### If you do not have 'Enhanced Sync' follow these steps (AMD):
|
||||||
|
1. Try setting `Wait for Vertical Refresh` to `Off` instead:
|
||||||
|
2. [](#)
|
||||||
|
3. Be aware however that it seems like AMDs latest drivers are buggy in that regard
|
||||||
|
|
||||||
### To play the game with GSYNC do these additional steps (Nvidia):
|
### To play the game with GSYNC do these additional steps (Nvidia):
|
||||||
1. Set `Monitor Technology` to `G-SYNC`
|
1. Under Nvidia Control Panel navigate to `3D Settings -> Manage 3D settings -> Program Settings -> Sekiro`
|
||||||
2. Make sure that `Preferred refresh rate` is still set to `Highest available`
|
2. Set `Monitor Technology` to `G-SYNC`
|
||||||
3. Use a 3rd party frame rate limiter like [RTSS](https://www.guru3d.com/files-details/rtss-rivatuner-statistics-server-download.html) and set a frame rate limit just a few fps below your monitor refresh rate, on a 144Hz Monitor use 138
|
3. Make sure that `Preferred refresh rate` is still set to `Highest available`
|
||||||
4. Start `Sekiro FPS Unlocker and more` and set FPS lock to your monitors refresh rate
|
4. Make sure that `Vertical sync` is still set to `Off`
|
||||||
5. Start the game and set it to Fullscreen
|
5. [](#)
|
||||||
6. Enjoy perfectly tearing free variable high refresh rates without VSYNC
|
6. Don't forget to Apply and close Nvidia Control Panel
|
||||||
|
7. Use a 3rd party frame rate limiter like [RTSS](https://www.guru3d.com/files-details/rtss-rivatuner-statistics-server-download.html) and set a frame rate limit just a few fps below your monitor refresh rate, on a 144Hz Monitor use 138
|
||||||
|
8. Start `Sekiro FPS Unlocker and more` and set FPS lock to your monitors refresh rate
|
||||||
|
9. Start the game and set it to Fullscreen
|
||||||
|
10. Enjoy perfectly tearing free variable high refresh rates without VSYNC
|
||||||
|
|
||||||
The graphic setup has to be done only once but as the patcher hot-patches the memory you have to start the patcher every time you want to unlock frame rate etc.
|
The graphic setup has to be done only once but as the patcher hot-patches the memory **you have to start the patcher every time you want to unlock frame rate etc**.
|
||||||
|
|
||||||
### To add a custom resolution
|
### To add a custom resolution
|
||||||
1. Start the game
|
1. Start the game
|
||||||
|
|
|
||||||
|
|
@ -5,23 +5,23 @@
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:local="clr-namespace:SekiroFpsUnlockAndMore"
|
xmlns:local="clr-namespace:SekiroFpsUnlockAndMore"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Sekiro FPS Unlocker and more v1.0.0" Height="530" Width="306" ResizeMode="CanMinimize" Loaded="Window_Loaded" Closing="Window_Closing">
|
Title="Sekiro FPS Unlocker and more v1.0.2" Height="Auto" SizeToContent="WidthAndHeight" Width="Auto" ResizeMode="CanMinimize" Loaded="Window_Loaded" Closing="Window_Closing">
|
||||||
|
|
||||||
<Grid>
|
<Grid Background="#FFF9F9F9">
|
||||||
<CheckBox x:Name="cbUnlockFps" Content="FPS lock (0= unlimited):" IsChecked="True" HorizontalAlignment="Left" Margin="10,12,0,0" VerticalAlignment="Top" FontSize="14 px" Checked="CheckBoxChanged_Handler" Unchecked="CheckBoxChanged_Handler"/>
|
<CheckBox x:Name="cbUnlockFps" Content="FPS lock (0= unlimited):" IsChecked="True" HorizontalAlignment="Left" Margin="10,12,0,0" VerticalAlignment="Top" FontSize="14 px" Checked="CheckBoxChanged_Handler" Unchecked="CheckBoxChanged_Handler"/>
|
||||||
<TextBox x:Name="tbFps" Text="144" MaxLength="3" HorizontalAlignment="Left" Height="25" Margin="181,10,0,0" VerticalAlignment="Top" Width="106" FontSize="14 px" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler"/>
|
<TextBox x:Name="tbFps" Text="144" MaxLength="3" HorizontalAlignment="Left" Height="25" Margin="181,10,10,10" VerticalAlignment="Top" Width="106" FontSize="14 px" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler"/>
|
||||||
<CheckBox x:Name="cbAddWidescreen" Content="Add custom resolution:" HorizontalAlignment="Left" Margin="10,42,0,0" VerticalAlignment="Top" FontSize="14 px" Checked="CheckBoxChanged_Handler" Unchecked="CheckBoxChanged_Handler"/>
|
<CheckBox x:Name="cbAddWidescreen" Content="Add custom resolution:" HorizontalAlignment="Left" Margin="10,42,0,0" VerticalAlignment="Top" FontSize="14 px" Checked="CheckBoxChanged_Handler" Unchecked="CheckBoxChanged_Handler"/>
|
||||||
<TextBox x:Name="tbWidth" Text="2560" MaxLength="4" HorizontalAlignment="Left" Height="25" Margin="181,40,0,0" VerticalAlignment="Top" Width="45" FontSize="14 px" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler" />
|
<TextBox x:Name="tbWidth" Text="2560" MaxLength="4" HorizontalAlignment="Left" Height="25" Margin="181,40,0,0" VerticalAlignment="Top" Width="45" FontSize="14 px" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler" />
|
||||||
<Label Content="x" HorizontalAlignment="Left" Margin="226,36,0,0" VerticalAlignment="Top" FontSize="14 px"/>
|
<Label Content="x" HorizontalAlignment="Left" Margin="226,36,0,0" VerticalAlignment="Top" FontSize="14 px"/>
|
||||||
<TextBox x:Name="tbHeight" Text="1080" MaxLength="4" HorizontalAlignment="Left" Height="25" Margin="242,40,0,0" VerticalAlignment="Top" Width="45" FontSize="14 px" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler" />
|
<TextBox x:Name="tbHeight" Text="1080" MaxLength="4" HorizontalAlignment="Left" Height="25" Margin="242,40,0,0" VerticalAlignment="Top" Width="45" FontSize="14 px" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler" />
|
||||||
<CheckBox x:Name="cbFov" Content="Increase FOV by:" HorizontalAlignment="Left" Margin="10,72,0,0" VerticalAlignment="Top" FontSize="14 px" Checked="CheckBoxChanged_Handler" Unchecked="CheckBoxChanged_Handler"/>
|
<CheckBox x:Name="cbFov" Content="Increase FOV by:" HorizontalAlignment="Left" Margin="10,72,0,0" VerticalAlignment="Top" FontSize="14 px" Checked="CheckBoxChanged_Handler" Unchecked="CheckBoxChanged_Handler"/>
|
||||||
<ComboBox x:Name="cbSelectFov" HorizontalAlignment="Left" VerticalAlignment="Top" Width="106" Height="25" Margin="181,70,0,0" FontSize="14 px" SelectedValuePath="Key" DisplayMemberPath="Value"/>
|
<ComboBox x:Name="cbSelectFov" HorizontalAlignment="Left" VerticalAlignment="Top" Width="106" Height="25" Margin="181,70,10,10" FontSize="14 px" SelectedValuePath="Key" DisplayMemberPath="Value"/>
|
||||||
<CheckBox x:Name="cbBorderless" Content="Borderless window" HorizontalAlignment="Left" Margin="10,100,0,0" VerticalAlignment="Top" FontSize="14 px" Checked="CbBorderless_Checked" Unchecked="CbBorderless_Unchecked"/>
|
<CheckBox x:Name="cbBorderless" Content="Borderless window" HorizontalAlignment="Left" Margin="10,100,0,0" VerticalAlignment="Top" FontSize="14 px" Checked="CbBorderless_Checked" Unchecked="CbBorderless_Unchecked"/>
|
||||||
<CheckBox x:Name="cbBorderlessStretch" Content="Fullscreen stretch" IsEnabled="False" HorizontalAlignment="Left" Margin="152,100,0,0" VerticalAlignment="Top" FontSize="14 px" Checked="CheckBoxChanged_Handler" Unchecked="CheckBoxChanged_Handler"/>
|
<CheckBox x:Name="cbBorderlessStretch" Content="Fullscreen stretch" IsEnabled="False" HorizontalAlignment="Left" Margin="152,100,0,0" VerticalAlignment="Top" FontSize="14 px" Checked="CheckBoxChanged_Handler" Unchecked="CheckBoxChanged_Handler"/>
|
||||||
<Button x:Name="bPatch" Content="Patch game (CTRL + P)" FontSize="14 px" HorizontalAlignment="Left" Margin="10,125,0,0" VerticalAlignment="Top" Width="277" Height="30"
|
<Button x:Name="bPatch" Content="Patch game (CTRL + P)" FontSize="14 px" HorizontalAlignment="Left" Margin="10,125,10,10" VerticalAlignment="Top" Width="277" Height="30"
|
||||||
BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Focusable="False" Click="BPatch_Click" />
|
BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Focusable="False" Click="BPatch_Click" />
|
||||||
<TextBox x:Name="tbStatus" Text="waiting for game..." TextAlignment="Center" HorizontalAlignment="Left" TextWrapping="NoWrap" Height="25" Margin="10,165,0,0" VerticalAlignment="Top" Width="277" FontSize="14 px" IsEnabled="False" FontWeight="Bold" />
|
<TextBox x:Name="tbStatus" Text="waiting for game..." TextAlignment="Center" HorizontalAlignment="Left" TextWrapping="NoWrap" Height="25" Margin="10,165,10,10" VerticalAlignment="Top" Width="277" FontSize="14 px" IsEnabled="False" FontWeight="Bold" />
|
||||||
<StackPanel HorizontalAlignment="Left" Height="305" Margin="13,195,0,0" VerticalAlignment="Top" Width="275">
|
<StackPanel HorizontalAlignment="Left" Height="Auto" Margin="12,195,12,5" VerticalAlignment="Top" Width="275">
|
||||||
<TextBlock HorizontalAlignment="Left" TextWrapping="WrapWithOverflow" VerticalAlignment="Top" FontSize="11 px" IsEnabled="False">
|
<TextBlock HorizontalAlignment="Left" TextWrapping="WrapWithOverflow" VerticalAlignment="Top" FontSize="11 px" IsEnabled="False">
|
||||||
<TextBlock.Inlines>
|
<TextBlock.Inlines>
|
||||||
<Run FontWeight="Bold">If your monitor is 60 Hz you will have to use</Run>
|
<Run FontWeight="Bold">If your monitor is 60 Hz you will have to use</Run>
|
||||||
|
|
|
||||||
|
|
@ -21,15 +21,15 @@ namespace SekiroFpsUnlockAndMore
|
||||||
internal byte[] PATCH_FRAMERATE_UNLIMITED = new byte[4] { 0x00, 0x00, 0x00, 0x00 };
|
internal byte[] PATCH_FRAMERATE_UNLIMITED = new byte[4] { 0x00, 0x00, 0x00, 0x00 };
|
||||||
internal byte[] PATCH_WIDESCREEN_219_DISABLE = new byte[1] { 0x74 };
|
internal byte[] PATCH_WIDESCREEN_219_DISABLE = new byte[1] { 0x74 };
|
||||||
internal byte[] PATCH_WIDESCREEN_219_ENABLE = new byte[1] { 0xEB };
|
internal byte[] PATCH_WIDESCREEN_219_ENABLE = new byte[1] { 0xEB };
|
||||||
internal byte[] PATCH_FOV_DISABLE = new byte[1] { 0x0C };
|
internal byte[] PATCH_FOV_DISABLE = new byte[2] { 0x0C, 0xE7};
|
||||||
internal Dictionary<byte, string> PATCH_FOVMATRIX = new Dictionary<byte, string>
|
internal Dictionary<byte[], string> PATCH_FOVMATRIX = new Dictionary<byte[], string>
|
||||||
{
|
{
|
||||||
{ 0x00, "- 50%" },
|
{ new byte[2] {0x00, 0xE7}, "- 50%" },
|
||||||
{ 0x04, "- 10%" },
|
{ new byte[2] {0x04, 0xE7}, "- 10%" },
|
||||||
{ 0x10, "+ 15%" },
|
{ new byte[2] {0x10, 0xE7}, "+ 15%" },
|
||||||
{ 0x14, "+ 40%" },
|
{ new byte[2] {0x14, 0xE7}, "+ 40%" },
|
||||||
{ 0x18, "+ 75%" },
|
{ new byte[2] {0x18, 0xE7}, "+ 75%" },
|
||||||
{ 0x1C, "+ 90%" },
|
{ new byte[2] {0x1C, 0xE7}, "+ 90%" },
|
||||||
};
|
};
|
||||||
|
|
||||||
internal Process _game;
|
internal Process _game;
|
||||||
|
|
@ -261,12 +261,16 @@ namespace SekiroFpsUnlockAndMore
|
||||||
if (_game.HasExited)
|
if (_game.HasExited)
|
||||||
{
|
{
|
||||||
_running = false;
|
_running = false;
|
||||||
|
if (_gameProc != IntPtr.Zero)
|
||||||
|
CloseHandle(_gameProc);
|
||||||
|
_game = null;
|
||||||
_gameHwnd = IntPtr.Zero;
|
_gameHwnd = IntPtr.Zero;
|
||||||
_gameProc = IntPtr.Zero;
|
_gameProc = IntPtr.Zero;
|
||||||
_gameProcStatic = IntPtr.Zero;
|
_gameProcStatic = IntPtr.Zero;
|
||||||
_offset_framelock = 0x0;
|
_offset_framelock = 0x0;
|
||||||
_offset_framelock_running_fix = 0x0;
|
_offset_framelock_running_fix = 0x0;
|
||||||
_offset_resolution = 0x0;
|
_offset_resolution = 0x0;
|
||||||
|
_offset_resolution_default = 0x0;
|
||||||
_offset_widescreen_219 = 0x0;
|
_offset_widescreen_219 = 0x0;
|
||||||
_offset_fovsetting = 0x0;
|
_offset_fovsetting = 0x0;
|
||||||
UpdateStatus("waiting for game...", Brushes.White);
|
UpdateStatus("waiting for game...", Brushes.White);
|
||||||
|
|
@ -320,8 +324,7 @@ namespace SekiroFpsUnlockAndMore
|
||||||
|
|
||||||
if (this.cbAddWidescreen.IsChecked == true)
|
if (this.cbAddWidescreen.IsChecked == true)
|
||||||
{
|
{
|
||||||
int width = -1;
|
bool isNumber = Int32.TryParse(this.tbWidth.Text, out int width);
|
||||||
bool isNumber = Int32.TryParse(this.tbWidth.Text, out width);
|
|
||||||
if (width < 800 || !isNumber)
|
if (width < 800 || !isNumber)
|
||||||
{
|
{
|
||||||
this.tbWidth.Text = "2560";
|
this.tbWidth.Text = "2560";
|
||||||
|
|
@ -332,8 +335,7 @@ namespace SekiroFpsUnlockAndMore
|
||||||
this.tbWidth.Text = "5760";
|
this.tbWidth.Text = "5760";
|
||||||
width = 5760;
|
width = 5760;
|
||||||
}
|
}
|
||||||
int height = -1;
|
isNumber = Int32.TryParse(this.tbHeight.Text, out int height);
|
||||||
isNumber = Int32.TryParse(this.tbHeight.Text, out height);
|
|
||||||
if (height < 450 || !isNumber)
|
if (height < 450 || !isNumber)
|
||||||
{
|
{
|
||||||
this.tbHeight.Text = "1080";
|
this.tbHeight.Text = "1080";
|
||||||
|
|
@ -357,8 +359,7 @@ namespace SekiroFpsUnlockAndMore
|
||||||
|
|
||||||
if (this.cbFov.IsChecked == true)
|
if (this.cbFov.IsChecked == true)
|
||||||
{
|
{
|
||||||
byte[] fovByte = new byte[1];
|
byte[] fovByte = ((KeyValuePair<byte[], string>) this.cbSelectFov.SelectedItem).Key;
|
||||||
fovByte[0] = ((KeyValuePair<byte, string>) this.cbSelectFov.SelectedItem).Key;
|
|
||||||
WriteBytes(_gameProcStatic, _offset_fovsetting, fovByte);
|
WriteBytes(_gameProcStatic, _offset_fovsetting, fovByte);
|
||||||
}
|
}
|
||||||
else if (this.cbFov.IsChecked == false)
|
else if (this.cbFov.IsChecked == false)
|
||||||
|
|
@ -406,8 +407,8 @@ namespace SekiroFpsUnlockAndMore
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the hexadecimal representation of an IEEE-754 floating point number
|
/// Returns the hexadecimal representation of an IEEE-754 floating point number
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="input">The floating point number</param>
|
/// <param name="input">The floating point number.</param>
|
||||||
/// <returns>The hexadecimal representation of the input</returns>
|
/// <returns>The hexadecimal representation of the input.</returns>
|
||||||
private string getHexRepresentationFromFloat(float input)
|
private string getHexRepresentationFromFloat(float input)
|
||||||
{
|
{
|
||||||
uint f = BitConverter.ToUInt32(BitConverter.GetBytes(input), 0);
|
uint f = BitConverter.ToUInt32(BitConverter.GetBytes(input), 0);
|
||||||
|
|
@ -514,8 +515,7 @@ namespace SekiroFpsUnlockAndMore
|
||||||
private static T Read<T>(IntPtr gameProc, Int64 lpBaseAddress)
|
private static T Read<T>(IntPtr gameProc, Int64 lpBaseAddress)
|
||||||
{
|
{
|
||||||
byte[] lpBuffer = new byte[Marshal.SizeOf(typeof(T))];
|
byte[] lpBuffer = new byte[Marshal.SizeOf(typeof(T))];
|
||||||
IntPtr lpNumberOfBytesRead;
|
ReadProcessMemory(gameProc, lpBaseAddress, lpBuffer, (ulong)lpBuffer.Length, out _);
|
||||||
ReadProcessMemory(gameProc, lpBaseAddress, lpBuffer, (ulong)lpBuffer.Length, out lpNumberOfBytesRead);
|
|
||||||
GCHandle gcHandle = GCHandle.Alloc(lpBuffer, GCHandleType.Pinned);
|
GCHandle gcHandle = GCHandle.Alloc(lpBuffer, GCHandleType.Pinned);
|
||||||
T structure = (T)Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject(), typeof(T));
|
T structure = (T)Marshal.PtrToStructure(gcHandle.AddrOfPinnedObject(), typeof(T));
|
||||||
gcHandle.Free();
|
gcHandle.Free();
|
||||||
|
|
@ -531,8 +531,7 @@ namespace SekiroFpsUnlockAndMore
|
||||||
/// <returns>True if successful, false otherwise.</returns>
|
/// <returns>True if successful, false otherwise.</returns>
|
||||||
private static bool WriteBytes(IntPtr gameProc, Int64 lpBaseAddress, byte[] bytes)
|
private static bool WriteBytes(IntPtr gameProc, Int64 lpBaseAddress, byte[] bytes)
|
||||||
{
|
{
|
||||||
IntPtr lpNumberOfBytesWritten;
|
return WriteProcessMemory(gameProc, lpBaseAddress, bytes, (ulong)bytes.Length, out _);
|
||||||
return WriteProcessMemory(gameProc, lpBaseAddress, bytes, (ulong)bytes.Length, out lpNumberOfBytesWritten);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -540,8 +539,8 @@ namespace SekiroFpsUnlockAndMore
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hProcess">Handle to the process in whose memory the pattern has been found.</param>
|
/// <param name="hProcess">Handle to the process in whose memory the pattern has been found.</param>
|
||||||
/// <param name="lpPatternAddress">The address where the pattern has been found.</param>
|
/// <param name="lpPatternAddress">The address where the pattern has been found.</param>
|
||||||
/// <param name="instructionLength">The length of the instruction including the 4 bytes pointer</param>
|
/// <param name="instructionLength">The length of the instruction including the 4 bytes pointer.</param>
|
||||||
/// <remarks>Static pointers in x86-64 are relative offsets from the instruction address. </remarks>
|
/// <remarks>Static pointers in x86-64 are relative offsets from the instruction address.</remarks>
|
||||||
/// <returns>The static offset from the process to desired object).</returns>
|
/// <returns>The static offset from the process to desired object).</returns>
|
||||||
internal static Int64 FindOffsetToStaticPointer(IntPtr hProcess, Int64 lpPatternAddress, int instructionLength)
|
internal static Int64 FindOffsetToStaticPointer(IntPtr hProcess, Int64 lpPatternAddress, int instructionLength)
|
||||||
{
|
{
|
||||||
|
|
@ -558,6 +557,27 @@ namespace SekiroFpsUnlockAndMore
|
||||||
return Regex.IsMatch(text, "[^0-9]+");
|
return Regex.IsMatch(text, "[^0-9]+");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Logs messages to log file
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">The message to write to file.</param>
|
||||||
|
private void LogToFile(string msg)
|
||||||
|
{
|
||||||
|
string timedMsg = "[" + DateTime.Now + "] " + msg;
|
||||||
|
Debug.WriteLine(timedMsg);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (StreamWriter writer = new StreamWriter(_logPath, true))
|
||||||
|
{
|
||||||
|
writer.WriteLine(timedMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Writing to log file failed: " + ex.Message, "Sekiro Fps Unlock And More");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateStatus(string text, Brush color)
|
private void UpdateStatus(string text, Brush color)
|
||||||
{
|
{
|
||||||
this.tbStatus.Background = color;
|
this.tbStatus.Background = color;
|
||||||
|
|
@ -571,9 +591,9 @@ namespace SekiroFpsUnlockAndMore
|
||||||
|
|
||||||
private void Numeric_PastingHandler(object sender, DataObjectPastingEventArgs e)
|
private void Numeric_PastingHandler(object sender, DataObjectPastingEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.DataObject.GetDataPresent(typeof(String)))
|
if (e.DataObject.GetDataPresent(typeof(string)))
|
||||||
{
|
{
|
||||||
String text = (String)e.DataObject.GetData(typeof(String));
|
string text = (string)e.DataObject.GetData(typeof(string));
|
||||||
if (IsNumericInput(text)) e.CancelCommand();
|
if (IsNumericInput(text)) e.CancelCommand();
|
||||||
}
|
}
|
||||||
else e.CancelCommand();
|
else e.CancelCommand();
|
||||||
|
|
@ -608,24 +628,6 @@ namespace SekiroFpsUnlockAndMore
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// log messages to file
|
|
||||||
private void LogToFile(string msg)
|
|
||||||
{
|
|
||||||
string timedMsg = "[" + DateTime.Now + "] " + msg;
|
|
||||||
Debug.WriteLine(timedMsg);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (StreamWriter writer = new StreamWriter(_logPath, true))
|
|
||||||
{
|
|
||||||
writer.WriteLine(timedMsg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
MessageBox.Show("Writing to log file failed: " + ex.Message, "Sekiro Fps Unlock And More");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region WINAPI
|
#region WINAPI
|
||||||
private const int WM_HOTKEY_MSG_ID = 0x0312;
|
private const int WM_HOTKEY_MSG_ID = 0x0312;
|
||||||
private const int MOD_CONTROL = 0x0002;
|
private const int MOD_CONTROL = 0x0002;
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@ namespace SekiroFpsUnlockAndMore
|
||||||
internal const string PATTERN_WIDESCREEN_219_MASK = "?xxxxxxxxx";
|
internal const string PATTERN_WIDESCREEN_219_MASK = "?xxxxxxxxx";
|
||||||
|
|
||||||
// credits to jackfuste for FOV findings
|
// credits to jackfuste for FOV findings
|
||||||
internal const string PATTERN_FOVSETTING = "F3 0F 10 08 F3 0F 59 0D 00 E7 9B 02"; // F3 0F 10 08 F3 0F 59 0D ?? E7 9B 02
|
internal const string PATTERN_FOVSETTING = "F3 0F 10 08 F3 0F 59 0D 00 00 9B 02"; // F3 0F 10 08 F3 0F 59 0D ?? ?? 9B 02
|
||||||
internal const string PATTERN_FOVSETTING_MASK = "xxxxxxxx?xxx";
|
internal const string PATTERN_FOVSETTING_MASK = "xxxxxxxx??xx";
|
||||||
internal const int PATTERN_FOVSETTING_OFFSET = 8;
|
internal const int PATTERN_FOVSETTING_OFFSET = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,9 @@ namespace SekiroFpsUnlockAndMore
|
||||||
else if (IntPtr.Size == 8)
|
else if (IntPtr.Size == 8)
|
||||||
dwStart = (long)pModule.BaseAddress;
|
dwStart = (long)pModule.BaseAddress;
|
||||||
int nSize = pModule.ModuleMemorySize;
|
int nSize = pModule.ModuleMemorySize;
|
||||||
|
|
||||||
IntPtr lpNumberOfBytesRead;
|
|
||||||
byte[] bData = new byte[nSize];
|
byte[] bData = new byte[nSize];
|
||||||
|
|
||||||
if (!ReadProcessMemory(hProcess, dwStart, bData, nSize, out lpNumberOfBytesRead))
|
if (!ReadProcessMemory(hProcess, dwStart, bData, nSize, out IntPtr lpNumberOfBytesRead))
|
||||||
throw new Exception("ReadProcessMemory error!");
|
throw new Exception("ReadProcessMemory error!");
|
||||||
if (lpNumberOfBytesRead.ToInt64() != nSize)
|
if (lpNumberOfBytesRead.ToInt64() != nSize)
|
||||||
throw new Exception("ReadProcessMemory error!");
|
throw new Exception("ReadProcessMemory error!");
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using System.Reflection;
|
using System.Windows;
|
||||||
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Windows;
|
|
||||||
|
|
||||||
[assembly: AssemblyTitle("SekiroFpsUnlockAndMore")]
|
[assembly: AssemblyTitle("SekiroFpsUnlockAndMore")]
|
||||||
[assembly: AssemblyDescription("")]
|
[assembly: AssemblyDescription("")]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue