9. Creating Sprite Group for Animation

(© Richard Ashbery)

Contents

Introduction

For some years now I've been experimenting with BASIC to create simple graphic animations and needed a method to produce GIF images to be uploaded to a website.

Many many years ago (1988 to be precise) Acorn Computers Ltd. published the BBC BASIC GUIDE. This has been updated and re-issued by RISC OS Open Ltd in 2017. The original guide illustrated a method using a VDU command to create a group of sprites from an animated shape. Although simple to understand it required quite a few operations in order to create the sprites.

An improved method which communicates directly with the operating system through an SWI command SYS "OS_SpriteOp" is more powerful and flexible and should be used instead. The following tutorial describes the 2 methods with a simple animated rotating square (figure 1).

Please note: Tutorial only covers creation of a sprite group. A GIF suitable for web pages can be built with InterGif but the process it is not covered in this tutorial.

Fig 1 Rotating Square

Method 1

Examine the program below...


MODE 1920,1080,32 : OFF

ORIGIN 1920,1080

n=0

REM Set up rotation variable for square

FOR m=0 TO 2*PI-PI/12 STEP PI/12

GCOL 3,63 : PROCdraw_square

z=INKEY(10)

REM Generate sprite group for animation

MOVE-200,-200

MOVE 200,200

VDU 23,27,1,n|

n+=1

REM Erase previous square after a delay

GCOL 3,63 : PROCdraw_square

NEXT m

END

DEF PROCdraw_square

FOR T = 0 TO 2*PI STEP PI/2

X=SIN(T+m)*200

Y=COS(T+m)*200

IF T=0 THEN MOVE X,Y ELSE DRAW X,Y

NEXT T

ENDPROC


The highlighted section in red performs the sprite group saving routine. The rotation of the square is controlled by a FOR-NEXT statement with the code inserted in the body of the program such that 'n' would be advanced a step at a time. For each rotation (n=n+1) a sprite is created. To generate the sprite group...

There are some quite serious limitations:

Important Note: Above method deprecated in favour of the following...

Method 2

The recommended technique of creating an animated sprite is to use SYS "OS_SpriteOp". It appears more complicated but is much more flexible and fully automated. No additional commands need typing into a TaskWindow and no dragging of the Next slot in Tasks is required.

The basic form of the SWI command is shown in table below...

Function SWI command
Initialise sprite SYS "OS_SpriteOp", &009,,
Create sprite group SYS "OS_SpriteOp", &00E,, STR$(n) Note 2
Save sprite to current working dir. Note 1 SYS "OS_SpriteOp", &00C,, "MyFileName"

Important: These basic SpriteOp codes use the 'System Sprites' memory which is
limited to 16MB.

User Sprite Area

The program below uses a 'User Sprite Area' instead of the 'System Sprites' memory. This is important as it enables the user to set sprite area memory much greater than 16MB. By simply adding &100 to the Reason code in all three SWI commands enables this action to be performed.

Function SWI command
Initialise sprite SYS "OS_SpriteOp", &109,sprite_area%
Create sprite group SYS "OS_SpriteOp", &10E,sprite_area%, STR$(n) Note 2
Save sprite to CWD Note 1 SYS "OS_SpriteOp", &10C,sprite_area%, "MyFilename"

Setting the Sprite_area% Parameters

These statements are coloured green in the program. Sandwitched between them are 2 lines (highlighted in black) that automatically set the amount of memory required for the sprite processing in the Next slot in the Task Manager.

  1. Set the required memory required for the sprite (4MB)
  2. Convert memory size to bytes (4*1024*1024)
  3. See Line 3
  4. See Line 4
  5. Allocate the required number of bytes in memory (sprite_area_size% - 1)
  6. Put the size of the area into first word (sprite_area%!0 = sprite_area_size%)
  7. The third word must be 16 on initialisation (sprite_area%!8 = 16)

Automate the Next slot (Lines 3 and 4)

Without these 2 lines creating the required animated sprite would require additional memory that would normally be assigned by dragging the Next slot to give a value greater than sprite_area_size%. With the example shown where sprite_area_size% = 4000K then to be on the safe side Next slot should be dragged to say 5000K. By including another 2 lines this process can be done automatically.

Line 3 (calculate the memory shortfall)

shortfall% = (sprite_area_size% + &19000) - (HIMEM - END)

The variable, shortfall% calculates how much extra memory is needed. BASIC requires about 100Kbytes (&19000) free to work in so this is added to sprite_area_size%.

sprite_area_size% + 102K = 4194K+102K = 4296K

Memory currently free in BASIC = HIMEM-END = 4255Kbytes

shortfall% = (sprite_area_size% + 102K) - (HIMEM - END) = 4296-4255K = 41K

Line 4 (calculate HIMEM+shortfall creating the equivalent of dragging Next slot)

IF shortfall% > 0 THEN END = HIMEM + shortfall%

With HIMEM at 4292K...

HIMEM + shortfall% = 4292+41 = 4333. This figure is then used to set the program's slot in the Task Manager using the BASIC keyword... END.


sprite_area_size% = 4

sprite_area_size% = sprite_area_size% * 1024 * 1024

shortfall% = (sprite_area_size% + &19000) - (HIMEM - END)

IF shortfall% > 0 THEN END = HIMEM + shortfall%

DIM sprite_area% (sprite_area_size% - 1)

sprite_area%!0 = sprite_area_size%

sprite_area%!8 = 16

SYS "OS_SpriteOp", &109, sprite_area% : REM start initialisation

MODE 1920,1080,32 : OFF

ORIGIN 1920,1080

n=0

REM Set up rotation variable for square

FOR m=0 TO 2*PI-PI/12 STEP PI/12

GCOL 3,63 : PROCdraw_square

z=INKEY(10)

REM Generate sprite group for animation

MOVE-200,-200

MOVE 200,200

SYS "OS_SpriteOp", &10E, sprite_area%, STR$(n) : REM Create sprite group

n+=1

REM Erase previous square after a delay

GCOL 3,63 : PROCdraw_square

NEXT m

SYS "OS_SpriteOp", &10C, sprite_area%, "MyFilename" : REM Save sprite group to disc

END

DEF PROCdraw_square

FOR T = 0 TO 2*PI STEP PI/2

X=SIN(T+m)*200

Y=COS(T+m)*200

IF T=0 THEN MOVE X,Y ELSE DRAW X,Y

NEXT T

ENDPROC


Notes

1. Current working directory = CWD. If the sprite requires saving to a specified directory then a full path to the directory must be given.

2. The STR$ keyword changes sprite group names to a string rather than just a numerical value.

Acknowledgement

A big thanks to Steve Fryatt for submitting various mini-tutorials describing how to implement these BASIC procedures. I hope I've understood the mechanics correctly. A steep learning curve but a very useful exercise and because program is fully automated makes process of creating animated sprites considerably easier.

©Richard Ashbery (18/4/20)

Top of page