mjrgh / PinballY

A table browser and launcher ("front end") for virtual pinball cabinets.
Other
46 stars 22 forks source link

Continuous scrolling in selection wheel after only single button press #203

Open TrucksO opened 2 years ago

TrucksO commented 2 years ago

Describe the bug The selection wheel at random times starts scrolling through multiple tables as if a button keeps getting held down, even though it was just a single, short press. For my system, this happens quite often, about 1 out of 5 button presses. At friends' VPins this is less frequent but still comes up, sometimes in the form of "double clicks/double jumps" instead of continuous scrolling. For some reason, this bug does not happen in PinballY versions 1.1.0 Beta 1, only higher versions.

To Reproduce

  1. Use PinballY version 1.1.0 Beta 2 or higher
  2. Start PinballY
  3. In the table selection wheel, press one of the flipper buttons (left, right, left magna save or right magna save) for a short time and immediately let go (just as if you wanted to move only one table/letter)
  4. At seemingly random, PinballY will now start to scroll through the tables
  5. Press one of the flipper buttons (again)
  6. Scrolling should stop now

Alternatively, instead of steps 3, 4 and 5 the system will jump two steps instead of one, as if the button had been pressed two times in quick succession.

Expected behavior When pressing left or right flipper, it should jump one step to the next table on the left or right, respectively. Same goes for the magna except that here it should jump directly to the next letter.

Windows version Windows 10

Additional context To rule out potential problems with the flipper buttons' hardware, I tried pushing the buttons with a keyboard - same result. I also did a quick check of the registered button presses in Windows by assigning the flipper buttons to letters in Pinscape. When I then went into e.g. Notepad and pressed the buttons, it would register exactly one letter instead of multiple when I held down the button. This would imply to me, that at least on the hardware side and in Windows itself, the "registration of the keys" for lack of a better word works fine.

fernandojconti commented 2 years ago

Happens to me too every once in a while. I haven't found any solution so far.

MikePinball commented 2 years ago

Just to note that I see this problem quite a lot. I have not been able to isolate it.

mjrgh commented 2 years ago

I haven't been able to reproduce this on my machines, so I'm afraid I can only guess at what might be going on. It's undoubtedly related to the wheel-spin acceleration change I made in 1.1.0 beta 2, since that intentionally changed the keyboard auto-repeat handling. But beyond that, it's guesswork on my end, because I can't replicate it and therefore can't catch it in the act to trace through whatever code is going wrong. The OP is on Windows 10, and I'm testing on 7 and 8.1, so maybe it's some subtle change in Win 10 to the way the system delivers WM_KEYxxx events that I'm not accounting for properly, although I haven't seen any documentation to suggest there are any such changes. Or maybe it's something hardware-specific. At any rate, as a wild guess, I've added some extra key state checks to try to stop the auto-repeat even if the key-up events go missing. Testing on my machine obviously doesn't tell me if it'll make any difference, since I can't seem to replicate the problem in the first place, so hopefully someone who's been experiencing the problem will be able to try it out. 1.1.0 beta 6, just posted.

jueank commented 2 years ago

