<< Home | About Forth | About TurboForth | Download | Language Reference | Resources | Tutorials | YouTube >>


9 Graphics Functions

TurboForth currently supports the following video modes:

Bitmap mode is not currently supported. It may be supported in the future in the form of a loadable library.

9.1 HCHAR and VCHAR

HCHAR and VCHAR mirror the TI BASIC commands HCHAR and VCHAR. They expect their arguments in the same order. The stack diagram for HCHAR and VCHAR is:

    HCHAR ( row column character repeat --)
    VCHAR ( row column character repeat --) 

Character is the ASCII code of the character to be displayed. Repeat is the number of times the character is to be repeated right-to-left (in the case of HCHAR, or top-to-bottom in the case of VCHAR) the screen. Unlike TI BASIC the repeat parameter is not optional.

Note that in TI BASIC both row and column numbers start at 1, however, in TurboForth they start at 0.

Example

    0 4 42 123 HCHAR

The above draws 123 asterisk characters (ASCII code 420) starting at row 0 and column 4. Note that when the screen edge is encountered the drawing continues from the left hand side of the screen on the line below.

    9 16 ASCII # 222 VCHAR 

The above draws 222 hash characters (the word ASCII is used to determine the ASCII code) beginning at row 9 and column 16. The drawing wraps top-to-bottom and left-to-right.

    : Diag 24 0 DO I I ASCII @ 1 HCHAR LOOP ; 

The above draws a diagonal line of @ characters.

9.2 Defining characters with DCHAR

The appearance of characters can be changed with the word DCHAR. The stack diagram for DCHAR is

    DCHAR ( address count ascii --)

As can be seen, DCHAR expects on the stack:

A single ASCII character requires 8 bytes (4 cells) of data to re-define it. Characters in 32 column mode are based on an 8x8 grid, as follows:

9.2.1 32 Column Mode

128  64  32  16  8   4   2   1 
                =$3C
                =$42
                =$A5
                =$81
                =$A5
                =$99
                =$42
                =$3C

To determine the graphic data for the above, simply treat each line as an 8 bit value, and add up the column values where a 1 (a dark cell) appears.

[Note: Characters in 40 and 80 column modes are based on an 6x8 grid:]

9.2.2 Redefining a Character

Once the graphic data has been determined, a character can be defined. There are number of ways to define a character, but the simplest method is with the word DATA.

9.2.3 Defining a Character Using Data

    1 GMODE
HEX : Face DATA 4 3C42 A581 A599 423C ASCII # DCHAR ; DECIMAL 0 0 ASCII # 200 HCHAR Face

The above defines a word called Face (DATA must be used inside a colon definition) which when invoked redefines ascii character 35 (the hash sign) to a face shape. HCHAR is then used to display 200 faces on the screen.

9.2.4 Alternative Method to Defining a Character

Alternatively, the word , (comma) can be used in conjunction with CREATE:

    1 GMODE
    HEX
    CREATE Face 3C42 , A581 , A599 , 423C ,
DECIMAL Face 4 ASCII # DCHAR

9.3 Setting colours with COLOR

In 32 column mode, each 8 ASCII characters are divided into 'sets'. Each set can have one foreground and one background colour assigned. Changing the colours of the set immediately changes the colours of the all characters in the set. The sets are defined as follows:

TurboForth
Set #
TI BASIC
Set #
ASCII Range
 
TurboForth
Set #
TI BASIC
Set #
ASCII Range
0
 
0
7
16
13
128
135
1
 
8
15
17
14
136
143
2
 
16
23
18
 
144
151
3
0
24
31
19
 
152
159
4
1
32
39
20
 
160
167
5
2
40
47
21
 
168
175
6
3
48
55
22
 
176
183
7
4
56
63
23
 
184
191
8
5
64
71
24
 
192
199
9
6
72
79
25
 
200
207
10
7
80
87
26
 
208
215
11
8
88
95
27
 
216
223
12
9
96
103
28
 
224
231
13
10
104
111
29
 
232
239
14
11
112
119
30
 
