; samegame 1k ; for the minigame competition 2002 ; written by Dominic Morris ; v1.1 MODULE samegame org 23775 defc font = 25600 defc arena = 27000 defc width = 16 defc depth = 10 defc int_seed = 23670 ; Some nice ROM routines defc stakbc = $2d2b defc printfp = $2de3 defc mult = $30A9 ;hl = hl * de xor a out (254),a ld l,a ld h,a ld (high),hl ld a,7 ld (23695),a ld (23624),a ; Set up a marginally nicer font ld hl,15616 ld de,font-256 ld (23606),de inc d ld bc,768 .font1 ld a,(hl) rla or (hl) ld (de),a inc hl inc de dec bc ld a,b or c jr nz,font1 .restart ld hl,16384 ;clear screen ld de,16385 ld bc,6911 ld (hl),l ldir ld hl,0 ;initialise score ld (score),hl ld (xypos),hl call init_level call drawboard call cursor .mloop xor a ld (23560),a .mloop1 halt ld a,(23560) and a jr z,mloop1 call toupper ld bc,(xypos) cp 'Q' jr nz,notup ld a,b and a jr z,mloop dec b .moved ld (xypos),bc push bc call reset pop bc call highlight ;toggle adjacent ones ld a,e ld (selected),a dec a call z,reset ;only one done call drawboard ;redraw the board call cursor jr mloop .notup cp 'A' jr nz,notdown ld a,b cp depth-1 jr z,mloop inc b jr moved .notdown cp 'O' jr nz,notleft ld a,c and a jr z,mloop dec c jr moved .notleft cp 'P' jr nz,notright ld a,c cp width-1 jr z,mloop inc c jr moved .notright cp 'G' jr z,restart cp ' ' jr z,isfire cp 'M' jr nz,mloop .isfire call crunchy ;remove spaces in y call crunchx ;remove spaces in x ld a,(selected) and a sub 2 jp m,noinc ld l,a ld h,0 ld e,l ld d,h call mult ld de,(score) add hl,de ld (score),hl .noinc call checkover ;check whether the game is over ld bc,(xypos) jr nc,moved ; Game over one way or another ld hl,(score) ld a,e and a jr nz,checkhigh ld de,1000 add hl,de ld (score),hl .checkhigh ld de,(high) and a sbc hl,de jr c,gameover1 ld hl,(score) ld (high),hl .gameover1 call drawboard ld hl,gameovertxt call pstr xor a ;wait for a keypress before restarting ld (23560),a .gameover2 halt ld a,(23560) and a jr z,gameover2 jp restart .init_level ld hl,arena ld b,width*depth .init_level1 push hl call random pop hl and 3 inc a ld (hl),a inc hl djnz init_level1 ret ; Highlight all connected pieces (recursive routine) ; Entry: b = y, c = x d = colour ; In loop: e = number of matchers ; Exit: bc = xy, e = number filled .highlight call getcontent ld d,a ld e,0 .highlight1 call getcontent and a ;don't want ordinary ones highlit ret z cp d ret nz bit 7,a ;already tagged ret nz inc e ;number tagged set 7,(hl) ;tag push bc inc c ld a,width-1 cp c call nc,highlight1 pop bc push bc dec c call p,highlight1 pop bc push bc dec b call p,highlight1 pop bc push bc inc b ld a,depth-1 cp b call nc,highlight1 pop bc ret ; Reset all pieces .reset ld hl,arena ld b,width * depth .reset1 res 7,(hl) inc hl djnz reset1 ret ; Check to see if the game is over ; nc = not over, c = over ; e = number on board .checkover ld e,0 ld b,depth-1 .checkover1 ld c,width-1 .checkover2 call getcontent and a jr z,nocheckany ex af,af ;save the content inc e dec c jp m,nocheckx call getcontent ex af,af ;original back cp (hl) ret z ;sets nc ex af,af .nocheckx inc c dec b jp m,nochecky call getcontent ex af,af cp (hl) ret z .nochecky inc b .nocheckany dec c jp p,checkover2 dec b jp p,checkover1 scf ;indicate no pairs found ret ;Crunch in y .crunchy ld c,width .crunch_0 ld b,depth ;bottom row dec c .crunch_1 dec b .crunch_11 call getcontent bit 7,a jr z,crunch_12 call crunch_3 jr crunch_11 .crunch_12 inc b .crunch_2 djnz crunch_1 ld a,c and a jr nz,crunch_0 ret ; Do the crunch .crunch_3 push bc ; Move down ; Entry hl = hole .movedown1 ld a,b and a jr z,movedown2 dec b ex de,hl ;de = incoming position call getcontent ld (de),a ld (hl),0 jr movedown1 .movedown2 ld (hl),0 ;reset top pop bc ret ; Crunch in x - only consider the bottom row .crunchx ld b,width .crunchx1 push bc ld a,width sub b ld c,a ld b,depth-1 call getcontent and a jr nz,crunchx2 ld d,c ;dest .crunchx11 call getcontent ex af,af inc c ld a,width+1 cp c jr z,crunchx12 ex af,af and a jr z,crunchx11 .crunchx12 dec c ld e,c ;source .crunchx15 call copycol inc e inc d ld a,d cp width jr nz,crunchx15 .crunchx2 pop bc djnz crunchx1 ret ; Copy column from right to left ; Enter: d = dest column e = source .copycol .copycol1 ld b,depth .copycol2 push bc dec b ld c,d call getcontent push hl ld a,e cp width ld a,0 jr nc,copycol3 ld c,e call getcontent ld (hl),0 ;zero source out .copycol3 pop hl ld (hl),a pop bc djnz copycol2 ret .drawboard ld b,depth .drawboard1 ld c,width .drawboard2 push bc dec b dec c call getcontent ld hl,blank and a jr z,drawboard3 ld hl,ball bit 7,a jr z,drawboard3 ld hl,miniball .drawboard3 and 127 ld (colour),a call arena_print pop bc dec c jr nz,drawboard2 djnz drawboard1 ld hl,scoretxt call pstr ld bc,(score) call pnum call pstr ;hightxt follows on from scoretxt ld bc,(high) jp pnum ; Cursor highlight ; Entry: bc = xy pos .cursor ld bc,(xypos) call getcontent ld hl,blank and a ld d,@00111000 jr z,cursor1 ld hl,ball ld d,a rlca jr nc,cursor0 ld hl,miniball res 7,d ;remove highlight .cursor0 and a rl d rl d rl d .cursor1 ld a,d .cursor2 ld (colour),a ; Fall through to arena_print ; Print something on the arena: ; b = board row ( 0 - 9 ) ; c = board col ( 0 - 15 ) ; hl = which sprite to use ; (Some optimization could be done here!) .arena_print ld a,b add a,a ld d,a ld a,c add a,a ld e,a .spriti ld a,d and 248 add 64 ld c,a ld a,d and 7 rrca rrca rrca add e ld e,a ld d,c push de ld b,16 ; 16 lines in a sprite .sprit2 ld a,(hl) ld (de),a inc hl inc e ld a,(hl) ld (de),a inc hl dec e inc d ld a,7 and d jr nz,outlo ld a,e add 32 ld e,a jr c,outlo ld a,d sub 8 ld d,a .outlo djnz sprit2 pop de ld a,d rrca rrca rrca and 3 or 88 ld d,a ex de,hl ld bc,31 ld a,(colour) ld (hl),a inc l ld (hl),a add hl,bc ld (hl),a inc l ld (hl),a ret ; Random routine - needs to preserve bc .random ld hl,(int_seed) ld a,h add a rl l rl h add a rl l rl h add a rl l rl h ld de,$7415 add hl,de ld (int_seed),hl ld a,h ret ; Get arena content ; Entry: b = row c = col ; Exit: hl = ptr, a = what's there .getcontent push de ld l,b ld h,0 add hl,hl add hl,hl add hl,hl add hl,hl ld e,c ld d,0 add hl,de ld de,arena add hl,de ld a,(hl) pop de ret ; Print a 255 terminated string using ROM routines .pstr ld a,(hl) inc hl inc a ret z dec a rst 16 jr pstr ; Print (b)c using ROM routines preserving hl .pnum push hl call stakbc call printfp pop hl ret .toupper cp 'a' ret c cp 'z'+1 ret nc and 223 ret .gameovertxt defb 22,8,8,17,6,16,0,18,1 defm "*** GAME OVER ***" defb 17,0,16,7,18,0,255 .scoretxt defb 22,21,0 defm "SCORE " defb 255 .hightxt defb 22,21,16 defm "HIGH " defb 255 .score defw 0 .high defw 0 .xypos defw 0 .selected defb 0 ;number selected .colour defb 0 .blank defs 32 ; Some sprites .ball defb @00000000,@00000000 defb @00000011,@11000000 defb @00001101,@01110000 defb @00010001,@11111000 defb @00111011,@01111100 defb @00010001,@10111100 defb @01010101,@11111110 defb @00100101,@11111110 defb @01001101,@01111110 defb @00010011,@11001110 defb @00100101,@11010100 defb @00010011,@10111100 defb @00000101,@11111000 defb @00001100,@11110000 defb @00000011,@11000000 defb @00000000,@00000000 .miniball defb @00000000,@00000000 defb @00000000,@00000000 defb @00000000,@00000000 defb @00000011,@11000000 defb @00000100,@11100000 defb @00001001,@11110000 defb @00011010,@01111000 defb @00010101,@11111000 defb @00011010,@01111000 defb @00010100,@01101000 defb @00001010,@01110000 defb @00000101,@01100000 defb @00000011,@11000000 defb @00000000,@00000000 defb @00000000,@00000000 defb @00000000,@00000000