Thank you very much for taking care of this issue! I did a quick test with beta 6 (will look closer when I'm back home). The issue still remains being present (using Windows 10). However, there is a change in behaviour. Previously, when the wheel was scrolling into one direction, a keypress with the opposite flipper button lead to the wheel immediately spinning into the other direction. Now, the wheel stops spinning at that position. Maybe this observation helps a bit. I think the initial issue with somehow not detecting the keyrelease and thus starting to scroll is not affected by the code change.

Further observation: The unwanted scrolling starts only if a flipper button is released very quickly after pressing the flipper button. When the flipper button is held until one or more than one table is cycled and then released, the scrolling does not continue. Another observation: After using PinballY for a short time, the issue disappeared. I could navigate as intended and the scrolling did not start, even when quickly pushing and releasing flipper buttons. I don't know what caused that change in behavior.

mjrgh commented 2 years ago

Thanks for trying it. Sounds like my guess about the cause was wrong. I don't have any other ideas at the moment, but I'll let you know if I think of anything. Out of curiosity, do you get any sticky repeat problems anywhere else other than the wheel spin? E.g., if you press Start to open the Play menu and press Next, can you get the sticky repeat to happen there as well?

jueank commented 2 years ago

Thanks for trying it. Sounds like my guess about the cause was wrong. I don't have any other ideas at the moment, but I'll let you know if I think of anything. Out of curiosity, do you get any sticky repeat problems anywhere else other than the wheel spin? E.g., if you press Start to open the Play menu and press Next, can you get the sticky repeat to happen there as well?

No, any other interaction works just fine (start, exit, menus)

mjrgh commented 2 years ago

Some more things to try:

  1. You mentioned that the spurious wheel spin stops when you press the opposite direction key. What happens when you press the same key while it's spinning? E.g., tap Next, let it spin, tap Next again.
  2. Go to the Options dialog > Game Wheel section, and enter this in the Auto-Repeat Rate box: 1000, 1000, 500, 500, 250, 250, 125. That will make the first two auto-repeats at 1-second intervals, the next two at 1/2 second intervals, the next two at 1/4 second intervals, and then 1/8 second from that point on. The slow rate is so that you can easily gauge the times by observation without a stopwatch. a. Let's check if the speed ramp is working when you INTEND it to auto-repeat. Press and hold Next. Do you observe the expected speed ramp in the wheel spin? b. Now repeat the test with just tapping Next to invoke the spurious wheel spin. Do you observe the same speed ramp this time? c. Repeat test (1) above (tap Next, let the spurious auto-repeat go, tap Next again to see if it stops it). But this time, wait until the speed ramp has reached the fastest speed before trying to stop it. If tapping Next at that point doesn't stop it, does it have any effect on the speed? That is, does it restart the 1s-1s-.5s-.5s-.25s-.25s-.125s speed ramp, or does the wheel just keep spinning at the high 1/8-second speed? Or something else?
  3. What happens when you intentionally press and hold the Next button for various periods? For example, press and hold for 1 second, press and hold for 2 seconds, press and hold for 5 seconds, press and hold for 10 seconds. Is there any difference in how often the spurious auto-repeat happens for different hold times?
jueank commented 2 years ago

I think I found the cause for the issue while following your instructions. Step 1 is before I found the cause. I just left it in.

  1. When pressing the SAME key/flipper button, the wheel spinning continues, but the speed is reset to the initial ramp-up value. Btw. the same happens when I press the OPPOSITE key/flipper button quickly. It immediately starts to spin in the opposite direction. This is a correction to what I wrote above. The spinning only stops by pressing the opposite key/F.B. when I hold it for a 'moment' and don't release it immediately.
  2. I'll describe what i did for step 2: For this I set the repeat rate to '1000, 1000, 500, 500, 250, 250, 125'. When cycling through the tables by holding the flipper button, I observed that the speed for showing the sequence of tables 'fluctuated' and paused for fractions of seconds while at the same time the virtual DMD updated to show the manufacturer logo animation & table name. (This fluctuation is not apparent when using the much quicker standard repeat-rate) At that point I wasn't sure if this fluctuation would influence my observations for the spinning issue we are after and disabled the virtual DMD altogether ([virtualdmd] enabled = false in C:\Visual Pinball\VPINMAME\DmdDevice.ini). After restarting PinballY with now disabled virtualDMD, the cycling/spinning behavior works flawless! It works perfect with '1000, 1000, 500, 500, 250, 250, 125' but also empty input field for the repeat-rate. The wheel stops reliably when lifting the flipper button and so far it did not start to spin uncontrolled. At this point, my assumption would be that the virtualDMD switching its content from table A to B simultaneously while the flipper button is pressed might either steal the keyboard focus (for a fraction of a second) and assigns it to the DMD window or otherwise influence how PinballY can reliably react to the 'keyp_up' of the flipper button. Btw. I updated extDMD yesterday to the newest (1.10.2) version, but the issue was also present with the version I used before (1.9)

I hope this helps to find the root cause and get rid of the issue.

mjrgh commented 2 years ago

After restarting PinballY with now disabled virtualDMD, the cycling/spinning behavior works flawless!

That's a great discovery. Hopefully that'll finally let me reproduce it and see what's going on internally. I expect you're exactly right that it's some kind of keyboard focus switching issue. I'll take a look at it and see what I can find.

mjrgh commented 2 years ago

I did a little quick testing with DMD-extensions 1.10.2 enabled, and I'm still not seeing the spurious auto-repeat. I also haven't noticed the change in repeat speed, so you might be onto something that they're related. Is there any common thread you notice in when the speed change happens? I'm thinking it could be something time-consume on the DMD-ext side that you have configured per game, like loading new media or something like that. Can you think of anything like that that you've configured on the DMD-ext side? If so, maybe try turning that off and see if that changes it - maybe we can further narrow down the specific cause not just to DMD-ext but to some particular configuration issue with DMD-ext. At any rate, it seems like the "vanilla" configuration of DMD-ext doesn't cause it all by itself, at least for me.

jueank commented 2 years ago

I'm thinking it could be something time-consume on the DMD-ext side that you have configured per game, like loading new media or something like that. Can you think of anything like that that you've configured on the DMD-ext side? If so, maybe try turning that off and see if that changes it

I think you are right. My extDMD config looks like below (inner glow, outer glow, backgroundimage, ...). But I think that extDMD is only a part of the problem. See below the code section for the tests I did and my conclusion.

[virtualdmd] ... style = default style.default.backgroundcolor = #ff000000 style.default.foreground.enabled = true style.default.foreground.size = 0,8 style.default.foreground.opacity = 1 style.default.foreground.luminosity = 0 style.default.foreground.rounded.enabled = true style.default.foreground.rounded = 0,7 style.default.foreground.blur.enabled = false style.default.innerglow.enabled = true style.default.outerglow.enabled = true style.default.background.enabled = false style.default.innerglow.size = 1 style.default.innerglow.opacity = 0,6 style.default.innerglow.luminosity = 0 style.default.innerglow.rounded.enabled = true style.default.innerglow.rounded = 1 style.default.innerglow.blur.enabled = true style.default.innerglow.blur = 54 style.default.outerglow.size = 8 style.default.outerglow.opacity = 0,15 style.default.outerglow.luminosity = -40 style.default.outerglow.rounded.enabled = true style.default.outerglow.rounded = 1 style.default.outerglow.blur.enabled = true style.default.outerglow.blur = 500 style.default.foreground.unlit = false style.default.foreground.unlit.color = #00000000 style.default.innerglow.unlit = false style.default.innerglow.unlit.color = #00000000 style.default.outerglow.unlit = false style.default.outerglow.unlit.color = #00000000 style.default.brightness = 0.95 style.default.dotsize = 0.92 style.default.dotrounding = 1 style.default.dotsharpness = 0.8 style.default.unlitdot = #00000000 style.default.dotglow = 0.154471544715447 style.default.backglow = 0.154471544715447 style.default.gamma = 1 style.default.tint = #00ff5820 style.default.glass = C:\Visual Pinball\VPinMAME\DMDext\textures\glasses\glass3.jpg style.default.glass.color = #ff808080 style.default.glass.lighting = 0.5 style.default.glass.padding.left = 0 style.default.glass.padding.top = 0 style.default.glass.padding.right = 0 style.default.glass.padding.bottom = 0 style.default.frame = style.default.frame.padding.left = 0 style.default.frame.padding.top = 0 style.default.frame.padding.right = 0 style.default.frame.padding.bottom = 0

I did these tests:

  1. extDMD enabled, above config in place (glow + background image enabled). Result: Cycling through the tables leads to uncontrolled spinning with every keystroke. --> Key_up is not detected.
  2. extDMD enabled, above config removed from dmddevice.ini (basic extDMD config). Result: Cycling through the tables is 50% ok, 50% not ok (uncontrolled spinning happens). My observation: When I hold the flipper button down long enough until extDMD has finished switching to the next manufacturer logo and then lift the flipper button - but before the spinning starts because of the flipper button held down - everything is ok: No uncontrolled spinning starts. When I hit the flipper button and release it immediately while extDMD is busy uncontrolled spinning starts.
  3. extDMD enabled like in step 2. This time - just by chance - I was navigating between 2 new tables which do not have any media present (no backglass image, no table image, no topper image). In step 1&2 I was switching between regular tables which usually have all three assets present. Result: Hitting the flipper button - even when released immediately - works ok. No uncontrolled spinning starts, I can reliably toggle back and forth between the two tables. (Although extDMD still had to switch to the next manufacturer logo!)

My final conclusion: It's the combination of 3 assets being loaded (bg, table & topper image) plus extDMD being updated which affects PinballY detecting the key_up. It might be that even when not using extDMD at all, but with an even heavier load of assets (videos) the same issue might be triggered as well. But that's just an assumption...

mjrgh commented 2 years ago

I'm going to try adding some logging to see if I can see some more about what's going on internally. Do you use the 32-bit or 64-bit build?

jueank commented 2 years ago

I have an important remark. And I'm sorry that I didn't thought of it earlier. The manufacturer logos + table title names are shown on the virtual DMD through that PinballY flexDMD.js extension (leveraging vbousquets flexDMD rendering lib. You know that..) - I could not for the heck of it remember where the manufacturer logos + table titles were coming from (I added the .js extension long ago before I paused using my cab over the season and forgot about it). Long story short: I disabled (commented out) the flexDMD.js extension and voilá, navigation with enabled extDMD + usual table assets (BG, table, topper) works also flawless. So I think we can narrow it down to the way flexDMD is ues through your Javascript API.

mjrgh commented 2 years ago

That's good to know. There does seem to be a basic problem with the way the flexDMD add-in works, in that it invokes a long-running operation on the main foreground thread, which blocks UI activity for a noticeable amount of time - that really needs to be moved onto a background thread in the flexDMD code. But even so, the keyboard behavior you're seeing is still weird.

Did you see my question about which version (32 or 64) you use? I want to post a private build with some additional logging for you to try out, to see what's going on with the keyboard.

jueank commented 2 years ago

Sorry, I missed that. It's the 64-bit version.

mjrgh commented 2 years ago

Sorry for the delay. Here's the test build - it's just the main .exe, which you can extract and replace your existing one with. Launch it, do the usual steps to trigger the nonstop spinning, let it run for a few seconds, and close the program. Post the PInballY.log file. It should have a bunch of data on the keyboard status during the repeats - which probably won't provide an answer but might at least point to the next thing to look at.

pinbally-keylog-20220727.zip

jueank commented 2 years ago

np. Now how to start... I cannot reproduce the uncontrolled wheel spinning anymore (at least for now)! This came also as a surprise to me when I re-enabled all setting that I disabled inbetween so that PinballY is usable for me (commented out FlexDMD.js in main.js + set [virtualdmd] enabled to false in dmddevice.ini) I re-enabled both for doing the keyboard logging, but the uncontrolled spinning did not occurr. Neither with the regular PinballY exe, nor with the keylog version. First I felt bad because you provided this test build after my feedback and me not being able to report any keyboard logs.. But then I was thinking about what I changed recently in the cab. And since PinballY behaves differently in regards to the spinning issue, I figured this might help to further track down the root cause. Let me summarize what I did in the last few days:

  1. In the options dialog -> real DMD, I switched from 'Disable always' to 'Automatic'. I did this more or less 'out of the moment' without properly testing if this makes any difference. In order to rule this out as a reason why the uncontrolled spinning does not occurr anymore I switched back and forth between the 2 settings today. This made no difference. I want to mention it nevertheless. Maybe you know better if this might be relevant or not.
  2. I switched to another PC for my cab some months ago and made a fresh Windows 10 installation. Most of the stuff that worked before was working again, except for my LED strips left & right to the playfield + the LED matrix at the end of the playfield. The strips/matrix are controlled by a Wemos D1 instead of a Teensy and with the PC I used before I had a patched directoutput.dll. The Wemos D1 is configured using a TeensyStripController element in the cabinet.xml of DOF. This worked perfectly in my old PC. In the new PC I did not had the patched directoutput.dll at hand, but still had the TeensyStripController element present in the cabinet.xml. So the LED strips simply don't show anything, because the communication to the Wemos D1 fails. Now comes the important part: This is the configuration that was present in the new PC when I reported about the uncontrolled spinning in PinballY. That is: Wemos D1 firmware which expects a patched directoutput.dll, but I was using the regular directoutput.dll from DOF and using a TeensyStripController configuration. Until now I was not aware that this might have been relevant for the uncontrolled spinning issue... Since I wanted to get the strips running again, I had a look at Arnoz tinytools 2 days ago. I did not remember which firmware I flashed to the Wemos D1 back then when I set up the LED strips initially. Therefore I flashed a new firmware to the Wemos D1 from Arnoz tinytools. I also updated the Silab CP210x Windows drivers using the ones from Arnoz tinytools. I also switched to the patched directoutput.dll from Arnoz tinytools. Finally, I replaced the TeensyStripController element in cabinet.xml by a WemosD1MPStripController element (properly configured by hand, not using Arnoz tinytools). This DOF & LED setup is working perfectly in PinballY & PinballX since 2 days. This is in my opinion the most important change in the cab since I reported the spinning issue days and weeks back. Today, I tried to reconfigure everything again the way I had it in the old PC: I switched back to a TeensyStripController element in cabinet.xml. I also switched back and forth between the patched directoutput.dll from Arnoz tinytools and the original directoutput.dll from DOF. The only thing I cannot recreate is going back to the old firmware that I had on the Wemos D1! Maybe that is the ultimate reason why I cannot provoke the uncontrolled spinning again. The reason I think that the communication of PinballY to DOF/directoutput.dll is relevant for the spinning issue is because with every switch to another table, the LEDs in the matrix are updated with another pattern. And potentially - when the communication through the COM port fails (because of the mismatch of Wemos firmware / directoutput.dll / TeensyStripController config) this might affect the timing of PinballY and keyboard events. There is another thing: While I was configuring the NEW LED & DOF setup using the things from Arnoz tinytools (the LED strips were already working) I had at least 10 random cases where PinballY freezed the moment I started a table. PinballY was hanging in the 'Loading...' or 'Running...' state of the table (I don't remember which one). I had to use the Task Manager to kill the PinballY process. I switched from WS2812B to WS2812 firmware (because I did not remember which was the correct type) and also switched from using compression to not using compression. PinballY never froze like that and I am 99% sure that it was caused by some incorrect DOF/Wemos config. Since VPinballX.exe (or B2SServer?) is talking to directoutput.dll just like PinballY does, I figure there might be a reason why a crash can happen exactly when a table is 'started' while something is wrong with the communication of PinballY to DOF. There is one more final thing: In GlobalConfig.xml of DOF I switched the value of LedWizDefaultMinCommandIntervalMs from 1 to 10 because in the 2 other files (the specific ones for B2SServer(?) and PinballY) have a value of 10 there. I did not switch this back yet. Maybe this timing setting might also affect the keyboard behavior and spinning issue.

