; level_y_move_player_with_block_001 - If the player is standing on a block, move player
; level_y_move_player_rorl - right?
; level_y_move_player_lorr - or left?
; level_y_move_player_right - move right by controller
; level_y_move_player_left - move right by controller
; level_y_player_fall - is the player falling?
; level_y_handle_jumping - handle jumping
; level_y_player_up - move the player up, called by jumping

;------------------------------------
; level_y_move_player_with_block_001
;   
; Is player on block?
; If player is on block, move player left or right
;
level_y_move_player_with_block_001:
   PUSH BC                     ; Save registers
   PUSH DE                     ;
   PUSH HL                     ;
   PUSH AF                     ;

   LD a, (RAM_HPOS + 104)      ;
   LD (RAM_COLL_X1), a         ; Player
   LD a, (RAM_VPOS + 52)       ;    
   ADD a, 8                    ;   
   LD (RAM_COLL_Y1), a         ; Player  

;--------------------------------------   
   LD hl, RAM_HPOS             ;
   LD de, RAM_VPOS             ;
   
   LD a, (RAM_COLL_Y1)         ; Y match?
   LD b, a                     ;
   LD a, (de)                  ; Platform Y
   CP b                        ;   
   JP NZ, ly_block_001_skip    ; 

   LD a, (RAM_COLL_X1)         ; X match?
   LD b, a                     ;   
   LD a, (hl)                  ; Platform edge x
   CP b                        ;
   JP P, ly_block_001_skip     ;

   INC hl                      ; 4 sprites over
   INC hl                      ;   
   INC hl                      ;
   INC hl                      ;  
   INC hl                      ;
   INC hl                      ;  

   LD a, (RAM_COLL_X1)         ; X match?
   LD b, a                     ;   
   LD a, (hl)                  ; Platform edge x
   CP b                        ;
   JP M, ly_block_001_skip     ;
   
   CALL level_y_move_player_rorl ; Move with platform 
   JP lymprorl_no_fall         ; Exit loop if no fall

ly_block_001_skip:
;-------------------------------------- 
;--------------------------------------   
   LD hl, RAM_HPOS + 16        ;
   LD de, RAM_VPOS + 8         ;
 
   LD a, (RAM_COLL_Y1)         ; Y match?
   LD b, a                     ;
   LD a, (de)                  ; Platform Y
   CP b                        ; 
   JP NZ, ly_block_002_skip    ; 
   
   LD a, (RAM_COLL_X1)         ; X match?
   LD b, a                     ;   
   LD a, (hl)                  ; Platform edge x
   CP b                        ;
   JP P, ly_block_002_skip     ;

   INC hl                      ; 4 sprites over
   INC hl                      ;   
   INC hl                      ;
   INC hl                      ;  
   INC hl                      ;
   INC hl                      ;  

   LD a, (RAM_COLL_X1)         ; X match?
   LD b, a                     ;   
   LD a, (hl)                  ; Platform edge x
   CP b                        ;
   JP M, ly_block_002_skip     ;
   
   CALL level_y_move_player_lorr ; Move with platform 
   JP lymprorl_no_fall         ; Exit loop if no fall

ly_block_002_skip:
;--------------------------------------
;--------------------------------------   
   LD hl, RAM_HPOS + 32        ;
   LD de, RAM_VPOS + 16        ;
 
   LD a, (RAM_COLL_Y1)         ; Y match?
   LD b, a                     ;
   LD a, (de)                  ; Platform Y
   CP b                        ; 
   JP NZ, ly_block_003_skip    ; 
   
   LD a, (RAM_COLL_X1)         ; X match?
   LD b, a                     ;   
   LD a, (hl)                  ; Platform edge x
   CP b                        ;
   JP P, ly_block_003_skip     ;

   INC hl                      ; 4 sprites over
   INC hl                      ;   
   INC hl                      ;
   INC hl                      ;  
   INC hl                      ;
   INC hl                      ;  

   LD a, (RAM_COLL_X1)         ; X match?
   LD b, a                     ;   
   LD a, (hl)                  ; Platform edge x
   CP b                        ;
   JP M, ly_block_003_skip     ;
   
   CALL level_y_move_player_rorl ; Move with platform 
   JP lymprorl_no_fall         ; Exit loop if no fall

