11 March 2016 - Forum Rules
Started by Piotyr, March 23, 2007, 10:11:50 PM
CheckBalPlatform: tay ;save offset from state as Y lda Enemy_ID,y ;check if other object is balance platform cmp #$24 bne ExBalP ;if not, leave lda PlatformCollisionFlag,x ;get collision flag of platform sta $00 ;store here
;-------------------------------------------------------------------------------------;$00 - used to hold collision flag, Y movement force + 5 or low byte of name table for rope;$01 - used to hold high byte of name table for rope;$02 - used to hold page location of ropeBalancePlatform: lda Enemy_Y_HighPos,x ;check high byte of vertical position cmp #$03 bne DoBPl jmp EraseEnemyObject ;if far below screen, kill the objectDoBPl: lda Enemy_State,x ;get object's state (set to $ff or other platform offset) bpl CheckBalPlatform ;if doing other balance platform, branch to leave rtsCheckBalPlatform: tay ;save offset from state as Y lda PlatformCollisionFlag,x ;get collision flag of platform sta $00 ;store here lda Enemy_MovingDir,x ;get moving direction beq ChkForFall jmp PlatformFall ;if set, jump hereChkForFall: lda #$2d ;check if platform is above a certain point cmp Enemy_Y_Position,x bcc ChkOtherForFall ;if not, branch elsewhere cpy $00 ;if collision flag is set to same value as beq MakePlatformFall ;enemy state, branch to make platforms fall clc adc #$02 ;otherwise add 2 pixels to vertical position sta Enemy_Y_Position,x ;of current platform and branch elsewhere jmp StopPlatforms ;to make platforms stopMakePlatformFall: jmp InitPlatformFall ;make platforms fallChkOtherForFall: cmp Enemy_Y_Position,y ;check if other platform is above a certain point bcc ChkToMoveBalPlat ;if not, branch elsewhere cpx $00 ;if collision flag is set to same value as beq MakePlatformFall ;enemy state, branch to make platforms fall clc adc #$02 ;otherwise add 2 pixels to vertical position sta Enemy_Y_Position,y ;of other platform and branch elsewhere jmp StopPlatforms ;jump to stop movement and do not returnChkToMoveBalPlat: lda Enemy_Y_Position,x ;save vertical position to stack pha lda PlatformCollisionFlag,x ;get collision flag bpl ColFlg ;branch if collision lda Enemy_Y_MoveForce,x clc ;add $05 to contents of moveforce, whatever they be adc #$05 sta $00 ;store here lda Enemy_Y_Speed,x adc #$00 ;add carry to vertical speed bmi PlatDn ;branch if moving downwards bne PlatUp ;branch elsewhere if moving upwards lda $00 cmp #$0b ;check if there's still a little force left bcc PlatSt ;if not enough, branch to stop movement bcs PlatUp ;otherwise keep branch to move upwardsColFlg: cmp ObjectOffset ;if collision flag matches beq PlatDn ;current enemy object offset, branchPlatUp: jsr MovePlatformUp ;do a sub to move upwards jmp DoOtherPlatform ;jump ahead to remaining codePlatSt: jsr StopPlatforms ;do a sub to stop movement jmp DoOtherPlatform ;jump ahead to remaining codePlatDn: jsr MovePlatformDown ;do a sub to move downwardsDoOtherPlatform: ldy Enemy_State,x ;get offset of other platform pla ;get old vertical coordinate from stack sec sbc Enemy_Y_Position,x ;get difference of old vs. new coordinate clc adc Enemy_Y_Position,y ;add difference to vertical coordinate of other sta Enemy_Y_Position,y ;platform to move it in the opposite direction lda PlatformCollisionFlag,x ;if no collision, skip this part here bmi DrawEraseRope tax ;put offset which collision occurred here jsr PositionPlayerOnVPlat ;and use it to position player accordinglyDrawEraseRope: ldy ObjectOffset ;get enemy object offset lda Enemy_Y_Speed,y ;check to see if current platform is ora Enemy_Y_MoveForce,y ;moving at all beq ExitRp ;if not, skip all of this and branch to leave ldx VRAM_Buffer1_Offset ;get vram buffer offset cpx #$20 ;if offset beyond a certain point, go ahead bcs ExitRp ;and skip this, branch to leave lda Enemy_Y_Speed,y pha ;save two copies of vertical speed to stack pha jsr SetupPlatformRope ;do a sub to figure out where to put new bg tiles lda $01 ;write name table address to vram buffer sta VRAM_Buffer1,x ;first the high byte, then the low lda $00 sta VRAM_Buffer1+1,x lda #$02 ;set length for 2 bytes sta VRAM_Buffer1+2,x lda Enemy_Y_Speed,y ;if platform moving upwards, branch bmi EraseR1 ;to do something else lda #$a2 sta VRAM_Buffer1+3,x ;otherwise put tile numbers for left lda #$a3 ;and right sides of rope in vram buffer sta VRAM_Buffer1+4,x jmp OtherRope ;jump to skip this partEraseR1: lda #$24 ;put blank tiles in vram buffer sta VRAM_Buffer1+3,x ;to erase rope sta VRAM_Buffer1+4,xOtherRope: lda Enemy_State,y ;get offset of other platform from state tay ;use as Y here pla ;pull second copy of vertical speed from stack eor #$ff ;invert bits to reverse speed jsr SetupPlatformRope ;do sub again to figure out where to put bg tiles lda $01 ;write name table address to vram buffer sta VRAM_Buffer1+5,x ;this time we're doing putting tiles for lda $00 ;the other platform sta VRAM_Buffer1+6,x lda #$02 sta VRAM_Buffer1+7,x ;set length again for 2 bytes pla ;pull first copy of vertical speed from stack bpl EraseR2 ;if moving upwards (note inversion earlier), skip this lda #$a2 sta VRAM_Buffer1+8,x ;otherwise put tile numbers for left lda #$a3 ;and right sides of rope in vram sta VRAM_Buffer1+9,x ;transfer buffer jmp EndRp ;jump to skip this partEraseR2: lda #$24 ;put blank tiles in vram buffer sta VRAM_Buffer1+8,x ;to erase rope sta VRAM_Buffer1+9,xEndRp: lda #$00 ;put null terminator at the end sta VRAM_Buffer1+10,x lda VRAM_Buffer1_Offset ;add ten bytes to the vram buffer offset clc ;and store adc #10 sta VRAM_Buffer1_OffsetExitRp: ldx ObjectOffset ;get enemy object buffer offset and leave rtsSetupPlatformRope: pha ;save second/third copy to stack lda Enemy_X_Position,y ;get horizontal coordinate clc adc #$08 ;add eight pixels ldx SecondaryHardMode ;if secondary hard mode flag set, bne GetLRp ;use coordinate as-is clc adc #$10 ;otherwise add sixteen more pixelsGetLRp: pha ;save modified horizontal coordinate to stack lda Enemy_PageLoc,y adc #$00 ;add carry to page location sta $02 ;and save here pla ;pull modified horizontal coordinate and #%11110000 ;from the stack, mask out low nybble lsr ;and shift three bits to the right lsr lsr sta $00 ;store result here as part of name table low byte ldx Enemy_Y_Position,y ;get vertical coordinate pla ;get second/third copy of vertical speed from stack bpl GetHRp ;skip this part if moving downwards or not at all txa clc adc #$08 ;add eight to vertical coordinate and tax ;save as XGetHRp: txa ;move vertical coordinate to A ldx VRAM_Buffer1_Offset ;get vram buffer offset asl rol ;rotate d7 to d0 and d6 into carry pha ;save modified vertical coordinate to stack rol ;rotate carry to d0, thus d7 and d6 are at 2 LSB and #%00000011 ;mask out all bits but d7 and d6, then set ora #%00100000 ;d5 to get appropriate high byte of name table sta $01 ;address, then store lda $02 ;get saved page location from earlier and #$01 ;mask out all but LSB asl asl ;shift twice to the left and save with the ora $01 ;rest of the bits of the high byte, to get sta $01 ;the proper name table and the right place on it pla ;get modified vertical coordinate from stack and #%11100000 ;mask out low nybble and LSB of high nybble clc adc $00 ;add to horizontal part saved here sta $00 ;save as name table low byte lda Enemy_Y_Position,y cmp #$e8 ;if vertical position not below the bcc ExPRp ;bottom of the screen, we're done, branch to leave lda $00 and #%10111111 ;mask out d6 of low byte of name table address sta $00ExPRp: rts ;leave!InitPlatformFall: tya ;move offset of other platform from Y to X tax jsr GetEnemyOffscreenBits ;get offscreen bits lda #$06 jsr SetupFloateyNumber ;award 1000 points to player lda Player_Rel_XPos sta FloateyNum_X_Pos,x ;put floatey number coordinates where player is lda Player_Y_Position sta FloateyNum_Y_Pos,x lda #$01 ;set moving direction as flag for sta Enemy_MovingDir,x ;falling platformsStopPlatforms: jsr InitVStf ;initialize vertical speed and low byte sta Enemy_Y_Speed,y ;for both platforms and leave sta Enemy_Y_MoveForce,y rtsPlatformFall: tya ;save offset for other platform to stack pha jsr MoveFallingPlatform ;make current platform fall pla tax ;pull offset from stack and save to X jsr MoveFallingPlatform ;make other platform fall ldx ObjectOffset lda PlatformCollisionFlag,x ;if player not standing on either platform, bmi ExPF ;skip this part tax ;transfer collision flag offset as offset to X jsr PositionPlayerOnVPlat ;and position player appropriatelyExPF: ldx ObjectOffset ;get enemy object buffer offset and leave rts;--------------------------------YMovingPlatform: lda Enemy_Y_Speed,x ;if platform moving up or down, skip ahead to ora Enemy_Y_MoveForce,x ;check on other position bne ChkYCenterPos sta Enemy_YMF_Dummy,x ;initialize dummy variable lda Enemy_Y_Position,x cmp YPlatformTopYPos,x ;if current vertical position => top position, branch bcs ChkYCenterPos ;ahead of all this lda FrameCounter and #%00000111 ;check for every eighth frame bne SkipIY inc Enemy_Y_Position,x ;increase vertical position every eighth frameSkipIY: jmp ChkYPCollision ;skip ahead to last partChkYCenterPos: lda Enemy_Y_Position,x ;if current vertical position < central position, branch cmp YPlatformCenterYPos,x ;to slow ascent/move downwards bcc YMDown jsr MovePlatformUp ;otherwise start slowing descent/moving upwards jmp ChkYPCollisionYMDown: jsr MovePlatformDown ;start slowing ascent/moving downwardsChkYPCollision: lda PlatformCollisionFlag,x ;if collision flag not set here, branch bmi ExYPl ;to leave jsr PositionPlayerOnVPlat ;otherwise position player appropriatelyExYPl: rts ;leave
;--------------------------------;$00 - used as adder to position player horizontallyXMovingPlatform: lda #$0e ;load preset maximum value for secondary counter jsr XMoveCntr_Platform ;do a sub to increment counters for movement jsr MoveWithXMCntrs ;do a sub to move platform accordingly, and return value lda PlatformCollisionFlag,x ;if no collision with player, bmi ExXMP ;branch ahead to leavePositionPlayerOnHPlat: lda Player_X_Position clc ;add saved value from second subroutine to adc $00 ;current player's position to position sta Player_X_Position ;player accordingly in horizontal position lda Player_PageLoc ;get player's page location ldy $00 ;check to see if saved value here is positive or negative bmi PPHSubt ;if negative, branch to subtract adc #$00 ;otherwise add carry to page location jmp SetPVar ;jump to skip subtractionPPHSubt: sbc #$00 ;subtract borrow from page locationSetPVar: sta Player_PageLoc ;save result to player's page location sty Platform_X_Scroll ;put saved value from second sub here to be used later jsr PositionPlayerOnVPlat ;position player vertically and appropriatelyExXMP: rts ;and we are done here;--------------------------------DropPlatform: lda PlatformCollisionFlag,x ;if no collision between platform and player bmi ExDPl ;occurred, just leave without moving anything jsr MoveDropPlatform ;otherwise do a sub to move platform down very quickly jsr PositionPlayerOnVPlat ;do a sub to position player appropriatelyExDPl: rts ;leave;--------------------------------;$00 - residual value from subRightPlatform: jsr MoveEnemyHorizontally ;move platform with current horizontal speed, if any sta $00 ;store saved value here (residual code) lda PlatformCollisionFlag,x ;check collision flag, if no collision between player bmi ExRPl ;and platform, branch ahead, leave speed unaltered lda #$10 sta Enemy_X_Speed,x ;otherwise set new speed (gets moving if motionless) jsr PositionPlayerOnHPlat ;use saved value from earlier sub to position playerExRPl: rts ;then leave;--------------------------------MoveLargeLiftPlat: jsr MoveLiftPlatforms ;execute common to all large and small lift platforms jmp ChkYPCollision ;branch to position player correctlyMoveSmallPlatform: jsr MoveLiftPlatforms ;execute common to all large and small lift platforms jmp ChkSmallPlatCollision ;branch to position player correctlyMoveLiftPlatforms: lda TimerControl ;if master timer control set, skip all of this bne ExLiftP ;and branch to leave lda Enemy_YMF_Dummy,x clc ;add contents of movement amount to whatever's here adc Enemy_Y_MoveForce,x sta Enemy_YMF_Dummy,x lda Enemy_Y_Position,x ;add whatever vertical speed is set to current adc Enemy_Y_Speed,x ;vertical position plus carry to move up or down sta Enemy_Y_Position,x ;and then leave rtsChkSmallPlatCollision: lda PlatformCollisionFlag,x ;get bounding box counter saved in collision flag beq ExLiftP ;if none found, leave player position alone jsr PositionPlayerOnS_Plat ;use to position player correctlyExLiftP: rts ;then leave
Quote from: SMB2J-2Q on December 31, 2022, 08:27:28 PMCould anyone please look into the code for Super Mario Bros. to find out why the invisible platform bug exists (World 4-3 comes to mind)? In Super Mario Bros. 2 (Japan; "The Lost Levels" to us) there were some tweaks to correct some of the original NES SMB1's flaws, but not that one.
Quote from: TakuikaNinja on January 01, 2023, 08:24:20 PMThat is more of a graphical limitation than a code issue. The 8x8 sprites which make up the enemies (including moving platforms) are constantly shuffled to work around the 8-per-scanline limitation. It's just that the platforms are so wide that the scanline limit is already maxed out in most scenarios where multiple of them are onscreen.
Page created in 0.093 seconds with 19 queries.