Wiki

Clone wiki

agtools / Tutorial 3c - Quantity with EMXSPR

Outline

ts3c.png

This example will demonstrate the use of EMXSPR, a highly optimised version of EMSPR which is best for bulk drawing of sprites, especially good for common sprites with animation or very large sprites with only a few animation frames.

The price is memory - EMXSPR costs more to store than the other formats. It also takes longer to 'cut' them from source material due to exra optimization passes.

Usage is otherwise exactly the same as for EMSPR.

Changes:

We're going to use a sinus pattern for drawing, so we'll pull in the standard 8192-entry, 32-bit sintable provided with AGT.

#include "tables/sintab32.h"

And we edit the asset container to load .emx:

        sprite_asset.load("ball.emx");

...and a bunch of variables we'll use to perform the sinus dance:

        s16 xphase_o = 0;
        s16 yphase_o = 485;
        s16 xphaseinc_o = 13;
        s16 yphaseinc_o = -21;
        s16 xphaseinc_i = -313;
        s16 yphaseinc_i = 281;

Once again we need to configure the drawing state machine for EMXSPR:

        AGT_BLiT_EMXSprInit();

And the rest is just a loop to call the AGT_BLiT_EMXSprDrawClipped() function instead of the EMSPr version, and to fetch & use coordinates derived from the sintable using the variables we declared earlier.

        // get the x,y offset for each sprite, scale down from 32bit to 8bit
        s32 x = sintab32[xphase_i & 8191] >> 24;
        s32 y = sintab32[yphase_i & 8191] >> 24;

        // draw each sprite, centred on 160,120
        AGT_BLiT_EMXSprDrawClipped
        (
            /*context=*/&drawcontext,
            /*asset=*/passet, 
            /*frame=*/sprite_frame,
            /*worldpos=*/160 + x, 120 + y
        );

        // advance through sincos table for each secondary x,y offset
        xphase_i += xphaseinc_i;
        yphase_i += yphaseinc_i;

The result is 40+ 15x15 sprites inside the vblank time, using C calls! Of course, we would get more sprites if we bypass the C calls and rearrange things directly in 68k - but optimization is not the point of this exercise. It is to show how the AGT pieces are fitting together. As mentioned earlier, AGT won't normally be drawing sprites this way. It has a faster path which we'll describe soon.

However there's clearly a problem with the background. The sprites are leaving trails - the background is being destroyed. This is because the playfield is a persistent buffer with anything written to it replacing its contents permanently. The playfield normally only gets 'fixed' at the edges when scrolling occurs, subject to the distance scrolled from frame to frame.

The next step will show how to properly combine sprites with backgrounds.

Updated