Question about YSI
#1

Hello.



Who know's the YSI/y_va include know's about va_SendClientMessage.

I just readed the impl.inc and in my head i saw something like is counting the characters then use the string +1.
Is like you having 'hello' having 5 but the count will be 5+1 and then it stops, it is that true ?
I want to use it to be easyer for me not to count every message that i create is verry hard to count a lot of messages.

Code:
/**--------------------------------------------------------------------------**\
					==============================
					 y_va - Enhanced vararg code!
					==============================
Description:
	This library currently provides two functions - va_printf and va_format
	which perform printf and format using variable arguments passed to another
	function.
	
	This is bsed on the variable parameter passing method based on code by Zeex.
	See page 15 of the code optimisations topic.
Legal:
	Version: MPL 1.1
	
	The contents of this file are subject to the Mozilla Public License Version 
	1.1 (the "License"); you may not use this file except in compliance with 
	the License. You may obtain a copy of the License at 
	http://www.mozilla.org/MPL/
	
	Software distributed under the License is distributed on an "AS IS" basis,
	WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
	for the specific language governing rights and limitations under the
	License.
	
	The Original Code is the YSI vararg include.
	
	The Initial Developer of the Original Code is Alex "******" Cole.
	Portions created by the Initial Developer are Copyright © 2011
	the Initial Developer. All Rights Reserved.
	
	Contributors:
		ZeeX, koolk, JoeBullet/******63, g_aSlice/Slice
	
	Thanks:
		JoeBullet/******63 - Handy arbitrary ASM jump code using SCTRL.
		ZeeX - Very productive conversations.
		koolk - IsPlayerinAreaEx code.
		TheAlpha - Danish translation.
		breadfish - German translation.
		Fireburn - Dutch translation.
		yom - French translation.
		50p - Polish translation.
		Zamaroht - Spanish translation.
		Dracoblue, sintax, mabako, Xtreme, other coders - Producing other modes
			for me to strive to better.
		Pixels^ - Running XScripters where the idea was born.
		Matite - Pestering me to release it and using it.
	
	Very special thanks to:
		Thiadmer - PAWN, whose limits continue to amaze me!
		Kye/Kalcor - SA:MP.
		SA:MP Team past, present and future - SA:MP.
	
Version:
	1.0
Changelog:
	02/05/11:
		First version.
Functions:
	Public:
		-
	Core:
		-
	Stock:
		-
	Static:
		-
	Inline:
		-
	API:
		-
Callbacks:
	-
Definitions:
	-
Enums:
	-
Macros:
	-
Tags:
	-
Variables:
	Global:
		-
	Static:
		-
Commands:
	-
Compile options:
	-
Operators:
	-
\**--------------------------------------------------------------------------**/

static stock
	YSI_g_sHeap,
	YSI_g_sStack,
	YSI_g_sArgCount,
	YSI_g_sArgs[5];

stock va_printf(const fmat[], va_:STATIC_ARGS)
{
	// Get the number of parameters.
	#emit LOAD.S.alt   STATIC_ARGS
	#emit INC.alt      // 2 - n
	#emit SHL.C.alt    2
	// "alt" now contains the number of static arguments in bytes - 4.
	
	// Get the previous parameter count.
	#emit LOAD.S.pri   0
	#emit ADD.C        8
	#emit LOAD.I
	#emit SUB
	#emit ADD.C        8
	#emit STOR.pri     YSI_g_sArgCount // "printf"s parameter count.
	
	// Get the address of the arguments we are replacing.
	#emit LOAD.S.pri   0
	#emit ADD
	
	// Copy them to our temporary buffer.
	#emit CONST.alt    YSI_g_sArgs
	#emit MOVS         8 // (n + 1) * 4
	
	// Go to the new "top" of the stack.
	#emit STACK        0
	#emit STOR.alt     YSI_g_sStack    // Store it.
	#emit ADD.C        8 // (n + 1) * 4
	#emit SCTRL        4
	
	// "frm" is still valid.
	#emit PUSH.S       fmat            // Get the final parameter.
	#emit PUSH         YSI_g_sArgCount // Push the parameter count.
	
	// Call the function.
	#emit SYSREQ.C     printf
	#emit STOR.pri     YSI_g_sArgCount
	
	// Copy the data back.
	#emit STACK        0
	#emit CONST.pri    YSI_g_sArgs
	#emit MOVS         8
	#emit LOAD.pri     YSI_g_sStack
	#emit SCTRL        4
	
	#emit LOAD.pri     YSI_g_sArgCount
	#emit RETN
	
	// This new version of the code worked first time!  I'm very happy with that
	// result, but I also feel it was justified given how long I spent staring
	// at it!
	return 0;
}

