The basic concept of tile maps are to take several generic texture sprites, all of equal size, and print them on the screen in order with respect to a set of data cataloging the arrangement.
Think of a person that puts down bathroom tiles. He (or she) has a set of multicolored tiles and some sort of drawing to show him (or her) the pattern that they need to be laid out. That person will pick and place the tiles on the floor according to the drawing they have. The same goes for calculator tile map routines.
Games like Joltima, DStar, and Journey use tile map
routines to display the different objects on the screen. Each level in the game
has it's own distinct data representing a pattern on the screen. The game also
contains a table of sprites (all of
equal length) that coorespond to a value that can be in the level data. Say for
example the value 4
when found in the level data could refer to an 8 by 8 sprite
of heart while a 5
refers to a diamond. The tile map routine will:
sprites: ;start of sprite data sprite_square: ;first sprite .db %00000000 .db %01111110 .db %01000010 .db %01000010 .db %01000010 .db %01000010 .db %01111110 .db %00000000 sprite_circle: ;second sprite .db %00011000 .db %00100100 .db %01000010 .db %01000010 .db %01000010 .db %00100100 .db %00011000 .db %00000000
The tile generator routine is designed to be fast. The level data has to suit the routine. Say you have a routine, just so it can be fast, start drawing at the bottom right of the screen moving left and up. Your data might also need to start with the first byte being the bottom right, the second byte being the next byte to the left, etc. The routine should not have to accommodate the data.
Here's an example of level data (starting at the top left and reading from left to right, like a book). Following the data is a simple user chart telling you what each value encountered in the level data looks like as a sprite. These values are going to coorespond to letters. Following that will be a graphical representation of the TI86 screen after the tile map has been drawn.
level_data: .db 0,1,0,0,2,0,0,0,0,3,0,0,0,0,0,0 .db 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 .db 0,0,0,0,1,0,0,3,0,2,0,2,0,0,0,0 .db 0,0,0,0,1,0,0,3,0,2,0,2,0,0,0,0 .db 0,0,0,0,1,0,0,3,0,2,0,2,0,0,0,0 .db 0,0,0,0,1,0,0,3,0,2,0,2,0,0,0,0 .db 0,0,0,0,1,0,0,3,0,2,0,2,0,0,0,0 .db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
Value | Letter |
0 | ' ' |
1 | 'a' |
2 | 'b' |
3 | 'c' |
a b c a a c b b a c b b a c b b a c b b a c b b aaaaaaaaaaaaaaaa |
If you ever start to build a game like Joltima, DStar, or Journey, you probably want to consider writting a quick C/C++ application to make the level data. Probably have it use bitmaps of the actual sprites that will be used. If you can't do it in C/C++, then try using QBASIC or batch files somehow. If you end up making tons of levels, you're going to get a headache trying to figure out all the data and what it looks like in your head; a quick application can be a life saver!
In the Code Tree section, you learn that before you start designing a routine, it is best to outline the routine the same way you would an essay for school. Here's the indention outline for the routine we are going to make.
draw 8 rows draw 16 columns draw sprite get value from level data find sprite for that value draw 8 rows of sprite get byte from sprite image data draw byte onto video memory increase video memory to next row increase sprite data by a byte loop drawing of sprite increase column and repeat increase row and repeat
There are only a few routines out there that print tile maps on the screen. One of the most notable comes from Assembly Coders Zenith. ACZ is one of the top programming groups around. They're routine DrawMap is one of the fastest tile map generators. It uses GridPutSprite by Dan Eble in the routine. When I started making this tutorial, I decided to make my own tile map engine. When it was done, I ran it against DrawMap and saw it was over 10% faster running about 5 times more per a second.
I've pasted my TileGen Routine here. You can download this along with many other Tile Engine routines that I've come across in the Download Section. Each line in the routine is represented by a number which corresponds to an explanation at the end of the routine. Follow each line and try to picture in your head what it is doing. The easiest way to do this is to print out the TileGen Code and then refer to the explanations.
- ↓;======================================
- ↓; tilegen by jimi (malcolmj1@juno.com)
- ↓; draws 16x8 tile map
- ↓;======================================
- ↓tilegen:
- ↓ ld ix,$fc00
- ↓ ld b,8
- ↓loop_row:
- ↓ push bc
- ↓columns:
- ↓ ld b,16
- ↓loop_columns:
- ↓ push hl
- ↓ ld l,(hl)
- ↓ ld h,0
- ↓ add hl,hl
- ↓ add hl,hl
- ↓ add hl,hl
- ↓
- ↓ ld de,tile0
- ↓ add hl,de
- ↓
- ↓draw_tile:
- ↓ ld de,$10
- ↓ ld c,b
- ↓ ld b,8
- ↓
- ↓ push ix
- ↓draw_tile_loop:
- ↓ ld a,(hl)
- ↓ ld (ix),a
- ↓ add ix,de
- ↓
- ↓ inc hl
- ↓
- ↓ djnz draw_tile_loop
- ↓ pop ix
- ↓
- ↓ ld b,c
- ↓ pop hl
- ↓
- ↓ inc hl
- ↓ inc ix
- ↓ djnz loop_columns
- ↓ ld de,$10*7
- ↓ add ix,de
- ↓ pop bc
- ↓ djnz loop_row
- ↓ ret
Line(s) | Explanation | Bytes | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
↑5 | TileGen is called in context as follows:
ld hl,tile_data ;pointer to start of tile data call tilegen ;run tile generator |
This routine can be modified. If you want to have the routine
draw the tile map to the graph screen so you can use a virtual
screen, just change line 6 to
ld ix,_plotSScreen
.
Let's say you want to have a status
bar at the bottom of the screen. Just change line
7 to ld b,7
and it will leave the bottom row empty.
You could also do the above change and move the start address
indicated by line 6 to start one row down
so you can have your status bar along the top. If you wanted
to have your status bar along the right, it gets a little
bit trickier. You need to edit lines 11 and
45 to account for not writing to the
right most column. Line 45 will have to
add 7 rows to go down another row and also over one column
since the previous time around it didn't make it to the right
most edge.
You can have multiple tile sets by adding a few lines
at the beginning to accomodate the routine so that
de
is loaded with the address of the desired
tile set to use. The routine would edit line
20 to write in that address instead of "tile0" with
the new address of the first tile in the new set.
ld (address of line 20+1),deMake sure to put a label above line 20 to so that you can reference it in the above code.