ly_block_003_skip:
;--------------------------------------
;--------------------------------------   
   LD hl, RAM_HPOS + 48        ;
   LD de, RAM_VPOS + 24        ;
 
   LD a, (RAM_COLL_Y1)         ; Y match?
   LD b, a                     ;
   LD a, (de)                  ; Platform Y
   CP b                        ; 
   JP NZ, ly_block_004_skip    ; 
   
   LD a, (RAM_COLL_X1)         ; X match?
   LD b, a                     ;   
   LD a, (hl)                  ; Platform edge x
   CP b                        ;
   JP P, ly_block_004_skip     ;

   INC hl                      ; 4 sprites over
   INC hl                      ;   
   INC hl                      ;
   INC hl                      ;  
   INC hl                      ;
   INC hl                      ;  

   LD a, (RAM_COLL_X1)         ; X match?
   LD b, a                     ;   
   LD a, (hl)                  ; Platform edge x
   CP b                        ;
   JP M, ly_block_004_skip     ;
   
   CALL level_y_move_player_lorr ; Move with platform 
   JP lymprorl_no_fall         ; Exit loop if no fall

ly_block_004_skip:
;--------------------------------------
;--------------------------------------   
   LD hl, RAM_HPOS + 64        ;
   LD de, RAM_VPOS + 32        ;
 
   LD a, (RAM_COLL_Y1)         ; Y match?
   LD b, a                     ;
   LD a, (de)                  ; Platform Y
   CP b                        ; 
   JP NZ, ly_block_005_skip    ; 
   
   LD a, (RAM_COLL_X1)         ; X match?
   LD b, a                     ;   
   LD a, (hl)                  ; Platform edge x
   CP b                        ;
   JP P, ly_block_005_skip     ;

   INC hl                      ; 4 sprites over
   INC hl                      ;   
   INC hl                      ;
   INC hl                      ;  
   INC hl                      ;
   INC hl                      ;  

   LD a, (RAM_COLL_X1)         ; X match?
   LD b, a                     ;   
   LD a, (hl)                  ; Platform edge x
   CP b                        ;
   JP M, ly_block_005_skip     ;
   
   CALL level_y_move_player_rorl ; Move with platform 
   JP lymprorl_no_fall         ; Exit loop if no fall

ly_block_005_skip:
;--------------------------------------
; Player is falling if not jumping
   CALL level_y_player_fall    ;
   
lymprorl_no_fall:   
   POP AF                      ; Restore registers
   POP HL                      ;
   POP DE                      ;
   POP BC                      ;
   RET                         ; End subroutine   
   
;----------------------------
; level_y_move_player_rorl
;
level_y_move_player_rorl:
   PUSH AF                     ; Save registers
   
   LD a, (RAM_FOE_STATE_1)     ; move fast blocks
   CP $00                      ;
   CALL Z, level_y_move_player_right     ;
   CP $7F                      ;
   CALL Z, level_y_move_player_left    ;

   LD a, 0                      ; Transition state
   LD (RAM_JUMP_STATE), a       ;
   
   POP AF                      ; Restore registers  
   RET                         ; End subroutine  	
   
;----------------------------
; level_y_move_player_lorr
;
level_y_move_player_lorr:
   PUSH AF                     ; Save registers
   
   LD a, (RAM_FOE_STATE_1)     ; move fast blocks
   CP $00                      ;
   CALL Z, level_y_move_player_left     ;
   CP $7F                      ;
   CALL Z, level_y_move_player_right    ;

   LD a, 0                      ; Transition state
   LD (RAM_JUMP_STATE), a       ;   
   
   POP AF                      ; Restore registers  
   RET                         ; End subroutine  
   
;----------------------------
; level_y_move_player_right
;
level_y_move_player_right:
   PUSH BC                     ; Save registers
   PUSH DE                     ;
   PUSH HL                     ;
   PUSH AF                     ;

; Change position   
   LD hl, RAM_HPOS + 84        ; Start of player HPOS
   LD b, 12                    ; 12 sprites
   