240
247
15
12
120
127
31
 
248
255

The stack signature for COLOR is as follows:

    COLOR ( set foreground background --)

The colour values are defined as follows:

Foreground /
Background colour value
Colour
0
Transparent
1
Black
2
Medium Green
3
Light Green
4
Dark Blue
5
Light Blue
6
Dark Red
7
Cyan
8
Medium Red
9
Light Red
10
Dark Yellow
11
Light Yellow
12
Dark Green
13
Magenta
14
Grey
15
White

Example:

    8 9 11 COLOR

The above sets the colours of characters 64 to 71 (set 8) to light red on light yellow. This can be demonstrated with:

    1 GMODE
    8 9 11 COLOR
    0 0 ASCII A 100 HCHAR  

9.4 Setting the screen colour with SCREEN

The screen border colour can be set with the word SCREEN:

    SCREEN ( colour --)

The colour values used are as per COLOR.

In addition, if any character sets (see COLOR, above) have the colour transparent defined as either their foreground or background colours, then the screen colour will 'show through' as appropriate.

 

9.5 Sprite Graphics

The graphics processor inside the TI-99/4A can display up to 32 sprites at a time. Sprites always appear above text or other graphics. In addition, the 32 sprites have priority over each other, with sprite 0 having the highest priority, and sprite 31 having the lowest priority. Higher priority sprites appear on top of lower priority sprites when they overlap. A limitation of the graphics processor is that only 4 sprites may be displayed on a scan line. The new F18A replacement graphics processor does not have this limitation. Also, sprites may not be used in 40 column text mode. Again, this restriction is removed with the F18A upgrade graphics processor.

9.5.1 Setting the Size of Sprites with MAGNIFY

Sprites can be 8 pixels by 8 pixels, or 16 pixels by 16 pixels. In addition, they can be double sized, whereby a single sprite pixel occupies two screen pixels. The word MAGNIFY is used to set the size of sprites:

The stack signature for MAGNIFY is:

    MAGNIFY ( n -- ) 

Meaning, it removes a single value from the top of the stack. Valid values for n are:

Value for n Description
0 8x8 pixel, non-magnified
1 8x8 pixel, double sized
2 16x16 pixel, non-magnified
3 16x16 pixel, double sized

Note that when using 16x16 sprites, the pattern code of the sprite should be evenly divisible by four. See SPRITE.

 

9.5.2 Defining Sprites with DCHAR

DCHAR can be used to define the shapes of sprites. If you are used to using Extended BASIC on the TI-99/4A you will be aware that sprites share the ASCII character set, meaning that to set the shape of sprites, you re-define characters in the ASCII character set. In TurboForth, sprites have their own 256 character set, independent of the ASCII character set. To assign shapes to sprite pattern set with DCHAR, simply start the pattern code from 256. For example:

    HEX
    : Face DATA 4 3C42 A581 A599 423C  101 DCHAR ;
    DECIMAL

