illusion's Blog
Contact Patches

Non MLAA Bug Fixes for The Last of Us (RPCS3)

Please be aware that the patch has already been released since October of 2020. This article covers the making of the patch.


Intro

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:

Overbloom: Menu
Overbloom: In-Game
Rainbow aiming reticles
Grahpical issues; This place has seen better days.
SPU Access Violation; This happens after a few minutes

Research

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?

0x12C41A4: 1.00
0x12C41A4: 0.50

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.

Timelaspe video showing float value adjusted.

Full Video

Welp, it didn’t crash. Let’s try increasing the value.

0x12C41A4: 0.75 It crashed after a few minutes

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.

Base multipliers in high region of memory

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.

Bloom Glow 1.00 (Non PostOnSpu Path)
Bloom Glow 0.00 (Non PostOnSpu Path)

With adjustments to the float, we are left with a similar glow seen in the MLAA Path.

Bloom Values Adjusted; RPCS3 Screenshot. (Non PostOnSpu Path)
PlayStation 3 Screenshot. (PostOnSpu 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.

Spot any difference?

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)

Value cannot be edited here

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.

  • Financial District

  • Escape the City

  • Go Big Horns

October 2020 - On Vacation and fixing bugs

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.

Menu in PlayStation 4 version

3F 80 00 00 01 31 89 C8 01 50 D7 F0 Setting this to 0 fixes the crash.

Breakpoint at 0x150d7f0

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.

Results

Patch

Patch was made available back in October 2020. You can download through the emulator built-in Patch Manager.

Supporters

Thanks to the patrons who supported me on various platforms! You guys are awesome!

Monthly supporters:

  • Patreon:

    • ac2pic
    • Alexa
    • Brett
    • Ciril
    • GarnetSunset
    • Mmmmmhno
    • Paul
    • PlayStation5Mods
    • RazzySxPB
    • Ryan
    • Voredy
    • YveltalGriffin
    • Zackery
    • alessaro92
    • ashenC
    • embee
    • erdosadam24
    • faith
    • maplemiyazaki
    • patrick
    • rudi
  • Github Sponsors:

    • VIPO777
    • WardFail
    • Whitehawkx
    • gorshco
    • jrson83
    • regal.
    • suwagawaki