SA-MP Forums

Go Back   SA-MP Forums > SA-MP Scripting and Plugins > Scripting Help

Reply
 
Thread Tools Display Modes
Old 24/01/2020, 03:51 PM   #1
Salint
Little Clucker
 
Salint's Avatar
 
Join Date: Aug 2018
Posts: 6
Reputation: 0
Default #emit

Hello!
I've returned to SA:MP after quite some time now and I checked a script and found this.
PHP Code:
stock SendClientMessageEx(playeridcolor, const text[], {Float_}:...)
{
    static
        
args,
        
str[144];

    if ((
args numargs()) == 3)
    {
        
SendClientMessage(playeridcolortext);
    }
    else
    {
        while (--
args >= 3)
        {
            
#emit LCTRL 5
            #emit LOAD.alt args
            #emit SHL.C.alt 2
            #emit ADD.C 12
            #emit ADD
            #emit LOAD.I
            #emit PUSH.pri
        
}
        
#emit PUSH.S text
        #emit PUSH.C 144
        #emit PUSH.C str
        #emit PUSH.S 8
        #emit SYSREQ.C format
        #emit LCTRL 5
        #emit SCTRL 4

        
SendClientMessage(playeridcolorstr);

        
#emit RETN
    
}
    return 
1;

From the usages of it, I see that this function is used to send messages with "variables" instead of formatting it and then sending the formatted message.

I just don't get what this #emit does. I tried to search for an emit preprocessor for C/C++(so I can get a general answer rather than a samp-related one), but can't find any results(There is a _emit keyword, which is not what this is).

It would be greatly appreciated if someone can briefly explain to me what that is. No complicated topics since I am just 14.

Have a nice day.

EDIT: If there is a "non-emit" alternative to do this, please let me know.
Salint is offline   Reply With Quote
Old 24/01/2020, 08:52 PM   #2
Markski
Big Clucker
 
Markski's Avatar
 
Join Date: Apr 2015
Location: La Plata, Argentina
Posts: 133
Reputation: 59
Default Re: #emit

#emit is a way to write in-line P-Code/Bytecode (Pawn's compiled "Assembly" so to speak).

This is often done to either bypass limitations of the language, obsfucate code, increase execution speed (by hand-assembling specific code faster than the compiler would) or all of the above.

In this case I think it is bypassing a limitation of how arguments are managed by the Pawn language, as it seems to be pushing a variable amount of arguments to the stack in that while, which would not be possible by writing it properly.

Quote:
#emit PUSH.S text
#emit PUSH.C 144
#emit PUSH.C str
#emit PUSH.S 8
#emit SYSREQ.C format
In this portion of the code, the parameters "text", "144", "str", and "8" are pushed to the stack to be used as variables, before doing a system call to the sa-mp server to run the "format" function with these.

The Pawn Language Official Document by CompuPhase has a small bit where these preprocessor directives are explained, including #emit

TL-DR: All of those emits are just for a format(), but it cannot be done without emits as it was done this way in order to be able to send a variable amount of arguments
Markski is offline   Reply With Quote
Old 24/01/2020, 09:25 PM   #3
Kwarde
High-roller
 
Kwarde's Avatar
 
Join Date: Nov 2009
Location: The Netherlands
Posts: 2,740
Reputation: 1686
Default Re: #emit

A non-emit alternative:

Code:
stock bool:FALSE = false;
new scmExStr[144];
#define SendClientMessageEx(%0,%1,%2,%3) do{format(scmExStr,144,%2,%3);SendClientMessage(%0,%1,scmExStr);}while(FALSE)
Note that this (obviously) will not work this way:
Code:
if (!statement)
    return SendClientMessageEx...
As it's a macro/define, this would be translated to "return do{format...".
Also if you just use parameters playerid, color, message it this ..Ex function would fail as it wouldn't be recognised by the pre-processor.
Also you may have noticed the "stock bool:FALSE = false". The do statement must run once (hence the while(false)). Using "false" you'd get an error (empty statement I believe, indu---something--- code). By defining stock FALSE you still use the same statement except the compiler doesn't recognise it as an empty statement. So in short, just a way to make the compiler happy)

Even though it doesn't matter that much with systems these days, this is better for runtime speeds. Just go with whatever you desire, this is just what I prefer.
__________________
When the opportunity presents itself to flip-a da table, uh, you flip-a da table.

Discord: Kwarde#8009
Kwarde is online now   Reply With Quote
Old 24/01/2020, 10:36 PM   #4
Markski
Big Clucker
 
Markski's Avatar
 
Join Date: Apr 2015
Location: La Plata, Argentina
Posts: 133
Reputation: 59
Default Re: #emit

Quote:
Originally Posted by Kwarde View Post
A non-emit alternative:

Code:
stock bool:FALSE = false;
new scmExStr[144];
#define SendClientMessageEx(%0,%1,%2,%3) do{format(scmExStr,144,%2,%3);SendClientMessage(%0,%1,scmExStr);}while(FALSE)
Note that this (obviously) will not work this way:
Code:
if (!statement)
    return SendClientMessageEx...
As it's a macro/define, this would be translated to "return do{format...".
Also if you just use parameters playerid, color, message it this ..Ex function would fail as it wouldn't be recognised by the pre-processor.
Also you may have noticed the "stock bool:FALSE = false". The do statement must run once (hence the while(false)). Using "false" you'd get an error (empty statement I believe, indu---something--- code). By defining stock FALSE you still use the same statement except the compiler doesn't recognise it as an empty statement. So in short, just a way to make the compiler happy)

Even though it doesn't matter that much with systems these days, this is better for runtime speeds. Just go with whatever you desire, this is just what I prefer.
This is a very creative approach, I wouldn't have thought of using a macro for this. +rep
Markski is offline   Reply With Quote
Old 25/01/2020, 04:35 AM   #5
Salint
Little Clucker
 
Salint's Avatar
 
Join Date: Aug 2018
Posts: 6
Reputation: 0
Default Re: #emit

Thanks, both of you.

Where can I learn about this(outside of samp)?
Salint is offline   Reply With Quote
Old 25/01/2020, 07:56 AM   #6
Calisthenics
High-roller
 
Join Date: May 2018
Posts: 1,227
Reputation: 205
Default Re: #emit

https://forum.sa-mp.com/showthread.php?t=308670
https://forum.sa-mp.com/showthread.php?t=570930
https://forum.sa-mp.com/showthread.php?t=591705

For more, read about Assembly x86
__________________
Calisthenics is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
#emit, What's it? SystemX Scripting Help 3 22/01/2016 04:44 PM
when should #emit be used sammp Scripting Help 3 15/11/2014 09:49 AM
Emit Help Snir_sofer Scripting Help 2 25/09/2012 05:54 PM
#emit rVar Scripting Help 2 08/09/2012 06:26 PM
Help with #emit _Petrol_ Scripting Help 0 23/08/2012 03:54 PM


All times are GMT. The time now is 08:11 AM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.