include "includes.i" xdef ResetPlayer xdef GetNextAutoMove xdef CheckPlayerMiss xdef UpdatePlayer xdef ProcessJoystick xdef InitialisePlayer xdef HidePlayer xdef SetupSpriteData xdef ScrollSprites xdef RenderPlayerScore xdef PreRenderColumnsRemaining xdef UpdatePlayerFallingAnimation xdef InstallPlayerColorPalette xdef SpriteEnableAuto xdef deadSprite ; used in items xdef spriteLagX xdef spriteY xdef spriteX xdef spriteCurrentPathwayTile xdef playerXColumn xdef playerXColumnLastSafe xdef playerLevelPausePixels xdef playerLevelMissPixels xdef pigPlayerSpriteConfig xdef cowPlayerSpriteConfig xdef robotPlayerSpriteConfig xdef tankPlayerSpriteConfig xdef playerSpriteConfig PLAYER_INSTALL_COLOR_PALETTE equ 0 PLAYER_SPRITE_DATA equ 4 PLAYER_SPRITE_FALLING_DATA equ 8 ResetPlayer: bsr SpriteDisableAuto move.l playerSpriteConfig,a0 move.l PLAYER_SPRITE_DATA(a0),d0 add.l #6*PLAYER_SPRITE_VERTICAL_BYTES,d0 move.l d0,currentSprite move.w #PATHWAY_CONFIG_FREE,pathwayLastConfig move.w #0,pathwayMissPending move.l #0,foregroundPlayerTileAddress bsr SpriteDisableAuto move.w #0,spritePlayerFallingAnimation move.w #PLAYER_INITIAL_X,spriteX move.w #PLAYER_INITIAL_Y,spriteY move.w #PLAYER_INITIAL_Y+16,spriteYEnd rts HidePlayer: move.w #0,spriteX move.w #0,spriteY move.w #0,spriteYEnd rts InitialisePlayer: move.l #PLAYER_LIVES_COUNTER,livesCounterText rts ScrollSprites: cmp.l #0,foregroundScrollPixels beq .skip sub.w #1,spriteX bra ScrollItemSprites .skip: rts UpdatePlayerFallingAnimation: move.w spritePlayerFallingAnimation,d0 lsr.w #1,d0 mulu.w #PLAYER_SPRITE_VERTICAL_BYTES,d0 move.l playerSpriteConfig,a0 move.l PLAYER_SPRITE_FALLING_DATA(a0),a0 add.l d0,a0 move.l a0,currentSprite add.w #1,spritePlayerFallingAnimation cmp.w #4<<1,spritePlayerFallingAnimation blt .dontResetAnimation move.w #0,spritePlayerFallingAnimation bsr HidePlayer .dontResetAnimation: rts UpdatePlayer: move.l playerSpriteConfig,a0 move.l PLAYER_SPRITE_DATA(a0),d0 move.w playerPausePixels,d2 ;; right cmp.w spriteR,d2 bge .skipRight move.w playerMovePixels,d1 add.w d1,spriteX add.l #7*PLAYER_SPRITE_VERTICAL_BYTES,d0 move.l d0,currentSprite .skipRight cmp.w #0,spriteR beq .notRight sub.w #1,spriteR cmp.w spriteR,d2 ble .notRight add.l #6*PLAYER_SPRITE_VERTICAL_BYTES,d0 move.l d0,currentSprite .notRight: ;; up cmp.w spriteU,d2 bge .skipUp cmp.w #PLAYER_TOP_Y,spriteY ble .skipUp move.w playerMovePixels,d1 sub.w d1,spriteY sub.w d1,spriteYEnd add.l #1*PLAYER_SPRITE_VERTICAL_BYTES,d0 move.l d0,currentSprite .skipUp: cmp.w #0,spriteU beq .notUp sub.w #1,spriteU cmp.w spriteU,d2 ble .notUp move.l d0,currentSprite .notUp: ;; down cmp.w spriteD,d2 bge .skipDown cmp.w #PLAYER_BOTTOM_Y,spriteY bge .skipDown move.w playerMovePixels,d1 add.w d1,spriteY add.w d1,spriteYEnd add.l #3*PLAYER_SPRITE_VERTICAL_BYTES,d0 move.l d0,currentSprite .skipDown: cmp.w #0,spriteD beq .notDown sub.w #1,spriteD cmp.w spriteD,d2 ble .notDown add.l #2*PLAYER_SPRITE_VERTICAL_BYTES,d0 move.l d0,currentSprite .notDown: ;; left cmp.w spriteL,d2 bge .skipLeft move.w playerMovePixels,d1 sub.w d1,spriteX add.l #5*PLAYER_SPRITE_VERTICAL_BYTES,d0 move.l d0,currentSprite .skipLeft cmp.w #0,spriteL beq .notLeft sub.w #1,spriteL cmp.w spriteL,d2 ble .notLeft add.l #4*PLAYER_SPRITE_VERTICAL_BYTES,d0 move.l d0,currentSprite .notLeft: cmp.w #$cf,spriteX blt .noScroll .noScroll: rts ProcessJoystick: btst.b #0,joystick beq .joystickNotPressed1 jsr UsePickup .joystickNotPressed1: jsr ReadJoystick cmp.w #0,spriteR bne .skip cmp.w #0,spriteU bne .skip cmp.w #0,spriteD bne .skip cmp.w #0,spriteL bne .skip cmp.w #0,spriteAutoMoveEnabled if 1 beq .autoMoveDisabled ;; Set fast as default, will be overridden to correct speed move.w #PLAYER_FAST_PAUSE_PIXELS,playerPausePixels move.w #PLAYER_FAST_CHECK_MISS_PIXELS,playerMissPixels else beq .autoMoveDisabled2 move.w #PLAYER_FAST_PAUSE_PIXELS,playerPausePixels move.w #PLAYER_FAST_CHECK_MISS_PIXELS,playerMissPixels .autoMoveDisabled2: endif bsr GetNextAutoMove cmp.w #1,d0 beq .skip .autoMoveDisabled: DiagonalJoystick: macro cmp.b #\1,joystickpos bne .\@1 cmp.b #\2,lastJoystickPos bne .\@2 move.b #\3,joystickpos bra .process .\@2: move.b #\2,joystickpos bra .process .\@1: endm ;; 812 ;; 7 3 ;; 654 if 0 DiagonalJoystick 2,1,3 DiagonalJoystick 8,1,7 DiagonalJoystick 4,3,5 DiagonalJoystick 6,5,7 move.b joystickpos,lastJoystickPos endif .process: cmp.b #3,joystickpos bne .notRight PlayerMoveRight bra .skip .notRight: cmp.b #1,joystickpos bne .notUp PlayerMoveUp bra .skip .notUp: cmp.b #5,joystickpos bne .notDown PlayerMoveDown bra .skip .notDown: cmp.b #7,joystickpos bne .notLeft PlayerMoveLeft bra .skip .notLeft: .skip: rts SpriteEnableAuto: CompareScore SCORE_ARROW_SUBTRACTION ble .toZero AddToScore SCORE_ARROW_SUBTRACTION bra .done .toZero: ResetScore .done: move.w #1,spriteAutoMoveEnabled bsr RenderPlayerScore rts SpriteDisableAuto: move.w #0,spriteAutoMoveEnabled move.w #PLAYER_JUMP_PIXELS,playerJumpPixels move.w #PLAYER_MOVE_PIXELS,playerMovePixels move.w playerLevelPausePixels,playerPausePixels move.w playerLevelMissPixels,playerMissPixels rts SetupSpriteData: move.l currentSprite,a0 move.w spriteLagX,d0 move.w d0,d1 andi #1,d1 lsr.l #1,d0 move.b d0,1(a0) ;spriteHStart move.w spriteY,d0 move.b d0,(a0) ;spriteVStart andi.w #$100,d0 cmp.w #0,d0 beq .s1 ori.w #$4,d1 .s1: move.w spriteYEnd,d0 move.b d0,2(a0) ;spriteVStop move.l a0,SPR0PTH(a6) andi.w #$100,d0 cmp.w #0,d0 beq .s2 ori.w #$2,d1 .s2: move.b d1,3(a0) ;spriteControl jsr SetupItemSpriteData move.l #deadSprite,SPR1PTH(a6) ; unused - could only use if sprite resused player sprite palette move.l #deadSprite,SPR6PTH(a6) ; unused - incompatible with oversize playfield data fetch move.l #deadSprite,SPR7PTH(a6) ; unused - incompatible with oversize playfield data fetch rts InstallPlayerColorPalette: move.l playerSpriteConfig,a0 move.l PLAYER_INSTALL_COLOR_PALETTE(a0),a1 jsr (a1) rts InstallPigColorPalette: include "out/sprite_pig-0-palette.s" rts InstallCowColorPalette: include "out/sprite_cow-0-palette.s" rts InstallRobotColorPalette: include "out/sprite_robot-0-palette.s" rts InstallTankColorPalette: include "out/sprite_tank-0-palette.s" rts CheckPlayerMiss: ;; check if player has fallen off the left side of the play area cmpi.w #PLAYER_INITIAL_X-15,spriteX blt .doBigBang move.w playerMissPixels,d1 cmp.w spriteR,d1 beq .check move.w playerMissPixels,d1 cmp.w spriteU,d1 beq .check move.w playerMissPixels,d1 cmp.w spriteD,d1 beq .check move.w playerMissPixels,d1 cmp.w spriteL,d1 beq .check jmp PostCheckPlayerMiss .check: cmp.w #1,pathwayMissPending beq .doBigBang move.w #PATHWAY_CONFIG_FREE,pathwayLastConfig move.l pathwayMapPtr,a2 move.l foregroundMapPtr,a3 ;; calculate the a2 offset of the top right tile based on foreground scroll move.l foregroundScrollX,d0 lsr.l #FOREGROUND_SCROLL_TILE_INDEX_CONVERT,d0 lsr.l #1,d0 and.b #$f0,d0 add.l d0,a2 add.l d0,a3 ;; add the offset based on the sprite's x position move.w spriteX,d0 ;; move.w spriteLagX,d0 cmpi.w #PLAYER_LEFT_X,d0 blt .doBigBang sub.w #PLAYER_LEFT_X,d0 lsr.w #4,d0 ; x columns move.l #(FOREGROUND_PLAYAREA_WIDTH_WORDS/2)-1,d1 sub.w d0,d1 mulu.w #FOREGROUND_PLAYAREA_HEIGHT_WORDS*2,d1 sub.l d1,a2 ; player x if y == bottom ? sub.l d1,a3 ; player x if y == bottom ? ;; add the offset based on the sprite's y postion move.w #PLAYER_BOTTOM_Y,d0 sub.w spriteY,d0 lsr.w #4,d0 ; y columns sub.l d1,d1 move.w #FOREGROUND_PLAYAREA_HEIGHT_WORDS-1,d1 sub.w d0,d1 lsl.w #1,d1 add.l d1,a2 add.l d1,a3 ;; a2 now points at the pathway tile under the sprite move.l a2,pathwayPlayerTileAddress move.w (a2),d0 move.w d0,spriteCurrentPathwayTile bsr CheckDirection ;; a3 now points at the tile under the sprite move.l a3,foregroundPlayerTileAddress cmp.w #$78e,d0 bge .noBigBang move.w (a3),d0 cmp.w #FOREGROUND_TILE_EMPTY,d0 ; empty tile bge .doBigBang cmp.w #FOREGROUND_TILE_ENDLEVEL,d0 beq .levelComplete cmp.w #$78e,d0 bge .noBigBang .doBigBang: jmp BigBang .levelComplete: jmp LevelComplete .noBigBang: move.w (a3),d0 cmp.w #$1e00,d0 blt .dontRenderPathway move.w #2,pathwayRenderPending move.w #0,pathwayFadeCount jsr InstallTilePalette .dontRenderPathway: cmp.w #$f02,d0 beq .clearPathway cmp.w #$1682,d0 beq .clearPathway bra .dontClearPathway .clearPathway: move.w #2,pathwayClearPending move.l a2,pathwayLastSafeTileAddress move.l a3,foregroundLastSafeTileAddress move.l playerXColumn,playerXColumnLastSafe move.l #PLAYER_BOTTOM_Y,d0 sub.w spriteY,d0 lsr.w #4,d0 ; y columns move.w #FOREGROUND_PLAYAREA_HEIGHT_WORDS-1,d1 sub.l d0,d1 mulu.w #2,d1 sub.l d1,a3 sub.l d1,a2 move.l a3,startForegroundMapPtr move.l a2,startPathwayMapPtr .dontClearPathway: jsr DetectItemCollisions jmp PostCheckPlayerMiss GetNextAutoMove: move.w spriteCurrentPathwayTile,d0 lsr.w #4,d0 ; light and dark colored tiles cmp.w #$708,d0 beq .horizontal cmp.w #$690,d0 beq .topLeft cmp.w #$5a0,d0 beq .leftBottom cmp.w #$4b0,d0 beq .rightBottom cmp.w #$528,d0 beq .topRight cmp.w #$618,d0 beq .vertical move.l foregroundPlayerTileAddress,a0 move.w (a0),d0 lsr.w #4,d0 ; light and dark colored tiles cmp.w #$3c0,d0 beq .topLeft cmp.w #$2d0,d0 beq .leftBottom cmp.w #$438,d0 beq .horizontal bra .skip .horizontal: cmp.w #PLAYER_MOVE_RIGHT,spriteLastMove beq .goRight bra .goLeft .topLeft: cmp.w #PLAYER_MOVE_RIGHT,spriteLastMove beq .goUp bra .goLeft .leftBottom: cmp.w #PLAYER_MOVE_RIGHT,spriteLastMove beq .goDown bra .goLeft .topRight: cmp.w #PLAYER_MOVE_DOWN,spriteLastMove beq .goRight bra .goUp .rightBottom: cmp.w #PLAYER_MOVE_UP,spriteLastMove beq .goRight bra .goDown .vertical: cmp.w #PLAYER_MOVE_UP,spriteLastMove beq .goUp bra .goDown .default: bra .skip .goRight: PlayerMoveRight bra .done .goUp: PlayerMoveUp bra .done .goDown: PlayerMoveDown bra .done .goLeft: PlayerMoveLeft bra .done .done: move.w #1,d0 rts .skip: bsr SpriteDisableAuto move.w #0,d0 rts CheckDirection: move.w playerMissPixels,d1 cmp.w #$7080,d0 ; dark horizontal beq .horizontal cmp.w #$708c,d0 ; light horizontal beq .horizontal cmp.w #$6900,d0 ; dark left-top beq .topLeft cmp.w #$690c,d0 ; light left-top beq .topLeft cmp.w #$5a00,d0 ; dark left-bottom beq .leftBottom cmp.w #$5a0c,d0 ; light left-bottom beq .leftBottom cmp.w #$4b00,d0 ; dark right-bottom beq .rightBottom cmp.w #$4b0c,d0 ; light right-bottom beq .rightBottom cmp.w #$5280,d0 ; dark top-right beq .topRight cmp.w #$528c,d0 ; light top-right beq .topRight cmp.w #$6180,d0 ; dark vertical beq .vertical cmp.w #$618c,d0 ; light vertical beq .vertical cmp.w #0,d0 beq .ok jmp BigBang .horizontal: move.w #PATHWAY_CONFIG_HORIZONTAL,pathwayLastConfig cmp.w spriteR,d1 beq .ok cmp.w spriteL,d1 beq .ok jmp BigBang .vertical: move.w #PATHWAY_CONFIG_VERTICAL,pathwayLastConfig cmp.w spriteU,d1 beq .ok cmp.w spriteD,d1 beq .ok jmp BigBang .topLeft: move.w #PATHWAY_CONFIG_TOP_LEFT,pathwayLastConfig cmp.w spriteR,d1 beq .ok cmp.w spriteD,d1 beq .ok jmp BigBang .topRight: move.w #PATHWAY_CONFIG_TOP_RIGHT,pathwayLastConfig cmp.w spriteD,d1 beq .ok cmp.w spriteL,d1 beq .ok jmp BigBang .rightBottom: move.w #PATHWAY_CONFIG_BOT_RIGHT,pathwayLastConfig cmp.w spriteU,d1 beq .ok cmp.w spriteL,d1 beq .ok jmp BigBang .leftBottom: move.w #PATHWAY_CONFIG_BOT_LEFT,pathwayLastConfig cmp.w spriteR,d1 beq .ok cmp.w spriteU,d1 beq .ok jmp BigBang .ok: rts UpdatePlayerScore: AddToScore 10 RenderPlayerScore: jsr RenderScore move.l playerXColumn,d0 cmp.l #100,playerXColumn bge .3 move.w #PANEL_COLUMNS_REMAINING_X+(8*3),d1 jsr RenderNumber2 bra .done .3: move.w #PANEL_COLUMNS_REMAINING_X+(8*2),d1 jsr RenderNumber3 .done: rts PreRenderColumnsRemaining: move.l playerXColumn,d0 move.w #PANEL_COLUMNS_REMAINING_X,d1 jsr RenderNumber5 rts pigPlayerSpriteConfig: dc.l InstallPigColorPalette dc.l spritePig dc.l spriteFalling1 cowPlayerSpriteConfig: dc.l InstallCowColorPalette dc.l spriteCow dc.l spriteFallingCow1 robotPlayerSpriteConfig: dc.l InstallRobotColorPalette dc.l spriteRobot dc.l spriteFallingRobot1 tankPlayerSpriteConfig: dc.l InstallTankColorPalette dc.l spriteTank dc.l spriteFallingTank1 playerSpriteConfig: dc.l pigPlayerSpriteConfig include "sprite_data.i" if 0 lastJoystickPos: dc.w 0 endif spritePlayerFallingAnimation: dc.w 0 currentSpriteOffset: dc.l 0 currentSprite: dc.l spritePig deadSprite: dc.l 0 spriteR: dc.w 0 spriteL: dc.w 0 spriteU: dc.w 0 spriteD: dc.w 0 spriteLagX: dc.w 0 spriteX: dc.w $0 spriteY: dc.w $e4 spriteYEnd: dc.w $f5 spriteCurrentPathwayTile: dc.w 0 spriteLastMove: dc.w 0 spriteAutoMoveEnabled: dc.w 0 playerMovePixels: dc.w PLAYER_MOVE_PIXELS playerJumpPixels: dc.w PLAYER_JUMP_PIXELS playerPausePixels: dc.w 0 playerMissPixels: dc.w 0 playerLevelPausePixels: dc.w 0 playerLevelMissPixels dc.w 0 pathwayLastConfig: dc.w PATHWAY_CONFIG_FREE pathwayMissPending: dc.w 0 playerXColumn: dc.l 0 playerXColumnLastSafe: dc.l 0