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

I need some advice how 3rd line or more(maybe) Pointer works #20073

Open
blitznoz opened this issue Mar 4, 2025 · 4 comments
Open

I need some advice how 3rd line or more(maybe) Pointer works #20073

blitznoz opened this issue Mar 4, 2025 · 4 comments

Comments

@blitznoz
Copy link

blitznoz commented Mar 4, 2025

I already mastered how pointer works on ps2 cbv7 even the 3rd line but cwcheat works differently and no source of that format to understand

not sure if is same as codebreaker for normal format
_L 0x6AAAAAAA 0xVVVVVVVV
_L 0x000Y0001 0xIIIIIIII

but 3 line is different

_L 0x200002B4 - plus 2B4?
0x00001A34 - offset?

working example from database
_C0 Infinite Health
_L 0x6027B850 0x00007530
_L 0x00020002 0x00001A34
_L 0x200002B4 0x00000000

Image

0x027B850 + 08800000 = 8A7B850 is pointer at 08FB7780 ?

Image

@NABN00B
Copy link
Contributor

NABN00B commented Mar 4, 2025

First let's go over the cheat format:

_L 0x6AAAAAAA 0xVVVVVVVV
_L 0xXXXYZZZZ 0xIIIIIIII

0x6AAA_AAAA -- pointer base address
0xVVVV_VVVV -- value to write at resolved (final) address
0xXXXY_ZZZZ -- XXX is pointer base offset divided by 4 (XXX * 4 is pointer base offset)
            -- Y is pointer operation type that determines 2 things:
               ------ number of bytes to write at resolved address
               ------ sign of last pointer offsetZ (positive or negative)
            -- ZZZZ - 1 determines number of extra cheat lines
0xIIII_IIII -- last pointer offsetZ

Then the explanation for how the pointer cheat works:

General Scenario                                           Your Scenario
(A through F used as marking, NOT as hex value here)       (A through F used as hex value here)
________________________________________________________________________________________________________________________

calculate pointer base offset (XXX * 4)
0x0000_0XXX * 0x0000_0100 == 0x0000_xxxx                   0x0000_0000 * 0x0000_0100 == 0x0000_0000


calculate pointer base (0x0880_0000 + pointer base address + pointer base offset)
0x0880_0000 + 0x0AAA_AAAA + 0x0000_xxxx == 0xBBBB_BBBB     0x0880_0000 + 0x0027_B850 + 0x0000_0000 == 0x08A7_B850


resolve pointer base (retrieve value at this address)
0xBBBB_BBBB -> 0xCCCC_CCCC                                 0x08A7_B850 -> 0x08FB_7780
>>>>>>>>>>>>> This is the point you've reached in Cheat Engine in your screenshot.


determine number of extra cheat lines
0xXXXY_ZZZZ     ZZZZ - 1 determines number of extra cheat lines     0x0002 - 1 == 1 extra cheat line




execute every extra cheat line
 _L 0xTUUU_UUUU 0xTUUU_UUUU                                _L 0x200002B4 0x00000000
(only gonna explain when T is 2 or 3 otherwise we're gonna be he here all day)

0xTUUU_UUUU -- T determines sign of pointer offsetN (2 is positive, 3 is negative)
            -- UUU_UUUU is pointer offsetN

walk through pointer offsetN
0xCCCC_CCCC := 0xCCCC_CCCC + 0x0UUU_UUUU                   0x08FB_78B4 + 0x0000_02B4 == 0x08FB_7B68 (store this)
(operation here depends on offsetN sign)                   (operation is add '+' because offsetN sign is positive)

repeat for second 0xTUUU_UUUU in cheat line, but only if second T is 2 or 3, otherwise do nothing




determine number of bytes to write and sign of pointer offsetZ
0xXXXY_ZZZZ     Y determines num of bytes, offset1 sign    0xXXX2_ZZZZ means write 4Bytes and offset1 sign is positive


apply last pointer offsetZ to retrieve final address
0xCCCC_CCCC + 0xIIII_IIII == 0xDDDD_DDDD                   0x08FB_7780 + 0x0000_1A34 == 0x08FB_78B4
(operation here depends on offset1 sign)                   (operation is add '+' because offset1 sign is positive)


write value at final address
&0xDDDD_DDDD := 0xVVVV_VVVV                                 &0x08FB_7B68 := 0x0000_7530
(size of 0xVVVV_VVVV depends on number of bytes to write)  (earlier we determined to write 4Bytes)

(Very likely I made a mistake somewhere.)

In my experience (which is not a lot), pointers to emulated memory like this are complicated to work with in Cheat Engine. In a single cheat entry we can only go as far as resolving the pointer base.

Then we would have to add a second cheat entry with the address you get from the first cheat entry. Eg:

8FB7780 + 2B4 + 1A34
PPSSPPWindows64.exe + F9B000

or:

8FB7B68
PPSSPPWindows64.exe + F9B000

However, because pointers are dynamic, the address from your first cheat entry can change at any time (usually when you die or switch levels). This means you have to recreate your second cheat entry every time that happens.

As far as I know the only way to correctly work with pointers throughout multiple sessions requires writing Lua scripts. See my example:

Image

@LunaMoo might know of a better solution.

Anyway this kind of question should go onto the Forums (or Discord server).

@LunaMoo
Copy link
Collaborator

LunaMoo commented Mar 4, 2025

Better solution is to not use pointers at all, but to modify game code to do what we want and only use CWC to inject our code. People think it requires a lot of learning, but it's not true, basics of low level programming + a cheat sheet with MIPS opcodes is enough.

@zeronirvada
Copy link

@LunaMoo & @NABN00B ,
Do you have any website link for all code types ?
I google search a lot but i never found _L 0x9 code type that i not familiar with or more

@NABN00B
Copy link
Contributor

NABN00B commented Mar 9, 2025

Sadly there isn't a comprehensive documentation (in English), that is something we should consider writing up a page for on the website.

Your best bet is reading the source code of how PPSSPP interprets the CWCheat commands here

CheatOperation CWCheatEngine::InterpretNextCwCheat(const CheatCode &cheat, size_t &i) {
and here
void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, size_t &i) {

From here we find that there is no 0x9 type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants