{Float,_}:...
#1

How I can make a function with infinite params ? Something like SendClientMessageEx, that's not working:
Код:
stock SendClientMessageEx( playerid, color, message[ ], {Float,_}:... );
{
    new string[ 128 ];
    format( string, 128, message, {Float,_}:... );
    return SendClientMessage( playerid, -1, string );
}
And how I can make this macro:
Код:
stock bool:False = false;

#define FormatSCLM(%0,%1,%2,%3,%4)\
do\
{\
     format(string1, 256, (%2), %4);\
     format(string2, 256, (%3), %4);\
     SCLM((%0),(%1), string1, string2);\
}\
while ( False )
with {Float,_}:... from the first question ? Becouse those macros increase the .AMX size .

PS: I looked in sscanf scripted version, but I don't understand from it.
Reply
#2

i don't think you can do it with any kind of parameters, just with '...'
Reply
#3

Quote:
Originally Posted by xDeadlyBoy
Посмотреть сообщение
i don't think you can do it with any kind of parameters, just with '...'
I can't, but ****** can do, look at sscanf scripted version.
Reply
#4

can you give me a link for it?
Reply
#5

You will need to use arguments. See the wiki for more help, or just look at how sscanf v1 is made.
Reply
#6

Quote:
Originally Posted by [L3th4l]
Посмотреть сообщение
You will need to use arguments. See the wiki for more help, or just look at how sscanf v1 is made.
Read this:
Quote:
Originally Posted by costel_nistor96
Посмотреть сообщение
How I can make a function with infinite params ? Something like
PS: I looked in sscanf scripted version, but I don't understand from it.
Can you make an example for me transforming the FormatSCLM macro to stock with "arguments" ? ... Maybe I will understand from that.
Reply
#7

You have to remake a new format function yourself if you want to make a stock.

But you can just use this macro:

pawn Код:
#define SendClientMessageEx(%0,%1,%2); {new _msg[128]; format(_msg, sizeof(_msg), %2); SendClientMessage(%0, %1, _msg);}
Reply
#8

Quote:
Originally Posted by MadeMan
Посмотреть сообщение
You have to remake a new format function yourself if you want to make a stock.

But you can just use this macro:

pawn Код:
#define SendClientMessageEx(%0,%1,%2); {new _msg[128]; format(_msg, sizeof(_msg), %2); SendClientMessage(%0, %1, _msg);}
...
Quote:
Originally Posted by costel_nistor96
Посмотреть сообщение
How I can make a function with infinite params ? Something like Becouse those macros increase the .AMX size .
I want to make with {Float,_}:..., not macros ... they are sucks. I want to see a example from FormatSCLM from the first post ...
Reply
#9

What sould the function "FormatSCLM" do?
I can only see 2 formats and a "SCLM" function wich is not shown in your post
Reply
#10

you need to use the functions:
pawn Код:
numargs();
getarg(argnum);
Reply
#11

Quote:
Originally Posted by Alby Fire
Посмотреть сообщение
What sould the function "FormatSCLM" do?
I can only see 2 formats and a "SCLM" function wich is not shown in your post
This function send a client message in two languages with parameters, example:
Код:
FormatSCLM( playerid, COLOR_WHITE, "Numele tau este %s", "You nick is %s", pName(playerid) );
I will try with the model from sscanf ... or from Debug_Print0

@****** - at Debug_Print0 ?
Reply
#12

Quote:
Originally Posted by ******
Посмотреть сообщение
Yes, that's the one. That takes a variable number of parameters and pushes them to printf.
I don't know how to do ... I tryed ~20 minutes and I don't know, the function don't work ...

That's the FS:
pawn Код:
#include <a_samp>
#include <zcmd>
#include <sscanf2>
#include <ysi/y_debug>

stock bool:False = false;

#define CreateStreamedObject CreateDynamicObject

#define DIALOG_EMPTY 3

public OnFilterScriptInit()
{

    return 1;
}

