Latest Forum Activity

GTAG - Downloads - ASI Plugins - SuperVars


DownloadDisclaimer: GTAG cannot be held responsible for any user submitted files.
TitleDownloadsFile sizeSubmitted
SuperVars129128.66 KB2 Mar 2013
Games SA
SummaryA variables extension for CLEO scripters
Rating5 (1 votes)
Submitted2 Mar 2013


-------------------------- SuperVars --------------------------


This is intended for modders. Installation is as simple as    
dropping the SuperVars.asi file into your main GTASA          
installation directory. Any scripts written with SuperVars    
only work with SuperVars installed. Therefore permission is    
granted to supply the ASI with any mod depending on it.

  Background Story  

I originally created the script 'ExtraVars' which demonstrated
a way to extend the limitations on variable usage by directly  
accessing memory using var arrays. A little example:

It's really like using a memory array in reverse, with 31@    
being the offset and 1@ being the index. 31@ would actually be
an offset from 0@ to a memory space, divided by 4. This        
basically tricks the game into reading and writing to the      
memory instead of the variable space itself.

However, this method wasn't without fault. I started noticing  
crashes caused by the index falling to certain values and      
causing the game to write to a bad section of memory.

I released a new method, using 'global' variables, which      
seemed a more fool-proof way to do it since the beginning      
offset would be static. Unfortunately it wasn't after a lot of
heavy use that I started to notice problems with this too,    
though it happened a lot less frequently.

In theory, a completely safe method would be to use two static
addresses within the EXE boundaries, but this would result in  
conflicts as CLEO's would all have to use the same space.

  A Solution

SuperVars is my perfectly stable solution to the problem. Not  
only is it 100% stable, but it comes with some super bonuses,  
hence the name.

However, the solution comes in the form on an ASI script,      
which will inevitably be a deterant to some, but I can't      
stress how much of a better solution it is. Also, in Sanny    
Builder, the opcode must be written on all operators using    
these vars, which if you've ever tried to use constants for    
variables in Sanny, isn't anything new. But don't worry, Sanny
Builder won't be the only compiler available for long.

SuperVars hooks SA's script array processing functions in      
order to use memory indexes as intended. Well, that was the    
original plan anyway... But since we're hooking the functions,
I figured I could make it better still...

  Basic Usage

SET_BIT_L 38@ 8

The first thing to do is let SuperVar's know we want to use    
it. SuperVar's will check if the script's +0xD5 flag is set,  
which can be easily done using the code line above. It can    
also be disabled with CLEAR_BIT_L.

If enabled, your string array variables won't be string array  
variables anymore. You may think that's a really bad thing,    
but these are barely used in regular scripts (due to the limit
on variables, you see). They instead will be regular arrays.  
Not regular SCM script arrays. Real arrays, like in a real    
programming language. Now that's nice.

Additionally, SuperVars sets another bit (+D5 bit 2) which can
be used to ensure that SuperVars is installed, for example:
    IF NOT IS_BIT_SET_L 38@ 9
        // SuperVars not installed, this mod cannot continue
        PRINT_HELP_STRING "This script needs SuperVars to run"

Unlike ExtraVars, SuperVars don't have to have a calculated    
index. They look like this:
    31@(-1@,4s) = 1

31@ contains a memory address - the start of your new variable
pool. -1@ is the array index. You may notice how it's actually
a negative variable index, well all constant indexes for      
SuperVars should be negative, going up to -32768@. If you were
to use 1@ as the index, SuperVars would read the value of 1@  
instead use that value as an index. To have a zero-index you  
simply use the address var, like so: 31@(31@,4s) - this will  
write directly to the address.

In the final part, '4s', 4 is the size of the array elements.  
Note, however, that specifying a different value such as 1 or  
2 will not currently allow you to write that many bytes to the
address, but will simply change how the index is calculated.  
So using 31@(-1@,2s) will access the memory +2 bytes of the    
address stored in 31@. If the size is 4, it's +4 bytes. It's  
recommended to only use 4 for this parameter for now, until    
SuperVars is able to force writing values of different sizes.

If you want to use default string arrays again, either use the
longstring variant or disable SuperVar operations until you    
need them again like so:
    CLEAR_BIT_L 38@ 8

However, SuperVars still works with string arrays just fine.

SuperVars won't affect string arrays with global var indexes.  

  Advanced Usage  

Given the information so far, most may go to use code looking  
like this:
    GET_LABEL_POINTER @VariablesMemory 0@
    0@(0@,4s) = 1
    0@(-1@,4s) = 2

However, SuperVars can operate on label pointer values itself.
So you can instead write it like this:
    0@ = @VariablesMemory
    0@(0@,4s) = 1
    0@(-1@,4s) = 2

