@elishacloud
Thanks for all the work you are doing here. While doing play testing I stumbled upon a bug/"quirk" with the game and rumble. If you time it right and open the PC pause menu (Esc key, P key, or gamepad button equivalent) at the very start of something that initiates a rumble, the rumble will continue indefinitely while the PC pause menu stays up.
Video example: https://www.youtube.com/watch?v=pQQx7VVxv4I
(The console versions never had a pause menu like this so I think when the PC devs added this menu in they probably didn't think to test how rumble would affect their new menu.)
Can an adjustment for rumble be made to do the following. The address and notes below were found by Bigmanjapan:
sh2pc.exe+542670 (00942670) byte
This address changes it's value from 0 to 2 (there is a value of 1 for a splitsecond inbetween) upon invoking Pause menu. Nothing else seems to be tied to the address.
So when sh2pc.exe+542670 (00942670) byte has a value of 2 can a stop signal be sent to the current rumble output? Possibly added to this portion of code?
I don't have a controller with force feedback in it that works on my PC so I cannot test this. However I implemented a very quick and dirty hack so that when sh2pc.exe+542670 (00942670) byte has a value of 2 I call the Stop() function once to stop the force feedback. Not sure if this will work.
Test module: d3d8.zip
_Note: this only works on v1.0._
Thanks, Elisha. Unfortunately, the quick fix didn't work for this.
Ok, it looks like maybe I was calling the wrong instance of Stop(). Try this one: d3d8.zip
Edit: if this does not work please send me your logs. There may be data in there that will help.
Unfortunately this one did not work.
Here is the log for this: d3d8.log
It looks like it is correctly calling the Stop() function. Maybe sending the Stop() function is not correct. We may need to have SH2 trigger the stop. I don't think I will figure this out by stabbing in the dark. Someone will need to troubleshoot this properly.
I noticed that this problem never occurs with the inventory screen. We should check what the game does differently for that menu.
00940EB6 (Byte)
The game uses this address to disable/enable the rumble when the inventory menu is opened. The issue I have right now is that I have to restore the value to 01 when the game is not paused. That's easy to do, but the rumble loop returns when I exit to the main menu because that part of the game isn't considered paused.
but the rumble loop returns when I exit to the main menu because that part of the game isn't considered paused.
So you've experienced this, too? I didn't bring this up because sometimes it keeps rumbling if I exit to main menu and other times it doesn't. So I wasn't sure if this was an isolated "thing" just for me or not.
Could we make it to where:
Or is that oversimplifying things too much?
Yes, good idea, that should work. I'll give it another try tomorrow.
@Polymega Cheat Table
Well done, Aero_. Tested in numerous spots and all seems well. The only other possible recommended addendum would be to set the rumble byte to 0 if the game/application loses focus which would be an @elishacloud thing, as the game will infinite rumble still that way if it loses focus at the start of a rumble point.
Great job with this!
I should be able to do both of these with just C++ code if I know what byte to set and when to set it.
Here is what I have so far:
sh2pc.exe+542670 (00942670) bytesh2pc.exe+540EB6 (00940EB6) byte?00942670 (byte) - Determines if PC Pause menu is pulled up. (Only determines the PC pause menu, no other menus.)00940EB6 (byte) - Toggles rumble acceptance on/off. Setting to 1 doesn't rumble the motors, it just allows the game to push rumble signals to the controller.Here is what I have so far:
That all seems correct. However, the only other thing is if the infinite rumble initiates and we stop it in the pause menu, but the user then returns to the main menu from the PC pause menu, the rumble will pick back up in the infinite loop within the main menu until they either fully exit game or load up another save point.
This is how the following suggestion also came into play (basically add this to your bullet points above):
This is because things like the main menu, credits, end results screen, etc. all have Room IDs with a value of 0.
Refer to Aero_'s comments below.
But Aero_ should give his final blessing on my notes as he's much more adept with this.
@elishacloud
You need to nop this call to stop the rumble loop from occurring in the main menu.
00497D71 call 00458330 // writes 01 to rumble address when returning to the main menu
Then you simply write 00 to 00940EB6 (rumble address) whenever the game is paused. When the game is not paused, you write 01.
Rumble address pointer: 004589CD, Offset -2 = 00940EB6 (byte)
But Aero_ should give his final blessing on my notes as he's much more adept with this.
Sorry, I forgot to comment on this. Your notes were fine, it's just that I solved the issue with the main menu a different way that didn't require the Room ID check.
Below is a test module. This should fix both issues; infinite rumble when in the pause menu and infinite rumble when the window focus is lost.
Test module: d3d8.zip
_Note: this only works with v1,0._
Thanks, Elisha! It's working good on the PC pause menu but the rumble will pick back up and continue indefinitely on the main menu if you time it right on the PC pause menu and quit to main menu still. (The nop'ing fix Aero_ mentioned above is the fix for that part.)
Also, I still get infinite rumble if I lose focus at the start of a rumble initation. This is being tested on my Win7 machine, if that makes any difference.
I did nop the function mentioned by @AeroWidescreen. But I see what is happening. After you leave the pause menu to enter the main menu I set the rumble address back to '1' because you left the pause menu. This means that even though the function is nop'ed it will still rumble because the rumble bit is on. I may need to check the room ID to fix this.
I still get infinite rumble if I lose focus at the start of a rumble initation.
Did you check the rumble address when this happened? I am fairly confident that the rumble address gets set to '0' when focus is lost. It is possible that more than just setting the bit is needed here.
@elishacloud
Yeah, in my Cheat Table I modify a function that is _not_ active when you're in the main menu (in addition to the nop) which allows the value to rest at 0. But since your C++ code is always active, the rumble value is being changed back to 1 because it thinks the game isn't paused anymore.
Did you check the rumble address when this happened? I am fairly confident that the rumble address gets set to '0' when focus is lost. It is possible that more than just setting the bit is needed here.
Duh. Why didn't I think of this? Sorry, I did a full-length play test just moments ago and my brain tends to get a little jello-y after that. Yes, the value gets set to 0 when the game loses focus, even though it continues to rumble.
Ok, here is an update that fixes the main menu issue. This also simplifies the code a bit. d3d8.zip
As far as the loss of focus we probably need to call some function once the focus is lost to actively stop the rumbling. @AeroWidescreen, would you be able to look into this?
Ok, here is an update that fixes the main menu issue.
Nice! Confirmed working!
@Polymega, I updated this to work on all versions of the game. I also added some debug logging. Can you run a few tests with force feedback and send me the log? Test the infinite loop fixes with the pause menu and also test the infinite loop issue when focus is lost.
Here is the test module: d3d8.zip
Hi Elisha,
Here are my notes:
No rumble on: | PC pause menu | Main menu from pause menu | Lost focus
-- | -- | -- | --
v1.0 | :heavy_check_mark:聽 | 聽:heavy_check_mark: | 聽:heavy_check_mark:
v1.1 | :heavy_check_mark:聽 | :x: | 聽:heavy_check_mark:
DC | :heavy_check_mark: | :x: | 聽:heavy_check_mark:
Here is a log file. I alt + tabbed probably 2-4 times during this session as I was mostly focusing on seeing if the trouble would come back up on the main menu: d3d8.log
Thanks for the tests and the log! Can you explain the results a bit more. I have two questions:
Absolutely!
Does this mean the infinite rumble issue is fixed with this update when focus is lost?
Yes, it seems this is fixed for all versions of the game. Along with rumble being disabled when the PC pause menu is pulled up.
Does this mean that the rumble issue is still happening in v1.1 and vDC when switching from the pause menu to the main menu?
Correct. So if you time bringing up the PC pause menu to initiate the infinite rumble it will no longer do that while the pause menu is up. However, if you proceed to quit to main menu the rumble will pick back up once again while on the main menu. This is fixed for v1.0, but not for the other versions.
I tried manually running the Stop() effect function when focus is lost. Glad to see that fixed the issue! The issue with the main menu was that I forgot to remove the hard coded v1.0 address. This update should completely fix this issue. d3d8.zip
Oh, jeez. Okay, this works great! But upon play testing I found it also infinite rumbles if you time it for the PC pause menu then go to the Options menu or Save/Load screen as well.
Or, in other words, if you time it for the PC pause menu then go to _any other_ menu from the pause menu (main menu, Options screen, or Save/Load screen) the infinite rumble will pick back up.
However, good news, as I think I found the addresses (on v1.0) for them. This was also a fun excuse for me to try and exercise my rookie Cheat Engine skills some more:
Options menu - sh2pc.exe+541600 (00941600) Byte 0 = Off, 2 = On
Save/Load screen - sh2pc.exe+53C01E (0093C01E) Byte 0 = Off, 2 = On
If those addresses could get added to the fix that would cover all possible infinite rumble states through the PC pause menu.
Wait, why don't you guys use this address instead: 00932004
It indicates when the game is paused, which includes the options menu, inventory menu, etc. But not the main menu, obviously.
Perfect! Thanks @AeroWidescreen! Let me try with this address.
Wait, why don't you guys use this address instead: 00932004
_Niiiice!_ Elisha, this is a byte that changes from 0 to 1 (not 2). 0 = Off, 1 = On. It will be set to 1 when any of the following happen:
However, its set to 0 for the main menu, so you'll need Aero_'s nop code for that, still.
Ok, try this update. This one is using the address from @AeroWidescreen. d3d8.zip
Stick a bow on this, Elisha, 'cause it's done. :)
Checked in fix under 1361e7b.
Well, the new force-feedback gamepad I ordered to fix this issue came today! LOL
Beautiful timing, really!
I dare you to try and initiate an infinite rumble now; you and Aero_ have put that on complete lock down now. :)
Oh, PS - Is your gamepad DirectInput or XInput?
It supports both XInput and DirectInput. There is an option on it two switch between the modes. I got this one.
Okay, a heads up with that and play testing: XInput Plus will disable vibration for DInput gamepads. But we need XInput Plus for XInput pads.
So if you're using XInput Plus and switch your pad to DInput, you will need to set EnableX2Dinput = False in the XinputPlus.ini file.
I also wanted to tell you this for future troubleshooting, when someone inevitably downloads XInput Plus but then proceeds to use a DInput pad and wonders why vibration isn't working.
This puppy was a lot trickier than we imagined but you all pulled through! You all are rockstars!
An update has been released with this fix in it. See v1.3.1340.0