Introduction
This tutorial is intended to guide you, not make you advanced with the GPU. Its a starting point for beginner and intermediate users. The best way to get better at the GPU is to learn through trial and error, and experience. The more you try to code with the GPU, the more you will get familiar with it and the faster you will learn. Try not to give up right away, I know it can be hard at times but you'll eventually understand the syntax and how the GPU works.
Important Note - (Feb 2012)
I made this tutorial for the older GPU which only supported ZASM code at the time. Some sections may be deprecated.
If you would like to write the code in C, visit the following thread: Graphics Library Documentation
Table of Contents
The Basics- Data Types
- Comments
- Ending Statements
Important Things- Exiting the Frame
- Hardware Clearing
- Draw Color
- Background Color
- Screen Resolution
Primitive Shapes- Rectangles
- Circles
- Lines
- Custom Shapes (Polygons)
Text Objects- Writing Strings
- Writing Numbers
- Writing Long Strings
- Writing Formatted Strings
E2 Wirelink- Storing Numbers
- Storing Strings
Examples- Rotating RGB Circle
- Cursor
- Rainbow Swirl
The Basics
Data Types
When using variables, you need to specify which type it is. Here is a list of the most common data types you can use.
Code:
color
string
vec2f
vec3f
alloc
define
matrix
color will allow you to make a variable that holds a Red,Green,Blue,Alpha value
string will hold a piece of text
vec2f will make a vector with X and Y components
vec3f will make a vector with X, Y and Z components
alloc will declare a number variable
define will make a constant number that cannot be changed.
matrix will create a matrix for 3D Projections
Comments
You can make a comment any time in your code by typing two "//" slashes
Code:
// I am a comment, I will not be executed!!
Ending statements
You may notice the ";" symbol in my code. It isn't necessary to use it if you put everything on seperate lines. You use it to tell the GPU that you are done with that statement. I personally use it because its good practice, and languages like C# require it after every statement. If you decide to use it, then you will be able to put multiple things on one line.
Important Things
Exiting the Frame
This is VERY important and always needs to be used or else we will be doing an infinite loop which lags like crazy. It will stop rendering the screen when you call it. Always put dexit at the bottom, and declare variables UNDER it. All of the code that tells the GPU what to do will be ABOVE dexit;
Hardware Clearing
Automatically after every frame in the GPU, it wil clear the screen. To make it so anything you draw stays on screen and is not cleared put this at the top of your code.
Otherwise, if you just want to clear the screen (Make it black) then use:
Draw Color
The GPU will always need color. We call dcolor <name> to set the current color to draw. Always call dcolor before drawing and if you need another color then call it again with a different color variable.
Then below dcolor we put dexit and declare the variable "white".
Code:
dexit;
color white,255,255,255;
4 parameters here, color name,R,G,B;
You can choose any variable name, I just use the color name white, because it is easy to identify it in the code. You can also add an additional parameter at the end for Alpha.
Background Color
Here we set the background color of the GPU
Code:
dclrscr blue;
dexit;
color blue,0,255,255;

Screen resolution
It is important to know that the GPU's screen resolution is 512x512. This will come in handy when determining positions to draw at on the screen. When you develop more advanced things it is also important to know that you can change the GPU to use different coordinates.
The opcode "dcvxpipe <number>" will change the screens coordinates, here are the ones you can use:
This is optional, if you dont use this then the coordinates will be defaulted to 0..512
Code:
0 Direct mapping
X = X
Y = Y
1 Screen resolution mapping
X = 512 * (X / RSCREEN_WIDTH)
Y = 512 * (Y / RSCREEN_HEIGHT)
2 Coordinates in 0..1 range
X = 512 * X
Y = 512 * Y
3 Coordinates in -1..1 range
X = 256 + X * 256
Y = 256 + Y * 256
4 Coordinates in -256..256 range
X = X + 256
Y = Y + 256
Primitive Shapes
Rectangles
First we set a color. Lets use blue.
Next we use one of two opcodes, either "drect" or "drectwh". drect will accept two positions and draw a rectangle from the top left to the bottom right or you can use drectwh which draws a rectangle from one position to a specified width and height.
Both opcodes will use 2 parameters that are vectors such as "drect pos1,pos2;" or "drectwh pos,size;" it's up to you to decide which one to use, but for now I will use drectwh.
We will now tell the GPU to exit by declaring dexit.
Now, at the very bottom under dexit; we need to state the variables we will be using. Remember, always declare variables UNDER dexit.
Code:
color blue,0,0,255;
vec2f pos,0,0;
vec2f size,128,128;
We use "color" to declare a color with 4 parameters "name,R,G,B"
We use "vec2f" to declare a vector with 3 parameters "name,X,Y"
Our final code will now be:
Code:
dcolor blue;
drectwh pos,size;
dexit;
color blue,0,0,255;
vec2f pos,128,128;
vec2f size,256,256;
This will now draw a rectangle (Well more of a square, but with similar results. Try stretching out the size and play around with it)

