;MIT License

;Copyright (c) 2021 Fedora Adventures Pixeltronics

;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.

.include "cpct_functions.h.s"
.include "render.h.s"
.include "man/entity.h.s"

rendersys_init::

    ld c, #0
    call cpct_setVideoMode_asm

    cpctm_setBorder_asm HW_WHITE

    ld c, #0
    call cpct_setVideoMode_asm

    ld hl, #_fedora_pal
    ld de, #16
    call cpct_setPalette_asm

    ret

rendersys_update::

    _renderloop:
    ;;Al usar push guardamos el valor de af en la pila
    ;;para que no se pierda el valor
    ;;ya que será el contador de las entidades que tendremos
    ;;que renderizar
    push af

    ld a, #(e_cmps_player) ;;Compruebo si es el personaje
    ld b, e_cmps(ix)
    and b
    jp nz, player_render

    ld a, #(e_cmps_door) ;;Compruebo si es la puerta
    ld b, e_cmps(ix)
    and b
    jp nz, puertaAbierta_render

    ld a, #(e_cmps_treasure) ;;Compruebo si es el diamante
    ld b, e_cmps(ix)
    and b
    jp nz, borrarTreasure_render

    ld a, #(e_cmps_platform) ;;Compruebo si son las plataformas
    ld b, e_cmps(ix)
    and b
    jp nz, platform_render

    ld a, #(e_cmps_alive | e_cmps_render)
    ld b, e_cmps(ix)                    
    and b
    jr nz, update_render

    pop af
    dec a
    ret z

    ld bc, #entity_size
    add ix, bc
    jr _renderloop

    ret
    
update_render::
    ;;borrarEntidad
    ld e, e_prev_ptr+0(ix)
    ld d, e_prev_ptr+1(ix)
    xor a       ;;A = 0
    ld c, e_w(ix)
    ld b, e_h(ix)
    call cpct_drawSolidBox_asm

    ;;renderizo
    ld de, #0XC000
    ld b, e_y(ix)
    ld c, e_x(ix)
    call cpct_getScreenPtr_asm
    ex de, hl

    ;;Guardo e_prev_ptr para borrar en el próximo ciclo
    ld e_prev_ptr+0(ix), e
    ld e_prev_ptr+1(ix), d

    ld l, e_ptr_sprite+0(ix)
    ld h, e_ptr_sprite+1(ix)
    ;ld hl, #_fedora_sprites_00
    ld b, e_h(ix) 
    ld c, e_w(ix)
    call cpct_drawSprite_asm

    pop af
    dec a
    ret z

    ld bc, #entity_size
    add ix, bc
    jr _renderloop

player_render::
    ;;borrarEntidad
    ld e, e_prev_ptr+0(ix)
    ld d, e_prev_ptr+1(ix)
    xor a       ;;A = 0
    ld c, e_w(ix)
    ld b, e_h(ix)
    call cpct_drawSolidBox_asm

    ;;renderizo
    ld de, #0XC000
    ld b, e_y(ix)
    ld c, e_x(ix)
    call cpct_getScreenPtr_asm
    ex de, hl

    ;;Guardo e_prev_ptr para borrar en el próximo ciclo
    ld e_prev_ptr+0(ix), e
    ld e_prev_ptr+1(ix), d
    
    ld a, #(e_cmps_phy_jumping) ;;Compruebo si está saltando
    ld b, e_cmps_physics(ix)
    and b
    jp nz, player_jump

    ld a, #(e_cmps_phy_falling) ;;Compruebo si está cayendo
    ld b, e_cmps_physics(ix)
    and b
    jp nz, player_fall

    ld a, #(e_cmps_phy_left) ;;Compruebo si se mueve a la izquierda
    ld b, e_cmps_physics(ix)
    and b
    jp nz, player_left1

    ld a, #(e_cmps_phy_right) ;;Compruebo si se mueve a la derecha
    ld b, e_cmps_physics(ix)
    and b
    jp nz, player_right1

    ld l, e_ptr_sprite+0(ix)
    ld h, e_ptr_sprite+1(ix)
    
    ld b, e_h(ix) 
    ld c, e_w(ix)
    call cpct_drawSprite_asm

    _entityNext:

    pop af
    dec a
    ret z

    ld bc, #entity_size
    add ix, bc
    jp _renderloop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Renderización de movimientos del personaje;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

player_left1::
    ld a, e_movimiento1(ix)
    cp #0
    jp nz, primer_Mov_Left

    jp player_left2

    jp _entityNext

player_left2::
    ld a, e_movimiento2(ix)
    cp #0
    jp nz, segundo_Mov_Left

    jp player_left3

    jp _entityNext

player_left3::
    ld a, e_movimiento3(ix)
    cp #0
    jp nz, tercer_Mov_Left

    jp player_left1

    jp _entityNext

player_right1::
    ld a, e_movimiento1(ix)
    cp #0
    jp nz, primer_Mov_Right

    jp player_right2

    jp _entityNext

player_right2::
    ld a, e_movimiento2(ix)
    cp #0
    jp nz, segundo_Mov_Right

    jp player_right3

    jp _entityNext

player_right3::
    ld a, e_movimiento3(ix)
    cp #0
    jp nz, tercer_Mov_Right

    jp player_right1

    jp _entityNext

