;----------------------------- ;|DuckHunt 82z! version 1.2a ;|By: Andrew Ungvarsky ;|Ti-82 Port: Ahmed El-Helw ;------------------------------ #INCLUDE "CRASH82.INC" duckx = TEXT_MEM ducky = TEXT_MEM+1 wing = TEXT_MEM+2 dirlr = TEXT_MEM+3 dirud = TEXT_MEM+4 moves = TEXT_MEM+5 temp = TEXT_MEM+6 gunx = TEXT_MEM+7 guny = TEXT_MEM+8 score = TEXT_MEM+9 bullets = TEXT_MEM+11 curduck = TEXT_MEM+12 needed = TEXT_MEM+13 dhit = TEXT_MEM+14 round = TEXT_MEM+15 dlay = TEXT_MEM+16 tscore = TEXT_MEM+18 noLet = TEXT_MEM+20 string = TEXT_MEM+30 .DB "DuckHunt 82Z 1.2a", 0 Initialize: ROM_CALL(CLEARLCD) CALL BUFCLR jp Title Title: ld hl,0 ld (CURSOR_POS),hl ld hl,TitleStuff ROM_CALL(D_ZT_STR) ld hl,57*256+0 ld (CURSOR_X),hl ld hl,hstext ROM_CALL(D_ZM_STR) ld hl,57*256+60 ld (CURSOR_X),hl ld hl,(highscore) call DispHL TitleLoop: call GET_KEY cp G_ENTER jp z,Start cp G_MODE ret z jp nz,TitleLoop NewRound: ROM_CALL(CLEARLCD) call nrInit ;Initialize Round NewDuck: call ndInit call PutGun jp Loop Start: call varInit call nrInit call ndInit call PutGun jr Loop Loop: call dispScore call LoadDuck ;Loads the Duck ld a,(ducky) ;Duck Y Coordinate into A ld e,a ;That into E ld a,(duckx) ;Duck X into A call SPRXOR call CR_GRBCopy jp GetKeyLoop GetKeyLoop: ld a,0ffh ;Reset keyport out (1),a ;Clear Port ld a,0feh ;Load desired port out (1),a ;Clear Keys in a,(1) ;Input Key cp 251 ;If key is right jp z,GunRight ;Goto Right cp 253 ;If key is left jp z,GunLeft ;Goto Left cp 247 ;Is it key Up jp z,GunUp ;Move Up cp 254 ;Is it Down jp z,GunDown ;Move Down ld a,0ffh ;Reset keyport out (1),a ;Clear Port ld a,0bfh ;Load desired port out (1),a ;Clear Keys in a,(1) ;Input Key cp 223 ;Is it 2nd jp z,shoot ;Shoot if so cp 127 ;Is it delete call z,GamePause ;Pause cp 191 ;Is it Quit? jp z,exit ;Return from Program if so jp nz,NoKey ;NoKey Otherwise ;--------shoot gun!--------- shoot: call PutGun ld a,(guny) ;gun y-coord->a ld e,a ;a->e ld a,(gunx) ;gun x-coord->a ld bc,shot ;sprite shot->bc call SPRXOR ;call Movax's sprite routine call CR_GRBCopy call delay ;delay call delay ;delay call delay ;delay ld a,(guny) ;gun y-coord->a ld e,a ;a->e ld a,(gunx) ;gun x-coord->a ld bc,shot ;sprite shot->bc call SPRXOR ;call Movax's sprite routine call CR_GRBCopy call PutGun erasebul: SET 7,(IY+$14) ld a,(bullets) ;bullets->a cp 3 call z,EraseNo3 cp 2 call z,EraseNo2 cp 1 call z,EraseNo1 ld hl,erase ;string erase->hl ROM_CALL(D_ZM_STR) ;display string on graph (erasing bullet) RES 7,(IY+$14) ;---------check for hit------- CheckForHit: ld a,(gunx) ;Loads Gun X into A add a,4 ;Add 8 to A [End of Sprite] ld b,a ;Loads A into B ld a,(duckx) ;Loads Duck X into A cp b ;Compares a to b jp c,ContinueCheck ;Continue Checking if a>b jp subbull ;Missed Otherwise ContinueCheck: ld a,(duckx) ;Duck X into A add a,4 ;Add 8 to A [End of Sprite] ld b,a ;Loads A into B ld a,(gunx) ;Gun X into A cp b ;Compare A to B jp c,CheckYHit ;If b>a then check Y-Coord jp subbull ;You missed otherwise CheckYHit: ld a,(guny) ;Loads Gun X into A add a,4 ;Add 8 to A [End of Sprite] ld b,a ;Loads A into B ld a,(ducky) ;Loads Duck X into A cp b ;Compares a to b jp c,ContinueCheckY ;Continue Checking if a>b jp subbull ;Missed Otherwise ContinueCheckY: ld a,(ducky) ;Duck X into A add a,4 ;Add 8 to A [End of Sprite] ld b,a ;Loads A into B ld a,(guny) ;Gun X into A cp b ;Compare A to B jp c,hit ;If b>a then Hit!!! jp subbull ;You missed otherwise erdc: call PutGun ;xor crosshairs on screen (erasing them) call LoadDuck ;load current duck sprite ld a,(ducky) ;ducky->a ld e,a ;a->e ld a,(duckx) ;duckx->a call SPRXOR ;call movax's xor sprite routine call CR_GRBCopy ;copy graph buffer to display ret ;--------duck fly away------ flyaway: call erdc ;erase duck and cursor SET 7,(IY+$14) ld hl,20*256+34 ;penrow=20,pencol=34 ld (CURSOR_X),hl ;set these coords ld hl,fas ;fly away string ROM_CALL(D_ZM_STR) RES 7,(IY+$14) flyaway1: ld a,(ducky) ;duck y-coord->a ld e,a ;a->e ld a,(duckx) ;duck x-coord->a ld bc,faway ;faway sprite->bc call SPRXOR ;call SPRXOR routine call CR_GRBCopy call delay ;delay ld a,(ducky) ;duck y-coord->a ld e,a ;a->e ld a,(duckx) ;duck x-coord->a ld bc,faway ;faway sprite->bc call SPRXOR ;call SPRXOR routine call CR_GRBCopy ld a,(ducky) ;duck y-coord->a cp 0 ;top of the screen? (a=0?) jp z,advance ;if so, goto fadvance dec a ;a-1->a (to decrease y-coord) ld (ducky),a ;a->duck y-coord jp flyaway1 ;loop! ;-----------A HIT!!!---------------- hit: call erdc ;erase duck and cursor! ld a,(dhit) ;ducks hit->a inc a ;a+1->a ld (dhit),a ;a->ducks hit ;------------update score------------ ld a,(bullets) ;bullets remaining->a cp 3 jp z,FullCredit cp 2 jp z,TwoHit jp nz,LeastCredit FullCredit: ld l,45 ld h,0 ld (tscore),hl ld de,(score) add hl,de ld (score),hl jr hitloop TwoHit: ld l,30 ld h,0 ld (tscore),hl ld de,(score) add hl,de ld (score),hl jr hitloop LeastCredit: ld l,15 ld h,0 ld (tscore),hl ld de,(score) add hl,de ld (score),hl hitloop: ld a,(ducky) ;duck y-coord->a ld e,a ;a->e ld a,(duckx) ;duck x-coord->a ld bc,hitduck ;sprite hitduck->bc call SPRXOR ;call movax's sprite routine call CR_GRBCopy call delay ;delay ld a,(ducky) ;duck y-coord->a ld e,a ;a->e ld a,(duckx) ;duck x-coord->a ld bc,hitduck ;sprite hitduck->bc call SPRXOR ;call movax's sprite routine call CR_GRBCopy ld a,(ducky) ;duck y-coord-> inc a ;a+1->a (make him go one more down the screen) ld (ducky),a ;a->duck y-coord cp 38 ;is it 38? (grass line?) jp z,advance ;if not, loop again cp 39 ;is it 38? (grass line?) jp z,advance ;if not, loop again cp 40 ;is it 38? (grass line?) jp z,advance ;if not, loop again cp 41 ;is it 38? (grass line?) jp z,advance ;if not, loop again cp 42 ;is it 38? (grass line?) jp z,advance ;if not, loop again cp 43 ;is it 38? (grass line?) jp z,advance ;if not, loop again jp hitloop advance: ;advance duck, round, or even END of game ld a,(curduck) ;current duck #->a cp 10 ;duck #10? (new round?) jp z,rndovr ;if so, goto round over inc a ;a+1->a (increase current duck #) ld (curduck),a ;a->current duck # jp NewDuck ;new duck! ;---------subtract bullet from remaining-------- subbull: ld a,(bullets) ;bullets left->a dec a ;a-1->a ld (bullets),a ;a->bullets or a ;zero? (out of bullets?) jp z,flyaway ;if so, goto flyaway! jp nz,NoKey ;return from getkey EraseNo3: ld hl,56*256+12 ld (CURSOR_X),hl ret EraseNo2: ld hl,56*256+8 ld (CURSOR_X),hl ret EraseNo1: ld hl,56*256+4 ld (CURSOR_X),hl ret GunUp: ld a,(guny) ;gun y-coord->a cp 0 ;a=0? (top of screen?) jp z,NoKey ;if so, NoKey call PutGun ld a,(guny) ;gun y-coord->a dec a ;a-1->a (to move up) dec a ;a-1->a (to move up) ld (guny),a ;a->gun y-coord jr PutMove ;put gun move GunDown: ld a,(guny) ;gun y-coord->a cp 38 ;a=38? (grass line?) jp z,NoKey ;if so, goto NoKey call PutGun ld a,(guny) ;gun y-coord->a inc a ;a+1->a (to move down) inc a ;a+1->a (to move down) ld (guny),a ;a->gun y-coord jp PutMove ;put gun move GunLeft: ld a,(gunx) ;gun x-coord->a cp 0 ;a=0? (left side of screen) jp z,NoKey ;if so, goto NoKey call PutGun ld a,(gunx) ;gun x-coord->a dec a ;a-1->a (to move left) dec a ;a-1->a (to move left) ld (gunx),a ;a->gun x-coord jp PutMove ;put gun move GunRight: ld a,(gunx) ;gun x-coord->a cp 88 ;a=88? (right side of screen) jp z,NoKey ;if so, goto NoKey call PutGun ld a,(gunx) ;gun x-coord->a inc a ;a+1->a (to move right) inc a ;a+1->a (to move right) ld (gunx),a ;a->gun x-coord jp PutMove ;Put GunMove ;-------move duck------------ dmove: ld a,(moves) ;moves->a inc a ;a+1->a ld (moves),a ;a->moves ld a,(dirlr) ;dirlr->a cp 1 ;is duck moving right? jp z,inca ;if so, increment duckx ld a,(duckx) ;duckx->a dec a ;a-1->a rinc: ;return from inc ld (duckx),a ;a->duckx ld a,(dirud) ;dirud->a cp 1 ;is duck moving up? jp z,deca ;if so, goto decrement a ld a,(ducky) ;ducky->a inc a ;a+1->a rdec: ;return from decrement ld (ducky),a ;a->ducky ret ;return to main body inca: ld a,(duckx) ;duckx->a inc a ;a+1->a jp rinc ;return from increment deca: ld a,(ducky) ;ducky->a dec a ;a-1->a jp rdec ;return from decrement PutMove: call PutGun ;re-display crosshairs jp SkipDelay ;return from gtkey, skipping delay NoKey: call delay ;Create a short delay jr SkipDelay SkipDelay: ld a,(moves) ;moves->a cp 200 ;has the duck moved # times? jp z,flyaway ;if so, fly away call LoadDuck ;Load Duck ld a,(ducky) ;ducky->a ld e,a ;a->e ld a,(duckx) ;duckx->a call SPRXOR ;Clear it! jp chwing ;call routine to change wing wingch: ;return from chwing. (Wing status changed) jp chkdloc ;check duck's location (if on any edges, ;change movement direction.) rchk: ;return from check call dmove ;move duck! jp Loop ;go to beginning of duck moving routine ;------change wing (up or down)---- chwing: ld a,(wing) ;wing->a inc a ;a+1->a ld (wing),a ;a->wing cp 3 ;is a 3? jp nz,wingch ;if not, goto wing changed (it must be 2) ld a,1 ;(else, reset wing to 1)... 1->a ld (wing),a ;a->wing jp wingch ;return from chwing ;------check duck's location------------- chkdloc: ld a,(duckx) ;duckx->a (duck's x-coord) cp 87 ;is x-coord 87? jp z,chdirlr ;if so, goto change duck's lr direction cp 1 ;is x-coord 1? jp z,chdirlr ;if so, goto change duck's lr direction nchk: ld a,(ducky) ;ducky->a (duck's y-coord) cp 1 ;is y-coord 1? jp z,chdirud ;if so, goto change duck's ud direction cp 38 ;is y-coord 38? jp z,chdirud ;if so, goto change duck's ud direction jp rchk chdirlr: ;change duck's lr movement ld a,(dirlr) ;dirlr->a inc a ;a+1->a ld (dirlr),a ;a->dirlr cp 3 ;is dirlr 3? jp nz,nchk ;if not, next chk (that means dirlr is 2) ld a,1 ;(otherwise... set it back to 1) 1->a ld (dirlr),a ;a->dirlr jp nchk ;next check chk chdirud: ;change duck's ud movement ld a,(dirud) ;dirud->a inc a ;a+1->a ld (dirud),a ;a->dirud cp 3 ;is dirud 3? jp nz,rchk ;if not, return (that means dirud is 2) ld a,1 ;(otherwise... set it back to 1) 1->a ld (dirud),a ;a->dirud jp rchk ;return from chk ;------ld which sprite (direction and wing up or down)---- LoadDuck: ld a,(wing) ;wing->a cp 2 ;wing down? jp z,down ;if so,jump to down ld a,(dirlr) ;dirlr->a cp 2 ;left? jp z,uleft ;if so, jump to (facing) up,left ld bc,drwu ;if none of these, sprite drwu->bc=20 ret ;duck loaded uleft: ld bc,dlwu ;sprite dlwu->bc ret ;duck loaded down: ld a,(dirlr) ;dirlr->a cp 2 ;left? jp z,dleft ;if so,jump to (facing) down,left ld bc,drwd ;otherwise, sprite drwd->bc ret ;jp duckldd dleft: ld bc,dlwd ;sprite dlwd->bc ret ;jp duckldd dispScore: SET 7,(IY+$14) ld hl,57*256+59 ;penrow=3D57,pencol=3D58 ld (CURSOR_X),hl ;set those coords ld hl,(score) ;score->hl call DispHL RES 7,(IY+$14) ret ;return PutGun: ld a,(guny) ;gun y-coord->a ld e,a ;a->e ld a,(gunx) ;gun x-coord->a ld bc,gun ;sprite gun->hl call SPRXOR ;PutSprite call CR_GRBCopy ret ;return PutDuck: ld a,(guny) ;gun y-coord->a ld e,a ;a->e ld a,(gunx) ;gun x-coord->a call LoadDuck call SPRXOR ;PutSprite call CR_GRBCopy ret ;return ;---------round over-------------- rndovr: ld hl,10*256+10 ;penrow=20,pencol=10 ld (CURSOR_X),hl ;set these coords ;-----Show how many hit/needed------- ld hl,youhit ;"You hit " ROM_CALL(D_ZM_STR) ;put string on graph ld a,(dhit) ;# ducks hit->a call DispA ld hl,andneed ;" and needed " ROM_CALL(D_ZM_STR) ;put string on graph ld a,(needed) ;# needed to advance->a call DispA ;---------Check for round clear!-------- ld a,(dhit) ;# needed to advance->a inc a ;Increase it, so that if they are =, it works out ld b,a ld a,(needed) cp b jp nc,exit ;-----if you've made it here, ROUND CLEAR!--------- ld hl,20*256+28 ;penrow=30,pencol=28 ld (CURSOR_X),hl ;set these coords ld hl,rndclr ;"Round Clear!" ROM_CALL(D_ZM_STR) ;put string on graph! ld a,(dhit) ;# ducks hit->a cp 10 ;did you hit all 10 ducks? jp nz,noperfect ;if not skip perfect, goto NOPERFECT! ld hl,(score) ;score->hl ld de,250 add hl,de ld (score),hl ;hl->score ld hl,34 ;penrow=0,pencol=34 ld (CURSOR_X),hl ;set coords ld hl,perfect ;"PERFECT!" ROM_CALL(D_ZM_STR) ld hl,00*256+21 ;penrow=10,pencol=21 ld (CURSOR_X),hl ;set coords ld hl,bonus ;"100 point BONUS!" ROM_CALL(D_ZM_STR) noperfect: call Pause call delay ;delay call delay ;delay call delay ;delay call delay ;delay ld a,(round) ;round #->a cp 5 ;round #5? jp z,winner ;if so, you win! inc a ;a+1->a ld (round),a ;a->round call ReSetDelay jp NewRound ;new round!!! ReSetDelay: ld a,(round) cp 2 jp z,LoadDelay2 jp nz,LoadDelay3 LoadDelay2: ld bc,$1300 ld (dlay),bc ret LoadDelay3: ld bc,$800 ld (dlay),bc ret ;--------WINNER!------------- winner: call BUFCLR ROM_CALL(CLEARLCD) ;Clear the Screen ld hl,7 ;penrow=0,pencol=7 ld (CURSOR_X),hl ;set these coords ld hl,congrats1 ;first line of congrats string ROM_CALL(D_ZM_STR) ld hl,6*256+9 ;penrow=6,pencol=9 ld (CURSOR_X),hl ;set these coords ld hl,congrats2 ;second line of congrats string ROM_CALL(D_ZM_STR) ;put string on graph! ld hl,12*256+14 ;penrow=12,pencol=14 ld (CURSOR_X),hl ;set these coords ld hl,congrats3 ;third line of congrats string ROM_CALL(D_ZM_STR) ;put string on graph! ld hl,18*256+0 ;penrow=18,pencol=0 ld (CURSOR_X),hl ;set these coords ld hl,congrats4 ;fourth line of congrats string ROM_CALL(D_ZM_STR) ;put string on graph! jp exit exit: ld hl,40*256+30 ;penrow=29,pencol=33 ld (CURSOR_X),hl ;set these coords ld hl,gameover ;"GAME OVER!" ROM_CALL(D_ZM_STR) ;put string on graph! ld hl,47*256+30 ;penrow=37,pencol=30 ld (CURSOR_X),hl ;set these coords ld hl,scr ;"SCORE = " ROM_CALL(D_ZM_STR) ;put string on graph! ld hl,47*256+50 ;penrow=37,pencol=30 ld (CURSOR_X),hl ;set these coords ld hl,(score) ;score->hl call DispHL ;Display it! call delay ;delay call delay ;delay call Pause call BUFCLR ROM_CALL(CLEARLCD) finish: ld hl,(score) ;final score ld de,(highscore) ;load high score call CP_HL_DE ;compare score w/ hi score jp nc,hisco ;if score is more ;or equal res 3, (iy+$05) ; normal text ret ; Input routine - made by Jimmy Mårdell 97-03-05 ; Reads a sentence entered from the keyboard. Only uppercase letters ; and space are allowed. Left arrowkey = backspace. ; ; When calling, HL should point to where the string should be stored ; and A should hold the maximum length of the string. Be sure there ; are enough space (A+1) to store the nullterminated string at HL! ; ($800C) should hold the screen position where the string starts. ; ; This input routine will also have a flashing cursor. If you don't like ; it, remove all rows where the explanation starts with a *. ; ; IMPORTANT: The input must NOT wrap to a new row! Then it will not work ; properly. The last char on a row should not be used either (if cursorcol=0 ; when calling, the maximum char length is 20). If you have a cursor, the ; two last chars should not be used (max length 19 if the screen location ; starts to the far left). ; ; The routine requires one temporary variable, noLet. ; largely indented stuff added by Adamman hisco: ROM_CALL(CLEARLCD) ld hl,(score) ld (highscore),hl ld hl,0 ld (CURSOR_X),hl ld hl,HiScr ROM_CALL(D_ZM_STR) ld hl,0*256+79 ld (CURSOR_X),hl ld hl,(score) call DispHL ld de, $0504 ;initials entered at 5,4 ld ($800C), de ;load location ld hl,hstext+12 ;hl points to initials ld a,3 ;max chars = 3 call INPUT ret INPUT: ; push bc ; push de ; push hl ; ei ; set 2,(iy+12) ; * Turn cursor blinking on (interrupts must be enabled) ld (noLet),a ; Store the maximum lenght of the string ld e,0 ; E = numbers of letters written so far WaK: ; ld a,32 ; ld ($800E),a ; * Set "character under cursor" to space push hl ; Save HL since GET_KEY destroys it's content ld a, 217 ROM_CALL(TX_CHARPUT) ld hl, $800D dec (hl) call GET_KEY ;get key press cp G_MODE jr z,exit_last cp $02 ; $02 = left key jr z,BackSpace cp $09 ; $09 = enter jr z,NameDone ;if enter then your done or a jr nz,CheckLetter pop hl jr WaK CheckLetter: ld hl,Letters ld bc,26 ; 26 letters to check cpir ; Compare A with each letter until a match is found ld d,c ; Then C = the letter. Store in D pop hl ; HL -> current position in string jr nz,WaK ; If not valid keystroke, wait for new key ld a,65 ; 65 = ascii char for A add a,d ; A now holds the ascii char for the letter pressed PutLetter: ld c,a ld a,(noLet) ; A = max letters cp e ; Check if max size is reached jr z,WaK ; If so, wait for a new key ld (hl),c ; If not, store the key entered inc hl ; Point to the next byte in the string inc e ; And increase the letter counter ld a,c ROM_CALL(TX_CHARPUT) ; Show the chars pressed on the screen jr WaK ; And jump back and wait for a new key BackSpace: pop hl ; HL -> current position in string ld a,e or a ; Check if string size = 0 jr z,WaK ; If so, backspace is impossible. Check for new key. ; res 2,(iy+12) ; * Stopp cursor blinking dec e ; Decrease string size dec hl ; And string pointer push hl ;temporary storage of hl ld hl,$800D ; HL -> x cursor position dec (hl) ; Decrease it ld a,32 ; Overwrite the last letter with a space ROM_CALL(TX_CHARPUT) ; Put the space over the chars ROM_CALL(TX_CHARPUT) ; * And over the (non) blinking cursor dec (hl) ; * Decrease the x coordinate twice dec (hl) ;decrease hl by 1 pop hl ;recall hl ; set 2,(iy+12) ; * Stopp cursor blinking jr WaK ; Wait for a key NameDone: pop hl ; HL -> current position in string ld (hl),0 ; Put a terminating zero at the end of the string ; res 2,(iy+12) ; * Stopp cursor blinking ; pop hl ; pop de ; pop bc ret exit_last: pop hl pop hl ret ; The keycodes of the letters A-Z stored backways Letters: .db $1A,$22,$2A ;ZYX .db $0B,$13,$1B,$23,$2B ;WVUTS .db $0C,$14,$1C,$24,$2C ;RQPON .db $0D,$15,$1D,$25,$2D ;MLKJI .db $0E,$16,$1E,$26,$2E ;HGFED .db $1F,$27,$2F ;CBA highscore: .db $00, $00 ;----------Initialize new round stuff-------------- nrInit: ;new round initialize call BUFCLR ;clear graph buffer ROM_CALL(CLEARLCD) ;clear screen SET 7,(IY+$14) ld a,44 ;44->a ld (gunx),a ;a->gun x-coord ld a,20 ;20->a ld (guny),a ;a->gun y-coord ld a,1 ;1->a ld (curduck),a ;a->current duck (1) ld a,0 ;0->a ld (dhit),a ;a->dhit (no ducks hit yet! duh) ld a,(round) ;round->a ld b,a ;a->b ld a,5 ;5->a add a,b ;a+b->a ld (needed),a ;a->needed ld hl,20*256+35 ;penrow=20,pencol=35 ld (CURSOR_X),hl ;set these coords ld hl,rnd ;"Round " ROM_CALL(D_ZM_STR) ld hl,20*256+60 ld (CURSOR_X),hl ld a,(round) ;round->a call DispA ;display a at penrow,pencol ld hl,30*256+15 ;penrow=30,pencol=15 ld (CURSOR_X),hl ;set these coords ld hl,hits ;hit string "Hit " ROM_CALL(D_ZM_STR) ;put string on graph! ld hl,30*256+27 ld (CURSOR_X),hl ld a,(needed) ;needed->a call DispA ld hl,30*256+34 ld (CURSOR_X),hl ld hl,outof10 ;" out of 10 ducks!" ROM_CALL(D_ZM_STR) ;put string on graph! call CR_GRBCopy ;copy buffer to display RES 7,(IY+$14) call Pause ;wait for Clear key call delay ;delay call delay ;delay call delay ;delay ret ;done,return from new round initialize ;-----------Initialize new duck stuff---------------- ndInit: ;new duck initialize call PutBG SET 7,(IY+$14) ld a,3 ;3->a ld (bullets),a ;a->bullets ld a,1 ;1->a ld (wing),a ;a->wing ld (moves),a ;a->moves ld (dirud),a ;a->dirud ld a,37 ;37->a ld (ducky),a ;a->ducky ld a,85 ;85->a (85 is max num for random) ld (temp),a ;a->temp call random ;call random routine... # from 1 - a ld (duckx),a ;a->duckx (a contains the random #) ld a,2 ;2->a (2 is max num for random) ld (temp),a ;a->temp call random ;random # generator inc a ld (dirlr),a ;a->dirlr ld hl,57*256+26 ;penrow=3D57,pencol=3D26 ld (CURSOR_X),hl ;set those coords ld a,(curduck) ;current duck->a call DispA ld hl,57*256+43 ;penrow=3D57,pencol=3D43 ld (CURSOR_X),hl ;set those coords ld a,(dhit) ;ducks hit->a call DispA RES 7,(IY+$14) call CR_GRBCopy ret random: ;by: Micheal Pearce ld a,(temp) ld b,a ld a,r add a,a ld hl,0 ld d,0 ld e,a RMul: add hl,de djnz RMul ld a,h ret varInit: ld hl,$0000 ;0->hl ld (score),hl ;hl->score ld a,1 ;1->a ld (round),a ;a->current round (1 to start) ld bc,$2000 ;initial delay length (2000)->bc ld (dlay),bc ;bc->dlay ret PutBG: ROM_CALL(CLEARLCD) ;Clear Screen call BUFCLR ;Clear Graph Buffer ld hl,bg ;background data->hl ld de,$88B8 ld bc,768 ;bytes to copy (?) ldir ;copy bytes to buffer CALL CR_GRBCopy RET delay: PUSH AF PUSH BC LD BC,(dlay) delayLoop: DEC BC LD A, B OR C JR NZ, delayLoop POP BC POP AF ret DispA: ld h,0 ld l,a DispHL: push de push hl ld de,string+5 xor a ld (de),a Repeat: call UNPACK_HL add a,'0' dec de ld (de),a ld a,h or l jr nz,Repeat ex de,hl ROM_CALL(D_ZM_STR) pop hl pop de ret Pause: call GET_KEY cp $00 jp z,Pause ret BUFCLR: ld hl,$88B8 ld de,$88B9 ld bc,$2FF ld (hl),0 ldir ret ;Dines/Evil Sam contrast routine GamePause: LD HL,$8008 ;HL=8008=pointer to contrast CP G_PLUS ;Was key up JR NZ,NotUp ;No continue LD A,(HL) ; Get contrast CP $1F ; Is contrast at max JR NC,NoAdd ;Yes jump INC A ;Inc contrast JR Continue ; Contrast changed NotUp: CP G_MINUS ;Was key down JR NZ,NotDown ;No continue LD A,(HL) ;Get contrast OR A ;Is it at min JR Z,NoAdd ;Yes jump DEC A ; Dec contrast Continue: LD (HL),A ; Save new contrast ADD A,$1E ; Add offset OR $C0 ; Make control word DI ; Disable contrast CALL $7F3 ; Delay for screen ops OUT ($10),A ; Set contrast EI ; Enable ints JR NoAdd NotDown: cp G_ENTER ; Check if ENTER was pressed ret z ; It was, so return to game NoAdd: CALL $129 ; Wait for a key (this is how the system does it) BIT 3,(IY+0) ; Has a key been pressed ? JR Z,NotDown ; No Wait again CALL GET_KEY ; Check which key was pressed JR GamePause ;end of routine ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ÛÛÛÛÛ Z80 ÛÛÛÛÛÛ³ Sprite83 ³ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ³ movax ³ÛÛÛÛÛÛÛÛÛÛÛÛ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÙ ; Sprite xor routine v1.0 ; Coded by Hannes Edfeldt in 1997 ; This routine uses xor to draw the sprite, therefore you can erase the sprite ; by just drawing it again at the same x and y coordinates. See xordemo.z80 ; for an example of how to use this routine. ; Feel free to use this routine in your own productions as long as you give me ; some credit. ; This file should of course be viewed in a DOS texteditor ;) ; Hannes Edfeldt -+- movax@algonet.se -+- http://www.algonet.se/~movax ;ÜÛÛÛÛÛÛÛÛÛÛÛÛß SPRXOR ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ Xor 8x8 sprite þ a=x, e=y, bc=sprite address ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ SPRXOR: push bc ; Save sprite address ;ÛÛÛÛ Calculate the address in graphbuf ÛÛÛÛ ld hl,0 ; Do y*12 ld d,0 add hl,de add hl,de add hl,de add hl,hl add hl,hl ld d,0 ; Do x/8 ld e,a srl e srl e srl e add hl,de ld de,$88B8 add hl,de ; Add address to graphbuf ld b,00000111b ; Get the remainder of x/8 and b cp 0 ; Is this sprite aligned to 8*n,y? jp z,ALIGN ;ÛÛÛÛ Non aligned sprite blit starts here ÛÛÛÛ pop ix ; ix->sprite ld d,a ; d=how many bits to shift each line ld e,8 ; Line loop LILOP: ld b,(ix+0) ; Get sprite data ld c,0 ; Shift loop push de SHLOP: srl b rr c dec d jp nz,SHLOP pop de ld a,b ; Write line to graphbuf xor (hl) ld (hl),a inc hl ld a,c xor (hl) ld (hl),a ld bc,11 ; Calculate next line address add hl,bc inc ix ; Inc spritepointer dec e jp nz,LILOP ; Next line jp DONE1 ;ÛÛÛÛ Aligned sprite blit starts here ÛÛÛÛ ALIGN: ; Blit an aligned sprite to graphbuf pop de ; de->sprite ld b,8 ALOP1: ld a,(de) xor (hl) ld (hl),a inc de push bc ld bc,12 add hl,bc pop bc djnz ALOP1 DONE1: ret ;ÜÛÛÛÛÛÛÛÛÛÛÛÛÜ SPRXOR ÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ;ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ¿ ;³ÛÛÛÛÛ Z80 ÛÛÛÛÛÛ³ Sprite83 ³ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ³ movax ³ÛÛÛÛÛÛÛÛÛÛÛÛ³ ;ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÙ ;--------------------- ;|Data ;--------------------- bg: .db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42,0,0,0,0,0,0 .db 0,0,0,0,0,85,0,0,0,0,0,0,0,0,0,0,0,170,128,0,0,0,0,0,0,0,0,0,0,85,64 .db 0,0,0,0,0,0,0,0,0,0,170,128,0,0,0,0,0,0,0,0,0,0,85,0,0,0,0,0,0,0,0 .db 0,0,0,58,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0 .db 0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0 .db 0,4,0,0,0,0,0,0,0,0,0,0,0,4,2,128,0,0,0,0,0,0,0,0,0,6,5,64,0,0,0 .db 0,0,0,0,0,0,10,138,160,0,0,0,0,0,0,0,0,0,21,85,80,0,0,0,0,0,0,0,0,0,10 .db 138,160,0,0,0,0,0,0,0,0,0,21,85,80,0,0,0,0,0,0,0,0,0,10,138,160,0,0,0,0,0 .db 0,0,0,0,3,28,0,0,0,0,0,0,0,0,0,0,3,56,0,0,0,0,0,0,0,0,0,0,163,48,0 .db 0,0,0,0,0,0,0,0,0,83,176,0,0,0,0,0,0,0,0,0,0,171,224,0,0,0,0,0,0,0,0 .db 0,0,83,202,128,0,0,0,0,0,0,0,0,0,167,213,64,0,0,0,0,0,0,0,0,0,71,42,160,0,0 .db 0,0,0,0,0,0,0,103,21,64,0,0,0,0,0,0,0,0,0,55,42,160,0,0,0,0,0,0,0,124,0 .db 63,21,64,0,0,0,0,0,0,0,244,0,31,130,0,0,0,0,0,0,0,3,230,0,31,134,0,0,0,0,0 .db 0,0,3,131,0,15,156,0,0,0,0,0,0,0,6,17,0,7,248,0,0,0,0,0,0,0,12,40,128,7,224 .db 0,0,0,0,0,0,0,12,0,64,7,128,0,0,0,0,0,0,0,12,128,64,7,128,0,0,0,0,0,0,0 .db 12,96,64,7,192,0,0,0,0,0,0,0,12,6,64,15,192,0,0,0,0,0,0,0,14,8,64,15,192,0,0 .db 0,0,0,0,0,6,129,128,15,192,0,0,0,0,0,0,0,7,131,128,15,192,17,16,1,8,2,33,9,47,255 .db 128,143,214,17,18,149,74,2,49,74,37,255,80,223,211,83,82,90,202,106,122,202,71,250,73,223,233,115,116,90,213 .db 110,122,213,98,102,137,239,219,115,84,172,213,70,124,213,110,118,150,175,235,106,246,189,213,109,85,213,237,90,214,255 .db 235,126,254,218,213,175,222,213,239,223,218,239,254,221,221,222,187,219,190,187,91,187,186,191,254,213,213,117,251,218,189 .db 251,218,187,189,128,0,127,255,255,255,255,255,255,255,255,255,149,39,96,0,0,0,15,203,38,112,0,3,165,82,108 .db 173,72,171,143,210,85,84,0,3,151,82,106,169,128,233,15,202,86,96,0,3,165,34,108,237,72,169,15,211,37,116 .db 0,3,128,0,96,0,0,0,15,192,0,0,0,3,140,204,101,0,8,0,15,192,0,0,0,3,140,204,111,128,0 .db 0,15,192,0,0,0,3,128,0,101,0,8,0,15,192,0,0,0,3,140,204,111,128,0,0,15,192,0,0,0,3 .db 128,0,101,0,8,0,15,192,0,0,0,3,255,255,224,0,0,0,15,192,0,0,0,3 drwu: ;duck facing right, wing up .db 01000000b .db 01100011b .db 00110100b .db 01111000b .db 11110000b .db 01000000b .db 00000000b .db 00000000b drwd: ;duck facing right, wing down .db 00000011b .db 00000100b .db 01111000b .db 11111000b .db 01001100b .db 00000000b .db 00000000b .db 00000000b dlwu: ;duck facing left, wing up .db 00000010b .db 11000110b .db 00101100b .db 00011110b .db 00001111b .db 00000010b .db 00000000b .db 00000000b dlwd: ;duck facing left, wing down .db 11000000b .db 00100000b .db 00011110b .db 00011111b .db 00110010b .db 00000000b .db 00000000b .db 00000000b gun: ;sprite for crosshairs .db 00000000b .db 00000000b .db 00100100b .db 00011000b .db 00011000b .db 00100100b .db 00000000b .db 00000000b shot: ;gunshot mark on screen .db 00000000b .db 01000010b .db 00101000b .db 00010100b .db 00101100b .db 00010010b .db 01001000b .db 00000000b faway: ;duck fly away .db 00001000b .db 00001000b .db 00011100b .db 00111110b .db 01101011b .db 00101010b .db 00010100b .db 00000000b hitduck: ;falling duck .db 00000100b .db 00010100b .db 00011110b .db 00011110b .db 00011100b .db 00001000b .db 00001000b .db 00000000b TitleStuff: .db " DuckHunt 82Z ", .db "Andrew Ungvarsky", .db "TI-82 Port by: ", .db " Ahmed El-Helw ", .db " Press Enter! ",0 erase: .db " ",0 ;string to erase bullet fas: .db "Fly Away!",0 ;fly away string rnd: .db "Round ",0 ;round # string hits: .db "Hit ",0 outof10 .db " out of 10 ducks!",0 rndclr .db "Round Clear!",0 youhit .db "You hit ",0 andneed .db " and needed ",0 prsclr .db "(Press Clear)",0 gameover .db "GAME OVER",0 congrats1 .db "Congratulations! You are",0 congrats2 .db "a hunting machine. BUT,",0 congrats3 .db "since I hate hunting,",0 congrats4 .db "there's no cool ending. SORRY!",0 scr .db "SCORE = ",0 perfect .db "PERFECT!",0 bonus .db "250 point BONUS!",0 hstext: .db "HighScore --ARE",0 HiScr: .db "A New High Score!",0