Circles
Note: Lots of circles create FPS lag. To reduce the lag you can change the number of points on a circle by changing the appropriate register. The code below will make the circle have 16 points, this is optional.
Code:
mov #regCircleQuality,16;
First we set a draw color, lets try green this time.
Now we use the dcircle command. It takes 2 parameters "dcircle pos,radius". Pos is a vector and radius is a number.
The circle will have a size of 128. This is a hardcoded value, you can also refer to a variable which holds a value.
Okay so now we are done drawing, so we need to call dexit and declare our variables under it. The final code will be:
Code:
dcolor green;
dcircle pos,128;
dexit;
color green,0,255,0;
vec2f pos,256,256; // Center of the screen

Lines
Now lets draw a line
First we set our color, lets try red this time.
Now, there is a command we can use to set the thickness of the line which is "dsetwidth". Lets set our line thicker before we draw it.
Our line will now have a thickness of 32 units.
Now to draw the line we use the "dline" command. It will accept 2 parameters which are positions. It draws a line from the first position to the second.
Now we are done drawing, we call dexit and declare the variables we used under it. The final code is now:
Code:
dcolor red;
dsetwidth 32;
dline pos1,pos2;
dexit;
color red,255,0,0;
vec2f pos1,0,0; // Top left corner
vec2f pos2,512,512; // Bottom right corner
If done correctly this will draw a big red line going down the screen.

Custom Shapes (Polygons)
Note: You can only create convex shapes in order for this to work correctly.
Here we will draw a triangle. First we set the color.
Now we call the opcode "dvxdata_2f". It accepts two parameters which are Label name, and amount of points to draw.
Code:
dvxdata_2f Triangle,3;
Now we declare dexit and our variables.
Code:
dexit;
color green,0,255,0;
Triangle: db 256,128; db 64,384; db 448,384;
Triangle will be the name of the label that holds our points. We use something called "db" in the label to give it vector points to draw from.
Its kind of like "Connect-The-Dots", you give it vector points and it will connect them to draw a shape.
Earlier in the code when we said "dvxdata_2f Triangle,3", we are giving it the name and the number 3 represents how many "db" points we made. Since we made 3 db's, dvxdata_2f needs to have 3 as the second parameter.
Full Code:
Code:
dcolor green;
dvxdata_2f Triangle,3;
dexit;
color green,0,255,0;
Triangle: db 256,128; db 64,384; db 448,384;
You might be thinking, wow... It's just a triangle, big deal.

But here are some examples of the amazing things you can do with polygons.
Credit goes to my buddies Maso and OmicroN for making these two.


Text Objects
Writing Strings
First we set a color as usual.
Then we set the size of the text using "dsetsize"
We can also change the font using "dsetfont"
These fonts are available to use
0 - Lucida Console
1 - Courier New
2 - Trebuchet
3 - Arial
4 - Times New Roman
5 - Coolvetica
6 - Akbar
7 - csd
It will default to Lucida Console by default if you dont set a font. Lets use the Trebuchet font. It's number association is 2 so we will write
Then we call "dwrite". It accepts two parameters which are the position and the string.
Then we do our usual dexit and declare the variables we used under it. The final code will be:
Code:
dcolor white;
dsetsize 64;
dsetfont 2;
dwrite pos,text;
dexit;
color white,255,255,255;
vec2f pos,76,224;
string text,'I am a string';

