version 0.2: fire bullets, exploding enemies
[nemesis.git] / nemesis.z80
1         .include "asm86.h"
2         .include "ti86asm.inc"
3         .include "ti86abs.inc"
4         .org _asm_exec_ram
5         nop
6         jp  Start
7         .dw $0000
8         .dw Title
9 Title:  .db "Nemesis v0.1.718 by Shiar",0
10 Start:
11         jr init
12
13 just_fired      = $c0f9         ;byte
14 temp1           = $c100         ;word
15
16 ;-------------------- init ----------------------------------------------------
17
18 init:
19         call _runindicoff
20
21 ;-------------------- main menu -----------------------------------------------
22
23         jp play_game
24
25 ;-------------------- exit ----------------------------------------------------
26
27 exit_game:
28         ret
29
30 ;----------------------- game setup -------------------------------------------
31
32 play_game:
33         ld  hl,stored_data_start
34         ld  bc,variables_end-stored_data_start-1
35
36 ;---------------------- display setup ----------------------------------------
37
38 set_up_display:
39         call _clrLCD
40
41         ld  hl,in_game_text
42         ld  b,3
43 l11:    ld  a,(hl)
44         ld  (_curCol),a
45         inc hl
46         ld  a,(hl)
47         ld  (_curRow),a
48         inc hl
49         call _puts
50         djnz l11
51
52 in_game_text:
53         .db 16,0,"LIVES",0
54         .db 16,3,"LEVEL",0
55         .db 16,6,"SCORE",0
56
57 str_question:
58         .db "-----",0
59
60 ;------------------------------------------------------------------------------
61 ;-------------------------- game loop -----------------------------------------
62 ;------------------------------------------------------------------------------
63
64 game_main_loop:
65         ld  hl,timer            ;update time
66         inc (hl)
67
68 Clear_screen:
69         xor a
70         ld  hl,GRAPH_MEM+(16*12)
71         ld  b,a
72 clearloop:
73         ld  (hl),a
74         inc hl
75         ld  (hl),a
76         inc hl
77         ld  (hl),a
78         inc hl
79         djnz clearloop
80
81 check_exitkey:
82         ld  a,%00111111         ;<exit> pressed?
83         out (1),a
84         nop
85         nop
86         in  a,(1)
87         bit 6,a
88         jr  z,quit              ;yes: quit game
89
90 game_stuff:
91         call Level_event        ;insert enemies
92         call Handle_Ship        ;move you
93         call Fire_bullet        ;check for fire
94         call Handle_bullets
95         call Handle_enemies     ;move enemies
96         call Enemies_hit        ;check for collision with enemies
97
98         call Display_Screen     ;display all
99 ;       halt \ halt \ halt      ;delay
100         jr   game_main_loop     ;loop
101
102 quit:   ret
103
104 ;---------------------- display -----------------------------------------------
105
106 Display_Screen:
107         ld  a,64                ;Display Image
108         ld  hl,GRAPH_MEM+(16*12)
109         ld  de,$fc00
110 displayloop:
111         ld  bc,12
112         ldir
113         inc de
114         inc de
115         inc de
116         inc de
117         dec a
118         jr  nz,displayloop
119
120 ;       ld  hl,$1007            ;Display Score
121 ;       ld  (_curRow),hl
122 ;       ld  hl,(score)
123 ;       jp  _D_HL_DECI
124         ret
125
126 ;------------------------- handle ship ----------------------------------------
127
128 Handle_Ship:
129         ld  a,(your_status)
130 ;       bit 4,a
131 ;       jr  nz,you_not_normal
132         or  a
133         jr  z,ok
134 ;       dec a
135 ;       ld  (your_status),a
136 ;       ld  hl,(lives)
137 ;       ld  a,l
138 ;       or  h
139 ;       jr  nz,ok
140 ;       pop af
141 ;       ret
142
143 ok:
144         ld  a,%01111110
145         out (1),a
146         ld  hl,y
147         in  a,(1)
148         rra
149         ld  b,a
150
151         jr  c,no_down
152         ld  a,(hl)
153         inc a
154         cp  73                  ;y < 73
155         jr  z,no_down
156         ld  (hl),a
157 no_down:
158         dec hl
159         rr  b
160         jr  c,no_left
161         ld  a,(hl)
162         dec a
163         jr  z,no_left           ;x > 0
164         ld  (hl),a
165 no_left:
166         rr b   
167         jr  c,no_right
168         ld  a,(hl)
169         inc a
170         cp  89                  ;x < 89
171         jr  z,no_right
172         ld  (hl),a
173 no_right:
174         ld d,(hl)
175         inc hl
176         rr  b
177         jr  c,no_up
178         ld  a,(hl)
179         dec a
180         cp  15                  ;y > 15
181         jr  z,no_up
182         ld  (hl),a
183 no_up:  ld  ix,spr_ship
184
185 display_common:
186         ld  e,(hl)
187         jp  drw_spr
188
189 ;you_not_normal:
190 ;       ld       hl,(score)
191 ;       ld       de,-6
192 ;       add      hl,de
193 ;       ld       a,255
194 ;       cp       h
195 ;       jr       nz,_ok_
196 ;       ld       hl,0
197 ;_ok_:  ld       (score),hl
198 ;       ld       a,(your_status)
199 ;       dec      a
200 ;       ld       (your_status),a
201 ;       inc      a
202 ;       and      14
203 ;       xor      14
204 ;       ld       hl,x-1
205
206 explosion_stuff:
207         rra
208         add a,a
209         add a,a
210         add a,a
211         ld  c,a
212         ld  b,0
213         ld  ix,spr_explosion
214         add ix,bc
215         inc hl
216         ld  d,(hl)
217         inc hl
218         jr  display_common
219
220 ;------------------------- fire bullet ----------------------------------------
221
222 Fire_bullet:
223         ld  a,%00111111
224         out (1),a
225 ;       ld  a,(your_status)
226 ;       or  a
227 ;       ret nz
228         ld  hl,just_fired
229         nop
230         in  a,(1)
231         bit 4,a
232         jr  z,fire
233         ld  (hl),0              ;not fired
234         ret
235
236 fire:   ld  a,(hl)
237         or  a                   ;can't fire when 1
238         ret nz
239         ld  (hl),1              ;just fired
240
241         ld  hl,ybullets
242         ld  de,3
243         ld  b,10
244
245 find_ybullet:
246         ld  a,(hl)
247         or  a
248         jr  z,found_ybullet     ;0 = no bullet here
249         add hl,de
250         djnz find_ybullet       ;look next bullet
251         ret
252
253 found_ybullet:
254         ld  (hl),1              ;use bullet
255         inc hl
256         ld  a,(x)
257         add a,3
258         ld  (hl),a              ;set x
259         ld  a,(y)
260         add a,2
261         inc hl
262         ld  (hl),a              ;set y
263         ret
264
265 ;------------------------ handle bullets --------------------------------------
266
267 remove_bullet:
268         dec hl
269         ld  (hl),0              ;dump this bullet!
270         ret
271
272 Handle_bullets:
273         ld  hl,ybullets
274         ld  b,10
275 scan_your_bullets:
276         push bc
277         push hl
278         ld  (temp1),hl
279         ld  a,(hl)
280         inc hl
281         dec a
282         call z,bullet_type1
283         pop hl
284         pop bc
285         ld  de,3
286         add hl,de
287         djnz scan_your_bullets
288         ret
289
290 bullet_type1:
291         ld  a,(hl)              ;d = X
292         inc a                   ;move right
293         cp  $5a                 ;off screen?
294         jr  z,remove_bullet
295         inc a                   ;move right
296         cp  $5a                 ;off screen?
297         jr  z,remove_bullet
298         ld  (hl),a              ;save new pos.
299         ld  d,a
300         inc hl
301         ld  e,(hl)              ;e = Y
302         ld  ix,spr_bullet01
303         push de
304         call drw_spr            ;display bullet
305         pop de
306         ld  b,20
307         ld  hl,enemies
308
309 hit_enemies:                    ;Hits with normal enemies
310         push hl
311
312         ld  a,(hl)
313         dec a
314         jr  nz,nohit            ;no hit when enemy_occ <> 1
315
316         inc hl
317         inc hl
318         ld  a,(hl)              ;check x
319         sub d
320         add a,5
321         jp  m,nohit
322         cp  8
323         jr  nc,nohit
324
325         inc hl
326         ld  a,(hl)              ;check y
327         sub e
328         add a,5
329         jp  m,nohit
330         cp  10
331         jr  nc,nohit
332
333         xor a
334         push hl
335         ld  hl,(temp1)
336         ld  (hl),a              ;remove bullet
337         pop hl
338
339         dec hl
340         dec hl
341         ld  (hl),a              ;explosionFrame 0
342         dec hl
343         ld  (hl),2              ;set to explode
344
345         pop hl
346         ret
347
348 nohit:  pop hl
349         inc hl
350         inc hl
351         inc hl
352         inc hl
353         djnz hit_enemies        ;check next enemy
354         ret
355
356 ;--------------------------- level events -------------------------------------
357
358 Level_event:
359         ld  a,(nextevent)
360         dec a
361         ld  (nextevent),a
362         or  a
363         ret nz
364
365 do_event:
366         ld  hl,(curevent)
367         ld  de,enemies-4
368 chk_noenemy:
369         inc de
370         inc de
371         inc de
372         inc de
373         ld  a,(de)
374         or  a
375         jr  nz,chk_noenemy
376
377         ld  a,$01
378         ld  (de),a              ;occ
379         inc de
380
381         ld  a,(hl)
382         ld  (de),a              ;type
383         inc de
384
385         ld  a,$5a
386         ld  (de),a              ;x
387         inc de
388
389         inc hl
390         ld  a,(hl)
391         ld  (de),a              ;y
392
393         inc hl                  ;+0
394         ld  a,(hl)
395         cp  $ff
396         jp  z,Next_level
397         ld  (nextevent),a
398
399         inc hl
400         ld  (curevent),hl
401         ret
402
403 ;--------------------------- handle enemies -----------------------------------
404
405 Handle_enemies:
406         ld  hl,enemies
407         ld  b,20
408
409 handle_enemy:
410         push hl
411         push bc
412
413         ld  a,(hl)
414         dec a
415         jr  z,normal_enemy      ;occ "normal" 1
416         dec a
417         jr  z,exploding_enemy   ;occ "exploding" 2
418         jr  next_enemy          ;occ "no enemy" 0
419
420 normal_enemy:
421         inc hl
422         ld  c,(hl)              ;type
423         inc hl
424         ld  d,(hl)              ;x
425         inc hl
426         ld  e,(hl)              ;y
427
428         ld  a,d
429         or  a
430         jr  z,next_enemy
431         dec a
432         ld  d,a
433         jr  z,remove_enemy
434
435         ld  (hl),e
436         dec hl
437         ld  (hl),d
438         ld  ix,spr_enemy01
439         ld  b,$00
440         add ix,bc
441         call drw_spr
442         jr  next_enemy
443
444 remove_enemy:
445         dec hl
446         dec hl
447 enemy_gone:
448         dec hl
449         ld  (hl),$0000          ;bye bye enemy
450
451 next_enemy:
452         pop bc
453         pop hl
454         inc hl
455         inc hl
456         inc hl
457         inc hl
458         djnz handle_enemy
459         ret
460
461 exploding_enemy:
462         inc  hl
463         push hl
464         ld   a,(hl)
465         call explosion_stuff    ;display explosion
466         pop  hl
467
468         ld  a,(hl)
469         cp  15
470         jr  z,enemy_gone        ;remove when at last frame
471         inc a
472         ld  (hl),a              ;next frame
473         jr  next_enemy
474
475 ;--------------------------- check collision ----------------------------------
476
477 Enemies_hit:
478         ld  de,(x)              ;e = X, d = Y
479         ld  hl,enemies-4
480 check_next:
481         inc hl
482         inc hl
483         inc hl
484         inc hl
485
486         ld  a,(hl)
487         cp  $ff
488         ret z                   ;-1 = no more enemies
489         push hl
490         cp  1
491         jr  nz,nocrash          ;1 = enemy
492
493         inc hl
494         inc hl
495         ld  a,(hl)              ;check x match
496         sub e
497         add a,6
498         jp  m,nocrash
499         cp  12
500         jr  nc,nocrash
501
502         inc hl
503         ld  a,(hl)              ;check y match
504         sub d
505         add a,6
506         jp  m,nocrash
507         cp  12
508         jr  nc,nocrash
509
510         dec hl
511         dec hl
512         ld  (hl),0              ;explosionFrame 0
513         dec hl
514         ld  (hl),2              ;set to explode
515
516 nocrash:
517         pop hl
518         jr  check_next
519
520 ;--------------------------- next level ---------------------------------------
521
522 Next_level:
523         ld  hl,Leveldata+1
524         ld  (curevent),hl
525         ret
526
527 ;--------------------------- putsprite ----------------------------------------
528
529 offsets_table:
530         .db 128,64,32,16,8,4,2,1
531 drw_spr:
532         ld  a,d
533         and 7
534         ld  hl,offsets_table
535         ld  c,a
536         ld  b,0
537         add hl,bc
538         ld  a,(hl)
539         ld  (_smc1+1),a
540
541         ld  (_smc1+1),a
542         ld  hl,GRAPH_MEM
543         ld  a,e
544         add a,a
545         add a,e
546         add a,a
547         rl  b
548         add a,a
549         rl  b
550         srl d
551         srl d
552         srl d
553         add a,d
554         jr  nc,_n1
555         inc b
556 _n1:    ld  c,a
557         add hl,bc
558           
559         ld  d,(ix)
560         ld  b,(ix+1)
561 _oloop: push bc                 ;Save # of rows
562         push hl                 ;Save screen address
563         ld  b,d                 ;Load width
564         ld  c,(ix+2)            ;Load one line of image
565         inc ix
566 _smc1:  ld  a,1                 ;Load pixel mask
567 _iloop: sla c                   ;Test leftmost pixel
568         jr  nc,_noplot          ;See if a plot is needed
569         ld  e,a                 ;OR pixel with screen
570         or  (hl)
571         ld  (hl),a
572         ld  a,e
573 _noplot: rrca
574         jr  nc,_notedge         ;Test if edge of byte reached
575         inc hl                  ;Go to next byte
576 _notedge:djnz _iloop
577         pop hl                  ;Restore address
578         ld  bc,12               ;Go to next line
579         add hl,bc
580         pop bc                  ;Restore data
581         djnz _oloop
582         ret
583
584
585
586 _D_HL_DECI:
587          push     bc
588          ld       de,up_data+4
589          ld       b,5
590 ldhld:   call     UNPACK_HL
591          add      a,'0'
592          ld       (de),a
593          dec      de
594          djnz     ldhld
595          ld       hl,up_data
596          ld       b,4
597 lis:     ld       a,(hl)
598          cp       '0'
599          jr       nz,dis
600          ld       (hl),' '
601          inc      hl
602          djnz     lis
603 dis:     ld       hl,up_data
604          call     _puts
605          pop      bc
606          ret
607
608 up_data: .db      "PAD98",0
609
610
611
612 ;------------------------------- sprites --------------------------------------
613
614 spr_ship:
615         .db 7,7         ;your ship:
616         .db %01110000   ;  ███
617         .db %11100000   ; ███
618         .db %11111100   ; ██████
619         .db %11110010   ; ████  █
620         .db %11111100   ; ██████
621         .db %11100000   ; ███
622         .db %01110000   ;  ███
623
624 spr_bullet01:
625         .db 5,3         ;your bullets
626         .db %11110000   ; ████
627         .db %11111000   ; █████
628         .db %11110000   ; ████
629
630 spr_bullet02:
631         .db 3,3         ;enemy bullets
632         .db %01000000   ;  █
633         .db %11100000   ; ███
634         .db %01000000   ;  █
635
636 spr_enemy01:
637         .db 6,6         ;enemy type one
638         .db %00111100   ;   ████
639         .db %01110000   ;  ███
640         .db %11110000   ; ████
641         .db %11110000   ; ████
642         .db %01110000   ;  ███
643         .db %00111100   ;   ████
644 spr_enemy02:
645         .db 6,6         ;enemy type two
646         .db %01111100   ;  █████
647         .db %11110000   ; ████
648         .db %10111000   ; █ ███
649         .db %10111000   ; █ ███
650         .db %11110000   ; ████
651         .db %01111100   ;  █████
652 spr_enemy03:
653         .db 6,6         ;enemy type three
654         .db %00111000   ;   ███
655         .db %01111100   ;  █████
656         .db %11111000   ; █████
657         .db %11111000   ; █████
658         .db %01111100   ;  █████
659         .db %00111000   ;   ███
660
661 spr_explosion:                               
662         .db 8,6         ;1
663         .db %00000000
664         .db %00011100
665         .db %00111110
666         .db %01010110
667         .db %00111000
668         .db %00000000
669
670         .db 8,6         ;2
671         .db %00110000
672         .db %01001110
673         .db %10111110
674         .db %01001111
675         .db %00111000
676         .db %00011010
677
678         .db 8,6         ;3
679         .db %11110011
680         .db %01001110
681         .db %10110101
682         .db %01000101
683         .db %00111110
684         .db %11011010
685
686         .db 8,6         ;4
687         .db %11110010
688         .db %01001110
689         .db %10110101
690         .db %01000101
691         .db %00111110
692         .db %01011010
693
694         .db 8,6         ;5
695         .db %01000001
696         .db %00100110
697         .db %00010101
698         .db %01000100
699         .db %00010010
700         .db %10011010
701
702         .db 8,6         ;6
703         .db %01000100
704         .db %00100000
705         .db %00000001
706         .db %01000100
707         .db %00100010
708         .db %10001000
709
710         .db 8,6         ;7
711         .db %00001000
712         .db %11000010
713         .db %00000000
714         .db %00100000
715         .db %00000001
716         .db %00110000
717
718         .db 8,6         ;8
719         .db %00000100
720         .db %00000000
721         .db %01000000
722         .db %00000000
723         .db %00000001
724         .db %00100100
725
726 ;---------------------------- enemy types -------------------------------------
727
728 ;enemy01:       .db $01,$00,$00         ;$hits   $fire frequency
729 ;enemy02:       .db $02,$00,$00
730 ;enemy03:       .db $04,$00,$00
731
732 ;---------------------------- level data --------------------------------------
733
734 Leveldata:
735         .db $10,$00,$40         ;$time (ff=end)    $type    $y-pos
736         .db $10,$00,$30
737         .db $10,$00,$20
738         .db $40,$00,$10
739         .db $01,$00,$44
740         .db $15,$00,$31
741         .db $04,$00,$38
742         .db $05,$00,$40
743         .db $03,$00,$2f
744         .db $04,$00,$3a
745         .db $12,$00,$10
746         .db $10,$00,$18
747         .db $0e,$00,$20
748         .db $0c,$00,$28
749         .db $0a,$00,$30
750         .db $08,$00,$38
751         .db $06,$00,$40
752         .db $04,$00,$48
753         .db $2a,$00,$20
754         .db $ff,$ff,$ff
755
756 ;---------------------------- texts -------------------------------------------
757
758 title_message:
759          .db      "* * NEMESIS * *",0
760
761 ;---------------------------- save data ---------------------------------------
762
763 stored_data_start:
764
765 curevent        .dw Leveldata+1         ;next event
766 nextevent       .db (Leveldata)         ;time to next event
767 score           .dw $0000
768 lives           .dw $0003
769 level           .dw $0000
770 x               .db $16
771 y               .db $46
772 shield          .db $00
773 ybullets        .dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0       ;10 x (state,x,y)
774 ;ebuls          .dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
775 enemies         .dw $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000
776                 .dw $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000
777                 .dw $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000
778                 .dw $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000
779                 .dw $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000
780 ; 0011 2233 >>  0=occupation (0=no enemy 1=normal 2=exploding)
781 ;               1=frame/ship 2=x 3=y
782
783 timer           .dw $0000
784 your_status     .db $00
785                 .db $00
786 warped_status   .db $00
787
788 variables_end:
789
790 stored_data_end:
791
792
793         .end
794
795
796
797
798 ;NEMESIS'86 by Shiar
799
800
801 ;0.01.717 -- 17.VII.99 -- size 984
802 ;
803 ;       + movement of ship over whole screen
804 ;       + enemies moving from right to left, appearing right at specified times
805 ;
806 ; 0.1.718 -- 18.VII.99 -- size 907
807 ;
808 ;       * no crash when level restarts for the third time
809 ;       * exit-procedure updated, unnecessary stuff/keychecks removed
810 ;       * alot of unused code removed
811 ;       + different types of enemies (just look different)
812 ;       + collision detection!! enemy ships disappear when you hit them
813 ;
814 ; 0.2.718 -- 18.VII.99 -- size 1153
815 ;
816 ;       + ability to fire bullets (F1). Enemies disappear on impact
817 ;       * enemies explode instead of disappearing
818
819