stock va_CallRemoteFunction(const function[], const fmat[], va_:STATIC_ARGS)
{
	// Get the number of parameters.
	#emit LOAD.S.alt   STATIC_ARGS
	#emit SHL.C.alt    2
	// "alt" now contains the number of static arguments in bytes.
	
	// Get the previous parameter count.
	#emit LOAD.S.pri   0
	#emit ADD.C        8
	#emit LOAD.I
	#emit SUB
	#emit ADD.C        8
	#emit STOR.pri     YSI_g_sArgCount // "format"s parameter count.
	
	// Get the address of the arguments we are replacing.
	#emit LOAD.S.pri   0
	#emit ADD
	
	// Copy them to our temporary buffer.
	#emit CONST.alt    YSI_g_sArgs
	#emit MOVS         12 // (n + 1) * 4
	
	// Go to the new "top" of the stack.
	#emit STACK        0
	#emit STOR.alt     YSI_g_sStack    // Store it.
	#emit ADD.C        12 // (n + 1) * 4
	#emit SCTRL        4
	
	// "frm" is still valid.
	#emit PUSH.S       fmat
	#emit PUSH.S       function
	#emit PUSH         YSI_g_sArgCount // Push the parameter count.
	
	// Call the function.
	#emit SYSREQ.C     CallRemoteFunction
	#emit STOR.pri     YSI_g_sArgCount
	
	// Copy the data back.
	#emit STACK        0
	#emit CONST.pri    YSI_g_sArgs
	#emit MOVS         12
	#emit LOAD.pri     YSI_g_sStack
	#emit SCTRL        4
	
	#emit LOAD.pri     YSI_g_sArgCount
	#emit RETN
	
	return 0;
}

stock va_CallLocalFunction(const function[], const fmat[], va_:STATIC_ARGS)
{
	// Get the number of parameters.
	#emit LOAD.S.alt   STATIC_ARGS
	#emit SHL.C.alt    2
	// "alt" now contains the number of static arguments in bytes.
	
	// Get the previous parameter count.
	#emit LOAD.S.pri   0
	#emit ADD.C        8
	#emit LOAD.I
	#emit SUB
	#emit ADD.C        8
	#emit STOR.pri     YSI_g_sArgCount // "format"s parameter count.
	
	// Get the address of the arguments we are replacing.
	#emit LOAD.S.pri   0
	#emit ADD
	
	// Copy them to our temporary buffer.
	#emit CONST.alt    YSI_g_sArgs
	#emit MOVS         12 // (n + 1) * 4
	
	// Go to the new "top" of the stack.
	#emit STACK        0
	#emit STOR.alt     YSI_g_sStack    // Store it.
	#emit ADD.C        12 // (n + 1) * 4
	#emit SCTRL        4
	
	// "frm" is still valid.
	#emit PUSH.S       fmat
	#emit PUSH.S       function
	#emit PUSH         YSI_g_sArgCount // Push the parameter count.
	
	// Call the function.
	#emit SYSREQ.C     CallLocalFunction
	#emit STOR.pri     YSI_g_sArgCount
	
	// Copy the data back.
	#emit STACK        0
	#emit CONST.pri    YSI_g_sArgs
	#emit MOVS         12
	#emit LOAD.pri     YSI_g_sStack
	#emit SCTRL        4
	
	#emit LOAD.pri     YSI_g_sArgCount
	#emit RETN
	
	return 0;
}

