Project

General

Profile

Actions

Emulator Issues #10872

closed

Twilight Princess weird reset crash

Added by PPLToast about 6 years ago. Updated about 6 years ago.

Status:
Invalid
Priority:
Normal
Assignee:
-
% Done:

0%

Operating system:
N/A
Issue type:
Bug
Milestone:
Regression:
No
Relates to usability:
No
Relates to performance:
No
Easy:
No
Relates to maintainability:
No
Regression start:
Fixed in:

Description

I talked a bit about this with JMC and booto, but forgot to make a proper issue report of it.

Game Name?

Wii versions of Twilight Princess.

What's the problem? Describe what went wrong.

A weird glitch was mentioned to me where if you soft reset the game from the home menu on a specific frame as you void out will crash the game after you try to load a save file. On Dolphin, the game will crash without even reaching the title screen.

What steps will reproduce the problem?

The glitch is a bit complicated to pull off from a fresh save file, so there's a save state for 5.0-6300 on the European version. Simply hit reset and the game will lock up.

Is there anything else that can help developers narrow down the issue?

https://drive.google.com/open?id=1jSEubUjoWoYEiBOE3p9-TBuS_DnIg5Jn

Contains ram dumps from Dolphin, a save state to recreate the issue on -6300 and a ram dump from where it crashes on console. This is probably too late to see what's going wrong on Dolphin's end, so I guess a ram dump would have to be done at the exact moment it would crash on Dolphin.

https://www.youtube.com/watch?v=GEy1g5G7Z9E

Here's a video of the crash on console.

I tried a variety of settings like toggling MMU among others, but nothing changes.


Files

stage_patch.png (140 KB) stage_patch.png sepalani, 02/09/2018 05:25 PM
NULL_i_data.png (13.8 KB) NULL_i_data.png sepalani, 02/09/2018 05:26 PM
RZDP01.zip.002 (4.77 MB) RZDP01.zip.002 savestate part 2 sepalani, 02/09/2018 05:32 PM
RZDP01.zip.001 (4.77 MB) RZDP01.zip.001 savestate part 1 sepalani, 02/09/2018 05:32 PM
RZDP01.zip.004 (4.77 MB) RZDP01.zip.004 savestate part 4 sepalani, 02/09/2018 05:33 PM
RZDP01.zip.005 (4.77 MB) RZDP01.zip.005 savestate part 5 sepalani, 02/09/2018 05:34 PM
RZDP01.zip.003 (4.77 MB) RZDP01.zip.003 savestate part 3 sepalani, 02/09/2018 05:34 PM
RZDP01.zip.006 (1.75 MB) RZDP01.zip.006 savestate part 6 sepalani, 02/09/2018 05:34 PM

Updated by sepalani about 6 years ago

I managed to trigger the issue using the provided savestate. When exiting the HOME menu it loads the stage properly. Otherwise, the game loads that same stage when pressing RESET as well (rather than loading the title screen) according the log.

To patch the stage, put a breakpoint where the PC is in the stage_patch.png screenshot (before the setStartStage call in the phase_1 function).
Then, go to the r4 address (available in the Register view, right click -> View Memory, then go) in the Memory view and patch:

  • the stage name (@r4): Replace "F_SP121" with "F_SP102"
  • the constants right after the stage name (@r4+0x8):

Constants (before)

0xFFFF01FF
0x0001001A
0x0000803E
0x953CFF00

Constants (after)

0x0064000A
0x0001001A
0x0000803E
0x953CFF00

Only the first line differs (@r4+0x8).

Regardless, the split zip archives contain the savestate after patching the game memory and reaching the title screen.
NULL_i_data.png is the call stack before the following error message which occurs while loading a save slot:

[ERROR]dStage_dt_c_decode: i_data is NULL
Actions #2

Updated by sepalani about 6 years ago

After diving into the code, this is what I found:

Starting the stage

The function responsible for starting a stage is dComIfG_play_c::setStartStage(dStage_startStage_c *), this one is called once when the phase_1 function is executed after pressing reset.

Setting the next stage

