catto@vivaldi.ecn.purdue.edu (Erin S Catto) (05/31/91)
Below is the new and improved source for Joust v2.1. Changes are minor. However the comments are improved (more). This source may be compiled on Chipper assembler. -Zoom catto@ecn.purdue.edu ======================================================================== ;-------------- ;Register Usage ;-------------- ; ;V0 = Sprite X coordinate (player, crows and eggs) ;V1 = Sprite Y coordinate ;V2 = Sprite X delta ;V3 = Sprite Y delta ;V4 = Current right/left flag (moves pointer) ;V5 = Old right/left flag ;V6 = Player's X coordinate, for collision checking, player dead flag ;V7 = Player's Y coordinate, for collision checking ;V8 = Mode of play flag ;V9 = # players left ;VA = Sprite scope flag ;VB = # crows, by level ;VC = level ;VD = scratch ;VE = scratch ;VF = collision, greater/less than flag ; ;Many items are stored, see bottom of source code ;Constants ;--------- SCOREDELTA = 1 SPRTHEIGHT = 8 ;height of sprite (player/crow) SPRTWIDTH = 8 ;width of sprite NONE = 0 ;Sprite scoping values (VA) ONECROW = 1 TWOCROWS = 2 ONECROW1EGG = 3 TWOEGGS = 4 ONEEGG = 5 GUYDEAD = #DD ;flag, V6 MODE1 = 0 ;levels 1-3 (slow) MODE2 = 1 ;levels 4-7 (faster with lava) MODE3 = 2 ;levels 8-99 (fastest with lava) KEYUP = #A KEYRGT = #C KEYLFT = 3 PAD1TOP = 28 ;geometry of islands PAD1BOT = 32 PAD1RGT = 16 ;---------------------------- PAD1LFT = 112 ; | ; ----2---- | PAD2TOP = 16 ; | PAD2BOT = 20 ; | PAD2RGT = 80 ;--1-- --1--| PAD2LFT = 48 ; | ; | PAD3TOP = 40 ; ----3---- | PAD3BOT = 44 ; | PAD3RGT = 80 ;---------------------------- PAD3LFT = 48 ROOF = 0 FLOOR = 60 BONUSLIMIT = 106 ;bonus round time limit JP BRAG DA 'Joust2 by Zoom' BRAG: DW #00FF ;turn on extended CALL NAME ;title screen ;This routine initializes registers and the score ;------------------------------------------------ REPLAY: LD V0, 0 ;zero score storage LD I, SCORE LD [I], V0 LD V8, MODE1 LD V9, 3 ;three players LD VC, 0 ;This routine sets # of buzzards (crows), conducts level intro -------------------------------------------------------------- NEWLEVEL: LD VD, 15 CALL DELAY CLS LD VA, TWOCROWS ADD VC, 1 LD VD, 7 SUB VD, VC SNE VF, 0 ;7 - n < 0 -> vf=0 JP STALL ;past level 8 freeze #crows SNE VC, 4 LD V8, MODE2 LD VB, VC ;levels 1-6, #crows=level + 1 ADD VB, 1 RSTALL: CALL RAY1 ;draw rays LD VE, 27 ;y coordinate of level number LD VD, 9 SUB VD, VC SNE VF, 0 ;check if level > 9 JP TWODIGIT ;draw two digit level DW #FC30 ;10 byte font for VD LD VD, 60 DRW VD, VE, 10 CALL RAY2 ;erase rays JP RESUME STALL: LD VB, 8 ;past level 7, #crows=8 LD V8, MODE3 ;fast mode JP RSTALL TWODIGIT: LD I, LEVEL ;two digit level number LD B, VC ;load bcd of vc into LEVEL data space LD V2, [I] ;read back bcd LD VD, 55 DW #F130 DRW VD, VE, 10 LD VD, 65 DW #F230 DRW VD, VE, 10 CALL RAY2 JP RESUME ;RESUME initializes sprites and screen or goes to bonus round ;------------------------------------------------------------ RESUME: LD VD, 7 AND VD, VC SNE VD, 7 ;every 7 levels is the bonus round JP BONUS CALL SCREEN CALL INITGUY CALL INITCROW1 SE VB, 0 ;sometimes only one crow left CALL INITCROW2 LD VD, 15 ;delay argument CALL DELAY ;MAIN is the game loop ---------------------- MAIN: CALL MOVEGUY SNE V6, GUYDEAD JP DIE SNE VA, NONE JP NEWLEVEL CALL MOVEOTHERS ;handles all non-player sprites SE V8, MODE1 CALL WAVE LD VD, 5 SNE V8, MODE1 CALL DELAY LD VD, 3 SNE V8, MODE2 CALL DELAY JP MAIN ;DELAY is a subroutine which takes VD (scratch) as an argument ;------------------------------------------------------------- DELAY: LD DT, VD DLP: LD VD, DT SE VD, 0 JP DLP RET ;MOVEGUY polls keyboard and sets up player motion ;------------------------------------------------- MOVEGUY: LD I, GUYSAVE ;retrieve player registers LD V5, [I] CALL GODOWN LD V2, 0 ;start with delta x = 0 LD VD, KEYUP SKNP VD CALL GOUP LD VD, KEYLFT SKNP VD CALL GOLEFT LD VD, KEYRGT SKNP VD CALL GORIGHT CALL DRAWGUY SNE V6, GUYDEAD ;lava death RET SE VF, 0 CALL COLLISION ;global collision routine RET ;DRAWGUY calls platform constraint routines (CHECKVERT & CHECKHORZ), does ;housekeeping and erases and redraws player sprite. TITLEGUY, for the ;the title and score screen, does not have platform constraints. ;------------------------------------------------------------------------ DRAWGUY: CALL CHECKVERT CALL CHECKHORZ TITLEGUY: LD VD, V0 LD VE, V1 ADD V0, V2 ADD V1, V3 LD I, GUY ADD I, V5 LD V5, 127 AND V0, V5 LD V5, V4 LD V6, V0 LD V7, V1 DRW VD, VE, 8 LD I, GUY ADD I, V4 DRW V0, V1, 8 SNE V1, 56 LD V6, GUYDEAD LD I, GUYSAVE LD [I], V5 RET ;MOVEOTHERS supervises sprite motion ;----------------------------------- MOVEOTHERS: SNE VA, ONECROW JP MOVECROW1 SNE VA, TWOCROWS JP MOVECROWS SNE VA, ONECROW1EGG JP MOVECROW1EGG1 SNE VA, TWOEGGS JP MOVEEGGS SNE VA, ONEEGG JP MOVEEGG1 ;MOVECROWS is used when two crows are present (VA=TWOCROWS) ;---------------------------------------------------------- MOVECROWS: CALL MOVECROW1 SNE VA, TWOCROWS ;if crow1 dies then crow2 becomes crow1 CALL MOVECROW2 RET ;MOVECROW1 - although somewhat subtle when playing the game, only one crow ;attacks the player the other crow is just random. CROW1 is the attacking ;crow. MOVECROW1: LD I, CROW1SAVE LD V5, [I] RND VD, 3 SNE VD, 0 CALL GORANDOM ;random motion CALL ATTACK ;within range, crow will attack CALL DRAWCROW1 SE VF, 0 ;collision? JP CROW1COLL RET ;ATTACK finds the absolute distance between player and crow and compares ;this with a minimum attacking distance. If the crow is close to the ;player ATTACK will instruct the crow to move towards the player and ;above it. ------------------------------------------------------------------------ ATTACK: LD VD, V6 ;V6 = current player x coord. SUB VD, V0 ;V0 = crow x coord SNE VF, 0 ;V6 < V0 ? SUBN VD, VF ;then VD = V0 - V6 LD VE, 16 ;x distance attack criteria SUB VE, VD SNE VF, 0 RET LD VD, V7 ;check y distance SUB VD,V1 SNE VF, 0 SUBN VD, VF LD VE, 12 SUB VE, VD SNE VF, 0 RET LD VD, V6 ;this part steers the crow towards SUB VD, V0 ;the player SNE VF, 0 CALL GOLEFT SE VF, 0 CALL GORIGHT LD VD, V7 SUB VD, V1 SE VF, 0 CALL GODOWN SNE VF, 0 CALL GOUP SNE V1, V7 CALL GOUP RET ;MOVECROW2 does not instruct crow2 to attack the player (otherwise the crows ;would stick together). Notice that crow2 is more random. Also note that ;crow2 is only present if crow1 is present. ;--------------------------------------------------------------------------- MOVECROW2: LD I, CROW2SAVE LD V5, [I] RND VD, 1 SNE VD, 0 CALL GORANDOM CALL DRAWCROW2 SE VF, 0 JP CROW2COLL ;collision routine for crows only RET DRAWCROW1: CALL DRAWCROW LD I, CROW1SAVE LD [I], V5 RET DRAWCROW2: CALL DRAWCROW LD I, CROW2SAVE LD [I], V5 RET ;DRAWCROW is similar to DRAWGUY ;------------------------------ DRAWCROW: CALL CHECKVERT CALL CHECKHORZ SNE V1, 52 CALL GOUP TITLECROW: LD VD, V0 LD VE, V1 ADD V0, V2 ADD V1, V3 LD I, CROW ADD I, V5 LD V5, 127 AND V0, V5 LD V5, V4 DRW VD, VE, 8 LD I, CROW ADD I, V4 DRW V0, V1, 8 RET MOVECROW1EGG1: CALL MOVECROW1 CALL MOVEEGG1 RET MOVEEGGS: CALL MOVEEGG2 CALL MOVEEGG1 RET ;MOVEEGG1 coordinates the egg motion and determines if the egg ;should fade away. -------------------------------------------------------------- MOVEEGG1: LD I, EGG1SAVE LD V4, [I] SNE V4, 2 ;v4 flags if egg is on the floor JP FADE1 ;count down for egg removal LD V2, 0 CALL HOPCHECK ;egg will hop on pads CALL DRAWEGG LD I, EGG1SAVE LD [I], V4 RET FADE1: ADD V2, 1 ;V2 becomes the count down to remove SNE V2, 8 ;the egg JP BYEEGG1 LD I, EGG1SAVE LD [I], V4 RET BYEEGG1: LD I, EGG DRW V0, V1, 4 SNE VA, TWOEGGS ;take care of sprite scope JP SHIFTEGG SNE VA, ONECROW1EGG JP MAKECROW2 LD VA, NONE RET ;SHIFTEGG (used by BYEEEGG1) moves egg2 data to egg1 when egg1 is ;eaten. Egg2 is never present without egg1. ;-------------------------------------------------------------------- SHIFTEGG: LD I, EGG2SAVE LD V4, [I] LD I, EGG1SAVE LD [I], V4 SNE VB, 0 LD VA, ONEEGG SNE VB, 0 RET CALL INITCROW1 LD VA, ONECROW1EGG RET ;MAKECROW2 is used by BYEEGG1 when crow1 is present ;-------------------------------------------------- MAKECROW2: SNE VB, 0 LD VA, ONECROW SNE VB, 0 RET CALL INITCROW2 LD VA, TWOCROWS RET ;MOVEEGG2 is similar to MOVEEGG1 ;------------------------------- MOVEEGG2: LD I, EGG2SAVE LD V4, [I] SNE V4, 2 JP FADE2 LD V2, 0 CALL HOPCHECK CALL DRAWEGG LD I, EGG2SAVE LD [I], V4 RET FADE2: ADD V2, 1 SNE V2, 8 JP BYEEGG2 LD I, EGG2SAVE LD [I], V4 RET BYEEGG2: LD I, EGG DRW V0, V1, 4 SNE VB, 0 JP BB2 CALL INITCROW1 LD VA, ONECROW1EGG RET BB2: LD VA, ONEEGG RET ;HOPCHECK determines if an egg is at the elevation of a platform ;--------------------------------------------------------------- HOPCHECK: SNE V1, PAD1TOP - 4 JP HOP1 SNE V1, PAD2TOP - 4 JP HOP23 SNE V1, PAD3TOP - 4 JP HOP23 LD V3, 1 RET ;HOP routines first check the x coordinate of the egg, then moves the ;egg up if the x coordinate is within the limits of a platform. ;-------------------------------------------------------------------- HOP1: CALL PAD1H SE V3, 0 RET LD VD, 1 LD ST, VD LD V3, #FD SNE V4, 0 LD V2, #FE SNE V4, 1 LD V2, #2 RET HOP23: CALL PAD23H ;platforms 2 & 3 have equal x limits SE V3, 0 RET LD VD, 1 LD ST, VD LD V3, #FD SNE V4, 0 LD V2, #FE SNE V4, 1 LD V2, #2 RET ;DRAWEGG updates x and y coordinates and checks if the egg is on the floor ;------------------------------------------------------------------------- DRAWEGG: LD VD, V0 LD VE, V1 ADD V0, V2 ADD V1, V3 LD I, EGG DRW VD, VE, 4 DRW V0, V1, 4 SNE V1, 56 LD V4, 2 RET ;The GO routines are generic motion functions that enhance interpretation ;------------------------------------------------------------------------ GOLEFT: LD V4, 8 ;version 1 resorted to increasing LD V2, #FC ;delta x and delta y to RET ;increase speed. ;Super Chip's speed makes this GORIGHT: LD V4, 0 ;unneccessary. LD V2, 4 ;Delays are used instead. RET GOUP: LD V3, #FE RET GODOWN: LD V3, 2 RET GORANDOM: RND VD, 1 LD ST, VD ;that awful clicking sound SNE VD, 0 CALL GOLEFT SNE VD, 1 CALL GORIGHT RND VD, 1 SNE VD, 0 CALL GODOWN SNE VD, 1 CALL GOUP RET ;WAVE uses a single draw with an a special sprite to switch the splashes ;from right to left. Data storage (SPLASHSAVE) contains the current ;direction and coordinate. ;----------------------------------------------------------------------- WAVE: RND VD, 3 ;save time by skipping this routine SE VD, 0 ;75% of the time RET LD I, SPLASHSAVE LD V1, [I] LD VD, 59 LD I, SPLASHXOR DRW V0, VD, 5 ADD V0, V1 SNE V0, 8 CALL SPLASHRGT SNE V0, 112 CALL SPLASHLFT LD I, SPLASHSAVE LD [I], V1 RET SPLASHRGT: LD V0, 16 LD V1, 8 RET SPLASHLFT: LD V0, 104 LD V1, #F8 RET ;The collision routines. Numerous routines are necessary to accomodate ;the different combination of sprites and to redefine the sprite scope when ;a sprite vanishes. The routines are only called as a result of VF<>0 ;after a draw command. You could continuously check coordinates for ;collisions but that reduces speed. ;========================================================================== ;The next three routines handle crow collisions only, collisions resulting ;from drawing a crow on previously drawn pixels.. CROW1COLL: CALL CROWCOLL SNE VF, 0 JP KILLCROW1 RET CROW2COLL: CALL CROWCOLL SNE VF, 0 JP KILLCROW2 RET ;CROWCOLL is used to determine which crow was hit. ;------------------------------------------------- CROWCOLL: LD VD, V6 ;V6 = player x SUB VD, V0 ;V0 = crow x SNE VF, 0 SUBN VD, VF LD VE, SPRTWIDTH SUB VD, VE SE VF, 0 RET LD VD, V7 ;V7 = player y SUB VD, V1 ;V1 = crow y SNE VF, 0 SUBN VD, VF LD VE, SPRTHEIGHT SUB VD, VE RET ;COLLISION is called buy MOVEGUY when the player collides with something ;This routine delegates collision checking based on the current sprite ;scope (VA). COLLISION: SNE VA, TWOCROWS JP COLLCC SNE VA, ONECROW JP KILLCROW1 SNE VA, TWOEGGS JP EATEGGS SNE VA, ONEEGG JP EATEGG1 JP COLLCB ;If EATEGGS is called then it is only necessary to determine which egg ;collided with the player by comparing coordinates. EATEGGS: LD I, EGG1SAVE LD V4, [I] CALL COLX SNE VF, 0 JP EATEGG2 CALL COLY SNE VF, 0 JP EATEGG2 JP EATEGG1 EATEGG1: CALL SCOREINC CALL SHORT CALL QUICK LD I, EGG1SAVE LD V4, [I] JP BYEEGG1 EATEGG2: CALL SCOREINC CALL SHORT CALL QUICK LD I, EGG2SAVE LD V4, [I] JP BYEEGG2 ;COLLCB is called when VA = ONECROW1EGG COLLCB: LD I, CROW1SAVE LD V5, [I] CALL COLX SNE VF, 0 JP EATEGG1 CALL COLY SNE VF, 0 JP EATEGG1 JP KILLCROW1 ;COLLCC is called when two crows are present ;------------------------------------------- COLLCC: LD I, CROW1SAVE LD V5, [I] CALL COLX SNE VF, 0 JP KILLCROW2 CALL COLY SNE VF, 0 JP KILLCROW2 JP KILLCROW1 COLX: LD VD, V6 SUB VD, V0 SNE VF, 0 SUBN VD, VF LD VE, SPRTWIDTH SUB VE, VD RET COLY: LD VD, V7 SUB VD, V1 SNE VF, 0 SUBN VD, VF LD VE, SPRTHEIGHT SUB VE, VD RET ;KILLCROW1 is called once it has been determined that the player has collided ;with crow1. So either the player dies or the crow dies and becomes an egg ;or there is a draw and BUMP1 is called. ;---------------------------------------------------------------------------- KILLCROW1: LD I, CROW1SAVE LD V5, [I] SNE V7, V1 JP BUMP1 LD VD, V7 SUB VD, V1 SE VF, 0 JP DIEGUY CALL QUICK ;sound for dead crow CALL SHORT LD I, CROW ADD I, V5 DRW V0, V1, 8 ;erase crow SNE VA, ONECROW1EGG ;new sprite scope JP MAKEEGG2 SNE VA, TWOCROWS JP SHIFTCROW SNE VA, ONECROW LD VA, ONEEGG CALL INITEGG1 ;an egg! RET MAKEEGG2: LD VA, TWOEGGS CALL INITEGG2 RET ;SHIFTCROW is called if crow1 dies and crow2 is present. I found it easier ;to move crow2 to crow1 instead of having crow2 alone. We also need crow1 ;because it attacks and crow2 doesn't ;-------------------------------------------------------------------------- SHIFTCROW: CALL INITEGG1 LD I, CROW2SAVE LD V5, [I] LD I, CROW1SAVE LD [I], V5 LD VA, ONECROW1EGG RET ;KILLCROW2 is similar to KILLCROW1 except there is no data swapping ;between crows ;------------------------------------------------------------------ KILLCROW2: LD I, CROW2SAVE LD V5, [I] SNE V7, V1 JP BUMP2 LD VD, V7 SUB VD, V1 SE VF, 0 JP DIEGUY CALL QUICK CALL SHORT LD I, CROW ADD I, V5 DRW V0, V1, 8 LD VA, ONECROW1EGG CALL INITEGG1 RET DIEGUY: LD V6, GUYDEAD ;flag is captured in mainloop RET ;this avoids jumping out of subroutines ;I think CHIP dies if you do that INITCROW2: CALL ADDCROW LD I, CROW2SAVE LD [I], V5 RET INITCROW1: CALL ADDCROW LD I, CROW1SAVE LD [I], V5 RET ADDCROW: CALL RANDINIT ;random crow placement ADD VB, #FF ;decrement # of crows CALL GOUP ;crow starts going up RND VD, 1 ;random right or left SE VD, 1 CALL GOLEFT SE VD, 0 CALL GORIGHT LD I, CROW ;crow sprite ADD I, V4 DRW V0, V1, 8 LD V5, V4 RET ;RANDINIT places the new crows in four different locations randomly ;------------------------------------------------------------------ RANDINIT: RND VD, 3 ;4 possibilities: 00 01 10 11 SNE VD, 0 JP STARTPAD1 SNE VD, 1 JP STARTPAD2 SNE VD, 2 JP STARTPAD3 STARTPAD4: LD V0, 120 LD V1, FLOOR - SPRTHEIGHT RET STARTPAD3: LD V0, 64 LD V1, PAD3TOP - SPRTHEIGHT RET STARTPAD2: LD V0, 64 LD V1, PAD2TOP - SPRTHEIGHT RET STARTPAD1: LD V0, 8 LD V1, PAD1TOP - SPRTHEIGHT RET INITEGG1: CALL INITEGG LD I, EGG1SAVE LD [I], V4 RET INITEGG2: CALL INITEGG LD I, EGG2SAVE LD [I], V4 RET ;INITEGG places the egg 8 pixels below the dead crow ;--------------------------------------------------- INITEGG: ADD V1, 8 ;v1 is dead crow y coordinate LD VD, 55 ;check the floor SUB VD, V1 ;so the egg won't fall thru SNE VF, 0 LD V1, 55 RND V4, 1 LD I, EGG DRW V0, V1, 4 RET ;The BUMP routines handle equal height collisions between the player and crow ;---------------------------------------------------------------------------- BUMP1: CALL BUMPTEST SE VF, 0 JP BUMP1RIGHT CALL GORIGHT ;set delta x CALL DRAWCROW1 ;adds delta x, draws CALL DRAWCROW1 ;adds delta x again and draws JP BUMPGUYLEFT BUMP1RIGHT: CALL GOLEFT CALL DRAWCROW1 CALL DRAWCROW1 JP BUMPGUYRIGHT BUMP2: CALL BUMPTEST SE VF, 0 JP BUMP2RIGHT CALL GORIGHT CALL DRAWCROW2 CALL DRAWCROW2 JP BUMPGUYLEFT BUMP2RIGHT: CALL GOLEFT CALL DRAWCROW2 CALL DRAWCROW2 JP BUMPGUYRIGHT ;BUMPTEST determines which side the player is on so that s/he is bumped in ;that direction. ;------------------------------------------------------------------------- BUMPTEST: LD VD, 3 LD ST, VD LD VD, V6 SUB VD, V0 RET BUMPGUYRIGHT: LD I, GUYSAVE LD V5, [I] CALL GORIGHT CALL DRAWGUY CALL DRAWGUY RET BUMPGUYLEFT: LD I, GUYSAVE LD V5 , [I] CALL GOLEFT CALL DRAWGUY CALL DRAWGUY RET ;DIE is jumped to from the main loop. It updates the player count, determines ;if the game is over and if not sets up the crows to resume. Eggs are lost. DIE: CALL SHORT CALL QUICK CALL LONG LD VD, 10 CALL DELAY ADD V9, #FF SNE V9, #0 JP FINI SNE VA, ONECROW ADD VB, 1 SNE VA, ONECROW1EGG ADD VB, 1 SNE VA, TWOCROWS ADD VB, 2 LD VA, TWOCROWS SNE VB, 0 JP NEWLEVEL LD VA, TWOCROWS SNE VB, 1 LD VA, ONECROW JP RESUME FINI: CALL BYE ;little tune CLS CALL SCOREDRW CALL FINITE ;flying birds JP REPLAY BYE: LD VD, 12 ;plays ending tune LD ST, VD LD VD, #18 CALL DELAY CALL SHORT CALL SHORT CALL LONG CALL LONG LD VD, 32 CALL DELAY CALL LONG CALL LONG LD VD, 32 CALL DELAY RET QUICK: LD VD, 2 LD ST, VD LD VD, 5 CALL DELAY RET SHORT: LD VD, 4 LD ST, VD LD VD, 10 CALL DELAY RET LONG: LD VD, 8 LD ST, VD LD VD, 20 CALL DELAY RET SCOREINC: LD I, SCORE LD V0, [I] ADD V0, SCOREDELTA LD [I], V0 RET SCOREDRW: LD I, SCORE LD V0, [I] LD B, V0 LD V2, [I] LD VE, 27 LD VD, 49 DW #F030 ;10 BYTE FONT FOR V0 DRW VD, VE, 10 ADD VD, 10 DW #F130 ;10 BYTE FONT FOR V1 DRW VD, VE, 10 ADD VD, 10 DW #F230 ;10 BYTE FONT FOR V2 DRW VD, VE, 10 RET RAY1: LD V3, 0 LD V4, 0 LD V5, 124 LD V6, 62 RAY2: LD I, DOT CONV: DRW V3, V4, 3 DRW V3, V6, 3 DRW V5, V4, 3 DRW V5, V6, 3 ADD V3, 4 ADD V4, 2 ADD V5, #FC ADD V6, #FE LD VD, 4 CALL DELAY SNE V3, 64 RET SNE V3, 128 RET JP CONV INITGUY: LD V4, 0 LD V5, 0 LD V0, PAD1LFT LD V1, PAD1TOP - 8 LD I, GUY DRW V0, V1, 8 LD I, GUYSAVE LD [I], V5 RET ;CHECKVERT and CHECKHORZ keep the crows and players from running through the ;platforms. Very important routines. Note that since Chipper allows ;constants to be named that you change the platform postions somewhat without ;glitching the code. Awesome! CHECKVERT: SNE V1, ROOF JP CHECKROOF SNE V1, FLOOR - SPRTHEIGHT JP CHECKFLOOR LD VD, 2 SE V3, VD JP STOPUP SNE V1, PAD1TOP - SPRTHEIGHT JP PAD1H SNE V1, PAD2TOP - SPRTHEIGHT JP PAD23H SNE V1, PAD3TOP - SPRTHEIGHT JP PAD23H RET STOPUP: SNE V1, PAD1BOT JP PAD1H SNE V1, PAD2BOT JP PAD23H SNE V1, PAD3BOT JP PAD23H RET PAD1H: LD VD, PAD1RGT SUBN VD, V0 SNE VF, 0 JP YHOLD LD VD, PAD1LFT - SPRTWIDTH SUB VD, V0 SNE VF, 0 JP YHOLD RET PAD23H: LD VD, PAD2LFT - SPRTWIDTH+1 SUBN VD, V0 SNE VF, 0 RET LD VD, PAD2RGT SUBN VD, V0 SNE VF, 0 JP YHOLD RET CHECKROOF: LD VD, #FE SNE V3, VD CALL GODOWN RET CHECKFLOOR: LD VD, 2 SE V3, VD RET SNE V8, MODE1 JP YHOLD SE V8, MODE1 JP PAD1H RET YHOLD: LD V3, 0 RET CHECKHORZ: SNE V2, 0 RET LD VD, 4 SE V2, VD JP STAYLEFT SNE V0, PAD1LFT - SPRTWIDTH JP PAD1V SNE V0, PAD2LFT - SPRTWIDTH JP PAD23V RET STAYLEFT: SNE V0, PAD1RGT JP PAD1V SNE V0, PAD2RGT JP PAD23V RET PAD1V: LD VD, PAD1TOP - SPRTHEIGHT - 3 SUBN VD, V1 SNE VF, 0 RET LD VD, PAD1BOT + 1 SUBN VD, V1 SNE VF, 0 JP XHOLD RET PAD23V: LD VD, 28 SUB VD, V1 SNE VF, 0 JP PAD3V PAD2V: LD VD, PAD2TOP - SPRTHEIGHT - 3 SUBN VD, V1 SNE VF, 0 RET LD VD, PAD2BOT + 1 SUBN VD, V1 SNE VF, 0 JP XHOLD RET PAD3V: LD VD, PAD3TOP - SPRTHEIGHT - 3 SUBN VD, V1 SNE VF, 0 RET LD VD, PAD3BOT + 1 SUBN VD, V1 SNE VF, 0 JP XHOLD RET XHOLD: LD V2, 0 RET SCREEN: CLS LD VD, 0 LD VE, 60 LD I, SOLIDPAD DRW VD, VE, 4 LD VD, 8 DRW VD, VE, 4 LD I, CENTERPAD LD VD, 16 SNE V8, MODE1 CALL FLOOR1 SE V8, MODE1 CALL FLOOR2 LD I, CENTERPAD LD VE, PAD1TOP LD VD, PAD1LFT + 8 DRW VD, VE, 4 LD VD, PAD1RGT - 16 DRW VD, VE, 4 LD VD, PAD2LFT + 8 LD VE, PAD2TOP DRW VD, VE, 4 LD VD, PAD2LFT + 16 DRW VD, VE, 4 LD VE, PAD3TOP DRW VD, VE, 4 LD VD, PAD3LFT + 8 DRW VD, VE, 4 LD I, RIGHTPAD LD VD, PAD3RGT - 8 DRW VD, VE, 4 LD VE, PAD2TOP DRW VD, VE, 4 LD VD, PAD1RGT - 8 LD VE, PAD1TOP DRW VD, VE, 4 LD I, LEFTPAD LD VD, PAD1LFT DRW VD, VE, 4 LD VE, PAD3TOP LD VD, PAD3LFT DRW VD, VE, 4 LD VE, PAD2TOP DRW VD, VE, 4 CALL PLAYSLEFT RET FLOOR1: DRW VD, VE, 4 ADD VD, 8 SE VD, 128 JP FLOOR1 RET ;FLOOR2 has lava FLOOR2: LD VD, 112 DRW VD, VE, 4 LD VD, 120 DRW VD, VE, 4 LD VD, 16 LD I, SPLASH LD VE, 59 IWLP: DRW VD, VE, 5 ADD VD, 8 SE VD, 112 JP IWLP LD V0, 104 LD V1, #F8 LD I, SPLASHSAVE LD [I], V1 RET PLAYSLEFT: SNE V9, 1 RET LD VD, 1 LD VE, 61 LD I, DOT DRW VD, VE, 3 ADD VD, 4 SE V9, 2 DRW VD, VE, 3 ADD VD, 4 LD V6, 3 SUB V6, V9 SNE VF, 0 DRW VD, VE, 3 RET NAME: LD I, TITLE LD VD, 36 LD VE, 24 DRW VD, VE, 0 LD V0, 32 ADD I, V0 ADD VD, 16 DRW VD, VE, 0 ADD I, V0 ADD VD, 16 DRW VD, VE, 0 ADD I, V0 ADD VD, 16 DRW VD, VE, 0 FINITE: LD V8, 0 ;animation demo setup LD VB, 1 LD VA, 0 CALL INITCROW1 CALL INITGUY CALL GORIGHT LD I, GUYSAVE LD [I], V5 TLP: LD VD, 10 CALL DELAY LD I, GUYSAVE LD V5, [I] CALL TSUB CALL TITLEGUY LD I, GUYSAVE LD [I], V5 LD I, CROW1SAVE LD V5, [I] CALL TSUB CALL TITLECROW LD I, CROW1SAVE LD [I], V5 LD VD, KEYUP SKP VD JP TLP RET TSUB: RND VD, #F SNE VD, 0 CALL GORANDOM SNE V1, 2 LD V3, 2 SNE V1, 54 LD V3, #FE RET BONUS: CALL SCREEN CALL INITGUY LD I, EGG LD VE, PAD2TOP - 4 LD VD, PAD2LFT + 2 DRW VD, VE, 4 ADD VD, 12 DRW VD, VE, 4 ADD VD, 12 DRW VD, VE, 4 LD VE, PAD3TOP - 4 LD VD, PAD3LFT + 2 DRW VD, VE, 4 ADD VD, 12 DRW VD, VE, 4 ADD VD, 12 DRW VD, VE, 4 LD VE, PAD1TOP - 4 LD VD, PAD1RGT - 6 DRW VD, VE, 4 LD VE, FLOOR - 4 DRW VD, VE, 4 LD VD, PAD1LFT + 2 DRW VD, VE, 4 LD V6, 0 LD V7, 0 ;-------------------------- ;Bonus Round Register Usage ;-------------------------- ;v0 = guy x ;v1 = guy y ;v2 = guy delta x ;v3 = guy delta y ;v4 = current right/left flag ;v5 = old right/left flag ;v6 = number of eggs eaten ;v7 = countdown timer BONUSMAIN: ADD V7, 1 SNE V7, BONUSLIMIT JP NEWLEVEL LD VD, 1 LD ST, VD LD VD, 3 CALL DELAY LD I, GUYSAVE LD V5, [I] CALL GODOWN LD V2, 0 LD VD, KEYUP SKNP VD CALL GOUP LD VD, KEYLFT SKNP VD CALL GOLEFT LD VD, KEYRGT SKNP VD CALL GORIGHT CALL CHECKVERT CALL CHECKHORZ LD VD, V0 LD VE, V1 ADD V0, V2 ADD V1, V3 LD I, GUY ADD I, V5 LD V5, 127 AND V0, V5 LD V5, V4 DRW VD, VE, 8 LD I, GUY ADD I, V4 DRW V0, V1, 8 SNE V1, 56 JP BONUSDIE LD I, GUYSAVE LD [I], V5 SE VF, 0 CALL BONUSCHECK SNE V6, 9 JP BIGBONUS JP BONUSMAIN BONUSCHECK: LD VE, FLOOR - 8 SNE V1, VE JP FLOORBONUS LD VE, PAD1TOP - 8 SNE V1, VE JP PAD1BONUS LD VE, PAD2TOP - 8 SNE V1, VE JP PAD23BONUS LD VE, PAD3TOP - 8 SNE V1, VE JP PAD23BONUS RET FLOORBONUS: LD VD, PAD1LFT + 4 SNE V0, VD JP BONUSEGG LD VD, PAD1RGT - 4 SNE V0, VD JP BONUSEGG RET PAD1BONUS: LD VD, PAD1RGT - 4 SNE V0, VD JP BONUSEGG RET PAD23BONUS: LD VD, PAD2LFT + 4 SNE V0, VD JP BONUSEGG ADD VD, 12 SNE V0, VD JP BONUSEGG ADD VD, 12 SNE V0, VD JP BONUSEGG RET BONUSEGG: ADD VD, #FE ADD VE, 4 LD I, EGG DRW VD, VE, 4 CALL SHORT CALL QUICK ADD V6, 1 LD I, SCORE LD V0, [I] ADD V0, SCOREDELTA LD [I], V0 RET BONUSDIE: LD VD, 8 LD ST, VD LD VD, 20 CALL DELAY ADD V9, #FF SNE V9, #0 JP FINI JP NEWLEVEL BIGBONUS: LD I, SCORE LD V0, [I] ADD V0, 8 LD [I], V0 ADD V9, 1 CALL LONG CALL SHORT CALL LONG JP NEWLEVEL SCORE: DB 0, 0, 0 DOT: DB $01000000, $11100000, $01000000 GUY: DB $00000110, $00001111, $00001100, $00001100 DB $00000110, $11111111, $01111111, $00011110 DB $01100000, $11110000, $00110000, $00110000 DB $01100000, $11111111, $11111110, $01111000 CROW: DB $00001110, $00001111, $00001100, $00001100 DB $11111110, $01111111, $00011111, $00001110 DB $01110000, $11110000, $00110000, $00110000 DB $01111111, $11111110, $11111000, $01110000 GUYSAVE: DB 0, 0, 0, 0, 0, 0 CROW1SAVE: DB 0, 0, 0, 0, 0, 0 CROW2SAVE: DB 0, 0, 0, 0, 0, 0 EGG1SAVE: DB 0, 0, 0, 0, 0 EGG2SAVE: DB 0, 0, 0, 0, 0 RIGHTPAD: DB $11111111, $10111010, $11101000, $10000000 LEFTPAD: DB $11111111, $01101101, $00011011, $00000010 CENTERPAD: DB $11111111, $11101110, $10111011, $10110110 SOLIDPAD: DB $11111111, $11111111, $11111111, $11111111 LEVEL: DB 0, 0, 0 ;used for twodigit level SPLASH: DB $00000110, $00011100, $00101000, $01011100, $11111110 SPLASHXOR: DB $01100110, $00100100, $00111100, $01100110, $00000000 SPLASHSAVE: DB 0, 0 ;right/left flag and x position EGG: DB $01100000, $11110000, $11110000, $01100000 TITLE: DB $00000000, $11000000 DB $00000000, $11000000 DB $00000000, $11000000 DB $00000000, $11000000 DB $00000000, $11000000 DB $00000000, $11000000 DB $00000000, $11000011 DB $00000000, $11000111 DB $00000000, $11001100 DB $00000000, $11001100 DB $11000000, $11001100 DB $11000000, $11001100 DB $11000000, $11001100 DB $11000000, $11001100 DB $01111111, $10000111 DB $00111111, $00000011 DB $00000000, $00000000 DB $00000000, $00000000 DB $00000000, $00000000 DB $00000000, $00000000 DB $00000000, $00000000 DB $00000000, $00000000 DB $11110000, $11000000 DB $11111000, $11000000 DB $00001100, $11000000 DB $00001100, $11000000 DB $00001100, $11000000 DB $00001100, $11000000 DB $00001100, $11000000 DB $00001100, $11000000 DB $11111000, $01111111 DB $11110000, $00111111 DB $00000000, $00000000 DB $00000000, $00000000 DB $00000000, $00000000 DB $00000000, $00000000 DB $00000000, $00000000 DB $00000000, $00000000 DB $11000011, $11111100 DB $11000111, $11111100 DB $11001100, $00000000 DB $11001100, $00000000 DB $11000111, $11110000 DB $11000011, $11111000 DB $11000000, $00001100 DB $11000000, $00001100 DB $11001111, $11111000 DB $11001111, $11110000 DB $00000000, $0 DB $00000000, $0 DB $00110000, $0 DB $00110000, $0 DB $00110000, $0 DB $00110000, $0 DB $11111100, $0 DB $11111100, $0 DB $00110000, $0 DB $00110000, $0 DB $00110000, $0 DB $00110000, $0 DB $00110011, $0 DB $00110011, $0 DB $00011110, $0 DB $00001100, $0