stock va_SetTimerEx(const function[], interval, bool:repeating, const fmat[], va_:STATIC_ARGS)
{
	// Get the number of parameters.
	#emit LOAD.S.alt   STATIC_ARGS
	#emit DEC.alt      // 2 - n
	#emit DEC.alt
	#emit SHL.C.alt    2
	// "alt" now contains the number of static arguments in bytes - 8.
	
	// Get the previous parameter count.
	#emit LOAD.S.pri   0
	#emit ADD.C        8
	#emit LOAD.I
	#emit SUB
	#emit ADD.C        8
	#emit STOR.pri     YSI_g_sArgCount // "format"s parameter count.
	
	// Get the address of the arguments we are replacing.
	#emit LOAD.S.pri   0
	#emit ADD
	
	// Copy them to our temporary buffer.
	#emit CONST.alt    YSI_g_sArgs
	#emit MOVS         20 // (n + 1) * 4
	
	// Go to the new "top" of the stack.
	#emit STACK        0
	#emit STOR.alt     YSI_g_sStack    // Store it.
	#emit ADD.C        20 // (n + 1) * 4
	#emit SCTRL        4
	
	// "frm" is still valid.
	#emit PUSH.S       fmat
	#emit PUSH.S       repeating
	#emit PUSH.S       interval
	#emit PUSH.S       function
	#emit PUSH         YSI_g_sArgCount // Push the parameter count.
	
	// Call the function.
	#emit SYSREQ.C     SetTimerEx
	#emit STOR.pri     YSI_g_sArgCount
	
	// Copy the data back.
	#emit STACK        0
	#emit CONST.pri    YSI_g_sArgs
	#emit MOVS         20
	#emit LOAD.pri     YSI_g_sStack
	#emit SCTRL        4
	
	#emit LOAD.pri     YSI_g_sArgCount
	#emit RETN
	
	return 0;
}

stock va_format(out[], size, const fmat[], va_:STATIC_ARGS)
{
	//P:C(if (_:STATIC_ARGS < 1) P:W("No static args found, please add a dummy local"););
	// Get the number of parameters.
	#emit LOAD.S.alt   STATIC_ARGS
	#emit DEC.alt      // 2 - n
	#emit SHL.C.alt    2
	// "alt" now contains the number of static arguments in bytes - 4.
	
	// Get the previous parameter count.
	#emit LOAD.S.pri   0
	#emit ADD.C        8
	#emit LOAD.I
	#emit SUB
	#emit ADD.C        8
	#emit STOR.pri     YSI_g_sArgCount // "format"s parameter count.
	
	// Get the address of the arguments we are replacing.
	#emit LOAD.S.pri   0
	#emit ADD
	
	// Copy them to our temporary buffer.
	#emit CONST.alt    YSI_g_sArgs
	#emit MOVS         16 // (n + 1) * 4
	
	// Go to the new "top" of the stack.
	#emit STACK        0
	#emit STOR.alt     YSI_g_sStack    // Store it.
	#emit ADD.C        16 // (n + 1) * 4
	#emit SCTRL        4
	
	// "frm" is still valid.
	#emit PUSH.S       fmat
	#emit PUSH.S       size
	#emit PUSH.S       out
	#emit PUSH         YSI_g_sArgCount // Push the parameter count.
	
	// Modify the heap to hold "locals".
	#emit HEAP         0
	#emit STOR.alt     YSI_g_sHeap
	#emit LCTRL        4
	#emit SCTRL        2
	
	// Call the function.
	#emit SYSREQ.C     format
	#emit STOR.pri     YSI_g_sArgCount
	
	// Copy the data back.
	#emit LOAD.pri     YSI_g_sHeap
	#emit SCTRL        2
	#emit STACK        0
	#emit CONST.pri    YSI_g_sArgs
	#emit MOVS         16
	#emit LOAD.pri     YSI_g_sStack
	#emit SCTRL        4
	
	#emit LOAD.pri     YSI_g_sArgCount
	#emit RETN
	
	return 0;
}

