diff --git a/README.md b/README.md index f19377f..4fea028 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,35 @@ # Sekiro FPS Unlocker and more -A small utility to remove frame rate limit, add custom resolutions with 21/9 widescreen support, increase field of view (FOV) (credits to jackfuste) and borderless window mode for [Sekiro: Shadows Die Twice](https://www.sekirothegame.com/) written in C#. -Patches games memory while running, does not modify any game files. works with every game version (legit steam & oh-not-so-legit), should work with all future updates. +A small utility to remove frame rate limit, add custom resolutions with 21/9 widescreen support, change field of view (FOV), borderless window mode and various game modifications for [Sekiro: Shadows Die Twice](https://www.sekirothegame.com/) written in C#. +Patches games memory while running, does not modify any game files. Wrks with every game version (legit steam & oh-not-so-legit), should work with all future updates. Also available [Nexus Mods](https://www.nexusmods.com/sekiro/mods/13/). ## Download **[Get the latest release here](https://github.com/uberhalit/SekiroFpsUnlockAndMore/releases)** ### See it in action: -[![Video preview](https://camo.githubusercontent.com/99b882828d8bb814a126282d67f0394460259df0/68747470733a2f2f692e696d6775722e636f6d2f4b4e4674454d772e706e67)](https://giant.gfycat.com/DevotedArtisticKingsnake.webm) +[![Video preview](https://camo.githubusercontent.com/784859be34b212aeebd5bac1baf47b9bffdd36db/68747470733a2f2f692e696d6775722e636f6d2f4d4d724f62487a2e706e67)](https://giant.gfycat.com/PhonyReadyGreatargus.webm) ## Features * does not modify any game files, RAM patches only * works with legit, unmodified steam version as well as with unpacked, not-so-legit versions * 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 -* 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) +* unlock frame rate (remove FPS limit) by setting a new custom limit +* add a custom resolution, 21/9 widescreen supported (will overwrite the default 1920x1080 / 1280x720 resolution, HUD limited to 16/9) +* increase and decrease field of view (FOV) * set the game to borderless window mode +* game modifications + * global game speed modifier + * player speed modifier * automatically patch game on startup * seamlessly switch between windowed, borderless and borderless fullscreen * hotkey for patching while in (borderless) window mode ## Usage +The following graphical guide has to be done if you want to unlock the game's framerate or play on a highter refresh rate in fullscreen. If you do not wish to use that feature you can scoll down further to the guides on all other features. 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 use any of its features**. + 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 @@ -35,20 +40,31 @@ The game enforces VSYNC and forces 60 Hz in fullscreen even on 144 Hz monitors s 3. **Make sure your monitor is set to the highest Refresh rate possible:** 4. [![Make sure your monitor is set to the highest Refresh rate possible](https://camo.githubusercontent.com/331eb420bee67f4e57d7e46601bfd51f462de68f/68747470733a2f2f692e696d6775722e636f6d2f625667767155372e706e67)](#) 5. Navigate to `3D Settings -> Manage 3D settings -> Program Settings` -6. Select Sekiro from the dropdown or add it manually if it's missing: `Add -> Select Sekiro -> Add Selected Program` -7. **Set `Vertical sync` to `Off`** -8. **Set `Preferred refresh rate` to `Highest available`** -9. [![Vertical sync Off and Preferred refresh rate Highest available](https://camo.githubusercontent.com/bae53a6199d5a6fc2b8e0c4f0bfab322ebecd648/68747470733a2f2f692e696d6775722e636f6d2f35446f526d55452e706e67)](#) -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 +6. **Check if you already have a Sekiro Profile in dropdown and if so DELETE IT** +7. Manually add Sekiro into a clean new profile: `Add -> Browse ->` Navigate to `sekiro.exe` and select it +8. **Make sure that there is a file path to Sekiro and that it is indeed correct and you haven't loaded a premade (empty) profile** +9. **Set `Preferred refresh rate` to `Highest available`** +10. **Set `Vertical sync` to `Off`** +11. [![Preferred refresh rate Highest available and Vertical sync Off](https://camo.githubusercontent.com/209678e46eb63c150abf394894ef24a75bb664d0/68747470733a2f2f692e696d6775722e636f6d2f56634d754f33362e706e67)](#) +12. Hit apply and close Nvidia Control Panel +13. Start `Sekiro FPS Unlocker and more` and set FPS lock to your desired framerate +14. Start the game and use fullscreen or borderless window mode +15. 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. [![Vertical sync Off and Preferred refresh rate Highest available](https://camo.githubusercontent.com/560355d19113ad3e6782c75cae992e7c91a4e0fd/68747470733a2f2f692e696d6775722e636f6d2f4657424b57536e2e706e67)](#) -5. Hit `Apply changes` and you are good to go +1. **Delete the Sekiro Profile in Nvidia Control panel as otherwise it will block all settings from Profile Inspector** +2. Hit apply and close the Nvidia Control panel +3. Download and extract the [Nvidia Inspector](https://www.techpowerup.com/download/nvidia-inspector/) +4. Start the Nvidia Profile Inspector +5. **Check if there already is a profile for Sekiro and if so DELETE IT using the red 'X' button** +6. Press the yellow start icon in the menu bar to create a new Profile (1) +7. [![Vertical sync Off and Preferred refresh rate Highest available](https://camo.githubusercontent.com/531be3614b0742e9065f8c2a19df7e31afcdc7ed/68747470733a2f2f692e696d6775722e636f6d2f6f75664a7239632e706e67)](#) +8. Name it `Sekiro` and select it in dropdown +9. Press the blue window icon with the plus symbol to add an application to this profile(2) +10. Change file type to `Application Absolute Path`, navigate to your `sekiro.exe` and select it +11. [![Application Absolute Path](https://camo.githubusercontent.com/0bb8ace024658dfcb31c5f3347df1505854819ec/68747470733a2f2f692e696d6775722e636f6d2f545669495357562e706e67)](#) +12. Make sure that the file path to the game is correct (3) +13. Under `2 - Sync and Refresh` set `Prefered Refreshrate` to `Highest available` and `Vertical Sync` to `Force off` (4) +14. Hit `Apply changes` and you are good to go (5) ### Follow these steps on AMD: 1. Right click on Desktop -> `Display settings` @@ -64,34 +80,33 @@ The game enforces VSYNC and forces 60 Hz in fullscreen even on 144 Hz monitors s 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: +1. Try setting `Wait for Vertical Refresh` to `Always off` instead: 2. [![Wait for Vertical Refresh Off](https://camo.githubusercontent.com/c06be2d7a7be65e379996eee66685209b276dcea/68747470733a2f2f692e696d6775722e636f6d2f417a7a716545332e706e67)](#) 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): 1. Under Nvidia Control Panel navigate to `3D Settings -> Manage 3D settings -> Program Settings -> Sekiro` 2. Set `Monitor Technology` to `G-SYNC` -3. Make sure that `Preferred refresh rate` is still set to `Highest available` -4. Make sure that `Vertical sync` is still set to `Off` +3. Set `Vertical sync` to `Off` again as enabling G-SYNC re-enables it +4. Make sure that `Preferred refresh rate` is still set to `Highest available` 5. [![Control Panel](https://camo.githubusercontent.com/b7b491c24020fd3eca41d857bd58b1c0c2ee037f/68747470733a2f2f692e696d6775722e636f6d2f614a41744444632e706e67)](#) -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**. +6. If you do not have `Preferred refresh rate` or `Vertical sync` see the guide above on how to use the Nvidia Profile Inspector +7. Don't forget to Apply and close Nvidia Control Panel +8. 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 +9. Start `Sekiro FPS Unlocker and more` and set FPS lock to your monitors refresh rate +10. Start the game and set it to Fullscreen +11. Enjoy perfectly tearing free variable high refresh rates without VSYNC ### To add a custom resolution 1. Start the game 2. Start `Sekiro FPS Unlocker and more`, set you desired resolution and enable it by ticking the check box -3. Set your custom resolution in the graphical settings, be aware that the ingame HUD will be limited to 16/9 +3. Set your custom resolution in the graphical settings +4. Be aware that your monitor has to natively support this resolution and the ingame HUD will be limited to 16/9 ### To use the FOV changer 1. Start the game 2. Load up your save game 3. Start `Sekiro FPS Unlocker and more`, set you desired FOV value and enable it by ticking the check box -4. If you reload a save FOV will reset so patch game manually again ### To use borderless window mode: 1. Start the game @@ -100,19 +115,25 @@ The graphic setup has to be done only once but as the patcher hot-patches the me 4. Start `Sekiro FPS Unlocker and more` and enable borderless window mode 5. If you want fullscreen borderless enable `Fullscreen stretch` +### To use any of the game modifications +1. Start the game +2. Load up your save game +3. Start `Sekiro FPS Unlocker and more` and expand `Game modifications` +4. Set your desired values and then tick the checkbox you'd wish to enable + ## Preview -[![Sekiro FPS Unlocker and more](https://camo.githubusercontent.com/3e7ebacca20a13e6325695fb870e7c2c97e7c2d4/68747470733a2f2f692e696d6775722e636f6d2f667445436150332e706e67)](#) +[![Sekiro FPS Unlocker and more](https://camo.githubusercontent.com/275b23b532ec7dcfc18a83d0ba9e8ae1f20b9e20/68747470733a2f2f692e696d6775722e636f6d2f615179334869392e706e67)](#) ### Unlocked framerate -[![Sekiro FPS Unlocker and more](https://camo.githubusercontent.com/cd23c8ff94e7cd777476d01d1be608df26fab26a/68747470733a2f2f692e696d6775722e636f6d2f766632393152532e706e67)](#) +[![Sekiro FPS Unlocker and more](https://camo.githubusercontent.com/2c22eea5a618066716cdd1d45274720814592172/68747470733a2f2f692e696d6775722e636f6d2f534e636b6445732e706e67)](#) -### Increased FOV and borderless window: -[![FOV increase on the fly and borderless window](https://camo.githubusercontent.com/3e446f64e61406027fbd73cf248336cafd7c6ff1/68747470733a2f2f692e696d6775722e636f6d2f5248544b4e6a522e706e67)](#) +### Increased FOV borderless window and 90% game speed: +[![FOV increase on the fly and borderless window](https://camo.githubusercontent.com/fbca15acc147937ccc1b98a9fc0850c06cff4476/68747470733a2f2f692e696d6775722e636f6d2f536e6f394e39302e706e67)](#) ## Prerequisites -* .NET Framework 4.0 +* .NET Framework 4.5 * administrative privileges (for patching) * 64 bit OS @@ -130,7 +151,8 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file ## Credits -* jackfuste for FOV findings and running speed fix +* Zullie the Witch#7202 for game speed and player speed modifier offsets +* jackfuste for FOV offset and basic running speed fix * TyChii93#2376 for AMD and widescreen testing * [Darius Dan](http://www.dariusdan.com) for the icon @@ -139,12 +161,19 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file * the game has forced VSYNC so unlocking the frame rate when your monitor has 60Hz will do nothing. You'll have to disable VSYNC in Nvidia Control Panel or AMD Radeon Settings first * in fullscreen the game forces the monitor to 60 Hz so you'll have to handle this with driver override too, see Usage * your monitor has to support your custom resolution otherwise it won't show up correctly -* due to how the game renders altering FOV will not move the HUD -* the HUD is limited to 16/9 even on 21/9 resolutions +* due to how the game renders altering HUD is limited to 16/9 even on 21/9 resolutions * the hotkey won't work if the game runs in exclusive, true fullscreen mode ## Version History +* v1.1.0 (2019-03-30) + * Added game speed modifier (thanks to Zullie the Witch#7202 for offset) + * Added player speed modifier (thanks to Zullie the Witch#7202 for offset) + * Settings are saved and loaded from config file now + * FOV will now stick even after save game load + * Fixed a potential issue with unlimited frame rate unlock + * Fixed a potential issue when user tried to enable borderless while in minimized fullscreen + * Improved initial load time til game is patchable * v1.0.2 (2019-03-26) * Added option to reduce FOV (request) * Added option to stretch borderless window to fullscreen regardless of window resolution diff --git a/SekiroFpsUnlockAndMore/App.config b/SekiroFpsUnlockAndMore/App.config index 74ade9d..d1428ad 100644 --- a/SekiroFpsUnlockAndMore/App.config +++ b/SekiroFpsUnlockAndMore/App.config @@ -1,6 +1,6 @@ - + diff --git a/SekiroFpsUnlockAndMore/GameData.cs b/SekiroFpsUnlockAndMore/GameData.cs new file mode 100644 index 0000000..83d4a98 --- /dev/null +++ b/SekiroFpsUnlockAndMore/GameData.cs @@ -0,0 +1,187 @@ +using System; +using System.Linq; +using System.Collections.Generic; + +namespace SekiroFpsUnlockAndMore +{ + internal class GameData + { + internal const string PROCESS_NAME = "sekiro"; + internal const string PROCESS_TITLE = "Sekiro"; + internal const string PROCESS_DESCRIPTION = "Shadows Die Twice"; + + + /** + fFrameTick determines default frame rate limit in seconds + 000000014116168D | C743 18 8988883C | mov dword ptr ds:[rbx+18],3C888889 | fFrameTick + 0000000141161694 | 4C:89AB 70020000 | mov qword ptr ds:[rbx+270],r13 | + */ + internal const string PATTERN_FRAMELOCK = "88 88 3C 4C 89 AB"; // 88 88 3C 4C 89 AB // first byte (last in mem) can can be 88/90 instead of 89 due to precision loss on floating point numbers + internal const string PATTERN_FRAMELOCK_MASK = "xxxxxx"; // mask for frame rate limiter signature scanning + internal const int PATTERN_FRAMELOCK_OFFSET = -1; // offset to byte array from found position + internal const string PATTERN_FRAMELOCK_FUZZY = "C7 43 00 00 00 00 00 4C 89 AB"; // C7 43 ?? ?? ?? ?? ?? 4C 89 AB + internal const string PATTERN_FRAMELOCK_FUZZY_MASK = "xx?????xxx"; + internal const int PATTERN_FRAMELOCK_FUZZY_OFFSET = 3; + + + /** + Reference pointer pFrametimeRunningSpeed to speed table entry that gets used in calculations. Add or remove multiplications of 4bytes to pFrametimeRunningSpeed address to use a higher or lower fFrametimeCriticalRunningSpeed from table + fFrametimeCriticalRunningSpeed should be roughly half the frame rate: 30 @ 60FPS limit, 50 @ 100FPS limit... + 00000001407D4E08 | F3:0F5905 90309202 | mulss xmm0,dword ptr ds:[1430F7EA0] | pFrametimeRunningSpeed->fFrametimeCriticalRunningSpeed + */ + internal const string PATTERN_FRAMELOCK_SPEED_FIX = "F3 0F 59 05 00 30 92 02"; // F3 0F 59 05 ?? 30 92 02 | 0F 51 C2 F3 0F 59 05 ?? ?? ?? ?? 0F 2F F8 + internal const string PATTERN_FRAMELOCK_SPEED_FIX_MASK = "xxxx?xxx"; + internal const int PATTERN_FRAMELOCK_SPEED_FIX_OFFSET = 4; + /** + 00000001430F7E10 + Key: Patch to pFrametimeRunningSpeed last byte + Value: Value resolve in float table from pFrametimeRunningSpeed->fFrametimeCriticalRunningSpeed + Hardcoded cause lazy -> if anyone knows how the table is calculated then tell me and I'll buy you a beer + */ + internal static Dictionary PATCH_FRAMELOCK_SPEED_FIX_MATRIX = new Dictionary + { + { new byte[1] {0x68}, 15f }, + { new byte[1] {0x6C}, 16f }, + { new byte[1] {0x70}, 16.6667f }, + { new byte[1] {0x74}, 18f }, + { new byte[1] {0x78}, 18.6875f }, + { new byte[1] {0x7C}, 18.8516f }, + { new byte[1] {0x80}, 20f }, + { new byte[1] {0x84}, 24f }, + { new byte[1] {0x88}, 25f }, + { new byte[1] {0x8C}, 27.5f }, + { new byte[1] {0x90}, 30f }, + { new byte[1] {0x94}, 32f }, + { new byte[1] {0x98}, 38.5f }, + { new byte[1] {0x9C}, 40f }, + { new byte[1] {0xA0}, 48f }, + { new byte[1] {0xA4}, 49.5f }, + { new byte[1] {0xA8}, 50f }, + { new byte[1] {0xAC}, 57.2958f }, + { new byte[1] {0xB0}, 60f }, + { new byte[1] {0xB4}, 64f }, + { new byte[1] {0xB8}, 66.75f }, + { new byte[1] {0xBC}, 67f }, + { new byte[1] {0xC0}, 78.8438f }, + { new byte[1] {0xC4}, 80f }, + { new byte[1] {0xC8}, 84f }, + { new byte[1] {0xCC}, 90f }, + { new byte[1] {0xD0}, 93.8f }, + { new byte[1] {0xD4}, 100f }, + { new byte[1] {0xD8}, 120f }, + { new byte[1] {0xDC}, 127f }, + { new byte[1] {0xE0}, 128f }, + { new byte[1] {0xE4}, 130f }, + { new byte[1] {0xE8}, 140f }, + { new byte[1] {0xEC}, 144f }, + { new byte[1] {0xF0}, 150f } + }; + internal static byte[] PATCH_FRAMELOCK_SPEED_FIX_DISABLE = new byte[1] { 0x90 }; // 30f + + /// + /// Finds closest valid speed fix value for a frame rate limit. + /// + /// The set frame rate limit. + /// The byte patch of the closest speed fix. + internal static byte[] FindSpeedFixForRefreshRate(int frameLimit) + { + float idealSpeedFix = frameLimit / 2f; + KeyValuePair closestSpeedFix = new KeyValuePair(PATCH_FRAMELOCK_SPEED_FIX_DISABLE, 30f); + foreach (var speedFix in PATCH_FRAMELOCK_SPEED_FIX_MATRIX.OrderBy(kvp => kvp.Value)) + { + if (Math.Abs(idealSpeedFix - speedFix.Value) < Math.Abs(idealSpeedFix - closestSpeedFix.Value)) + closestSpeedFix = speedFix; + } + return closestSpeedFix.Key; + } + + + /** + Reference pointer pCurrentResolutionWidth to iInternalGameWidth (and iInternalGameHeight which is +4 bytes) + 000000014114AC85 | 0F57D2 | xorps xmm2,xmm2 | + 000000014114AC88 | 890D 92147D02 | mov dword ptr ds:[14391C120],ecx | pCurrentResolutionWidth->iInternalGameWidth + 000000014114AC8E | 0F57C9 | xorps xmm1,xmm1 | + 000000014114AC91 | 8915 8D147D02 | mov dword ptr ds:[14391C124],edx | pCurrentResolutionHeight->iInternalGameHeight + */ + internal const string PATTERN_RESOLUTION_POINTER = "0F 57 D2 89 0D 00 00 00 00 0F 57 C9"; // 0F 57 D2 89 0D ?? ?? ?? ?? 0F 57 C9 + internal const string PATTERN_RESOLUTION_POINTER_MASK = "xxxxx????xxx"; + internal const int PATTERN_RESOLUTION_POINTER_OFFSET = 3; + internal const int PATTERN_RESOLUTION_POINTER_INSTRUCTION_LENGTH = 6; + + + /** + DATA SECTION. All resolutions are listed in memory as width1 height1 width2 height2 ... + Overwrite an unused one with desired new one. Some glitches, 1920x1080 and 1280x720 works best + */ + internal const string PATTERN_RESOLUTION_DEFAULT = "80 07 00 00 38 04 00 00"; // 1920x1080 + internal const string PATTERN_RESOLUTION_DEFAULT_720 = "40 06 00 00 84 03 00 00"; // 1280x720 + internal const string PATTERN_RESOLUTION_DEFAULT_MASK = "xxxxxxxx"; + internal static byte[] PATCH_RESOLUTION_DEFAULT_DISABLE = new byte[8] { 0x80, 0x07, 0x00, 0x00, 0x38, 0x04, 0x00, 0x00 }; + internal static byte[] PATCH_RESOLUTION_DEFAULT_DISABLE_720 = new byte[8] { 0x40, 0x06, 0x00, 0x00, 0x84, 0x03, 0x00, 0x00 }; + + + /** + Conditional jump instruction that determines if 16/9 scaling for game is enforced or not, overwrite with non conditional JMP so widescreen won't get clinched + 000000014012967A | 74 47 | je sekiro.1401296C3 | conditional jump + 000000014012967C | 47:8B94C7 1C020000 | mov r10d,dword ptr ds:[r15+r8*8+21C] | start of long resolution scaling calculation method within jump + */ + internal const string PATTERN_RESOLUTION_SCALING_FIX = "47 47 8B 94 C7 1C 02 00 00"; // 47 47 8B 94 C7 1C 02 00 00 + internal const string PATTERN_RESOLUTION_SCALING_FIX_MASK = "xxxxxxxxx"; + internal const int PATTERN_RESOLUTION_SCALING_FIX_OFFSET = -1; + internal static byte[] PATCH_RESOLUTION_SCALING_FIX_ENABLE = new byte[1] { 0xEB }; // JMP + internal static byte[] PATCH_RESOLUTION_SCALING_FIX_DISABLE = new byte[1] { 0x74 }; // JE + + + /** + Reference pointer pFovTableEntry to FOV entry in game FOV table that gets used in FOV calculations. Overwrite pFovTableEntry address to use a higher or lower fFOV from table + 0000000140739548 | F3:0F1008 | movss xmm1,dword ptr ds:[rax] | + 000000014073954C | F3:0F590D 0CE79B02 | mulss xmm1,dword ptr ds:[1430F7C60] | pFovTableEntry->fFov + */ + // credits to 'jackfuste' for original offset + 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??xx"; + internal const int PATTERN_FOVSETTING_OFFSET = 8; + /** + + */ + internal static Dictionary PATCH_FOVSETTING_MATRIX = new Dictionary + { + { new byte[2] {0x00, 0xE7}, "- 50%" }, + { new byte[2] {0x04, 0xE7}, "- 10%" }, + { new byte[2] {0x10, 0xE7}, "+ 15%" }, + { new byte[2] {0x14, 0xE7}, "+ 40%" }, + { new byte[2] {0x18, 0xE7}, "+ 75%" }, + { new byte[2] {0x1C, 0xE7}, "+ 90%" } + }; + internal static byte[] PATCH_FOVSETTING_DISABLE = new byte[2] { 0x0C, 0xE7 }; // + 0% + + + /** + Reference pointer pTimeRelated to pTimescaleManager pointer, offset in struct to fTimescale which acts as a global speed scale for almost all ingame calculations + 0000000141149E87 | 48:8B05 3A24B402 | mov rax,qword ptr ds:[143C8C2C8] | pTimeRelated->[pTimescaleManager+0x360]->fTimescale + 0000000141149E8E | F3:0F1088 60030000 | movss xmm1,dword ptr ds:[rax+360] | offset from TimescaleManager->fTimescale + 0000000141149E96 | F3:0F5988 68020000 | mulss xmm1,dword ptr ds:[rax+268] | + */ + // credits to 'Zullie the Witch' for original offset + internal const string PATTERN_TIMESCALE = "48 8B 05 00 00 00 00 F3 0F 10 88 00 00 00 00 F3 0F"; // 48 8B 05 ?? ?? ?? ?? F3 0F 10 88 ?? ?? ?? ?? F3 0F + internal const string PATTERN_TIMESCALE_MASK = "xxx????xxxx????xx"; + internal const int PATTERN_TIMESCALE_INSTRUCTION_LENGTH = 7; + 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 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 + 00000001406BF1DE | 48:85DB | test rbx,rbx | + 00000001406BF1E1 | 74 3C | je sekiro.1406BF21F | + 00000001406BF1E3 | 8B17 | mov edx,dword ptr ds:[rdi] | + */ + // credits to 'Zullie the Witch' for original offset + internal const string PATTERN_TIMESCALE_PLAYER = "48 8B 1D 00 00 00 00 48 85 DB 74 3C 8B 17"; // 48 8B 1D ?? ?? ?? ?? 48 85 DB 74 3C 8B 17 + internal const string PATTERN_TIMESCALE_PLAYER_MASK = "xxx????xxxxxxx"; + internal const int PATTERN_TIMESCALE_PLAYER_INSTRUCTION_LENGTH = 7; + internal const int PATTERN_TIMESCALE_POINTER2_OFFSET = 0x88; + internal const int PATTERN_TIMESCALE_POINTER3_OFFSET = 0x1FF8; + internal const int PATTERN_TIMESCALE_POINTER4_OFFSET = 0x28; + internal const int PATTERN_TIMESCALE_POINTER5_OFFSET = 0xD00; + } +} diff --git a/SekiroFpsUnlockAndMore/MainWindow.xaml b/SekiroFpsUnlockAndMore/MainWindow.xaml index fa0ab7b..6b6ed6a 100644 --- a/SekiroFpsUnlockAndMore/MainWindow.xaml +++ b/SekiroFpsUnlockAndMore/MainWindow.xaml @@ -5,25 +5,64 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:SekiroFpsUnlockAndMore" mc:Ignorable="d" - Title="Sekiro FPS Unlocker and more v1.0.2" Height="Auto" SizeToContent="WidthAndHeight" Width="Auto" ResizeMode="CanMinimize" Loaded="Window_Loaded" Closing="Window_Closing"> + Title="Sekiro FPS Unlocker and more v1.1.0" Width="Auto" Height="Auto" SizeToContent="WidthAndHeight" ResizeMode="CanMinimize" Loaded="Window_Loaded" Closing="Window_Closing"> - - - - -