//in some program
int AMXAPI amx_GetAddr(AMX *amx,cell amx_addr,cell **phys_addr)
{
AMX_HEADER *hdr;
unsigned char *data;
assert(amx!=NULL);
hdr=(AMX_HEADER *)amx->base;
assert(hdr!=NULL);
assert(hdr->magic==AMX_MAGIC);
data=(amx->data!=NULL) ? amx->data : amx->base+(int)hdr->dat;
assert(phys_addr!=NULL);
if (amx_addr>=amx->hea && amx_addr<amx->stk || amx_addr<0 || amx_addr>=amx->stp) {
*phys_addr=NULL;
return AMX_ERR_MEMACCESS;
} /* if */
*phys_addr=(cell *)(data + (int)amx_addr);
return AMX_ERR_NONE;
}
// native GetPlayerPos(playerid, &Float:x, &Float:y, &Float:z)
static cell AMX_NATIVE_CALL n_GetPlayerPos(AMX *amx, cell *params)
{
CHECK_PARAMS(4);//check if params[0] = 4*4 (4*sizeof(cell))
cell* cptr;//a pointer
amx_GetAddr(amx, params[2], &cptr);//get address of params[2]
*cptr = amx_ftoc(pPlayer->m_vecPos.X);//set params[2]
amx_GetAddr(amx, params[3], &cptr);//etc
*cptr = amx_ftoc(pPlayer->m_vecPos.Y);
amx_GetAddr(amx, params[4], &cptr);
*cptr = amx_ftoc(pPlayer->m_vecPos.Z);
return 1;
}
//My DLL:
///////////////////////////////////////////////////////
// From "amx.c", part of the PAWN language runtime:
// http://code.google.com/p/pawnscript/source/browse/trunk/amx/amx.c
ucell GetPlayerPosAddress = NULL;
cell GetPlayerPosPositionData[6] = {4*sizeof(cell),NULL,NULL,NULL,NULL,NULL};
AMX FakeAMX;
#define USENAMETABLE(hdr) \
((hdr)->defsize==sizeof(AMX_FUNCSTUBNT))
#define NUMENTRIES(hdr,field,nextfield) \
(unsigned)(((hdr)->nextfield - (hdr)->field) / (hdr)->defsize)
#define GETENTRY(hdr,table,index) \
(AMX_FUNCSTUB *)((unsigned char*)(hdr) + (unsigned)(hdr)->table + (unsigned)index*(hdr)->defsize)
#define GETENTRYNAME(hdr,entry) \
(USENAMETABLE(hdr) ? \
(char *)((unsigned char*)(hdr) + (unsigned)((AMX_FUNCSTUBNT*)(entry))->nameofs) : \
((AMX_FUNCSTUB*)(entry))->name)
typedef ucell AMX_NATIVE_CALL n_GetPlayerPos( AMX* amx, cell* params );//call to the function in program
n_GetPlayerPos* func_GetPlayerPos = NULL;//the function call addr
int GetPlayerPos(int playerid,float *x,float *y,float *z)
{
GetPlayerPosPositionData[0] = 4*sizeof(cell);
GetPlayerPosPositionData[1] = playerid;
func_GetPlayerPos(&FakeAMX,GetPlayerPosPositionData);
std::cout << (float)amx_ctof(GetPlayerPosPositionData[3]) << std::endl;
std::cout << (float)amx_ctof(GetPlayerPosPositionData[4]) << std::endl;
std::cout << (float)amx_ctof(GetPlayerPosPositionData[5]) << std::endl;
*x = amx_ctof(GetPlayerPosPositionData[3]);
*y = amx_ctof(GetPlayerPosPositionData[4]);
*z = amx_ctof(GetPlayerPosPositionData[5]);
return 1;
}
///////////////////////////////////////////////////////
PLUGIN_EXPORT int PLUGIN_CALL AmxLoad( AMX *amx )
{
//Code from sscanf2.5, [PAWN]SSCANF Author: Y_Less
int
num,
idx;
// Operate on the raw AMX file, don't use the amx_ functions to avoid issues
// with the fact that we've not actually finished initialisation yet. Based
// VERY heavilly on code from "amx.c" in the PAWN runtime library.
AMX_HEADER *
hdr = (AMX_HEADER *)amx->base;
AMX_FUNCSTUB *
func;
num = NUMENTRIES(hdr, natives, libraries);
for (idx = 0; idx != num; ++idx)
{
func = GETENTRY(hdr, natives, idx);
if (!strcmp("GetPlayerPos", GETENTRYNAME(hdr, func)))
{
GetPlayerPosAddress = func->address;//set adress
FakeAMX = *amx;//create a copy of a valid AMX
FakeAMX.data = (unsigned char*)sizeof(cell);//edit the AMX to point to our data
func_GetPlayerPos = (n_GetPlayerPos*)GetPlayerPosAddress;//assign the function address
break;
}
}
//end sscanf cut
return 1;
}