CMD:test(playerid, params[])
{
    new pName[ MAX_PLAYER_NAME ];
    GetPlayerName(playerid, pName, MAX_PLAYER_NAME);
    FormatSCLMFS(playerid, -1, "Nickul tau este %s (ID: %d)", "Your nick is %s (ID: %s)", pName, playerid);
    return 1;
}

stock FormatSCLMFS(playerid, color, strRO[], strENG[], {Float,_}:...) <ysi_debug:on>
{
    // This uses the variable parameter passing method based on code by Zeex.
    // See page 15 of the code optimisations topic.
    new arguments = (numargs() - 1) * 4;
    if (arguments)
    {
        new
            arg_start,
            arg_end;

        // Load the real address of the last static parameter.  Do this by
        // loading the address of the parameter and then adding the value of
        // [FRM] (frame pointer).
        #emit CONST.alt                 playerid
        #emit CONST.alt                 color
        #emit CONST.alt                 strRO
        #emit CONST.alt                 strENG
        #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 variables on the value just loaded.
        #emit LOAD.S.alt                arguments
        #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 or constantly reload two variables.
        do
        {
            #emit LOAD.I
            #emit PUSH.pri
            arg_end -= 4;
            #emit LOAD.S.pri            arg_end
        }
        while (arg_end > arg_start);

        // Push the static parameter.
        #emit PUSH.S                    playerid
        #emit PUSH.S                    color
        #emit PUSH.S                    strRO
        #emit PUSH.S                    strENG

        // Now push the number of parameters sent and call the function.
        arguments += 4;
        #emit PUSH.S                    arguments
        #emit SYSREQ.C                  SCLMFS

        // Clear the stack, including the return.
        arguments += 4;
        #emit LCTRL                     4
        #emit LOAD.S.alt                arguments
        #emit ADD
        #emit SCTRL                     4
    }
    else
    {
        SCLMFS(playerid, color, strRO, strENG);
    }
    return 1;
}

stock SCLMFS(playerid, color, ro[], eng[])
{
    switch(GetPVarInt(playerid,"Language"))
    {
        case 0: SendClientMessage(playerid, color, eng);
        case 1: SendClientMessage(playerid, color, ro);
    }
    return 1;
}
and a warning:
Код:
H:\Jocuri\server sa-mp 0.3\filterscripts\testinfparams.pwn(0) : warning 230: no implementation for state "off" in function "FormatSCLMFS", no fall-back
Reply
#13

Quote:
Originally Posted by ******
Посмотреть сообщение
There is a link in that function to a post - go read that post as that is all the documentation on this technique that exists.
I don't know how to do instead of english language, two languages in this function ... I don't know how to multiply "fstring" and "message".

This crashes:
pawn Код:
stock FormatSCLMFS(playerid, color, fstringRO[], fstringENG[], {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) * 4;
    if (n)
    {
        new
            messageRO[128],
            messageENG[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        fstringRO
        #emit CONST.alt        fstringENG
        #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 -= 4;
            #emit LOAD.S.pri      arg_end
        }
        while (arg_end > arg_start);

        // Push the static format parameters.
        #emit PUSH.S          fstringRO
        #emit PUSH.S          fstringENG
        #emit PUSH.C          128
        #emit PUSH.ADR        messageRO
        #emit PUSH.ADR        messageENG

        // Now push the number of arguments passed to format, including both
        // static and variable ones and call the function.
        n += 4 * 3;
        #emit PUSH.S           n
        #emit SYSREQ.C         format

        // Remove all data, including the return value, from the stack.
        n += 4;
        #emit LCTRL          4
        #emit LOAD.S.alt        n
        #emit ADD
        #emit SCTRL          4

        return SCLMFS(playerid, color, messageRO, messageENG);
        //return print(message);
    }
    else
    {
        return SCLMFS(playerid, color, fstringRO, fstringENG);
        //return print(fstring);
    }
}
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)