lympr_loop_01:   
   INC (hl)                    ; Go right
   INC hl                      ; Move address
   INC hl                      ;
   DEC b                       ;
   JP NZ, lympr_loop_01        ;   
 
; Animate tiles
lympr_animate:
   LD a, (RAM_FRAME_CTR)       ; Change based on frame
   AND $18                     ; Mask unwanted bits
   CP $00                      ;
   JP Z, lympr_frame0          ;
   CP $08                      ;
   JP Z, lympr_frame1          ;
   CP $10                      ;
   JP Z, lympr_frame0          ;   
   CP $18                      ;
   JP Z, lympr_frame2          ;
   
lympr_frame0:   
   LD de, level_x_run_frame_R0 ;
   JP lxmpr_frame_done         ;
lympr_frame1:   
   LD de, level_x_run_frame_R1 ;  
   JP lxmpr_frame_done         ;
lympr_frame2:   
   LD de, level_x_run_frame_R2 ;

lympr_frame_done: 
   CALL lxmpl_subcopy          ;
   
   POP AF                      ; Restore registers
   POP HL                      ;
   POP DE                      ;
   POP BC                      ;
   RET                         ; End subroutine    
   
;----------------------------
; level_y_move_player_left
;
level_y_move_player_left:
   PUSH BC                     ; Save registers
   PUSH DE                     ;
   PUSH HL                     ;
   PUSH AF                     ;

; Change position   
   LD hl, RAM_HPOS + 84        ; Start of player HPOS
   LD b, 12                    ; 12 sprites
   
lympl_loop_01:   
   DEC (hl)                    ; Go left
   INC hl                      ; Move address
   INC hl                      ;
   DEC b                       ;
   JP NZ, lympl_loop_01        ;   
 
; Animate tiles
lympl_animate:
   LD a, (RAM_FRAME_CTR)       ; Change based on frame
   AND $18                     ; Mask unwanted bits
   CP $00                      ;
   JP Z, lympl_frame0          ;
   CP $08                      ;
   JP Z, lympl_frame1          ;
   CP $10                      ;
   JP Z, lympl_frame0          ;   
   CP $18                      ;
   JP Z, lympl_frame2          ;
   
lympl_frame0:   
   LD de, level_x_run_frame_L0 ;
   JP lxmpr_frame_done         ;
lympl_frame1:   
   LD de, level_x_run_frame_L1 ;  
   JP lxmpr_frame_done         ;
lympl_frame2:   
   LD de, level_x_run_frame_L2 ;

lympl_frame_done: 
   CALL lxmpl_subcopy          ;
   
   POP AF                      ; Restore registers
   POP HL                      ;
   POP DE                      ;
   POP BC                      ;
   RET                         ; End subroutine      
   
;-------------------------   
; level_y_player_fall
;
level_y_player_fall: 
   PUSH BC                     ; Save registers
   PUSH DE                     ;
   PUSH HL                     ;
   PUSH AF                     ;
   
   LD hl, RAM_VPOS + 42        ; Player 1 falls
   LD b, 12                    ;
lypf_pfalling_loop:   
   INC (hl)                    ; Go down
   INC hl                      ; Next sprite
   DEC b                       ;
   JP NZ, lypf_pfalling_loop   ;
   
   LD de, level_x_jump_frame   ; Falling tiles
   CALL lxmpl_subcopy          ;
   
   LD a, 2                     ; Still falling
   LD (RAM_JUMP_STATE), a      ;     
   
   POP AF                      ; Restore registers
   POP HL                      ;
   POP DE                      ;
   POP BC                      ;
   RET                         ; End subroutine  

;---------------------------------
; level_y_handle_jumping
;
level_y_handle_jumping:
   PUSH BC                      ; Save registers
   PUSH DE                      ;
   PUSH HL                      ;
   PUSH AF                      ;   

   LD a, (RAM_JUMP_STATE)       ;
   CP 0                         ; on ground?
   JP Z, lyhj_ground            ;
   CP 1                         ; rising to max?
   JP Z, lyhj_rising            ;
   CP 2                         ; falling to ground
   JP Z, lyhj_falling           ;

