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_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
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.