;;;;;;;;;;;;;-------LICENSE NOTICE-----------;;;;;;;;;;;;;;;
;; MIT License

;; Copyright (c) 2021 DreamyZombies Studio

;; Permission is hereby granted, free of charge, to any person obtaining a copy
;; of this software and associated documentation files (the "Software"), to deal
;; in the Software without restriction, including without limitation the rights
;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
;; copies of the Software, and to permit persons to whom the Software is
;; furnished to do so, subject to the following conditions:

;; The above copyright notice and this permission notice shall be included in all
;; copies or substantial portions of the Software.

;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
;; SOFTWARE.
;;
;; Authors:
;;  Abderrahamane Guermat Benaouali (agb139@alu.ua.es)
;;  Jorge Angulo Espí (jae17@alu.ua.es)
;;  Sami Hadj-Djilani (sh101@alu.ua.es)


;;
;; INPUT SYSTEM
;;

.include "../cpct_functions.h.s"
.include "../sys/render.h.s"
.include "../sys/physics.h.s"
.include "../man/game.h.s"
.include "../man/input.h.s"

.globl _main
.globl _sprite_hero1
.globl _sprite_hero2
.globl play_jump
_jumps:: .db 0
_isJumping:: .db 0
_SpriteOrder:: .db 0 ;0:herox_r 1:herox
_max_aceleration == 2
_pixels = 4
_waitJump_with_wall = 20
_pixelMovs:: .db 4
_aceleration:: .db 4
_canJumpWall:: .db 0

;;   INPUT: 
;;      IX: Pointer to entity
;; DESTROY: A, HL, C
user_input::

    call cpct_scanKeyboard_asm

    ld  a, (_canJumpWall)
    cp a, #1
    jp z, not_jumping_no_update

    ld  a, (_isJumping)
    ld b, a

    sub a, #1
    jp z, jumping

    ld a, b
    sub a, #2
    jp z, from_jump

not_jumping:

    ld a, #0
    ld (_isJumping), a

not_jumping_no_update:

    ld  hl, #0x0808 ;Key_Q
    call cpct_isKeyPressed_asm
    jp  nz,  updateUp

jumping:

    ld  hl, #0x0803 ;Key_P
    call cpct_isKeyPressed_asm
    jp  nz,  updateRight

    ld  hl, #0x0404 ;Key_O
    call cpct_isKeyPressed_asm
    jp  nz,  updateLeft

    ld a, #_pixels
    ld (_aceleration), a
    ld (_pixelMovs), a
    
    ret

from_jump:

    ld  hl, #0x0808 ;Key_Q
    call cpct_isKeyPressed_asm
    jp  nz,  jumping

    ld a, #0
    ld (_isJumping), a
    jp not_jumping

;;   INPUT: 
;;      IX: Pointer to entity
updateUp:

    ld a, #0
    ld (_canJumpWall), a

    ld a, #1
    ld  (_isJumping), a
    
    call can_move_hero_left
    jp nz, can_jump_left
ret1:   
    call can_move_hero_rigth
    jp nz, can_jump_right
ret2:
    call can_move_hero_down
    call nz, block_check_down

    call can_move_hero_down
    jp nz, jmps_before

    ld a, #0
    ld  (_isJumping), a
    
    ret

jmps_before:

    ld a, #0
    ld (_isJumping), a

    jp jmps

jmpsL:

    ld a, #1
    ld  (_isJumping), a

    ld a, #0
    ld (_canJumpWall), a

    ld e, #_waitJump_with_wall

    wait_loop_jump_wallL:
        halt
        dec e
        jp nz, wait_loop_jump_wallL
    ld a, 0(ix)
    add a, #2
    ld 0(ix), a

    ld a, #2
    ld 6(ix), a
    jp jmps

jmpsR:

    ld a, #1
    ld  (_isJumping), a

    ld a, #0
    ld (_canJumpWall), a

    ld e, #_waitJump_with_wall

    wait_loop_jump_wallR:
        halt
        dec e
        jp nz, wait_loop_jump_wallR

    ld a, 0(ix)
    sub a, #2
    ld 0(ix), a

    ld a, #1
    ld 6(ix), a