; Player is on the ground   
lyhj_ground: 
   IN a, (PORT_INPUT1)          ; Press jump?
   BIT 4, a                     ; Go up? 
   JP NZ, lyhj_falling          ; Do not start a jump. Could fall.  
   
   LD a, 1                      ; Transition state
   LD (RAM_JUMP_STATE), a       ;
   CALL sound_jump_sfx          ;
   
   JP lyhj_stay_put             ;

; Player is rising   
lyhj_rising:
   IN a, (PORT_INPUT1)          ; Keep going up if button is pressed
   BIT 4, a                     ; Go up? 
   CALL Z, level_y_player_up    ; Go up 
   
   IN a, (PORT_INPUT1)          ; Keep going up if button is pressed
   BIT 4, a                     ; Go up? 
   JP Z, lyhj_stay_put          ;

   LD a, 2                      ; Transition state
   LD (RAM_JUMP_STATE), a       ;
   LD a, 0                      ; Reset jump height
   LD (RAM_JUMP_HEIGHT), a      ;   
   JP lyhj_stay_put             ;
   
; Player is falling   
lyhj_falling:
   CALL level_y_move_player_with_block_001 ; Move player if on a block, else fall
   
lyhj_stay_put:   
   POP AF                       ; Restore registers
   POP HL                       ;
   POP DE                       ;
   POP BC                       ;
   RET                          ; End subroutine  
   
;----------------------------------
; level_x_player_up
;
level_y_player_up:  
   PUSH BC                      ; Save registers
   PUSH DE                      ;
   PUSH HL                      ;
   PUSH AF                      ; 
   
   LD hl, RAM_VPOS + 42         ; Player 1 jumps
   LD b, 12                     ;
   
; Scroll up if at limit.
   LD a, (hl)                   ;
   CP $50                       ;
   JP NZ, lypf_prising_loop     ; 
   
   LD a, (RAM_SCROLL_CTR)       ;
   DEC a                        ; Go up!
   CP $FF                       ;
   JP NZ, lypf_skip_save_vscrl  ;
   
   LD a, (RAM_PEDOMETER)        ; Increment pedometer
   INC a                        ;
   LD (RAM_PEDOMETER), a        ;
   CALL level_x_increment_score ; 5 points per screen
   CALL level_x_increment_score ;
   CALL level_x_increment_score ;
   CALL level_x_increment_score ;
   CALL level_x_increment_score ;
   
   LD a, $DF                    ; Skip $E0-$FF
lypf_skip_save_vscrl:   
   LD (RAM_SCROLL_CTR), a       ;
   
   
   CALL vertical_scroll         ; Perform vertical scrolling
   
   LD de, RAM_VPOS              ; Push the blocks down
   LD a, 40                     ;
   LD c, a                      ;
lypf_blocks_down_loop:    
   LD a, (de)                   ;
   INC a                        ;
   
   CP $C8                       ; Do not allow $D0!
   JP NZ, lypf_skip_blk_reset   ; 
   
   LD a, $00                    ; Reset platform position
   
lypf_skip_blk_reset:  
   LD (de), a                   ;
   INC de                       ;
   DEC c                        ;
   JP NZ, lypf_blocks_down_loop ;
   
   JP lypf_skip_up              ; Let screen scroll up
   
lypf_prising_loop:   
   DEC (hl)                     ; Go up
   INC hl                       ; Next sprite
   DEC b                        ;
   JP NZ, lypf_prising_loop     ;

lypf_skip_up:
   LD de, level_x_jump_frame    ; Falling tiles
   CALL lxmpl_subcopy           ;   
   
   LD a, (RAM_JUMP_HEIGHT)      ; What is the current state? 
   INC a                        ; Start count up to the maximum
   LD (RAM_JUMP_HEIGHT), a      ;

   CP 7*8                       ; Jump up 3 1/2 blocks maximum
   JP NZ, lypf_end000           ;
   LD a, 2                      ; Transition state
   LD (RAM_JUMP_STATE), a       ;
   LD a, 0                      ; Reset jump height
   LD (RAM_JUMP_HEIGHT), a      ;
   
lypf_end000:   
   POP AF                       ; Restore registers
   POP HL                       ;
   POP DE                       ;
   POP BC                       ;
   RET                          ; End subroutine   
   
   