The above word defines sprite character one (1) (not ASCII character two-hundred-and-fifty-seven (0x101) as a face shape. Note that in the above example, hexadecimal mode is on (meaning all numbers will be interpreted as hex numbers), therefore 257 is represented as 101.

 

9.5.3 Initialising Sprites with SPRITE

To display a sprite, it must first have some shape data assigned to it with DCHAR (see the section above) otherwise its shape data will be all 0's, and nothing will be seen. Once some shape data has been assigned, the sprite can be initialised with the word SPRITE.

The stack signature for SPRITE is as follows:

    SPRITE ( sprite y x pattern color -- )

Where:

Example:

Run the above code by typing Test and pressing ENTER. A single sprite, in the shape of a smiley face will be seen.

Here is another example, the code below produces the display shown on the right:

Run the example by typing Go and pressing ENTER.

9.5.4 Changing a Sprites' Location with SPRLOC

A sprite, once initialised, can be moved to a different position on the screen with the word SPRLOC. This is more economical (and faster) than using SPRITE, since only sprite number, row and column data have to be specified, pattern and colour data remain un-changed.

The stack signature for SPRLOC is as follows:

    SPRLOC ( sprite row column -- )

Having run the above 32 sprites example, let's change the location of sprite #5:

    5 100 10 SPRLOC

The above moves sprite #5 to row 100 and column 10.

 

9.5.5 Determining a Sprites' Location with SPRLOC?

Sometimes it will be necessary to determine the position of a sprite, to determine if it has collided with another sprite, for example. SPRLOC? can be used for this. When given a sprite number, SPRLOC? will return the row and column positions of the sprite:

    SPRLOC? ( sprite -- row column )

For example, to determine the position of sprite number 5, enter the following:

    5 SPRLOC?

TurboForth will respond with...

    ok:2

...indicating that 2 values have been pushed to the stack. The stack can be non-destructively inspected with the word .S:

    .S
    100 10 <--TOP ok:2 

Indicating that sprite 5 is at row 100 and column 10.

9.5.6 Changing a Sprites' Definition with SPRPAT

The pattern of a sprite can be changed with SPRPAT. SPRPAT can be used to produce sprite animation.

The stack signature for SPRPAT is:

SPRPAT ( sprite pattern -- )

Where pattern is the sprite pattern (from 0 255) to use. If 16x16 sprites is active (see MAGNIFY) then pattern number should be evenly divisible by 4.

Example

The above code places a sprite, with a face shape on the screen. The pattern can be changed to a hash shape with:

    0 1 SPRPAT 

Note, as per section 9.5.2 to define a sprites' character with DCHAR you add 256 to the ASCII code. The red values above are equivalent. The blue values above are also equivalent. Note that in the above code, hexadecimal mode is active, thus 256 decimal is represented as 100 hexadecimal, and 257 decimal is represented as 101 hexadecimal.

 

9.5.7 Changing a Sprites' Colour with SPRCOL

A sprites' colour can be changed with SPRCOL. 16 colours are available, as defined in COLOR.

The stack signature for SPRCOL is as follows:

    SPRCOL ( sprite color -- )

Example:

If the example code given in SPRPAT is used (see above), then the colour of the sprite can be changed to yellow with:

    0 11 SPRCOL

9.5.8 Setting Up Movement Vectors with SPRVEC (SMLIST in V1.0 & V1.1)

Sprites can be given a movement vector to follow. Having assigned a vector to a sprite, it will move (follow its vector) each time the word SPRMOV (see below) is executed.

The stack signature for SPRVEC is as follows:

    SPRVEC ( sprite r c -- )

Where sprite is the sprite number (0 to 31), y is the number of pixel rows to move on each call to SPRMOV and c is the number of pixel columns to move on each call to SPRMOV. The movement vector remains in force until another vector is applied to the sprite.

Positive values for r cause the sprite to move downwards on the screen. Negative values cause the sprite to move upwards.

Positive values for c cause the sprite to move rightwards on the screen. Negative values cause the sprite to move leftwards.

See SPRMOV below for an example.

9.5.9 Moving Sprites with SPRMOV

If a sprite has been given a vector (see SPRVEC above) then the sprite will move according to its vector when SPRMOV is executed.

The stack signature for SPRMOV is as follows:

    SPRMOV ( start_sprite# count -- )

The combination of a starting sprite number (start_sprite#) and a count allows sprites to be moved in groups if desired. For example, a large object could be built from multiple consequtive sprites and moved as a single object with a single call to SPRMOV.

As an example, the following would move sprites 4, 5 6 and 7 according to their vectors assigned via SPRVEC (see above):

    4 4 SPRMOV

Example:

The following example places four sprites on the screen. The red sprite (sprite 0) moves to the right by 1 pixel per call to SPRMOV. The white sprite (sprite 1) moves by 2 pixels to the right per call to SPRMOV. The blue sprite (sprite 2) moves by 3 pixels to the right per call to SPRMOV, and the yellow sprite (sprite 3) moves to the right by 4 pixels per call to SPRMOV.

<-- Back to Tutorials


<< Home | About Forth | About TurboForth | Download | Language Reference | Resources | Tutorials | YouTube >>