*(float*)(x) first "converts" x to a pointer to a float, then the * before the first ( reads from or writes to the pointer.
In 32-bit assembly reading looks like
MOV [register], DWORD PTR DS:[x]
and writing
MOV DWORD PTR DS:[x], [register]
Every 32-bit pointer is a DWORD, every 64-bit pointer is a QWORD (if the application is compiled in 32 bits, it would also be DWORD in 64 bit systems)
The structs look like this :
struct WeaponInfo
{
BYTE Something[0x2424]; //Begins at 0, ends at 0x2423
float OldNoReload; //WeaponInfo + 0x2424 (Old offset, I'm not longer hacking CrossFire so much)
};
struct WeaponMgr
{
WeaponInfo *WepInf[600]; //Every pointer takes 4 Bytes because every 32-bit application has got an address range of 4 Bytes
};
Somewhere in CShell.dll :
WeaponMgr *Weapons;
WeaponMgr *Weapons is a pointer to a WeaponMgr structure.
So if this WeaponMgr struct begins at A00000 (as an example) the Pointer "Weapons" is A00000.
WeaponInfo *WepInf[600] means that in the WeaponMgr struct are 600 Pointers (600 Pointers take 2400 Bytes) to WeaponInfo structures.
When one of the WeaponInfo structures begins at A00000, one of the pointers is A00000.
Every WeaponInfo structure contains information about a specific weapon (like how long the reload animation is).
If you want to read a value from every weapon, the compiler will compile it like this :
MOV ECX, 0 // Self-explaining
MOV EAX, DWORD PTR DS:[[WeaponMgr]] // Moves to the register EAX where WepInf points to
5A0012 MOV EDX, 4 x ECX // Every 32-bit pointer takes 4 Bytes, so it multiplies ECX (in a for-loop normally i)
ADD EDX, EAX //Adds EAX to EDX (If WepInf points to A00000 and EDX is 8 (i = 2), EDX now will be A00008
MOV EDX, DWORD PTR DS:[EDX] //Moves the Pointer to the WeaponInfo structure to EDX
MOV EBX, DWORD PTR DS:[EDX + Offset] //Moves the Value of an information of a weapon to EBX
CMP ECX, 600 //Compare ECX with 600
INC ECX // Add 1 to ECX
JL 5A0012 //Jump to 5A0012 if ECX is smaller than 600