player_jump::
    ld a, #(e_cmps_phy_left) ;;Compruebo si se mueve a la izquierda
    ld b, e_cmps_physics(ix)
    and b
    jp nz, jump_left

    ld a, #(e_cmps_phy_right) ;;Compruebo si se mueve a la izquierda
    ld b, e_cmps_physics(ix)
    and b
    jp nz, jump_right

    ld hl, #_fedora_sprites_07
    ld b, e_h(ix) 
    ld c, e_w(ix)
    call cpct_drawSprite_asm

    jp _entityNext

player_fall::
    ld hl, #_fedora_sprites_08
    ld b, e_h(ix) 
    ld c, e_w(ix)
    call cpct_drawSprite_asm

    jp _entityNext


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Renderización de movimientos a la izquierda del personaje;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

primer_Mov_Left::
   dec a
   ld e_movimiento1(ix), a
   ld hl, #_fedora_sprites_05
   ld b, e_h(ix) 
   ld c, e_w(ix)
   call cpct_drawSprite_asm

   ld a, e_movimiento1(ix)
   cp #0
   jp z, reiniciarValor2
   
   jp _entityNext

segundo_Mov_Left::
   dec a
   ld e_movimiento2(ix), a
   ld hl, #_fedora_sprites_09
   ld b, e_h(ix) 
   ld c, e_w(ix)
   call cpct_drawSprite_asm

   ld a, e_movimiento2(ix)
   cp #0
   jp z, reiniciarValor3
   
   jp _entityNext

tercer_Mov_Left::
   dec a
   ld e_movimiento3(ix), a
   ld hl, #_fedora_sprites_10
   ld b, e_h(ix) 
   ld c, e_w(ix)
   call cpct_drawSprite_asm

   ld a, e_movimiento3(ix)
   cp #0
   jp z, reiniciarValor1
   
   jp _entityNext

reiniciarValor1::
    ld e_movimiento1(ix), #5
    jp _entityNext

reiniciarValor2::
    ld e_movimiento2(ix), #5
    jp _entityNext

reiniciarValor3::
    ld e_movimiento3(ix), #5
    jp _entityNext


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Renderización de movimientos a la derecha del personaje;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

primer_Mov_Right::
   dec a
   ld e_movimiento1(ix), a
   ld hl, #_fedora_sprites_01
   ld b, e_h(ix) 
   ld c, e_w(ix)
   call cpct_drawSprite_asm

   ld a, e_movimiento1(ix)
   cp #0
   jp z, reiniciarValor2
   
   jp _entityNext

segundo_Mov_Right::
   dec a
   ld e_movimiento2(ix), a
   ld hl, #_fedora_sprites_02
   ld b, e_h(ix) 
   ld c, e_w(ix)
   call cpct_drawSprite_asm

   ld a, e_movimiento2(ix)
   cp #0
   jp z, reiniciarValor3
   
   jp _entityNext

tercer_Mov_Right::
   dec a
   ld e_movimiento3(ix), a
   ld hl, #_fedora_sprites_03
   ld b, e_h(ix) 
   ld c, e_w(ix)
   call cpct_drawSprite_asm

   ld a, e_movimiento3(ix)
   cp #0
   jp z, reiniciarValor1
   
   jp _entityNext

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Renderización de movimientos en el salto del personaje;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

jump_left::
   ld hl, #_fedora_sprites_06
   ld b, e_h(ix) 
   ld c, e_w(ix)
   call cpct_drawSprite_asm

   jp _entityNext

jump_right::
   ld hl, #_fedora_sprites_11
   ld b, e_h(ix) 
   ld c, e_w(ix)
   call cpct_drawSprite_asm

   jp _entityNext


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Renderización de la puerta abierta;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

puertaAbierta_render::
    ;;borrarEntidad
    ld e, e_prev_ptr+0(ix)
    ld d, e_prev_ptr+1(ix)
    xor a       ;;A = 0
    ld c, e_w(ix)
    ld b, e_h(ix)
    call cpct_drawSolidBox_asm

    ;;renderizo
    ld de, #0XC000
    ld b, e_y(ix)
    ld c, e_x(ix)
    call cpct_getScreenPtr_asm
    ex de, hl

    ;;Guardo e_prev_ptr para borrar en el próximo ciclo
    ld e_prev_ptr+0(ix), e
    ld e_prev_ptr+1(ix), d

    ld hl, #_fedora_puerta_1
    ld b, e_h(ix) 
    ld c, e_w(ix)
    call cpct_drawSprite_asm

    pop af
    dec a
    ret z

    ld bc, #entity_size
    add ix, bc
    jp _renderloop

platform_render::
    ;;renderizo
    ld de, #0XC000
    ld b, e_y(ix)
    ld c, e_x(ix)
    call cpct_getScreenPtr_asm
    ex de, hl

    ld l, e_ptr_sprite+0(ix)
    ld h, e_ptr_sprite+1(ix)
    
    ld b, e_h(ix) 
    ld c, e_w(ix)
    call cpct_drawSprite_asm

    ld a, e_cmps(ix)
    res 2, a
    ld e_cmps(ix), a

    pop af
    dec a
    ret z

    ld bc, #entity_size
    add ix, bc
    jp _renderloop


borrarTreasure_render::
    ;;borrarEntidad
    ld e, e_prev_ptr+0(ix)
    ld d, e_prev_ptr+1(ix)
    xor a       ;;A = 0
    ld c, e_w(ix)
    ld b, e_h(ix)
    call cpct_drawSolidBox_asm

    ld a, e_cmps(ix)
    res 3, a
    ld e_cmps(ix), a

    pop af
    dec a
    ret z

    ld bc, #entity_size
    add ix, bc
    jp _renderloop


