-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpiecelib.asc
576 lines (534 loc) · 10.4 KB
/
piecelib.asc
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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
; MSX Block Puzzle game, released as entry for the MSXDev'20
; Created by David Heremans, aka turbor on mrc
;
; Check if the player is allowed to move the piece and handle the actions initiated by the player
;
shiftleftallowed
; out Z-flag indicates shift allowed {{{
ld hl,itemmask+1
ld bc,10*256+128
shiftleftallowed1:
ld a,(hl)
and c
ret nz
inc hl
inc hl
djnz shiftleftallowed1
xor a
ret ;}}}
shiftrightallowed
; out Z-flag indicates shift allowed {{{
ld hl,itemmask
ld bc,10*256+64
shiftrightallowed1:
ld a,(hl)
and c
ret nz
inc hl
inc hl
djnz shiftrightallowed1
xor a
ret ;}}}
shiftupallowed
; out Z-flag indicates shift allowed {{{
ld hl,itemmask
ld a,(hl)
inc hl
or (hl)
ret ;}}}
shiftdownallowed
; out Z-flag indicates shift allowed {{{
ld hl,itemmask+2*9
ld a,(hl)
inc hl
or (hl)
ret ;}}}
item_is_placable_on_board: ; in a=piecenumber, out Z-flag indicates if placing is possible
; {{{
call addressofpiece
; copy 5 words of mask to itemmask
inc hl
inc hl
inc hl
ld de,itemmask
ld bc,10
ldir
; clear mask lower lines
ld hl,0
ld (itemmask+10),hl
ld (itemmask+12),hl
ld (itemmask+14),hl
ld (itemmask+16),hl
ld (itemmask+18),hl
xor a
ld (ai_possible_x),a
item_is_placable_on_board1
; make backup of piece at top row
ld hl,itemmask
ld de,maskbackup
ld bc,20
ldir
xor a
ld (ai_possible_y),a
item_is_placable_on_board2
;debug show image of piece for a while
; ;call item_place_color
; ld a,7
; ld (piececolor),a
; call grid10x10_to_nametabel ; draw grid
; call item_to_nametabel ; draw item over grid
; call gridnametabel_to_vram
; ei
; halt
; halt
; halt
; halt
; halt
; halt
; halt
; halt
;
call item_place_allowed
ret z
call shiftdownallowed
jr nz,item_is_placable_on_board4
call shiftdown
ld hl,ai_possible_y
inc (hl)
jr item_is_placable_on_board2
; checked entire column so restore backup and shift right (if allowed)
item_is_placable_on_board4
ld hl,maskbackup
ld de,itemmask
ld bc,20
ldir
call shiftrightallowed
ret nz ;can not move to right anymore so entire playarea checked and no placing possible
call shiftright
ld hl,ai_possible_x
inc (hl)
jr item_is_placable_on_board1
; place itemmask over gridbitmap
item_place_allowed:
; out Z-flag indiactes if placing is allowed {{{
ld b,20
ld hl,itemmask
ld de,gridbitmap
item_place_allowed1:
ld a,(de)
and (hl)
ret nz
inc de
inc hl
djnz item_place_allowed1
or a
ret ;}}}
item_place_color:
ld a,1 ; {{{
ld (piececolor),a
call item_place_allowed
ret z
ld a,2
ld (piececolor),a
ret; }}}
item_to_nametabel:
ld ix,nametabel+32+1 ; row 1 column 1 {{{
ld de,(pieceoffset)
add ix,de
ld de,itemmask
ld b,10
item_to_nametabel1
ld a,(de)
inc de
ld l,a
ld a,(de)
inc de
ld h,a
or l
jr z,item_to_nametabel2
push ix
push de
push bc
call item_to_nametabel3
pop bc
pop de
pop ix
item_to_nametabel2:
ex de,hl
ld de,64
add ix,de
ex de,hl
djnz item_to_nametabel1
ret
; now use the bits in hl to set the correct chars in (ix+?)
item_to_nametabel3:
ld b,10
item_to_nametabel4:
add hl,hl
jr nc,item_to_nametabel18
ld a,(piececolor)
add a,a
add a,a
ld (ix+0),a
inc a
ld (ix+1),a
inc a
ld (ix+32),a
inc a
ld (ix+33),a
item_to_nametabel18
inc ix
inc ix
djnz item_to_nametabel4
ret ;}}}
shiftright: ;{{{
ld b,10
ld hl,itemmask
shiftright1:
ld e,(hl)
inc hl
ld d,(hl)
srl d
rr e
ld (hl),d
dec hl
ld (hl),e
inc hl
inc hl
djnz shiftright1
ret ;}}}
shiftleft: ;{{{
ld b,10
ld hl,itemmask
shiftleft1:
ld e,(hl)
inc hl
ld d,(hl)
ex de,hl
add hl,hl
ex de,hl
ld (hl),d
dec hl
ld (hl),e
inc hl
inc hl
djnz shiftleft1
ret ;}}}
shiftdown: ;{{{
ld de,itemmask+2*10-1
ld hl,itemmask+2*9-1
ld bc,10*2
lddr
ld hl,0
ld (itemmask),hl
ret ;}}}
shiftup: ;{{{
ld de,itemmask
ld hl,itemmask+2
ld bc,10*2
ldir
ld hl,0
ld (itemmask+2*9),hl
ret ;}}}
check_possible_gameover: ;for all pieceplayable[123] check if pieceplacable somehwere on board
call check_possible_gameover1 ; {{{
push af
call clear_itemmask
pop af
ret z
ld a,1
ld (gameover),a
ret ;}}}
check_possible_gameover1:
call clear_itemmask
ld a,(pieceplayable1)
cp 255
jr z,check_possible_gameover2
call item_is_placable_on_board
jr nz,check_possible_gameover2
xor a
ret
check_possible_gameover2:
ld a,(pieceplayable2)
cp 255
jr z,check_possible_gameover3
call item_is_placable_on_board
jr nz,check_possible_gameover3
xor a
ret
check_possible_gameover3:
ld a,(pieceplayable3)
cp 255
jr z,check_possible_gameover4
call item_is_placable_on_board
ret nz
xor a
ret
check_possible_gameover4:
; all 3 pieces checked and no placable one
ld a,1
or a
ret
; }}}
; out Z-flag if new items generated
check_new_pieces_needed:
; {{{
ld a,(pieceplayable1)
ld hl,(pieceplayable2)
and h
and l
cp 255
ret nz
call selectnewplayablepieces
call makepiecesharder
ld de,charanimationinit
call addroutine
call playablepieces_to_nametabel
xor a
ret ; ret z flag if new pieces are added
;jr select_next_piece
; }}}
determine_itemmaskoffset:
; {{{
; first get extra offset to center for current piece
ld hl,(pieceplayednowpnt)
inc hl
ld a,(hl)
neg
ld (itemmask_oldpiece_offsetrow),a
inc hl
ld a,(hl)
neg
ld (itemmask_oldpiece_offsetcol),a
ld b,10
ld hl,itemmask
determine_itemmaskoffset2:
ld a,(hl)
ld e,a
inc hl
ld d,(hl)
inc hl
or d
jr nz,determine_itemmaskoffset3
djnz determine_itemmaskoffset2
; empty mask so offset 0,0
xor a
ld (itemmaskrowoffset),a
ld (itemmaskcoloffset),a
ret
determine_itemmaskoffset3:
ld a,10
sub b
ld (itemmaskrowoffset),a
dec hl
dec hl
determine_itemmaskoffset4:
ld a,(hl)
or e
ld e,a
inc hl
ld a,(hl)
inc hl
or d
ld d,a
djnz determine_itemmaskoffset4
ld b,16
ex de,hl
determine_itemmaskoffset5:
add hl,hl
jr c,determine_itemmaskoffset6
djnz determine_itemmaskoffset5
determine_itemmaskoffset6:
ld a,16
sub b
ld (itemmaskcoloffset),a
ret
; }}}
select_next_piece:
call select_next_piece7
xor a
ld (pieceplacenextpiece),a ; we use this variable at the end to start the soundeffect so we can not clear at the beginning of the routine
ret
select_next_piece7:
; {{{
ld a,(emptyitemmask)
or a
jp z,select_next_piece5
; switching from one piece to another....
; otherwise already done by dropping
call determine_itemmaskoffset
select_next_piece5:
; store current version to reset view later
ld a,(pieceplayednow)
ld b,a
ld a,(pieceplayednowselected)
ld c,a
; now to next piece
select_next_piece0:
ld a,(pieceplayednowselected)
inc a
cp 3
jr c,select_next_piece2
xor a
select_next_piece2:
ld (pieceplayednowselected),a
ld d,0
ld e,a
ld hl,pieceplayable1
add hl,de
ld a,(hl)
cp 255
jr z,select_next_piece0 ;already used so up to next piece
ld a,e
cp c
ret z ; same as when we started so two pieces are no longer in use, so simply return.
ld a,(hl)
ld (pieceplayednow),a
push bc
call addressofpiece
pop bc
ld (pieceplayednowpnt),hl
; now first reset the previous to the correct color
; if not empty
ld a,b
inc a
jr z,select_next_piece3
ld a,c
push bc
call get_preview_nametabel
pop bc
ld hl,#3031
ld a,b
call activateplayablepiece
select_next_piece3:
; clear mask lower lines
ld hl,0
ld (itemmask+10),hl
ld (itemmask+12),hl
ld (itemmask+14),hl
ld (itemmask+16),hl
ld (itemmask+18),hl
ld a,(pieceplayednowselected)
call get_preview_nametabel
ld hl,#3030 ; 3032 ; use itemmask but make preview empty...
ld a,(pieceplayednow)
call activateplayablepiece
ld a,1
ld (emptyitemmask),a
ld a,(pieceplacenextpiece)
or a
jp nz,startsfx2 ; start sfx if user initiated the switch
ret
; }}}
drop_piece_in_grid:
;{{{
xor a
ld (pieceplaceingrid),a ; flag as performed
;return if itemmask is empty!
ld b,20
ld hl,itemmask
drop_piece_in_grid1:
or (hl)
inc hl
djnz drop_piece_in_grid1
or a
ret z
;return if not placable, to speed thins up we use the color
ld a,(piececolor)
cp 2
jr nz,drop_piece_in_grid7
call startsfx4
xor a ; make sure we return Z
ret
drop_piece_in_grid7:
; first OR both masks , do not clean itemask at same time!
ld b,20
ld hl,gridbitmap
ld de,itemmask
drop_piece_in_grid2:
ld a,(de)
or (hl)
ld (hl),a
inc hl
inc de
djnz drop_piece_in_grid2
; then determine offset for next piece and clear itemmask
call determine_itemmaskoffset
call clear_itemmask
; update our grid10x10 for display purposes
call gridbitmap_to_grid10x10
; now the score of this piece
ld hl,(pieceplayednowpnt)
ld a,(hl)
ld (blockscore+1+5),a
; then check if we have rows/cols that need disappearing
call calc_cols_to_remove
call calc_rows_to_remove
; calc_*_to_remove can not cleanup since it would hinder the next calc_*_to_remove
; so split this up and then clean from mask and grid10x10
call calc_cols_remove
call calc_rows_remove
call calc_remove_speed
;now start sfx for blockdrop or colrowsremove
ld a,(row2dispnumber)
ld e,a
ld a,(col2dispnumber)
or e
jr z,drop_piece_in_grid8
call startsfx5
jr drop_piece_in_grid9
drop_piece_in_grid8:
call startsfx3
drop_piece_in_grid9:
;now the score
ld a,(row2dispnumber)
ld e,a
ld a,(col2dispnumber)
add a,e
ld (blockscore+1+4),a
;for each line more then 2 we add extra blockscore
sub 2
jr nc,drop_piece_in_grid3
xor a
drop_piece_in_grid3
inc a
ld b,a
drop_piece_in_grid4
push bc
;then add blockscore to realscore
ld hl,realscore+5+1
ld de,blockscore+5+1
call bcdadddehl
pop bc
djnz drop_piece_in_grid4
; now mark piece as being used by writing 255 into it
ld hl,pieceplayable1
ld de,(pieceplayednowselected)
xor a
ld d,a
dec a
add hl,de
ld (hl),a
ld (pieceplayednow),a
ld a,e
call clear_piece_preview;
;now we start the correct lettersptrite animation
ld a,(row2dispnumber)
ld e,a
ld a,(col2dispnumber)
add a,e
sub 2
jr c,drop_piece_in_grid6
ld a,(encouragetext)
inc a
cp 7
jr c,drop_piece_in_grid5
xor a
drop_piece_in_grid5
ld (encouragetext),a
call spritestartanimation
drop_piece_in_grid6
ld a,1
or a ; make sure we return NZ
ret ;}}}
; vim:foldmethod=marker:ft=z8a:ts=16