stock va_return(const fmat[], va_:STATIC_ARGS)
{
	static
		out[YSI_MAX_STRING * 8],
		size = sizeof (out);
	
	// Get the number of parameters.
	#emit LOAD.S.alt   STATIC_ARGS
	#emit DEC.alt      // 2 - n
	#emit SHL.C.alt    2
	// "alt" now contains the number of static arguments in bytes - 4.
	
	// Get the previous parameter count.
	#emit LOAD.S.pri   0
	#emit ADD.C        8
	#emit LOAD.I
	#emit SUB
	#emit ADD.C        8
	#emit STOR.pri     YSI_g_sArgCount // "format"s parameter count.
	
	// Get the address of the arguments we are replacing.
	#emit LOAD.S.pri   0
	#emit ADD
	
	// Copy them to our temporary buffer.
	#emit CONST.alt    YSI_g_sArgs
	#emit MOVS         16 // (n + 1) * 4
	
	// Go to the new "top" of the stack.
	#emit STACK        0
	#emit STOR.alt     YSI_g_sStack    // Store it.
	#emit ADD.C        16 // (n + 1) * 4
	#emit SCTRL        4
	
	// "frm" is still valid.
	#emit PUSH.S       fmat
	#emit PUSH         size
	#emit PUSH.C       out
	#emit PUSH         YSI_g_sArgCount // Push the parameter count.
	
	// Modify the heap to hold "locals".
	#emit HEAP         0
	#emit STOR.alt     YSI_g_sHeap
	#emit LCTRL        4
	#emit SCTRL        2
	
	// Call the function.
	#emit SYSREQ.C     format
	
	// Copy the data back.
	#emit LOAD.pri     YSI_g_sHeap
	#emit SCTRL        2
	#emit STACK        0
	#emit CONST.pri    YSI_g_sArgs
	#emit MOVS         16
	#emit LOAD.pri     YSI_g_sStack
	#emit SCTRL        4
	
	// Now do the real return.
	return out;
}

stock va_strlen(arg)
{
	// Get the length of the string at the given position on the previous
	// function's stack (convenience function).
	// Get the address of the previous function's stack.  First get the index of
	// the argument required.
	#emit LOAD.S.pri arg
	// Then convert that number to bytes from cells.
	#emit SMUL.C     4
	// Get the previous function's frame.  Stored in variable 0 (in the current
	// frame).  Parameters are FRM+n+12, locals are FRM-n, previous frame is
	// FRM+0, return address is FRM+4, parameter count is FRM+8.  We could add
	// checks that "arg * 4 < *(*(FRM + 0) + 8)", for the previous frame parameter
	// count (in C pointer speak).
	#emit LOAD.S.alt 0
	// Add the frame pointer to the argument offset in bytes.
	#emit ADD
	// Add 12 to skip over the function header.
	#emit ADD.C      12
	// Load the address stored in the specified address.
	#emit LOAD.I
	// Push the address we just determined was the source.
	#emit PUSH.pri
	// Push the number of parameters passed (in bytes) to the function.
	#emit PUSH.C     4
	// Call the function.
	#emit SYSREQ.C   strlen
	// Restore the stack to its level before we called this native.
	#emit STACK      8
	#emit RETN
	// Never called.
	return 0;
}