jmps:

    call can_move_hero_up
    jp nz, block_check_up
    ld a, #7
    ld  (_jumps), a

    ld a, #_max_aceleration
    ld (_aceleration), a
    ld (_pixelMovs), a

    push ix
    call play_jump
    pop ix
    
    ret
;; Comprobamos las interacciones con los bloques
block_check_up::

    ;; PINCHO
    ld b, a
    sub a, #8
    jp z, game_manager_death

    ;; PINCHO
    ld a, b
    sub a, #20
    jp z, game_manager_death

    ;; PINCHO
    ld a, b
    sub a, #25
    jp z, game_manager_death

    ;; PINCHO
    ld a, b
    sub a, #26
    jp z, game_manager_death


    ;; LLAVE 1
    ld a, b
    sub a, #10
    jp z, game_manager_level_update

    ;; LLAVE 2
    ld a, b
    sub a, #11
    jp z, game_manager_level_update

    ;; LLAVE HUECO BLANCO
    ld a, b
    sub a, #17
    jp z, game_manager_level_update
    
    ret

jmpsDeath:

    ld  a, (_jumps)
    ld a, #7
    ld  (_jumps), a
    jp game_manager_death
ret 



;;   INPUT: 
;;      IX: Pointer to entity
updateDown::

    call can_move_hero_down
    jp nz, block_check_down
    
    ld a, 1(ix)
    add a, #1
    ld 1(ix), a

    ld a, #1
    ld  (_isJumping), a

    call can_move_hero_down
    jp nz, block_check_down

    ld a, 1(ix)
    add a, #1
    ld 1(ix), a

    ld a, #1
    ld  (_isJumping), a

    ret
;; Comprobamos las interacciones con los bloques
block_check_down:

    ;; PINCHO
    ld b, a
    sub a, #8
    ;jp z, updateDownDeath
    jp z, game_manager_death 

    ;; PINCHO
    ld a, b
    sub a, #20
    jp z, game_manager_death

    ;; PINCHO
    ld a, b
    sub a, #23
    ;jp z, updateDownDeath
    jp z, game_manager_death 

    ;; PINCHO
    ld a, b
    sub a, #24
    ;jp z, updateDownDeath
    jp z, game_manager_death 

    ;; LLAVE 1
    ld a, b
    sub a, #10
    jp z, game_manager_level_update

    ;; LLAVE 2
    ld a, b
    sub a, #11
    jp z, game_manager_level_update

    ;; LLAVE HUECO BLANCO
    ld a, b
    sub a, #17
    jp z, game_manager_level_update

    ;; BLOQUE SÓLIDO
    ld  a, (_isJumping)
    ld b, a
    sub a, #1
    jp z, updateIsJumping
    
    ret
;;   INPUT: 
;;      IX: Pointer to entity
updateDownDeath::

    ld a, 1(ix)
    add a, #1
    ld 1(ix), a
    jp game_manager_death
    ret
    

;;   INPUT: 
;;      IX: Pointer to entity
updateRight:

    call can_move_hero_rigth
    jp nz, block_check_right

    ld a, #0
    ld  (_canJumpWall), a

    call can_move_hero_down
    call z, downing

    ld  a, (_pixelMovs)
    dec a
    jp z, moveXRight
    ld (_pixelMovs), a

    ld a, #2
    ld 6(ix), a

    ret

moveXRight:

    ld a, (_SpriteOrder)
    dec a
    jp z, continueR
    ld a, #1
    ld (_SpriteOrder), a
    jp hereR
continueR:
    ld a, #0
    ld (_SpriteOrder), a
hereR:

    ld a, 0(ix)
    add a, #1
    ld 0(ix), a
    ld a, #2
    ld 6(ix), a

    ld a, (_aceleration)
    sub a, #1
    ld (_aceleration), a
    ld (_pixelMovs), a
    jp z, set_max_aceleration
    
    ret

set_max_aceleration:
    ld a, #3
    ld (_aceleration), a
    ld (_pixelMovs), a
    ret


