I have this function that I know its responsible for making some nice math between a 2D vector to return the highest 3D Y value at the provided 2D coordinate. I also know it takes two parameters, int iX
and int iZ
. I have the ASM and the pseudo-C generated by Hex-Rays, but I can't make this code cmpile, I'm not so good with the Hex-Rays pseudo-code.
The ASM code:
00464770 /$ 56 PUSH ESI
00464771 |. 8BF1 MOV ESI,ECX
00464773 |. 833E 00 CMP DWORD PTR DS:[ESI],0
00464776 |. 75 06 JNZ SHORT 0046477E
00464778 |. 33C0 XOR EAX,EAX
0046477A |. 5E POP ESI
0046477B |. C2 0800 RETN 8
0046477E |> 8B4424 0C MOV EAX,DWORD PTR SS:[ESP+C]
00464782 |. 8B4C24 08 MOV ECX,DWORD PTR SS:[ESP+8]
00464786 |. 50 PUSH EAX
00464787 |. 51 PUSH ECX
00464788 |. C1F8 0E SAR EAX,0E
0046478B |. C1F9 0E SAR ECX,0E
0046478E |. 50 PUSH EAX
0046478F |. 51 PUSH ECX
00464790 |. 8BCE MOV ECX,ESI
00464792 |. E8 59FEFFFF CALL 004645F0
00464797 |. FF86 14000400 INC DWORD PTR DS:[ESI+40014]
0046479D |. 5E POP ESI
0046479E \. C2 0800 RETN 8
The pseudo-code:
signed int __thiscall sub_464770(void *this, int a2, int a3)
{
void *v3; // esi@1
signed int result; // eax@2
v3 = this;
if ( *(_DWORD *)this )
{
result = sub_4645F0((int)this, a2 >> 14, a3 >> 14, a2, a3);
++*((_DWORD *)v3 + 65541);
}
else
{
result = 0;
}
return result;
}
signed int __thiscall sub_4645F0(int this, unsigned __int8 a2, unsigned __int8 a3, int a4, int a5)
{
int v5; // ebx@1
int v6; // edi@1
int v7; // esi@1
signed int v8; // ebp@2
int v9; // eax@3
int v10; // edx@3
int v11; // eax@3
int v12; // ecx@3
int v13; // eax@5
signed int result; // eax@9
signed int v15; // [sp+14h] [bp+4h]@1
int v16; // [sp+18h] [bp+8h]@2
v7 = this;
v5 = this + 4 * (a3 + (a2 << 8)) + 4;
v6 = *(_DWORD *)(this + 262164);
v15 = -51200;
if ( *(_DWORD *)v5 && (v8 = 1, v16 = **(_WORD **)v5 + 1, v16 > 1) )
{
do
{
v10 = *(_DWORD *)(v7 + 262172);
v11 = 28 * *(_WORD *)(*(_DWORD *)v5 + 2 * v8);
v12 = *(_DWORD *)(v11 + v10 + 4);
v9 = v10 + v11;
if ( v12 != v6 )
{
if ( *(_BYTE *)(320 * *(_WORD *)(v9 + 14) + *(_DWORD *)(v7 + 262192) + 168) & 1 )
{
*(_DWORD *)(v9 + 4) = v6;
v13 = sub_464320(v7, v9, a4, a5);
if ( v13 != -32767 )
{
if ( v13 > v15 )
v15 = v13;
}
}
}
++v8;
}
while ( v8 < v16 );
result = v15;
}
else
{
result = -51200;
}
return result;
}
int __thiscall sub_464320(int this, int a2, int a3, int a4)
{
int v4; // eax@1
int v5; // ecx@1
int v6; // ebx@1
int v7; // esi@1
int v8; // esi@1
int v9; // edi@1
int v10; // edx@1
signed int v11; // ecx@16
int v12; // eax@17
int v13; // edx@22
int v14; // edi@22
int v15; // eax@23
int v16; // ecx@24
int v17; // eax@31
int v18; // edx@33
int v19; // ebx@33
int v20; // ebp@33
signed int v21; // ecx@34
int v22; // ecx@36
int v23; // eax@37
int v24; // eax@40
int v25; // eax@45
int v26; // edx@45
int v27; // esi@45
int v28; // edi@46
int v29; // eax@49
int v30; // eax@49
signed int v31; // ecx@52
int result; // eax@53
int v33; // [sp+10h] [bp-24h]@1
int v34; // [sp+14h] [bp-20h]@1
signed int v35; // [sp+18h] [bp-1Ch]@25
signed int v36; // [sp+1Ch] [bp-18h]@28
signed int v37; // [sp+20h] [bp-14h]@24
int v38; // [sp+20h] [bp-14h]@37
signed int v39; // [sp+24h] [bp-10h]@24
int v40; // [sp+24h] [bp-10h]@40
int v41; // [sp+28h] [bp-Ch]@1
int v42; // [sp+2Ch] [bp-8h]@1
int v43; // [sp+30h] [bp-4h]@1
int v44; // [sp+38h] [bp+4h]@1
int v45; // [sp+38h] [bp+4h]@43
signed int v46; // [sp+40h] [bp+Ch]@24
v8 = *(_DWORD *)(this + 262168);
v4 = v8 + 28 * *(_WORD *)(a2 + 10);
v5 = v8 + 28 * *(_WORD *)(a2 + 8);
v9 = *(_DWORD *)(v5 + 16);
v43 = v8 + 28 * *(_WORD *)(a2 + 12);
v33 = v43;
v10 = *(_DWORD *)(v4 + 16);
v7 = v5;
v6 = v4;
v41 = v5;
v42 = v4;
v34 = v5;
v44 = v4;
if ( v10 < v9 )
{
v7 = v4;
v34 = v4;
}
if ( *(_DWORD *)(v43 + 16) < *(_DWORD *)(v7 + 16) )
{
v7 = v43;
v34 = v43;
}
if ( v7 == v4 )
{
v44 = v43;
v6 = v43;
}
if ( *(_DWORD *)(v5 + 16) > *(_DWORD *)(v6 + 16) )
{
if ( v7 != v5 )
{
v44 = v5;
v6 = v5;
}
}
if ( *(_DWORD *)(v4 + 16) > *(_DWORD *)(v6 + 16) )
{
if ( v7 != v4 )
{
v44 = v4;
v6 = v4;
}
}
if ( *(_DWORD *)(v43 + 16) > *(_DWORD *)(v6 + 16) )
{
if ( v7 != v43 )
{
v44 = v43;
v6 = v43;
}
}
v11 = 0;
while ( 1 )
{
v12 = *(&v41 + v11);
if ( v7 != v12 )
{
if ( v6 != v12 )
break;
}
++v11;
if ( v11 >= 3 )
goto LABEL_22;
}
v33 = *(&v41 + v11);
LABEL_22:
v13 = *(_DWORD *)(v7 + 16);
v14 = a4;
if ( a4 < v13 )
goto LABEL_58;
v15 = *(_DWORD *)(v6 + 16);
if ( a4 > v15 )
goto LABEL_58;
v16 = *(_DWORD *)(v33 + 16);
v37 = v15 - v13;
v39 = *(_DWORD *)(v33 + 16) - v13;
v46 = v15 - v16;
v35 = v15 == v13 ? 0 : ((*(_DWORD *)(v44 + 8) - *(_DWORD *)(v7 + 8)) << 8) / (v15 - v13);
v36 = *(_DWORD *)(v33 + 16) == v13 ? 0 : ((*(_DWORD *)(v33 + 8) - *(_DWORD *)(v7 + 8)) << 8)
/ (*(_DWORD *)(v33 + 16) - v13);
v17 = v46 ? ((*(_DWORD *)(v44 + 8) - *(_DWORD *)(v33 + 8)) << 8) / v46 : 0;
v20 = v14 - *(_DWORD *)(v7 + 16);
v18 = *(_DWORD *)(v7 + 8);
v19 = v18 + (v35 * (v14 - *(_DWORD *)(v7 + 16)) >> 8);
if ( v14 >= v16 )
{
v21 = v17 * (v14 - *(_DWORD *)(v33 + 16));
v18 = *(_DWORD *)(v33 + 8);
}
else
{
v21 = v36 * v20;
}
v22 = v18 + (v21 >> 8);
if ( v37 )
{
v23 = ((*(_DWORD *)(v44 + 12) - *(_DWORD *)(v7 + 12)) << 8) / v37;
v7 = v34;
v38 = v23;
}
else
{
v38 = 0;
}
if ( v39 )
{
v24 = ((*(_DWORD *)(v33 + 12) - *(_DWORD *)(v7 + 12)) << 8) / v39;
v7 = v34;
v40 = v24;
}
else
{
v40 = 0;
}
if ( v46 )
{
v7 = v34;
v45 = ((*(_DWORD *)(v44 + 12) - *(_DWORD *)(v33 + 12)) << 8) / v46;
}
else
{
v45 = 0;
}
v25 = *(_DWORD *)(v7 + 12);
v26 = *(_DWORD *)(v33 + 16);
v27 = v25 + (v38 * v20 >> 8);
v28 = v14 >= v26 ? *(_DWORD *)(v33 + 12) + (v45 * (v14 - v26) >> 8) : v25 + (v40 * v20 >> 8);
if ( v19 > v22 )
{
v29 = v19;
v19 = v22;
v22 = v29;
v30 = v27;
v27 = v28;
v28 = v30;
}
if ( a3 < v19 || a3 > v22 )
{
LABEL_58:
result = -32767;
}
else
{
v31 = v22 - v19;
if ( v31 )
result = v27 + (((v28 - v27) << 8) / v31 * (a3 - v19) >> 8);
else
result = v27 + (v27 * (a3 - v19) >> 8);
}
return result;
}
I don't know why the functions have void *this
as the first parameter though.
void *this
is the way C++ non-static member functions receive thethis
pointer.