djhackersdev / bemanitools

Runs recent Konami arcade games and emulates various arcade hardware.
The Unlicense
84 stars 16 forks source link

Random button presses/misfiring #89

Closed icex2 closed 1 year ago

icex2 commented 3 years ago

Copy-paste of a bug report from pigstall:

I have a very particular problem running bemanitools on IIDX Happy Sky, sometimes the game will just randomly send me to test mode when I’m not even pressing anything, it’s gets very infuriating sometimes when I clear a song and I don’t have anytime to take a picture of the score and whenever I check to see the log on why it’s happening I always see something like this

MzX2569

It’s always the settings path being remapped, is there anyway to fix this? I’m not 100% sure it’s the tools fault since Happy Sky is what, 16 years old? Old data can be fucky but I’ve never seen this issue with any other tools I’ve used

icex2 commented 2 years ago

In GitLab by @mon on Jan 6, 2022, 10:45

This happens with jubeat Knit, too. I thought it was some weird input buffering but it seems like there is actually a common thread between the old games here.

icex2 commented 2 years ago

Can you be more specific with "old games"? Are only certain versions of jubeat affect and if yes, which ones exactly?

Also noting that I am getting the same symptoms on pumptools which is a different project and running on Linux. What connects this to BT5 somewhat is the similarity in architecture of the iohooking system which copy-pasted parts of the IRP approach.

The symptoms appear more often on certain versions in the past (can't name any specific versions unfortunately) and are also happening to some people more often than others (different setups).

My assumptions based on these observations are that the hooking framework (capnhook) has some sort of concurrency issue, e.g. buffer/variable write visibility between threads.

I remember trying to debug this on the ezusb layer once but the state variables were not affected (printing to log when something gets triggered, game showed misfiring but no output was printed to the logs).

icex2 commented 2 years ago

In GitLab by @mon on Jan 8, 2022, 24:45

"Old games" in this case is just "I've seen it in knit, someone else has seen it in Knit, this issue is Happy Sky, there might be a common thread". I don't have any other instances of it happening.

It's a little odd that in both cases, despite totally different IO hooks, it's test mode. That makes me think there might be something more complex at play rather than just funky IO hooks. How do Pump's issues manifest?

I foresee I might need to actually trace the "enter test mode" functionality in Knit to truly get to the bottom of this.

icex2 commented 2 years ago

It's a little odd that in both cases, despite totally different IO hooks, it's test mode. That makes me think there might be something more complex at play rather than just funky IO hooks.

I have seen this happening during gameplay on IIDX as well which results in all buttons getting triggered at the same time (because you cannot go into the test menu during the game). I think the symptom of "the game entering the test menu" shows because every arcade game will go into test menu once the corresponding input is triggered. Pump is no exception there, see also here.

I foresee I might need to actually trace the "enter test mode" functionality in Knit to truly get to the bottom of this.

I am pretty sure, though having no proof, that this is a dead end. Since this stuff happens across different games (IIDX vs. jubeat) with different IO hardware emulations (ezusb vs. p3/p4 io) and even across different code bases/toolsets (bemanitools vs. pumptools), this indicates to me that we have a fundamental issue somewhere in the (io)hook stuff.

Again, pointing out that pumptools shares a lot of architectural aspects with BT5 as I took capnhook's architecture and applied it to pumptools to a great extent.

icex2 commented 2 years ago

In GitLab by @mon on Jan 9, 2022, 23:59

I have seen this happening during gameplay on IIDX as well which results in all buttons getting triggered at the same time

Now this is interesting - how long does it last? A single frame/input cycle, or longer?

icex2 commented 2 years ago

Can’t give you a concrete number on frames/cycles but all inputs are only getting triggered “once”, i.e. i see all buttons pressed once and released (beams lighting up briefly and key sound noise).

icex2 commented 1 year ago

Debugging another issue but also running into this again and re-reading the previous comments, I noticed that probably the common denominator for this is the DeviceIoControl call as it overlaps with both, jubeat and iidx, in order to read inputs from the IO. Since this issue seems to be appearing randomly, I still assume it is some sort of race condition. This might be around the only critical section in the live path when the game is banging the DeviceIoControl call in iohook's iohook_invoke_next function.

A lot of assumptions, but maybe something might be useful later.

icex2 commented 1 year ago

I finally figured this out and fixes are provided in https://github.com/djhackersdev/bemanitools/pull/236 and are included in the 5.44 release.

For details, see the PR and relevant commits related to the misfiring issue. I have everything explained in detail in the commit messages and as comments in the code.