;; Comprobamos las interacciones con los bloques
block_check_right:

    ;; PINCHO
    ld b, a
    sub a, #8
    ;;jp z, UpdateRightDeath
    jp z, game_manager_death

    ;; PINCHO
    ld a, b
    sub a, #20
    jp z, game_manager_death

    ;; PINCHO
    ld a, b
    sub a, #21
    jp z, game_manager_death 

    ;; LLAVE 1
    ld a, b
    sub a, #10
    jp z, game_manager_level_update

    ;; LLAVE 2
    ld a, b
    sub a, #11
    jp z, game_manager_level_update

    ;; LLAVE HUECO BLANCO
    ld a, b
    sub a, #17
    jp z, game_manager_level_update

    ld a, b
    sub a, #9
    jp z, canJumpWall
    jp cantJumpWall

UpdateRightDeath:

    ld  a, (_pixelMovs)
    dec a
    jp z, moveXRightDeath
    ld (_pixelMovs), a

    ld  hl, (_sprite_hero2)
    rrc (hl)
    ld  (_sprite_hero2), hl

    ld a, #2
    ld 6(ix), a
    jp game_manager_death
    ret

moveXRightDeath:
    ld a, 0(ix)
    add a, #1
    ld 0(ix), a
    ld a, #2
    ld 6(ix), a

    ld a, (_aceleration)
    ld (_pixelMovs), a
    jp game_manager_death
    ret

;;   INPUT: 
;;      IX: Pointer to entity
updateLeft:

    call can_move_hero_left
    jp nz, block_check_left

    ld a, #0
    ld  (_canJumpWall), a
    
    call can_move_hero_down
    call z, downing

    ld  a, (_pixelMovs)
    dec a
    jp z, moveXLeft
    ld (_pixelMovs), a
    
    ld a, #1
    ld 6(ix), a

    ret

downing::
    ld a, #1
    ld (_aceleration), a
    ld (_pixelMovs), a
    ret

moveXLeft:

    ld a, (_SpriteOrder)
    dec a
    jp z, continue
    ld a, #1
    ld (_SpriteOrder), a
    jp here
continue:
    ld a, #0
    ld (_SpriteOrder), a
here:

    ld a, 0(ix)
    sub a, #1
    ld 0(ix), a    
    ld a, #1
    ld 6(ix), a
    
    ld a, (_aceleration)
    sub a, #1
    
    ld (_aceleration), a
    ld (_pixelMovs), a
    jp z, set_max_aceleration
    
    ret 

;; Comprobamos las interacciones con los bloques
block_check_left:

    ;; PINCHO
    ld b, a
    sub a, #8
    ;jp z, updateLeftDeath
    jp z, game_manager_death

    ;; PINCHO
    ld a, b
    sub a, #20
    jp z, game_manager_death 

    ;; PINCHO
    ld a, b
    sub a, #22
    jp z, game_manager_death 

    ;; LLAVE 1
    ld a, b
    sub a, #10
    jp z, game_manager_level_update

    ;; LLAVE 2
    ld a, b
    sub a, #11
    jp z, game_manager_level_update

    ;; LLAVE HUECO BLANCO
    ld a, b
    sub a, #17
    jp z, game_manager_level_update

    ld a, b
    sub a, #9
    jp z, canJumpWall

cantJumpWall:
    ld a, #0
    ld (_canJumpWall), a

    ret

canJumpWall:
    ld a, #1
    ld (_canJumpWall), a

    ret
;;   INPUT: 
;;      IX: Pointer to entity
updateLeftDeath:

    ld  a, (_pixelMovs)
    dec a
    jp z, moveXLeftDeath
    ld (_pixelMovs), a

    ld  hl, (_sprite_hero1)
    rlc (hl)
    ld  (_sprite_hero1), hl
    
    ld a, #1
    ld 6(ix), a
    jp game_manager_death
    ret

moveXLeftDeath:

    ld a, 0(ix)
    sub a, #1
    ld 0(ix), a    
    ld a, #1
    ld 6(ix), a
    
    ld a, (_aceleration)
    ld (_pixelMovs), a
    jp game_manager_death
    ret


can_jump_left:

    ld b, a
    cp a, #9
    jp z, jmpsL
    
    jp ret1

can_jump_right:

    ld b, a
    cp a, #9
    jp z, jmpsR

    jp ret2

updateIsJumping:
    ld a, #2
    ld  (_isJumping), a

    ret