ZalaXa 5 — Wide Tiles

In this tutorial I’d like to take a little step sideways, and look at something that might come in useful later, and which will pave the way to some fun stuff in part 6.

The btiles we looked at in part 4 were 16×16 pixel size. NIRVANA+ also supports 24×16 wide tiles, in a .wtile file format. Take a look at \tutorials\part5\tiles\monster.wtile in the ZX-Paintbrush graphical editor.

These are the same two monster tiles we animated in part 4, in wtile format instead of btile format, repeated four times each. We will come back to the reason for the repetitions in part 6!

In order to use these wide tiles, I’ve made a few small changes to the part 4 code. Defining the ENABLE_WIDE_SPRITE and ENABLE_WIDE_DRAW constants enables wide tiles in NIRVANA+.

40
41
42
43
; constants.asm
 
ENABLE_WIDE_SPRITE      equ true
ENABLE_WIDE_DRAW        equ true

The database has a new WTile table importing the new tiles. (I suppose it doesn’t look much like a table, but I tend to think of any data in a regular repeating format as a table—the curse of having been a database programmer for many years. In this particular case, each btile is always 48 bytes long, and a wtile is 72 bytes long, so files containing tiles are totally made up of tabular data!)

14
15
16
17
18
19
20
21
22
23
; database.asm
 
WTile proc
::WIDE_IMAGES:
;                                                           BTile         Best
;          FileName                                       Indices    Viewed As     Notes
Monster equ ($-WTile)/Sprites.BTileLen
import_bin "..\tiles\monster.wtile"                     ; 000-007        4 x 2     Preshifted monster
 
pend

You may notice that they’re in a separate table, and the WTile indices start again at 0, even though we’ve left the BTiles in the program. This is because NIRVANA+ treats them separately—in fact you can have 255 of each type of tile, and can even mix and match them.

Finally, I’ve tweaked the AnimateDemo routine to alternate the tile indices between 0 and 4. Technically-speaking, the xor opcodes do a boolean exlusive-or operation on numbers. xor %00000100 (or xor 4 in decimal) flips bit 2 of the a register, leaving the other bits unchanged. In this case, it comes to the same thing as repeatedly adding or subtracting 4 from a. Because of the cunning way our wtiles are laid out (in sets of powers of two), the effect is to select the first monster in each animation frame.

3
4
5
6
7
8
9
10
11
12
13
14
15
; sprites.asm
 
AnimateDemo             proc
 
                        ld a, (FRAMES)                  ; Read the LSB of the ROM frame counter (0.255)
                        and %00000111                   ; Take the lowest 3 bits (effectively FRAMES modulus 8),
                        ret nz                          ;   and return 7 out of every 8 frames.
 
                        ld a, (Sprites.AIndex)          ; For every 8th frame, read Sprite A's tile index,
                        xor %00000100                   ;   alternate between (0 => 4 => 0 => 4 => etc),
                        ld (Sprites.AIndex), a          ;   then save it back.
                        ret
pend

The end result looks just the same as part 4, but we have a new technique up our sleeves now!

In the next part, I’m going to make our sprite move around the screen—animation in space, as well as the animation in time we already have.

Leave a Reply

Your email address will not be published. Required fields are marked *