.nolist #include "ion.inc" #define showtimeleft ;#define finaldebug ;#define ptikeys iFastCopy .equ ionFastCopy iPutSprite .equ ionPutSprite iLargeSprite .equ ionLargeSprite iRandom .equ ionRandom fontFlags equ 32h fracDrawLFont equ 2 fracTallLFont equ 3 customFont equ 7 FPS equ 64 StartTime equ 120 AbsorbWaitMagitude equ 8 ;Menu Definitions MenuItem .equ $9872 HighScoreType .equ $9872 ;Ingame Definitions ;SaveSScreen .equ $86ec BlockScoreTime .equ $86ec ;SaveSScreen ShotsOnscreen .equ $9872 EnemiesOnscreen .equ ShotsOnScreen+1 CurrentLevel .equ EnemiesOnScreen+1 LevelStage .equ CurrentLevel+1 ;0,1, or 2 CraftX .equ LevelStage+1 CraftY .equ CraftX+1 ;1 byte MaxShots .equ 5*10 ;ShotArray format: ; byte who (0=none, 1=player, 2=enemy) ; byte xinc ; byte yinc ; byte xpos ; byte ypos ; word spriteptr ShotElementLength .equ 7 ShotArray .equ CraftY+1 EnemyArray .equ ShotArray+ShotElementLength*MaxShots MaxEnemies .equ 10 ;EnemyArray format: ; byte health ; byte xAccel ; byte yAccel ; byte xVel ; byte yVel ; byte xPos ; byte yPos ; word spriteptr EnemyElementLength .equ 9 TotalScore .equ EnemyArray+EnemyElementLength*MaxEnemies ;2 bytes Powerup_Speed .equ TotalScore+2 Powerup_Multi .equ Powerup_Speed+1 Powerup_Power .equ Powerup_Multi+1 WhoShot .equ Powerup_Power+1 FrameTimer .equ WhoShot+1 TimeLeft .equ FrameTimer+1 ;byte SaveShot .equ TimeLeft+1 Radius .equ SaveShot+2 whichKind .equ Radius+1 InitX .equ whichKind+1 InitY .equ InitX+1 invertTimer .equ InitY+1 Recurse .equ invertTimer+1 FrameTimeChange .equ Recurse+1 BlockArray .equ FrameTimeChange+1 BlockArrayLength .equ 12*8 ;(96/8)*(64/8) BlockArrayEnd .equ BlockArray+BlockArrayLength AbsorbWait .equ BlockArrayEnd ClearedFlag .equ AbsorbWait+1 EndData .equ ClearedFlag+1 .echoln "Variables are ",ClearedFlag-$9872," bytes of safeRAM." .list .org progstart-2 .db $BB,$6D INIT: .db $C9 jr nc,Start Description: .db "Invalid Tangram DE",0 START: ;main routines di DispMainMenu: in a,(1) inc a jr nz,DispMainMenu set TextWrite,(iy+sgrFlags) ;Make text go to buffer ld de,gbuf ld hl,TitleScreen ld bc,$300 ldir call iFastCopy xor a ld (MenuItem),a MenuItemDisp: set fracDrawLFont, (iy + fontFlags) ld hl,(43*256)+51 ld (pencol),hl ld hl,MenuStrings ld a,(MenuItem) or a jr z,MenuItemDisp2 inc a cp 2 jr nz,MenuItemDisp2 ld a,(Difficulty) inc a MenuItemDisp2: add a,a ld b,a add a,a add a,b ld e,a ld d,0 add hl,de ld b,6 bcall(_vputsn) res fracDrawLFont,(iy+fontFlags) call iFastCopy MenuWaitLoop: push af ld a,$ff out (1),a pop af call Pause push af ld a,$ff out (1),a pop af cp $0f ;[clear] jr z,QuitFinal cp $04 ;[up] jr z,MainMenuUp cp $01 ;[down] jr z,MainMenuDown cp $02 jr z,MainMenuDiffChg cp $03 jr z,MainMenuDiffChg cp $09 ;[enter] jr nz,MenuWaitLoop ld a,(MenuItem) or a jr z,BeginPlay dec a jr z,BeginPlay dec a jp z,ShowHelp dec a jp z,HighScores QuitFinal: res fracDrawLFont,(iy+fontFlags) res TextWrite,(iy+sgrFlags) ;Make text go to buffer ret MainMenuUp: ld a,(MenuItem) dec a cp $ff jr nz,MainMenuUp2 ld a,4 MainMenuUp2: ld (MenuItem),a jr MenuItemDisp MainMenuDown: ld a,(MenuItem) inc a cp 5 jr nz,MainMenuUp2 xor a jr MainMenuUp2 MainMenuDiffChg: ld a,(MenuItem) cp 1 jp nz,MenuItemDisp ld a,(Difficulty) ld b,a ld a,1 sub b ld (Difficulty),a jp MenuItemDisp BeginPlay: xor a ld h,a ld l,a ld (ShotsOnScreen),a ;a=hl=0 ld (EnemiesOnScreen),a ld (Powerup_Power),a ld (Powerup_Multi),a ld (Powerup_Speed),a ld (FrameTimeChange),a ld (invertTimer),a ld (AbsorbWait),a ld (TotalScore),hl inc a ;a=1 ld (FrameTimer),a ld a,41 ld (CraftX),a ld (CraftY),a ld a,StartTime+1 ld (TimeLeft),a ld a,(CheatMode) ld (Powerup_Power),a ld (Powerup_Multi),a ld (Powerup_Speed),a ld a,0 ld (CurrentLevel),a ld a,2 ld (LevelStage),a ld hl,ShotArray ld (hl),0 push hl; pop de inc de ld bc,ShotElementLength*MaxShots-1 ldir ;clear out shot array ld hl,EnemyArray ld (hl),0 push hl pop de inc de ld bc,EnemyElementLength*MaxEnemies-1 ldir ;clear out enemy array ld hl,BlockArray ld (hl),0 push hl pop de inc de ld bc,BlockArrayLength-1 ldir AddEnemies: ld a,(CurrentLevel) inc a ld (CurrentLevel),a ld a,(LevelStage) inc a cp 3 jr nz,AddEnemiesA xor a AddEnemiesA: ld (LevelStage),a or a jr z,AddEnemies0 dec a jr z,AddEnemies1 AddEnemies2: ld de,(2*256)+14 ld a,1 call PushEnemyItem ld de,(2*256)+22 ld a,2 call PushEnemyItem ld de,(38*256)+7 ld a,2 call PushEnemyItem ld de,(82*256)+14 ld a,1 call PushEnemyItem ld de,(74*256)+22 ld a,2 call PushEnemyItem jr MainLoop AddEnemies0: ld de,(2*256)+16 ld a,1 call PushEnemyItem ld de,(22*256)+7 ld a,1 call PushEnemyItem ld de,(42*256)+16 ld a,1 call PushEnemyItem ld de,(62*256)+7 ld a,1 call PushEnemyItem ld de,(82*256)+16 ld a,1 call PushEnemyItem jr MainLoop AddEnemies1: ld de,(2*256)+12 ld a,2 call PushEnemyItem ld de,(20*256)+16 ld a,2 call PushEnemyItem ld de,(38*256)+7 ld a,2 call PushEnemyItem ld de,(56*256)+16 ld a,2 call PushEnemyItem ld de,(74*256)+12 ld a,2 call PushEnemyItem MainLoop: #ifdef finaldebug call CheckError #endif ld a,(AbsorbWait) or a jr z,NoAbsorbDec dec a ld (AbsorbWait),a NoAbsorbDec: ld hl,FrameTimer ld a,(hl) dec a ld (hl),a or a jp nz,NoFrameTick FrameTick: ld a,FPS ld (hl),a ld a,(TimeLeft) dec a ld (TimeLeft),a or a jp z,GameOver xor a ld (FrameTimeChange),a call ReRenderBlocksAndText ;Now it's time to modify accelerations ld hl,EnemyArray ld b,MaxEnemies ChangeAccelSearch: ld a,(hl) or a jr z,ChangeAccelSearch1 push hl push bc ld d,1 push hl push de ld de,7 add hl,de ld a,(hl) inc hl ld h,(hl) ld l,a ld de,SpriteEnemy2 or a sbc hl,de pop de jr z,ChangeAccelSearchS inc d ChangeAccelSearchS: pop hl inc hl push de ChangeAccelSearchIn: push de ld b,3 call iRandom dec a ld b,(hl) add a,b cp -2 jr nz,ChangeAccelSearchIn1 inc a ChangeAccelSearchIn1: cp 2 jr nz,ChangeAccelSearchIn2 dec a ChangeAccelSearchIn2: ld (hl),a inc hl pop de dec d jr nz,ChangeAccelSearchIn pop af dec a jr nz,ChangeAccelSearchIn3 inc hl ChangeAccelSearchIn3: inc hl inc hl ld d,(hl) inc hl ld e,(hl) ld b,0 ld c,1 ld a,2 ld (WhoShot),a ld hl,Shot1D call GenerateNewShot pop bc pop hl ChangeAccelSearch1: ld de,EnemyElementLength add hl,de djnz ChangeAccelSearch ;Now it's time to generate shots NoFrameTick: ld a,(FrameTimer) and %00000011 or a jr nz,NoPowerupTick ld a,(Powerup_Power) or a jr z,PowerupCheckMulti dec a ld (Powerup_Power),a PowerupCheckMulti: ld a,(Powerup_Multi) or a jr z,PowerupCheckSpeed dec a ld (Powerup_Multi),a PowerupCheckSpeed: ld a,(Powerup_Speed) or a jr z,NoPowerupTick dec a ld (Powerup_Speed),a NoPowerupTick: #ifdef finaldebug call CheckError #endif ;STEP 1: Render Player ld hl,BlockScoreTime ld de,gbuf ld bc,768 ldir ld a,(CraftX) ld d,a ld a,(CraftY) ld e,a ld b,2 ld hl,SpritePlayer call ClipBigSprite ;STEP 2: Render Enemies ld hl,EnemyArray ld b,MaxEnemies ld de,EnemyElementLength EnemyDispLoop: ld a,(hl) or a jp z,EnemyDispLoopSkip push hl push de push bc inc hl ;@xaccel ld d,(hl) inc hl ;@yaccel ld e,(hl) inc hl ;@xvel ld c,(hl) ld a,(FrameTimer) and %00000001 jr z,EnemySkipMove ld a,c cp -32 jr nc,EnemyDispXVelInc cp 32 jr nc,EnemyDispNoXVelInc EnemyDispXVelInc: add a,d ld (hl),a ld c,a EnemyDispNoXVelInc: inc hl ;@yvel ld b,(hl) ld a,b cp -32 jr nc,EnemyDispNoYVelInc cp 32 jr nc,EnemyDispNoYVelInc EnemyDispYVelInc: add a,e ld (hl),a ld b,a EnemyDispNoYVelInc: bit 7,c jr z,EnemyDivideXVelPos ld a,c cpl inc a srl a srl a srl a srl a cpl inc a ld c,a jr EnemyDivideYVel EnemyDivideXVelPos: srl c srl c srl c srl c EnemyDivideYVel: bit 7,b jr z,EnemyDivideYVelPos ld a,b cpl inc a srl a srl a srl a srl a cpl inc a ld b,a jr EnemyDivideYVelC EnemyDivideYVelPos: srl b srl b srl b srl b EnemyDivideYVelC: inc hl ;@xpos ld a,(hl) add a,c ld (hl),a ld d,a ;offscreen check for X cp -6 jr nc,EnemyNoPosFixX cp 95 call nc,EnemyPosFixX EnemyNoPosFixX: inc hl ;@ypos ld a,(hl) add a,b ld (hl),a ld e,a ;offscreen check for Y cp -6 jr nc,EnemyNoPosFixY cp 63 call nc,EnemyPosFixY EnemyNoPosFixY: ;collision check time! jr EnemyNoSkipMove EnemySkipMove: inc hl inc hl ld d,(hl) inc hl ld e,(hl) EnemyNoSkipMove: ld b,1 inc hl ld a,(hl) inc hl ld h,(hl) ld l,a ld b,2 cp SpriteEnemy2 >> 8 jr nz,EnemyDispLoop2 inc b EnemyDispLoop2: call ClipBigSprite pop bc pop de pop hl EnemyDispLoopSkip: add hl,de dec b jp nz,EnemyDispLoop ;STEP 3: Render Shots #ifdef finaldebug call CheckError #endif ld hl,ShotArray ld b,MaxShots ld de,ShotElementLength ShotDispLoop: ld (SaveShot),hl ld a,(hl) ld (WhoShot),a or a jp z,ShotDispLoopSkip xor a ld (ClearedFlag),a push hl push de push bc inc hl ld c,(hl) inc hl ld b,(hl) inc hl ld a,(hl) add a,c ld (hl),a ld d,a ;offscreen check for X cp -7 jp nc,ShotDispCont1 cp 96 jp nc,ShotDisable ShotDispCont1: inc hl ld a,(hl) add a,b ld (hl),a ld e,a ;offscreen check for Y cp -7 jp nc,ShotDispCont2 cp 64 jp nc,ShotDisable ShotDispCont2: ;Inputs ;d = x ;e = y ;collision check time! push de push hl ld a,(WhoShot) dec a jp nz,ShotCollidePlayer ld hl,EnemyArray ld b,MaxEnemies ShotCollideLoop: push de push bc push hl ld a,(hl) or a jp z,ShotCollideLoop2 inc hl inc hl inc hl inc hl inc hl ld b,(hl) inc hl ld c,(hl) push hl push de inc hl ld a,(hl) inc hl ld h,(hl) ld l,a ld de,SpriteEnemy1 or a ;clear the carry flag sbc hl,de ;hl-de pop de pop hl jr nz,ShotCollideWidth1 ld a,10 jr ShotCollideWidth2 ShotCollideWidth1: ld a,14 ShotCollideWidth2: push de pop hl add a,b ld d,a ld a,8 add a,c ld e,a ld a,h cp b jp c,ShotCollideLoop2 cp d jp nc,ShotCollideLoop2 ld a,l cp c jp c,ShotCollideLoop2 cp e jp nc,ShotCollideLoop2 ld e,h ld hl,(SaveShot) ld (hl),0 ld a,(ClearedFlag) or a jr nz,ShotCollideSkipDouble ld hl,ShotsOnScreen dec (hl) ld a,1 ld (ClearedFlag),a ShotCollideSkipDouble: pop hl push hl ld a,(Powerup_Power) srl a srl a srl a srl a srl a inc a ld d,a ld a,(hl) sub d ld (hl),a or a jr z,ShotCollideEnemyDead bit 7,a jr z,ShotCollideLoop2 ShotCollideEnemyDead: xor a ld (hl),a ld a,(EnemiesOnScreen) dec a ld (EnemiesOnScreen),a push de ld hl,(TotalScore) ld a,(CurrentLevel) ld e,a ld d,0 add hl,de ld (TotalScore),hl pop de srl e srl e srl e ;e = e/8 ld d,0 ld hl,BlockArray+12*7 add hl,de push hl ld hl,SaveSScreen+12*(7*8) add hl,de pop de ex de,hl ld b,64/8 BlockAddLoop: ld a,(hl) or a jr z,BlockAddFound push de ld de,-12 add hl,de pop de push hl ld hl,-12*8 add hl,de ex de,hl pop hl djnz BlockAddLoop jr ShotCollideLoop2 ;this column is full BlockAddFound: ld a,(LevelStage) inc a ld (hl),a add a,a add a,a add a,a push de ld hl,Block0 ld e,a ld d,0 add hl,de pop de ld b,8 ex de,hl BlockAddPrecache: ld a,(de) ld (hl),a inc de push bc ld bc,12 add hl,bc pop bc djnz BlockAddPrecache ShotCollideLoop2: pop hl ld bc,9 add hl,bc pop bc pop de dec b jp nz,ShotCollideLoop jr ShotCollideDone ShotCollidePlayer: push de pop hl ;current position x,y ld a,(CraftX) ld b,a add a,8 ld d,a ld a,(CraftY) ld c,a add a,15 ld e,a ld a,h cp b jr c,ShotCollideDone cp d jr nc,ShotCollideDone ld a,l cp c jr c,ShotCollideDone cp e jr nc,ShotCollideDone ld a,2 ld (invertTimer),a ld hl,(SaveShot) ld (hl),0 ld hl,ShotsOnScreen dec (hl) ;ld b,2 ;ld d,80 ;ld e,8 ; ld hl,SavesScreen ; ld (_SpriteBuffer),hl ; ld hl,MinusTen ; call ClipBigSprite ; ld hl,PlotsScreen ; ld (_SpriteBuffer),hl ld a,(FrameTimeChange) sub 10 ld (FrameTimeChange),a call ReRenderBlocksAndText ld a,(TimeLeft) sub 10 ld (TimeLeft),a or a jr z,ShotCollideGameOver cp -10 jr c,ShotCollideDone ShotCollideGameOver: pop hl pop de pop hl pop hl pop hl jp GameOver ShotCollideDone: pop hl pop de ld b,1 inc hl ld a,(hl) inc hl ld h,(hl) ld l,a call ClipBigSprite pop bc pop de pop hl ShotDispLoopSkip: add hl,de dec b jp nz,ShotDispLoop jr MainShowGUI ShotDisable: pop bc pop de pop hl ld (hl),0 ld a,(ShotsOnScreen) dec a ld (ShotsOnScreen),a jr ShotDispLoopSkip ;STEP 4: Render GUI MainShowGUI: #ifdef finaldebug call CheckError #endif ld hl,gbuf+9*12 ld de,Powerup_Speed ld b,3 MainShowGUIBarLoop: ld a,(hl) or %00000010 ld (hl),a inc hl push hl push bc ld a,(de) push de srl a srl a srl a srl a ld de,$00 or a jr z,MainShowGUIBarLoop2 ld b,a MainShowGUIBarLoop1: scf rr d rr e djnz MainShowGUIBarLoop1 MainShowGUIBarLoop2: ld a,(hl) or d ld (hl),a inc hl ld a,(hl) or e ld (hl),a inc hl ld a,(hl) or %01000000 ld (hl),a pop de inc de pop bc pop hl push de ld de,11+12 add hl,de pop de djnz MainShowGUIBarLoop xor a ld (CheatMode),a ld a,(invertTimer) or a jr z,MainGUINoInvert dec a ld (invertTimer),a ld a,255 ld (CheatMode),a ld hl,gbuf ld bc,$300 InvertLoop: ld a,(hl) cpl ld (hl),a inc hl dec bc ld a,b or c jr nz,InvertLoop MainGUINoInvert: call iFastCopy KeyLoop: #ifdef finaldebug call CheckError #endif ld a,(EnemiesOnScreen) or a jp z,AddEnemies ld a,$ff out (1),a nop \ nop ld a,$fe out (1),a nop \ nop in a,(1) bit 0,a call z,KeyShipDown bit 1,a call z,KeyShipLeft bit 2,a call z,KeyShipRight bit 3,a call z,KeyShipUp ld a,$bf out (1),a nop \ nop in a,(1) cp $bf push af call z,Off pop af cp $df call z,PlayerShot ld a,$df out (1),a nop \ nop ld a,(AbsorbWait) or a jr nz,KeyLoopSkipAbsorb in a,(1) cp $7f call z,PlayerAbsorb KeyLoopSkipAbsorb: ld a,$fd out (1),a nop \ nop in a,(1) cp $bf jp nz,MainLoop ld b,64 ld hl,gbuf ld d,%10101010 PauseOuterLoop: in a,(1) inc a jr nz,PauseOuterLoop ld c,12 PauseInnerLoop: ld a,(hl) or d ld (hl),a inc hl dec c jr nz,PauseInnerLoop ld a,d cpl ld d,a djnz PauseOuterLoop ld hl,PausedSprite ld de,gbuf+12*23+3 ld c,18 PauseSpriteOuter: ld b,7 PauseSpriteInner: ld a,(hl) ld (de),a inc hl inc de djnz PauseSpriteInner inc de inc de inc de inc de inc de dec c jr nz,PauseSpriteOuter call iFastCopy PauseKey: call Pause cp $0F jp z,DispMainMenu cp $09 jp z,MainLoop jr PauseKey KeyShipDown: push af ld a,(CraftY) cp 59 jr z,KeyShipRet inc a inc a ld (CraftY),a jr KeyShipRet KeyShipLeft: push af ld a,(CraftX) cp -7 jr z,KeyShipRet dec a dec a ld (CraftX),a jr KeyShipRet KeyShipRight: push af ld a,(CraftX) cp 91 jr z,KeyShipRet inc a inc a ld (CraftX),a jr KeyShipRet KeyShipUp: push af ld a,(CraftY) cp -11 jr z,KeyShipRet dec a dec a ld (CraftY),a KeyShipRet: pop af ret PlayerShot: ld a,(Powerup_Speed) srl a ;2 srl a ;4 srl a ;8 srl a ;16 srl a ;32 srl a ;64 ld b,a ld c,%00001111 or a jr z,PlayerShot2 PlayerShot1: srl c djnz PlayerShot1 PlayerShot2: ld a,(FrameTimer) and c or a ret nz ld a,1 ld (WhoShot),a ld a,(CraftX) add a,3 ld d,a ld a,(CraftY) sub 6 ld e,a ld a,0 call ShotLevel ld b,0 ld c,-1 push de call GenerateNewShot pop de ld a,(Powerup_Multi) cp 85 ret c ld a,1 call ShotLevel ld b,-1 ld c,-1 push de call GenerateNewShot pop de ld a,2 call ShotLevel ld b,1 ld c,-1 push de call GenerateNewShot pop de ld a,(Powerup_Multi) cp 170 ret c ld a,3 call ShotLevel ld b,-1 ld c,0 push de call GenerateNewShot pop de ld a,4 call ShotLevel ld b,1 ld c,0 push de call GenerateNewShot pop de ret ShotLevel: push de ld hl,ShotMatrix add a,a ld e,a ld d,0 add hl,de ld de,0 ld a,(Powerup_Power) cp 85 jr c,ShotLevelGo ld de,10 cp 170 jr c,ShotLevelGo ld de,20 ShotLevelGo: add hl,de ld a,(hl) inc hl ld h,(hl) ld l,a pop de ret PushEnemyItem: ;inputs: ; a = ship type ; d - x ; e = y ld hl,SpriteEnemy2 dec a jr nz,PushEnemyItem2 ld hl,SpriteEnemy1 PushEnemyItem2: ld a,(EnemiesOnScreen) cp MaxEnemies ret z ;quit if maxenemies are already onscreen push bc push de push hl push de ld hl,EnemyArray ld de,9 GenerateNewEnemyFind: ld a,(hl) or a jr z,GenerateNewEnemyFound add hl,de jr GenerateNewEnemyFind GenerateNewEnemyFound: ld b,1 ld a,(CurrentLevel) GenerateNewEnemyHealth: cp 3 jr c,GenerateNewEnemyHealthDone sub 3 inc b jr GenerateNewEnemyHealth GenerateNewEnemyHealthDone: ld (hl),b inc hl push hl ld b,2 call iRandom dec a pop hl ld (hl),a ;xaccel inc hl xor a ld (hl),a ;yaccel inc hl xor a ld (hl),a ;xvel inc hl ld (hl),a ;yvel inc hl pop de ld (hl),d inc hl ld (hl),e inc hl pop de ld (hl),e inc hl ld (hl),d ld a,(EnemiesOnScreen) inc a ld (EnemiesOnScreen),a pop de pop bc ret GenerateNewShot: ;inputs: ; hl = sprite ptr ; b = x inc ; c = y inc ; d = x ; e = y ; (WhoShot) = who ld a,(ShotsOnScreen) cp MaxShots ret nc ;quit if maxshots are already onscreen push hl push de push bc ld hl,ShotArray ld de,7 ld b,MaxShots GenerateNewShotFind: ld a,(hl) or a jr z,GenerateNewShotFound add hl,de djnz GenerateNewShotFind ld a,MaxShots ld (ShotsOnScreen),a pop bc ret GenerateNewShotFound: pop bc ld a,(WhoShot) ld (hl),a inc hl ld (hl),b inc hl ld (hl),c inc hl pop de ld (hl),d inc hl ld (hl),e inc hl pop de ld (hl),e inc hl ld (hl),d ld a,(ShotsOnScreen) inc a ld (ShotsOnScreen),a ret EnemyPosFixX: ld d,-6 bit 7,a jr nz,EnemyPosFixX2 ld d,94 EnemyPosFixX2: ld a,d ld (hl),a push af dec hl ;@yvel dec hl ;@xvel ld c,(hl) xor a sub c ld (hl),a dec hl ;@yaccel dec hl ;@xaccel ld c,(hl) xor a sub c ld (hl),a inc hl inc hl inc hl inc hl pop af ret EnemyPosFixY: ld e,-6 bit 7,a jr nz,EnemyPosFixY2 ld e,62 EnemyPosFixY2: ld a,e ld (hl),a push af dec hl ;@xpos dec hl ;@yvel ld c,(hl) xor a sub c ld (hl),a dec hl ;@xvel dec hl ;@yaccel ld c,(hl) xor a sub c ld (hl),a inc hl inc hl inc hl inc hl pop af ret PlayerAbsorb: ld a,AbsorbWaitMagitude ld (AbsorbWait),a ld a,(CraftX) add a,5 bit 7,a ret nz cp 96 ret nc srl a srl a srl a ld (InitX),a ;initialize x ld a,(CraftY) add a,15 bit 7,a ret nz cp 64 ret nc srl a srl a srl a ld (InitY),a ;initialize y ld b,a ld a,(InitX) sla a sla a sla a sla a or b ld b,a ld c,0 ;bc is now the bitpacked block vector pointer ld a,(InitX) ld d,a ld a,(InitY) add a,a add a,a ld l,a add a,a add a,l ;a=a*12 add a,d ld h,0 ld l,a ld de,BlockArray add hl,de ld a,(hl) or a ret z ;bc is safe through this whole process ld (whichKind),a ld a,(Difficulty) or a jr z,BlockAbsorbSkipDiff push hl ld e,(hl) dec e ld d,0 ld hl,Powerup_Speed add hl,de ld a,(hl) pop hl or a ret nz BlockAbsorbSkipDiff: ld (hl),4 call BlockAbsorbRecurse ;start this whole process ld hl,BlockArray ld c,0 ld b,12*8 BlockCountLoop: ld a,(hl) cp 4 jr nz,BlockCountLoop2 inc c BlockCountLoop2: inc hl djnz BlockCountLoop ld a,c dec a jr nz,BlockContinueAbsorb ld a,(InitX) ld c,a ld a,(InitY) add a,a add a,a ld l,a add a,a add a,l ;a = a*12 add a,c ld l,a ld h,0 ld de,BlockArray add hl,de ld a,(whichKind) ld (hl),a ret BlockContinueAbsorb: ld a,(whichKind) dec a ld hl,Powerup_Speed ld e,a ld d,0 add hl,de ld a,(hl) srl a srl a srl a srl a add a,c add a,c ; PU = PU + 2*numblocks cp 16 jr c,BlockContinueAbsorb2 ld a,255 jr BlockContinueAbsorb3 BlockContinueAbsorb2: sla a sla a sla a sla a BlockContinueAbsorb3: ld (hl),a ld a,c add a,c ld c,a ld a,(FrameTimeChange) add a,c ld (FrameTimeChange),a ld a,(TimeLeft) push af ld b,a ld a,255 sub b cp c jr nc,BlockContinueAbsorb4 pop af ld a,255 sub c push af BlockContinueAbsorb4: pop af add a,c ld (TimeLeft),a BlockCollapseInit: ld hl,BlockArray+12*7 ld b,12 BlockCollapseOuter: push hl push bc BlockCollapseInnerInit: ld b,8 ;sourcecount ld c,b ;destcount push hl ;hl = source pop de ;de = dest BlockCollapseInner: ld a,b or a jr z,BlockCollapseInnerFinish1 ld a,(hl) or a jr z,BlockCollapseInnerInv cp 4 jr z,BlockCollapseInnerInv ld a,(hl) ld (de),a dec b dec c push de ld de,-12 add hl,de pop de push hl ld hl,-12 add hl,de ex de,hl pop hl jr BlockCollapseInner BlockCollapseInnerInv: dec b push de ld de,-12 add hl,de pop de jr BlockCollapseInner BlockCollapseInnerFinish1: ld a,c or a jr z,BlockCollapseInnerFinish dec c xor a ld (de),a ld hl,-12 add hl,de ex de,hl jr BlockCollapseInnerFinish1 BlockCollapseInnerFinish: pop bc pop hl inc hl djnz BlockCollapseOuter call ReRenderBlocksAndText BlockCollapseFinishDB: ld a,$ff out (1),a nop \ nop in a,(1) inc a jr nz,BlockCollapseFinishDB ret BlockAbsorbRecurse: ;first set up d and e from bc push bc ld a,b and %00001111 ld e,a ;unpack y pop bc ld a,b srl a srl a srl a srl a ld d,a ;unpack x push de ld a,c add a,a ld e,a ld d,0 ld hl,AbsorbOffsetTable add hl,de pop de ld a,(hl) add a,d ld d,a ;offset d cp 12 jr nc,BlockAbsorbRecurseOffscreen inc hl ld a,(hl) add a,e ld e,a ;offset e cp 8 jr nc,BlockAbsorbRecurseOffscreen ;don't insert anything here - a==e push bc add a,a ;a must == e for this to work properly!! add a,a ld l,a add a,a add a,l ;a=a*12 add a,d ld h,0 ld l,a ld bc,BlockArray add hl,bc ld b,(hl) ld a,(WhichKind) cp b jr nz,BlockAbsorbRecurse2 ld (hl),4 ;now we need to pack d, e into bc ld a,d sla a sla a sla a sla a or e ld b,a ld c,0 call BlockAbsorbRecurse BlockAbsorbRecurse2: pop bc BlockAbsorbRecurseOffscreen: inc c ld a,c cp 4 jr nz,BlockAbsorbRecurse ret AbsorbOffsetTable: .db 0,1 .db 1,0 .db 0,-1 .db -1,0 GameOver: bcall(_cleargbuf) ld b,19 ld c,5 ld a,27 ld l,3 ld ix,GameOverSprite call iLargeSprite set fracDrawLFont, (iy + fontFlags) set TextWrite,(iy+sgrFlags) ;Make text go to buffer ld hl,(25*256)+4 ld (pencol),hl ld hl,LevelTxt bcall(_vputs) ld hl,(34*256)+4 ld (pencol),hl ld hl,ScoreTxt bcall(_vputs) res fracDrawLFont, (iy + fontFlags) ld de,(41*256)+34 ld hl,(TotalScore) call WordtoDec ld de,(41*256)+25 ld a,(CurrentLevel) call BytetoDec res TextWrite,(iy+sgrFlags) ;Make text go to buffer call iFastCopy GameOverPause: call Pause cp $09 jr nz,GameOverPause ld de,(TotalScore) ld hl,HighScoreTableEasy push de ld de,HighScoreTableHard-HighScoreTableEasy ld a,(Difficulty) or a jr z,GameOverPauseEasy add hl,de GameOverPauseEasy: pop de ld b,5 GameOverCheckHS: inc hl inc hl inc hl ld a,(hl) inc hl push hl ld h,(hl) ld l,a bcall(_cphlde) pop hl inc hl inc hl jr c,GameOverSetHS djnz GameOverCheckHS jp HighScores GameOverSetHS: ;now it's time to push anything down if necessary dec hl dec hl dec hl dec hl dec hl dec hl push hl ld hl,HighScoreTableEasy+3*6 push de ld de,HighScoreTableHard-HighScoreTableEasy ld a,(Difficulty) or a jr z,GameOverShiftEasy add hl,de GameOverShiftEasy: pop de GameOverShiftLoop: dec b jr z,GameOverShiftLoopDone ld de,6 ld c,e GameOverShiftInner: push hl ld a,(hl) add hl,de ld (hl),a pop hl inc hl dec c jr nz,GameOverShiftInner push de ld de,-12 add hl,de pop de jr GameOverShiftLoop GameOverShiftLoopDone: set TextWrite,(iy+sgrFlags) ;Make text go to buffer ld de,(48*256)+37 ld (pencol),de ld hl,Initials bcall(_vputs) set fracDrawLFont, (iy + fontFlags) pop hl ld b,3 ;number of chars ld de,(55*256)+40 ld (pencol),de GameOverSetHSOuter: ld c,'A' ;the character GameOverSetHSInner: ld a,c ld de,(pencol) push de push bc push hl bcall(_vputmap) call ifastcopy bcall(_getk) pop hl pop bc pop de ld (pencol),de cp $01 jr nz,GameOverSetHSInner2 ld a,c cp $20 jr z,GameOverSetHSInner dec c jr GameOverSetHSInner GameOverSetHSInner2: cp $04 jr nz,GameOverSetHSInner3 ld a,c cp $B5 jr z,GameOverSetHSInner inc c jr GameOverSetHSInner GameOverSetHSInner3: cp $09 jr nz,GameOverSetHSInner ld (hl),c inc hl ld a,(pencol) add a,6 ld (pencol),a djnz GameOverSetHSOuter ld de,(TotalScore) ld (hl),e inc hl ld (hl),d inc hl ld a,(CurrentLevel) ld (hl),a res fracDrawLFont, (iy + fontFlags) res TextWrite,(iy+sgrFlags) ;Make text go to buffer HighScores: ld b,64 HSDebounce: ;ld a,$ff ;out (1),a nop \ nop in a,(1) inc a jr nz,HSDebounce djnz HSDebounce ld a,(Difficulty) ld (HighScoreType),a HSDispReloop: bcall(_cleargbuf) ld de,gbuf+24 ld hl,HighScoresSprite ld bc,12*9 ldir set TextWrite,(iy+sgrFlags) ;Make text go to buffer ld a,$cf ld de,(12*256)+2 ld (pencol),de bcall(_vputmap) ld a,$05 ld de,(12*256)+89 ld (pencol),de bcall(_vputmap) ld a,40 ld (pencol),a ld a,(HighScoreType) ld hl,EasyTxt or a jr z,HSDispInnerEasy ld hl,HardTxt HSDispInnerEasy: bcall(_vputs) set fracDrawLFont, (iy + fontFlags) ld b,5 ld hl,HighScoreTableEasy ld a,(HighScoreType) or a jr z,HSDispSkipHard ld hl,HighScoreTableHard HSDispSkipHard: ld a,20 ld (penrow),a HighScoreOuter: ld a,2 ld (pencol),a ld c,3 HighScoreInner: ld a,(hl) push hl push bc bcall(_vputmap) pop bc pop hl inc hl ld a,(pencol) add a,3 ld (pencol),a dec c jr nz,HighScoreInner inc a inc a ld d,a ld a,(penrow) ld e,a push bc push hl ld a,(hl) inc hl ld h,(hl) ld l,a call WordToDec pop hl inc hl inc hl push hl ld a,(penrow) ld e,a ld d,67 ld a,(hl) call ByteToDec pop hl inc hl ld a,(penrow) add a,8 ld (penrow),a pop bc djnz HighScoreOuter call iFastCopy res TextWrite,(iy+sgrFlags) ;Make text go to buffer res fracDrawLFont, (iy + fontFlags) ld b,32 HSClearKeys: push bc bcall(_getk) pop bc or a jr nz,HSClearKeys djnz HSClearKeys call Pause cp $09 jp z,DispMainMenu ld a,(HighScoreType) ld b,a ld a,1 sub b ld (HighScoreType),a jp HSDispReloop ShowHelp: in a,(1) inc a jr nz,ShowHelp ;debouncing loop bcall(_cleargbuf) set TextWrite,(iy+sgrFlags) ;Make text go to buffer ld ix,HelpSprite ld bc,(9*256)+5 ld a,31 ld l,1 call iLargeSprite ld b,2 ld de,(15*256)+11 ld hl,SpritePlayer call ClipBigSprite ld b,2 ld de,(55*256)+18 ld hl,SpriteEnemy1 call ClipBigSprite ld b,3 ld de,(70*256)+17 ld hl,SpriteEnemy2 call ClipBigSprite ld b,8 ld a,23 ld l,36 ld ix,Block1 call iPutSprite ld b,8 ld a,23 ld l,45 ld ix,Block2 call iPutSprite ld b,8 ld a,23 ld l,54 ld ix,Block3 call iPutSprite ld de,(26*256)+6 ld (pencol),de ld hl,HelpTxt1 bcall(_vputs) ld de,(26*256)+58 ld (pencol),de ; ld hl,HelpTxt2 bcall(_vputs) ld de,(36*256)+32 ld (pencol),de ; ld hl,HelpTxt3 bcall(_vputs) ld de,(45*256)+32 ld (pencol),de ; ld hl,HelpTxt4 bcall(_vputs) ld de,(54*256)+32 ld (pencol),de ; ld hl,HelpTxt5 bcall(_vputs) ld de,(57*256)+87 ld (pencol),de ; ld hl,HelpTxt6 bcall(_vputs) call iFastCopy call Pause ShowHelp2: in a,(1) inc a jr nz,ShowHelp2 bcall(_cleargbuf) ld ix,HelpSprite ld bc,(9*256)+5 ld a,31 ld l,1 call iLargeSprite ld de,(11*256)+1 ld (pencol),de ld hl,HelpTxt7 bcall(_vputs) ld de,(17*256)+1 ld (pencol),de bcall(_vputs) ld de,(23*256)+6 ld (pencol),de bcall(_vputs) ld de,(29*256)+1 ld (pencol),de bcall(_vputs) ld de,(35*256)+1 ld (pencol),de bcall(_vputs) ld de,(43*256)+1 ld (pencol),de bcall(_vputs) ld de,(49*256)+1 ld (pencol),de bcall(_vputs) ld de,(55*256)+1 ld (pencol),de bcall(_vputs) ld de,(57*256)+87 ld (pencol),de ld hl,HelpTxt6 bcall(_vputs) call iFastCopy call Pause res TextWrite,(iy+sgrFlags) ;Make text go to buffer ShowHelp3: in a,(1) inc a jr nz,ShowHelp3 jp DispMainMenu #ifdef finaldebug CheckError: push hl push de push bc ld hl,ShotArray ld de,7 ld b,MaxShots ld c,0 CEFind: ld a,(hl) or a jr z,CEFind2 inc c CEFind2: add hl,de djnz CEFind ld a,(ShotsOnScreen) cp c pop bc pop de pop hl ret z CEFreeze: jr CEFreeze #endif EasyTxt: .db "EASY",0 HardTxt: .db "HARD",0 LevelTxt: .db "Level:",0 ScoreTxt: .db "Score:",0 HelpTxt1: .db "Your ship",0 .db "Enemies",0 .db "Rapid shot",0 .db "Multi shot",0 .db "Power shot",0 HelpTxt6: .db ">>",0 HelpTxt7: .db $c1,"2nd]=Shoot enemies",0 .db $c1,"ALPHA]=Absorb groups of 2+",0 .db "blocks to gain powerups",0 .db $c1,"Arrows]=Move your ship",0 .db $c1,"CLEAR]=Pause/quit",0 .db "More at www.cemetech.net",0 .db "Based on the PC game by",0 .db "Josh Szepietowski",0 Initials: .db "Initials:",0 MenuStrings: .db " PLAY " .db $cf,"EASY",$05 .db $cf,"HARD",$05 .db " HELP " .db "SCORES" .db " QUIT " GameOverSprite: ;40 x 19 .db $3F,$1E,$30,$6F,$E0,$7F,$3F,$38,$EF,$E0,$E0,$73,$BD,$EC,$00,$C0 .db $61,$B7,$6F,$80,$C3,$61,$B2,$6F,$80,$C3,$7F,$B0,$6C,$00,$E3,$7F .db $B0,$6C,$00,$7F,$61,$B0,$6F,$E0,$3F,$61,$B0,$6F,$E0,$00,$00,$00 .db $00,$00,$3E,$30,$DF,$DF,$80,$7F,$30,$DF,$DF,$C0,$E3,$B0,$D8,$18 .db $E0,$C1,$B0,$DF,$18,$E0,$C1,$B0,$DF,$1F,$C0,$C1,$B0,$D8,$1F,$80 .db $E3,$B9,$D8,$19,$C0,$7F,$1F,$9F,$D8,$E0,$3E,$0F,$1F,$D8,$60 HighScoresSprite: ;96x9 .db $18,$6C,$7E,$C3,$00,$7F,$1F,$8F,$1F,$8F,$E7,$F0,$18,$6C,$FE,$C3 .db $00,$FF,$3F,$9F,$9F,$CF,$EF,$F0,$18,$6D,$C0,$C3,$00,$C0,$70,$39 .db $D8,$EC,$0C,$00,$18,$6D,$80,$C3,$00,$FE,$60,$30,$D8,$EF,$8F,$E0 .db $1F,$ED,$86,$FF,$00,$7F,$60,$30,$DF,$CF,$87,$F0,$1F,$ED,$86,$FF .db $00,$03,$60,$30,$DF,$8C,$00,$30,$18,$6D,$C6,$C3,$00,$03,$70,$39 .db $D9,$CC,$00,$30,$18,$6C,$FE,$C3,$00,$FF,$3F,$9F,$98,$EF,$EF,$F0 .db $18,$6C,$7E,$C3,$00,$FE,$1F,$8F,$18,$6F,$EF,$E0 PausedSprite: ;56x18 .db $00,$00,$00,$00,$00,$00,$00,$3F,$07,$8C,$33,$FB,$FB,$F0,$3F,$8F .db $CC,$37,$FB,$FB,$F8,$31,$DC,$EC,$36,$03,$03,$1C,$31,$D8,$6C,$37 .db $F3,$E3,$0C,$3F,$98,$6C,$33,$FB,$E3,$0C,$3F,$1F,$EC,$30,$1B,$03 .db $0C,$30,$1F,$EC,$30,$1B,$03,$1C,$30,$18,$6F,$F7,$FB,$FB,$F8,$30 .db $18,$67,$E7,$F3,$FB,$F0,$00,$00,$00,$00,$00,$00,$00,$30,$00,$01 .db $8B,$00,$00,$18,$2E,$CE,$EC,$8A,$68,$E4,$C8,$2C,$A4,$CA,$92,$88 .db $CA,$A8,$28,$A4,$8C,$92,$88,$8E,$C8,$2E,$A4,$EA,$A2,$6E,$EA,$A8 .db $30,$00,$01,$A3,$00,$00,$18,$00,$00,$00,$00,$00,$00,$00 HelpSprite: .db $C3,$7F,$60,$7E,$00,$C3,$7F,$60,$7F,$00,$C3,$60,$60,$63,$80,$C3 .db $7C,$60,$63,$80,$FF,$7C,$60,$7F,$00,$FF,$60,$60,$7E,$00,$C3,$60 .db $60,$60,$00,$C3,$7F,$7F,$60,$00,$C3,$7F,$7F,$60,$00 ShotMatrix: .dw Shot1U,Shot1UL,Shot1UR,Shot1L,Shot1R .dw Shot2U,Shot2UL,Shot2UR,Shot2L,Shot2R .dw Shot3U,Shot3UL,Shot3UR,Shot3L,Shot3R Shot1D: .db 7 .db $00,$8F,$20,$07,$50,$07,$20,$07,$20,$8F,$20,$8F,$00,$8F Shot1U: .db 7 .db $00,$8F,$20,$8F,$20,$8F,$20,$07,$50,$07,$20,$07,$00,$8F Shot1UL: .db 7 .db $00,$1F,$40,$0F,$20,$03,$18,$81,$14,$C1,$0C,$C1,$00,$E1 Shot1UR: .db 7 .db $00,$F1,$04,$E1,$08,$81,$30,$03,$50,$07,$60,$07,$00,$0F Shot1L: .db 5 .db $00,$E1,$0C,$00,$72,$00,$0C,$00,$00,$E1 Shot1R: .db 5 .db $00,$87,$30,$00,$4E,$00,$30,$00,$00,$87 Shot2U: .db 8 .db $20,$8F,$20,$8F,$20,$8F,$20,$07,$50,$07,$D8,$03,$70,$03 Shot2UL: .db 8 .db $80,$1F,$40,$0F,$20,$03,$18,$80,$17,$C0,$0A,$C0,$0E,$E0,$09,$E0 Shot2UR: .db 8 .db $01,$F8,$02,$F0,$04,$C0,$18,$01,$E8,$03,$50,$03,$70,$07,$90,$07 Shot2L: .db 7 .db $00,$F8,$02,$E0,$0F,$00,$F1,$00,$0F,$00,$02,$E0,$00,$F8 Shot2R: .db 7 .db $00,$1F,$40,$07,$F0,$00,$8F,$00,$F0,$00,$40,$07,$00,$1F Shot3U: .db 8 .db $20,$07,$50,$07,$50,$07,$50,$03,$88,$03,$88,$03,$50,$03,$20,$07 Shot3UL: .db 8 .db $80,$0F,$60,$03,$58,$01,$24,$00,$23,$80,$12,$80,$0D,$C0,$0B,$E0 Shot3UR: .db 8 .db $01,$F0,$06,$C0,$1A,$80,$24,$00,$C4,$01,$48,$01,$B0,$03,$D0,$07 Shot3L: .db 7 .db $00,$E1,$0C,$00,$72,$00,$81,$00,$72,$00,$0C,$00,$00,$E1 Shot3R: .db 7 .db $00,$87,$30,$00,$4E,$00,$81,$00,$4E,$00,$30,$00,$00,$87 SpriteEnemy1: .db 8 .db $00,$C4,$11,$80,$2A,$00,$7F,$00,$7F,$00,$6A,$00,$40,$00,$00,$1F .db 8 .db $00,$7F,$00,$3F,$80,$1F,$C0,$1F,$C0,$1F,$C0,$1F,$40,$1F,$00,$1F SpriteEnemy2: .db 9 .db $00,$FC,$01,$E0,$0B,$C0,$1C,$80,$22,$00,$7F,$00,$39,$00,$10,$80,$00,$C6 .db 9 .db $00,$1F,$C0,$03,$E8,$01,$1C,$00,$22,$00,$FF,$00,$CE,$00,$84,$00,$00,$31 .db 9 .db $00,$FF,$00,$FF,$00,$FF,$00,$FF,$00,$7F,$00,$7F,$00,$7F,$00,$FF,$00,$FF SpritePlayer: .db 16 .db $00,$F1,$04,$F1,$04,$F1,$04,$E0,$0E,$E0,$0E,$E0,$0E,$C0,$1F,$C0 .db $1B,$C0,$1B,$80,$31,$80,$24,$00,$4E,$00,$5F,$00,$71,$00,$00,$04 .db 16 .db $00,$FF,$00,$FF,$00,$FF,$00,$FF,$00,$FF,$00,$FF,$00,$7F,$00,$7F .db $00,$7F,$00,$3F,$80,$3F,$80,$1F,$40,$1F,$40,$1F,$C0,$1F,$00,$1F Titlescreen: .db $FF,$FF,$FF,$FF,$FF,$9F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF .db $FF,$20,$00,$00,$00,$00,$00,$01,$FF,$FF,$FF,$FF,$FE,$46,$FC,$61 .db $8F,$18,$1B,$E1,$FF,$FF,$FF,$FF,$FC,$86,$FE,$61,$9F,$98,$1B,$F1 .db $FF,$FF,$BF,$FF,$E1,$06,$C7,$61,$B9,$D8,$1B,$39,$FF,$FF,$BF,$FF .db $CE,$06,$C3,$61,$B0,$D8,$1B,$19,$FF,$FE,$AF,$FF,$90,$06,$C3,$61 .db $B0,$D8,$1B,$19,$FF,$FF,$BF,$F8,$20,$06,$C3,$61,$BF,$D8,$1B,$19 .db $FF,$FF,$BF,$F3,$C0,$06,$C3,$73,$BF,$D8,$1B,$39,$FF,$FE,$AF,$E4 .db $00,$06,$C3,$3F,$30,$DF,$DB,$F1,$FF,$FC,$A7,$C8,$00,$06,$C3,$1E .db $30,$DF,$DB,$E1,$FF,$FE,$AF,$90,$00,$00,$00,$00,$00,$00,$00,$01 .db $FF,$FF,$BF,$A3,$FC,$78,$FC,$1F,$BF,$07,$8C,$19,$FF,$FD,$17,$A3 .db $FC,$FC,$FE,$3F,$BF,$8F,$CE,$39,$FF,$F9,$13,$A0,$61,$CE,$C7,$70 .db $31,$DC,$EF,$79,$FF,$FD,$17,$A0,$61,$86,$C3,$60,$31,$D8,$6D,$D9 .db $FF,$FF,$1F,$A0,$61,$86,$C3,$61,$BF,$98,$6C,$99,$FF,$FD,$17,$A0 .db $61,$FE,$C3,$61,$BF,$1F,$EC,$19,$FF,$F9,$13,$A0,$61,$FE,$C3,$71 .db $B3,$9F,$EC,$19,$FF,$FD,$17,$A0,$61,$86,$C3,$3F,$B1,$D8,$6C,$19 .db $FF,$FF,$1F,$90,$61,$86,$C3,$1F,$B0,$D8,$6C,$19,$FF,$FA,$0B,$C8 .db $00,$00,$00,$00,$00,$00,$00,$01,$FF,$F2,$09,$E4,$00,$00,$00,$00 .db $00,$00,$00,$01,$FF,$FA,$0B,$F3,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FD .db $FF,$FE,$0F,$F8,$00,$00,$00,$00,$00,$00,$00,$01,$FF,$FA,$0B,$FF .db $E4,$FF,$FF,$FF,$FF,$FF,$FF,$FD,$FF,$F2,$09,$FF,$F1,$00,$00,$00 .db $00,$00,$00,$05,$FF,$FA,$0B,$FF,$FA,$12,$00,$01,$10,$04,$80,$05 .db $FF,$FE,$0F,$FF,$FA,$14,$4A,$D1,$B3,$56,$1B,$05,$FF,$FC,$07,$FF .db $FA,$18,$AC,$A9,$55,$64,$AA,$85,$FF,$F4,$05,$FF,$FA,$14,$C8,$A9 .db $15,$44,$AA,$85,$FF,$E4,$04,$FF,$FA,$12,$68,$A9,$13,$42,$9A,$85 .db $FF,$F4,$05,$FF,$FA,$00,$00,$00,$00,$00,$00,$05,$FF,$FC,$07,$FF .db $FA,$00,$00,$00,$00,$00,$00,$05,$FF,$F4,$05,$FF,$FA,$00,$00,$00 .db $00,$00,$00,$05,$FF,$E4,$04,$FF,$FA,$00,$00,$00,$00,$00,$00,$05 .db $FE,$F4,$05,$EF,$F9,$00,$00,$00,$38,$00,$00,$05,$FE,$F8,$03,$EF .db $FC,$80,$00,$00,$FE,$00,$00,$05,$FC,$E8,$02,$E7,$FE,$40,$00,$03 .db $FF,$80,$00,$05,$FC,$C8,$02,$67,$FF,$2F,$80,$00,$00,$00,$01,$F5 .db $F8,$E8,$02,$E3,$FF,$A8,$95,$55,$55,$55,$55,$15,$D8,$F8,$03,$E3 .db $7F,$BB,$80,$00,$00,$00,$01,$DD,$CC,$88,$02,$26,$7F,$82,$00,$00 .db $00,$00,$00,$41,$C6,$88,$02,$2C,$7F,$BA,$00,$00,$00,$00,$00,$5D .db $C3,$88,$02,$38,$7F,$AA,$00,$00,$00,$00,$00,$55,$FF,$90,$01,$3F .db $FF,$AA,$00,$00,$00,$00,$00,$55,$F9,$10,$01,$13,$FF,$AA,$00,$00 .db $00,$00,$00,$55,$F9,$10,$01,$13,$FF,$AA,$00,$00,$00,$00,$00,$55 .db $F9,$FF,$FF,$F3,$FF,$BA,$00,$00,$00,$00,$00,$5D,$FF,$2F,$FE,$9F .db $FF,$82,$00,$00,$00,$00,$00,$41,$FC,$4C,$E6,$47,$FF,$BB,$80,$00 .db $00,$00,$01,$DD,$FA,$8D,$B6,$2B,$FF,$A8,$95,$55,$55,$55,$55,$15 .db $F9,$0F,$1E,$13,$FF,$2F,$80,$00,$00,$00,$01,$F5,$FF,$8D,$B6,$3F .db $FE,$40,$00,$03,$FF,$80,$00,$05,$FF,$4C,$E6,$5F,$FC,$80,$00,$00 .db $FE,$00,$00,$05,$FF,$2F,$FE,$9F,$FD,$00,$00,$00,$38,$00,$00,$05 .db $FF,$FF,$FF,$FF,$FD,$00,$00,$00,$00,$00,$00,$05,$FF,$F8,$03,$FF .db $FD,$07,$00,$01,$00,$20,$00,$85,$FF,$FE,$0F,$FF,$FD,$08,$26,$89 .db $91,$B0,$C4,$C5,$FF,$F9,$B3,$FF,$FD,$08,$55,$55,$2A,$28,$AA,$85 .db $FF,$FD,$F7,$FF,$FD,$08,$65,$59,$32,$28,$AC,$85,$FF,$FF,$FF,$FF .db $FD,$07,$34,$4C,$99,$AA,$A6,$45,$FF,$FF,$FF,$FF,$FD,$00,$00,$00 .db $00,$00,$00,$05,$FF,$FF,$FF,$FF,$FD,$00,$00,$00,$00,$00,$00,$05 SmFontDigit0: .db 6 .db $00,$03,$78,$03,$48,$03,$58,$03,$78,$03,$00,$03 SmFontDigit1: .db 6 .db $00,$03,$60,$03,$20,$03,$60,$03,$70,$03,$00,$03 SmFontDigit2: .db 6 .db $00,$03,$70,$03,$08,$03,$30,$03,$78,$03,$00,$03 SmFontDigit3: .db 6 .db $00,$03,$78,$03,$38,$03,$18,$03,$78,$03,$00,$03 SmFontDigit4: .db 6 .db $00,$03,$48,$03,$48,$03,$78,$03,$08,$03,$00,$03 SmFontDigit5: .db 6 .db $00,$03,$78,$03,$70,$03,$18,$03,$70,$03,$00,$03 SmFontDigit6: .db 6 .db $00,$03,$40,$03,$78,$03,$58,$03,$78,$03,$00,$03 SmFontDigit7: .db 6 .db $00,$03,$78,$03,$08,$03,$18,$03,$18,$03,$00,$03 SmFontDigit8: .db 6 .db $00,$03,$78,$03,$78,$03,$58,$03,$78,$03,$00,$03 SmFontDigit9: .db 6 .db $00,$03,$78,$03,$48,$03,$78,$03,$18,$03,$00,$03 SmFontNegSign: .db 5 .db $00,$07,$00,$07,$70,$07,$00,$07,$00,$07 SmFontPosSign: .db 5 .db $00,$07,$20,$07,$70,$07,$20,$07,$00,$07 FontDigit0: .db 7 .db $00,$03,$78,$03,$48,$03,$58,$03,$58,$03,$78,$03,$00,$03 FontDigit1: .db 7 .db $00,$0F,$60,$0F,$20,$0F,$20,$0F,$60,$07,$70,$07,$00,$07 FontDigit2: .db 7 .db $00,$03,$78,$03,$08,$03,$78,$03,$60,$03,$78,$03,$00,$03 FontDigit3: .db 7 .db $00,$03,$78,$03,$08,$03,$38,$83,$18,$03,$78,$03,$00,$03 FontDigit4: .db 7 .db $00,$03,$48,$03,$48,$03,$78,$03,$18,$03,$18,$43,$00,$43 FontDigit5: .db 7 .db $00,$03,$78,$03,$40,$03,$78,$03,$18,$03,$78,$03,$00,$03 FontDigit6: .db 7 .db $00,$03,$78,$03,$40,$03,$78,$03,$58,$03,$78,$03,$00,$03 FontDigit7: .db 7 .db $00,$03,$78,$03,$08,$03,$18,$43,$18,$43,$18,$43,$00,$43 FontDigit8: .db 7 .db $00,$03,$78,$03,$48,$03,$78,$03,$58,$03,$78,$03,$00,$03 FontDigit9: .db 7 .db $00,$03,$78,$03,$48,$03,$78,$03,$18,$03,$18,$43,$00,$43 ;MinusTen: ; .db 6 ; .db $00,$F0,$05,$00,$65,$00,$0D,$00,$0D,$E0,$00,$E0 ; .db 6 ; .db $00,$0F,$E0,$0F,$20,$0F,$60,$0F,$E0,$0F,$00,$0F Block0: .db $00,$00,$00,$00,$00,$00,$00,$00 Block1: .db $FF,$81,$BD,$BD,$BD,$BD,$81,$FF Block2: .db $FF,$83,$A1,$89,$83,$A1,$89,$FF Block3: .db $FF,$AB,$D5,$AB,$D5,$AB,$D5,$FF HighScoreTableEasy: .db "CRM",50,0,10 .db "CEM",40,0,8 .db "ETE",30,0,6 .db "CH.",20,0,4 .db "NET",10,0,2 HighScoreTableHard: .db "KER",40,0,5 .db "MMA",30,0,4 .db "RTI",20,0,3 .db "AN.",10,0,2 .db "ROX",5,0,1 Difficulty: .db 0 ;0=easy, 1=hard #include tbdsrp_m.inc ClipBigSprite: ;d = x ;e = y ;hl = sprite ;(hl) = height ;b = width (in bytes) push bc push de push hl ld a,d cp 96 jr c,ClipBigSpriteGo cp -7 ccf ClipBigSpriteGo: call c,ClipSprite_MASK pop hl ld a,(hl) add a,a ld e,a ld d,0 add hl,de inc hl pop de pop bc ld a,8 add a,d ld d,a cp 96 ret nc djnz ClipBigSprite ret WordToDec: ;hl = number ;d,e = x,y ld bc,-10000 call Num1 ld bc,-1000 call Num1 ld bc,-100 call Num1 ld bc,-10 call Num1 ld bc,-1 jr Num1 ByteToDec: ;a = number ;d,e = x,y ld h,0 ld l,a ld bc,-100 call Num1 ld bc,-10 call Num1 ld bc,-1 Num1: ld a,-1 Num2: inc a add hl,bc jr c,Num2 sbc hl,bc push hl push de ld l,a add a,a ld b,a add a,a ld c,a add a,a add a,c add a,b add a,l ld c,a ld b,0 ld hl,FontDigit0 add hl,bc ld b,1 call ClipBigSprite pop de pop hl ld a,d add a,5 ld d,a ret ByteToDecSigned: ;a = number ;d,e = x,y push de push af bit 7,a jr nz,ByteToDecSignedNeg ByteToDecSignedPos: ld hl,SmFontPosSign jr ByteToDecContinue ByteToDecSignedNeg: pop af cpl inc a push af ld hl,SmFontNegSign ByteToDecContinue: ld b,1 call ClipBigSprite pop af pop de ld h,0 ld l,a ld a,d add a,4 ld d,a ld bc,-100 call Num12 ld bc,-10 call Num12 ld bc,-1 Num12: ld a,-1 Num22: inc a add hl,bc jr c,Num22 sbc hl,bc push hl push de ld l,a add a,a add a,a ld c,a add a,a add a,c add a,l ld c,a ld b,0 ld hl,SmFontDigit0 add hl,bc ld b,1 call ClipBigSprite pop de pop hl ld a,d add a,5 ld d,a ret ReRenderBlocksAndText: ld hl,SaveSScreen ld de,BlockArray ld b,64/8 BlockRenderOuter: ld c,96/8 BlockRenderInner: push bc push de push hl ld a,(de) add a,a add a,a add a,a push hl ld de,Block0 ld h,0 ld l,a add hl,de pop de ld b,8 ;from hl to de BlockRenderCopyLoop: ld a,(hl) ld (de),a inc hl push hl ld hl,12 add hl,de ex de,hl pop hl djnz BlockRenderCopyLoop pop hl pop de pop bc inc de inc hl dec c jr nz,BlockRenderInner push de ld de,7*12 add hl,de pop de djnz BlockRenderOuter ld hl,SaveSScreen ld (_SpriteBuffer),hl #ifdef showtimeleft ld de,(1*256)+1 ld hl,(TotalScore) call WordtoDec ld de,(80*256)+1 ld a,(TimeLeft) call BytetoDec ld de,(76*256)+8 ld a,(FrameTimeChange) or a call nz,BytetoDecSigned #endif ld hl,PlotsScreen ld (_SpriteBuffer),hl ret Off: ld a,2 out ($10),a ;turn off screen res OnInterrupt,(iy+OnFlags) res curAble,(iy+curFlags) call debounceon im 1 eI ; disable interrupts ld a,1 out (3),a halt di res OnInterrupt,(iy+OnFlags) ld a,3 out ($10),a ;turn on screen call debounceon ret debounceon: in a,(4) bit 3,a jr z,debounceon ret Pause: bcall(_getk) or a jr z,Pause ret CheatMode: .db 0 .end END