bsnes icon indicating copy to clipboard operation
bsnes copied to clipboard

"Wolverine - Adamantium Rage (USA)" hangs on the latest master version

Open Screwtapello opened this issue 1 year ago • 21 comments

As reported by user usVSthem on Discord, the USA version of the game Wolverine - Adamantium Rage hangs after displaying the unskippable developer and publisher logos, but before displaying the title screen. The European version, and the Japanese version (just named "Wolverine") both work fine.

Bisecting history points to 4f7a269ba5d053bb824b5ffa0978799331a5f2d8 as the commit that introduced the problem, which changed how bsnes handled joypad polling - which makes sense, since it's only once the game tries to interact with the joypad that the problem occurs.

Note that this commit fixes the game SpellCraft - Aspects of Valor, so whatever we do here has to make both games work - we can't just revert this specific fix.

Screwtapello avatar Aug 26 '24 09:08 Screwtapello

I believe the same game works fine on ares, even though ares has exactly the same HVBJOY code. Clearly there's some other difference in the SFC emulation.

Screwtapello avatar Aug 26 '24 11:08 Screwtapello

From the issue about SpellCraft - Aspects of Valor:

@asuramaru said that their fix in bsnes was subtly different from @jbo-85's fix in higan, and if a game ever worked in one but not the other, that would be a clue to which implementation was more correct

https://github.com/bsnes-emu/bsnes/issues/86#issuecomment-720015859

I should test SCAoV in ares to see how it holds up.

Screwtapello avatar Aug 26 '24 12:08 Screwtapello

I suspect the higan commit being referenced is https://github.com/higan-emu/higan/commit/e422ddc7293b10aae8a1935d4c7f96aeb8445430 which is a much more complex change.

Screwtapello avatar Aug 26 '24 12:08 Screwtapello

Good catch on this @Screwtapello ! Hopefully a solution will present itself soon!

I wonder if this issue is why you can't register your name on bs legend of Zelda. You can move the cursor but there's no response when trying to register your player.

Has @carmiker seen this yet? He seems to be very familiar with bsnes code.

Edit** tried using a newer version of the bs Zelda roms and this problem doesn't happen or persist.

joepogo avatar Sep 14 '24 05:09 joepogo

I am aware of it, and hope to fix it.

carmiker avatar Sep 14 '24 06:09 carmiker

I have found at the moment it seems a workaround is to overclock the CPU by any percent and the game will be playable until it's fixed proper.

joepogo avatar Sep 15 '24 01:09 joepogo

Apparently Mesen has done more research into autopolling behaviour, including a new test ROM, as mentioned in ares' issue tracker: https://github.com/ares-emulator/ares/issues/970#issuecomment-2555190463

Screwtapello avatar Dec 23 '24 09:12 Screwtapello

Yes, and all the problematic games we had back then work without any issues with Mesen. If someone wants more context, they should go to the snes development server discord, channel "emulator dev" December 2024 posts.

Max833 avatar Dec 23 '24 22:12 Max833

I've got 3 more tests to write after Christmas (to test writing and reading JOYSER0 during autojoy).

After that I will rerecord the test outputs and post them all to my website.

undisbeliever avatar Dec 24 '24 03:12 undisbeliever

Just want to let you all know the tests and console recordings are going to be delayed a bit. Fiskbit came up with 2 more autojoy tests and I would like to publish all of the autojoy tests at once.

undisbeliever avatar Dec 28 '24 01:12 undisbeliever

Here are the auto-joypad tests from undisbeliever: https://github.com/undisbeliever/snes-test-roms/tree/master/src/hardware-tests/auto-joypad

Max833 avatar Mar 24 '25 21:03 Max833

User nut1293 on Discord reported that changing autoJoypadCounter < 33 to autoJoypadCounter < 17 in https://github.com/bsnes-emu/bsnes/blob/b815744b4cff6d6854090545b78ae8e1a6669976/bsnes/sfc/cpu/io.cpp#L41 (the line introduced by the regressing commit linked in the OP) fixes the problem with Wolverine, though I haven't tested it myself. I'm also not sure what the theoretical justification is for that number, although apparently it came from studying anomie's timing docs.

Screwtapello avatar May 26 '25 13:05 Screwtapello

Mesen was able to eliminate all bugs with the help of the testroms listed above. They talked, tested and tweaked a lot about it in the SNES development discord. Maybe it helps to look and ask there as well.

And: https://github.com/SourMesen/Mesen2/commit/e4d317635fa9c34a7dd17974d33e2ac442554bf6 https://github.com/SourMesen/Mesen2/commit/d1aa957a8052cfa87418908dd46c9cad80d287e8 https://github.com/SourMesen/Mesen2/commit/6b772003647f02f42787a79a2682362a72a544cd https://github.com/SourMesen/Mesen2/commit/ff1580def4352605004203b5b1b011e8a3bfd3ca

