-
Notifications
You must be signed in to change notification settings - Fork 0
/
tilemap.z80
212 lines (204 loc) · 5.11 KB
/
tilemap.z80
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
;;######################
loadMap:
;;# loads a map and updates mapWidth and mapHeight
;;# input:
;;# - hl = pointer to map
;;# output:
;;# - mapWidth and mapHeight are set
;;######################
ld de, mapWidth
ldi
ldi
ld (mapPtr), hl
;;right now hl points to the map data
xor a
ld (numBuildings), a ; reset the number of buildings in the map
ld bc, 0 ; c = current column, b = current row
ld de, buildingArray ; where buildings are stored (HP, etc.)
readMapLoop:
push hl
ld a, (hl)
and $7F ; clear out bit 7
sub 2
cp 12 - 2 ; check if sprite is between tile_airport and tile_village2
call c, loadBuilding
pop hl
inc hl
inc c ; increase column
ld a, (mapWidth) ; check if column = map width
cp c ; if not, loop back
jr nz, readMapLoop ; otherwise, continue to next row
ld c, 0
inc b ; increase row
ld a, (mapHeight) ; check if row = mapHeight
cp b
jr nz, readMapLoop
ret
loadBuilding:
ld hl, numBuildings
inc (hl) ; add one to numBuildings
ex de, hl ; put buildingArray into hl for easier use
ld (hl), c ; save x (current column)
inc hl
ld (hl), b ; save y (current row)
inc hl
ld (hl), 20 ; save building's HP
cp 6
jr nz, +_ ; jr nz, $ + 4
ld (hl), 10 ; 10 if it's a village
_:
inc hl
ex de, hl
;blablabla
ret
;;######################
drawTilemap:
;;# draws a tilemap to the graph buffer
;;# inputs:
;;# - none, just make sure map variables are set
;;######################
;; first we need to load the pointer to the tilemap
ld hl, neutralCtr ;
inc (hl)
ld hl, (mapPtr) ; skip width/height
ld de, (mapY) ; e = mapY, d = mapWidth
ld b, d ; b = mapWidth
ld d, 0
_:
add hl, de
djnz -_ ; djnz $ - 1
ld a, (mapX)
ld e, a
add hl, de
; now we load the screen info. for 8x8 sprites, b = 12 (12 columns), c = 8 (8 rows)
ld bc, $0C08
drawRow_loop:
push bc
push hl
ld a, (hl)
bit 7, a
jr z, +_
and %0111111
ld hl, neutralCtr
bit 0, (hl)
jr z, ++_ ;jr z, $ + 3
xor a
_:
call drawTileA ;draw sprite
_:
pop hl
pop bc
inc hl
djnz drawRow_loop
ld a, (mapWidth)
sub 12
ld e, a ;14 = map width, later we will change this to allow maps with variable widths, 12 = number of tiles we've drawn
ld d, 0
add hl, de
ld b, 12 ;reset b to 12 because the next row will also have 12 columns
dec c
jr nz, drawRow_loop
ret
;;######################
drawTileA:
;;######################
ld l, a
ld h, 0
add hl, hl
add hl, hl
add hl, hl ;x8
ld de, tile_data
add hl, de
push hl
pop ix
;;calculate y coordinate: (8-c)*8
ld a, 8
sub c ; 8-c
ld l, a ; l holds the y coordinate
;;calculate x coordinate: (12-b)*8
ld a, 12
sub b ; a = x coordinate
;;######################
drawSprite:
;;# Draws an aligned sprite to the gbuf
;;# inputs:
;;# - a = x (tile position: 0-11)
;;# - l = y (tile position: 0-7)
;;# - ix = sprite
;;######################
call getGbufOffsetTile ; gets the gbuf offset in hl and prepares b/de for sprite loop
drawSprite_loop:
ld a, (ix) ; read sprite byte
ld (hl), a ; overwrite the value in gbuf with sprite byte
inc ix ; move to next byte in sprite
add hl, de ; move to next row in gbuf (de = 12)
djnz drawSprite_loop ; repeat b times (8)
ret
;;######################
drawSpriteXOR:
;;# XORs a tile-aligned sprite to the gbuf
;;# inputs:
;;# - a = x coord
;;# - l = y coord
;;# - ix = sprite
;;######################
call getGbufOffsetTile ; prepare hl, b, and de for sprite loop
drawSpriteXOR_loop:
ld a, (ix) ; sprite byte
xor (hl) ; xor that with value in gbuf
ld (hl), a ; store XOR'd sprite back to gbuf
inc ix ; next sprite byte
add hl, de ; next gbuf row
djnz drawSpriteXOR_loop ; repeat b times
ret
;;######################
getGbufOffsetTile:
;;# calculates the tile offset in the gbuf
;;#input:
;;# - a = x tile
;;# - l = y tile
;;# output:
;;# - hl = gbuf offset
;;# - b = 8
;;# - de = 12
;;######################
ld de, gbuf ; add x offset to gbuf
add a, e ; a will never be > 12
ld e, a ; .. so there's no risk of overflow
ld h, 0 ; clear MSB of hl
add hl, hl ; convert y tile row into gbuf row: tileY*spriteHeight*gbufWidth
add hl, hl ; .. multiply by 8 (spriteHeight)
add hl, hl ; x8 each tile is 8 pixels tall
ld c, l ; essentially ld bc,hl (instruction doesn't exist)
ld b, h
add hl, hl ; x2
add hl, bc ; x3
add hl, hl ; x6
add hl, hl ; x12 (gbufWidth)
add hl, de ; add to gbuf, hl now = correct offset in gbuf
ld de, 12 ; width of the graph buffer (96 pixels/8 = 12)
ld b, 8 ; each sprite has 8 rows
ret
;;######################
getGbufOffset:
;;# calculates the offset in the gbuf
;;#input:
;;# - a = x tile
;;# - l = y tile
;;# output:
;;# - hl = gbuf offset
;;# - b = 8
;;# - de = 12
;;######################
ld de, gbuf ; add x offset to gbuf
add a, e ; a will never be > 12
ld e, a ; .. so there's no risk of overflow
ld h, 0 ; clear MSB of hl
ld c, l ; essentially ld bc,hl (instruction doesn't exist)
ld b, h
add hl, hl ; x2
add hl, bc ; x3
add hl, hl ; x6
add hl, hl ; x12 (gbufWidth)
add hl, de ; add to gbuf, hl now = correct offset in gbuf
ret