Gericom / GBARunner3

184 stars 24 forks source link

Dragon Quest Monsters shaky overworld map #74

Open zenseii opened 8 months ago

zenseii commented 8 months ago

Tested on DSi with SD card.

The overworld map should not shake and instead be still:

https://github.com/Gericom/GBARunner3/assets/12501091/a731fddf-10bb-4ffc-ab7e-c370eecf1d19

Savefile for GBARunner3 and mGBA. Exit the inn and leave the town (bottom choice in the town menu) DragonQM GBAR3 mGBA.zip

no$gba savestate: DQM Overworld nocash.zip

zenseii commented 8 months ago

Using JIT patches did not fix this.

Only added msr and mrs addresses as the subs pc addresses didn't seem like code: image

json file with addresses:

{
    "runSettings": {
        "jitPatchAddresses": [
            "0x080000C4",
            "0x080000D0",
            "0x08000160",
            "0x08000234",
            "0x08000240",
            "0x08000260",
            "0x0800026C",
            "0x0800027C"
        ]
    }
}

A9HJ00.json

zenseii commented 8 months ago

Disabling wram icache changes nothing.

Gericom commented 8 months ago

On DS hardware interestingly without manual jit patches there are way less glitches on the world map, but then the performance sucks and sound is bad. With manual jit patches the performance and sound is good, but the map glitches are much more. (There also seems to be some bug with applying jit patches where it sometimes ignores some of the patch offsets? I am investigating it)

Gericom commented 8 months ago

I pushed the manual jit patches to develop, as they fix performance of the game on regular DS hardware

Gericom commented 8 months ago

Okay so for Dragon Quest Monsters the world map issue is an irq latency problem. This is a result from aborts and undefined instructions in the irq handler, from sound sample fetches (which still need to be improved performance wise) and probably from sd fetches. Disabling sound is not sufficient to fix the issue. I tried implementing a kernel mode irq handler for this game, as optimized as possible. When using that combined with disabled sound the problem is mostly solved. Only sd fetches still cause an occasional glitch

For later reference, the (partially) kernel mode irq handler for this game

    adds pc, pc, #(bios_irq_handler - 8 - .)

bios_irq_handler:
    PUSH {R0-R3,R12,LR}
    MOV R3, #0x4000000
    ldr r1, [R3,#-4]
    cmp r1, #0x06800000
    ldrhs pc,= gotoBiosIrq
    ldr pc,= 2f

.text
2:
    ldr r2,= vm_emulatedIfImeIe
    ldr r12,= (emu_ioRegisters + 0x200)
    ldrh r2, [r2]
    ldrh r12, [r12]
    mov r1, r2, lsr #15
    bic r2, r2, #0xC000
    orr r2, r12, r2, lsl #16
    msr cpsr_c, #0x10
    // game irq handler
    @ ldr r2, [r3, #0x200]!
    add r3, r3, #0x200
    @ ldrh r1, [r3, #8]
    // mrs r0, spsr
    @ push {r0-r3,lr}
    @ mov r0, #1
    @ strh r0, [r3, #8]
    and r1, r2, r2, lsr #16
    rsb r12, r1, #0
    and r0, r12, r1
    clz r12, r0
    rsb r12, r12, #31
    strh r0, [r3, #2]
    bic r2, r2, r0
    and r1, r2, #0xFFFFFFFE
    @ strh r1, [r3]
    // mrs r3, cpsr
    @ bic r3, r3, #0xDF
    @ orr r3, r3, #0x1F
    // msr cpsr, r3
    ldr r1,= 0x03001F80
    ldr r0, [r1, r12, lsl #2]
    blx r0
    // mrs r3, cpsr
    @ bic r3, r3, #0xDF
    @ orr r3, r3, #0x92
    // msr cpsr, r3
    @ pop {r0-r3,lr}
    @ strh r2, [r3]
    @ strh r1, [r3, #8]
    // msr spsr, r0
loc_138:
    POP {R0-R3,R12,LR}
    vmSUBS pc, lr, 4

gotoBiosIrq:
    adr lr, loc_138
    msr cpsr_c, #0x10
    mov pc, r1

So the main things to improve are

Gericom commented 4 months ago

The issue has almost entirely been fixed now with the recent irq latency improvements. There are still some random hickups, which are most likely caused by sd fetches (probably from music samples, as the glitches seem to go away after a while, probably because the samples are all in the sd cache by then)

VeaNika commented 4 months ago

There is a regression of this issue beginning in the latest commit https://github.com/Gericom/GBARunner3/commit/addae4d3daf5e3b3119716171ed60f95a2eda59d

Follow the same steps as the OP to reproduce it.

VeaNika commented 3 months ago

The issue has been partially fixed back to how it was reported by Gericom in commit https://github.com/Gericom/GBARunner3/commit/2034ec518de6f0c2a1054b234331e6e192614d73

It still has some side-effect issues due to SD fetching, as previously mentioned.

Dartz150 commented 3 months ago

According to the conversations we had on discord, this game relies tightly on execution timing (or myabe on yet unknown behaviors), as adding artificial overhead fixes the game, and removing it makes the issue to appear again.

To "fix" this issue, add two nops in https://github.com/Gericom/GBARunner3/blob/90b994f7bdff5aeccafc0146193a2df4c838cadf/code/core/arm9/source/MemoryEmulator/Arm/ArmDispatch.s#L16

image