I know, I wrote a lot of stuff here. But maybe it helps to fid the root cause.

mjrgh commented 2 years ago

I'm afraid that's a bit too much new information for me to speculate about a root cause or to try all of the different combinations myself. If you can't get the problem to reproduce any more no matter what you do, then it's as good as solved for your setup, and you can just call it done and move on. I'll leave the issue open so that the next person who runs into it can read back through what you've tried so far and pick up where you left off. If you do feel motivated to keep experimenting, nothing beats the scientific method - change one variable at a time, test after each change, repeat until you can identify one thing where you can conclusively demonstrate that if you do X, the problem manifests, and if you don't do X, it doesn't.

jueank commented 2 years ago

Sure, for the moment I'm fine with my cab. I really wanted to help you fixing the problem for anyone. Therefore I wrote all the details above. Ultimately it boils down to the following: If there's a problem with the communication to the LED controller / directoutput.dll, it might affect PinballYs timing and ability to react to the keyboard events.

mjrgh commented 2 years ago

I really wanted to help you fixing the problem for anyone. Therefore I wrote all the details above.

Certainly any information could turn out to be useful, so I appreciate you noting it all down for future reference.

Ultimately it boils down to the following: If there's a problem with the communication to the LED controller / directoutput.dll, it might affect PinballYs timing and ability to react to the keyboard events.

It's probably more productive not to speculate on an underlying theory of the root cause until we have a solid isolated test case, since these sorts of perceived correlations so often turn out to be red herrings. I wouldn't rule out a DOF delay as somehow related, although that doesn't suggest anything to me about what the underlying cause could be, so it could just as well be coincidental or randomly correlated. Hopefully someone will be able to isolate the real test case at some point - there's evidently some set of conditions that causes it given that you were able to reproduce it so consistently in your old setup.