stock va_getstring(dest[], arg, len = sizeof (dest))
{
	// Get the address of the previous function's stack.  First get the index of
	// the argument required.
	#emit LOAD.S.pri arg
	// Then convert that number to bytes from cells.
	#emit SMUL.C     4
	// Get the previous function's frame.  Stored in variable 0 (in the current
	// frame).  Parameters are FRM+n+12, locals are FRM-n, previous frame is
	// FRM+0, return address is FRM+4, parameter count is FRM+8.  We could add
	// checks that "arg * 4 < *(*(FRM + 0) + 8)", for the previous frame parameter
	// count (in C pointer speak).
	#emit LOAD.S.alt 0
	// Add the frame pointer to the argument offset in bytes.
	#emit ADD
	// Add 12 to skip over the function header.
	#emit ADD.C      12
	// Load the address stored in the specified address.
	#emit LOAD.I
	// Push the length for "strcat".
	#emit PUSH.S     len
	// Push the address we just determined was the source.
	#emit PUSH.pri
	// Load the address of the destination.
	#emit LOAD.S.alt dest
	// Blank the first cell so "strcat" behaves like "strcpy".
	#emit CONST.pri  0
	// Store the loaded number 0 to the loaded address.
	#emit STOR.I
	// Push the loaded address.
	#emit PUSH.alt
	// Push the number of parameters passed (in bytes) to the function.
	#emit PUSH.C     12
	// Call the function.
	#emit SYSREQ.C   strcat
	// Restore the stack to its level before we called this native.
	#emit STACK      16
}

stock PlayerText:va_CreatePlayerTextDraw(playerid, Float:x, Float:y, fmat[], va_args<>)
{
	return CreatePlayerTextDraw(playerid, x, y, va_return(fmat, va_start<4>));
}

stock Text:va_TextDrawCreate(Float:x, Float:y, fmat[], va_args<>)
{
	return TextDrawCreate(x, y, va_return(fmat, va_start<3>));
}

stock va_SendClientMessage(playerid, colour, const fmat[], va_args<>)
{
	return SendClientMessage(playerid, colour, va_return(fmat, va_start<3>));
}

stock va_SendClientMessageToAll(colour, const fmat[], va_args<>)
{
	return SendClientMessageToAll(colour, va_return(fmat, va_start<2>));
}

stock va_SendPlayerMessageToPlayer(playerid, senderid, const fmat[], va_args<>)
{
	return SendPlayerMessageToPlayer(playerid, senderid, va_return(fmat, va_start<3>));
}

stock va_SendPlayerMessageToAll(senderid, const fmat[], va_args<>)
{
	return SendPlayerMessageToAll(senderid, va_return(fmat, va_start<2>));
}

stock va_GameTextForPlayer(playerid, const fmat[], time, style, va_args<>)
{
	return GameTextForPlayer(playerid, va_return(fmat, va_start<4>), time, style);
}

stock va_GameTextForAll(const fmat[], time, style, va_args<>)
{
	return GameTextForAll(va_return(fmat, va_start<3>), time, style);
}

stock va_print(const fmat[], va_args<>)
{
	return print(va_return(fmat, va_start<1>));
}

stock va_fprintf(File:fhnd, const fmat[], va_args<>)
{
	return fwrite(fhnd, va_return(fmat, va_start<2>));
}
Reply
#2

Still up.
Reply
#3

