.include "asm86.h" .include "ti86asm.inc" .include "ti86abs.inc" .org _asm_exec_ram nop jp Start .dw $0000 .dw Title Title: .db "Nemesis v0.3.719 by Shiar",0 Start: jr init just_fired = $c0f9 ;byte temp1 = $c100 ;word ;-------------------- init ---------------------------------------------------- init: call _runindicoff ;-------------------- main menu ----------------------------------------------- jp play_game ;-------------------- exit ---------------------------------------------------- exit_game: ret ;----------------------- game setup ------------------------------------------- play_game: ld hl,stored_data_start ld bc,variables_end-stored_data_start-1 ;---------------------- display setup ---------------------------------------- set_up_display: call _clrLCD ld hl,in_game_text ld b,3 l11: ld a,(hl) ld (_curCol),a inc hl ld a,(hl) ld (_curRow),a inc hl call _puts djnz l11 in_game_text: .db 16,0,"LIVES",0 .db 16,3,"LEVEL",0 .db 16,6,"SCORE",0 str_question: .db "-----",0 ;------------------------------------------------------------------------------ ;-------------------------- game loop ----------------------------------------- ;------------------------------------------------------------------------------ game_main_loop: ld hl,timer ;update time inc (hl) Clear_screen: xor a ld hl,GRAPH_MEM+(16*12) ld b,a ld a,(background) clearloop: ld (hl),a inc hl ld (hl),a inc hl ld (hl),a inc hl djnz clearloop check_exitkey: ld a,%00111111 ; pressed? out (1),a nop nop in a,(1) bit 6,a jr z,quit ;yes: quit game game_stuff: call Level_event ;insert enemies call Handle_Ship ;move you call Fire_bullet ;check for fire call Handle_bullets ;move bullets call Handle_enemies ;move enemies call Enemy_fires ;check for enemy fire call Enemy_bullets ;move bullets call Enemies_hit ;check for collision with enemies call Display_Screen ;display all halt \ halt \ halt ;delay jr game_main_loop ;loop quit: ret ;---------------------- display ----------------------------------------------- Display_Screen: ld a,64 ;Display Image ld hl,GRAPH_MEM+(16*12) ld de,$fc00 displayloop: ld bc,12 ldir inc de inc de inc de inc de dec a jr nz,displayloop ; ld hl,$1007 ;Display Score ; ld (_curRow),hl ; ld hl,(score) ; jp _D_HL_DECI ret ;------------------------- handle ship ---------------------------------------- Handle_Ship: ld a,(your_occ) or a jr z,ok ;0 = normal stat ; dec a ; ld (your_status),a ; ld hl,(lives) ; ld a,l ; or h ; jr nz,ok ; pop af ; ret ok: ld a,%01111110 out (1),a ld hl,y in a,(1) rra ld b,a jr c,no_down ld a,(hl) inc a cp 73 ;y < 73 jr z,no_down ld (hl),a no_down: dec hl rr b jr c,no_left ld a,(hl) dec a jr z,no_left ;x > 0 ld (hl),a no_left: rr b jr c,no_right ld a,(hl) inc a cp 89 ;x < 89 jr z,no_right ld (hl),a no_right: ld d,(hl) inc hl rr b jr c,no_up ld a,(hl) dec a cp 15 ;y > 15 jr z,no_up ld (hl),a no_up: ld ix,spr_ship display_common: ld e,(hl) jp drw_spr ;you_not_normal: ; ld a,(your_status) ; dec a ; ld (your_status),a ; inc a ; and 14 ; xor 14 ; ld hl,x-1 explosion_stuff: rra add a,a add a,a add a,a ld c,a ld b,0 ld ix,spr_explosion add ix,bc inc hl ld d,(hl) inc hl jr display_common damage_you: or %10101010 ld (background),a ret ;------------------------- fire bullet ---------------------------------------- Fire_bullet: ld a,%00111111 out (1),a ld a,(your_occ) or a ret nz ;return if not normal stat ld hl,just_fired in a,(1) bit 4,a jr z,fire ;fire pressed? ld (hl),0 ;not fired ret fire: ld a,(hl) or a ;can't fire when 1 ret nz ld (hl),1 ;just fired ld hl,ybullets ld de,3 ld b,10 find_ybullet: ld a,(hl) or a jr z,found_ybullet ;0 = no bullet here add hl,de djnz find_ybullet ;look next bullet ret found_ybullet: ld (hl),1 ;use bullet inc hl ld a,(x) add a,5 ld (hl),a ;set x ld a,(y) add a,2 inc hl ld (hl),a ;set y ret ;------------------------ handle bullets -------------------------------------- remove_bullet: dec hl ld (hl),0 ;dump this bullet! ret Handle_bullets: ld hl,ybullets ld b,10 scan_bullets: push bc push hl ld (temp1),hl ld a,(hl) inc hl dec a call z,bullet_type1 pop hl pop bc ld de,3 add hl,de djnz scan_bullets ret bullet_type1: ld a,(hl) ;d = X inc a ;move right cp $5a ;off screen? jr z,remove_bullet inc a ;move right cp $5a ;off screen? jr z,remove_bullet ld (hl),a ;save new pos. ld d,a inc hl ld e,(hl) ;e = Y ld ix,spr_bullet01 push de call drw_spr ;display bullet pop de ld b,20 ld hl,enemies hit_enemies: ;Hits with normal enemies push hl ld a,(hl) and %00000001 jr z,nohit ;no hit when enemy_occ <> 1 inc hl inc hl ld a,(hl) ;check x sub d add a,5 jp m,nohit cp 8 jr nc,nohit inc hl ld a,(hl) ;check y sub e add a,5 jp m,nohit cp 10 jr nc,nohit xor a push hl ld hl,(temp1) ld (hl),a ;remove bullet pop hl dec hl dec hl dec hl ld a,(hl) ;occ srl a srl a ;occ/4 = HP left jr nz,hpleft ld (hl),2 ;set to explode inc hl ld (hl),a ;explosionFrame 0 pop hl ret hpleft: dec a add a,a add a,a inc a ;HP*4+1 = occ 1 ld (hl),a ;save pop hl ret nohit: pop hl inc hl inc hl inc hl inc hl djnz hit_enemies ;check next enemy ret ;--------------------------- level events ------------------------------------- Level_event: ld a,(nextevent) dec a ld (nextevent),a or a ret nz do_event: ld hl,(curevent) ld de,enemies-4 chk_noenemy: inc de inc de inc de inc de ld a,(de) or a jr nz,chk_noenemy inc de ld a,(hl) ld (de),a ;type ld hl,enemy01 ld c,a ld b,0 add hl,bc add hl,bc add hl,bc ;hl = enemy specs dec de ld a,(hl) ;load hitpoints or 1 ;set type 1 (normal) enemy ld (de),a ;occ inc de inc de ld a,$5a ld (de),a ;x inc de ld hl,(curevent) inc hl ld a,(hl) ld (de),a ;y inc hl ;+0 ld a,(hl) cp $ff jp z,Next_level ld (nextevent),a inc hl ld (curevent),hl ret ;--------------------------- enemy fires -------------------------------------- Enemy_fires: ld a,r and %01111111 cp 19 ret p add a,a add a,a ld c,a ld b,0 ;bc = a*4 ld hl,enemies add hl,bc ;hl = enemy ld a,(hl) or a ret z ;return if no enemy dec a dec a ret z ;or exploding enemy inc hl inc hl ld c,(hl) ;enemy x-pos dec c dec c ;c = x-2 inc hl ld a,(hl) ;y-pos add a,5 ld e,a ;e = y+5 ld b,10 ld hl,ebullets find_ebullet: ld a,(hl) or a jr z,found_ebullet ;0 = not used inc hl inc hl inc hl djnz find_ebullet ;look next bullet ret found_ebullet: ld (hl),1 ;use bullet inc hl ld (hl),c ;set x-pos inc hl ld (hl),e ;set y-pos ret ;----------------------------- enemy bullets ---------------------------------- Enemy_bullets: ld hl,ebullets ld b,10 handle_bullet: push bc push hl ld a,(hl) or a jr nz,enemy_bullet next_bullet: pop hl pop bc inc hl inc hl inc hl djnz handle_bullet ret enemy_bullet: inc hl ld a,(hl) ;bullet x dec a jp m,remove_ebullet ;off screen? jr z,remove_ebullet ;" dec a ;move left ld (hl),a ld d,a ;d=x inc hl ld e,(hl) ;e=y ld ix,spr_bullet11 ;display enemy bullet call drw_spr ld a,(your_occ) or a jr nz,next_bullet ;0 = you're normal pop hl push hl inc hl ;check x ld a,(x) sub (hl) add a,6 jp m,next_bullet cp 9 jr nc,next_bullet inc hl ;check y ld a,(y) sub (hl) add a,6 jp m,next_bullet cp 9 jr nc,next_bullet call damage_you ;HIT!! remove_ebullet: dec hl dec hl ld (hl),0 ;bullet > unused jr next_bullet ;--------------------------- handle enemies ----------------------------------- Handle_enemies: ld hl,enemies ld b,20 handle_enemy: push bc push hl ld a,(hl) and %00000011 jr z,next_enemy ;occ "no enemy" 0 and %00000001 jr z,exploding_enemy ;occ "exploding" 2 normal_enemy: ;occ "normal" 1 inc hl ld a,(hl) ;type add a,a add a,a add a,a ld c,a ;type*8 = offset inc hl ld d,(hl) ;x inc hl ld e,(hl) ;y ld a,d or a jr z,next_enemy dec a ld d,a jr z,remove_enemy ld (hl),e dec hl ld (hl),d ld ix,spr_enemy01 ld b,$00 add ix,bc call drw_spr jr next_enemy remove_enemy: dec hl dec hl enemy_gone: dec hl ld (hl),$0000 ;bye bye enemy next_enemy: pop hl ld bc,$0004 add hl,bc pop bc djnz handle_enemy ret exploding_enemy: inc hl push hl ld a,(hl) call explosion_stuff ;display explosion pop hl ld a,(hl) cp 15 jr z,enemy_gone ;remove when at last frame inc a ld (hl),a ;next frame jr next_enemy ;--------------------------- check collision ---------------------------------- Enemies_hit: ld a,(your_occ) or a ret nz ld de,(x) ;e = X, d = Y ld hl,enemies-4 check_next: ld bc,$0004 add hl,bc ld a,(hl) cp $ff ret z ;-1 = no more enemies push hl cp 1 jr nz,nocrash ;1 = enemy inc hl inc hl ld a,(hl) ;check x match sub e add a,6 jp m,nocrash cp 12 jr nc,nocrash inc hl ld a,(hl) ;check y match sub d add a,6 jp m,nocrash cp 12 jr nc,nocrash dec hl dec hl ld (hl),0 ;explosionFrame 0 dec hl ld (hl),2 ;set to explode call damage_you nocrash: pop hl jr check_next ;--------------------------- next level --------------------------------------- Next_level: ld hl,Leveldata+1 ld (curevent),hl ret ;--------------------------- putsprite ---------------------------------------- offsets_table: .db 128,64,32,16,8,4,2,1 drw_spr: ld a,d and 7 ld hl,offsets_table ld c,a ld b,0 add hl,bc ld a,(hl) ld (_smc1+1),a ld (_smc1+1),a ld hl,GRAPH_MEM ld a,e add a,a add a,e add a,a rl b add a,a rl b srl d srl d srl d add a,d jr nc,_n1 inc b _n1: ld c,a add hl,bc ld d,(ix) ld b,(ix+1) _oloop: push bc ;Save # of rows push hl ;Save screen address ld b,d ;Load width ld c,(ix+2) ;Load one line of image inc ix _smc1: ld a,1 ;Load pixel mask _iloop: sla c ;Test leftmost pixel jr nc,_noplot ;See if a plot is needed ld e,a ;OR pixel with screen or (hl) ld (hl),a ld a,e _noplot: rrca jr nc,_notedge ;Test if edge of byte reached inc hl ;Go to next byte _notedge:djnz _iloop pop hl ;Restore address ld bc,12 ;Go to next line add hl,bc pop bc ;Restore data djnz _oloop ret _D_HL_DECI: push bc ld de,up_data+4 ld b,5 ldhld: call UNPACK_HL add a,'0' ld (de),a dec de djnz ldhld ld hl,up_data ld b,4 lis: ld a,(hl) cp '0' jr nz,dis ld (hl),' ' inc hl djnz lis dis: ld hl,up_data call _puts pop bc ret up_data: .db "PAD98",0 ;------------------------------- sprites -------------------------------------- spr_ship: .db 7,7 ;your ship: .db %01110000 ; ███ .db %11100000 ; ███ .db %11111100 ; ██████ .db %11110010 ; ████ █ .db %11111100 ; ██████ .db %11100000 ; ███ .db %01110000 ; ███ spr_bullet01: .db 5,3 ;your bullets .db %00110000 ; ░▒▓██ .db %11111000 ; ░▒▓█████ .db %00110000 ; ░▒▓██ spr_bullet02: .db 5,3 ;your bullets .db %11110000 ; ░▒▓████ .db %11111000 ; ░▒▓█████ .db %11110000 ; ░▒▓████ spr_bullet11: .db 3,3 ;enemy bullets .db %01000000 ; █▓▒░ .db %11100000 ; ███▓▒░ .db %01000000 ; █▓▒░ spr_enemy01: .db 6,6 ;enemy type one .db %00111100 ; ████ .db %01110000 ; ███ .db %11110000 ; ████ .db %11110000 ; ████ .db %01110000 ; ███ .db %00111100 ; ████ spr_enemy02: .db 6,6 ;enemy type two .db %01111100 ; █████ .db %11110000 ; ████ .db %10111000 ; █ ███ .db %10111000 ; █ ███ .db %11110000 ; ████ .db %01111100 ; █████ spr_enemy03: .db 6,6 ;enemy type three .db %00111000 ; ███ .db %01111100 ; █████ .db %11111000 ; █████ .db %11111000 ; █████ .db %01111100 ; █████ .db %00111000 ; ███ spr_enemy03: .db 6,6 ;enemy type three .db %00111000 ; ███ .db %01111100 ; ██ .db %11111000 ; █████ .db %11111000 ; █████ .db %01111100 ; █████ .db %00111000 ; ███ spr_explosion: .db 8,6 ;1 .db %00000000 .db %00011100 .db %00111110 .db %01010110 .db %00111000 .db %00000000 .db 8,6 ;2 .db %00110000 .db %01001110 .db %10111110 .db %01001111 .db %00111000 .db %00011010 .db 8,6 ;3 .db %11110011 .db %01001110 .db %10110101 .db %01000101 .db %00111110 .db %11011010 .db 8,6 ;4 .db %11110010 .db %01001110 .db %10110101 .db %01000101 .db %00111110 .db %01011010 .db 8,6 ;5 .db %01000001 .db %00100110 .db %00010101 .db %01000100 .db %00010010 .db %10011010 .db 8,6 ;6 .db %01000100 .db %00100000 .db %00000001 .db %01000100 .db %00100010 .db %10001000 .db 8,6 ;7 .db %00001000 .db %11000010 .db %00000000 .db %00100000 .db %00000001 .db %00110000 .db 8,6 ;8 .db %00000100 .db %00000000 .db %01000000 .db %00000000 .db %00000001 .db %00100100 ;---------------------------- enemy types ------------------------------------- enemy01: .db %00000000,$ff,$ff ;$hits $fire frequency enemy02: .db %00000100,$ff,$ff enemy03: .db %00001000,$ff,$ff ;---------------------------- level data -------------------------------------- Leveldata: .db $01,$01,$40 ;$time (ff=end) $type $y-pos .db $10,$00,$30 .db $10,$02,$20 .db $40,$01,$10 .db $01,$00,$44 .db $15,$01,$31 .db $04,$02,$38 .db $05,$00,$40 .db $03,$00,$2f .db $04,$00,$3a .db $12,$00,$10 .db $10,$00,$18 .db $0e,$00,$20 .db $0c,$00,$28 .db $0a,$00,$30 .db $08,$00,$38 .db $06,$00,$40 .db $04,$00,$48 .db $2a,$00,$20 .db $ff,$ff,$ff ;---------------------------- texts ------------------------------------------- title_message: .db "* * NEMESIS * *",0 ;---------------------------- save data --------------------------------------- stored_data_start: level .dw $0000 ;level number background .db %00000001 ;level background timer .dw $0000 curevent .dw Leveldata+1 ;next event nextevent .db (Leveldata) ;time to next event score .dw $0000 your_occ .db $00 ;0=normal 1=exploding 2=gone lives .dw $0003 ;unused x .db $16 ;x-pos y .db $46 ;think about it.. hp .db $00 ;hitpoints left your_status .db $00,$00 ;unused ybullets .dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;10 x (state,x,y) ebullets .dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;10 x (state,x,y) enemies .dw $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000 .dw $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000 .dw $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000 .dw $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000 .dw $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000 ; 0011 2233 >> 0=occupation (and %00000011: 0=no enemy 1=normal 2=exploding) ; 1=frame/ship 2=x 3=y variables_end: stored_data_end: .end ;NEMESIS'86 by Shiar ;0.01.717 -- 17.VII.99 -- size 984 ; ; + movement of ship over whole screen ; + enemies moving from right to left, appearing right at specified times ; ; 0.1.718 -- 18.VII.99 -- size 907 ; ; * no crash when level restarts for the third time ; * exit-procedure updated, unnecessary stuff/keychecks removed ; * alot of unused code removed ; + different types of enemies (just look different) ; + collision detection!! enemy ships disappear when you hit them ; ; 0.2.718 -- 18.VII.99 -- size 1153 ; ; + ability to fire bullets (F1). Enemies disappear on impact ; * enemies explode instead of disappearing ; ; 0.3.719 -- 19.VII.99 -- size 1401 ; ; * bullets appear correctly (not INSIDE your ship) ; + some enemies can take multiple hits (differs per class) ; + all enemies fire bullets at random ; + if you're hit by bullet/enemy, you'll lose one hitpoint