 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
oddgamer Advanced Cheater
Reputation: 0
Joined: 19 Jan 2013 Posts: 60
|
Posted: Sat Aug 16, 2025 9:26 am Post subject: Custom type gone wrong |
|
|
So many, many moons ago, I asked the wonderful people here to help me make a custom type for searching for "ticks", to make finding time-related values easier in Rimworld (yes, there are other, easier ways to cheat this game, yes I could turn on the dev mode or edit the save file or any of a billion other things, thank you, I'm aware, I'm having fun doing it this way, moving on).
Time in RimWorld is measured in ticks. 60 ticks to a real-world second (which is shown sometimes), 2500 to an in-game hour, 60,000 to an in-game day (24 in-game hours), and 3,600,000 to an in-game year (60 in-game days), all stored as a 4-byte signed integer. When I want to, say, find the age of someone that is 42 years old, I need to bust out the calculator and figure out what 41 x 3,600,000 and 43 x that are in order to get the possible range of values. Which is frustrating. The idea here would be that the number displayed would be a float or double (probably float) that represents the integer number divided by those various values (so different types for second, hour, day, year).
This one, for finding seconds of time left and from which I adapted the others, does not work. I don't think it ever worked. I didn't write this, I don't know who did (can't find it on here). I gave it a value of 50, which is nearly 60 and so the number reported should be almost 1 (specifically it should be 0.833333). Instead what I get is 1.401298464E-45. Not even close. Can anyone help fix this?
Code: |
alloc(ConvertRoutine,1024)
alloc(ConvertBackRoutine,1024)
alloc(TypeName,256)
alloc(ByteSize,4)
alloc(PreferedAlignment,4)
alloc(UsesFloat,1)
alloc(UsesString,1)
alloc(MaxStringSize,2)
alloc(CallMethod,1)
TypeName:
db 'Tick Seconds',0
ByteSize:
dd 8
PreferedAlignment:
dd 4
UsesFloat:
db 1
UsesString:
db 0
MaxStringSize:
dw #100
CallMethod:
db 1
multiplier:
dd (float)60
//cdecl int ConvertRoutine(unsigned char *input, PTR_UINT address);
ConvertRoutine:
[64-bit]
movss xmm0,[rcx]
divss xmm0,[multiplier]
movd eax,xmm0
ret
[/64-bit]
//cdecl void ConvertBackRoutine(int i, PTR_UINT address, unsigned char *output);
ConvertBackRoutine:
[64-bit]
movd xmm0,ecx
mulss xmm0,[multiplier]
movss [r8],xmm0
ret
[/64-bit]
|
|
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4690
|
Posted: Sat Aug 16, 2025 12:37 pm Post subject: |
|
|
Quote: | all stored as a 4-byte signed integer |
The script is treating it as a float. Convert an integer to/from a float using `cvtsi2ss` / `cvttss2si` respectively
Code: | ...
//cdecl int ConvertRoutine(unsigned char *input, PTR_UINT address);
ConvertRoutine:
[64-bit]
cvtsi2ss xmm0,[rcx]
divss xmm0,[multiplier]
movd eax,xmm0
ret
[/64-bit]
//cdecl void ConvertBackRoutine(int i, PTR_UINT address, unsigned char *output);
ConvertBackRoutine:
[64-bit]
movd xmm0,ecx
mulss xmm0,[multiplier]
cvttss2si eax,xmm0
mov [r8],eax
ret
[/64-bit] |
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
oddgamer Advanced Cheater
Reputation: 0
Joined: 19 Jan 2013 Posts: 60
|
Posted: Sat Aug 16, 2025 3:15 pm Post subject: |
|
|
ParkourPenguin wrote: |
The script is treating it as a float. Convert an integer to/from a float using `cvtsi2ss` / `cvttss2si` respectively
|
Thank you so much! It's awesome!! Tested and it works!!! This will make life so much easier!!!! I need to stop now, running out of exclamation points!!!!! I may need help!!!!!!
But seriously, thanks for that. I really appreciate it.
|
|
Back to top |
|
 |
Csimbi I post too much
Reputation: 97
Joined: 14 Jul 2007 Posts: 3320
|
Posted: Sun Aug 17, 2025 7:22 am Post subject: |
|
|
ParkourPenguin wrote: | ... |
Isn't there a potential overflow here (due to 32bit register usage)?
Shouldn't 64bit registers be used?
|
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4690
|
Posted: Sun Aug 17, 2025 11:08 am Post subject: |
|
|
No. The ConvertRoutine function takes an int (really 4-bytes of arbitrary data), the ConvertBackRoutine function is passed an int, and the native data stored in memory is a 4-byte integer. Everything is 4 bytes.
Setting ByteSize to 8 is weird if the native type is a 4-byte integer (it should be 4), but that won't cause any bad things to happen. CE just gives the functions more data than they need in the input / output parameters. In theory, if the 4-byte value is the last 4 bytes in a scannable region of memory, then it wouldn't be found; however, that's very unlikely to happen.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
Csimbi I post too much
Reputation: 97
Joined: 14 Jul 2007 Posts: 3320
|
Posted: Sun Aug 17, 2025 2:04 pm Post subject: |
|
|
So, multipling two ints can never be longer than an int? That's news to me.
|
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4690
|
|
Back to top |
|
 |
Csimbi I post too much
Reputation: 97
Joined: 14 Jul 2007 Posts: 3320
|
Posted: Mon Aug 18, 2025 11:47 am Post subject: |
|
|
ParkourPenguin wrote: | Of course, users could always enter ridiculous values, but if they do that, it's their fault. |
So true
|
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|