[Tutorial] Accessing enumerator array via emit
#1

Hello. I decided that I'll share things I learned about emit with you guys - feel free to correct me (both in langauge and script)

We start with:

pawn Code:
#include <a_samp>
#define BYTES(%0) (4 * (%0))
#define SIZE    (6)

enum Bollocks {
    id,
    pancake[32]
}
new Arr[SIZE][Bollocks];
1 constant for size of array, and one macro for swapping cell to bytesize (yeah, you can do it by hand, and you can't use in emit, but it can be useful).

What will we do today? I propose copying string from address a1 to each element of array.

pawn Code:
main() {
    new copycat[32] = "0123456789012345678901234567890";
    new addr;
    #emit ADDR.pri      copycat
    #emit STOR.S.pri    addr

    new stringPos = BYTES(_:pancake);
We have 32 cells long string (array of chars to be exact (but not char-array)). We need its address in near future, so we'll retrieve it using ADDR (FRM + offset) and store it in addr variable. Simple. The stringPos variable points to offset of 'pancake' enum field and converts it to cellsize (in our case it is 1*4, for id field it is 0*4).

pawn Code:
for(new offset = 0; offset != BYTES(SIZE); offset += BYTES(1)) {
        #emit ZERO.pri
        #emit MOVE.alt
We start a loop with 4 step, and iterate our array. First thing we do is pri = 0, alt = pri (if you forget about this, you can get random values from previous calculations).

pawn Code:
#emit CONST.alt     Arr
#emit LOAD.S.pri    offset
#emit ADD
#emit MOVE.alt
#emit LOAD.I
#emit ADD
#emit LOAD.S.alt    stringPos
#emit ADD
#emit MOVE.alt
#emit LOAD.S.pri    addr
#emit MOVS          128
}
Let's get through this step by step:

pawn Code:
#emit CONST.alt     Arr
#emit LOAD.S.pri    offset
#emit ADD
#emit MOVE.alt
#emit LOAD.I
#emit ADD
Load address of Arr to alt register. Load value of offset to pri register, then add those values (Arr address + current offset). Copy value of pri to alt (pri = arr address + current offset, alt = pri), and load the value at address held in pri.

pawn Code:
#emit LOAD.S.alt    stringPos
#emit ADD
#emit MOVE.alt
#emit LOAD.S.pri    addr
#emit MOVS          128
Load to alt register value in stringPos (which is pancake field offset in bytes), and add values (value of Arr[offset] + pancake offset). Move value from pri to alt. Load value from addr to pri (addr holds address of first character in copycat string). Finally copy 128 bytes (32 cells) from copycat starting at Arr[offset/4][pancake][0].

pawn Code:
for(new i = 0; i != SIZE; ++i) {
    printf("Row %d: \"%s\"", i+1, Arr[i][pancake]);
}
Result:

pawn Code:
Row 1: "Hello there. What's up?"
Row 2: "Hello there. What's up?"
Row 3: "Hello there. What's up?"
Row 4: "Hello there. What's up?"
Row 5: "Hello there. What's up?"
Row 6: "Hello there. What's up?"
Mission accomplished!

Summary - to access any element in enum array

pawn Code:
enum Wat {
    a = 5,
    b = 30,
    c = 65
}
new A[10][Wat][3];
(let's say set A[5][b][2] to 25)
All we have to do is:

pawn Code:
new offset = _:b * 4;
#emit ZERO.pri
#emit MOVE.alt

#emit CONST.pri A
#emit ADD.C 0x10 //(5*4 = 20 = 0x10)
#emit MOVE.alt
#emit LOAD.I
#emit ADD
#emit LOAD.S.alt offset
#emit ADD
#emit MOVE.alt
#emit LOAD.I
#emit ADD
#emit CONST.alt 8
#emit ADD
#emit MOVE.alt
#emit CONST.pri 25
#emit STOR.I
Done!
Reply
#2

To be honest, you lost me before the loop. I am gonna have to re - read Y_Less's tutorial again ! But whatever I did follow was awesome, gave insight on what we use - we take for granted !
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)