Deji How to use SuperVars? I've seen the example but I can't understand it. And what is 'array'?
Arrays are a way to access equal portions of memory in a larger memory space. Those portions can be used as variables. The GTA scripting environments already support arrays which access the local variables memory space:
1@ = 2 // assign index
0@(1@,5i) = 3 // change the memory 8 bytes (4*index) from the address of 0@
// 2@ now contains the value '3'
The 'array' is: 0@(1@,5i)
Where 0@ is the 'base variable offset' (whose address is used as the beginning of the array), 1@ is the index (determining how far into the array to access), '5' refers to the total size of the array (actually completely unused - any value works just the same) and 'i' specifies you're accessing the array indexes as 4 byte integers. Hence the formula is something like 'offset + sizeof(type) * index'.
SuperVars modifies their behaviour in order to make it more useful. Now, instead of only accessing local variable memory, you can access any memory using a similar syntax and many other tricks...
0@ = 0x100 // imaginary memory address
0006: 0@(-2@,4s) = 0xDEADBEEF
Now, the 4 bytes at the memory address '0x108' contains the value '0xDEADBEEF'.
Here, everything works a bit differently...
0@(-2@,4s) - 0@ is now read, instead of it being turned into an address itself - the value it reads is instead treated as the start of the array
0@(-2@,4s) - Now, negative local variable indexes are treated as plain positive integer index (in this case '2') - which specifies that we're accessing the 3rd (as it starts from 0) array index.
0@(-2@,4s) - Now, the '4' refers to the size of the type we're trying to access. It was unused before, so now it has a legitimate purpose. In this case 4 means each index takes 4 bytes, and that is multiplied by the index to find the address to access. Most times this should be 4, because that's the only size the SCM script engine is capable of accessing using it's default operators.
0@(-2@,4s) - Finally, 's' is simply to specify it as a "SuperVar", making all this functionality work in the first place. Note, that this is usually used for string arrays. And in thinking that, Sanny Builder will try to compile it with string opcodes, unless you specify the correct opcodes to use. However, you can also go back to using regular arrays with 'i', 'f', or 'v' (for strings), but 's' can be used for all of those uses, anyway.
There are one or two slightly weird situations to get used to, however:
GET_VAR_POINTER 30@ STORE_TO 30@ // get memory address of 30@ - CLEO 4 opcode
0007: 30@(30@,4s) = 0.0
0006: 30@(-1@,4s) = 5
Here, we're accessing 30@ and 31@. To access the '0 index' you need to use the same variable as an index as the one you used for an offset. Because -0@ would be the same as 0@ and then it would attempt to read 0@ for the index, instead.
Here's a more practical example. SuperVars will automatically convert labels to full addresses when used as base addresses so you can easily set up a label with usable memory following it and access it for more variables. Alternatively, you could use CLEO 4's ALLOCATE_MEMORY and use the resulting memory (which is more optimal 75% of the time)...
1@ = @VARIABLES
0085: 2@ = 1@(1@,4s) // reads '0xDEADBEEF' to 2@
0085: 3@ = 1@(-1@,4s) // reads '0xCAFEBABE' to 3@
0085: 4@ = 1@(-2@,4s) // reads '0x8BADF00D' to 4@
0085: 5@ = 1@(-2@,4s) // reads '0x00BAC0DE' to 5@
EFBEADDE // index 0 "1@(1@,4s)"
BEBAFECA // index 1 "1@(-1@,4s)"
0DF0AD8B // index 2 "1@(-2@,4s)"
DEC0BA00 // index 3, etc..
There are some nicely written examples as part of the SuperVars archive and a more complete guide to its many uses. The examples include a flawless save system demonstrating a way to write SuperVar variables to a save-dependent file (since enable_thread_saving won't do that) and load it again when the script starts in a loaded game.
The examples also show you how to make it look easier to read...
GET_CHAR_HEALTH $PLAYER_ACTOR SVar[PlayerHealth]
// All this code is hurting my head...
000E: SVar[PlayerHealth] -= 10
SET_CHAR_HEALTH $PLAYER_ACTOR SVar[PlayerHealth]
And SuperVars also allows you to do crazy things like emulate C-like library for a basic object oriented language feel.
Note that SuperVars.asi will have to be installed on the users computer for it to work, but permission is given to distribute it with whatever you create. It's current version only supports 1.0 (badly need to update it). It's not the neatest solution, but the most stable way to access external memory directly, without memory reading and writing to and from variables every time you need to do something
Oh, yeah... one more thing. The limit of an index is -32768@, which can access memory as far as 4161536 bytes from the base address, I believe