This should make providing CLEO 3 compatibility easier.

Obviously, a HEX..END construct should follow :VariablesMemory
with enough bytes (00's) of space to store your data.

You can make using SuperVars easier using Sanny's const and    
var constructs.
    SUPERVAR = string

Since SuperVar's operate on string arrays, you can emulate a  
new type by making 'SuperVar' a constant for 'string'. By      
doing this, you can declare your SuperVar like so:
    0@ : array 4 of SuperVar

Where '4' is the size of the elements in your SuperVar. What's
more, you can create a constant for the SuperVar variable      
    SUPERVAR = string
    SVAR = 0@

Which means you can make your code look much neater:
    IF 0039:   SVar[-1@] == 0
        0006: SVar[-1@] = 1

What's more, you can assign constants to the indexes          
themselves, resulting in a somewhat object-oriented appearance
to your scripts:
    SUPERVAR = string
    RPGStats = 0@
    Score = RPG
    Level = -1@
    Money = -2@
    Experience = -3@
    0006: RPGStats = @RPGStats_Memory
    0006: RPGStats[Score] = 0
    0006: RPGStats[Level] = 1
    0006: RPGStats[Money] = 500
    0007: RPGStats[Experience] = 0.0

We can also get the offset of an array element in CLEO 4:
    GET_VAR_POINTER RPGStats[Money] 1@
    READ_MEMORY 1@ 4 OFF 2@  // returns "500" to 2@

This could be used to circumvent the inability to write lower
sizes of data for now.


SuperVars also fully support working with string opcodes:
    0@ = @StringMemory
    06D2: 0@(0@,4s) = "0123456789ABCDEFG"
    PRINT_HELP_STRING 0@  // 0123456789ABCDEF

Will print "0123456789ABCDEF" as theres a limit of 16 chars on
the opcode. Though it's not at all hard to create a longer    
string 16 chars at a time...
    0@ = @StringMemory
    06D2: 0@(0@,4s) = "0123456789ABCDEF"
    06D2: 0@(-1@,16s) = "GHIJKLMNOPQRSTUV"
    06D2: 0@(-2@,16s) = "WXYZ"

The entire string will be printed. We can also use this to    
print the portion of the string located at the index:

This will print just the alphabet portion of the string. Of    
course, we aren't just restricted to using CLEO 4 opcodes:
    05AA: 0@(0@,8s) = 'MOREREP'
    05AA: 0@(-1@,8s) = 'HELP101'
    PRINT_HELP 0@(0@,8s)  // ~s~You need to gain more respect.
    WAIT 3000
    PRINT_HELP 0@(-1@,8s)  // Respect can be earned be passing certain missions, killing rival gangs members, gaining territory and tagging.

Here we can happily create an array of GXT entry strings and  
print each one easily. We could also use a positive var index  
in order to iterate through what is essentially a real array  
of strings:
    05AA: 0@(0@,8s) = 'SWEET_1'
    05AA: 0@(-1@,8s) = 'SWEET1B'
    05AA: 0@(-2@,8s) = 'SWEET_2'
    05AA: 0@(-3@,8s) = 'SWEET_3'
    05AA: 0@(-4@,8s) = 'SWEET_4'
    05AA: 0@(-5@,8s) = 'SWEET_5'
    05AA: 0@(-6@,8s) = 'SWEET_6'
    05AA: 0@(-7@,8s) = 'SWEET_7'

    FOR 1@ = 0 TO 7
        NOT COMPARE_STRING_LS8 0@(1@,8s) 'SWEET_5'
    PRINT_HELP 0@(1@,8s)  // Sweet's Girl

  Demo Scripts  

I've provided a few demo scripts to help scripters understand  
how to take advantage of SuperVars in their own scripts.

These scripts can be found in the "examples" folder.

   Very Basic Usage
     A very newbie-friendly guide to using SuperVars.
   Save System
     An intermediate guide to creating a save feature for      
     scripts using SuperVars. The demo takes the form of a    
     rampage feature with a high score system and also shows  
     methods of accessing game memory using SuperVars.
     This demo requires IntOperations.cleo, a plugin included  
     included with CLEO 4.

All demo scripts are currently written in                      
'SCR for Sanny Builder'. This is a collection of files which  
improve the quality of the scripting language in Sanny Builder.

These files can be generated via the Opcode Database:

You want to systematically select each "File" option and click
"Download" after making sure these other options are applied:

   Update File
     If you still want to use your current language from time
     to time, you should input your current sascm.ini file.
     Make sure you use Sanny Builders {$VERSION} directive to
     differentiate between versions of the scripting language.
     INI Version: SCR (v2)
   Optional Libraries
     Check all that apply

Save the files to your "Sanny Builder 3datasa" directory,  
replacing the originals.