Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Xinput vibration CWCheat (PPSSPP specific 0xA code type) #12816

Merged
merged 1 commit into from
Apr 17, 2020

Conversation

LunaMoo
Copy link
Collaborator

@LunaMoo LunaMoo commented Apr 12, 2020

Just something I was fooling around with, this basically adds a new PPSSPP specific code type(0xA) which can set left and right vibration(separately) for Xinput gamepads.

Test CWCheat which applies various force and length on left/right(dpad/face buttons), button activated will work in any game, but ultimately with some test cheats this could be used to for example vibrate on character being hit or whatever.

_C0 Vibration TEST PRESS Keys to trigger
//Test different power
_L 0xD0000000 0x10001000 //Triangle
_L 0xA0000000 0x00F0FFFF
_L 0xD0000000 0x10002000 //Circle
_L 0xA0000000 0x00F02000
_L 0xD0000000 0x10004000 //Cross
_L 0xA0000000 0x00F06000
_L 0xD0000000 0x10008000 //Square
_L 0xA0000000 0x00F08000
//Test Different lenght
_L 0xD0000000 0x10000010 //Up
_L 0xA010F000 0x00000000
_L 0xD0000000 0x10000020 //Right
_L 0xA080F000 0x00000000
_L 0xD0000000 0x10000040 //Down
_L 0xA0F0F000 0x00000000
_L 0xD0000000 0x10000080 //Left
_L 0xA0C0F000 0x00000000
_C0 Vibration read from memory TEST
_L 0xA1000000 0x08801000
//activate this cheat after the read from memory test to start vibration
_C0 write to memory vibration values
_L 0x20001000 0xF000F000
_L 0x20001004 0x00F000F0
//and later this one to stop it
_C0 clear vibration values from memory
_L 0x20001000 0x00000000
_L 0x20001004 0x00000000

Syntax of the new cheat is:

0xA0NNLLLL 0x00MMRRRR
Where:
NN/MM is lenght the vibration last
LLLL/RRRR is the vibration power
can be set separately to left and right motor

syntax for read from memory is:
0xA1000000 0xNNNNNNNN
where 0xNNNNNNNN is the address that at the following offsets reads values for:
+0x0 = left vibration(u16)
+0x2 = right vibration(u16)
+0x4 =  left vibration time(u8)
+0x6 = right vibration time(u8)

When activated it constantly sets vibration and it's lenght, so it's use should be combined with test codes like 0xD/0xE to activate vibration on specific events or key presses.

With read from memory version we can for example rise vibration together with car speed or something alike althrough we still have to do the math in our own script injected to memory and hooked to game code that would provide the data in such format.

This currently works by sending cheat activated vibration and vibration lenght(dropout) to sceCtrl from where Xinput(potentially dinput and other vibration stuff in the future) can grab it.

Core/CwCheat.h Outdated Show resolved Hide resolved
Windows/PPSSPP.vcxproj Outdated Show resolved Hide resolved
Windows/XinputDevice.cpp Outdated Show resolved Hide resolved
@LunaMoo
Copy link
Collaborator Author

LunaMoo commented Apr 12, 2020

Sorry, I'll clean it later on:3, for now I'm wondering why the vibration doesn't change despite values being changed, unless I exit settings screen that somehow triggers it.

Copy link
Collaborator

@unknownbrackets unknownbrackets left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do like the idea of exposing vibration (and perhaps explicit touch position support) via cheats or game patches.

-[Unknown]

Windows/XinputDevice.cpp Outdated Show resolved Hide resolved
Core/CwCheat.cpp Outdated Show resolved Hide resolved
Windows/XinputDevice.cpp Outdated Show resolved Hide resolved
@LunaMoo
Copy link
Collaborator Author

LunaMoo commented Apr 12, 2020

I have a problem with using dll instead of xinput.lib, PPSSPP_XInputSetState, vibration.wLeftMotorSpeed seems to be rising by 1 every time I press anything on gamepad and vibration.wRightMotorSpeed is always 0. It's as if it was using XINPUT_STATE, but I made sure to change that to XINPUT_VIBRATION as well, unless I'm blind heh.
Also added prevVibration and a check to set it only on change, but despite it never changing, it's spammed every frame, I don't get why.

Edit:
Oh PPSSPP_XInputSetState get's set to same value(addres?) as PPSSPP_XInputGetState by that pointer I guess (LPCSTR)100 so need to figure out how to get XinputSetState pointer.

Windows/XinputDevice.cpp Show resolved Hide resolved
Windows/XinputDevice.cpp Outdated Show resolved Hide resolved
Windows/XinputDevice.cpp Outdated Show resolved Hide resolved
@LunaMoo LunaMoo force-pushed the XVibrationCheat branch 2 times, most recently from ae15e14 to ab13b71 Compare April 12, 2020 18:49
@LunaMoo LunaMoo changed the title Implement Xinput vibration cheat(WIP - help needed) Implement Xinput vibration CWCheat (PPSSPP specific 0xA code type) Apr 12, 2020
@LunaMoo LunaMoo added the Cheats label Apr 12, 2020
@LunaMoo LunaMoo added this to the v1.10.0 milestone Apr 12, 2020
Core/CwCheat.cpp Outdated Show resolved Hide resolved
Core/HLE/sceCtrl.h Outdated Show resolved Hide resolved
@LunaMoo
Copy link
Collaborator Author

LunaMoo commented Apr 13, 2020

That last push is just an unnecessary newline inside one of the functions that would bug me if I left it;3.

If the code is fine now I guess this is complete:). As for now I have no ideas about implementing Dinput Rumble or Haptic feedback, maybe someday.

@LunaMoo
Copy link
Collaborator Author

LunaMoo commented Apr 13, 2020

I discovered some bug trying to make an actual game cheat for better presentation, no idea why, but unthrottle can cause vibration to never end even if the cheat will be disabled as if the value was never reduced.

Guess the __CtrlVblank is a bad place to reduce it from?:c

Another related issue - unthrottle can cause vibration stop in menu to never trigger? I made a check that sets vibration to 0 outside INGAME, but with unthrottle GetUIState() doesn't work?

Or maybe it all works, but there's something bad happening with Xinput itself or my check to update vibration only on change fails somehow with unthrottle:c.

Derp everything appears to be working, I have a feeling that XInputSetState can't be called too often as it also breaks without the check to update only on change. Will try to work around that with some timer following real time maybe.

@LunaMoo
Copy link
Collaborator Author

LunaMoo commented Apr 13, 2020

Yep with a timer it all works even if I get 2000% speed in game, this also explains my initial issue where it wasn't working at all before I added a check to update only on change.

0xA0 vibration cheat(Xinput)
Syntax is: 0xA0NNLLLL 0x00MMRRRR
where NN/MM is time vibration lasts LLLL/RRRR is the vibration power

0xA1 read value for the vibration(Xinput) from game memory
Syntax is: 0xA1000000 0xNNNNNNNN
where NNNNNNNN is the address that stores following values at offset:
0xNNNNNNNN + 0x0 Left Vibration power,
0xNNNNNNNN + 0x2 Right Vibration Power
0xNNNNNNNN + 0x4 Left Vibration time
0xNNNNNNNN + 0x6 Right Vibration time

Left some room for other PPSSPP specific cheats(0xA2-0xAF)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants