Please be aware that the patch has already been released since October of 2020. This article covers the making of the patch.
Back in August - October 2020, I got curious to see if I could fix some of the bugs introduced with the MLAA Patch for Naughty Dog Games on the RPCS3 Emulator.
This allowed for a number of benefits for instances, resolution upscaling and overall faster performance.
But it also has a few disadvantages such as:
Overbloom and Black screen in some parts of the game.
Crashes during some subchapters rendering the game completely unplayable.
So I asked my friend, ZEROx to help out and not only did we succeeded in our goal, we mananged to improve the game overall and resolve some emulator bugs in the process. Although the crashes are actually a real bug.
Things we wanted to improve upon:
0x12C41A4 I found this memory address when I was searching for Field of View. Selecting a bunch of 1.00s (
3F 80 00 00) and setting them to 0.50 (
3F 00 00 00).
What does it do you may ask?
It seems like this adjust sun’s position, brightness and other things.. there has to be more to this. let’s try Financial District - one of the subchapters in the game.
Welp, it didn’t crash. Let’s try increasing the value.
I guess 0.50 worked. Interesting.
Part 1 - Bloom Fix
0x12C41A4 is the base multiplier for many of the game’s graphics variable. Introduced in Uncharted 3 and onwards.
Altering this value will also alter the values in the higher range of the game memory.
So I then passed this off to ZEROx and he discovered the area where the values are located.
We now have fine control over the float values, meaning we can tweak the individual values to our liking.
As an example:
3F 80 00 00 01 31 89 E8 01 50 E1 98 This affects Bloom Glow.
With adjustments to the float, we are left with a similar glow seen in the MLAA Path.
Remember the pattern above?
01 50 E1 98 this looks like a memory address.
ZEROx came to the rescue and made a list of values used throughout the game.
The columns belows contains memmory address and their float values loaded in sections of the game.
Non-MLAA (Post on SPU) path bloom values: Item: e190 e194 e198 e19c e1a0 e1a4 e1a8 e1ac Fog-e610 Menu: 1.103 1.1 0 0.8 0.3 1.7 0 2.2 0 ... The Cargo: 0.2 1.602 -0.0315 0.8 0.1 1.6 0 2.4 0 Pre-Ellie: 0.2 1.402 -0.0015 0.8 0.2 1.5 0 1.5 0 ... Bills intro: 2.244 1.68 0.02 1.1 0.05 1.9 0 2.11 0 Bills offroad: 1.4499 1.08 0.02 0.93 0.05 1.9 0 2.11 0 Bills forest: 1.649 0.98 0.02 1 0.05 1.9 0 2 0 Bills town: 0.5495 2.6 0.02 1.05 0 1.8 0 2 0 Bills inside building: 0.5495 2 0.02 1.05 0 1.8 0 2 0 Bills music shop: 1.7196 2 0.02 1.05 0 1.8 0 2 0 Bills on the roof: 0.5495 2.6 0.02 1.13 0 1.8 0 2 0 Bills Trap: 0.78 2.951 0.02 1.28 0 1.9 0 2 0 Bills Trap escape: 0.48 2.951 0.02 1.28 0 1.9 0 2 0 ... Ending: 1.1 1.1 0 0.75 0.302 1.7 0 2.3 0
Since it would be too long to show the entire patchcodes (Over 40 lines!)
Here’s a quick rundown:
The patch only covers 3 problematic places: Main Menu, Bill’s Town and Ending.
It compares floats as 4 bytes hex with certain values which are unique for those levels.
For example, this is the snippet of code for main menu bloom patch.
# Bloom correction patch - [ be32, 0x00a803a8, 0x2f840000 ] #if r4 <= 0 - [ be32, 0x00a803ac, 0x409d0058 ] #Skip to Main menu # Patch Menu/Ending level - [ be32, 0x00a80404, 0x808909a0 ] #r4 unique value e190 - [ be32, 0x00a80408, 0x3ca03f8d ] #r5 = 3f8d0000 - [ be32, 0x00a8040c, 0x38a52f6f ] #r5 = 3f8d2f6f - [ be32, 0x00a80410, 0x7f842800 ] #compare r4 to r5 - [ be32, 0x00a80414, 0x419e0010 ] #Patch menu - [ be32, 0x00a80418, 0x80a909a4 ] #r5 unique value e194 - [ be32, 0x00a8041c, 0x7f842800 ] #compare r4 to r5 - [ be32, 0x00a80420, 0x4c9e0020 ] #Return (bnelr) # Patch function - [ be32, 0x00a8042c, 0xedad0332 ] #f13=f13*f12 - [ be32, 0x00a80430, 0xec000332 ] #f0=f0*f12 - [ be32, 0x00a80434, 0x4e800020 ] #Return
And if it hits one condition it applies coef, its needed for the two values by using fmuls.
(i.e 0.199 * 1.00 and 0.199 * 0.5)
0.199 is the actual float value, multiplied by base: 1.00 which is the default.
0x150E198 must be 0, doesn’t matter if its positive or negative values. It affects bloom glow and negative values seen in The Cargo subchapter, which causes a black screen.
0x150E1A0 must be 0, this affects aiming reticles.
Now, we have a crash to burn.
Part 2 - Crash Fix
So I went searching for the floats.
3F 80 00 00 01 31 89 E8 01 50 E0 E0
This seem to stop the crash when lowering the value to 0.5 (3F 00 00 00)
Breakpoint leads to here.
0095b8ec c1 a9 08 f0 lfs f13,0x8f0(param_7)=>DAT_0150e0e0 0095b8f0 c0 1e 80 8c lfs f0,-0x7f74(r30)=>DAT_012bec38 = 3F000000h 0095b8f4 ff 8d 00 00 fcmpu cr7,f13,f0 0095b8f8 40 9d 00 2c ble cr7,LAB_0095b924 LAB_0095b924 0095b924 eb c1 ff f0 ld r30,local_10(r1) 0095b928 4e 80 00 20 blr
It looks like it compares against float at
0x12bec38 and branches to
0x95b924 when it meet its condition.
An easy patch here is to make it branch regardless of its condition check.
The result is crashing fixed during the following sections.
Escape the City
Go Big Horns
Part 3 - Cabin Resort Fix
ZEROx hunted down one more crash.
This subchapter will cause crashing if Runtime Lighting is set to GPU Lighting, one of the lighting path available in the game.
3F 80 00 00 01 31 89 C8 01 50 D7 F0 Setting this to 0 fixes the crash.
00a7ffa4 80 09 0e 20 lwz r0,0xe20(param_7) 00a7ffa8 2f 80 00 00 cmpwi cr7,r0,0x0 00a7ffac 41 9e 01 a4 beq cr7,LAB_00a80150
The same patching method can be used here. Branch regardless of the compare condition.
Patch was made available back in October 2020. You can download through the emulator built-in Patch Manager.
Thanks to the patrons who supported me on various platforms! You guys are awesome!
- Jeff Eberlin