Writing Numbers
Then we set the size of the text using "dsetsize"
Then we call "dwritei". It accepts two parameters which are the position and the number.
Then we do our usual dexit and declare the variables we used under it. The final code will be:
Code:
dcolor white;
dsetsize 128;
dwritei pos,1337;
dexit;
color white,255,255,255;
vec2f pos,100,192;
If we want to write the number held in a variable the code would be:
Code:
dcolor white;
dsetsize 128;
dwritei pos,#var;
dexit;
color white,255,255,255;
vec2f pos,100,192;
alloc var,1337;
The "#" symbol means we are referring to the data held in the variable.

Writing Long Strings
This is useful if you dont want to declare a bunch of strings, and just want to display a long block of text.
Here's a code example of how to do this.
Code:
dcolor white;
dsetsize 24;
dwrite pos,text;
dexit;
vec2f pos;
color white,255,255,255;
// Text is a label containing strings
text:
db 'But theres no sense crying',10;
db 'over every mistake.',10;
db 'You just keep on trying',10;
db 'till you run out of cake.',10;
db 'And the science gets done.',10;
db 'And you make a neat gun',10;
db 'for the people who are',10;
db 'still alive.',0;
Your probably wondering "What are those 10's for?". Well in ASCII code the 10 represents the newline character. It makes the strings go to the next line. You can look at an ASCII table for the keys and insert any character you want there. This is basically one long concatenated string. You NEED to end the db code with a 0, to terminate the string and stop writing.

Writing Formatted Strings
Here an example of how to write a concatenated/formatted string with a number. REMEMBER to use dwritefmt, not dwrite.
Code:
dcolor white;
dsetsize 40;
timer #time; // Assign the variable time to server curtime
dwritefmt pos,text;
dexit;
vec2f pos,120,236;
color white,255,255,255;
string text,'Time = %i'; // the %i means it will take an integer/number
alloc time;

E2 Wirelink
Probably the part you are all wanting to know is how to interact with a GPU using E2 and wirelink. GPU ports reside in the address range 63488 to 64511 which means we have 1024 indexes for data storage. There's actually a TON of other addresses you can use for storage, but this address range is empty and has a sufficient amount of space. If you need more memory, then you can optionally use the address range 32768 to 63487.
Note: If you are going to input values into the GPU whether it be X, Y, Z, coordinates or R, G, B colors, you have to input each seperate element of the variable.
GPU only accepts numbers into its memory.
Storing Numbers
In the E2, the code for storing number data looks like this:
Code:
@inputs GPU:wirelink
interval(1000)
GPU[63488] = curtime()
# Address 63488 now holds the curtime() timer value.
In the GPU, we can now use this data, lets try writing the number to the screen using this code.
Code:
dcolor white;
dsetsize 128;
dwritei pos,#63488;
dexit;
color white,255,255,255;
vec2f pos,0,0;
Remember, we need to use the "#" symbol to tell it that we want the data held in that address number. If done correctly, the number on the screen will gradually increment each second.

Storing Strings
The E2 code to store strings is:
Code:
@inputs GPU:wirelink
interval(1000)
GPU:writeString(63488,"LoL")
# Address 63488 now points to the string "LoL"
The GPU will store the string like this, so be careful not to overwrite any of the addresses which store the data of the string.
63488 = L
63489 = o
63490 = L
It actually stores them as bytes, but I am just showing them as chars in that example.
The GPU code for using the string will be:
Code:
dcolor white;
dsetsize 128;
dwrite pos,63488;
dexit;
color white,255,255,255;
vec2f pos,140,192
We dont use the "#" symbol here because we dont want the data in 63488, we want 63488 as a pointer to a null-terminated string.
Bookmarks