a nice place to hook for engine drawing:
module_base + 0x14C10
do the engine drawing before calling the original function, as this will flush the internal buffer to the directdraw surface.
for engine drawing text:
module_base + 0x1C5F0
//void __usercall DrawTextOnScreen(int xpos<ecx>, unsigned int color<edi>, int ypos, char *txt)
Code:
void DrawEngText_game( int x, int y, unsigned int color, char* txt )
{
__asm {
mov eax, module_base
add eax, 0x1c5f0
mov ecx, x
mov edi, color
push txt
push y
call eax
add esp, 8
}
}
better make sure you are not getting the text out of the screen bounds, or it will crash! (hint: one letter is approx 8 px wide)
//--------------------------
if you want to do directdraw hooking / drawing, either hook flip or Bltfast (both are called in this function)
the game has 3 surfaces, all are referenced in this function
for the w2s: the z is either the width / 2,
or simply the width if the player is zoomed in
Code:
//Generated using ReClass 2011 by DrUnKeN ChEeTaH
#define OFF_PLAYERS 0x6A534
// 32 players = max
#define OFF_CUR_PLAYER 0x13CDEF0
#define OFF_ISZOOMED 0x13EDA20
#define OFF_XRES 0x73164
#define OFF_YRES 0x739A8
enum weap_t {
spade = 0,
pickaxe,
block,
gun,
grenade
};
enum gun_t {
rifle = 0,
smg,
shotgun
};
class CPlayer
{
public:
char _0x00F0[672];
DWORD valid; //0x0000
vec3f Position; //0x0004
vec3f Position2; //0x0010
char _0x001C[12];
vec3f right; //0x0028
vec3f up; //0x0034
vec3f fwd; //0x0040
gun_t typegun; //0x004C
char _0x0050[20];
__int32 ducking; //0x0064
char _0x0068[8];
weap_t weapon; //0x0070
char _0x0074[4];
__int32 team; //0x0078
char _0x007C[4];
__int32 alive; //0x0080
__int32 joined; //0x0084
char _0x0088[8];
__int32 points; //0x0090
__int32 blocks_left; //0x0094
__int32 ammo_loaded; //0x0098
__int32 ammo_spare; //0x009C
__int32 grenades; //0x00A0
__int32 health; //0x00A4
char _0x00A8[56];
char name[16]; //0x00E0
};//Size=0x0390
Code:
void w2s_init( vec3f& eye, vec3f& up, vec3f& right, vec3f& fwd, DWORD width, DWORD height, DWORD z )
{
eyepos = eye;
vup = up;
vright = right;
vfwd = fwd;
screen_size = vec2f( (float)width, (float)height );
screen_res = vec3f( (float)width / 2, (float)height / 2, (float)z );
}
bool w2s_project( const vec3f& pos3d, vec3f& out )
{
vec3f loc = pos3d - eyepos;
float z = loc.dot(vfwd);
if( z < 1.0 ) return false;
z = screen_res.z / z;
out.x = (loc.x*vright.x + loc.y*vright.y + loc.z*vright.z)*z + screen_res.x;
out.y = (loc.x*vup.x + loc.y*vup.y + loc.z*vup.z)*z + screen_res.y;
out.z = z;
if( out.x >= 0 && out.x < screen_size.x &&
out.y >= 0 && out.y < screen_size.y )
return true;
return false;
}
example of using the offsets
Code:
DWORD GetAddress( DWORD offs )
{
return module_base + offs;
}
DWORD xres = *(PDWORD)GetAddress( OFF_XRES );
DWORD yres = *(PDWORD)GetAddress( OFF_YRES );
DWORD zoomed = *(PDWORD)GetAddress(OFF_ISZOOMED);
DWORD zres = xres >> (zoomed == 0 ? 1 : 0);
oh, player locations are their heads already, how nice isnt it?
(usefull for w2s init )
i was chatting with 'tvc' in irc, and he pointed out that the unused char[] in the player struct actually belong to the beginning.
- edited to the beginning, and adjusted start offset (ignore the offset comments that are now off)
edit:
yes i know they are not complete, i reversed some more already, but i'll leave that up to you