-
Notifications
You must be signed in to change notification settings - Fork 0
/
puzzle_init.z80
255 lines (224 loc) · 8.33 KB
/
puzzle_init.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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
render_puzzle_tiles:
IF DEBUG_DIRTY_FLASH
call reset_dirty_flasher
ENDIF
call init_remaining_tiles_region
ld a, REMAINING_REDRAW_ALL_FORCE
ld (redraw_remaining_tiles_flags), a
; memset remaining tiles to zero (we count
; them shortly))
ld bc, 0
ld (remaining_tiles), bc
ld (remaining_tiles+2), bc
ld (remaining_tiles+4), bc
ld (remaining_tiles+6), bc
ld (remaining_tiles_last_time), bc
ld (remaining_tiles_last_time+2), bc
ld (remaining_tiles_last_time+4), bc
ld (remaining_tiles_last_time+6), bc
xor a
ld (tiles_drawn_last_time), a
; now draw the play area (AND count the 'remaining
; tiles' at the same time)
ld hl, tiles ; where the tile data is
ld bc, 10*256+12 ; count 12 rows and 10 columns
ld de, GRID_X_OFFSET ; this is 12*0+0+32 i.e. x=0 and y=0
@next_col:
ld a, (hl)
; increment count of tiles..
cp NUM_NON_TILES
jr c, @+done_update_count
push hl
ld hl, remaining_tiles
sub NUM_NON_TILES+1
add l
ld l, a
inc (hl)
pop hl
ld a, (hl)
@done_update_count:
push bc ; TODO OPTIMIZE THIS AWAY
push hl
call draw_tile_at_de_tile_a
pop hl
res 7, e ; because, draw_tile_at_de_tile_a ends with DE one pixel row below above start pixel
inc d
pop bc ; TODO OPTIMIZE THIS AWAY
ld a, e
add 8 ; 16 pixels to the right
ld e, a
inc hl
djnz @-next_col
; now, skip the next 6 bytes of hl for the next row
inc hl
inc hl
inc hl
inc hl
inc hl
inc hl
ld b, 10 ; reset column counters for next row
ld e, GRID_X_OFFSET ; column zero
ld a, d ; next row on screen (128*16 pixels = 256*8 bytes)
add 8 ; ...
ld d, a ; ...
dec c
jr nz, @-next_col
call render_remaining_tiles
ret
memcpy_level_data:
; first, page in the puzzle data into LMPR
; (make a backup of the old lmpr - use stack)
in a, (LMPR)
push af
ld a, 3+32
out (LMPR), a
; compute level index (from level:major:minor)
; each level_number from i=0..7 contributes i sets of 4 problems
; within which, major points to a set of 4 problems, and minor points to a level within that set of 4 problems
ld a, (level_number)
ld b, a ; do the summation this many times (which might be zero!)
inc b
ld a, 0
ld c, 0 ; the adder (which goes up by 4 each iteration - add 4, then add 8, then add 12, ...)
@keep_counting:
dec b
jr z, @_done_counting
inc c
inc c
inc c
inc c
add a, c
jp @-keep_counting
@_done_counting:
; now add (major * 4) + minor to this:
ld b, a
ld a, (level_problem_major_number)
add a, a
add a, a ; multiply by 4
add b
ld b, a
ld a, (level_problem_minor_number)
add b
; on entry, a = which level
; LEVEL DATA IS EXACTLY 128 BYTES
ASSERT PUZZLEDATA_START==0
ld l, 0
and a
rra
rr l
ld h, a
; To save space, the levels are (slightly) compressed
; Our grid in game state is 16x12 but our level data is just 10x12
; so just copy 10 bytes, 12 times
ld de, tiles
ld a, 12 ; count number of rows
@next:
ld bc, 10
LDIR
inc de; align to destination buffer
inc de
inc de
inc de
inc de
inc de
dec a
jr nz, @-next
; finally copy the remaining pieces
ld bc, puzzle_copy_len - 16*12
ldir
; finally page out the LMPR (revert to what it was before)
pop af ; lmpr backup
out (LMPR), a
ret
init_level_tileset:
; we can probably have some level-specific tiles.
; for now that's just the background brick
; (which is not stored as part of the level data, but depends on
; the level number instead)
xor a
ld l, a
ld a, (level_number)
rra
rr l
add a, bricks_bitmaps/256
ld h, a
ld de, tiles_bitmaps+3*128
ld bc, 128
ldir
; dunno where to put this, but set border color also:
ld a, (level_number)
ld hl, border_colors
ld e, a
ld d, 0
add hl, de
ld a, (hl)
out (BORDER),a
ret
border_colors:
defb %00100111, %00100100, %00100000, %00000100, %00000111, %00100011, %00100101, %00000101
init_game_state:
; call after doing memcpy_level_data
; basically a memclear but also a few other things
ld hl, game_state_zero_start
xor a
ld (hl), a
ld de, game_state_zero_start + 1
ld bc, game_state_zero_end - game_state_zero_start - 1
LDIR
; memclr tiles_flags
ld hl, tiles_flags
xor a
ld (hl), a
ld de, tiles_flags+1
ld bc, 16*12-1
LDIR
call init_cursor_controller
call init_slider_stack
; initialize slider wait state
ld a, (slider_wait_init)
ld (slider_wait_frame), a
ret
render_screen_layout:
ld a, 0x66 ; RED
call clear_screen
ld de, PLAYER_Y_OFFSET*128
ld hl, strings.PLAYER
ld c, 0x11 ; WHITE
call print_text_hl_de
ld de, TIME_LABEL_Y_OFFSET*128
ld hl, strings.TIME
call print_text_hl_de
; FIXME TODO - this should render the fatnum ' and " symbols (not using print text)
ld de, CLOCK_Y_OFFSET*128
ld hl, strings.CLOCK
call print_text_hl_de
;
ld a, (level_number)
add 49; '1' ascii
ld (strings.LEVEL + 6), a
ld c, 0x11 ; WHITE
ld de, LEVEL_Y_OFFSET*128
ld hl, strings.LEVEL
call print_text_hl_de
ld a, (level_problem_major_number)
add 49; '1' ascii
ld (strings.PROBLEM + 1), a
ld a, (level_problem_minor_number)
add 49; '1' ascii
ld (strings.PROBLEM + 3), a
ld c, 0x11 ; WHITE
ld de, 0+((LEVEL_Y_OFFSET+8)*128)+(LEVEL_X_OFFSET/2)
ld hl, strings.PROBLEM
call print_text_hl_de
call init_draw_retry
ret
strings.PLAYER: defm "PLAYER-1"
defb 0
strings.LEVEL: defm "LEVEL X"
defb 0
strings.PROBLEM: defm "(X-X)"
defb 0
strings.TIME: defm "TIME"
defb 0
; render xx'yyzz" (double-spaced for fatnums)
strings.CLOCK: defb 32,32, 39, 32,32, 32,32, 34, 0