[Tutorial] Using bit arrays in PAWN
#1

Using bit arrays

Introduction
Since I like to write tutorials about saving memory, I decided to come up with this tutorial, which teaches you the real meaning of boolean arrays, aswell as bit arrays, and how to use them!

What are boolean arrays?
Boolean arrays look like this:

pawn Код:
new bool:gPlayerArray[MAX_PLAYERS];
However, "bool" is just a predefined tag, "true" and "false" are the values for 1 and 0 respectively, so in reality these arrays can actually hold up to 2,147,483,647 values, just like normal variables. If MAX_PLAYERS is 500, the array above is 2,000 bytes.

There are also "char arrays":

pawn Код:
new bool:gPlayerArray[MAX_PLAYERS char];
The array above is a mere 500 bytes. Still, not bad, but there is still some sparse data left in the array.

Now let's take a bit at bit arrays:

pawn Код:
new BitArray:gPlayerArray<MAX_PLAYERS>;
Believe it or not, the array above is only 29 bytes! Bit arrays use a complex method of packing data into the array, by tightly packing the data into a 1-bit array using specialized bit manipulation, rather than each 4-byte cell (as opposed to regular arrays) or each byte (as opposed to char arrays, I still need clarification on this though).

Let's get started!
You can get y_bit from the latest YSI version here:

https://sampforum.blast.hk/showthread.php?tid=321092

You can either use "Bit:" or "BitArray:" to initialize bit arrays:

pawn Код:
new BitArray:gUsingPhone<MAX_PLAYERS>;
These arrays only hold 1-bit values, which are either "true" or "false". Here are a list of relevant functions:

pawn Код:
Bit_Let(BitArray:array<>, slot);
This will set the value in the specified slot to "true".

pawn Код:
Bit_Vet(BitArray:array<>, slot);
This will set the value in the specified slot to "false".

pawn Код:
Bit_Set(BitArray:array<>, slot, bool:value);
This will set the value in the specified slot to "value", which can be either true or false.

pawn Код:
Bit_Get(BitArray:array<>, slot);
Returns either "true" or "false", depending on the value set.

Multiple dimensions
You can also use 2D arrays with these bit arrays:

pawn Код:
new BitArray:gVehicleStreamed[MAX_VEHICLES]<MAX_PLAYERS>;
Setting the value is slightly different, since you need to specify both indices:

pawn Код:
Bit_Let(gVehicleStreamed[vehicleid], playerid, true);
The same goes for the other functions.

Multiple bits
y_bit supports 1 bit arrays, and that's all that you'll probably need. If you feel that you need more bits, you might want to check out "rBits":

https://sampforum.blast.hk/showthread.php?tid=275142

It supports 1 bit, as well as 2, 4, 8 and 16 bits (a normal variable is 32 bits).

Conclusion
You've reached the end of this tutorial, that's cool.

The reason why I write these type of tutorials is to point out better methods of saving memory in PAWN, because nobody wants a cluttered, 500 MB AMX file!
Reply
#2

I hope people would read this because Bit Array saves a lot of memory! I have been using y_bits since I came back from scripting which was in (2013), here's some more example: http://forum.sa-mp.com/showpost.php?...4&postcount=16
Reply
#3

Can I ask why does when I use new Text:Library[MAX_PLAYERS char] = { Text:INVALID_TEXT_DRAW, ...};

and later

pawn Код:
for(new playerid; playerid < MAX_PLAYERS; playerid++)
    {
        Library[playerid] = TextDrawCreate(301.000000, 300.000000, "Library~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~");
...
    }
It says

[19:49:16] [debug] Run time error 4: "Array index out of bounds"
[19:49:16] [debug] Accessing element at index 29 past array upper bound 28


Whats so special about that char and where I can read more about it?

Its like Library[MAX_PLAYERS] would have just 29 cells
Reply
#4

Try this:

pawn Код:
for(new playerid; playerid < MAX_PLAYERS; playerid++)
    {
        Library{playerid} = TextDrawCreate(301.000000, 300.000000, "Library~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~~n~");
...
    }
You need to use curly braces, as opposed to square brackets, when accessing an index within a char array.
Reply
#5

@ikey07 That shows up because MAX_PLAYERS is 500, and the Char-Array has a limit, if you go over than 255 it will give a Crash Detect warning which is

pawn Код:
[19:49:16] [debug] Run time error 4: "Array index out of bounds"
[19:49:16] [debug]  Accessing element at index 29 past array upper bound 28
So I'd suggest you re-define the MAX_PLAYERS to 255, if you want to use Char-Array

pawn Код:
#if (defined MAX_PLAYERS)
    #undef MAX_PLAYERS
    #define MAX_PLAYERS (255)
#endif
Char Array Limits: YOU must not go over 255 and lower than [b]0, also Char-Array uses Curly Braces ( { and }) )
Reply
#6

I have defined MAX_PLAYERS as 114, but seems I might use it only for player stats where I need 1/0
Reply
#7

I have this

Код:
enum e_Enum {
    bit:pRegistered
    // Another enum
};
new PlayerData[playerid][e_Enum];

How to use bit_vet?
Reply
#8

Quote:
Originally Posted by Patrick
Посмотреть сообщение
So I'd suggest you re-define the MAX_PLAYERS to 255, if you want to use Char-Array
That's not the issue, at all. A char array can store values up to 255 as you correctly point out, but invalid text draw is 0xFFFF which translates to 65535; way beyond that limit. Size of the array is irrelevant. You could create an array of size 4000 char which would allow you to store 4000 values between 0 and 255.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)