├── .gitattributes
├── .gitignore
├── Bioshock Physics Unlocker.sln
├── Bioshock Physics Unlocker
├── Bioshock Physics Unlocker.vcxproj
├── Bioshock Physics Unlocker.vcxproj.filters
└── main.cpp
├── LICENSE.md
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | build/
21 | bld/
22 | [Bb]in/
23 | [Oo]bj/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opensdf
80 | *.sdf
81 | *.cachefile
82 |
83 | # Visual Studio profiler
84 | *.psess
85 | *.vsp
86 | *.vspx
87 | *.sap
88 |
89 | # TFS 2012 Local Workspace
90 | $tf/
91 |
92 | # Guidance Automation Toolkit
93 | *.gpState
94 |
95 | # ReSharper is a .NET coding add-in
96 | _ReSharper*/
97 | *.[Rr]e[Ss]harper
98 | *.DotSettings.user
99 |
100 | # JustCode is a .NET coding add-in
101 | .JustCode
102 |
103 | # TeamCity is a build add-in
104 | _TeamCity*
105 |
106 | # DotCover is a Code Coverage Tool
107 | *.dotCover
108 |
109 | # NCrunch
110 | _NCrunch_*
111 | .*crunch*.local.xml
112 | nCrunchTemp_*
113 |
114 | # MightyMoose
115 | *.mm.*
116 | AutoTest.Net/
117 |
118 | # Web workbench (sass)
119 | .sass-cache/
120 |
121 | # Installshield output folder
122 | [Ee]xpress/
123 |
124 | # DocProject is a documentation generator add-in
125 | DocProject/buildhelp/
126 | DocProject/Help/*.HxT
127 | DocProject/Help/*.HxC
128 | DocProject/Help/*.hhc
129 | DocProject/Help/*.hhk
130 | DocProject/Help/*.hhp
131 | DocProject/Help/Html2
132 | DocProject/Help/html
133 |
134 | # Click-Once directory
135 | publish/
136 |
137 | # Publish Web Output
138 | *.[Pp]ublish.xml
139 | *.azurePubxml
140 | # TODO: Comment the next line if you want to checkin your web deploy settings
141 | # but database connection strings (with potential passwords) will be unencrypted
142 | *.pubxml
143 | *.publishproj
144 |
145 | # NuGet Packages
146 | *.nupkg
147 | # The packages folder can be ignored because of Package Restore
148 | **/packages/*
149 | # except build/, which is used as an MSBuild target.
150 | !**/packages/build/
151 | # Uncomment if necessary however generally it will be regenerated when needed
152 | #!**/packages/repositories.config
153 |
154 | # Windows Azure Build Output
155 | csx/
156 | *.build.csdef
157 |
158 | # Windows Azure Emulator
159 | efc/
160 | rfc/
161 |
162 | # Windows Store app package directory
163 | AppPackages/
164 |
165 | # Visual Studio cache files
166 | # files ending in .cache can be ignored
167 | *.[Cc]ache
168 | # but keep track of directories ending in .cache
169 | !*.[Cc]ache/
170 |
171 | # Others
172 | ClientBin/
173 | [Ss]tyle[Cc]op.*
174 | ~$*
175 | *~
176 | *.dbmdl
177 | *.dbproj.schemaview
178 | *.pfx
179 | *.publishsettings
180 | node_modules/
181 | orleans.codegen.cs
182 |
183 | # RIA/Silverlight projects
184 | Generated_Code/
185 |
186 | # Backup & report files from converting an old project file
187 | # to a newer Visual Studio version. Backup files are not needed,
188 | # because we have git ;-)
189 | _UpgradeReport_Files/
190 | Backup*/
191 | UpgradeLog*.XML
192 | UpgradeLog*.htm
193 |
194 | # SQL Server files
195 | *.mdf
196 | *.ldf
197 |
198 | # Business Intelligence projects
199 | *.rdl.data
200 | *.bim.layout
201 | *.bim_*.settings
202 |
203 | # Microsoft Fakes
204 | FakesAssemblies/
205 |
206 | # GhostDoc plugin setting file
207 | *.GhostDoc.xml
208 |
209 | # Node.js Tools for Visual Studio
210 | .ntvs_analysis.dat
211 |
212 | # Visual Studio 6 build log
213 | *.plg
214 |
215 | # Visual Studio 6 workspace options file
216 | *.opt
217 |
218 | # Visual Studio LightSwitch build output
219 | **/*.HTMLClient/GeneratedArtifacts
220 | **/*.DesktopClient/GeneratedArtifacts
221 | **/*.DesktopClient/ModelManifest.xml
222 | **/*.Server/GeneratedArtifacts
223 | **/*.Server/ModelManifest.xml
224 | _Pvt_Extensions
225 |
226 | # Paket dependency manager
227 | .paket/paket.exe
228 |
229 | # FAKE - F# Make
230 | .fake/
231 |
232 | # =========================
233 | # Operating System Files
234 | # =========================
235 |
236 | # OSX
237 | # =========================
238 |
239 | .DS_Store
240 | .AppleDouble
241 | .LSOverride
242 |
243 | # Thumbnails
244 | ._*
245 |
246 | # Files that might appear in the root of a volume
247 | .DocumentRevisions-V100
248 | .fseventsd
249 | .Spotlight-V100
250 | .TemporaryItems
251 | .Trashes
252 | .VolumeIcon.icns
253 |
254 | # Directories potentially created on remote AFP share
255 | .AppleDB
256 | .AppleDesktop
257 | Network Trash Folder
258 | Temporary Items
259 | .apdisk
260 |
261 | # Windows
262 | # =========================
263 |
264 | # Windows image file caches
265 | Thumbs.db
266 | ehthumbs.db
267 |
268 | # Folder config file
269 | Desktop.ini
270 |
271 | # Recycle Bin used on file shares
272 | $RECYCLE.BIN/
273 |
274 | # Windows Installer files
275 | *.cab
276 | *.msi
277 | *.msm
278 | *.msp
279 |
280 | # Windows shortcuts
281 | *.lnk
282 |
--------------------------------------------------------------------------------
/Bioshock Physics Unlocker.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.23107.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bioshock Physics Unlocker", "Bioshock Physics Unlocker\Bioshock Physics Unlocker.vcxproj", "{28592A05-EE28-4BB7-A906-2DC3855C4CD2}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|x64 = Debug|x64
11 | Debug|x86 = Debug|x86
12 | Release|x64 = Release|x64
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {28592A05-EE28-4BB7-A906-2DC3855C4CD2}.Debug|x64.ActiveCfg = Debug|x64
17 | {28592A05-EE28-4BB7-A906-2DC3855C4CD2}.Debug|x64.Build.0 = Debug|x64
18 | {28592A05-EE28-4BB7-A906-2DC3855C4CD2}.Debug|x86.ActiveCfg = Debug|Win32
19 | {28592A05-EE28-4BB7-A906-2DC3855C4CD2}.Debug|x86.Build.0 = Debug|Win32
20 | {28592A05-EE28-4BB7-A906-2DC3855C4CD2}.Release|x64.ActiveCfg = Release|x64
21 | {28592A05-EE28-4BB7-A906-2DC3855C4CD2}.Release|x64.Build.0 = Release|x64
22 | {28592A05-EE28-4BB7-A906-2DC3855C4CD2}.Release|x86.ActiveCfg = Release|Win32
23 | {28592A05-EE28-4BB7-A906-2DC3855C4CD2}.Release|x86.Build.0 = Release|Win32
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/Bioshock Physics Unlocker/Bioshock Physics Unlocker.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | {28592A05-EE28-4BB7-A906-2DC3855C4CD2}
23 | BioshockPhysicsUnlocker
24 | 8.1
25 | Bioshock Physics Unlocker
26 |
27 |
28 |
29 | Application
30 | true
31 | v140
32 | MultiByte
33 |
34 |
35 | Application
36 | false
37 | v140
38 | true
39 | MultiByte
40 |
41 |
42 | Application
43 | true
44 | v140
45 | MultiByte
46 |
47 |
48 | Application
49 | false
50 | v140
51 | true
52 | MultiByte
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | BioshockPhysicsUnlocker
74 |
75 |
76 | BioshockPhysicsUnlocker
77 |
78 |
79 |
80 | Level3
81 | Disabled
82 | true
83 | MultiThreadedDebug
84 |
85 |
86 | true
87 |
88 |
89 | copy "$(TargetPath)" "C:\Program Files (x86)\Steam\steamapps\common\bioshock\Builds\Release\$(TargetFileName)" /y
90 |
91 |
92 | Copy to Bioshock directory
93 |
94 |
95 |
96 |
97 | Level3
98 | Disabled
99 | true
100 | MultiThreadedDebug
101 |
102 |
103 | true
104 |
105 |
106 |
107 |
108 | Level3
109 | MaxSpeed
110 | true
111 | true
112 | true
113 | MultiThreaded
114 |
115 |
116 | true
117 | true
118 | true
119 |
120 |
121 | copy "$(TargetPath)" "C:\Program Files (x86)\Steam\steamapps\common\bioshock\Builds\Release\$(TargetFileName)" /y
122 |
123 |
124 | Copy to Bioshock directory
125 |
126 |
127 |
128 |
129 | Level3
130 | MaxSpeed
131 | true
132 | true
133 | true
134 | MultiThreaded
135 |
136 |
137 | true
138 | true
139 | true
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
--------------------------------------------------------------------------------
/Bioshock Physics Unlocker/Bioshock Physics Unlocker.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 |
--------------------------------------------------------------------------------
/Bioshock Physics Unlocker/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #define BIOSHOCK "Bioshock.exe"
9 | #define BACKUP "Bioshock_Backup.exe"
10 | #define TIMESTEP_SIGNATURE "\x48\x6B\x55\x6E\x72\x65\x61\x6C\x43\x68\x61\x72\x61\x63\x74\x65\x72\x50\x6F\x69\x6E\x74\x43\x6F\x6C\x6C\x65\x63\x74\x6F\x72\x40\x40\x00\x00\x00\x3A\x3A\x3A\x3A\x3A\x3A\x3A\x3A\x00\x00\x00\x00\x2E\x3F\x41\x56\x46"
11 | #define TIMESTEP_MASK "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx???????????????xxxxx"
12 | #define TIMESTEP_OFFSET 36
13 | #define MESSAGE_SLEEP_TIME 2500
14 | #define ERROR_SLEEP_TIME 7000
15 |
16 | struct ScanResult {
17 | bool found;
18 | std::streampos location;
19 | };
20 |
21 | ScanResult scanPatchLocation(std::fstream &file, const char *search, const char *mask, unsigned int offset) {
22 | std::stringstream strings;
23 | strings << file.rdbuf();
24 | std::string fileString = strings.str();
25 |
26 | ScanResult patch;
27 | size_t fileLength = fileString.length();
28 | size_t sigLength = strlen(mask);
29 |
30 | for (unsigned int i = 0; i < fileLength - sigLength; i++) {
31 | for (unsigned int j = 0; j < sigLength; j++) {
32 | if (mask[j] == '?') { continue; }
33 | if (search[j] == fileString.at(i + j)) {
34 | if (j == sigLength - 1) {
35 | patch.found = true;
36 | patch.location = i + offset;
37 | return patch;
38 | }
39 | }
40 | else {
41 | break;
42 | }
43 | }
44 | }
45 |
46 | patch.found = false;
47 | patch.location = 0;
48 | return patch;
49 | }
50 |
51 | int main() {
52 | // Try to locate Bioshock
53 | std::cout << "Opening Bioshock executable...";
54 | std::fstream bsBinary(BIOSHOCK, std::ios::binary | std::ios::out | std::ios::in);
55 |
56 | if (!bsBinary.good()) {
57 | std::cerr << "Error! Could not find the Bioshock executable. Aborting..." << std::endl;
58 | std::this_thread::sleep_for(std::chrono::milliseconds(ERROR_SLEEP_TIME));
59 | return EXIT_FAILURE;
60 | }
61 | else {
62 | std::cout << "Success!" << std::endl;
63 | }
64 |
65 | // Find the location in the exe to patch
66 | std::cout << "Scanning for location to patch...";
67 | ScanResult timestepPatch = scanPatchLocation(bsBinary, TIMESTEP_SIGNATURE, TIMESTEP_MASK, TIMESTEP_OFFSET);
68 | if (!timestepPatch.found) {
69 | std::cerr << "Error! Could not find the physics timestep location to patch. Aborting..." << std::endl;
70 | std::this_thread::sleep_for(std::chrono::milliseconds(ERROR_SLEEP_TIME));
71 | return EXIT_FAILURE;
72 | }
73 | else {
74 | std::cout << "Success!" << std::endl;
75 | }
76 |
77 | // Make a backup if we don't already have one.
78 | if (!std::experimental::filesystem::exists(BACKUP)) {
79 | std::cout << "Making a backup of Bioshock.exe...";
80 |
81 | std::ofstream saveBackup(BACKUP, std::ios::binary);
82 | if (saveBackup.good()) {
83 | bsBinary.clear();
84 | bsBinary.seekg(0, std::ios::beg);
85 | saveBackup << bsBinary.rdbuf();
86 | std::cout << "Success!" << std::endl;
87 | }
88 | else {
89 | std::cerr << "WARNING: Could not create backup!" << std::endl;
90 | }
91 | }
92 |
93 | // Show the user what the timestep is set to right now.
94 | float curTimestep;
95 | bsBinary.seekg(timestepPatch.location);
96 | bsBinary.read((char*)&curTimestep, sizeof(float));
97 | std::cout << "The physics FPS is currently: " << (1.0 / curTimestep) << " FPS" << std::endl;
98 |
99 | // User input so they can change it.
100 | std::string inputLine;
101 | int inFPS;
102 | while ((std::cout << "New physics FPS: ") && std::getline(std::cin, inputLine) && !(std::istringstream{ inputLine } >> inFPS)) {
103 | std::cerr << "Invalid choice." << std::endl;
104 | }
105 |
106 | // Actually replace it in the file
107 | float desiredTimestep = 1.0f / inFPS;
108 | bsBinary.seekp(timestepPatch.location);
109 | bsBinary.write((char*)&desiredTimestep, sizeof(float));
110 |
111 | // cool.
112 | std::cout << "Updated physics to " << inFPS << " FPS! Quitting..." << std::endl;
113 | std::this_thread::sleep_for(std::chrono::milliseconds(MESSAGE_SLEEP_TIME));
114 |
115 | return EXIT_SUCCESS;
116 | }
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 TurtleHx
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #Bioshock Physics Unlocker
2 | Simple patcher which lets you adjust Bioshock's physics timestep.
3 |
4 | [Video comparison](https://www.youtube.com/watch?v=PKNRgX93TCc)
5 |
6 | This has been tested with the Steam release of the game, and should also work for the version 1.0 & 1.1 retail releases. I have heard that it does not work with the Direct2Drive release of the game, presumably due to some form of DRM.
7 |
8 | ##Usage
9 | 1. Download the [latest release](https://github.com/TurtleHx/Bioshock-Physics-Unlocker/releases/latest).
10 | 2. Extract the `BioshockPhysicsUnlocker.exe` file into your Bioshock directory, typically: `C:\Program Files (x86)\Steam\steamapps\common\bioshock\Builds\Release`.
11 | 3. Run the executable and enter your desired physics framerate.
12 |
13 | ##License
14 | MIT
15 |
--------------------------------------------------------------------------------