The function responsible for setting the next stage is dComIfGp_setNextStage(char const *, short, signed char, signed char, float, unsigned long, int, signed char, short, int, int) and is called by dComIfG_changeOpeningScene(scene_class *, short).

Next stage setup after pressing RESET

In order to call dComIfG_changeOpeningScene (which is called by dComIfG_resetToOpening(scene_class *)), the following conditions have to be met:

In the dComIfG_resetToOpening(scene_class *) function (dComIfG_changeOpeningScene's caller)

r13 = 0x80525ea0

1.  u32 ptr = *(r13-0x4E10)     // @0x80521090      (value = 0x80537440)
    u8 b = *(ptr + 0x10)        // @0x80537440+0x10 (value = 0x00)
    Condition: b == 0

2.  u8 b = *(ptr + 0x11)        // @0x80537440+0x11 (value = 0x00)
    Condition: b == 0

3.  u32 v = *(ptr)              // @0x80537440+0x00 (value = 0x00000001)
                                // Set in mDoRst_resetCallBack(int, void *) m_Do_Reset.o 
    Condition: v != 0

4.  u32 ptr2 = *(r13-0x4F00)    // @0x80520FA0      (value = 0x805EE410)
    u32 fadeout = *(ptr2+4)     // @0x805EE410+4    (value = 0x00000001)
                                // Set in JUTFader::startFadeOut(int) JUtility.a JUTFader.o
    Condition: fadeout != 2

In the dScnPly_Draw(dScnPly_c *) function (dComIfG_resetToOpening's caller)

Condition: fopOvlpM_IsPeek() != true

When these 5 conditions are met, the dComIfG_changeOpeningScene function is called. Regarding the normal behaviour, when RESET is pressed (either via the Wii button or the HOME menu) it sets the next stage to be "F_SP102", then calls dScnPly_Draw a bunch of time to draw the fadeout animation and finally calls phase_1. However, when the bug occurs, the next stage isn't set because those conditions aren't met, especially since fopOvlpM_IsPeek() == true. Overwriting the return value allows to reach the title screen but won't produce the save slot loading glitch. Moreover, when the bug happens the next stage isn't set, so it reloads the previous one which is "F_SP121" and dScnPly_Draw is never called again which is weird.

I'll investigate and try to find why. However, if it's a timing issue, the savestate might have saved the "bad" timing and might be useless to check if the issue has been fixed.

Actions #3

Updated by sepalani about 6 years ago

I tried to find a consistent setup to reproduce the glitch from the title screen savestate I provided and I realised that breakpoints or waiting too much won't trigger the glitch. The i_data = NULL mentioned in the debug message seems to be located on the heap, so I assume it's a memory corruption glitch. According to the memory breakpoints it could be either the DVD reading/writing to it or the game reloading a scene.

Either way, I don't know how accurate this is compared to the real console since it could behave differently. Could someone please reproduce the following steps when the glitch occurs on a real console (using the appropriate debugging tools):

Breakpoint setup

Put a breakpoint on 0x8001abf8 (mDoRst_resetCallBack)
When hit, put a breakpoint on:

  • 0x802e637c (JUTReportConsole_f)
  • 0x80009358 (OSReport_Error)

Then, resume the execution.

Debug messages

JUTReportConsole_f

When the JUTReportConsole_f's breakpoint is hit,
  1. Extract the string located in memory based on r3 value
  2. Count the number of "%" character in the string and extract the same number of register (starting at r4)
    -> Example: if there are 2 "%" characters, write down the r4 and r5 values
    -> (Optional) if the register value is an address, write down the string
        r3 = 0x804076de ("Start StageName:RoomNo [%s:%d]")
        r4 = 0x8047f628 ("F_SP121")
        r5 = 0x00000001
  3. Describe where and when the breakpoint is hit

Then, resume the execution.

OSReport_Error

Same as JUTReportConsole_f
Actions #4

Updated by PPLToast about 6 years ago

This can be closed, because I just got it to work on Dolphin the same as it does on console. Sepalani can confirm.

Sorry for wasting everyone's time.

Actions #5

Updated by JosJuice about 6 years ago

  • Status changed from New to Invalid
Actions

Also available in: Atom PDF