Poor Sam got nerfed. Now his force range starts out really low (about 5 characters), but can be improved by picking the proper extra. And finally cheat keys appear. Press 1 to advance to the next stage.
We modify the existing SamUseForce routine to check for a max range (stored in PLAYER_FORCE_RANGE):
If the extra is picked up the range is simply increased to a max of 38 (Remember, screen width is 40 characters):
Adding cheat keys is way easier. Since the Kernal (yes, with an 'a') comes with a keyboard check routine we just call that. Notice that for this to work you must not have the Kernal disabled (remember the memory layout in the beginning):
And still something new: Element Areas. A new primitive that fills an area with m/n repeats of an element:
Previous Step Next Step
We modify the existing SamUseForce routine to check for a max range (stored in PLAYER_FORCE_RANGE):
;------------------------------------------------------------ ;sam uses power ;returns 1 when holding an enemy ;------------------------------------------------------------ !zone SamUseForce SamUseForce lda SPRITE_HELD beq .NoSpriteHeldNow lda #1 rts .NoSpriteHeldNow stx PARAM6 ldy SPRITE_CHAR_POS_Y,x dey lda SCREEN_LINE_OFFSET_TABLE_LO,y sta ZEROPAGE_POINTER_1 lda SCREEN_BACK_LINE_OFFSET_TABLE_HI,y sta ZEROPAGE_POINTER_1 + 1 ldy SPRITE_CHAR_POS_X,x lda #0 sta PARAM7 .ShotContinue lda PARAM7 cmp PLAYER_FORCE_RANGE beq .OutOfRange inc PARAM7 ;y contains shot X pos ;PARAM6 contains x sprite index of player ldx PARAM6 lda SPRITE_DIRECTION,x beq .ShootRight ;shooting left dey lda (ZEROPAGE_POINTER_1),y jsr IsCharBlocking beq .CheckHitEnemy ldx PARAM6 .ShotDoneMiss .OutOfRange lda #0 .ShotDoneHit rts .ShootRight iny lda (ZEROPAGE_POINTER_1),y jsr IsCharBlocking bne .ShotDoneMiss .CheckHitEnemy ;hit an enemy? ldx #0 .CheckEnemy stx PARAM2 sty PARAM1 lda SPRITE_ACTIVE,x beq .CheckNextEnemy tax lda IS_TYPE_ENEMY,x beq .CheckNextEnemy ldx PARAM2 ;is vulnerable? lda SPRITE_STATE,x cmp #128 bpl .CheckNextEnemy ;sprite pos matches on x? lda SPRITE_CHAR_POS_X,x cmp PARAM1 bne .CheckNextEnemy ;sprite pos matches on y? ldy PARAM6 lda SPRITE_CHAR_POS_Y,x cmp SPRITE_CHAR_POS_Y,y beq .EnemyHit ;sprite pos matches on y + 1? clc adc #1 cmp SPRITE_CHAR_POS_Y,y beq .EnemyHit ;sprite pos matches on y - 1? sec sbc #2 cmp SPRITE_CHAR_POS_Y,y bne .CheckNextEnemy .EnemyHit ;enemy hit! stx SPRITE_HELD inc SPRITE_HELD ;call enemy hit behaviour ldy SPRITE_ACTIVE,x ;enemy is active dey dey lda ENEMY_HIT_BEHAVIOUR_TABLE_LO,y sta ZEROPAGE_POINTER_1 lda ENEMY_HIT_BEHAVIOUR_TABLE_HI,y sta ZEROPAGE_POINTER_1 + 1 ;set up return address for rts lda #>( .ShotDoneHit - 1 ) pha lda #<( .ShotDoneHit - 1 ) pha ;1 as return value lda #1 jmp (ZEROPAGE_POINTER_1) .CheckNextEnemy ldx PARAM2 ldy PARAM1 inx cpx #8 beq .NoEnemyHit jmp .CheckEnemy .NoEnemyHit jmp .ShotContinue
If the extra is picked up the range is simply increased to a max of 38 (Remember, screen width is 40 characters):
.EffectIncForceRange cpx #0 beq .DeanDoesNotUseForce lda PLAYER_FORCE_RANGE clc adc #2 sta PLAYER_FORCE_RANGE cmp #38 bcs .NotTooLong lda #38 sta PLAYER_FORCE_RANGE .NotTooLong jmp .RemoveItem
Adding cheat keys is way easier. Since the Kernal (yes, with an 'a') comes with a keyboard check routine we just call that. Notice that for this to work you must not have the Kernal disabled (remember the memory layout in the beginning):
JSR $FFE4 ;GETIN BEQ .NOCHEAT CMP #49 bne .NOCHEAT ;jump to next level jsr StartLevel inc LEVEL_NR jsr BuildScreen jsr CopyLevelToBackBuffer jsr DisplayGetReady .NOCHEAT
And still something new: Element Areas. A new primitive that fills an area with m/n repeats of an element:
!zone LevelElementArea LevelElementArea ;!byte LD_ELEMENT_AREA,24,16,5,1,EL_SN_BROWN_ROCK ;X pos iny lda (ZEROPAGE_POINTER_1),y sta PARAM1 sta PARAM10 ;Y pos iny lda (ZEROPAGE_POINTER_1),y sta PARAM2 ;x count iny lda (ZEROPAGE_POINTER_1),y sta PARAM7 sta PARAM9 ;y count iny lda (ZEROPAGE_POINTER_1),y sta PARAM8 ;type iny lda (ZEROPAGE_POINTER_1),y sta PARAM3 ;store y for later tya pha .NextElementRow jsr DrawLevelElement dec PARAM7 beq .RowDone lda PARAM1 clc adc PARAM4 sta PARAM1 jmp .NextElementRow .RowDone lda PARAM2 clc adc PARAM5 sta PARAM2 lda PARAM9 sta PARAM7 lda PARAM10 sta PARAM1 dec PARAM8 bne .NextElementRow jmp NextLevelData
Previous Step Next Step
Attached Files
-
step47.zip (120.37K)
downloads: 48
Create a custom theme