This is the case for all strings (unless if you're using the dynamic memory plugin).
Strings (arrays) are basically just a bunch of variables. PAWN reads these arrays as strings. All string functions (reading strings, strings such as strcmp(), strlen()) use the null terminator (aka EOS aka \0) to find the end of the string.
So if you have the text "hello", the array needs the size of the string (in this case 5) + 1 cell (one cell is one index / memory space of the array) for the null terminator. This is what "hello" would look like:
pawn Code:
//Using: new myArray[] = "Hello";
//Would basically be this:

new myArray[6];
myArray = {
    'H', 'e', 'l', 'l', 'o', EOS //EOS == '\0'
};
If you have a larger array where not all space is used, the null terminator is placed after the last character so that during runtime the end of the string is found. All string functions use the null terminator. Example:
pawn Code:
new myArray[10] = "Hello";
//so, myArray is:
//'H', 'e', 'l', 'l', 'o', EOS, '', '', '', '', EOS
That's why strlen() in this case would return 5 and not 10, because it stops at the null terminator. And as you can see, those unused characters are a waste of space. One cell is 32 bits and thus 4 bytes (1 byte = 8 bits). In above example, 5 cells are wasted and thus 5*4 = 20 bytes.

You don't have to define the array size of the array has a default value/input. For example:
pawn Code:
new myArray[] = "Hello world!";
would automatically assign 13 cells.

And that's why you include one more cell than the size of the array. It is not y_va specific.
Reply
#4

Quote:
Originally Posted by Kwarde
View Post
This is the case for all strings (unless if you're using the dynamic memory plugin).
Strings (arrays) are basically just a bunch of variables. PAWN reads these arrays as strings. All string functions (reading strings, strings such as strcmp(), strlen()) use the null terminator (aka EOS aka \0) to find the end of the string.
So if you have the text "hello", the array needs the size of the string (in this case 5) + 1 cell (one cell is one index / memory space of the array) for the null terminator. This is what "hello" would look like:
pawn Code:
//Using: new myArray[] = "Hello";
//Would basically be this:

new myArray[6];
myArray = {
    'H', 'e', 'l', 'l', 'o', EOS //EOS == '\0'
};
If you have a larger array where not all space is used, the null terminator is placed after the last character so that during runtime the end of the string is found. All string functions use the null terminator. Example:
pawn Code:
new myArray[10] = "Hello";
//so, myArray is:
//'H', 'e', 'l', 'l', 'o', EOS, '', '', '', '', EOS
That's why strlen() in this case would return 5 and not 10, because it stops at the null terminator. And as you can see, those unused characters are a waste of space. One cell is 32 bits and thus 4 bytes (1 byte = 8 bits). In above example, 5 cells are wasted and thus 5*4 = 20 bytes.

You don't have to define the array size of the array has a default value/input. For example:
pawn Code:
new myArray[] = "Hello world!";
would automatically assign 13 cells.

And that's why you include one more cell than the size of the array. It is not y_va specific.
Yes my friend thanks for this tutorial is worthing a lot.

This is how i do a format message that i need something to show like a number or a name.
Code:
new string[9], test = 0;
format(string, sizeof(string), "Hello %d", test);
SendClientMessage(playerid, -1, string);
Ok, so i wanted to ask about 'YSI/y_va' if it works how it supposed to be, in that include if you look closely it has something to count the characters then to end it.
The reason why i ask is because i don't need to count every single char, and i don't want to use EOS.

Normal format:
Code:
new string[9], test = 0;
format(string, sizeof(string), "Hello %d", test);
SendClientMessage(playerid, -1, string);
YSI/y_va format:
Code:
new test = 0;
va_SendClientMessage(playerid, -1, "Hello %d", test);
It's more simple and i don't need to count and dont need to use EOS.
And the question about everything is, it is how EOS works to end the character count string at the end or it keeps counting until MAX_STRING and ruin my host CPU MEM ?

Edit: imagine using
Code:
new string[MAX_STRING]; // GLOBAL

new test = 0;
string[0] = (EOS);
format(string, sizeof(string), "Hello %d", test);
SendClientMessage(playerid, -1, string);
Instead of

Code:
new test = 0;
va_SendClientMessage(playerid, -1, "Hello %d", test);
I want to know if 'y_va' will use more CPU MEM than EOS.
Reply
#5

Quote:

'YSI/y_va'

YSI_Coding\y_va* (if no warning is displayed, you are using an older version of YSI and I can recommend you to upgrade to the latest YSI).

Quote:

It's more simple and i don't need to count and dont need to use EOS.

In normal situations you don't need to use EOS, this goes automatically. I merely showed you how strings work. Eg. doing this:
pawn Code:
new myArray[15];
format(myArray, 15, "Hello world!"); //Note that in this situation, using [myArray = "Hello world!";] would be a much better choice
Will automatically set the array to (something like):
Code:
{'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!', EOS, '', '', EOS}
.

As for being afraid of wasting memory. Just make sure you don't use way too much cells like some people do (eg. using 512 cells for a client message).
Here's a pretty safe SendClientMessageFormatted(ToAll) function:
pawn Code:
SendClientMessageFormatted(playerid, color, const format[], va_args<>)
{
    new __scmfStr[144];
    va_format(__scmfStr, 144, format, va_start<3>);
    if (playerid == INVALID_PLAYER_ID)
        return SendClientMessage(playerid, color, __scmfStr);
    else return SendClientMessageToAll(color, __scmfStr);
}
#define SendClientMessageToAllFormatted(%0) SendClientMessage(INVALID_PLAYER_ID, %0)
Some people tend to use 'static' instead of 'new'. By doing this it's allocated to the global memory (and thus also the amx size -no issue though) instead of the stack. This could mean it's a bit faster but I don't think it makes that much of a difference. static variables also remember their value (unless if it's a file-global variable/symbol, then it's a symbol that's only available for that file) so if sensitive data was sent using above function, it's stored in the server(/system)'s memory.

Anyway, to go to your question:
Quote:

I want to know if 'y_va' will use more CPU MEM than EOS.

EOS isn't a system like y_va. EOS is just a macro for '\0', which is just a character. You are trying to compare a character to a system (that's like comparing the letter K with a TV). And even y_va would use EOS if needed, because that's just how PAWN works. All string functions use the null terminator to determine the length of the string. If you have this array/string:
pawn Code:
new myArray[] = "Hello there cruel cruel beautifull world!";
myArray[5] = EOS; //[5] is the space after Hello
printf("Length of myArray is %d", strlen(myArray));
print(myArray);
It would print:
Code:
Length of myArray is 5
Hello
The null terminator was found after 'o' so it assumes it's the end of the string. The rest of the array is then totally ignored. Some (old) 'erase' functions set the null terminator to the first index of an array. This does not erase the string but merely
I do get what you mean though, and remember this:
Y_L3ss is all about optimalisations. In general you're best of using YSI's library, so just go for it. Also, GTA SA/SAMP is pretty old. Systems these days should not have problems with it (unless if you're using a VPS with crap CPUs -large gamemodes could then run into problems).


Also I'm a bit tired at this moment so if there are typo's or perhaps some information that's a tad wrong I offer you my humble and sincere apologies.
Reply
#6

Ok Ok, the tutorial is nice and i learned a lot from it.

But i don't think we get the same question :P.

I got 'Hello' i have 5 chars but i need to add +1 to work ok ?. Good

I want to use a system that count the chars without making me count them first and determine them.

Code:
new str[6];
'Hello'; I don't want this.
I want something a system i think YSI/y_va has it but idk how to read that code and idk if it has it or not.
That code i think count's untill the last char +1 then stops the count and get's cleared.
That is what i want, anything else like your tutorial mostly i knewed.

I repeat thanks a lot for these tutorials i got a some few steps that helped me from your tuts.
Reply
#7

Use notepad++. It shows length of the text. Alternatively, if you have this string: "Your ID is %d!", and your max playerID is 150 and thus 5 characters lang, you could do this:
Code:
new string[] = "Your ID is XXX!";
That way the compiler sets the array size and you don't have to count. However that's inconvenient especially when the inputs can be long. Otherwise, such a thing is not possible afaik (unless when using the dynamic memory plugin)

You keep coming up with string lengths and y_va. va stands for varargs. It's a library that provides va_printf() and va_format(), using a system to easily use multiple undefined parameters. The alternative would be using "..." and functions such as getarg() and numargs(). It doesn't have anything to do with counting the length of a string.
Reply
#8

Thanks @Kwarde for all your time and tuts.

This is what i wanted to know
Code:
y_va, doesn't have anything to do with counting the length of a string.
Thanks, and nice thing about counting the length of a text in notepad++ i will use it is more efficient.


T/C.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)