darthcloud / BlueRetro

Multiplayer Bluetooth controllers adapter for retro video game consoles
https://blueretro.io
Apache License 2.0
1.35k stars 111 forks source link

SNES Multitap controller 4 doesn't work on NBA Jam since v1.8.2 #656

Open amaiorano opened 1 year ago

amaiorano commented 1 year ago

BlueRetro firmware version

v1.8.2

BlueRetro firmware specification

HW1

BlueRetro firmware variant

Universal

BlueRetro hardware type

External adapter with detachable cord

Manufacturer

I did

System used

Nintendo SFC SNES

Bluetooth controller brand & name

2xPS3 and 2xN30

What is problem? (only list ONE problem per report)

When multitap is enabled (slot 2), NBA Jam allows you to play up to four players. With v1.8.1, it works great, but since v1.8.2, the first three controllers work, but attempting to use the fourth controller causes the game to detect an invalid device. It shows a screen that says:

PROBLEM

A DEVICE NOT SUPPORTED BY
THIS PROGAM HAS BEEN
CONNECTED.

PLEASE USE THE STANDARD
CONTROLLERS ONLY.

More details about NBA Jam: when multitap is enabled, the title screen only shows two options: "Start Game" and "Options" (if you see more options, multitap is not detected). Selecting "Options", and moving to the bottom where you can configure controller buttons, pressing start on the 2nd and 3rd controllers activates their configuration, but pressing start on the fourth controller does not. However if you mash buttons on controller 4, the game detects an invalid controller and displays the message above.

I suspect that this change may have broken multitap in NBA Jam: https://github.com/darthcloud/BlueRetro/commit/0eb8e2551221a5a4362c313f087047bae9b1d45a

What did you expect to happen?

All four controllers work in multitap mode in NBA Jam.

Attach files like logs or Bluetooth traces here

No response

darthcloud commented 1 year ago

@DigiDwrf is it something you could look at?

DigiDwrf commented 1 year ago

I'm going to check this out ASAP. I remember testing all NBA games and they worked fine.

DigiDwrf commented 1 year ago

I've just tested NBA Jam and also the tournament edition, and both games worked fine.

IMG_20230326_205229.jpg

IMG_20230326_205205.jpg

I think this may have to be related with configuration inside Blueretro.io. @amaiorano be sure not to swap with mouse inside the device config, and Multitap in Slot 2 is the only one supported.

DigiDwrf commented 1 year ago

No issues inside the options menu either.

IMG_20230326_210802.jpg

darthcloud commented 1 year ago

@DigiDwrf how are your cable made? Custom, my SMD pcb or AOI DIP pcb?

Could be a slight timing issue related to level shifter difference on AIO board?

DigiDwrf commented 1 year ago

I'm using a DIY dev kit for the esp32 module, and 74AHCT125N DIP14 ICs for the connector.

DigiDwrf commented 1 year ago

It could be more of a configuration issue. @amaiorano let us know.

amaiorano commented 1 year ago

I think this may have to be related with configuration inside Blueretro.io. @amaiorano be sure not to swap with mouse inside the device config, and Multitap in Slot 2 is the only one supported.

Yeah, I did not enable any mouse swap, and I enabled Multitap in Slot 2 (Global config, as Game ID didn't work).

I wonder if the fact that I'm using 2x N30 controllers makes any difference? These obviously don't have enough buttons to support SNES, but it's what I have on hand at the moment (I plan to get 8Bitdo DIY SNES PCBs). The other two controllers are PS3, which have been working just fine. What I've been doing is pairing the N30 controllers first as controllers 1 and 2 respectively, and then the PS3 controllers as 3 and 4 (and the LED display on the PS3 controllers shows that they are indeed 3 and 4).

Are there any timing values that can be tweaked in the source code that I should try changing? I'm able to build the binary and upload it. I'm also able to get the serial output from the esp32 module if that's helpful for debugging. Let me know.

DigiDwrf commented 1 year ago

Ok. I'm going to make further tests. I doubt that this part of code if the problem, this code is faster than the previous one, it was optimized to read/write faster into the GPIO. Most snes games were fixed (some write/read too fast, and won't work on this device), including this one (connectivity of the 4th and 5th controllers was not constant, so they would stutter in menus, and buttons might not respond in-game for brief periods of time).

@amaiorano The reason I think the problem might not be in this part of code is that I've not updated to 1.8.3, I'm using a custom firmware, a tree branch of 1.7.3, with this particular changes you mention. I'm going to update to 1.8.3 and see if I have the same problem you are having. If that's the case, some other games could be broken too, and it's something I will also look into.

