#define SendFormat(%0,%1,%2,%3) do{new str[128];format(_str,128,%2,%3);SendClientMessage(%0,%1,_str);}while(FALSE)
new string[128];
format(string, sizeof(string), "grdgr %d rgsrg", integer);
SendClientMessage(playerid, COLOR, string);
#define FormatMsg(%0,%1,%2,%3) format(%2, sizeof(%2), %3); \
SendClientMessage(%0, %1, %2)
//%0 = playerid, %1 = color, %2 = string to format then send, %3 = string content
//Example of use:
new string[128];
new name[MAX_PLAYER_NAME]; GetPlayerName(playerid, name, sizeof(name));
FormatMsg(playerid, COLOR, string, "Message sent to pl %d named %s", playerid, name);
#define FormatMsgEx(%0,%1,%2) new STRING[128]; \
format(STRING, 128, %2); \
SendClientMessage(%0, %1, %2)
//%0 = playerid, %1 = color, %2 = string content
//Example of use:
new name[MAX_PLAYER_NAME]; GetPlayerName(playerid, name, sizeof(name));
FormatMsgEx(playerid, COLOR, "Message sent to pl %d named %s", playerid, name);
// HUGE credit to ZeeX for finally cracking this problem:
// http://forum.sa-mp.com/index.php?topic=79810.msg901721#msg901721
stock CPF(playerid, color, fstring[], {Float, _}:...)
{
// This is the number of parameters which are not variable that are passed
// to this function (i.e. the number of named parameters).
static const
STATIC_ARGS = 3;
// Get the number of variable arguments.
new
n = (numargs() - STATIC_ARGS) * BYTES_PER_CELL;
if (n)
{
new
message[128],
arg_start,
arg_end;
// Load the real address of the last static parameter. Do this by
// loading the address of the last known static parameter and then
// adding the value of [FRM].
#emit CONST.alt fstring
#emit LCTRL 5
#emit ADD
#emit STOR.S.pri arg_start
// Load the address of the last variable parameter. Do this by adding
// the number of variable parameters on the value just loaded.
#emit LOAD.S.alt n
#emit ADD
#emit STOR.S.pri arg_end
// Push the variable arguments. This is done by loading the value of
// each one in reverse order and pushing them. I'd love to be able to
// rewrite this to use the values of pri and alt for comparison,
// instead of having to constantly load and reload two variables.
do
{
#emit LOAD.I
#emit PUSH.pri
arg_end -= BYTES_PER_CELL;
#emit LOAD.S.pri arg_end
}
while (arg_end > arg_start);
// Push the static format parameters.
#emit PUSH.S fstring
#emit PUSH.C 128
#emit PUSH.ADR message
// Now push the number of arguments passed to format, including both
// static and variable ones and call the function.
n += BYTES_PER_CELL * 3;
#emit PUSH.S n
#emit SYSREQ.C format
// Remove all data, including the return value, from the stack.
n += BYTES_PER_CELL;
#emit LCTRL 4
#emit LOAD.S.alt n
#emit ADD
#emit SCTRL 4
return SendClientMessage(playerid, color, message);
//return print(message);
}
else
{
return SendClientMessage(playerid, color, fstring);
//return print(fstring);
}
}
Originally Posted by CaHbKo
I join the question.
I was using CPF for a long time now, and always wondered if all those #emits are taking too long or not. Well, it doesn't make my server lag or something, but macro looks smaller and more efficient in my eyes. I'm not sure how to test the function 'speed', maybe someone already did this? |
Originally Posted by » RyDeR «
I used as string "\"%s\" is my name!!" (%s = pName = "RyDeR")
and both runned them 1.000.000 times and format with 128 bytes used 656 ms. CPF had 986 ms. It's clearly that using it in your command is much faster. |
#define FormatMsgEx(%0,%1,%2,%3) new string[128]; \
format(string,128,%2,%3); \
SendClientMessage(%0,%1,%2)
Originally Posted by » RyDeR «
I used as string "\"%s\" is my name!!" (%s = pName = "RyDeR")
and both runned them 1.000.000 times and format with 128 bytes used 656 ms. CPF had 986 ms. It's clearly that using it in your command is much faster. |
Originally Posted by dice7
none of the defines in the first post work
|