#pragma once
static DWORD CRUTCH_LOCAL_VARIABLE = 0;
RpHAnimHierarchy* GtaSA::RpSkinAtomicGetHAnimHierarchy(const RpAtomic* atomic) // 0x7C7540
{
/*
007C7540 | 8B4424 04 | mov eax,dword ptr ss:[esp+4] |
007C7544 | 8B0D A478C900 | mov ecx,dword ptr ds:[C978A4] |
007C754A | 8B0401 | mov eax,dword ptr ds:[ecx+eax] |
007C754D | C3 | ret |
*/
uintptr_t eax = (uintptr_t)atomic;
uintptr_t ecx = this->read<uintptr_t>(0xC978A4);
eax = this->read<uintptr_t>(eax + ecx);
return (RpHAnimHierarchy*)eax;
}
void GtaSA::RpClumpForAllAtomics(RpClump* clump, void* callback, void* data)
{
/*
00749B70 | 8B4424 04 | mov eax,dword ptr ss:[esp+4] |
00749B74 | 53 | push ebx |
00749B75 | 55 | push ebp |
00749B76 | 56 | push esi |
00749B77 | 57 | push edi |
00749B78 | 8D78 08 | lea edi,dword ptr ds:[eax+8] |
00749B7B | 8B40 08 | mov eax,dword ptr ds:[eax+8] |
00749B7E | 3BC7 | cmp eax,edi |
00749B80 | 74 1E | je gta_sa.749BA0 |
00749B82 | 8B5C24 1C | mov ebx,dword ptr ss:[esp+1C] |
00749B86 | 8B6C24 18 | mov ebp,dword ptr ss:[esp+18] |
00749B8A | 8B30 | mov esi,dword ptr ds:[eax] |
00749B8C | 83C0 C0 | add eax,FFFFFFC0 |
00749B8F | 53 | push ebx |
00749B90 | 50 | push eax |
00749B91 | FFD5 | call ebp |
00749B93 | 83C4 08 | add esp,8 |
00749B96 | 85C0 | test eax,eax |
00749B98 | 74 06 | je gta_sa.749BA0 |
00749B9A | 3BF7 | cmp esi,edi |
00749B9C | 8BC6 | mov eax,esi |
00749B9E | 75 EA | jne gta_sa.749B8A |
00749BA0 | 8B4424 14 | mov eax,dword ptr ss:[esp+14] |
00749BA4 | 5F | pop edi |
00749BA5 | 5E | pop esi |
00749BA6 | 5D | pop ebp |
00749BA7 | 5B | pop ebx |
00749BA8 | C3 | ret |
*/
uintptr_t eax = (uintptr_t)clump;
uintptr_t edi = eax + 8;
eax = this->read<uintptr_t>(eax + 8);
if (eax == edi)
{
eax = (uintptr_t)clump; // 00749BA0 | 8B4424 14 | mov eax,dword ptr ss:[esp+14] |
}
else
{
uintptr_t ebx = (uintptr_t)data; // ???? // 00749B82 | 8B5C24 1C | mov ebx, dword ptr ss: [esp+1C]
uintptr_t ebp = (uintptr_t)callback; // 00749B86 | 8B6C24 18 | mov ebp, dword ptr ss: [esp + 18]
uintptr_t esi = this->read<uintptr_t>(eax); // 00749B8A | 8B30 | mov esi, dword ptr ds: [eax]
eax += 0xFFFFFFC0; // actually its a minus
/* callback start */
/*
00734A20 | 8B4424 04 | mov eax,dword ptr ss:[esp+4] |
00734A24 | 50 | push eax |
00734A25 | E8 162B0900 | call gta_sa.7C7540 |
00734A2A | 8B4C24 0C | mov ecx,dword ptr ss:[esp+C] |
00734A2E | 8901 | mov dword ptr ds:[ecx],eax |
00734A30 | 83C4 04 | add esp,4 |
00734A33 | 33C0 | xor eax,eax |
00734A35 | C3 | ret |
*/
eax = (uintptr_t)RpSkinAtomicGetHAnimHierarchy((const RpAtomic*)eax); // 00734A25 | E8 162B0900 | call gta_sa.7C7540 |
CRUTCH_LOCAL_VARIABLE = eax; // the next code - instead of 00734A2A...00734A2E instructions
eax ^= eax;
/* callback end */
if (eax == 0)
{
eax = (uintptr_t)clump;
}
else
{
std::cout << "unreverced block 0x749B9A" << std::endl;
// 00749B9A | 3BF7 | cmp esi, edi |
// 00749B9C | 8BC6 | mov eax, esi |
}
}
return; // eax;
}
RpHAnimHierarchy* GtaSA::GetAnimHierarchyFromSkinClump(RpClump* clump)
{
/*
00734A40 | 51 | push ecx |
00734A41 | 8B4C24 08 | mov ecx,dword ptr ss:[esp+8] |
00734A45 | 8D4424 00 | lea eax,dword ptr ss:[esp] |
00734A49 | 50 | push eax |
00734A4A | 68 204A7300 | push gta_sa.734A20 |
00734A4F | 51 | push ecx |
00734A50 | C74424 0C 00000000 | mov dword ptr ss:[esp+C],0 |
00734A58 | E8 13510100 | call gta_sa.749B70 |
00734A5D | 8B4424 0C | mov eax,dword ptr ss:[esp+C] |
00734A61 | 83C4 10 | add esp,10 |
00734A64 | C3 | ret |
*/
uintptr_t ecx = (uintptr_t)clump;
uintptr_t eax = 0; // ???
RpClumpForAllAtomics((RpClump*)ecx, /* callback addr */ (void*)0x734A20, &eax); // &eax ???
eax = CRUTCH_LOCAL_VARIABLE;
return (RpHAnimHierarchy*)eax;
}
//-------------------------------------------------------------------
RwInt32 GtaSA::RpHAnimIDGetIndex(RpHAnimHierarchy* hierarchy, RwInt32 ID) // 0x7C51A0
{
/*
007C51A0 | 8B5424 04 | mov edx,dword ptr ss:[esp+4] |
007C51A4 | 56 | push esi |
007C51A5 | 83C8 FF | or eax,FFFFFFFF |
007C51A8 | 8B72 10 | mov esi,dword ptr ds:[edx+10] |
007C51AB | 8B52 04 | mov edx,dword ptr ds:[edx+4] |
007C51AE | 33C9 | xor ecx,ecx |
007C51B0 | 57 | push edi |
007C51B1 | 85D2 | test edx,edx |
007C51B3 | 7E 15 | jle gta_sa.7C51CA |
007C51B5 | 8B7C24 10 | mov edi,dword ptr ss:[esp+10] |
007C51B9 | 3B3E | cmp edi,dword ptr ds:[esi] |
007C51BB | 74 0B | je gta_sa.7C51C8 |
007C51BD | 41 | inc ecx |
007C51BE | 83C6 10 | add esi,10 |
007C51C1 | 3BCA | cmp ecx,edx |
007C51C3 | 7C F4 | jl gta_sa.7C51B9 |
007C51C5 | 5F | pop edi |
007C51C6 | 5E | pop esi |
007C51C7 | C3 | ret |
007C51C8 | 8BC1 | mov eax,ecx |
007C51CA | 5F | pop edi |
007C51CB | 5E | pop esi |
007C51CC | C3 | ret |
*/
uintptr_t edx = (uintptr_t)hierarchy;
uintptr_t eax = 0xFFFFFFFF;
uintptr_t esi = this->read<uintptr_t>(edx + 0x10);
edx = this->read<uintptr_t>(edx + 0x4);
uintptr_t ecx = 0;
if (edx == 0)
{
// just return
std::cout << "unreverced block 0x7C51CA" << std::endl; //007C51CA | 5F | pop edi |
}
else
{
uintptr_t edi = ID; // esp+0x10
do
{
if (edi != this->read<uintptr_t>(esi))
{
ecx++;
esi += 0x10;
}
else
{
eax = ecx;
break;
}
} while (ecx != edx);
}
return eax;
}
RwMatrix* GtaSA::RpHAnimHierarchyGetMatrixArray(RpHAnimHierarchy* hierarchy)
{
/*
007C5120 | 8B4424 04 | mov eax,dword ptr ss:[esp+4] |
007C5124 | 8B40 08 | mov eax,dword ptr ds:[eax+8] |
007C5127 | C3 | ret |
*/
uintptr_t eax = (uintptr_t)hierarchy;
eax = this->read<uintptr_t>(eax + 8);
return (RwMatrix*)eax;
}
void GtaSA::vectorMult(uintptr_t edx, uintptr_t esi, uintptr_t ecx)
{
float ecxReaded[3];
this->readBuf(ecx, 4*3, (void*)ecxReaded);
uintptr_t eax = (uintptr_t)esi;
// ecx = ecx;
float st0 = this->read<float>(eax + 0x20);
st0 *= ecxReaded[2];
float st1 = st0;
st0 = this->read<float>(eax + 0x10);
st0 *= ecxReaded[1];
st1 += st0; // ? 0059C8A7 | DEC1 | faddp st(1),st(0) |
st0 = this->read<float>(eax);
st0 *= ecxReaded[0];
st1 += st0; // ? 0059C8AD | DEC1 | faddp st(1),st(0) |
st0 = st1;
st0 += this->read<float>(eax + 0x30); // ? 0059C8AF | D840 30 | fadd st(0),dword ptr ds:[eax+30] |
((float*)(edx))[0] = st0;
st0 = this->read<float>(eax + 0x24);
st0 *= ecxReaded[2];
st1 = st0;
st0 = this->read<float>(eax + 0x4);
st0 *= ecxReaded[0];
st1 += st0; // 0059C8C5 | DEC1 | faddp st(1),st(0) |
//st0 = st1; // 0059C8C5 | DEC1 | faddp st(1),st(0) |
st0 = this->read<float>(eax + 0x14);
st0 *= ecxReaded[1];
st1 += st0;
st0 = st1;
st0 += this->read<float>(eax + 0x34);
((float*)(edx))[1] = st0;
st0 = this->read<float>(eax + 0x28);
st0 *= ecxReaded[2];
st1 = st0;
st0 = this->read<float>(eax + 0x8);
st0 *= ecxReaded[0];
st1 += st0; // 0059C8E1 | DEC1 | faddp st(1),st(0) |
st0 = this->read<float>(eax + 0x18);
st0 *= ecxReaded[1];
st1 += st0;
st0 = st1;
st0 += this->read<float>(eax + 0x38); // ? 0059C8AF | D840 30 | fadd st(0),dword ptr ds:[eax+30] |
//ecx = eax;
//this->write<uintptr_t>(ecx, edx); // 0059C8F4 | 8911 | mov dword ptr ds:[ecx],edx |
//edx =
((float*)(edx))[2] = st0;
}
//-------------------------------------------------------------------
void GtaSA::getBonePosition(uintptr_t pedStruct, Vector3* buf, unsigned int boneId, bool updateSkinBones)
{
uintptr_t esi = pedStruct;
uintptr_t eax = 0; eax = this->read<uintptr_t>(esi + 0x474);
if (updateSkinBones)
{
std::cout << "unreverced block 0x5E4295" << std::endl;
}
else
{
if ((eax & 0xFF00) == 0x400) // 005E42E6 | F6C4 04 | test ah,4
{
uintptr_t ecx = this->read<uintptr_t>(esi + 0x18); // 005E42A9 | 8B4E 18 | mov ecx,dword ptr ds:[esi+18] |
eax = (uintptr_t)GetAnimHierarchyFromSkinClump((RpClump*)ecx); // 0x734A40
uintptr_t edi = eax; // 005E42B2 | 8BF8 | mov edi,eax |
if (edi == 0)
{
// 005E42BF | 8B46 14 | mov eax,dword ptr ds:[esi+14] |
std::cout << "unreverced block 005E42BF" << std::endl;
}
else
{
uintptr_t ecx = boneId; // 005E4347 | 8B4C24 1C | mov ecx,dword ptr ss:[esp+1C] |
eax = RpHAnimIDGetIndex((RpHAnimHierarchy*)edi, ecx); // 005E434D | E8 4E0E1E00 | call gta_sa.7C51A0
esi = eax; // 005E4353 | 8BF0 | mov esi,eax |
eax = (uintptr_t)RpHAnimHierarchyGetMatrixArray((RpHAnimHierarchy*)edi);
// edx = buf
esi = esi << 6;
eax += esi;
eax += 0x30;
buf->x = this->read<float>(eax);
buf->y = this->read<float>(eax + 4);
buf->z = this->read<float>(eax + 8);
}
}
else
{
std::cout << "!unreverced block 0x5E42EB" << std::endl;
eax = boneId;
esi = this->read<uintptr_t>(esi + 0x14); // ped struct
eax = eax + eax * 2;
uintptr_t ecx = eax * 4 + 0x8D13A8;
// IM STOPPED HERE
float res[3];
//uintptr_t edx = (uintptr_t)(res);
// push ecx
// push esi
// push edx
// call func 0x0059C890(edx, esi, ecx)
vectorMult((uintptr_t)res, esi, ecx);
buf->x = res[0];// *(float*)(edx);
buf->y = res[1];//*(float*)(edx + 4);
buf->z = res[2];//*(float*)(edx + 8);
//float* firstMatrix = (float*)this->readBuf(16, edx);
//edx = LOCAL_VAR_ADDR
// push esi
// push edx
// call matrix multiply // 005E4303 | E8 8885FBFF | call gta_sa.59C890 |
/*float res[16];
float arg1[16];
this->readBuf(ecx, 4 * 4 * 4, arg1);
ecx = (uintptr_t)arg1;
float arg2[16];
this->readBuf(esi, 16*4, arg2);
::vec3mx(arg1, arg1, res);
uintptr_t edx = (uintptr_t)res;
/*
buf->x = *(float*)(edx);
buf->y = *(float*)(edx + 4);
buf->z = *(float*)(edx + 8);*/
}
}
}