mirror of
https://github.com/uberhalit/SekiroFpsUnlockAndMore.git
synced 2026-06-13 09:57:55 +00:00
Added FreezeMem for fTimescalePlayer
ApplicationSettings are decoupled from base class now Cleanup Refactor
This commit is contained in:
parent
12b6c52149
commit
772b69c1fb
7 changed files with 1743 additions and 1641 deletions
|
|
@ -158,9 +158,38 @@ namespace SekiroFpsUnlockAndMore
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Reference pointer pTimeRelated to pTimescaleManager pointer, offset in struct to <float>fTimescale which acts as a global speed scale for almost all ingame calculations
|
Reference pointer pPlayerStatsRelated to PlayerStats pointer, offset in struct to <int>iPlayerDeaths
|
||||||
0000000141149E87 | 48:8B05 3A24B402 | mov rax,qword ptr ds:[143C8C2C8] | pTimeRelated->[pTimescaleManager+0x360]->fTimescale
|
00000001407AAC92 | 0FB648 7A | movzx ecx,byte ptr ds:[rax+7A] |
|
||||||
0000000141149E8E | F3:0F1088 60030000 | movss xmm1,dword ptr ds:[rax+360] | offset from TimescaleManager->fTimescale
|
00000001407AAC96 | 888B F7000000 | mov byte ptr ds:[rbx+F7],cl |
|
||||||
|
00000001407AAC9C | 48:8B05 4DD03903 | mov rax,qword ptr ds:[143B47CF0] |
|
||||||
|
00000001407AACA3 | 8B88 8C000000 | mov ecx,dword ptr ds:[rax+8C] |
|
||||||
|
00000001407AACA9 | 898B F8000000 | mov dword ptr ds:[rbx+F8],ecx |
|
||||||
|
00000001407AACAF | 48:8B05 3AD03903 | mov rax,qword ptr ds:[143B47CF0] | pPlayerStatsRelated->[PlayerStats+0x90]->iPlayerDeaths
|
||||||
|
00000001407AACB6 | 8B88 90000000 | mov ecx,dword ptr ds:[rax+90] | offset pPlayerStats->iPlayerDeaths
|
||||||
|
*/
|
||||||
|
// credits to 'Me_TheCat' for original offset
|
||||||
|
internal const string PATTERN_PLAYER_DEATHS = "0F B6 48 00 88 8B 00 00 00 00 48 8B 05 00 00 00 00 8B 88 00 00 00 00 89 8B 00 00 00 00 48 8B 05 00 00 00 00 8B 88 00 00 00 00"; // 0F B6 48 ?? 88 8B ?? ?? 00 00 48 8B 05 ?? ?? ?? ?? 8B 88 ?? ?? 00 00 89 8B ?? ?? 00 00 48 8B 05 ?? ?? ?? ?? 8B 88 ?? ?? 00 00
|
||||||
|
internal const string PATTERN_PLAYER_DEATHS_MASK = "xxx?xx??xxxxx????xx??xxxx??xxxxx????xx??xx";
|
||||||
|
internal const int PATTERN_PLAYER_DEATHS_OFFSET = 29;
|
||||||
|
internal const int PATTERN_PLAYER_DEATHS_INSTRUCTION_LENGTH = 7;
|
||||||
|
internal const int PATTERN_PLAYER_DEATHS_POINTER_OFFSET_OFFSET = 9;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Reference pointer pTotalKills to <int>iTotalKills, does not get updated on every kill but mostly on every 2nd, includes own player deaths...
|
||||||
|
0000000141151838 | 48:8D0D A9A5B302 | lea rcx,qword ptr ds:[143C8BDE8] | pTotalKills->iTotalKills
|
||||||
|
000000014115183F | 891481 | mov dword ptr ds:[rcx+rax*4],edx |
|
||||||
|
0000000141151842 | C3 | ret |
|
||||||
|
*/
|
||||||
|
// credits to 'Me_TheCat' for original offset
|
||||||
|
internal const string PATTERN_TOTAL_KILLS = "48 8D 0D 00 00 00 00 89 14 81 C3"; // 48 8D 0D ?? ?? ?? ?? 89 14 81 C3
|
||||||
|
internal const string PATTERN_TOTAL_KILLS_MASK = "xxx????xxxx";
|
||||||
|
internal const int PATTERN_TOTAL_KILLS_INSTRUCTION_LENGTH = 7;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Reference pointer pTimeRelated to TimescaleManager pointer, offset in struct to <float>fTimescale which acts as a global speed scale for almost all ingame calculations
|
||||||
|
0000000141149E87 | 48:8B05 3A24B402 | mov rax,qword ptr ds:[143C8C2C8] | pTimeRelated->[TimescaleManager+0x360]->fTimescale
|
||||||
|
0000000141149E8E | F3:0F1088 60030000 | movss xmm1,dword ptr ds:[rax+360] | offset TimescaleManager->fTimescale
|
||||||
0000000141149E96 | F3:0F5988 68020000 | mulss xmm1,dword ptr ds:[rax+268] |
|
0000000141149E96 | F3:0F5988 68020000 | mulss xmm1,dword ptr ds:[rax+268] |
|
||||||
*/
|
*/
|
||||||
// credits to 'Zullie the Witch' for original offset
|
// credits to 'Zullie the Witch' for original offset
|
||||||
|
|
@ -169,6 +198,7 @@ namespace SekiroFpsUnlockAndMore
|
||||||
internal const int PATTERN_TIMESCALE_INSTRUCTION_LENGTH = 7;
|
internal const int PATTERN_TIMESCALE_INSTRUCTION_LENGTH = 7;
|
||||||
internal const int PATTERN_TIMESCALE_POINTER_OFFSET_OFFSET = 11;
|
internal const int PATTERN_TIMESCALE_POINTER_OFFSET_OFFSET = 11;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Reference pointer pPlayerStructRelated1 to 4 more pointers up to player data class, offset in struct to <float>fTimescalePlayer which acts as a speed scale for the player character
|
Reference pointer pPlayerStructRelated1 to 4 more pointers up to player data class, offset in struct to <float>fTimescalePlayer which acts as a speed scale for the player character
|
||||||
00000001406BF1D7 | 48:8B1D 128C4A03 | mov rbx,qword ptr ds:[143B67DF0] | pPlayerStructRelated1->[pPlayerStructRelated2+0x88]->[pPlayerStructRelated3+0x1FF8]->[pPlayerStructRelated4+0x28]->[pPlayerStructRelated5+0xD00]->fTimescalePlayer
|
00000001406BF1D7 | 48:8B1D 128C4A03 | mov rbx,qword ptr ds:[143B67DF0] | pPlayerStructRelated1->[pPlayerStructRelated2+0x88]->[pPlayerStructRelated3+0x1FF8]->[pPlayerStructRelated4+0x28]->[pPlayerStructRelated5+0xD00]->fTimescalePlayer
|
||||||
|
|
@ -184,13 +214,5 @@ namespace SekiroFpsUnlockAndMore
|
||||||
internal const int PATTERN_TIMESCALE_POINTER3_OFFSET = 0x1FF8;
|
internal const int PATTERN_TIMESCALE_POINTER3_OFFSET = 0x1FF8;
|
||||||
internal const int PATTERN_TIMESCALE_POINTER4_OFFSET = 0x28;
|
internal const int PATTERN_TIMESCALE_POINTER4_OFFSET = 0x28;
|
||||||
internal const int PATTERN_TIMESCALE_POINTER5_OFFSET = 0xD00;
|
internal const int PATTERN_TIMESCALE_POINTER5_OFFSET = 0xD00;
|
||||||
|
|
||||||
// game stat values by Me_TheCat
|
|
||||||
internal const string PATTERN_PLAYER_DEATHS = "8B 88 90 00 00 00 89 8B FC 00 00 00 48 8B";
|
|
||||||
internal const string PATTERN_PLAYER_DEATHS_MASK = "xxxxxxxxx???xx";
|
|
||||||
|
|
||||||
internal const string PATTERN_TOTAL_KILLS = "48 8D 0D 00 00 00 00 89 14 81 C3";
|
|
||||||
internal const string PATTERN_TOTAL_KILLS_MASK = "xxx????xxxx";
|
|
||||||
internal const int PATTERN_TOTAL_KILLS_OFFSET = 7;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,113 +5,105 @@
|
||||||
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.1.0" Width="Auto" Height="Auto" SizeToContent="WidthAndHeight" ResizeMode="CanMinimize" Loaded="Window_Loaded" Closing="Window_Closing">
|
Title="Sekiro FPS Unlocker and more v1.1.1" Width="Auto" Height="Auto" SizeToContent="WidthAndHeight" ResizeMode="CanMinimize" Loaded="Window_Loaded" Closing="Window_Closing">
|
||||||
|
|
||||||
<Grid Background="#FFF9F9F9">
|
<Grid Background="#FFF9F9F9">
|
||||||
<StackPanel Margin="10,10,10,0" Width="290" Height="Auto">
|
<DockPanel>
|
||||||
<DockPanel LastChildFill="False">
|
<StackPanel DockPanel.Dock="Top" Margin="10,10,10,0" Width="290" Height="Auto">
|
||||||
<CheckBox x:Name="cbFramelock" DockPanel.Dock="Left" Margin="0,0,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Frame rate lock:" IsChecked="True" Checked="CbFramelock_Check_Handler" Unchecked="CbFramelock_Check_Handler" />
|
<DockPanel LastChildFill="False">
|
||||||
<TextBox x:Name="tbFramelock" DockPanel.Dock="Right" Margin="0,0,0,0" Width="116" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Text="144" MaxLength="3" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler" />
|
<CheckBox x:Name="cbFramelock" DockPanel.Dock="Left" Margin="0,0,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Frame rate lock:" IsChecked="True" Checked="CbFramelock_Check_Handler" Unchecked="CbFramelock_Check_Handler" />
|
||||||
</DockPanel>
|
<TextBox x:Name="tbFramelock" DockPanel.Dock="Right" Margin="0,0,0,0" Width="116" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Text="144" MaxLength="3" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler" />
|
||||||
<DockPanel Margin="0,5,0,0" LastChildFill="False">
|
</DockPanel>
|
||||||
<CheckBox x:Name="cbAddResolution" DockPanel.Dock="Left" Margin="0,0,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Add custom resolution:" Checked="CbAddResolution_Check_Handler" Unchecked="CbAddResolution_Check_Handler" />
|
<DockPanel Margin="0,5,0,0" LastChildFill="False">
|
||||||
<TextBox x:Name="tbHeight" DockPanel.Dock="Right" Margin="0,0,0,0" Width="50" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Text="1080" MaxLength="4" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler" />
|
<CheckBox x:Name="cbAddResolution" DockPanel.Dock="Left" Margin="0,0,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Add custom resolution:" Checked="CbAddResolution_Check_Handler" Unchecked="CbAddResolution_Check_Handler" />
|
||||||
<Label DockPanel.Dock="Right" Margin="0,0,0,0" Height="25" FontSize="14 px" Content="x" />
|
<TextBox x:Name="tbHeight" DockPanel.Dock="Right" Margin="0,0,0,0" Width="50" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Text="1080" MaxLength="4" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler" />
|
||||||
<TextBox x:Name="tbWidth" DockPanel.Dock="Right" Margin="0,0,0,0" Width="50" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Text="2560" MaxLength="4" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler" />
|
<Label DockPanel.Dock="Right" Margin="0,0,0,0" Height="25" FontSize="14 px" Content="x" />
|
||||||
</DockPanel>
|
<TextBox x:Name="tbWidth" DockPanel.Dock="Right" Margin="0,0,0,0" Width="50" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Text="2560" MaxLength="4" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler" />
|
||||||
<DockPanel Margin="0,5,0,0" LastChildFill="False">
|
</DockPanel>
|
||||||
<CheckBox x:Name="cbFov" DockPanel.Dock="Left" Margin="0,0,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Increase FOV by:" Checked="CbFov_Check_Handler" Unchecked="CbFov_Check_Handler" />
|
<DockPanel Margin="0,5,0,0" LastChildFill="False">
|
||||||
<ComboBox x:Name="cbSelectFov" DockPanel.Dock="Right" Margin="0,0,0,0" Width="116" Height="25" FontSize="14 px" SelectedValuePath="Key" DisplayMemberPath="Value" DropDownClosed="CbSelectFov_DropDownClosed"/>
|
<CheckBox x:Name="cbFov" DockPanel.Dock="Left" Margin="0,0,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Increase FOV by:" Checked="CbFov_Check_Handler" Unchecked="CbFov_Check_Handler" />
|
||||||
</DockPanel>
|
<ComboBox x:Name="cbSelectFov" DockPanel.Dock="Right" Margin="0,0,0,0" Width="116" Height="25" FontSize="14 px" SelectedValuePath="Key" DisplayMemberPath="Value" DropDownClosed="CbSelectFov_DropDownClosed"/>
|
||||||
<StackPanel Margin="0,5,0,0" Orientation="Horizontal">
|
</DockPanel>
|
||||||
<CheckBox x:Name="cbBorderless" DockPanel.Dock="Left" Margin="0,0,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Borderless window" IsEnabled="False" Checked="CbBorderless_Checked" Unchecked="CbBorderless_Unchecked"/>
|
<StackPanel Margin="0,5,0,0" Orientation="Horizontal">
|
||||||
<CheckBox x:Name="cbBorderlessStretch" DockPanel.Dock="Right" Margin="10,0,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Fullscreen stretch" IsEnabled="False" Checked="CbBorderlessStretch_Check_Handler" Unchecked="CbBorderlessStretch_Check_Handler" />
|
<CheckBox x:Name="cbBorderless" DockPanel.Dock="Left" Margin="0,0,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Borderless window" ToolTip="To enable this set 'Windowed' mode in game options first." IsEnabled="False" Checked="CbBorderless_Checked" Unchecked="CbBorderless_Unchecked"/>
|
||||||
</StackPanel>
|
<CheckBox x:Name="cbBorderlessStretch" DockPanel.Dock="Right" Margin="10,0,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Fullscreen stretch" IsEnabled="False" Checked="CbBorderlessStretch_Check_Handler" Unchecked="CbBorderlessStretch_Check_Handler" />
|
||||||
<DockPanel Margin="0,5,0,0" LastChildFill="False">
|
</StackPanel>
|
||||||
<CheckBox x:Name="cbLogStats" Content="Log stats (Deaths, Enemies killed)" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" FontSize="14 px" Checked="CbStatChanged" Unchecked="CbStatChanged" />
|
<CheckBox x:Name="cbLogStats" Margin="0,5,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Log stats to file (Deaths, Kills)" ToolTip="Check the guide on how to display these with OBS." Checked="CbStatChanged" Unchecked="CbStatChanged" />
|
||||||
</DockPanel>
|
<Expander x:Name="exGameMods" Margin="-3,5,0,0" Height="Auto" FontSize="14 px" Header="Game modifications" IsExpanded="False">
|
||||||
<Expander x:Name="exGameMods" Margin="-3,4,0,0" Height="Auto" FontSize="14 px" Header="Game modifications" IsExpanded="False">
|
<Grid Margin="3,0,0,0" Background="#FFF9F9F9">
|
||||||
<Grid Margin="3,0,0,0" Background="#FFF9F9F9">
|
<StackPanel Width="Auto" Height="Auto">
|
||||||
<StackPanel Width="Auto" Height="Auto">
|
<DockPanel Margin="0,3,0,0" LastChildFill="False">
|
||||||
<DockPanel Margin="0,3,0,0" LastChildFill="False">
|
<CheckBox x:Name="cbGameSpeed" DockPanel.Dock="Left" Margin="0,0,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Game speed (%):" Checked="CbGameSpeed_Check_Handler" Unchecked="CbGameSpeed_Check_Handler" />
|
||||||
<CheckBox x:Name="cbGameSpeed" DockPanel.Dock="Left" Margin="0,0,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Game speed (%):" Checked="CbGameSpeed_Check_Handler" Unchecked="CbGameSpeed_Check_Handler" />
|
<Button x:Name="bGs100" DockPanel.Dock="Right" Content="100" Margin="0,0,0,0" Width="30" Height="25" FontSize="14 px" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
|
||||||
<Button x:Name="bGs100" DockPanel.Dock="Right" Content="100" Margin="0,0,0,0" Width="30" Height="25" FontSize="14 px" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
|
|
||||||
Focusable="False" Click="BGs100_Click" />
|
Focusable="False" Click="BGs100_Click" />
|
||||||
<Button x:Name="bGsHigher" DockPanel.Dock="Right" Content=">" Margin="0,0,3,0" Width="25" Height="25" FontSize="14 px" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
|
<Button x:Name="bGsHigher" DockPanel.Dock="Right" Content=">" Margin="0,0,3,0" Width="25" Height="25" FontSize="14 px" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
|
||||||
Focusable="False" Click="BGsHigher_Click" />
|
Focusable="False" Click="BGsHigher_Click" />
|
||||||
<TextBox x:Name="tbGameSpeed" DockPanel.Dock="Right" Margin="0,0,3,0" Width="30" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Text="100" TextAlignment="Center" MaxLength="3" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler" />
|
<TextBox x:Name="tbGameSpeed" DockPanel.Dock="Right" Margin="0,0,3,0" Width="30" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Text="100" TextAlignment="Center" MaxLength="3" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler" />
|
||||||
<Button x:Name="bGsLower" DockPanel.Dock="Right" Content="<" Margin="0,0,3,0" Width="25" Height="25" FontSize="14 px" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
|
<Button x:Name="bGsLower" DockPanel.Dock="Right" Content="<" Margin="0,0,3,0" Width="25" Height="25" FontSize="14 px" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
|
||||||
Focusable="False" Click="BGsLower_Click" />
|
Focusable="False" Click="BGsLower_Click" />
|
||||||
<Button x:Name="bGs0" DockPanel.Dock="Right" Content="0" Margin="0,0,3,0" Width="30" Height="25" FontSize="14 px" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
|
<Button x:Name="bGs0" DockPanel.Dock="Right" Content="0" Margin="0,0,3,0" Width="30" Height="25" FontSize="14 px" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
|
||||||
Focusable="False" Click="BGs0_Click" />
|
Focusable="False" Click="BGs0_Click" />
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
<DockPanel Margin="0,5,0,0" LastChildFill="False">
|
<DockPanel Margin="0,5,0,0" LastChildFill="False">
|
||||||
<CheckBox x:Name="cbPlayerSpeed" DockPanel.Dock="Left" Margin="0,0,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Player speed (%):" ToolTip="To enable this start the game and load a save, then start the patcher." Checked="CbPlayerSpeed_Check_Handler" Unchecked="CbPlayerSpeed_Check_Handler" />
|
<CheckBox x:Name="cbPlayerSpeed" DockPanel.Dock="Left" Margin="0,0,0,0" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Content="Player speed (%):" ToolTip="To enable this start the game and load a save, then tick the checkbox." Checked="CbPlayerSpeed_Check_Handler" Unchecked="CbPlayerSpeed_Check_Handler" />
|
||||||
<Button x:Name="bPs100" DockPanel.Dock="Right" Content="100" Margin="0,0,0,0" Width="30" Height="25" FontSize="14 px" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
|
<Button x:Name="bPs100" DockPanel.Dock="Right" Content="100" Margin="0,0,0,0" Width="30" Height="25" FontSize="14 px" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
|
||||||
Focusable="False" Click="BPs100_Click" />
|
Focusable="False" Click="BPs100_Click" />
|
||||||
<Button x:Name="bPsHigher" DockPanel.Dock="Right" Content=">" Margin="0,0,3,0" Width="25" Height="25" FontSize="14 px" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
|
<Button x:Name="bPsHigher" DockPanel.Dock="Right" Content=">" Margin="0,0,3,0" Width="25" Height="25" FontSize="14 px" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
|
||||||
Focusable="False" Click="BPsHigher_Click" />
|
Focusable="False" Click="BPsHigher_Click" />
|
||||||
<TextBox x:Name="tbPlayerSpeed" DockPanel.Dock="Right" Margin="0,0,3,0" Width="30" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Text="100" TextAlignment="Center" MaxLength="3" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler" />
|
<TextBox x:Name="tbPlayerSpeed" DockPanel.Dock="Right" Margin="0,0,3,0" Width="30" Height="25" FontSize="14 px" VerticalContentAlignment="Center" Text="100" TextAlignment="Center" MaxLength="3" PreviewTextInput="Numeric_PreviewTextInput" DataObject.Pasting="Numeric_PastingHandler" />
|
||||||
<Button x:Name="bPsLower" DockPanel.Dock="Right" Content="<" Margin="0,0,3,0" Width="25" Height="25" FontSize="14 px" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
|
<Button x:Name="bPsLower" DockPanel.Dock="Right" Content="<" Margin="0,0,3,0" Width="25" Height="25" FontSize="14 px" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
|
||||||
Focusable="False" Click="BPsLower_Click" />
|
Focusable="False" Click="BPsLower_Click" />
|
||||||
<Button x:Name="bPs0" DockPanel.Dock="Right" Content="0" Margin="0,0,3,0" Width="30" Height="25" FontSize="14 px" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
|
<Button x:Name="bPs0" DockPanel.Dock="Right" Content="0" Margin="0,0,3,0" Width="30" Height="25" FontSize="14 px" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
|
||||||
Focusable="False" Click="BPs0_Click" />
|
Focusable="False" Click="BPs0_Click" />
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Expander>
|
</Expander>
|
||||||
<Button x:Name="bPatch" Margin="0,7,0,0" Width="290" Height="30" FontSize="14 px" IsEnabled="False" Content="Patch game (CTRL + P)" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
|
<Button x:Name="bPatch" Margin="0,7,0,0" Width="290" Height="30" FontSize="14 px" IsEnabled="False" Content="Patch game (CTRL + P)" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
|
||||||
Focusable="False" Click="BPatch_Click" />
|
Focusable="False" Click="BPatch_Click" />
|
||||||
<TextBox x:Name="tbStatus" Margin="0,5,0,0" Width="290" Height="25" FontSize="14 px" FontWeight="Bold" Text="waiting for game..." TextAlignment="Center" TextWrapping="NoWrap" IsEnabled="False" />
|
<TextBox x:Name="tbStatus" Margin="0,5,0,0" Width="290" Height="25" FontSize="14 px" FontWeight="Bold" Text="waiting for game..." TextAlignment="Center" TextWrapping="NoWrap" IsEnabled="False" />
|
||||||
<TextBlock HorizontalAlignment="Left" TextWrapping="WrapWithOverflow" Margin="2,5,2,0" VerticalAlignment="Top" FontSize="11 px" IsEnabled="False">
|
<TextBlock Margin="2,5,2,0" FontSize="11 px" TextWrapping="WrapWithOverflow" IsEnabled="False">
|
||||||
<TextBlock.Inlines>
|
<TextBlock.Inlines>
|
||||||
<Run FontWeight="Bold" Foreground="#FF0046FF">This patcher does not modify game files, you have to start it every time.</Run>
|
<Run FontWeight="Bold" Foreground="#FF0046FF">This patcher does not modify game files, you have to start it every time.</Run>
|
||||||
<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>
|
||||||
<Run FontWeight="Bold" Foreground="#FFF00000">fullscreen mode and force disable VSYNC</Run>
|
<Run FontWeight="Bold" Foreground="#FFF00000">fullscreen mode and force disable VSYNC</Run>
|
||||||
<Run FontWeight="Bold">with Nvidia Control panel or AMD Radeon Settings to get frame rate unlock working.</Run>
|
<Run FontWeight="Bold">with Nvidia Control panel or AMD Radeon Settings to get frame rate unlock working.</Run>
|
||||||
<Run>To avoid stuttering it's recommended to disable VSYNC even with a 144 Hz monitor.</Run>
|
<Run>To avoid stuttering it's recommended to disable VSYNC even with a 144 Hz monitor.</Run>
|
||||||
<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>
|
||||||
<Run FontWeight="Bold" Foreground="#FFF00000">borderless window mode or force the game to run on highest available refresh rate</Run>
|
<Run FontWeight="Bold" Foreground="#FFF00000">borderless window mode or force the game to run on highest available refresh rate</Run>
|
||||||
<Run FontWeight="Bold">using Nvidia Control panel or AMD Radeon Settings.</Run>
|
<Run FontWeight="Bold">using Nvidia Control panel or AMD Radeon Settings.</Run>
|
||||||
<Run>Borderless window mode requires "Windowed" in game settings first.</Run>
|
<Run>Borderless window mode requires "Windowed" in game settings first.</Run>
|
||||||
<Run FontWeight="Bold">Custom resolution adds 21/9 support and overwrites a default resolution, hud will be limited to 16/9.</Run>
|
<Run FontWeight="Bold">Custom resolution adds 21/9 support and overwrites a default resolution, hud will be limited to 16/9.</Run>
|
||||||
<Run>Borderless window mode with custom resolution requires you to patch and set resolution first, then add borderless patch afterwards.</Run>
|
<Run>Borderless window mode with custom resolution requires you to patch and set resolution first, then add borderless patch afterwards.</Run>
|
||||||
<Run FontWeight="Bold">To enable Player Speed modification you have to be ingame first.</Run>
|
<Run FontWeight="Bold">To enable Player Speed modification you have to be ingame first.</Run>
|
||||||
<Run FontWeight="Bold" Foreground="#FFF00000">See the link below for detailed information, guides, GSYNC support and an AMD fix.</Run>
|
<Run FontWeight="Bold" Foreground="#FFF00000">See the link below for detailed information, guides, GSYNC support and an AMD fix.</Run>
|
||||||
</TextBlock.Inlines>
|
</TextBlock.Inlines>
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<Label HorizontalAlignment="Right" FontSize="12 px">
|
<Label HorizontalAlignment="Right" FontSize="12 px">
|
||||||
<Hyperlink NavigateUri="https://github.com/uberhalit/SekiroFpsUnlockAndMore" RequestNavigate="Hyperlink_RequestNavigate">
|
<Hyperlink NavigateUri="https://github.com/uberhalit/SekiroFpsUnlockAndMore" RequestNavigate="Hyperlink_RequestNavigate">
|
||||||
v1.1.0 - by uberhalit
|
v1.1.1 - by uberhalit
|
||||||
</Hyperlink>
|
</Hyperlink>
|
||||||
</Label>
|
</Label>
|
||||||
<StatusBar DockPanel.Dock="Bottom" Margin="-10,0,-10,0" VerticalAlignment="Bottom">
|
</StackPanel>
|
||||||
<StatusBar.ItemsPanel>
|
<StatusBar DockPanel.Dock="Bottom" Height="25">
|
||||||
<ItemsPanelTemplate>
|
<StatusBarItem DockPanel.Dock="Left">
|
||||||
<Grid>
|
<TextBlock Name="sbDeathCount">
|
||||||
<Grid.ColumnDefinitions>
|
<Run Text="Deaths:" />
|
||||||
<ColumnDefinition Width="Auto" />
|
<Run Text="{Binding Deaths}" />
|
||||||
<ColumnDefinition Width="Auto" />
|
</TextBlock>
|
||||||
<ColumnDefinition Width="Auto" />
|
</StatusBarItem>
|
||||||
</Grid.ColumnDefinitions>
|
<Separator Margin="5,4,5,4" Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}"/>
|
||||||
</Grid>
|
<StatusBarItem DockPanel.Dock="Left">
|
||||||
</ItemsPanelTemplate>
|
<TextBlock Name="sbKillCount">
|
||||||
</StatusBar.ItemsPanel>
|
<Run Text="Kills:" />
|
||||||
|
<Run Text="{Binding Kills}" />
|
||||||
<StatusBarItem Grid.Column="0">
|
</TextBlock>
|
||||||
<TextBlock Name="sbDeathCount">
|
</StatusBarItem>
|
||||||
<Run Text="Deaths:"/>
|
<Separator Margin="5,4,5,4" Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}"/>
|
||||||
<Run Text="{Binding Deaths}"/>
|
<StatusBarItem DockPanel.Dock="Right" HorizontalAlignment="Right">
|
||||||
</TextBlock>
|
<TextBlock Name="sbStatus" />
|
||||||
</StatusBarItem>
|
</StatusBarItem>
|
||||||
<Separator Grid.Column="1" />
|
</StatusBar>
|
||||||
<StatusBarItem Grid.Column="2">
|
</DockPanel>
|
||||||
<TextBlock Name="sbKillCount">
|
</Grid>
|
||||||
<Run Text="Kills:"/>
|
|
||||||
<Run Text="{Binding Kills}"/>
|
|
||||||
</TextBlock>
|
|
||||||
</StatusBarItem>
|
|
||||||
</StatusBar>
|
|
||||||
</StackPanel>
|
|
||||||
</Grid>
|
|
||||||
</Window>
|
</Window>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Timers;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
|
@ -11,8 +12,6 @@ using System.Windows.Threading;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Timers;
|
|
||||||
using Timer = System.Timers.Timer;
|
|
||||||
|
|
||||||
namespace SekiroFpsUnlockAndMore
|
namespace SekiroFpsUnlockAndMore
|
||||||
{
|
{
|
||||||
|
|
@ -28,33 +27,31 @@ namespace SekiroFpsUnlockAndMore
|
||||||
internal long _offset_resolution_default = 0x0;
|
internal long _offset_resolution_default = 0x0;
|
||||||
internal long _offset_resolution_scaling_fix = 0x0;
|
internal long _offset_resolution_scaling_fix = 0x0;
|
||||||
internal long _offset_fovsetting = 0x0;
|
internal long _offset_fovsetting = 0x0;
|
||||||
//game stat offsets
|
internal long _offset_total_kills = 0x0;
|
||||||
internal long _offset_player_deaths = 0x0;
|
internal long _offset_player_deaths = 0x0;
|
||||||
internal long _pointer_player_deaths = 0x0;
|
|
||||||
internal long _offset_timescale = 0x0;
|
internal long _offset_timescale = 0x0;
|
||||||
internal long _offset_timescale_player = 0x0;
|
internal long _offset_timescale_player = 0x0;
|
||||||
internal bool _use_resolution_720 = false;
|
internal long _offset_timescale_player_pointer_start = 0x0;
|
||||||
internal long _offset_total_kills = 0x0;
|
|
||||||
internal long _pointer_total_kills = 0x0;
|
|
||||||
|
|
||||||
internal const string deathCounterFilename = "DeathCouner.txt";
|
|
||||||
internal SettingsService _settingsService;
|
internal SettingsService _settingsService;
|
||||||
internal const string totalKillsFilename = "TotalKillsCounter.txt";
|
internal StatusViewModel _statusViewModel = new StatusViewModel();
|
||||||
|
|
||||||
internal StatViewModel _statViewModel = new StatViewModel();
|
internal readonly System.Timers.Timer _timerStatsCheck = new System.Timers.Timer();
|
||||||
private bool _statLoggingEnabled = false;
|
internal readonly DispatcherTimer _dispatcherTimerFreezeMem = new DispatcherTimer();
|
||||||
internal readonly Timer _statRecordTimer = new Timer();
|
internal readonly DispatcherTimer _dispatcherTimerCheck = new DispatcherTimer();
|
||||||
internal readonly DispatcherTimer _dispatcherTimerCheck = new DispatcherTimer();
|
|
||||||
internal bool _running = false;
|
internal bool _running = false;
|
||||||
internal string _logPath;
|
internal string _logPath;
|
||||||
|
internal string _deathCounterPath;
|
||||||
|
internal string _killCounterPath;
|
||||||
internal bool _retryAccess = true;
|
internal bool _retryAccess = true;
|
||||||
|
internal bool _use_resolution_720 = false;
|
||||||
|
internal bool _statLoggingEnabled = false;
|
||||||
internal RECT _windowRect;
|
internal RECT _windowRect;
|
||||||
|
|
||||||
|
public MainWindow()
|
||||||
public MainWindow()
|
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
DataContext = _statViewModel;
|
DataContext = _statusViewModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -71,6 +68,9 @@ namespace SekiroFpsUnlockAndMore
|
||||||
GC.KeepAlive(mutex);
|
GC.KeepAlive(mutex);
|
||||||
|
|
||||||
_logPath = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + @"\SekiroFpsUnlockAndMore.log";
|
_logPath = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + @"\SekiroFpsUnlockAndMore.log";
|
||||||
|
_deathCounterPath = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + @"\DeathCounter.txt";
|
||||||
|
_killCounterPath = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + @"\TotalKillsCounter.txt";
|
||||||
|
|
||||||
this.cbSelectFov.ItemsSource = GameData.PATCH_FOVSETTING_MATRIX;
|
this.cbSelectFov.ItemsSource = GameData.PATCH_FOVSETTING_MATRIX;
|
||||||
this.cbSelectFov.SelectedIndex = 2;
|
this.cbSelectFov.SelectedIndex = 2;
|
||||||
|
|
||||||
|
|
@ -80,7 +80,6 @@ namespace SekiroFpsUnlockAndMore
|
||||||
if (!RegisterHotKey(hWnd, 9009, MOD_CONTROL, VK_P))
|
if (!RegisterHotKey(hWnd, 9009, MOD_CONTROL, VK_P))
|
||||||
MessageBox.Show("Hotkey is already in use, it may not work.", "Sekiro FPS Unlocker and more");
|
MessageBox.Show("Hotkey is already in use, it may not work.", "Sekiro FPS Unlocker and more");
|
||||||
|
|
||||||
// add a hook for WindowsMessageQueue to recognize hotkey-press
|
|
||||||
ComponentDispatcher.ThreadFilterMessage += new ThreadMessageEventHandler(ComponentDispatcherThreadFilterMessage);
|
ComponentDispatcher.ThreadFilterMessage += new ThreadMessageEventHandler(ComponentDispatcherThreadFilterMessage);
|
||||||
|
|
||||||
_dispatcherTimerCheck.Tick += new EventHandler(async (object s, EventArgs a) =>
|
_dispatcherTimerCheck.Tick += new EventHandler(async (object s, EventArgs a) =>
|
||||||
|
|
@ -91,9 +90,11 @@ namespace SekiroFpsUnlockAndMore
|
||||||
_dispatcherTimerCheck.Interval = new TimeSpan(0, 0, 0, 2);
|
_dispatcherTimerCheck.Interval = new TimeSpan(0, 0, 0, 2);
|
||||||
_dispatcherTimerCheck.Start();
|
_dispatcherTimerCheck.Start();
|
||||||
|
|
||||||
_statRecordTimer.Elapsed += new ElapsedEventHandler(StatReadTimer);
|
_dispatcherTimerFreezeMem.Tick += new EventHandler(FreezeMemory);
|
||||||
_statRecordTimer.Interval = 1500;
|
_dispatcherTimerFreezeMem.Interval = new TimeSpan(0, 0, 0, 0, 2000);
|
||||||
_statRecordTimer.Start();
|
|
||||||
|
_timerStatsCheck.Elapsed += new ElapsedEventHandler(StatReadTimer);
|
||||||
|
_timerStatsCheck.Interval = 2000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -101,14 +102,13 @@ namespace SekiroFpsUnlockAndMore
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
||||||
{
|
{
|
||||||
|
_timerStatsCheck.Stop();
|
||||||
SaveConfiguration();
|
SaveConfiguration();
|
||||||
ComponentDispatcher.ThreadFilterMessage -= ComponentDispatcherThreadFilterMessage;
|
ComponentDispatcher.ThreadFilterMessage -= ComponentDispatcherThreadFilterMessage;
|
||||||
IntPtr hWnd = new WindowInteropHelper(this).Handle;
|
IntPtr hWnd = new WindowInteropHelper(this).Handle;
|
||||||
UnregisterHotKey(hWnd, 9009);
|
UnregisterHotKey(hWnd, 9009);
|
||||||
if (_gameAccessHwnd != IntPtr.Zero)
|
if (_gameAccessHwnd != IntPtr.Zero)
|
||||||
CloseHandle(_gameAccessHwnd);
|
CloseHandle(_gameAccessHwnd);
|
||||||
|
|
||||||
_statRecordTimer.Stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -133,21 +133,21 @@ namespace SekiroFpsUnlockAndMore
|
||||||
{
|
{
|
||||||
_settingsService = new SettingsService(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + @"\SekiroFpsUnlockAndMore.xml");
|
_settingsService = new SettingsService(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + @"\SekiroFpsUnlockAndMore.xml");
|
||||||
if (!_settingsService.Load()) return;
|
if (!_settingsService.Load()) return;
|
||||||
this.cbFramelock.IsChecked = _settingsService.settings.cbFramelock;
|
this.cbFramelock.IsChecked = _settingsService.ApplicationSettings.cbFramelock;
|
||||||
this.tbFramelock.Text = _settingsService.settings.tbFramelock.ToString();
|
this.tbFramelock.Text = _settingsService.ApplicationSettings.tbFramelock.ToString();
|
||||||
this.cbAddResolution.IsChecked = _settingsService.settings.cbAddResolution;
|
this.cbAddResolution.IsChecked = _settingsService.ApplicationSettings.cbAddResolution;
|
||||||
this.tbWidth.Text = _settingsService.settings.tbWidth.ToString();
|
this.tbWidth.Text = _settingsService.ApplicationSettings.tbWidth.ToString();
|
||||||
this.tbHeight.Text = _settingsService.settings.tbHeight.ToString();
|
this.tbHeight.Text = _settingsService.ApplicationSettings.tbHeight.ToString();
|
||||||
this.cbFov.IsChecked = _settingsService.settings.cbFov;
|
this.cbFov.IsChecked = _settingsService.ApplicationSettings.cbFov;
|
||||||
this.cbSelectFov.SelectedIndex = _settingsService.settings.cbSelectFov;
|
this.cbSelectFov.SelectedIndex = _settingsService.ApplicationSettings.cbSelectFov;
|
||||||
this.cbBorderless.IsChecked = _settingsService.settings.cbBorderless;
|
this.cbBorderless.IsChecked = _settingsService.ApplicationSettings.cbBorderless;
|
||||||
this.cbBorderlessStretch.IsChecked = _settingsService.settings.cbBorderlessStretch;
|
this.cbBorderlessStretch.IsChecked = _settingsService.ApplicationSettings.cbBorderlessStretch;
|
||||||
this.exGameMods.IsExpanded = _settingsService.settings.exGameMods;
|
this.exGameMods.IsExpanded = _settingsService.ApplicationSettings.exGameMods;
|
||||||
this.cbGameSpeed.IsChecked = _settingsService.settings.cbGameSpeed;
|
this.cbGameSpeed.IsChecked = _settingsService.ApplicationSettings.cbGameSpeed;
|
||||||
this.tbGameSpeed.Text = _settingsService.settings.tbGameSpeed.ToString();
|
this.tbGameSpeed.Text = _settingsService.ApplicationSettings.tbGameSpeed.ToString();
|
||||||
this.cbPlayerSpeed.IsChecked = _settingsService.settings.cbPlayerSpeed;
|
this.cbPlayerSpeed.IsChecked = _settingsService.ApplicationSettings.cbPlayerSpeed;
|
||||||
this.tbPlayerSpeed.Text = _settingsService.settings.tbPlayerSpeed.ToString();
|
this.tbPlayerSpeed.Text = _settingsService.ApplicationSettings.tbPlayerSpeed.ToString();
|
||||||
this.cbLogStats.IsChecked = _settingsService.settings.cbLogStats;
|
this.cbLogStats.IsChecked = _settingsService.ApplicationSettings.cbLogStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -155,21 +155,21 @@ namespace SekiroFpsUnlockAndMore
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void SaveConfiguration()
|
private void SaveConfiguration()
|
||||||
{
|
{
|
||||||
_settingsService.settings.cbFramelock = this.cbFramelock.IsChecked == true;
|
_settingsService.ApplicationSettings.cbFramelock = this.cbFramelock.IsChecked == true;
|
||||||
_settingsService.settings.tbFramelock = Convert.ToInt32(this.tbFramelock.Text);
|
_settingsService.ApplicationSettings.tbFramelock = Convert.ToInt32(this.tbFramelock.Text);
|
||||||
_settingsService.settings.cbAddResolution = this.cbAddResolution.IsChecked == true;
|
_settingsService.ApplicationSettings.cbAddResolution = this.cbAddResolution.IsChecked == true;
|
||||||
_settingsService.settings.tbWidth = Convert.ToInt32(this.tbWidth.Text);
|
_settingsService.ApplicationSettings.tbWidth = Convert.ToInt32(this.tbWidth.Text);
|
||||||
_settingsService.settings.tbHeight = Convert.ToInt32(this.tbHeight.Text);
|
_settingsService.ApplicationSettings.tbHeight = Convert.ToInt32(this.tbHeight.Text);
|
||||||
_settingsService.settings.cbFov = this.cbFov.IsChecked == true;
|
_settingsService.ApplicationSettings.cbFov = this.cbFov.IsChecked == true;
|
||||||
_settingsService.settings.cbSelectFov = this.cbSelectFov.SelectedIndex;
|
_settingsService.ApplicationSettings.cbSelectFov = this.cbSelectFov.SelectedIndex;
|
||||||
_settingsService.settings.cbBorderless = this.cbBorderless.IsChecked == true;
|
_settingsService.ApplicationSettings.cbBorderless = this.cbBorderless.IsChecked == true;
|
||||||
_settingsService.settings.cbBorderlessStretch = this.cbBorderlessStretch.IsChecked == true;
|
_settingsService.ApplicationSettings.cbBorderlessStretch = this.cbBorderlessStretch.IsChecked == true;
|
||||||
_settingsService.settings.exGameMods = this.exGameMods.IsExpanded;
|
_settingsService.ApplicationSettings.exGameMods = this.exGameMods.IsExpanded;
|
||||||
_settingsService.settings.cbGameSpeed = this.cbGameSpeed.IsChecked == true;
|
_settingsService.ApplicationSettings.cbGameSpeed = this.cbGameSpeed.IsChecked == true;
|
||||||
_settingsService.settings.tbGameSpeed = Convert.ToInt32(this.tbGameSpeed.Text);
|
_settingsService.ApplicationSettings.tbGameSpeed = Convert.ToInt32(this.tbGameSpeed.Text);
|
||||||
_settingsService.settings.cbPlayerSpeed = this.cbPlayerSpeed.IsChecked == true;
|
_settingsService.ApplicationSettings.cbPlayerSpeed = this.cbPlayerSpeed.IsChecked == true;
|
||||||
_settingsService.settings.tbPlayerSpeed = Convert.ToInt32(this.tbPlayerSpeed.Text);
|
_settingsService.ApplicationSettings.tbPlayerSpeed = Convert.ToInt32(this.tbPlayerSpeed.Text);
|
||||||
_settingsService.settings.cbLogStats = this.cbLogStats.IsChecked == true;
|
_settingsService.ApplicationSettings.cbLogStats = this.cbLogStats.IsChecked == true;
|
||||||
_settingsService.Save();
|
_settingsService.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -238,26 +238,26 @@ namespace SekiroFpsUnlockAndMore
|
||||||
PatternScan patternScan = new PatternScan(_gameAccessHwnd, _gameProc.MainModule);
|
PatternScan patternScan = new PatternScan(_gameAccessHwnd, _gameProc.MainModule);
|
||||||
|
|
||||||
_offset_framelock = patternScan.FindPatternInternal(GameData.PATTERN_FRAMELOCK, GameData.PATTERN_FRAMELOCK_MASK, ' ') + GameData.PATTERN_FRAMELOCK_OFFSET;
|
_offset_framelock = patternScan.FindPatternInternal(GameData.PATTERN_FRAMELOCK, GameData.PATTERN_FRAMELOCK_MASK, ' ') + GameData.PATTERN_FRAMELOCK_OFFSET;
|
||||||
Debug.WriteLine("1. Framelock found at: 0x" + _offset_framelock.ToString("X"));
|
Debug.WriteLine("fFrameTick found at: 0x" + _offset_framelock.ToString("X"));
|
||||||
if (!IsValidAddress(_offset_framelock))
|
if (!IsValidAddress(_offset_framelock))
|
||||||
{
|
{
|
||||||
_offset_framelock = patternScan.FindPatternInternal(GameData.PATTERN_FRAMELOCK_FUZZY, GameData.PATTERN_FRAMELOCK_FUZZY_MASK, ' ') + GameData.PATTERN_FRAMELOCK_FUZZY_OFFSET;
|
_offset_framelock = patternScan.FindPatternInternal(GameData.PATTERN_FRAMELOCK_FUZZY, GameData.PATTERN_FRAMELOCK_FUZZY_MASK, ' ') + GameData.PATTERN_FRAMELOCK_FUZZY_OFFSET;
|
||||||
Debug.WriteLine("2. Framelock found at: 0x" + _offset_framelock.ToString("X"));
|
Debug.WriteLine("2. fFrameTick found at: 0x" + _offset_framelock.ToString("X"));
|
||||||
}
|
}
|
||||||
if (!IsValidAddress(_offset_framelock))
|
if (!IsValidAddress(_offset_framelock))
|
||||||
{
|
{
|
||||||
UpdateStatus("framelock not found...", Brushes.Red);
|
UpdateStatus("fFrameTick not found...", Brushes.Red);
|
||||||
LogToFile("framelock not found...");
|
LogToFile("fFrameTick not found...");
|
||||||
_offset_framelock = 0x0;
|
_offset_framelock = 0x0;
|
||||||
this.cbFramelock.IsEnabled = false;
|
this.cbFramelock.IsEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_offset_framelock_speed_fix = patternScan.FindPatternInternal(GameData.PATTERN_FRAMELOCK_SPEED_FIX, GameData.PATTERN_FRAMELOCK_SPEED_FIX_MASK, ' ') + GameData.PATTERN_FRAMELOCK_SPEED_FIX_OFFSET;
|
_offset_framelock_speed_fix = patternScan.FindPatternInternal(GameData.PATTERN_FRAMELOCK_SPEED_FIX, GameData.PATTERN_FRAMELOCK_SPEED_FIX_MASK, ' ') + GameData.PATTERN_FRAMELOCK_SPEED_FIX_OFFSET;
|
||||||
Debug.WriteLine("Speed fix found at: 0x" + _offset_framelock_speed_fix.ToString("X"));
|
Debug.WriteLine("pFrametimeRunningSpeed at: 0x" + _offset_framelock_speed_fix.ToString("X"));
|
||||||
if (!IsValidAddress(_offset_framelock_speed_fix))
|
if (!IsValidAddress(_offset_framelock_speed_fix))
|
||||||
{
|
{
|
||||||
UpdateStatus("speed fix not found...", Brushes.Red);
|
UpdateStatus("pFrametimeRunningSpeed no found...", Brushes.Red);
|
||||||
LogToFile("speed fix not found...");
|
LogToFile("pFrametimeRunningSpeed not found...");
|
||||||
_offset_framelock_speed_fix = 0x0;
|
_offset_framelock_speed_fix = 0x0;
|
||||||
this.cbFramelock.IsEnabled = false;
|
this.cbFramelock.IsEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
@ -265,7 +265,7 @@ namespace SekiroFpsUnlockAndMore
|
||||||
bool enableResolutionPatch = true;
|
bool enableResolutionPatch = true;
|
||||||
if ((int) SystemParameters.PrimaryScreenWidth < 1281) _use_resolution_720 = true;
|
if ((int) SystemParameters.PrimaryScreenWidth < 1281) _use_resolution_720 = true;
|
||||||
_offset_resolution_default = patternScan.FindPatternInternal(!_use_resolution_720 ? GameData.PATTERN_RESOLUTION_DEFAULT : GameData.PATTERN_RESOLUTION_DEFAULT_720, GameData.PATTERN_RESOLUTION_DEFAULT_MASK, ' ');
|
_offset_resolution_default = patternScan.FindPatternInternal(!_use_resolution_720 ? GameData.PATTERN_RESOLUTION_DEFAULT : GameData.PATTERN_RESOLUTION_DEFAULT_720, GameData.PATTERN_RESOLUTION_DEFAULT_MASK, ' ');
|
||||||
Debug.WriteLine("Default resolution found at: 0x" + _offset_resolution_default.ToString("X"));
|
Debug.WriteLine("default resolution found at: 0x" + _offset_resolution_default.ToString("X"));
|
||||||
if (!IsValidAddress(_offset_resolution_default))
|
if (!IsValidAddress(_offset_resolution_default))
|
||||||
{
|
{
|
||||||
UpdateStatus("default resolution not found...", Brushes.Red);
|
UpdateStatus("default resolution not found...", Brushes.Red);
|
||||||
|
|
@ -274,7 +274,7 @@ namespace SekiroFpsUnlockAndMore
|
||||||
_offset_resolution_default = 0x0;
|
_offset_resolution_default = 0x0;
|
||||||
}
|
}
|
||||||
_offset_resolution_scaling_fix = patternScan.FindPatternInternal(GameData.PATTERN_RESOLUTION_SCALING_FIX, GameData.PATTERN_RESOLUTION_SCALING_FIX_MASK, ' ') + GameData.PATTERN_RESOLUTION_SCALING_FIX_OFFSET;
|
_offset_resolution_scaling_fix = patternScan.FindPatternInternal(GameData.PATTERN_RESOLUTION_SCALING_FIX, GameData.PATTERN_RESOLUTION_SCALING_FIX_MASK, ' ') + GameData.PATTERN_RESOLUTION_SCALING_FIX_OFFSET;
|
||||||
Debug.WriteLine("Scaling fix found at: 0x" + _offset_resolution_scaling_fix.ToString("X"));
|
Debug.WriteLine("scaling fix found at: 0x" + _offset_resolution_scaling_fix.ToString("X"));
|
||||||
if (!IsValidAddress(_offset_resolution_scaling_fix))
|
if (!IsValidAddress(_offset_resolution_scaling_fix))
|
||||||
{
|
{
|
||||||
UpdateStatus("scaling fix not found...", Brushes.Red);
|
UpdateStatus("scaling fix not found...", Brushes.Red);
|
||||||
|
|
@ -282,70 +282,98 @@ namespace SekiroFpsUnlockAndMore
|
||||||
enableResolutionPatch = false;
|
enableResolutionPatch = false;
|
||||||
_offset_resolution_scaling_fix = 0x0;
|
_offset_resolution_scaling_fix = 0x0;
|
||||||
}
|
}
|
||||||
long offset_resolution_pointer = patternScan.FindPatternInternal(GameData.PATTERN_RESOLUTION_POINTER, GameData.PATTERN_RESOLUTION_POINTER_MASK, ' ') + GameData.PATTERN_RESOLUTION_POINTER_OFFSET;
|
long ref_pCurrentResolutionWidth = patternScan.FindPatternInternal(GameData.PATTERN_RESOLUTION_POINTER, GameData.PATTERN_RESOLUTION_POINTER_MASK, ' ') + GameData.PATTERN_RESOLUTION_POINTER_OFFSET;
|
||||||
Debug.WriteLine("Resolution pointer found at: 0x" + offset_resolution_pointer.ToString("X"));
|
Debug.WriteLine("ref_pCurrentResolutionWidth found at: 0x" + ref_pCurrentResolutionWidth.ToString("X"));
|
||||||
if (!IsValidAddress(offset_resolution_pointer))
|
if (!IsValidAddress(ref_pCurrentResolutionWidth))
|
||||||
{
|
{
|
||||||
|
UpdateStatus("re_pCurrentResolutionWidth not found...", Brushes.Red);
|
||||||
|
LogToFile("ref_pCurrentResolutionWidth not found...");
|
||||||
enableResolutionPatch = false;
|
enableResolutionPatch = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_offset_resolution = DereferenceStaticX64Pointer(_gameAccessHwnd, offset_resolution_pointer, GameData.PATTERN_RESOLUTION_POINTER_INSTRUCTION_LENGTH);
|
_offset_resolution = DereferenceStaticX64Pointer(_gameAccessHwnd, ref_pCurrentResolutionWidth, GameData.PATTERN_RESOLUTION_POINTER_INSTRUCTION_LENGTH);
|
||||||
Debug.WriteLine("Resolution found at: 0x" + _offset_resolution.ToString("X"));
|
Debug.WriteLine("pCurrentResolutionWidth at: 0x" + _offset_resolution.ToString("X"));
|
||||||
if (!IsValidAddress(_offset_resolution))
|
if (!IsValidAddress(_offset_resolution))
|
||||||
{
|
{
|
||||||
UpdateStatus("resolution not valid...", Brushes.Red);
|
UpdateStatus("pCurrentResolutionWidth not valid...", Brushes.Red);
|
||||||
LogToFile("resolution not valid...");
|
LogToFile("pCurrentResolutionWidth not valid...");
|
||||||
_offset_resolution = 0x0;
|
_offset_resolution = 0x0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.cbAddResolution.IsEnabled = enableResolutionPatch;
|
this.cbAddResolution.IsEnabled = enableResolutionPatch;
|
||||||
|
|
||||||
_offset_fovsetting = patternScan.FindPatternInternal(GameData.PATTERN_FOVSETTING, GameData.PATTERN_FOVSETTING_MASK, ' ') + GameData.PATTERN_FOVSETTING_OFFSET;
|
_offset_fovsetting = patternScan.FindPatternInternal(GameData.PATTERN_FOVSETTING, GameData.PATTERN_FOVSETTING_MASK, ' ') + GameData.PATTERN_FOVSETTING_OFFSET;
|
||||||
Debug.WriteLine("FOV found at: 0x" + _offset_fovsetting.ToString("X"));
|
Debug.WriteLine("pFovTableEntry found at: 0x" + _offset_fovsetting.ToString("X"));
|
||||||
if (!IsValidAddress(_offset_fovsetting))
|
if (!IsValidAddress(_offset_fovsetting))
|
||||||
{
|
{
|
||||||
UpdateStatus("FOV not found...", Brushes.Red);
|
UpdateStatus("pFovTableEntry not found...", Brushes.Red);
|
||||||
LogToFile("FOV not found...");
|
LogToFile("pFovTableEntry not found...");
|
||||||
_offset_fovsetting = 0x0;
|
_offset_fovsetting = 0x0;
|
||||||
this.cbFov.IsEnabled = false;
|
this.cbFov.IsEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Game stats
|
long ref_pPlayerStatsRelated = patternScan.FindPatternInternal(GameData.PATTERN_PLAYER_DEATHS, GameData.PATTERN_PLAYER_DEATHS_MASK, ' ') + GameData.PATTERN_PLAYER_DEATHS_OFFSET;
|
||||||
_offset_player_deaths = patternScan.FindPatternInternal(GameData.PATTERN_PLAYER_DEATHS, GameData.PATTERN_PLAYER_DEATHS_MASK, ' ');
|
Debug.WriteLine("ref_pPlayerStatsRelated found at: 0x" + ref_pPlayerStatsRelated.ToString("X"));
|
||||||
Debug.WriteLine("Player Deaths found at: 0x" + _offset_player_deaths.ToString("X"));
|
if (!IsValidAddress(ref_pPlayerStatsRelated))
|
||||||
if (!IsValidAddress(_offset_player_deaths))
|
|
||||||
{
|
{
|
||||||
LogToFile("Player death counter not found...");
|
UpdateStatus("ref_pPlayerStatsRelated not found...", Brushes.Red);
|
||||||
}
|
LogToFile("ref_pPlayerStatsRelated not found...");
|
||||||
|
this.cbLogStats.IsEnabled = false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_pointer_player_deaths = Read<Int64>(_gameAccessHwndStatic, DereferenceStaticX64Pointer(_gameAccessHwndStatic, _offset_player_deaths, 0)) + 0x90;
|
long pPlayerStatsRelated = DereferenceStaticX64Pointer(_gameAccessHwndStatic, ref_pPlayerStatsRelated, GameData.PATTERN_PLAYER_DEATHS_INSTRUCTION_LENGTH);
|
||||||
|
Debug.WriteLine("pPlayerStatsRelated found at: 0x" + pPlayerStatsRelated.ToString("X"));
|
||||||
|
if (IsValidAddress(pPlayerStatsRelated))
|
||||||
|
{
|
||||||
|
int playerStatsToDeathsOffset = Read<Int32>(_gameAccessHwndStatic, ref_pPlayerStatsRelated + GameData.PATTERN_PLAYER_DEATHS_POINTER_OFFSET_OFFSET);
|
||||||
|
Debug.WriteLine("offset pPlayerStats->iPlayerDeaths found : 0x" + playerStatsToDeathsOffset.ToString("X"));
|
||||||
|
if (playerStatsToDeathsOffset > 0) _offset_player_deaths = Read<Int64>(_gameAccessHwndStatic, pPlayerStatsRelated) + playerStatsToDeathsOffset;
|
||||||
|
Debug.WriteLine("iPlayerDeaths found at: 0x" + _offset_player_deaths.ToString("X"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (!IsValidAddress(_offset_player_deaths))
|
||||||
|
{
|
||||||
|
UpdateStatus("Player Deaths not found...", Brushes.Red);
|
||||||
|
LogToFile("Player Deaths not found...");
|
||||||
|
_offset_player_deaths = 0x0;
|
||||||
|
this.cbLogStats.IsEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
_offset_total_kills = patternScan.FindPatternInternal(GameData.PATTERN_TOTAL_KILLS, GameData.PATTERN_TOTAL_KILLS_MASK, ' ') + GameData.PATTERN_TOTAL_KILLS_OFFSET;
|
long ref_pTotalKills = patternScan.FindPatternInternal(GameData.PATTERN_TOTAL_KILLS, GameData.PATTERN_TOTAL_KILLS_MASK, ' ');
|
||||||
Debug.WriteLine("Total kills found at: 0x" + _offset_total_kills.ToString("X"));
|
Debug.WriteLine("ref_pTotalKills found at: 0x" + ref_pTotalKills.ToString("X"));
|
||||||
if (!IsValidAddress(_offset_total_kills))
|
if (!IsValidAddress(ref_pTotalKills))
|
||||||
{
|
{
|
||||||
LogToFile("Total kills counter not found...");
|
UpdateStatus("ref_pTotalKills not found...", Brushes.Red);
|
||||||
}
|
LogToFile("ref_pTotalKills not found...");
|
||||||
|
this.cbLogStats.IsEnabled = false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_pointer_total_kills = DereferenceStaticX64Pointer(_gameAccessHwndStatic, _offset_total_kills, 0);
|
_offset_total_kills = DereferenceStaticX64Pointer(_gameAccessHwndStatic, ref_pTotalKills, GameData.PATTERN_TOTAL_KILLS_INSTRUCTION_LENGTH);
|
||||||
|
if (!IsValidAddress(_offset_total_kills))
|
||||||
|
{
|
||||||
|
UpdateStatus("pTotalKills not valid...", Brushes.Red);
|
||||||
|
LogToFile("pTotalKills not valid...");
|
||||||
|
_offset_total_kills = 0x0;
|
||||||
|
this.cbLogStats.IsEnabled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (_offset_player_deaths > 0x0 && _offset_total_kills > 0x0) _timerStatsCheck.Start();
|
||||||
|
|
||||||
this.cbBorderless.IsEnabled = true;
|
this.cbBorderless.IsEnabled = true;
|
||||||
|
|
||||||
long offset_pTimeRelated = patternScan.FindPatternInternal(GameData.PATTERN_TIMESCALE, GameData.PATTERN_TIMESCALE_MASK, ' ');
|
long ref_pTimeRelated = patternScan.FindPatternInternal(GameData.PATTERN_TIMESCALE, GameData.PATTERN_TIMESCALE_MASK, ' ');
|
||||||
Debug.WriteLine("pTimeRelated found at: 0x" + offset_pTimeRelated.ToString("X"));
|
Debug.WriteLine("ref_pTimeRelated found at: 0x" + ref_pTimeRelated.ToString("X"));
|
||||||
if (IsValidAddress(offset_pTimeRelated))
|
if (IsValidAddress(ref_pTimeRelated))
|
||||||
{
|
{
|
||||||
long pTimescaleManager = DereferenceStaticX64Pointer(_gameAccessHwndStatic, offset_pTimeRelated, GameData.PATTERN_TIMESCALE_INSTRUCTION_LENGTH);
|
long pTimescaleManager = DereferenceStaticX64Pointer(_gameAccessHwndStatic, ref_pTimeRelated, GameData.PATTERN_TIMESCALE_INSTRUCTION_LENGTH);
|
||||||
Debug.WriteLine("pTimescaleManager found at: 0x" + pTimescaleManager.ToString("X"));
|
Debug.WriteLine("pTimescaleManager found at: 0x" + pTimescaleManager.ToString("X"));
|
||||||
if (IsValidAddress(pTimescaleManager))
|
if (IsValidAddress(pTimescaleManager))
|
||||||
{
|
{
|
||||||
_offset_timescale = Read<Int64>(_gameAccessHwndStatic, pTimescaleManager) + Read<Int32>(_gameAccessHwndStatic, offset_pTimeRelated + GameData.PATTERN_TIMESCALE_POINTER_OFFSET_OFFSET);
|
_offset_timescale = Read<Int64>(_gameAccessHwndStatic, pTimescaleManager) + Read<Int32>(_gameAccessHwndStatic, ref_pTimeRelated + GameData.PATTERN_TIMESCALE_POINTER_OFFSET_OFFSET);
|
||||||
Debug.WriteLine("timescale found at: 0x" + _offset_timescale.ToString("X"));
|
Debug.WriteLine("fTimescale found at: 0x" + _offset_timescale.ToString("X"));
|
||||||
if (!IsValidAddress(_offset_timescale))
|
if (!IsValidAddress(_offset_timescale))
|
||||||
{
|
{
|
||||||
_offset_timescale = 0x0;
|
_offset_timescale = 0x0;
|
||||||
|
|
@ -354,8 +382,8 @@ namespace SekiroFpsUnlockAndMore
|
||||||
}
|
}
|
||||||
if (_offset_timescale == 0x0)
|
if (_offset_timescale == 0x0)
|
||||||
{
|
{
|
||||||
UpdateStatus("Timescale not found...", Brushes.Red);
|
UpdateStatus("fTimescale not found...", Brushes.Red);
|
||||||
LogToFile("Timescale not found...");
|
LogToFile("fTimescale not found...");
|
||||||
this.cbGameSpeed.IsEnabled = false;
|
this.cbGameSpeed.IsEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -367,6 +395,7 @@ namespace SekiroFpsUnlockAndMore
|
||||||
Debug.WriteLine("pPlayerStructRelated2 found at: 0x" + pPlayerStructRelated2.ToString("X"));
|
Debug.WriteLine("pPlayerStructRelated2 found at: 0x" + pPlayerStructRelated2.ToString("X"));
|
||||||
if (IsValidAddress(pPlayerStructRelated2))
|
if (IsValidAddress(pPlayerStructRelated2))
|
||||||
{
|
{
|
||||||
|
_offset_timescale_player_pointer_start = pPlayerStructRelated2;
|
||||||
long pPlayerStructRelated3 = Read<Int64>(_gameAccessHwndStatic, pPlayerStructRelated2) + GameData.PATTERN_TIMESCALE_POINTER2_OFFSET;
|
long pPlayerStructRelated3 = Read<Int64>(_gameAccessHwndStatic, pPlayerStructRelated2) + GameData.PATTERN_TIMESCALE_POINTER2_OFFSET;
|
||||||
Debug.WriteLine("pPlayerStructRelated3 found at: 0x" + pPlayerStructRelated3.ToString("X"));
|
Debug.WriteLine("pPlayerStructRelated3 found at: 0x" + pPlayerStructRelated3.ToString("X"));
|
||||||
if (IsValidAddress(pPlayerStructRelated3))
|
if (IsValidAddress(pPlayerStructRelated3))
|
||||||
|
|
@ -380,7 +409,7 @@ namespace SekiroFpsUnlockAndMore
|
||||||
if (IsValidAddress(pPlayerStructRelated5))
|
if (IsValidAddress(pPlayerStructRelated5))
|
||||||
{
|
{
|
||||||
_offset_timescale_player = Read<Int64>(_gameAccessHwndStatic, pPlayerStructRelated5) + GameData.PATTERN_TIMESCALE_POINTER5_OFFSET;
|
_offset_timescale_player = Read<Int64>(_gameAccessHwndStatic, pPlayerStructRelated5) + GameData.PATTERN_TIMESCALE_POINTER5_OFFSET;
|
||||||
Debug.WriteLine("timescale found at: 0x" + _offset_timescale_player.ToString("X"));
|
Debug.WriteLine("fTimescalePlayer found at: 0x" + _offset_timescale_player.ToString("X"));
|
||||||
if (!IsValidAddress(_offset_timescale_player))
|
if (!IsValidAddress(_offset_timescale_player))
|
||||||
{
|
{
|
||||||
_offset_timescale_player = 0x0;
|
_offset_timescale_player = 0x0;
|
||||||
|
|
@ -390,7 +419,7 @@ namespace SekiroFpsUnlockAndMore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_offset_timescale_player == 0x0)
|
if (_offset_timescale_player_pointer_start == 0x0)
|
||||||
{
|
{
|
||||||
UpdateStatus("Playerscale not found...", Brushes.Red);
|
UpdateStatus("Playerscale not found...", Brushes.Red);
|
||||||
LogToFile("Playerscale not found...");
|
LogToFile("Playerscale not found...");
|
||||||
|
|
@ -404,6 +433,35 @@ namespace SekiroFpsUnlockAndMore
|
||||||
return Task.FromResult(true);
|
return Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read and refresh all offsets that can change on quick travel or save game loading.
|
||||||
|
/// </summary>
|
||||||
|
private void ReadIngameOffsets()
|
||||||
|
{
|
||||||
|
bool valid = false;
|
||||||
|
if (_offset_timescale_player_pointer_start > 0)
|
||||||
|
{
|
||||||
|
long pPlayerStructRelated3 = Read<Int64>(_gameAccessHwndStatic, _offset_timescale_player_pointer_start) + GameData.PATTERN_TIMESCALE_POINTER2_OFFSET;
|
||||||
|
if (IsValidAddress(pPlayerStructRelated3))
|
||||||
|
{
|
||||||
|
long pPlayerStructRelated4 = Read<Int64>(_gameAccessHwndStatic, pPlayerStructRelated3) + GameData.PATTERN_TIMESCALE_POINTER3_OFFSET;
|
||||||
|
if (IsValidAddress(pPlayerStructRelated4))
|
||||||
|
{
|
||||||
|
long pPlayerStructRelated5 = Read<Int64>(_gameAccessHwndStatic, pPlayerStructRelated4) + GameData.PATTERN_TIMESCALE_POINTER4_OFFSET;
|
||||||
|
if (IsValidAddress(pPlayerStructRelated5))
|
||||||
|
{
|
||||||
|
_offset_timescale_player = Read<Int64>(_gameAccessHwndStatic, pPlayerStructRelated5) + GameData.PATTERN_TIMESCALE_POINTER5_OFFSET;
|
||||||
|
if (IsValidAddress(_offset_timescale_player))
|
||||||
|
{
|
||||||
|
valid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!valid) _offset_timescale_player = 0x0;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether everything is ready for patching.
|
/// Determines whether everything is ready for patching.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -426,6 +484,8 @@ namespace SekiroFpsUnlockAndMore
|
||||||
_offset_resolution_default = 0x0;
|
_offset_resolution_default = 0x0;
|
||||||
_offset_resolution_scaling_fix = 0x0;
|
_offset_resolution_scaling_fix = 0x0;
|
||||||
_offset_fovsetting = 0x0;
|
_offset_fovsetting = 0x0;
|
||||||
|
_offset_player_deaths = 0x0;
|
||||||
|
_offset_total_kills = 0x0;
|
||||||
_offset_timescale = 0x0;
|
_offset_timescale = 0x0;
|
||||||
_offset_timescale_player = 0x0;
|
_offset_timescale_player = 0x0;
|
||||||
this.cbFramelock.IsEnabled = true;
|
this.cbFramelock.IsEnabled = true;
|
||||||
|
|
@ -649,7 +709,17 @@ namespace SekiroFpsUnlockAndMore
|
||||||
/// <param name="showStatus">Determines if status should be updated from within method, default is true.</param>
|
/// <param name="showStatus">Determines if status should be updated from within method, default is true.</param>
|
||||||
private bool PatchPlayerSpeed(bool showStatus = true)
|
private bool PatchPlayerSpeed(bool showStatus = true)
|
||||||
{
|
{
|
||||||
if (!this.cbPlayerSpeed.IsEnabled || _offset_timescale_player == 0x0 || !CanPatchGame()) return false;
|
if (!this.cbPlayerSpeed.IsEnabled || !CanPatchGame()) return false;
|
||||||
|
if (this.cbPlayerSpeed.IsChecked == true)
|
||||||
|
{
|
||||||
|
if (_offset_timescale_player_pointer_start > 0x0) ReadIngameOffsets();
|
||||||
|
if (_offset_timescale_player == 0x0)
|
||||||
|
{
|
||||||
|
this.cbPlayerSpeed.IsChecked = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_offset_timescale_player == 0x0) return false;
|
||||||
if (this.cbPlayerSpeed.IsChecked == true)
|
if (this.cbPlayerSpeed.IsChecked == true)
|
||||||
{
|
{
|
||||||
bool isNumber = Int32.TryParse(this.tbPlayerSpeed.Text, out int playerSpeed);
|
bool isNumber = Int32.TryParse(this.tbPlayerSpeed.Text, out int playerSpeed);
|
||||||
|
|
@ -667,11 +737,13 @@ namespace SekiroFpsUnlockAndMore
|
||||||
if (timeScalePlayer < 0.01f)
|
if (timeScalePlayer < 0.01f)
|
||||||
timeScalePlayer = 0.00001f;
|
timeScalePlayer = 0.00001f;
|
||||||
WriteBytes(_gameAccessHwndStatic, _offset_timescale_player, BitConverter.GetBytes(timeScalePlayer));
|
WriteBytes(_gameAccessHwndStatic, _offset_timescale_player, BitConverter.GetBytes(timeScalePlayer));
|
||||||
|
if (!_dispatcherTimerFreezeMem.IsEnabled) _dispatcherTimerFreezeMem.Start();
|
||||||
}
|
}
|
||||||
else if (this.cbPlayerSpeed.IsChecked == false)
|
else if (this.cbPlayerSpeed.IsChecked == false)
|
||||||
{
|
{
|
||||||
WriteBytes(_gameAccessHwndStatic, _offset_timescale_player, BitConverter.GetBytes(1.0f));
|
WriteBytes(_gameAccessHwndStatic, _offset_timescale_player, BitConverter.GetBytes(1.0f));
|
||||||
if (showStatus) UpdateStatus(DateTime.Now.ToString("HH:mm:ss") + " Game unpatched!", Brushes.White);
|
if (showStatus) UpdateStatus(DateTime.Now.ToString("HH:mm:ss") + " Game unpatched!", Brushes.White);
|
||||||
|
_dispatcherTimerFreezeMem.Stop();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -701,27 +773,50 @@ namespace SekiroFpsUnlockAndMore
|
||||||
UpdateStatus(DateTime.Now.ToString("HH:mm:ss") + " Game unpatched!", Brushes.White);
|
UpdateStatus(DateTime.Now.ToString("HH:mm:ss") + " Game unpatched!", Brushes.White);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads some hidden stats and outputs them to text files. Use to display counters on Twitch stream or just look at them and get disspointed
|
/// Freeze values in memory that can't be patched to require no freezing easily.
|
||||||
/// </summary
|
/// </summary>
|
||||||
private void StatReadTimer(object sender, EventArgs e)
|
private void FreezeMemory(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (_gameAccessHwndStatic == IntPtr.Zero) return;
|
if (!this.cbPlayerSpeed.IsEnabled || this.cbPlayerSpeed.IsChecked != true)
|
||||||
if (IsValidAddress(_pointer_player_deaths))
|
{
|
||||||
{
|
_dispatcherTimerFreezeMem.Stop();
|
||||||
int playerDeaths = Read<Int32>(_gameAccessHwndStatic, _pointer_player_deaths);
|
return;
|
||||||
_statViewModel.Deaths = playerDeaths;
|
}
|
||||||
if (_statLoggingEnabled) LogStatFile(deathCounterFilename, playerDeaths.ToString());
|
if (_offset_timescale_player_pointer_start == 0x0 || !CanPatchGame()) return;
|
||||||
|
if (_offset_timescale_player_pointer_start > 0x0) ReadIngameOffsets();
|
||||||
|
if (_offset_timescale_player == 0x0) return;
|
||||||
|
|
||||||
if (IsValidAddress(_pointer_total_kills))
|
bool isNumber = Int32.TryParse(this.tbPlayerSpeed.Text, out int playerSpeed);
|
||||||
{
|
if (playerSpeed < 0 || !isNumber)
|
||||||
int totalKills = Read<Int32>(_gameAccessHwndStatic, _pointer_total_kills);
|
{
|
||||||
totalKills -= playerDeaths; //Since this value seems to track every death, including the player
|
this.tbPlayerSpeed.Text = "100";
|
||||||
_statViewModel.Kills = totalKills;
|
playerSpeed = 100;
|
||||||
if (_statLoggingEnabled) LogStatFile(totalKillsFilename, totalKills.ToString());
|
}
|
||||||
}
|
else if (playerSpeed >= 999)
|
||||||
}
|
{
|
||||||
}
|
this.tbPlayerSpeed.Text = "999";
|
||||||
|
playerSpeed = 1000;
|
||||||
|
}
|
||||||
|
float timeScalePlayer = playerSpeed / 100f;
|
||||||
|
if (timeScalePlayer < 0.01f) timeScalePlayer = 0.00001f;
|
||||||
|
WriteBytes(_gameAccessHwndStatic, _offset_timescale_player, BitConverter.GetBytes(timeScalePlayer));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads some hidden stats and outputs them to text files and status bar. Use to display counters on Twitch stream or just look at them and get disappointed.
|
||||||
|
/// </summary>
|
||||||
|
private void StatReadTimer(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (_gameAccessHwndStatic == IntPtr.Zero || _offset_player_deaths == 0x0 || _offset_total_kills == 0x0) return;
|
||||||
|
int playerDeaths = Read<Int32>(_gameAccessHwndStatic, _offset_player_deaths);
|
||||||
|
_statusViewModel.Deaths = playerDeaths;
|
||||||
|
if (_statLoggingEnabled) LogStatsFile(_deathCounterPath, playerDeaths.ToString());
|
||||||
|
int totalKills = Read<Int32>(_gameAccessHwndStatic, _offset_total_kills);
|
||||||
|
totalKills -= playerDeaths; // Since this value seems to track every death, including the player
|
||||||
|
_statusViewModel.Kills = totalKills;
|
||||||
|
if (_statLoggingEnabled) LogStatsFile(_killCounterPath, totalKills.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the hexadecimal representation of an IEEE-754 floating point number
|
/// Returns the hexadecimal representation of an IEEE-754 floating point number
|
||||||
|
|
@ -917,22 +1012,22 @@ namespace SekiroFpsUnlockAndMore
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Logs stat values to separate files for the use in OBS
|
/// Logs stats values to separate files for use in OBS or similar.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="filename">File name</param>
|
/// <param name="filename">The filepath to the status file.</param>
|
||||||
/// <param name="msg">Just a single stat value</param>
|
/// <param name="msg">The value to write to the text file.</param>
|
||||||
private void LogStatFile(string filename, string value)
|
private void LogStatsFile(string filename, string msg)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (StreamWriter writer = new StreamWriter(filename, false))
|
using (StreamWriter writer = new StreamWriter(filename, false))
|
||||||
{
|
{
|
||||||
writer.Write(value);
|
writer.Write(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
MessageBox.Show("Failed writing stat file: " + ex.Message, "Sekiro Fps Unlock And More");
|
MessageBox.Show("Failed writing stats file: " + ex.Message, "Sekiro Fps Unlock And More");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -995,6 +1090,11 @@ namespace SekiroFpsUnlockAndMore
|
||||||
PatchWindow();
|
PatchWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CbStatChanged(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
_statLoggingEnabled = cbLogStats.IsChecked == true;
|
||||||
|
}
|
||||||
|
|
||||||
private void CbGameSpeed_Check_Handler(object sender, RoutedEventArgs e)
|
private void CbGameSpeed_Check_Handler(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
PatchGameSpeed();
|
PatchGameSpeed();
|
||||||
|
|
@ -1073,11 +1173,6 @@ namespace SekiroFpsUnlockAndMore
|
||||||
if (this.cbPlayerSpeed.IsChecked == true) PatchPlayerSpeed();
|
if (this.cbPlayerSpeed.IsChecked == true) PatchPlayerSpeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CbStatChanged(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
_statLoggingEnabled = (bool)cbLogStats.IsChecked;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void BPatch_Click(object sender, RoutedEventArgs e)
|
private void BPatch_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
PatchGame();
|
PatchGame();
|
||||||
|
|
|
||||||
|
|
@ -21,5 +21,5 @@ using System.Runtime.InteropServices;
|
||||||
ResourceDictionaryLocation.SourceAssembly
|
ResourceDictionaryLocation.SourceAssembly
|
||||||
)]
|
)]
|
||||||
|
|
||||||
[assembly: AssemblyVersion("1.1.0.1")]
|
[assembly: AssemblyVersion("1.1.1.0")]
|
||||||
[assembly: AssemblyFileVersion("1.1.0.1")]
|
[assembly: AssemblyFileVersion("1.1.1.0")]
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</ApplicationDefinition>
|
</ApplicationDefinition>
|
||||||
<Compile Include="SettingsService.cs" />
|
<Compile Include="SettingsService.cs" />
|
||||||
<Compile Include="StatViewModel.cs" />
|
<Compile Include="StatusViewModel.cs" />
|
||||||
<Page Include="MainWindow.xaml">
|
<Page Include="MainWindow.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,8 @@ namespace SekiroFpsUnlockAndMore
|
||||||
{
|
{
|
||||||
[XmlRoot("SekiroFpsUnlockAndMore")]
|
[XmlRoot("SekiroFpsUnlockAndMore")]
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class SettingsService
|
public class ApplicationSettings
|
||||||
{
|
{
|
||||||
private readonly string sConfigurationPath = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + @"\config.xml";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Read and store settings here.
|
|
||||||
/// </summary>
|
|
||||||
public SettingsService settings;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings definition
|
* Settings definition
|
||||||
*/
|
*/
|
||||||
|
|
@ -39,6 +31,8 @@ namespace SekiroFpsUnlockAndMore
|
||||||
[XmlElement]
|
[XmlElement]
|
||||||
public bool cbBorderlessStretch { get; set; }
|
public bool cbBorderlessStretch { get; set; }
|
||||||
[XmlElement]
|
[XmlElement]
|
||||||
|
public bool cbLogStats { get; set; }
|
||||||
|
[XmlElement]
|
||||||
public bool exGameMods { get; set; }
|
public bool exGameMods { get; set; }
|
||||||
[XmlElement]
|
[XmlElement]
|
||||||
public bool cbGameSpeed { get; set; }
|
public bool cbGameSpeed { get; set; }
|
||||||
|
|
@ -48,10 +42,16 @@ namespace SekiroFpsUnlockAndMore
|
||||||
public bool cbPlayerSpeed { get; set; }
|
public bool cbPlayerSpeed { get; set; }
|
||||||
[XmlElement]
|
[XmlElement]
|
||||||
public int tbPlayerSpeed { get; set; }
|
public int tbPlayerSpeed { get; set; }
|
||||||
[XmlElement]
|
}
|
||||||
public bool cbLogStats { get; set; }
|
|
||||||
|
|
||||||
public SettingsService() { }
|
public class SettingsService
|
||||||
|
{
|
||||||
|
private readonly string _sConfigurationPath = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + @"\config.xml";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read and store settings here.
|
||||||
|
/// </summary>
|
||||||
|
public ApplicationSettings ApplicationSettings;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a settings provider to load and save settings.
|
/// Create a settings provider to load and save settings.
|
||||||
|
|
@ -59,11 +59,8 @@ namespace SekiroFpsUnlockAndMore
|
||||||
/// <param name="settingsFilePath">The file path to the settings file.</param>
|
/// <param name="settingsFilePath">The file path to the settings file.</param>
|
||||||
public SettingsService(string settingsFilePath = null)
|
public SettingsService(string settingsFilePath = null)
|
||||||
{
|
{
|
||||||
if (settingsFilePath != null)
|
if (settingsFilePath != null) _sConfigurationPath = settingsFilePath;
|
||||||
{
|
ApplicationSettings = new ApplicationSettings();
|
||||||
sConfigurationPath = settingsFilePath;
|
|
||||||
settings = new SettingsService();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -72,14 +69,14 @@ namespace SekiroFpsUnlockAndMore
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
internal bool Load()
|
internal bool Load()
|
||||||
{
|
{
|
||||||
if (!File.Exists(sConfigurationPath)) return false;
|
if (!File.Exists(_sConfigurationPath)) return false;
|
||||||
|
|
||||||
XmlSerializer xmlSerializer = new XmlSerializer(typeof(SettingsService));
|
XmlSerializer xmlSerializer = new XmlSerializer(typeof(ApplicationSettings));
|
||||||
using (StreamReader streamReader = new StreamReader(sConfigurationPath))
|
using (StreamReader streamReader = new StreamReader(_sConfigurationPath))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
settings = (SettingsService)xmlSerializer.Deserialize(streamReader);
|
ApplicationSettings = (ApplicationSettings)xmlSerializer.Deserialize(streamReader);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
@ -95,12 +92,12 @@ namespace SekiroFpsUnlockAndMore
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal void Save()
|
internal void Save()
|
||||||
{
|
{
|
||||||
XmlSerializer xmlSerializer = new XmlSerializer(typeof(SettingsService));
|
XmlSerializer xmlSerializer = new XmlSerializer(typeof(ApplicationSettings));
|
||||||
using (StreamWriter streamReader = new StreamWriter(sConfigurationPath))
|
using (StreamWriter streamReader = new StreamWriter(_sConfigurationPath))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
xmlSerializer.Serialize(streamReader, settings);
|
xmlSerializer.Serialize(streamReader, ApplicationSettings);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,11 @@
|
||||||
using System;
|
using System.ComponentModel;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace SekiroFpsUnlockAndMore
|
namespace SekiroFpsUnlockAndMore
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For Status bar display
|
/// For Status bar display
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class StatViewModel : INotifyPropertyChanged
|
class StatusViewModel : INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
private int _deaths = 0;
|
private int _deaths = 0;
|
||||||
public int Deaths
|
public int Deaths
|
||||||
Loading…
Add table
Add a link
Reference in a new issue