Max833 avatar May 26 '25 17:05 Max833

Testing the current version of bsnes against games known to be sensitive to joypad polling:

  • ✅ Nuke (PD) works, although it seems a bit keen to auto-repeat
  • ✅ The sky looks fine in Secret of Mana (I sure am glad I happened to still have the late-game save-file I used for testing last time!)
  • ✅ In Spellcraft, I can activate the password orb without automatically dismissing it
  • ❌ In Spellcraft, I cannot hold B at the main menu to automatically select "New Game"
  • ✅ In Super Conflict, no random inputs on the main menu, or the level select, or in-game
  • ✅ In Super Star Wars, the game does not automatically unpause itself
  • ✅ In Taikyoku Igo - Goliath, the title-screen animation is not skipped, and I can enter the game
  • ✅ In Tatakae Genshijin 2, the attract-mode does not immediately exit
  • ✅ In Williams Arcade's Greatest Hits, no menu items are skipped
  • ❌ In Wolverine - Adamantium Rage, the game hangs before it gets to the main menu (that's what this issue is about)
  • ✅ In World Masters Golf, the D-pad does not auto-repeat on the main menu

Looking at undisbeliever's tests, I don't think any of them are relevant besides auto-joy-timing-test.sfc, which produces the following results:

Event Min Max
Start 2A 4F
End 2C 52

Next, to make the suggested change and retest, and maybe also get some hardware verification.

Screwtapello avatar Jun 04 '25 09:06 Screwtapello

After applying the patch, let's go through the list again.

  • ✅ Nuke (PD) works, although it seems a bit keen to auto-repeat
  • ✅ The sky looks fine in Secret of Mana
  • ❌ In Spellcraft, I cannot activate the password orb without automatically dismissing it
  • ✅ In Spellcraft, I can hold B at the main menu to automatically select "New Game"
  • ✅ In Super Conflict, no random inputs on the main menu, or the level select, or in-game
  • ✅ In Super Star Wars, the game does not automatically unpause itself
  • ✅ In Taikyoku Igo - Goliath, the title-screen animation is not skipped, and I can enter the game
  • ✅ In Tatakae Genshijin 2, the attract-mode does not immediately exit
  • ✅ In Williams Arcade's Greatest Hits, no menu items are skipped
  • ✅ In Wolverine - Adamantium Rage, the game gets to the main menu
  • ✅ In World Masters Golf, the D-pad does not auto-repeat on the main menu
Event Min Max
Start 2D 50
End D8 FA

So, that's better than the current configuration, but it's clearly still not perfect, as the Spellcraft test that worked is now broken.

Screwtapello avatar Jun 07 '25 08:06 Screwtapello

And for the record, I had a friend with a 2-chip 2/1/3 SFC run the same test ROM.

Event Min Max
Start 29 71
End 4B 9C

Screwtapello avatar Jun 07 '25 08:06 Screwtapello

Firstly, I want to apologise for not publishing the test results/analysis on my website. I honestly forgot about it. I had a run of bad luck that broke a number of things around me that needed fixing (including my PC and file-server not booting), followed by mild burnout from working on the smpspeed tests results for the TAS-bot community.

The autojoy tests are inconsistent on every run and reset. I think my sd2snes is hijacking the reset signal and causing a the S-CPU to be out of sync with the S-PPU and throwing off the results. I will need to instrument my console and scope the signals to confirm the sd2snes reset signal hijacking. I do not have a way to run my tests without a sd2snes to confirm the autojoy timing is consistent on original hardware.

Here's the timings I recorded for the auto-joy-timing-test and resetting the console with the reset button.

Min Max
start 002B - 002D 006F - 0071
end 004B - 004C 009A - 009C
1-CHIP NTSC SFC console
    start 002B 006F
    end   004B 009C

    start 002C 0070
    end   004C 009B

    start 002C 0070
    end   004C 009C

    start 002C 0070
    end   004C 009B

    start 002C 0071
    end   004B 009B

    start 002C 006F
    end   004B 009A


    start 002B 0070
    end   004B 009C

    start 002C 006F
    end   004B 009A

    start 002A 0071
    end   004C 009A


2/1/3 NTSC SFC console (3-chip S-CPU A)
    start 002B 006F
    end   004B 009C

    start 002C 0070
    end   004C 009B

    start 002C 0070
    end   004C 009B

    start 002C 0070
    end   004B 009B

    start 002C 0070
    end   004C 009C

    start 002C 006F
    end   004B 009A


1/1/1 NTSC SFC console
    start 002C 0070
    end   004B 009B

    start 002C 0070
    end   004C 009B

    start 002C 0070
    end   004C 009B

    start 002C 0070
    end   004C 009B

    start 002D 0070
    end   004C 009C

    start 002C 0071
    end   004B 009B

    start 002B 0070
    end   004C 009B

undisbeliever avatar Jun 07 '25 09:06 undisbeliever

Here's a zip file with all of the auto-joyapd-read tests and the latest screen recordings (in jpeg and AV1 formats).

I've included a basic notes.txt that explains what I did when I recorded the tests.

The results appear identical for my 3 consoles except for 11-clear-autojoy-timing-test. This test is different on my 1CHIP console (compared to my S-CPU-A and 1/1/1 consoles). I do not know if the change occurred in the S-CPU-B or 1CHIP revisions (or if it is my 1CHIP console).

I will start working on the website results page (with an explanation of the test hypothesis and analysis) tomorrow. I cannot state how long this will take.

auto-joypad-tests-and-results.zip

undisbeliever avatar Jun 07 '25 10:06 undisbeliever

The hardware timings I posted were a summation of a bunch of measurements taken from a cold boot, and after a few resets, with an FXPak (SD2SNES) and Everdrive. All those situations produced numbers pretty close to yours - starting from the mid-high $2x to about $70, ending from the mid-high $4x to the mid-high $9x.

It did occur to me that rather than just recording the extreme minimum and maximum, it might be nice to record all the start times and end times in SRAM, so we could calculate the average and standard deviation. But if Mesen got accurate emulation without that information, maybe it's not necessary.

Screwtapello avatar Jun 07 '25 11:06 Screwtapello

(the minimum start of $29 I recorded came from an Everdrive on cold boot)

Screwtapello avatar Jun 07 '25 11:06 Screwtapello

...it might be nice to record all the start times and end times in SRAM, so we could calculate the average and standard deviation...

FullSNES says the polling always takes the same number of cycles, and always happens on a multiple of 256 cycles, whenever that falls into the "start joypad polling" window. If that's been verified, there's probably no call for advanced stats.

Screwtapello avatar Jun 07 '25 12:06 Screwtapello

@Screwtapello what's your opinion on the following diff?

diff --git a/bsnes/sfc/cpu/timing.cpp b/bsnes/sfc/cpu/timing.cpp
index e443e5a5..ab82c541 100644
--- a/bsnes/sfc/cpu/timing.cpp
+++ b/bsnes/sfc/cpu/timing.cpp
@@ -205,6 +205,8 @@ auto CPU::joypadEdge() -> void {
   //it is not yet confirmed if polling can be stopped early and/or (re)started later
   if(!io.autoJoypadPoll) return;
 
+  status.autoJoypadCounter++;
+
   if(vcounter() == ppu.vdisp() && hcounter() >= 130 && hcounter() <= 256) {
     //begin new polling sequence
     status.autoJoypadCounter = 0;
@@ -241,6 +243,4 @@ auto CPU::joypadEdge() -> void {
     io.joy3 = io.joy3 << 1 | port0.bit(1);
     io.joy4 = io.joy4 << 1 | port1.bit(1);
   }
-
-  status.autoJoypadCounter++;
 }

I have tested this with Spellcraft and Wolverine and both games work fine.

The results of the auto-joypad timing test are:

min max
start 002A 0051
end 004C 0071

Morilli avatar Jun 21 '25 12:06 Morilli

@Morilli did you mean Spellcraft, not Secret of Mana?

carmiker avatar Jun 21 '25 15:06 carmiker

Great work so far on all this guys!! @carmiker would it be possible to merge this and the other commits to retroarch once it's completed?

Right now retroarch bsnes is 8 commits behind. I tried creating a pull request to merge the commits but it won't let me. 😔

joepogo avatar Jun 21 '25 17:06 joepogo

Implementing more conditions that mesen uses:

diff --git a/bsnes/sfc/cpu/timing.cpp b/bsnes/sfc/cpu/timing.cpp
index e443e5a5..02d64d87 100644
--- a/bsnes/sfc/cpu/timing.cpp
+++ b/bsnes/sfc/cpu/timing.cpp
@@ -205,7 +205,9 @@ auto CPU::joypadEdge() -> void {
   //it is not yet confirmed if polling can be stopped early and/or (re)started later
   if(!io.autoJoypadPoll) return;
 
-  if(vcounter() == ppu.vdisp() && hcounter() >= 130 && hcounter() <= 256) {
+  status.autoJoypadCounter++;
+
+  if(vcounter() == ppu.vdisp() && (counter.cpu & 255) == 0 && hcounter() >= 130 && hcounter() <= 384) {
     //begin new polling sequence
     status.autoJoypadCounter = 0;
   }
@@ -241,6 +243,4 @@ auto CPU::joypadEdge() -> void {
     io.joy3 = io.joy3 << 1 | port0.bit(1);
     io.joy4 = io.joy4 << 1 | port1.bit(1);
   }
-
-  status.autoJoypadCounter++;
 }

Note: I'm not sure whether <= 384 or < 384 is more correct (or whether it even matters).

Auto-joypad timing test results:

min max
start 002A 0071
end 004B 009C

Morilli avatar Jun 21 '25 18:06 Morilli