If this message appears when you pair or press buttons (and not at boot, or by itself when you reach a part, so multitap code is working fine), then I suspect is a problem not related to timing, but to mapping (inside firmware). When I pair my SN30 controller, I have to use "START + A, macOS" mode to make it work, other modes are not well mapped or supported (@darthcloud we need your help here), and they exhibit strange behaviour (snes controller data is made of two bytes, the last 4 bits are signature, anything that is written from bit 13 to bit 16 can mess up with multitap games, and make them think you're connecting a mouse, or a superscope, if mapping is faulty, then we know where to look). Try this with your N30 and let me know if the problem is fixed.

amaiorano commented 1 year ago

@amaiorano The reason I think the problem might not be in this part of code is that I've not updated to 1.8.3, I'm using a custom firmware, a tree branch of 1.7.3, with this particular changes you mention. I'm going to update to 1.8.3 and see if I have the same problem you are having. If that's the case, some other games could be broken too, and it's something I will also look into.

Interesting. In my case, I made a custom build of 1.8.3 where I reverted your patch, and it works perfectly in NBA Jam. I will try making a custom build of 1.7.3 + your patch (same as you), and see if that works.

If this message appears when you pair or press buttons (and not at boot, or by itself when you reach a part, so multitap code is working fine), then I suspect is a problem not related to timing, but to mapping (inside firmware). When I pair my SN30 controller, I have to use "START + A, macOS" mode to make it work, other modes are not well mapped or supported (@darthcloud we need your help here), and they exhibit strange behaviour (snes controller data is made of two bytes, the last 4 bits are signature, anything that is written from bit 13 to bit 16 can mess up with multitap games, and make them think you're connecting a mouse, or a superscope, if mapping is faulty, then we know where to look). Try this with your N30 and let me know if the problem is fixed.

That's very interesting about use the macOS mode. I will try that. In my case, they are all mapped in Windows mode using START + UP (see https://download.8bitdo.com/Manual/Mod-Kit/Mod-Kit-for-NES-Original&Classic-controller.pdf). @darthcloud added support for the N30 as part of 1.8.2 assuming the Windows mode, I believe.

In my case, all four controllers are paired even before I launch the game from the clone Super Everdrive menu. NBA Jam recognizes a multitap (showing only 2 options), and whether I start a new game or go into options, pressing start on the player 4 controller, which is a PS3 controller, doesn't do anything. But then if I start pressing other buttons (I didn't carefully check which ones), suddenly the game shows that error screen. So it's possible that it's related to mapping, as you suggest. I can try the macOS mode for my two N30 controllers. I also have 2 other PS3 controllers that I could test with, so that would make 4x PS3 controllers, and this could also help understand the bug.

So here's what I'll do:

  1. Try 1.7.3 + your patch (NES30's paired in Windows mode)
  2. On 1.8.3: try NES30's paired in MacOS mode
  3. On 1.8.3: try 4x PS3 controllers on 1.8.3
DigiDwrf commented 1 year ago

OK good, let me know what did you find, I'm going to test 1.8.3 in my device.

DigiDwrf commented 1 year ago

The patch works fine in 1.8.3, just tested it and no issues. I don't use N30 or PS3, so I can't test it with those controllers, I'm using SN30, SF30 pro and 2 PS4 pads. This has to be related to snes data mapping for those controllers then, or maybe a hardware issue. Tested my SN30 controler with START+X and worked fine too (so this was fixed I guess). I'll keep making tests and let you know if I find any problem. 4p and 5p uses the same timing, could you try another game? (e.g. pieces or any other nba game)

darthcloud commented 1 year ago

Wired side and Wireless are completely independent beside a single async shared buffer.

You should always see maximum player at the console side regardless of # of bluetooth controller connected (or type for that matter).

If his setup work in 1.8.3 minus your change, I don't see how it can be related to BT side stuff.

DigiDwrf commented 1 year ago

Wired side and Wireless are completely independent beside a single async shared buffer.

You should always see maximum player at the console side regardless of # of bluetooth controller connected (or type for that matter).

If his setup work in 1.8.3 minus your change, I don't see how it can be related to BT side stuff.

Multitap loads fine, the problem occurs when buttons are pressed, so this particular controllers might be sending wrong bit data to the wired_adapter struct data inside main/adapter.c I guess. I've tested the last 1.8.3 firmware and found no issues at all, so I don't really think that the problem is related to this part of the code, but somehow, it triggers this problem with these controllers.

The code is huge, so knowing exactly where and why this happens is hard. Which part holds information about wireless controllers data sending to the shared buffer? I need to know where I can look into and track the bug (Im guessing main/adapter.c or main/adapter.h, but I'm not sure).

@amaiorano have you tried both ps3 and N30 controllers as 4p? or this just happens with one particular controller type?

amaiorano commented 1 year ago

Okay, I finally got myself all setup and tested everything. Here are my results:

Setup

First, I used another BlueRetro ESP32 adapter I made - one where I could disconnect the Vcc line so that I could plug it to my laptop. This let me do a few things:

  1. Easier to flash
  2. Was able to run idf.py monitor to see if there was anything logged when the bug occurred (spoiler: nope, nothing)
  3. Ensured the bug wasn't due to sharing the 5V rail of the SNES -- I wondered about this since I am also using a clone Everdrive, which I understand also uses more power.
  4. Would allow me to rule out whether it was the new BlueRetro adapter I made with the PCB (spoiler: it does).

0BC956E8-8ECB-4749-8944-A8E83C70BE44

Test Results

Conclusions

I'm not really sure where to go from here. I think only time will tell if this is really only PS3-controller + NBA Jam specific or not. Having said that, if you could get your hands on a PS3 controller or two, you could try to reproduce this problem on your end.

Unrelated: MacOS mode

Just a side note from me: using MacOS mode (A + START) on my N30 controllers makes my controllers significantly less responsive than Windows mode (UP + START). I tested all 4 N30 controllers in MacOS mode using the Controller Test Suite on my NES, and the response time was very poor, even player 1 and 2 (3 and 4 are always more laggy). I put them back to Windows mode, and the response time is better (P1 and P2 are super fast). Also, @darthcloud's support for the N30s in 1.8.2 are for Windows mode -- in MacOS mode, I am forced to remap the buttons for B to work (and A is mapped to B).

darthcloud commented 1 year ago

@amaiorano thanks for the extra tests it's really weird the BT device types affect the wired side.

I will try to look at it after I'm done with release 1.8.4

DigiDwrf commented 1 year ago

I have a pair or ps3 controllers. I'm going to test them and let you know my results.

The first thing that comes to my mind is that SNES support in general, is a bit slow to process for the esp32, so we're going to encounter timing related issues all the time. There's this game called Virtual Bart, and whether you use the previous unpatched code for multitap, or the new one, with multiplayer on, or off, inside blueretro.io, bart will jump (B button) randomly sometimes. This can be subttle or more frequent, depending on wich type of controller you use. I think this game in particular is bad coded. The first button in the bit row is "B" and the game might be sending LATCH or other signal when is not required (since it's not a multiplayer game, I've not analyzed this, but can't think in another cause) and this messes up with the "B" button state (so data is sent too late). Standard controllers ignore this because they're fast enough for the SNES, but the esp32 is more complex. I've experimented this from previous unpatched versions too.

As far as I can tell, the patch for that multiplayer void function is a bit faster that the previous code, and all the intermittent detections are now gone for every game. Some few games just won't never work because the GPIO is not fast enough, and the only way to make them work, or work propperly is by using an FPGA or second device that acts a single port, both, or multitap that handles all the SNES protocol, collects and sends asynchronorus data into the esp32, so no information would be lost.

I use a SD2SNES cartridge, so it could be a power issue too, like @amaiorano mentioned, but can't be sure about this.

@amaiorano Have you tried any other multitap games, with and without the patch and see the difference? Top gear 3000 was unplayable, and now it works, but it has the same "B" button self-pressing issue in the game's menu at random times (this doesn't happen to often also). All NBA roms work as expected in my case, so I will make this ps3 controller tests. I remember this NBA game to disconnect 4th controller randomly before the patch, I might be wrong at this, but most NBA games sufrered from this problem (with both 4p and 5p, they are read almost at the same time after 2p and 3p).

Important note: this patch has a on/off switch, like the real hardware. This function occurs when LATCH goes high: If you press L+R+DOWN+B on the second controller for a brief time, multitap will be virtually "unplugged", and pressing B on 3p will attach it again. This is VERY usefull when you don't want to change configuration inside blueretro.io, works for games that demand multitap to be unplugged before using them (like Yoshi's Island and other first party games), and games that use the third port in multitap as the second port in snes (e.g. Battletoads in Battlemaniacs once you enter in game, 2p won't do anything and 4p will work instead, this one has a buggy code too that sends unnecessary SELECT data, I could say this might happen on real hardware as well). We could try dissabling this part of code to speed it up and make tests again, but if we encounter the same problem, I wouldn't dissable this switch.

@amaiorano Is it possible to record the bug in video so I can see better what is happening and how is triggered?