-
-
Notifications
You must be signed in to change notification settings - Fork 434
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
Add template function for calling native gta functions #3768
Conversation
In my opinion for now you should refactor only few functions calls, see how it behave in production, and then refactor more. You may miss something, make mistake and it is kinda hard to verify if all your refactors are allright. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see you've taken a liking to my method :)
This way dealing with raw memory would be much better.
I tested some functions that I changed and so far everything works fine, but maybe you're right, that's why this is enough for now. Only when the next nightly after merging this PR turns out to work without any problems, then I will finish the remaining files |
MSVC doesn't optimize your calls. link |
Is there anything I can do about it? |
My bad there was an invalid compiler option. There should be |
This seems like a suboptimal approach to me. I think we should rather replace address #defines with proper typed function declarations. e.g. instead of #define FUNC_HasCollisionBeenLoaded 0x410CE0 and DWORD dwFunc = FUNC_HasCollisionBeenLoaded;
bool bRet = false;
_asm
{
push 0
push vecPosition
call dwFunc
mov bRet, al
add esp, 8
}
return bRet;
just do static auto FUNC_HasCollisionBeenLoaded = reinterpret_cast<bool(__cdecl*)(CVector* vecPosition, bool flag)>(0x410CE0); and return FUNC_HasCollisionBeenLoaded(vecPosition, false); |
Even better, create the appropriate methods in the class you are calling it for (if any) and then call that method instead (definition would just be reinterpreted mem address). |
In that case, I have an even better suggestion. Maybe we should create a single header file, something like |
This file will be too messy. I prefer declaring methods to to access engine functions. void someLogic() {
// some code
using CEntity_ResolveReferences = void*(__thiscall*)(CEntitySAInterface*);
((CEntity_ResolveReferences)0x571A40)(m_pInterface);
// some code
} CEntity_ResolveReferences can be declared in CEntitySAInterface CEntitySAInterface {
//...
void* ResolveReferences()
{
// we can skip additional definition for 0x571A40
// this number is described in the context
return ((void*(__thiscall*)(CEntitySAInterface*))0x571A40)(this);
};
}
void someLogic() {
// code
m_pInterface->ResolveReferences();
// code
} I kinda agree that this PR gives too small improvements. |
/////////////////////////////
/// CPed
/////////////////////////////
static auto FUNC_SetModelIndex = reinterpret_cast<void(__thiscall*)(CPedSAInterface* ped, int index)>(0x5E4880);
static auto FUNC_AttachPedToEntity = reinterpret_cast<void(__thiscall*)(CPedSAInterface* ped, CEntitySAInterface* entity, float offsetX, float offsetY, float offsetZ, int direction, float rotationLimit, std::uint32_t weaponType)>(0x5E7CB0);
static auto FUNC_SetIsStanding = reinterpret_cast<void(__thiscall*)(CPedSAInterface* ped, bool standing)>(0x4ABBE0);
static auto FUNC_SetCurrentWeapon = reinterpret_cast<void(__thiscall*)(CPedSAInterface* ped, std::uint8_t slot)>(0x5E61F0);
static auto FUNC_GiveWeapon = reinterpret_cast<std::uint32_t(__thiscall*)(CPedSAInterface* ped, std::uint32_t weaponID, int ammo, int unusedUnknown)>(0x5E6080);
static auto FUNC_GetBonePosition = reinterpret_cast<void(__thiscall*)(CPedSAInterface* ped, CVector* pos, std::uint32_t boneID, bool dynamic)>(0x5E4280);
/////////////////////////////
/// CPlayerPed
/////////////////////////////
static auto FUNC_MakeChangesForNewWeapon_Slot = reinterpret_cast<void(__thiscall*)(CPlayerPedSAInterface* playerPed, std::uint8_t weaponSlot)>(0x60D000); Personally, I wouldn't say that it looks messy. Additionally, this file would be rarely edited. Will editing CEntitySAInterface cause any issues due to incorrect size? |
Methods don't change data struct. Only virtual functions add |
What about |
What do you think about a namespace for all gta global funcs? |
|
This PR adds a simple template function that is used to call native GTA functions. This is more readable than manually casting or "using".
The
PrepareSignature
function prepares arguments of the appropriate types, andCallGTAFunction
calls the function and optionally returns the result.The syntax is simple
Example
Calling conventions are given in capital letters.